implement sound module
This commit is contained in:
parent
8369f06194
commit
ca97cb7de8
3 changed files with 30 additions and 7 deletions
|
@ -1,5 +1,6 @@
|
||||||
use crate::display::Display;
|
use crate::display::Display;
|
||||||
use crate::instruction::{Instruction, ProcessorInstruction};
|
use crate::instruction::{Instruction, ProcessorInstruction};
|
||||||
|
use crate::sound::SoundModule;
|
||||||
use crate::stack::Stack;
|
use crate::stack::Stack;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use log::{debug, info, trace, warn};
|
use log::{debug, info, trace, warn};
|
||||||
|
@ -38,9 +39,10 @@ const FONT_SPRITES: [u8; 80] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Emulator emulates the Chip8 CPU.
|
/// Emulator emulates the Chip8 CPU.
|
||||||
pub struct Emulator<D>
|
pub struct Emulator<D, S>
|
||||||
where
|
where
|
||||||
D: Display,
|
D: Display,
|
||||||
|
S: SoundModule,
|
||||||
{
|
{
|
||||||
/// Memory represents the emulator's memory.
|
/// Memory represents the emulator's memory.
|
||||||
memory: [u8; MEMORY_SIZE],
|
memory: [u8; MEMORY_SIZE],
|
||||||
|
@ -59,23 +61,27 @@ where
|
||||||
stack_pointer: u8,
|
stack_pointer: u8,
|
||||||
/// The display_data holds all the data associated with the display
|
/// The display_data holds all the data associated with the display
|
||||||
display: D,
|
display: D,
|
||||||
|
/// The sound module for making sounds.
|
||||||
|
sound_module: S,
|
||||||
/// The stack of the emulator.
|
/// The stack of the emulator.
|
||||||
stack: Stack<u16>,
|
stack: Stack<u16>,
|
||||||
/// Holds the display data, each bit corresponds to a pixel.
|
/// Holds the display data, each bit corresponds to a pixel.
|
||||||
display_data: [bool; DISPLAY_WIDTH * DISPLAY_HEIGHT],
|
display_data: [bool; DISPLAY_WIDTH * DISPLAY_HEIGHT],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> Emulator<D>
|
impl<D, S> Emulator<D, S>
|
||||||
where
|
where
|
||||||
D: Display,
|
D: Display,
|
||||||
|
S: SoundModule,
|
||||||
{
|
{
|
||||||
/// Creates a new `Emulator` instance.
|
/// Creates a new `Emulator` instance.
|
||||||
///
|
///
|
||||||
pub fn new(display: D) -> Emulator<D> {
|
pub fn new(display: D, sound_module: S) -> Emulator<D, S> {
|
||||||
let mut emulator = Emulator {
|
let mut emulator = Emulator {
|
||||||
memory: [0; MEMORY_SIZE],
|
memory: [0; MEMORY_SIZE],
|
||||||
registers: [0; NUMBER_OF_REGISTERS],
|
registers: [0; NUMBER_OF_REGISTERS],
|
||||||
display,
|
display,
|
||||||
|
sound_module,
|
||||||
index_register: 0,
|
index_register: 0,
|
||||||
program_counter: 0,
|
program_counter: 0,
|
||||||
delay_timer: 0,
|
delay_timer: 0,
|
||||||
|
@ -153,7 +159,7 @@ where
|
||||||
|
|
||||||
/// Should make an audible beep.
|
/// Should make an audible beep.
|
||||||
fn do_beep(&mut self) {
|
fn do_beep(&mut self) {
|
||||||
// beep, for now
|
self.sound_module.beep();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes the instruction
|
/// Executes the instruction
|
||||||
|
@ -435,11 +441,12 @@ where
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::display::TerminalDisplay;
|
use crate::display::TerminalDisplay;
|
||||||
|
use crate::sound::TerminalSound;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_load_font_data() {
|
fn test_load_font_data() {
|
||||||
let emulator = Emulator::new(TerminalDisplay::new());
|
let emulator = Emulator::new(TerminalDisplay::new(), TerminalSound);
|
||||||
assert_eq!(emulator.memory[0xf0..0xf0 + 80], FONT_SPRITES)
|
assert_eq!(emulator.memory[0xf0..0xf0 + 80], FONT_SPRITES)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +459,7 @@ mod tests {
|
||||||
.expect("Failed to read test ROM");
|
.expect("Failed to read test ROM");
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
let mut emulator = Emulator::new(TerminalDisplay::new());
|
let mut emulator = Emulator::new(TerminalDisplay::new(), TerminalSound);
|
||||||
emulator
|
emulator
|
||||||
.load_rom("roms/ibm-logo.ch8")
|
.load_rom("roms/ibm-logo.ch8")
|
||||||
.expect("failed to load ROM");
|
.expect("failed to load ROM");
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
use crate::display::RatatuiDisplay;
|
use crate::display::RatatuiDisplay;
|
||||||
use crate::emulator::Emulator;
|
use crate::emulator::Emulator;
|
||||||
|
use crate::sound::TerminalSound;
|
||||||
use env_logger;
|
use env_logger;
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
mod emulator;
|
mod emulator;
|
||||||
mod input;
|
mod input;
|
||||||
mod instruction;
|
mod instruction;
|
||||||
|
mod sound;
|
||||||
mod stack;
|
mod stack;
|
||||||
|
|
||||||
fn main() -> Result<(), anyhow::Error> {
|
fn main() -> Result<(), anyhow::Error> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let mut emulator = Emulator::new(RatatuiDisplay::new());
|
let mut emulator = Emulator::new(RatatuiDisplay::new(), TerminalSound);
|
||||||
|
|
||||||
emulator.emulate(String::from("./roms/3-corax+.ch8"))?;
|
emulator.emulate(String::from("./roms/3-corax+.ch8"))?;
|
||||||
|
|
||||||
|
|
14
src/sound.rs
Normal file
14
src/sound.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/// SoundModule represents a module which can produce sound.
|
||||||
|
pub trait SoundModule {
|
||||||
|
/// beep makes a beep sound.
|
||||||
|
fn beep(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TerminalSound is a simple module that makes terminal beep sound.
|
||||||
|
pub struct TerminalSound;
|
||||||
|
|
||||||
|
impl SoundModule for TerminalSound {
|
||||||
|
fn beep(&mut self) {
|
||||||
|
print!("\x07");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue