CPU-Emulator-Z80
view release on metacpan or search on metacpan
lib/CPU/Emulator/Z80/Manual.pod view on Meta::CPAN
=item C - carry
=back
and also the undocumented bits 3 and 5 of the register:
=over
=item 3 - bit 3 (with the least-significant bit being bit 0)
=item 5 - bit 5
=back
It's worth noting that bits 3 and 5 are emulated correctly, so
don't go storing anything in them that you care about.
=head1 I/O and INTERRUPTS
=head2 INTERRUPTS
For now, only IM 1 and NMIs are supported. You can generate a
non-maskable interrupt using the nmi() method, and a maskable
interrupt using the interrupt() method.
The nmi() method will execute a CALL 0x0066 immediately after
the current instruction has completed. Note that maskable
interrupts are disabled until either an EI instruction or you reach
RETN, at which point maskable interrupts will be restored to whatever
state they were in when nmi() was called.
If maskable interrupts are enabled (they are disabled at power-on)
then the interrupt() method will return true, and the next
instructions will be DI and RST 0x38. You will need to re-enable
interrupts at the earliest opportunity in your interrupt handler.
Because only IM 1 is supported, interrupts can't tell the CPU what
to do. This means that you'll have to write your own interrupt
handler that polls any I/O devices you have defined.
Given that interrupts need to be generated by calling a method from
perl, and that the run() method doesn't normally return, you will
need to find some way of generating them asychronously.
=head2 INPUT
You can create an input device using the add_input_device() method.
=head2 OUTPUT
You can create an output device using the add_output_device() method.
=head2 AN EXAMPLE
Here's an example of how to make the keyboard available to the
emulator. It generates an interrupt every 0.1 seconds, and also
feeds key-presses into a buffer. The input function for port 0xC001
in the emulator will return values from that buffer, and that for
port 0xC000 will return how many values are in the buffer.
use Time::HiRes qw(setitimer ITIMER_REAL);
use Term::ReadKey;
...
my @kb_buffer;
$cpu->add_input_device(
address => 0xC000,
function => sub { $#kb_buffer + 1 }
);
$cpu->add_input_device(
address => 0xC001,
function => sub { shift(@kb_buffer) || 0 }
);
setitimer(ITIMER_REAL, 1, 0.1); # after 1 sec, int every 0.1 sec
$SIG{ALRM} = sub {
my $key = ReadKey(-1);
push @kb_buffer, $key if($key);
$cpu->interrupt();
};
ReadMode 'noecho';
ReadMode 'cbreak';
$cpu->run();
$SIG{ALRM} = 'IGNORE';
ReadMode'normal';
=head1 SEE ALSO
L<CPU::Emulator::Z80>
L<CPU::Emulator::Memory>
L<CPU::Z80::Assembler>
=head1 AUTHOR, LICENCE and COPYRIGHT
Copyright 2008 David Cantrell E<lt>F<david@cantrell.org.uk>E<gt>
This documentation is free-as-in-speech. It may be used,
distributed and modified under the terms of the Creative Commons
Attribution-Share Alike 2.0 UK: England & Wales License, whose
text you may read at
L<http://creativecommons.org/licenses/by-sa/2.0/uk/>.
=head1 CONSPIRACY
This is also free-as-in-mason documentation.
=cut
( run in 2.087 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )