#!/usr/bin/perl # # 8259A # use strict; use warnings; use Getopt::Std; sub outb { my $data = shift; my $port = shift; open(IO, "> /dev/port") || die "open /dev/port: $!\n"; sysseek(IO, $port, 0) || die; my $x = pack("C", $data); syswrite(IO, $x, 1); close(IO); } sub inb { my $port = shift; my $data; open(IO, "/dev/port") || die "open /dev/port: $!\n"; sysseek(IO, $port, 0) || die; sysread(IO, $data, 1); close(IO); return unpack("C", $data); } sub set_edge_level { my $irq = shift; my $to = shift; my $mask = 1 << ($irq & 7); my $port = 0x4d0 + ($irq >> 3); my $val = inb($port); if ($to eq "edge") { outb($val & ~$mask, $port); } else { outb($val | $mask, $port); } print "irq $irq: -> $to\n"; } our($opt_e, $opt_l); getopts('e:l:'); if ($opt_e and ($opt_e < 15)) { set_edge_level($opt_e, "edge"); } elsif ($opt_l and ($opt_l < 15)) { set_edge_level($opt_l, "level"); } foreach my $irq (0..15) { my $mask = 1 << ($irq & 7); my $port = 0x4d0 + ($irq >> 3); my $val = inb($port); printf "irq %d: %02x, %s\n", $irq, $val, ($val & $mask) ? "level" : "edge"; }