spectrusty/
lib.rs

1/*
2    Copyright (C) 2020-2022  Rafal Michalski
3
4    This file is part of SPECTRUSTY, a Rust library for building emulators.
5
6    SPECTRUSTY is free software: you can redistribute it and/or modify it under
7    the terms of the GNU Lesser General Public License (LGPL) as published
8    by the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10
11    SPECTRUSTY is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public License
17    along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
19    Author contact information: see Cargo.toml file, section [package.authors].
20*/
21/*! # SPECTRUSTY
22
23**S P E C T R U S T Y**
24<svg viewBox="0 0 350 100" width="3em" height="1em" style="padding-top:4px" xmlns="http://www.w3.org/2000/svg">
25  <polygon points="0,100 100,0 150,0 50,100" fill="#D80000" stroke="#D80000"/>
26  <polygon points="50,100 150,0 200,0 100,100" fill="#D8D800" stroke="#D8D800"/>
27  <polygon points="100,100 200,0 250,0 150,100" fill="#00D800" stroke="#00D800"/>
28  <polygon points="150,100 250,0 300,0 200,100" fill="#00D8D8" stroke="#00D8D8"/>
29</svg>
30is a library for building emulators based on various ZX Spectrum computer models and clones.
31
32Components of the library can also be used to implement chiptune players, format converters, and more.
33
34Because of its vast scope, **SPECTRUSTY** has been split into several dependent crates and one extra crate
35with complementary utilities. The additional crates can be used separately or through this library.
36
37* `spectrusty` - this library.
38* [spectrusty-core] - defines basic traits and structs.
39* [spectrusty-audio] - tools for synthesizing and playing audio samples.
40* [spectrusty-formats] - file formats and related utilities.
41* [spectrusty-peripherals] - emulators of various peripheral devices.
42* [z80emu] - Zilog's Z80 CPU family emulator, re-exported as `z80emu`.
43
44The separate crate [spectrusty-utils], provides additional utilities, like TAPe
45organizers, tape ROM auto-loader, printer utilities, and keyboard helpers for various platforms.
46
47Several features control which components will be included:
48
49* `"audio"` - includes [spectrusty-audio] which is re-exported as [audio].
50* `"formats"` - includes [spectrusty-formats] which is re-exported as [formats].
51* `"peripherals"` - includes [spectrusty-peripherals] which is re-exported as [peripherals].
52
53Additional features:
54
55* `"snapshot"` - enables serde serializers and deserializers, so custom snapshots can be created
56  with ease in elastic formats.
57* `"compression"` - enables gzip compression/decompression of memory chunks stored in snapshots.
58* `"boxed_frame_cache"` - chipset implementations will have significantly reduced struct sizes
59  by boxing their internal [UlaFrameCache] instances at the cost of a minimal performance penalty.
60* `"sdl2"` - enables audio implementation for [SDL2] hardware abstraction layer.
61* `"cpal"` - enables audio implementation for [cpal] native audio library.
62
63The default features are:
64
65```text
66default = ["formats", "peripherals", "snapshot", "compression"]
67```
68
69## Traits
70
71Implemented by ZX Spectrum's core chipset emulators.
72
73Responsible for code execution, keyboard input, video, and accessing peripheral devices:
74
75| trait | function |
76|-------|----------|
77| [UlaCommon][chip::UlaCommon]       | A grouping trait that includes all of the traits listed below in this table |
78| [ControlUnit][chip::ControlUnit]   | Code execution, reset/nmi, access to [BusDevice] peripherals |
79| [FrameState][chip::FrameState]     | Provides access to the frame and T-state counters |
80| [MemoryAccess][chip::MemoryAccess] | Provides access to onboard memory [ZxMemory] and memory extensions [MemoryExtension] |
81| [Video][video::Video]              | Rendering video frame into pixel buffer, border-color control |
82| [KeyboardInterface][peripherals::KeyboardInterface] | Keyboard input control |
83| [EarIn][chip::EarIn]               | EAR line input access |
84| [MicOut][chip::MicOut]             | MIC line output access |
85| [UlaControl][chip::UlaControl]     | Accessors for specialized ULA functionality |
86
87Audio output:
88
89| trait | function |
90|-------|----------|
91| [UlaAudioFrame][audio::UlaAudioFrame] | A grouping trait that includes all of the traits listed below in this table |
92| [AudioFrame][audio::AudioFrame] | A helper trait for setting up [Blep] and ending audio frames |
93| [EarMicOutAudioFrame][audio::EarMicOutAudioFrame] | Adds [Blep] steps from EAR/MIC output lines data |
94| [EarInAudioFrame][audio::EarInAudioFrame] | Adds [Blep] steps from EAR/MIC output lines data |
95| [AyAudioFrame][peripherals::ay::audio::AyAudioFrame] | Renders [Blep] steps from AY-3-891x sound processor | 
96
97Emulated computer configurations:
98
99| trait | function |
100|-------|----------|
101| [HostConfig][chip::HostConfig] | Defines CPU clock frequency and a video frame duration |
102
103Associated traits implemented by special unit structs for driving audio and video rendering and memory contention:
104
105| trait | function |
106|-------|----------|
107| [VideoFrame] | Helps driving video rendering, provides arithmetic and conversion tools for [VideoTs] timestamps |
108| [MemoryContention][clock::MemoryContention] | A trait that helps establish if an address is being contended |
109| [AmpLevels][audio::AmpLevels] | Converts digital audio levels to sample amplitudes |
110
111Implemented by other components:
112
113| trait | implemented by | function |
114|-------|----------------|----------|
115| [Cpu] | Z80 CPU | Central processing unit |
116| [ZxMemory] | System memory | An access to memory banks, pages, screens, attaching external ROM's |
117| [PagedMemory16k][memory::PagedMemory16k] | Memory group | Groups memory implementations with 16k paging capability |
118| [PagedMemory8k][memory::PagedMemory8k] | Memory group | Groups memory implementations with 8k paging capability |
119| [MemoryExtension] | Memory extensions | Installs program counter traps to switch in and out external banks of memory |
120| [BusDevice] | I/O peripheral devices | Establishes address and data BUS communication between CPU and peripherals |
121| [Blep] | Bandwidth-Limited Pulse Buffer | An intermediate amplitude differences buffer for rendering square-waves |
122
123## Structs
124
125These are the most commonly used:
126
127| struct | function |
128|--------|----------|
129| [VideoTs] | A video T-state timestamp, that consist of two components: a scan line number and a horizontal T-state |
130| [VFrameTs][clock::VFrameTs]`<V>` | A [VideoFrame] aware video T-state timestamp, for timestamp calculations |
131| [VFrameTsCounter][clock::VFrameTsCounter]`<V, C>` | Counts T-states and handles the CPU clock contention |
132| [Ula][chip::ula::Ula]`<M, B, X, V>` | A chipset for emulating ZX Spectrum 16/48k PAL/NTSC |
133| [Ula128][chip::ula128::Ula128]`<B, X>` | A chipset for emulating ZX Spectrum 128k/+2 |
134| [Ula3][chip::ula3::Ula3]`<B, X>` | A chipset for emulating ZX Spectrum +2A/+3 |
135| [Scld][chip::scld::Scld]`<M, B, X, V>` | A chipset for emulating TC2048 / TC2068 / TS2068 |
136| [UlaPlus][chip::plus::UlaPlus]`<U>` | A wrapper chipset enhancer for emulating ULAplus graphic modes |
137
138### Generic parameters
139
140* `M`: A system memory that implements [ZxMemory] trait.
141* `B`: A peripheral device that implements [BusDevice].
142* `X`: A memory extension that implements [MemoryExtension].
143* `V`: A unit struct that implements [VideoFrame].
144* `C`: A unit struct that implements [MemoryContention][clock::MemoryContention].
145* `U`: An underlying chipset implementing [UlaPlusInner][chip::plus::UlaPlusInner].
146
147[spectrusty-core]: /spectrusty_core
148[spectrusty-audio]: /spectrusty_audio
149[spectrusty-formats]: /spectrusty_formats
150[spectrusty-peripherals]: /spectrusty_peripherals
151[spectrusty-utils]: /spectrusty_utils
152[z80emu]: /z80emu
153[SDL2]: https://crates.io/crates/sdl2
154[cpal]: https://crates.io/crates/cpal
155[BusDevice]: bus::BusDevice
156[Blep]: audio::Blep
157[ZxMemory]: memory::ZxMemory
158[MemoryExtension]: memory::MemoryExtension
159[UlaFrameCache]: chip::ula::frame_cache::UlaFrameCache
160[VideoFrame]: video::VideoFrame
161[VideoTs]: clock::VideoTs
162[Cpu]: /z80emu/%2A/z80emu/trait.Cpu.html
163*/
164pub use spectrusty_core::z80emu;
165pub use spectrusty_core::clock;
166#[cfg(feature = "formats")] pub use spectrusty_formats as formats;
167
168pub mod audio;
169pub mod bus;
170pub mod chip;
171pub mod memory;
172pub mod peripherals;
173pub mod video;
174
175#[cfg(test)]
176mod tests {
177    use core::convert::TryFrom;
178    use super::clock::{FTs, VFrameTs};
179    use super::chip::ula::UlaVideoFrame;
180
181    type VFTs = VFrameTs<UlaVideoFrame>;
182    #[test]
183    fn test_clock_conversion() {
184        assert_eq!(VFTs::default(), VFTs::new(0, 0));
185        assert_eq!(0, FTs::from(VFTs::new(0, 0)));
186        let vts = VFTs::max_value();
187        assert_eq!(vts, VFTs::new(32767, 154));
188        let ts = FTs::from(vts);
189        assert_eq!(ts, 32767 * 224 + 154);
190        let vts = VFTs::try_from(-32768 * 224 - 69).unwrap();
191        assert_eq!(vts, VFTs::new(-32768, -69));
192        assert_eq!(vts, VFTs::min_value());
193        assert!(VFTs::try_from(FTs::min_value()).is_err());
194        assert!(VFTs::try_from_tstates(FTs::min_value()).is_none());
195        assert!(VFTs::try_from(FTs::max_value()).is_err());
196        assert!(VFTs::try_from_tstates(FTs::max_value()).is_none());
197    }
198}