pub trait Io {
type Timestamp: Sized;
type WrIoBreak;
type RetiBreak;
fn read_io(
&mut self,
port: u16,
timestamp: Self::Timestamp
) -> (u8, Option<NonZeroU16>) { ... }
fn write_io(
&mut self,
port: u16,
data: u8,
timestamp: Self::Timestamp
) -> (Option<Self::WrIoBreak>, Option<NonZeroU16>) { ... }
fn is_irq(&mut self, timestamp: Self::Timestamp) -> bool { ... }
fn irq_data(
&mut self,
pc: u16,
timestamp: Self::Timestamp
) -> (u8, Option<NonZeroU16>) { ... }
fn reti(
&mut self,
address: u16,
timestamp: Self::Timestamp
) -> Option<Self::RetiBreak> { ... }
}
Expand description
This trait defines an interface for handling data provided to IN
or from OUT
instruction
families and maskable interrupts.
Please see also cycles.
Required Associated Types§
sourcetype Timestamp: Sized
type Timestamp: Sized
This type is being used for timestamping I/O operations. See also Clock::Timestamp.
sourcetype WrIoBreak
type WrIoBreak
A value of this type is returned when a break is being requested by Io::write_io.
Provided Methods§
sourcefn read_io(
&mut self,
port: u16,
timestamp: Self::Timestamp
) -> (u8, Option<NonZeroU16>)
fn read_io(
&mut self,
port: u16,
timestamp: Self::Timestamp
) -> (u8, Option<NonZeroU16>)
Called during the IO_IORQ
cycle when executing one of the IN
instructions.
Should return a single byte from the emulated device at the given port
and the optional
number of wait states to be inserted during the IO_IORQ
cycle.
The timestamp
given here has been previously returned from Clock::add_io.
This method is being used by the Cpu to read data from the I/O port.
The default implementation returns (u8::MAX, None)
.
sourcefn write_io(
&mut self,
port: u16,
data: u8,
timestamp: Self::Timestamp
) -> (Option<Self::WrIoBreak>, Option<NonZeroU16>)
fn write_io(
&mut self,
port: u16,
data: u8,
timestamp: Self::Timestamp
) -> (Option<Self::WrIoBreak>, Option<NonZeroU16>)
Called during the IO_IORQ
cycle when executing one of the OUT
instructions.
Should write a single data
byte to the device at the given port
.
The timestamp
given here has been previously returned from Clock::add_io.
Returning Some(Self::WrIoBreak)
from this method is a request to break the execution after
the currently executed instruction completes.
See Cpu::execute_with_limit.
The returned tuple’s second argument is an optional number of wait states to be inserted
during the IO_IORQ
cycle.
This method is being used by the Cpu to write data to the I/O port.
The default implementation returns (None, None)
.
sourcefn is_irq(&mut self, timestamp: Self::Timestamp) -> bool
fn is_irq(&mut self, timestamp: Self::Timestamp) -> bool
Should return true
if the interrupt request signal - the INT
line - is active.
The timestamp
given here has been previously returned from the Clock::as_timestamp method.
Look at the diagrams in the cycles module for the information when exactly, in the execution cycle, this method is being called.
The default implementation returns false
.
sourcefn irq_data(
&mut self,
pc: u16,
timestamp: Self::Timestamp
) -> (u8, Option<NonZeroU16>)
fn irq_data(
&mut self,
pc: u16,
timestamp: Self::Timestamp
) -> (u8, Option<NonZeroU16>)
Called during the INT_IORQ
cycle when the maskable interrupt has been requested and accepted.
Depending on the interrupt mode this method should return a tuple with its first argument being:
- IM 0: an opcode of a command to execute.
- IM 1: irrelevant as it is just being ignored.
- IM 2: the lower half of an address of the vector jump table entry.
The upper half of this address is being taken from the value of the register
I
.
In reality, during the INT_IORQ
cycle, a byte is being sampled from the data bus where an external
device places it while requesting an interrupt.
The returned tuple’s second argument is an optional number of wait states to be inserted
during the INT_IORQ
cycle.
The default implementation returns (RST_38H_OPCODE, None)
equalizing mode 0 to mode 1.
sourcefn reti(
&mut self,
address: u16,
timestamp: Self::Timestamp
) -> Option<Self::RetiBreak>
fn reti(
&mut self,
address: u16,
timestamp: Self::Timestamp
) -> Option<Self::RetiBreak>
When RETI
instruction is being executed this method is being called to update the device
implementation instance, so another interrupt signal can be set up if necessary.
This method is being called in the middle of the instruction execution, before the returning address is popped from the machine stack.
The given address
is pointing immediately after the RETI
instruction opcode.
The given timestamp
is taken after the RETI
instruction opcode was read but before popping
the return value from the stack. After calling this method the Clock counter will be
further increased 2 x
by the MEMRW cycles.
Returning Some(Self::RetiBreak)
from this method is a request to break the execution after
the execution of RETI
completes. See Cpu::execute_with_limit.
The default implementation returns None
.