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}