Commit | Line | Data |
---|---|---|
e007e1c9 MW |
1 | #! /usr/bin/perl |
2 | ||
3 | use autodie; | |
4 | ||
5 | sub intify ($) { | |
6 | my ($n) = @_; | |
7 | if ($n =~ /^0/) { $n = oct $n; } | |
8 | return $n; | |
9 | } | |
10 | ||
11 | my $MEM = ""; | |
12 | my $BASE = 0x4009; | |
13 | my $LIMIT = 0x8000; | |
14 | ||
15 | for my $a (@ARGV) { | |
16 | $a =~ /^(\w+):(.*)$/ or die "bad spec ADDR:FILE"; | |
17 | my $addr = intify $1; | |
18 | my $file = $2; | |
19 | ||
20 | my $body = ""; | |
21 | open my $fh, "<", $file; | |
22 | READ: for (;;) { | |
23 | sysread $fh, my $buf, 4096; | |
24 | last READ unless length $buf; | |
25 | $body .= $buf; | |
26 | } | |
27 | close $fh; | |
28 | ||
29 | $addr >= $BASE && $LIMIT >= $addr + length $body | |
30 | or die "out of bounds"; | |
31 | ||
32 | $addr -= $BASE; | |
33 | my $end = $addr + length $body; | |
34 | my $before = $addr > length $MEM | |
35 | ? $MEM . "\0" x ($addr - length $MEM) | |
36 | : substr $MEM, 0, $addr; | |
37 | my $after = $end <= length $MEM | |
38 | ? "" | |
39 | : substr $MEM, $end; | |
40 | $MEM = $before . $body . $after; | |
41 | } | |
42 | ||
43 | syswrite STDOUT, $MEM; |