1#![no_std]
28#![feature(generic_arg_infer)]
29#![feature(error_in_core)]
30
31#[macro_use]
32extern crate disclose;
33
34#[cfg(feature="std")]
35mod foundation {
36 extern crate std;
37 pub use std::{any, array, borrow, boxed, convert, fmt, num, ops, rc, result, slice, string, sync, vec};
38}
39#[cfg(not(feature="std"))]
40mod foundation {
41 extern crate alloc;
42 pub use alloc::{boxed, rc, string, vec};
43 pub use core::{array, borrow, convert, fmt, num, result, ops, slice, any};
44}
45
46#[cfg_attr(feature="open", disclose)]
47mod prelude {
48 pub use super::{foundation::*, Harness, Machine, chip::State};
49 pub(crate) use super::{raw, bits::{u8, u16}};
50 pub use self::{boxed::Box, num::Wrapping, string::String, borrow::{Borrow, BorrowMut}, ops::{Deref, DerefMut, Index, IndexMut}};
51}
52use self::{prelude::*, rc::Rc};
53
54mod chip;
55
56#[cfg(feature="_cpp")]
58mod cpp;
59
60#[allow(non_camel_case_types)]
61mod raw {
62 pub type u8 = core::primitive::u8;
63 pub type u16 = core::primitive::u16;
64}
65
66#[allow(non_camel_case_types)]
67mod bits {
68 use super::*;
69 pub type u8 = crate::num::Wrapping<raw::u8>;
70 pub type u16 = crate::num::Wrapping<raw::u16>;
71}
72
73#[cfg(any(feature="open", doc))]
74pub use crate::chip::{State, access::*, opcode::{self as op, Op::{self, *}, Flag::*, Test::*}};
75
76pub trait Harness {
81 fn read(&self, from: u16) -> u8;
87
88 fn read_word(&self, from: u16) -> u16 {
97 Wrapping(raw::u16::from_le_bytes([self.read(from).0, self.read(from + Wrapping(1)).0]))
98 }
99
100 fn write(&mut self, to: u16, value: u8) { let _ = (value, to); }
104
105 fn write_word(&mut self, to: u16, value: u16) {
114 for (index, byte) in value.0.to_le_bytes().into_iter().enumerate() {
115 self.write(to + Wrapping(index as raw::u16), Wrapping(byte))
116 }
117 }
118
119 fn input(&mut self, port: raw::u8) -> u8;
122
123 fn output(&mut self, port: raw::u8, value: u8);
126
127
128 #[cfg(any(feature="open", doc))]
132 fn did_execute(&mut self, client: &chip::State, did: chip::opcode::Op) -> Result<Option<chip::opcode::Op>, String> { let _ = (client, did); Ok( None ) }
133
134 fn as_any(&self) -> Option<&dyn any::Any> { None }
137}
138
139#[cfg(feature="std")]
140use crate::sync::{Arc, Mutex};
141use core::{borrow::BorrowMut, cell::RefCell, marker::PhantomData, ops::{Deref, DerefMut}};
142
143type Shared<H, C> = Rc<RefCell<(C, PhantomData<H>)>>;
144
145impl<H: Harness + ?Sized, C: BorrowMut<H>> Harness for Shared<H, C> {
146 fn read(&self, address: u16) -> u8 { self.deref().borrow().0.borrow().read(address) }
147 fn read_word(&self, address: u16) -> u16 { self.deref().borrow().0.borrow().read_word(address) }
148 fn write(&mut self, address: u16, value: u8) { (**self).borrow_mut().0.borrow_mut().write(address, value) }
149 fn write_word(&mut self, address: u16, value: u16) { (**self).borrow_mut().0.borrow_mut().write_word(address, value) }
150 fn input(&mut self, port: raw::u8) -> u8 { (**self).borrow_mut().0.borrow_mut().input(port) }
151 fn output(&mut self, port: raw::u8, value: u8) { (**self).borrow_mut().0.borrow_mut().output(port, value) }
152 #[cfg(feature="cfg")]
153 fn did_execute(&mut self, client: &chip::State, did: chip::opcode::Op) -> Result<Option<chip::opcode::Op>, string::String> {
154 (**self).borrow_mut().0.borrow_mut().did_execute(client, did)
155 }
156}
157
158#[cfg(feature="std")]
159type Synced<H, C> = Arc<Mutex<(C, PhantomData<H>)>>;
160
161#[cfg(feature="std")]
162impl<H: Harness + ?Sized, C: BorrowMut<H>> Harness for Synced<H, C> {
163 fn read(&self, address: u16) -> u8 { self.deref().lock().unwrap().0.borrow().read(address) }
164 fn read_word(&self, address: u16) -> u16 { self.deref().lock().unwrap().0.borrow().read_word(address) }
165 fn write(&mut self, address: u16, value: u8) { (**self).lock().unwrap().0.borrow_mut().write(address, value) }
166 fn write_word(&mut self, address: u16, value: u16) { (**self).lock().unwrap().0.borrow_mut().write_word(address, value) }
167 fn input(&mut self, port: raw::u8) -> u8 { (**self).lock().unwrap().0.borrow_mut().input(port) }
168 fn output(&mut self, port: raw::u8, value: u8) { (**self).lock().unwrap().0.borrow_mut().output(port, value) }
169 #[cfg(feature="cfg")]
170 fn did_execute(&mut self, client: &chip::State, did: chip::opcode::Op) -> Result<Option<chip::opcode::Op>, string::String> {
171 (**self).lock().unwrap().0.borrow_mut().did_execute(client, did)
172 }
173}
174
175#[repr(C)]
179pub struct SimpleBoard {
180 ram: [u8; 65536],
181 pub port_out: [u8; 256],
182 pub port_in: [u8; 256]
183}
184
185mod simple;
186
187pub struct Machine<H: Harness + ?Sized, C: BorrowMut<H>> {
192 chip: chip::State,
193 board: C,
194 _grammar: PhantomData<H>,
195}
196
197impl<H: Harness + ?Sized, C: BorrowMut<H>> Machine<H, C> {
198 pub fn new(board: C) -> Self {
199 Self { board, chip: chip::State::new(), _grammar: PhantomData::default() }
200 }
201
202 fn split_mut(&mut self) -> (&mut chip::State, &mut H) { (&mut self.chip, self.board.borrow_mut() )}
203}
204
205impl<H: Harness + ?Sized, C: BorrowMut<H>> Machine<Shared<H, C>, Shared<H, C>> {
209 pub fn fork(&self) -> Self { Self::new(self.board.clone()) }
210}
211
212#[cfg(feature="std")]
213impl<H: Harness + ?Sized, C: BorrowMut<H>> Machine<Synced<H, C>, Synced<H, C>> {
214 pub fn fork(&self) -> Self { Self::new(self.board.clone()) }
215}
216
217impl<H: Harness + ?Sized, C: BorrowMut<H>> Deref for Machine<H, C> {
218 type Target = H;
219 fn deref(&self) -> &Self::Target { self.board.borrow() }
220}
221
222impl<H: Harness + ?Sized, C: BorrowMut<H>> DerefMut for Machine<H, C> {
223 fn deref_mut(&mut self) -> &mut Self::Target { self.board.borrow_mut() }
224}
225
226pub struct Install<H: Harness + ?Sized>(PhantomData<H>);
227
228impl<H: Harness + ?Sized> Install<H> {
229 pub fn new<C: BorrowMut<H>>(board: C) -> Machine<H, C> {
233 Machine::new( board )
234 }
235
236 pub fn new_shared<C: BorrowMut<H>>(board: C) -> Machine<Shared<H, C>, Shared<H, C>> {
240 Machine::new(Rc::new(RefCell::new( (board, PhantomData::default()) )))
241 }
242
243 #[cfg(feature="std")]
248 pub fn new_synced<C: BorrowMut<H>>(board: C) -> Machine<Synced<H, C>, Synced<H, C>> {
249 Machine::new(Arc::new(Mutex::new( (board, PhantomData::default()) )))
250 }
251}
252
253#[allow(dead_code)]
254impl<H: Harness + ?Sized, C: BorrowMut<H>> Machine<H, C> {
255 fn as_ref(&self) -> &chip::State { &self.chip }
256 fn as_mut(&mut self) -> &mut chip::State { &mut self.chip }
257}
258
259#[cfg(feature="open")]
260impl<H: Harness + ?Sized, C: BorrowMut<H>> AsRef<chip::State> for Machine<H, C> {
261 fn as_ref(&self) -> &chip::State { self.as_ref() }
262}
263
264#[cfg(feature="open")]
265impl<H: Harness + ?Sized, C: BorrowMut<H>> AsMut<chip::State> for Machine<H, C> {
266 fn as_mut(&mut self) -> &mut chip::State { self.as_mut() }
267}