Struct intel8080::CPU

source ·
pub struct CPU {
    pub reg: Registers,
    pub flags: Flags,
    pub pc: u16,
    pub sp: u16,
    pub bus: Bus,
    pub halt: bool,
    pub int: (bool, u8),
    pub inte: bool,
    pub debug: Debug,
    /* private fields */
}

Fields§

§reg: Registers§flags: Flags§pc: u16§sp: u16§bus: Bus§halt: bool§int: (bool, u8)

Interrupt request : true / false, instruction to execute (normally a RST command)

§inte: bool

Interrupt enable bit

§debug: Debug

Outputs CPU state and disassembled code to stdout after each execute()

3E 0f     MVI A,$0f
PC : 0x0003	SP : 0xff00	S : 0	Z : 0	A : 0	P : 0	C : 0
B : 0x00	C : 0x00	D : 0x00	E : 0x00	H : 0x00	L : 0x00 ...

Implementations§

source§

impl CPU

source

pub fn dasm(&self, address: u16) -> String

Disassembles code at (address)

source§

impl CPU

source

pub fn new() -> CPU

Creates a new CPU instance and its 16 bits address bus.

Examples found in repository?
examples/interrupt_test.rs (line 13)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
fn load_execute() -> Result<(), Box<dyn Error>> {
    let  a: Vec<String> = env::args().collect();
    let mut c = CPU::new();
    c.debug.switch = true;

    // Loads assembled program into memory
    c.bus.load_bin(&a[1], 0x000)?;

    c.sp = 0xff00;
    c.inte = false;
    c.int = (true, 0xcf);

    loop {
        c.execute();
        println!("{}\n", c.debug.string);
        if c.pc == 0x0000 { break }             //  if CP/M warm boot -> we exit
    }
    Ok(())
}
More examples
Hide additional examples
examples/cpmloader.rs (line 13)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
fn load_execute() -> Result<(), Box<dyn Error>> {
    let  a: Vec<String> = env::args().collect();
    let mut c = CPU::new();
    // Loads assembled program into memory
    c.bus.load_bin(&a[1], 0x100)?;
    
    // RET at 0x05 for mocking of CP/M BDOS system calls
    c.bus.write_word(0x0005, 0xc9);

    // Setting PC to 0x0100 (CP/M Binaries are loaded with a 256 byte offset)
    c.pc = 0x0100;

    /* Setting up stack : by disassembling CP/M software, it seems
    that the $0006 address is read to set the stack by some programs */
    c.bus.write_word(0x0006, 0xFF00);
    
    /* Setting up stack in case of the program does not read the $0006 address
    and does not set any stack. */
    c.sp = 0xFF00;

    loop {
        c.execute();
        if c.pc == 0x0005 { bdos_call(&c) }
        if c.pc == 0x0000 { break }             //  if CP/M warm boot -> we exit
    }
    Ok(())
}
source

pub fn set_freq(&mut self, f: f32)

Sets CPU frequency (MHz)

use intel8080::CPU;
let mut c = CPU::new();
c.set_freq(1.7);            // CPU will run at 1.7 Mhz
source

pub fn execute_timed(&mut self) -> Option<u32>

Fetches and executes one instruction from (pc). Returns the sleep time when slice_max_cycles is reached.

source

pub fn execute(&mut self) -> u32

Fetches and executes one instruction from (pc). Returns the number of consumed clock cycles. No execution speed limit.

Examples found in repository?
examples/interrupt_test.rs (line 24)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
fn load_execute() -> Result<(), Box<dyn Error>> {
    let  a: Vec<String> = env::args().collect();
    let mut c = CPU::new();
    c.debug.switch = true;

    // Loads assembled program into memory
    c.bus.load_bin(&a[1], 0x000)?;

    c.sp = 0xff00;
    c.inte = false;
    c.int = (true, 0xcf);

    loop {
        c.execute();
        println!("{}\n", c.debug.string);
        if c.pc == 0x0000 { break }             //  if CP/M warm boot -> we exit
    }
    Ok(())
}
More examples
Hide additional examples
examples/cpmloader.rs (line 32)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
fn load_execute() -> Result<(), Box<dyn Error>> {
    let  a: Vec<String> = env::args().collect();
    let mut c = CPU::new();
    // Loads assembled program into memory
    c.bus.load_bin(&a[1], 0x100)?;
    
    // RET at 0x05 for mocking of CP/M BDOS system calls
    c.bus.write_word(0x0005, 0xc9);

    // Setting PC to 0x0100 (CP/M Binaries are loaded with a 256 byte offset)
    c.pc = 0x0100;

    /* Setting up stack : by disassembling CP/M software, it seems
    that the $0006 address is read to set the stack by some programs */
    c.bus.write_word(0x0006, 0xFF00);
    
    /* Setting up stack in case of the program does not read the $0006 address
    and does not set any stack. */
    c.sp = 0xFF00;

    loop {
        c.execute();
        if c.pc == 0x0005 { bdos_call(&c) }
        if c.pc == 0x0000 { break }             //  if CP/M warm boot -> we exit
    }
    Ok(())
}

Auto Trait Implementations§

§

impl RefUnwindSafe for CPU

§

impl Send for CPU

§

impl Sync for CPU

§

impl Unpin for CPU

§

impl UnwindSafe for CPU

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.