mirror of
https://github.com/softwarejanitor/DOS33.git
synced 2024-11-08 19:07:55 +00:00
132 lines
3.2 KiB
Perl
132 lines
3.2 KiB
Perl
#!/usr/bin/perl -w
|
|
|
|
#
|
|
# zap.pl:
|
|
#
|
|
# Utility to edit a DOS 3.3 sector (.DSK or .DO disk image).
|
|
#
|
|
# 20190115 LSH
|
|
#
|
|
|
|
use strict;
|
|
|
|
use DSK;
|
|
|
|
my $debug = 0;
|
|
|
|
my $trk = -1;
|
|
my $sec = -1;
|
|
my $dst_trk = -1;
|
|
my $dst_sec = -1;
|
|
my $write = 0;
|
|
|
|
my @mods = ();
|
|
|
|
while (defined $ARGV[0] && $ARGV[0] =~ /^-/) {
|
|
# Debug
|
|
if ($ARGV[0] eq '-d') {
|
|
$debug = 1;
|
|
shift;
|
|
# Track
|
|
} elsif ($ARGV[0] eq '-t' && defined $ARGV[1] && $ARGV[1] =~ /^\d+$/) {
|
|
$trk = $ARGV[1];
|
|
shift;
|
|
shift;
|
|
# Sector
|
|
} elsif ($ARGV[0] eq '-s' && defined $ARGV[1] && $ARGV[1] =~ /^\d+$/) {
|
|
$sec = $ARGV[1];
|
|
shift;
|
|
shift;
|
|
# Destination track
|
|
} elsif ($ARGV[0] eq '-dt' && defined $ARGV[1] && $ARGV[1] =~ /^\d+$/) {
|
|
$dst_trk = $ARGV[1];
|
|
shift;
|
|
shift;
|
|
# Destination sector
|
|
} elsif ($ARGV[0] eq '-ds' && defined $ARGV[1] && $ARGV[1] =~ /^\d+$/) {
|
|
$dst_sec = $ARGV[1];
|
|
shift;
|
|
shift;
|
|
# Allow modifying data.
|
|
} elsif ($ARGV[0] =~ /^-m([ahA])/ && defined $ARGV[1] && $ARGV[1] ne '') {
|
|
my $typ = $1;
|
|
print "$ARGV[1] typ=$typ\n" if $debug;
|
|
if ($ARGV[1] =~ /^([0-9a-fA-F]+):\s*(.+)$/) {
|
|
print "1=$1 2=$2\n" if $debug;
|
|
push @mods, { 'typ' => $typ, 'addr' => $1, 'vals' => $2 };
|
|
}
|
|
shift;
|
|
shift;
|
|
} elsif ($ARGV[0] eq "-w") {
|
|
$write = 1;
|
|
shift;
|
|
} else {
|
|
die "Unknown command line argument $ARGV[0]\n";
|
|
}
|
|
}
|
|
|
|
my $dskfile = shift or die "Must supply .dsk filename\n";
|
|
die "Must supply track number 0-35\n" unless $trk >= 0 && $trk <= 35;
|
|
die "Must supply sector number 0-16\n" unless $sec >= 0 && $sec <= 16;
|
|
|
|
$dst_trk = $trk unless $dst_trk >= 0;
|
|
$dst_sec = $sec unless $dst_sec >= 0;
|
|
|
|
my $buf;
|
|
|
|
if (rts($dskfile, $trk, $sec, \$buf)) {
|
|
# Display the data in the sector.
|
|
dump_sec($buf);
|
|
|
|
# Allow modifying data.
|
|
if ($write) {
|
|
print "WRITING $dst_trk $dst_sec\n" if $debug;
|
|
# Unpack the data in the sector.
|
|
my @bytes = unpack "C256", $buf;
|
|
|
|
foreach my $mod (@mods) {
|
|
my @mbytes = ();
|
|
if ($mod->{'typ'} eq 'a') {
|
|
print "ASCII vals=$mod->{'vals'}\n" if $debug;
|
|
# Normal ASCII
|
|
@mbytes = map { pack('C', ord($_)) } ($mod->{'vals'} =~ /(.)/g);
|
|
} elsif ($mod->{'typ'} eq 'A') {
|
|
print "HEX vals=$mod->{'vals'}\n" if $debug;
|
|
# Apple II ASCII
|
|
@mbytes = map { pack('C', ord($_) | 0x80) } ($mod->{'vals'} =~ /(.)/g);
|
|
} elsif ($mod->{'typ'} eq 'h') {
|
|
print "A2 ASCII vals=$mod->{'vals'}\n" if $debug;
|
|
# HEX
|
|
@mbytes = map { pack('C', hex(lc($_))) } ($mod->{'vals'} =~ /(..)/g);
|
|
}
|
|
my $addr = hex($mod->{'addr'});
|
|
print "addr=$addr\n" if $debug;
|
|
foreach my $byte (@mbytes) {
|
|
print sprintf("byte=%02x\n", ord($byte)) if $debug;
|
|
$bytes[$addr++] = ord($byte);
|
|
}
|
|
}
|
|
|
|
# Re-pack the data in the sector.
|
|
$buf = pack "C*", @bytes;
|
|
|
|
# Write the sector.
|
|
if (wts($dskfile, $dst_trk, $dst_sec, $buf)) {
|
|
# Read the sector back in.
|
|
if (rts($dskfile, $dst_trk, $dst_sec, \$buf)) {
|
|
# Display the data in the modified sector.
|
|
dump_sec($buf);
|
|
} else {
|
|
print "Failed final read!\n";
|
|
}
|
|
} else {
|
|
print "Failed write!\n";
|
|
}
|
|
}
|
|
} else {
|
|
print "Failed initial read!\n";
|
|
}
|
|
|
|
1;
|
|
|