CPU-Emulator-Z80

 view release on metacpan or  search on metacpan

example/machine.pl  view on Meta::CPAN

#!/usr/local/bin/perl -w

use strict;

use CPU::Emulator::Z80;
use Time::HiRes qw(setitimer ITIMER_VIRTUAL ITIMER_REAL);
use Term::ReadKey;
use IO::Scalar;
use Data::Dumper;

my $cpu = CPU::Emulator::Z80->new( # RAM is 64K of zeroes
    ports => 256,
);
my $clock = 0; # clock isn't running
my @banks = (
    {

example/machine.pl  view on Meta::CPAN

    }
);
$cpu->memory()->bank(%{$banks[0]}); # boot loader
$cpu->memory()->bank(%{$banks[1]}); # OS

$cpu->add_output_device(address => 0x00, function => \&mem_bank);
$cpu->add_output_device(address => 0x01, function => \&mem_unbank);
$cpu->add_output_device(address => 0x02, function => \&io_wr_stdout);
$cpu->add_output_device(address => 0xFF, function => \&hw_start_clock);

setitimer(ITIMER_VIRTUAL, 1, 1);
# setitimer(ITIMER_REAL, 1, 0.2);
$SIG{VTALRM} = sub {
# $SIG{ALRM} = sub {
    my $key = ReadKey(-1);
    if($key) {
        # print "Got char $key\n";
    }
    $cpu->interrupt() if($clock);
};

ReadMode 'noecho';

interrupt-HOWTO  view on Meta::CPAN

#!/usr/local/bin/perl -w

use strict;

use CPU::Emulator::Z80;
use Time::HiRes qw(setitimer ITIMER_REAL);
use Term::ReadKey;

my $cpu = CPU::Emulator::Z80->new();

setitimer(ITIMER_REAL, 1, 0.01); # after 1 sec, interrupt every sec
# setitimer(ITIMER_VIRTUAL, 1, 1); # after 1 sec, interrupt every sec
# $SIG{VTALRM} = sub {
$SIG{ALRM} = sub {
    ReadMode 'cbreak';
    my $key = ReadKey(-1);
    if($key) {
        print "Got char $key\n";
    }
    $cpu->interrupt();
};

lib/CPU/Emulator/Z80/Manual.pod  view on Meta::CPAN

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';



( run in 1.319 second using v1.01-cache-2.11-cpan-49f99fa48dc )