1use std::time::Duration;
2
3use rand::random;
4
5use crate::{generate_chip, State};
6
7use super::{ChipBuilder, ChipRunner, ChipSet, Pin, PinType};
8
9#[derive(Debug, Clone)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34pub struct Ram256B {
35 powered: bool,
36 ram: Vec<u8>,
37 pub vcc: Pin,
38 pub gnd: Pin,
39 pub cs: Pin,
40 pub we: Pin,
41 pub oe: Pin,
42 pub a0: Pin,
43 pub a1: Pin,
44 pub a2: Pin,
45 pub a3: Pin,
46 pub a4: Pin,
47 pub a5: Pin,
48 pub a6: Pin,
49 pub a7: Pin,
50 pub io0: Pin,
51 pub io1: Pin,
52 pub io2: Pin,
53 pub io3: Pin,
54 pub io4: Pin,
55 pub io5: Pin,
56 pub io6: Pin,
57 pub io7: Pin,
58}
59
60impl Ram256B {
61 pub const CS: usize = 1;
62 pub const WE: usize = 2;
63 pub const OE: usize = 3;
64 pub const A0: usize = 4;
65 pub const A1: usize = 5;
66 pub const A2: usize = 6;
67 pub const A3: usize = 7;
68 pub const A4: usize = 8;
69 pub const A5: usize = 9;
70 pub const A6: usize = 10;
71 pub const A7: usize = 12;
72 pub const IO0: usize = 13;
73 pub const IO1: usize = 14;
74 pub const IO2: usize = 15;
75 pub const IO3: usize = 16;
76 pub const IO4: usize = 17;
77 pub const IO5: usize = 18;
78 pub const IO6: usize = 19;
79 pub const IO7: usize = 20;
80 pub const VCC: usize = 22;
81 pub const GND: usize = 11;
82
83 fn set_io_type(&mut self, pin_type: PinType) {
84 self.io0.pin_type = pin_type;
85 self.io1.pin_type = pin_type;
86 self.io2.pin_type = pin_type;
87 self.io3.pin_type = pin_type;
88 self.io4.pin_type = pin_type;
89 self.io5.pin_type = pin_type;
90 self.io6.pin_type = pin_type;
91 self.io7.pin_type = pin_type;
92 }
93}
94
95generate_chip!(
96 Ram256B,
97 cs: Ram256B::CS,
98 we: Ram256B::WE,
99 oe: Ram256B::OE,
100 a0: Ram256B::A0,
101 a1: Ram256B::A1,
102 a2: Ram256B::A2,
103 a3: Ram256B::A3,
104 a4: Ram256B::A4,
105 a5: Ram256B::A5,
106 a6: Ram256B::A6,
107 a7: Ram256B::A7,
108 io0: Ram256B::IO0,
109 io1: Ram256B::IO1,
110 io2: Ram256B::IO2,
111 io3: Ram256B::IO3,
112 io4: Ram256B::IO4,
113 io5: Ram256B::IO5,
114 io6: Ram256B::IO6,
115 io7: Ram256B::IO7,
116 vcc: Ram256B::VCC,
117 gnd: Ram256B::GND
118);
119
120impl ChipBuilder<ChipSet> for Ram256B {
121 fn build() -> ChipSet {
122 ChipSet::Ram256B(Ram256B {
123 powered: false,
124 ram: Vec::from([0; 256]),
125 vcc: Pin::from(PinType::Input),
126 gnd: Pin::from(PinType::Output),
127 cs: Pin::from(PinType::Input),
128 we: Pin::from(PinType::Input),
129 oe: Pin::from(PinType::Input),
130 a0: Pin::from(PinType::Input),
131 a1: Pin::from(PinType::Input),
132 a2: Pin::from(PinType::Input),
133 a3: Pin::from(PinType::Input),
134 a4: Pin::from(PinType::Input),
135 a5: Pin::from(PinType::Input),
136 a6: Pin::from(PinType::Input),
137 a7: Pin::from(PinType::Input),
138 io0: Pin::from(PinType::Floating),
139 io1: Pin::from(PinType::Floating),
140 io2: Pin::from(PinType::Floating),
141 io3: Pin::from(PinType::Floating),
142 io4: Pin::from(PinType::Floating),
143 io5: Pin::from(PinType::Floating),
144 io6: Pin::from(PinType::Floating),
145 io7: Pin::from(PinType::Floating),
146 })
147 }
148}
149
150impl ChipRunner for Ram256B {
151 fn run(&mut self, _: Duration) {
152 if self.vcc.state.as_logic(1.0) == State::High {
153 if !self.powered {
154 for i in 0..256 {
155 self.ram[i] = random::<u8>();
156 }
157 self.powered = true;
158 }
159 self.gnd.state = State::Low;
160
161 if self.cs.state == State::Low {
163 if self.we.state == State::Low {
165 self.set_io_type(PinType::Input);
167 let addr = Pin::read_threshold(
169 &[
170 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
171 &self.a7,
172 ],
173 3.3,
174 );
175 self.ram[addr] = Pin::read_threshold(
176 &[
177 &self.io0, &self.io1, &self.io2, &self.io3, &self.io4, &self.io5,
178 &self.io6, &self.io7,
179 ],
180 3.3,
181 ) as u8;
182 } else if self.oe.state == State::Low {
183 self.set_io_type(PinType::Output);
185
186 let addr = Pin::read_threshold(
188 &[
189 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
190 &self.a7,
191 ],
192 3.3,
193 );
194 Pin::write(
195 &mut [
196 &mut self.io0,
197 &mut self.io1,
198 &mut self.io2,
199 &mut self.io3,
200 &mut self.io4,
201 &mut self.io5,
202 &mut self.io6,
203 &mut self.io7,
204 ],
205 self.ram[addr] as usize,
206 );
207 } else {
208 self.set_io_type(PinType::Floating);
209 }
210 } else {
211 self.set_io_type(PinType::Floating);
212 }
213 } else if self.powered {
214 self.set_io_type(PinType::Floating);
215 self.powered = false;
216 }
217 }
218}
219
220impl ToString for Ram256B {
221 fn to_string(&self) -> std::string::String {
222 let mut string = String::from(
223 "ADR| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n---+------------------------------------------------",
224 );
225 for (addr, byte) in self.ram.iter().enumerate() {
226 if addr % 16 == 0 {
227 string.push_str(&format!("\n {addr:02X}|"));
228 }
229 string.push_str(&format!(
230 "{}{byte:02X}",
231 if self.cs.state.as_logic(3.3) == State::Low
232 && Pin::read_threshold(
233 &[
234 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
235 &self.a7
236 ],
237 3.3
238 ) == addr
239 {
240 ">"
241 } else {
242 " "
243 }
244 ));
245 }
246 string.push('\n');
247 string
248 }
249}
250
251#[derive(Debug, Clone)]
277#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
278pub struct Ram8KB {
279 powered: bool,
280 ram: Vec<u8>,
281 pub vcc: Pin,
282 pub gnd: Pin,
283 pub cs: Pin,
284 pub we: Pin,
285 pub oe: Pin,
286 pub a0: Pin,
287 pub a1: Pin,
288 pub a2: Pin,
289 pub a3: Pin,
290 pub a4: Pin,
291 pub a5: Pin,
292 pub a6: Pin,
293 pub a7: Pin,
294 pub a8: Pin,
295 pub a9: Pin,
296 pub a10: Pin,
297 pub a11: Pin,
298 pub a12: Pin,
299 pub io0: Pin,
300 pub io1: Pin,
301 pub io2: Pin,
302 pub io3: Pin,
303 pub io4: Pin,
304 pub io5: Pin,
305 pub io6: Pin,
306 pub io7: Pin,
307}
308
309impl Ram8KB {
310 pub const CS: usize = 1;
311 pub const WE: usize = 2;
312 pub const OE: usize = 3;
313 pub const A0: usize = 4;
314 pub const A1: usize = 5;
315 pub const A2: usize = 6;
316 pub const A3: usize = 7;
317 pub const A4: usize = 8;
318 pub const A5: usize = 9;
319 pub const A6: usize = 10;
320 pub const A7: usize = 11;
321 pub const A8: usize = 12;
322 pub const A9: usize = 14;
323 pub const A10: usize = 15;
324 pub const A11: usize = 16;
325 pub const A12: usize = 17;
326 pub const IO0: usize = 18;
327 pub const IO1: usize = 19;
328 pub const IO2: usize = 20;
329 pub const IO3: usize = 21;
330 pub const IO4: usize = 22;
331 pub const IO5: usize = 23;
332 pub const IO6: usize = 24;
333 pub const IO7: usize = 25;
334 pub const VCC: usize = 26;
335 pub const GND: usize = 13;
336
337 fn set_io_type(&mut self, pin_type: PinType) {
338 self.io0.pin_type = pin_type;
339 self.io1.pin_type = pin_type;
340 self.io2.pin_type = pin_type;
341 self.io3.pin_type = pin_type;
342 self.io4.pin_type = pin_type;
343 self.io5.pin_type = pin_type;
344 self.io6.pin_type = pin_type;
345 self.io7.pin_type = pin_type;
346 }
347}
348
349generate_chip!(
350 Ram8KB,
351 cs: Ram8KB::CS,
352 we: Ram8KB::WE,
353 oe: Ram8KB::OE,
354 a0: Ram8KB::A0,
355 a1: Ram8KB::A1,
356 a2: Ram8KB::A2,
357 a3: Ram8KB::A3,
358 a4: Ram8KB::A4,
359 a5: Ram8KB::A5,
360 a6: Ram8KB::A6,
361 a7: Ram8KB::A7,
362 a8: Ram8KB::A8,
363 a9: Ram8KB::A9,
364 a10: Ram8KB::A10,
365 a11: Ram8KB::A11,
366 a12: Ram8KB::A12,
367 io0: Ram8KB::IO0,
368 io1: Ram8KB::IO1,
369 io2: Ram8KB::IO2,
370 io3: Ram8KB::IO3,
371 io4: Ram8KB::IO4,
372 io5: Ram8KB::IO5,
373 io6: Ram8KB::IO6,
374 io7: Ram8KB::IO7,
375 vcc: Ram8KB::VCC,
376 gnd: Ram8KB::GND
377);
378
379impl ChipBuilder<ChipSet> for Ram8KB {
380 fn build() -> ChipSet {
381 ChipSet::Ram8KB(Ram8KB {
382 powered: false,
383 ram: Vec::from([0; 8192]),
384 vcc: Pin::from(PinType::Input),
385 gnd: Pin::from(PinType::Output),
386 cs: Pin::from(PinType::Input),
387 we: Pin::from(PinType::Input),
388 oe: Pin::from(PinType::Input),
389 a0: Pin::from(PinType::Input),
390 a1: Pin::from(PinType::Input),
391 a2: Pin::from(PinType::Input),
392 a3: Pin::from(PinType::Input),
393 a4: Pin::from(PinType::Input),
394 a5: Pin::from(PinType::Input),
395 a6: Pin::from(PinType::Input),
396 a7: Pin::from(PinType::Input),
397 a8: Pin::from(PinType::Input),
398 a9: Pin::from(PinType::Input),
399 a10: Pin::from(PinType::Input),
400 a11: Pin::from(PinType::Input),
401 a12: Pin::from(PinType::Input),
402 io0: Pin::from(PinType::Floating),
403 io1: Pin::from(PinType::Floating),
404 io2: Pin::from(PinType::Floating),
405 io3: Pin::from(PinType::Floating),
406 io4: Pin::from(PinType::Floating),
407 io5: Pin::from(PinType::Floating),
408 io6: Pin::from(PinType::Floating),
409 io7: Pin::from(PinType::Floating),
410 })
411 }
412}
413
414impl ChipRunner for Ram8KB {
415 fn run(&mut self, _: Duration) {
416 if self.vcc.state.as_logic(1.0) == State::High {
417 if !self.powered {
418 for i in 0..256 {
419 self.ram[i] = random::<u8>();
420 }
421 self.powered = true;
422 }
423 self.gnd.state = State::Low;
424
425 if self.cs.state == State::Low {
427 if self.we.state == State::Low {
429 self.set_io_type(PinType::Input);
431 let addr = Pin::read_threshold(
433 &[
434 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
435 &self.a7, &self.a8, &self.a9, &self.a10, &self.a11, &self.a12,
436 ],
437 3.3,
438 );
439 self.ram[addr] = Pin::read_threshold(
440 &[
441 &self.io0, &self.io1, &self.io2, &self.io3, &self.io4, &self.io5,
442 &self.io6, &self.io7,
443 ],
444 3.3,
445 ) as u8;
446 } else if self.oe.state == State::Low {
447 self.set_io_type(PinType::Output);
449
450 let addr = Pin::read_threshold(
452 &[
453 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
454 &self.a7, &self.a8, &self.a9, &self.a10, &self.a11, &self.a12,
455 ],
456 3.3,
457 );
458 Pin::write(
459 &mut [
460 &mut self.io0,
461 &mut self.io1,
462 &mut self.io2,
463 &mut self.io3,
464 &mut self.io4,
465 &mut self.io5,
466 &mut self.io6,
467 &mut self.io7,
468 ],
469 self.ram[addr] as usize,
470 );
471 } else {
472 self.set_io_type(PinType::Floating);
473 }
474 } else {
475 self.set_io_type(PinType::Floating);
476 }
477 } else if self.powered {
478 self.set_io_type(PinType::Floating);
479 self.powered = false;
480 }
481 }
482}
483
484impl ToString for Ram8KB {
485 fn to_string(&self) -> std::string::String {
486 let mut string = String::from(
487 " ADR| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n-----+------------------------------------------------",
488 );
489 for (addr, byte) in self.ram.iter().enumerate() {
490 if addr % 16 == 0 {
491 string.push_str(&format!("\n {addr:04X}|"));
492 }
493 string.push_str(&format!(
494 "{}{byte:02X}",
495 if self.cs.state.as_logic(3.3) == State::Low
496 && Pin::read_threshold(
497 &[
498 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
499 &self.a7, &self.a8, &self.a9, &self.a10, &self.a11, &self.a12,
500 ],
501 3.3
502 ) == addr
503 {
504 ">"
505 } else {
506 " "
507 }
508 ));
509 }
510 string.push('\n');
511 string
512 }
513}
514
515#[derive(Debug, Clone)]
538#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
539pub struct Rom256B {
540 powered: bool,
541 rom: Vec<u8>,
542 pub vcc: Pin,
543 pub gnd: Pin,
544 pub cs: Pin,
545 pub oe: Pin,
546 pub a0: Pin,
547 pub a1: Pin,
548 pub a2: Pin,
549 pub a3: Pin,
550 pub a4: Pin,
551 pub a5: Pin,
552 pub a6: Pin,
553 pub a7: Pin,
554 pub io0: Pin,
555 pub io1: Pin,
556 pub io2: Pin,
557 pub io3: Pin,
558 pub io4: Pin,
559 pub io5: Pin,
560 pub io6: Pin,
561 pub io7: Pin,
562}
563
564impl Rom256B {
565 pub const CS: usize = 1;
566 pub const OE: usize = 3;
567 pub const A0: usize = 4;
568 pub const A1: usize = 5;
569 pub const A2: usize = 6;
570 pub const A3: usize = 7;
571 pub const A4: usize = 8;
572 pub const A5: usize = 9;
573 pub const A6: usize = 10;
574 pub const A7: usize = 12;
575 pub const IO0: usize = 13;
576 pub const IO1: usize = 14;
577 pub const IO2: usize = 15;
578 pub const IO3: usize = 16;
579 pub const IO4: usize = 17;
580 pub const IO5: usize = 18;
581 pub const IO6: usize = 19;
582 pub const IO7: usize = 20;
583 pub const VCC: usize = 22;
584 pub const GND: usize = 11;
585
586 fn set_io_type(&mut self, pin_type: PinType) {
587 self.io0.pin_type = pin_type;
588 self.io1.pin_type = pin_type;
589 self.io2.pin_type = pin_type;
590 self.io3.pin_type = pin_type;
591 self.io4.pin_type = pin_type;
592 self.io5.pin_type = pin_type;
593 self.io6.pin_type = pin_type;
594 self.io7.pin_type = pin_type;
595 }
596
597 pub fn set_data(mut self, data: &[u8]) -> Self {
598 self.rom = Vec::from(data);
599 self.rom.resize(256, 0);
600 self
601 }
602}
603
604generate_chip!(
605 Rom256B,
606 cs: Rom256B::CS,
607 oe: Rom256B::OE,
608 a0: Rom256B::A0,
609 a1: Rom256B::A1,
610 a2: Rom256B::A2,
611 a3: Rom256B::A3,
612 a4: Rom256B::A4,
613 a5: Rom256B::A5,
614 a6: Rom256B::A6,
615 a7: Rom256B::A7,
616 io0: Rom256B::IO0,
617 io1: Rom256B::IO1,
618 io2: Rom256B::IO2,
619 io3: Rom256B::IO3,
620 io4: Rom256B::IO4,
621 io5: Rom256B::IO5,
622 io6: Rom256B::IO6,
623 io7: Rom256B::IO7,
624 vcc: Rom256B::VCC,
625 gnd: Rom256B::GND
626);
627
628impl ChipBuilder<Rom256B> for Rom256B {
629 fn build() -> Rom256B {
630 Rom256B {
631 powered: false,
632 rom: Vec::from([0; 256]),
633 vcc: Pin::from(PinType::Input),
634 gnd: Pin::from(PinType::Output),
635 cs: Pin::from(PinType::Input),
636 oe: Pin::from(PinType::Input),
637 a0: Pin::from(PinType::Input),
638 a1: Pin::from(PinType::Input),
639 a2: Pin::from(PinType::Input),
640 a3: Pin::from(PinType::Input),
641 a4: Pin::from(PinType::Input),
642 a5: Pin::from(PinType::Input),
643 a6: Pin::from(PinType::Input),
644 a7: Pin::from(PinType::Input),
645 io0: Pin::from(PinType::Floating),
646 io1: Pin::from(PinType::Floating),
647 io2: Pin::from(PinType::Floating),
648 io3: Pin::from(PinType::Floating),
649 io4: Pin::from(PinType::Floating),
650 io5: Pin::from(PinType::Floating),
651 io6: Pin::from(PinType::Floating),
652 io7: Pin::from(PinType::Floating),
653 }
654 }
655}
656
657impl From<Rom256B> for ChipSet {
658 fn from(value: Rom256B) -> Self {
659 ChipSet::Rom256B(value)
660 }
661}
662
663impl ChipRunner for Rom256B {
664 fn run(&mut self, _: Duration) {
665 if self.vcc.state.as_logic(1.0) == State::High {
666 if !self.powered {
667 self.powered = true;
668 }
669 self.gnd.state = State::Low;
670
671 if self.cs.state == State::Low {
673 if self.oe.state == State::Low {
675 self.set_io_type(PinType::Output);
677
678 let addr = Pin::read_threshold(
680 &[
681 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
682 &self.a7,
683 ],
684 3.3,
685 );
686 Pin::write(
687 &mut [
688 &mut self.io0,
689 &mut self.io1,
690 &mut self.io2,
691 &mut self.io3,
692 &mut self.io4,
693 &mut self.io5,
694 &mut self.io6,
695 &mut self.io7,
696 ],
697 self.rom[addr] as usize,
698 );
699 } else {
700 self.set_io_type(PinType::Floating);
701 }
702 } else {
703 self.set_io_type(PinType::Floating);
704 }
705 } else if self.powered {
706 self.set_io_type(PinType::Floating);
707 self.powered = false;
708 }
709 }
710}
711
712impl ToString for Rom256B {
713 fn to_string(&self) -> std::string::String {
714 let mut string = String::from(
715 "ADR| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n---+------------------------------------------------",
716 );
717 for (addr, byte) in self.rom.iter().enumerate() {
718 if addr % 16 == 0 {
719 string.push_str(&format!("\n {addr:02X}|"));
720 }
721 string.push_str(&format!(
722 "{}{byte:02X}",
723 if self.cs.state.as_logic(3.3) == State::Low
724 && Pin::read_threshold(
725 &[
726 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
727 &self.a7
728 ],
729 3.3
730 ) > 0
731 {
732 ">"
733 } else {
734 " "
735 }
736 ));
737 }
738 string.push('\n');
739 string
740 }
741}
742
743#[derive(Debug, Clone)]
769#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
770pub struct Rom8KB {
771 powered: bool,
772 rom: Vec<u8>,
773 pub vcc: Pin,
774 pub gnd: Pin,
775 pub cs: Pin,
776 pub oe: Pin,
777 pub a0: Pin,
778 pub a1: Pin,
779 pub a2: Pin,
780 pub a3: Pin,
781 pub a4: Pin,
782 pub a5: Pin,
783 pub a6: Pin,
784 pub a7: Pin,
785 pub a8: Pin,
786 pub a9: Pin,
787 pub a10: Pin,
788 pub a11: Pin,
789 pub a12: Pin,
790 pub io0: Pin,
791 pub io1: Pin,
792 pub io2: Pin,
793 pub io3: Pin,
794 pub io4: Pin,
795 pub io5: Pin,
796 pub io6: Pin,
797 pub io7: Pin,
798}
799
800impl Rom8KB {
801 pub const CS: usize = 1;
802 pub const OE: usize = 3;
803 pub const A0: usize = 4;
804 pub const A1: usize = 5;
805 pub const A2: usize = 6;
806 pub const A3: usize = 7;
807 pub const A4: usize = 8;
808 pub const A5: usize = 9;
809 pub const A6: usize = 10;
810 pub const A7: usize = 11;
811 pub const A8: usize = 12;
812 pub const A9: usize = 14;
813 pub const A10: usize = 15;
814 pub const A11: usize = 16;
815 pub const A12: usize = 17;
816 pub const IO0: usize = 18;
817 pub const IO1: usize = 19;
818 pub const IO2: usize = 20;
819 pub const IO3: usize = 21;
820 pub const IO4: usize = 22;
821 pub const IO5: usize = 23;
822 pub const IO6: usize = 24;
823 pub const IO7: usize = 25;
824 pub const VCC: usize = 26;
825 pub const GND: usize = 13;
826
827 fn set_io_type(&mut self, pin_type: PinType) {
828 self.io0.pin_type = pin_type;
829 self.io1.pin_type = pin_type;
830 self.io2.pin_type = pin_type;
831 self.io3.pin_type = pin_type;
832 self.io4.pin_type = pin_type;
833 self.io5.pin_type = pin_type;
834 self.io6.pin_type = pin_type;
835 self.io7.pin_type = pin_type;
836 }
837
838 pub fn set_data(mut self, data: &[u8]) -> Self {
839 self.rom = Vec::from(data);
840 self.rom.resize(8192, 0);
841 self
842 }
843}
844
845generate_chip!(
846 Rom8KB,
847 cs: Rom8KB::CS,
848 oe: Rom8KB::OE,
849 a0: Rom8KB::A0,
850 a1: Rom8KB::A1,
851 a2: Rom8KB::A2,
852 a3: Rom8KB::A3,
853 a4: Rom8KB::A4,
854 a5: Rom8KB::A5,
855 a6: Rom8KB::A6,
856 a7: Rom8KB::A7,
857 a8: Rom8KB::A8,
858 a9: Rom8KB::A9,
859 a10: Rom8KB::A10,
860 a11: Rom8KB::A11,
861 a12: Rom8KB::A12,
862 io0: Rom8KB::IO0,
863 io1: Rom8KB::IO1,
864 io2: Rom8KB::IO2,
865 io3: Rom8KB::IO3,
866 io4: Rom8KB::IO4,
867 io5: Rom8KB::IO5,
868 io6: Rom8KB::IO6,
869 io7: Rom8KB::IO7,
870 vcc: Rom8KB::VCC,
871 gnd: Rom8KB::GND
872);
873
874impl ChipBuilder<Rom8KB> for Rom8KB {
875 fn build() -> Rom8KB {
876 Rom8KB {
877 powered: false,
878 rom: Vec::from([0; 8192]),
879 vcc: Pin::from(PinType::Input),
880 gnd: Pin::from(PinType::Output),
881 cs: Pin::from(PinType::Input),
882 oe: Pin::from(PinType::Input),
883 a0: Pin::from(PinType::Input),
884 a1: Pin::from(PinType::Input),
885 a2: Pin::from(PinType::Input),
886 a3: Pin::from(PinType::Input),
887 a4: Pin::from(PinType::Input),
888 a5: Pin::from(PinType::Input),
889 a6: Pin::from(PinType::Input),
890 a7: Pin::from(PinType::Input),
891 a8: Pin::from(PinType::Input),
892 a9: Pin::from(PinType::Input),
893 a10: Pin::from(PinType::Input),
894 a11: Pin::from(PinType::Input),
895 a12: Pin::from(PinType::Input),
896 io0: Pin::from(PinType::Floating),
897 io1: Pin::from(PinType::Floating),
898 io2: Pin::from(PinType::Floating),
899 io3: Pin::from(PinType::Floating),
900 io4: Pin::from(PinType::Floating),
901 io5: Pin::from(PinType::Floating),
902 io6: Pin::from(PinType::Floating),
903 io7: Pin::from(PinType::Floating),
904 }
905 }
906}
907
908impl From<Rom8KB> for ChipSet {
909 fn from(value: Rom8KB) -> Self {
910 ChipSet::Rom8KB(value)
911 }
912}
913
914impl ChipRunner for Rom8KB {
915 fn run(&mut self, _: Duration) {
916 if self.vcc.state.as_logic(1.0) == State::High {
917 if !self.powered {
918 self.powered = true;
919 }
920 self.gnd.state = State::Low;
921
922 if self.cs.state == State::Low {
924 if self.oe.state == State::Low {
926 self.set_io_type(PinType::Output);
928
929 let addr = Pin::read_threshold(
931 &[
932 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
933 &self.a7, &self.a8, &self.a9, &self.a10, &self.a11, &self.a12,
934 ],
935 3.3,
936 );
937 Pin::write(
938 &mut [
939 &mut self.io0,
940 &mut self.io1,
941 &mut self.io2,
942 &mut self.io3,
943 &mut self.io4,
944 &mut self.io5,
945 &mut self.io6,
946 &mut self.io7,
947 ],
948 self.rom[addr] as usize,
949 );
950 } else {
951 self.set_io_type(PinType::Floating);
952 }
953 } else {
954 self.set_io_type(PinType::Floating);
955 }
956 } else if self.powered {
957 self.set_io_type(PinType::Floating);
958 self.powered = false;
959 }
960 }
961}
962
963impl ToString for Rom8KB {
964 fn to_string(&self) -> std::string::String {
965 let mut string = String::from(
966 " ADR| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n-----+------------------------------------------------",
967 );
968 for (addr, byte) in self.rom.iter().enumerate() {
969 if addr % 16 == 0 {
970 string.push_str(&format!("\n {addr:04X}|"));
971 }
972 string.push_str(&format!(
973 "{}{byte:02X}",
974 if self.cs.state.as_logic(3.3) == State::Low
975 && Pin::read_threshold(
976 &[
977 &self.a0, &self.a1, &self.a2, &self.a3, &self.a4, &self.a5, &self.a6,
978 &self.a7, &self.a8, &self.a9, &self.a10, &self.a11, &self.a12,
979 ],
980 3.3
981 ) == addr
982 {
983 ">"
984 } else {
985 " "
986 }
987 ));
988 }
989 string.push('\n');
990 string
991 }
992}