1#[allow(unused_imports)]
9use super::vec::Vec;
10use core::num::NonZeroU16;
11use core::ops::Range;
12use core::marker::PhantomData;
13use z80emu::{Io, Memory};
14
15#[derive(Default)]
19pub struct Terminator<T: Copy>(PhantomData<T>);
20
21pub const fn bit8(n: u32) -> u8 {
23 1 << n
24}
25
26pub trait BusMemory {
28 fn memory_debug(&self, addr: Range<u16>) -> Vec<u8>;
30}
31
32pub trait BusDevice {
34 type Timestamp: Copy;
36 type NextDevice: BusDevice;
38 fn reset(&mut self, ts: Self::Timestamp);
40 fn frame_end(&mut self, ts: Self::Timestamp);
43 fn m1(&mut self, ts: Self::Timestamp);
46 fn next_device(&mut self) -> &mut Self::NextDevice;
48 fn next_second(&mut self, delta: Self::Timestamp);
50}
51
52pub trait MemoryControl {
54 fn read_ctrl(&self) -> u8;
56 fn write_ctrl(&mut self, data: u8);
58 fn memory_debug(&self, addr: Range<u16>) -> Vec<u8>;
60}
61
62pub struct Bus<D, M> {
64 port_match_mask: u16,
65 port_match_bits: u16,
66 device: D,
67 memory: M,
68}
69
70impl <T: Copy, D, M: MemoryControl> BusMemory for Bus<D, M>
71where D: BusDevice<Timestamp=T>
72{
73 fn memory_debug(&self, addrs: Range<u16>) -> Vec<u8> {
74 self.memory.memory_debug(addrs)
75 }
76}
77
78impl <T: Copy, D, M> BusDevice for Bus<D, M>
79where D: BusDevice<Timestamp=T>
80{
81 type Timestamp = T;
82 type NextDevice = D;
83 fn reset(&mut self, ts: T) {
84 self.device.reset(ts)
85 }
86 fn frame_end(&mut self, ts: Self::Timestamp) {
87 self.device.frame_end(ts)
88 }
89 fn m1(&mut self, ts: T) {
90 self.device.m1(ts)
91 }
92 fn next_device(&mut self) -> &mut D {
93 &mut self.device
94 }
95 fn next_second(&mut self, delta: T) {
96 self.device.next_second(delta);
97 }
98}
99
100impl<D, M> Bus<D, M> {
101 pub fn new(device: D, memory: M) -> Self {
104 Bus { port_match_mask: 0, port_match_bits: 0, device, memory }
105 }
106
107 pub fn with_port_bits(mut self, port_match_mask: u16, port_match_bits: u16) -> Self {
109 assert_eq!(port_match_mask & port_match_bits, port_match_bits);
110 self.port_match_mask = port_match_mask;
111 self.port_match_bits = port_match_bits;
112 self
113 }
114 pub fn memory_ref(&self) -> &M {
116 &self.memory
117 }
118 pub fn memory_mut(&mut self) -> &mut M {
120 &mut self.memory
121 }
122 pub fn into_inner(self) -> (D, M) {
124 (self.device, self.memory)
125 }
126}
127
128impl<T, D, M> Io for Bus<D, M>
129where T: Copy,
130 D: BusDevice + Io<Timestamp=T,WrIoBreak=(),RetiBreak=()>,
131 M: Memory<Timestamp=T> + MemoryControl
132{
133 type Timestamp = T;
134 type WrIoBreak = ();
135 type RetiBreak = ();
136
137 #[inline(always)]
138 fn write_io(&mut self, port: u16, data: u8, ts: T) -> (Option<()>, Option<NonZeroU16>) {
139 if port & self.port_match_mask == self.port_match_bits {
140 self.memory.write_ctrl(data);
141 (None, None)
142 }
143 else {
144 self.device.write_io(port, data, ts)
145 }
146 }
147
148 #[inline(always)]
149 fn read_io(&mut self, port: u16, ts: T) -> (u8, Option<NonZeroU16>) {
150 if port & self.port_match_mask == self.port_match_bits {
151 (self.memory.read_ctrl(), None)
152 }
153 else {
154 self.device.read_io(port, ts)
155 }
156 }
157
158 #[inline(always)]
159 fn is_irq(&mut self, ts: Self::Timestamp) -> bool {
160 self.device.is_irq(ts)
161 }
162
163 #[inline(always)]
164 fn irq_data(&mut self, pc: u16, ts: Self::Timestamp) -> (u8, Option<NonZeroU16>) {
165 self.device.irq_data(pc, ts)
166 }
167
168 #[inline(always)]
169 fn reti(&mut self, addr: u16, ts: Self::Timestamp) -> Option<()> {
170 self.device.reti(addr, ts)
171 }
172}
173
174impl<T, D, M> Memory for Bus<D, M>
175where T: Copy,
176 D: BusDevice<Timestamp=T> + Io<Timestamp=T>,
177 M: Memory<Timestamp=T>
178{
179 type Timestamp = T;
180 #[inline(always)]
181 fn read_opcode(&mut self, pc: u16, ir: u16, ts: T) -> u8 {
182 self.device.m1(ts);
183 self.memory.read_opcode(pc, ir, ts)
184 }
185 #[inline(always)]
186 fn read_mem(&self, addr: u16, ts: T) -> u8 {
187 self.memory.read_mem(addr, ts)
188 }
189 #[inline(always)]
190 fn read_mem16(&self, addr: u16, ts: T) -> u16 {
191 self.memory.read_mem16(addr, ts)
192 }
193 #[inline(always)]
194 fn write_mem(&mut self, addr: u16, data: u8, ts: T) {
195 self.memory.write_mem(addr, data, ts);
196 }
197 #[inline(always)]
198 fn read_debug(&self, addr: u16) -> u8 {
199 self.memory.read_debug(addr)
200 }
201}
202
203impl<T: Copy> BusDevice for Terminator<T> {
204 type Timestamp = T;
205 type NextDevice = Self;
206 #[inline(always)]
207 fn reset(&mut self, _ts: T) {}
208 #[inline(always)]
209 fn frame_end(&mut self, _ts: Self::Timestamp) {}
210 #[inline(always)]
211 fn m1(&mut self, _ts: T) {}
212 #[inline(always)]
213 fn next_device(&mut self) -> &mut Self {
214 self
215 }
216 #[inline(always)]
217 fn next_second(&mut self, _delta: T) {}
218}
219
220impl<T: Copy> Terminator<T> {
221 pub fn new() -> Self {
222 Terminator(PhantomData)
223 }
224}
225
226impl<T: Copy> Io for Terminator<T> {
227 type Timestamp = T;
228 type WrIoBreak = ();
229 type RetiBreak = ();
230
231 #[inline(always)]
232 fn write_io(&mut self, _port: u16, _data: u8, _ts: T) -> (Option<()>, Option<NonZeroU16>) {
233 (None, None)
234 }
235 #[inline(always)]
236 fn read_io(&mut self, _port: u16, _ts: T) -> (u8, Option<NonZeroU16>) {
237 (u8::max_value(), None)
238 }
239 #[inline(always)]
240 fn is_irq(&mut self, _ts: Self::Timestamp) -> bool {
241 false
242 }
243 #[inline(always)]
244 fn irq_data(&mut self, _pc: u16, _ts: Self::Timestamp) -> (u8, Option<NonZeroU16>) {
245 (u8::max_value(), None)
246 }
247 #[inline(always)]
248 fn reti(&mut self, _addr: u16, _ts: Self::Timestamp) -> Option<()> {
249 None
250 }
251}