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 )