OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [tools/] [bin/] [create_disk] - Blame information for rev 38

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 22 wfjm
#!/usr/bin/perl -w
2 32 wfjm
# $Id: create_disk 692 2015-06-21 11:53:24Z mueller $
3 22 wfjm
#
4 25 wfjm
# Copyright 2013-2014 by Walter F.J. Mueller 
5 22 wfjm
#
6
# This program is free software; you may redistribute and/or modify it under
7
# the terms of the GNU General Public License as published by the Free
8
# Software Foundation, either version 2, or at your option any later version.
9
#
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
12
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
# for complete details.
14
#
15
#  Revision History:
16
# Date         Rev Version  Comment
17 32 wfjm
# 2015-06-21   692   1.1.2  use sysseek rather seek; add RM80
18 30 wfjm
# 2015-04-06   665   1.1.1  add alias RM03 (for RM02) and RP05 (for RP04)
19 25 wfjm
# 2014-06-14   562   1.1    BUGFIX: repair --boot; add RM02,RM05,RP04,RP07
20 22 wfjm
# 2013-05-20   521   1.0    First draft
21
#
22
 
23
use 5.10.0;                                 # require Perl 5.10 or higher
24
use strict;                                 # require strict checking
25
 
26
use Getopt::Long;
27
use FileHandle;
28
use Fcntl qw(:seek);
29
 
30
my %opts = ();
31
 
32
GetOptions(\%opts, "help", "typ=s", "ini=s", "bad", "boot"
33
          )
34
  or exit 1;
35
 
36
sub do_inipatt;
37
sub do_badtable;
38 25 wfjm
sub do_boot;
39 22 wfjm
sub print_help;
40
 
41
# disk type table
42
my %disktype = (
43
  RK05 => {cyl=> 203, hd=>   2, sec=>  12, bps=> 512, bad=>0},
44
  RL01 => {cyl=> 256, hd=>   2, sec=>  40, bps=> 256, bad=>1},
45
  RL02 => {cyl=> 512, hd=>   2, sec=>  40, bps=> 256, bad=>1},
46 32 wfjm
  RM03 => {cyl=> 823, hd=>   5, sec=>  32, bps=> 512, bad=>1},
47 25 wfjm
  RM05 => {cyl=> 823, hd=>  19, sec=>  32, bps=> 512, bad=>1},
48 31 wfjm
  RM80 => {cyl=> 559, hd=>  14, sec=>  31, bps=> 512, bad=>1},
49 32 wfjm
  RP05 => {cyl=> 411, hd=>  19, sec=>  22, bps=> 512, bad=>1},
50 25 wfjm
  RP06 => {cyl=> 815, hd=>  19, sec=>  22, bps=> 512, bad=>1},
51
  RP07 => {cyl=> 630, hd=>  32, sec=>  50, bps=> 512, bad=>1}
52 22 wfjm
);
53
 
54
autoflush STDOUT 1 if (-p STDOUT);          # autoflush if output into pipe
55
 
56
if (exists $opts{help}) {
57
  print_help(1);
58
  exit 0;
59
}
60
 
61
if (scalar(@ARGV) != 1) {
62
  print STDERR "create_disk-E: specify one and only one output file\n";
63
  print_help(0);
64
  exit 1;
65
}
66
 
67
my $fnam = shift @ARGV;
68
 
69
if (-e $fnam) {
70
  print STDERR "create_disk-E: file '$fnam' exists already\n";
71
  exit 1;
72
}
73
 
74
my $typ = uc($opts{typ});
75 30 wfjm
 
76 32 wfjm
$typ = "RM03" if defined $typ && $typ eq "RM02"; # RM02 is equivalent to RM03
77
$typ = "RP05" if defined $typ && $typ eq "RP04"; # RM04 is equivalent to RP05
78 30 wfjm
 
79 22 wfjm
unless (defined $typ && exists $disktype{$typ}) {
80
  print STDERR "create_disk-E: no or invalid --typ specification, use --help\n";
81
  exit 1;
82
}
83
 
84
my $cyl = $disktype{$typ}{cyl};
85
my $hd  = $disktype{$typ}{hd};
86
my $sec = $disktype{$typ}{sec};
87
my $bps = $disktype{$typ}{bps};
88
my $bad = $disktype{$typ}{bad};
89
 
90
if ($opts{bad} && !$bad) {
91
  print STDERR "create_disk-E: --bad not supported for type '$typ', abort\n";
92
  exit 1;
93
}
94
 
95
my $nblk = $cyl*$hd*$sec;
96
my $cap  = $nblk * $bps;
97
 
98
my $fh = new FileHandle;
99
sysopen($fh, $fnam, O_RDWR|O_CREAT)
100
  or die "failed to create '$fnam': $!";
101
 
102 31 wfjm
# seek to end, write 1 byte at end
103
my $rc = sysseek($fh, $cap-1, SEEK_SET);
104 22 wfjm
if (not $rc) {die "seek failed: $!";}
105
my $buf = pack('C1',0);
106
$rc = syswrite($fh, $buf, length($buf));
107
if ($rc<=0) {die "write failed: $!";}
108
 
109
# handle init patterns
110
do_inipatt if $opts{ini};
111
 
112
# handle factory bad block table
113
do_badtable if $opts{bad};
114
 
115
# write dummy boot block
116 25 wfjm
do_boot if $opts{boot};
117 22 wfjm
 
118
#-------------------------------------------------------------------------------
119
 
120
sub do_inipatt {
121
  my $ini = $opts{ini};
122
 
123 31 wfjm
  if ($ini eq 'zero' || $ini eq 'ones' || $ini eq 'dead') {
124 22 wfjm
    my @dat;
125
    for (my $i=0; $i<$bps/4; $i++) {
126
      push @dat, 0,0            if $ini eq 'zero';
127
      push @dat, -1,-1          if $ini eq 'ones';
128
      push @dat, 0xdead,0xbeaf  if $ini eq 'dead';
129
    }
130
    my $buf = pack('v*',@dat);
131 32 wfjm
    my $rc = sysseek($fh, 0, SEEK_SET);
132 22 wfjm
    if (not $rc) {die "seek failed: $!";}
133
    for (my $i=0; $i<$nblk; $i++) {
134
      $rc = syswrite($fh, $buf, length($buf));
135
      if ($rc<=0) {die "write failed: $!";}
136
    }
137
 
138
  } elsif ($ini eq 'test') {
139
    my $addr = 0;
140
    my $cur_sec = 0;
141
    my $cur_trk = 0;
142
    my $cur_cyl = 0;
143 32 wfjm
    my $rc = sysseek($fh, 0, SEEK_SET);
144 22 wfjm
    if (not $rc) {die "seek failed: $!";}
145
    for (my $i=0; $i<$nblk; $i++) {
146
      my @dat;
147
      for (my $i=0; $i<$bps/16; $i++) {
148
        push @dat, ($addr & 0xffff);
149
        push @dat, (($addr>>16) & 0xffff);
150
        push @dat, $cur_cyl, $cur_trk, $cur_sec;
151
        push @dat, $cyl, $hd, $sec;
152
        $addr += 16;
153
      }
154
      my $buf = pack('v*',@dat);
155
      $rc = syswrite($fh, $buf, length($buf));
156
      if ($rc<=0) {die "write failed: $!";}
157
      $cur_sec += 1;
158
      if ($cur_sec >= $sec) {
159
        $cur_sec = 0;
160
        $cur_trk += 1;
161
        if ($cur_trk >= $hd) {
162
          $cur_trk = 0;
163
          $cur_cyl += 1;
164
        }
165
      }
166
    }
167
 
168
  } else {
169
    print STDERR "create_disk-W: unknown --ini mode '$ini', --ini ignored\n";
170
  }
171
  return;
172
}
173
 
174
#-------------------------------------------------------------------------------
175
 
176
sub do_badtable {
177
  my @dat;
178
  push @dat, 012345, 012345;                # pack number
179
  push @dat, 0,0;                           # dummy c/s/h spec
180
  for (my $i=4; $i<$bps/2; $i++) {
181
    push @dat, -1;                          # end of table
182
  }
183
  my $buf = pack('v*',@dat);
184
 
185
  my $pos = $cap - $sec*$bps;               # position of last track
186 32 wfjm
  my $rc = sysseek($fh, $pos, SEEK_SET);
187 22 wfjm
  if (not $rc) {die "seek failed: $!";}
188
  my $nsec = ($sec > 10) ? 10 : $sec;       # write last track, at most 10 sec
189
  for (my $i=0; $i<$nsec; $i++) {
190
    $rc = syswrite($fh, $buf, length($buf));
191
    if ($rc<=0) {die "write failed: $!";}
192
  }
193
  return;
194
}
195
 
196
#-------------------------------------------------------------------------------
197
 
198 25 wfjm
sub do_boot {
199 22 wfjm
  my @dat;
200
 
201
  push @dat, 0012700, 0000100;    #         start:  mov     #text, r0
202
  push @dat, 0105710;             #         1$:     tstb    (r0)
203
  push @dat, 0001406;             #                 beq     3$
204
  push @dat, 0105737, 0177564;    #         2$:     tstb    @#XCSR
205
  push @dat, 0100375;             #                 bpl     2$
206
  push @dat, 0112037, 0177566;    #                 movb    (r0)+,@#XBUF
207
  push @dat, 0000770;             #                 br      1$
208
  push @dat, 0000000;             #         3$:     halt
209
 
210
  my $buf = pack('v*',@dat);
211 32 wfjm
  my $rc = sysseek($fh, 0, SEEK_SET);
212 22 wfjm
  if (not $rc) {die "seek failed: $!";}
213
  $rc = syswrite($fh, $buf, length($buf));
214
  if ($rc<=0) {die "write failed: $!";}
215
 
216
  $buf  = "\r\n";
217
  $buf .= "\r\n";
218
  $buf .= "++======================================++\r\n";
219
  $buf .= "|| This is not a hardware bootable disk ||\r\n";
220
  $buf .= "++======================================++\r\n";
221
  $buf .= "\r\n";
222
  $buf .= "Disk image created with 'create_disk --typ=$typ':\r\n";
223 30 wfjm
  $buf .= sprintf "  number of cylinders:    %7d\r\n", $cyl;
224
  $buf .= sprintf "  tracks per cylinder:    %7d\r\n", $hd;
225
  $buf .= sprintf "  sectors per track:      %7d\r\n", $sec;
226
  $buf .= sprintf "  block size:             %7d\r\n", $bps;
227
  $buf .= sprintf "  total number of sectors:%7d\r\n", $nblk;
228
  $buf .= sprintf "  capacity in kByte:      %7d\r\n", $cap/1024;
229 22 wfjm
  $buf .= "\r\n";
230
  $buf .= "CPU WILL HALT\r\n";
231
  $buf .= "\r\n";
232
 
233
  # NOTE: the text above almost fills the first 512 bytes !!
234 25 wfjm
  #       don't add more text, all has been said anyway   !!
235 22 wfjm
 
236 32 wfjm
  $rc = sysseek($fh ,0100, SEEK_SET);
237 22 wfjm
  if (not $rc) {die "seek failed: $!";}
238
  $rc = syswrite($fh, $buf, length($buf));
239
  if ($rc<=0) {die "write failed: $!";}
240
 
241
  return;
242
}
243
 
244
#-------------------------------------------------------------------------------
245
 
246
sub print_help {
247
  my ($ptyp) = @_;
248
  print "usage: create_disk [options] \n";
249
  print "  --typ=  specified disk type, must be specified\n";
250
  print "  --ini=   initialization pattern, can be\n";
251
  print "  --bad         create factory bad block table on last track\n";
252
  print "  --boot        write dummy boot block, print volume info and HALT\n";
253
  print "  --help        print full help, with list --typ and --ini options\n";
254
  return unless $ptyp;
255
 
256
  print "\n";
257
  print "currently supported disk types:\n";
258
  print "  type #cyl #trk #sec  bps tot_sec  blocks  -bad\n";
259
  foreach my $typ (sort keys %disktype) {
260
    my $cyl = $disktype{$typ}{cyl};
261
    my $hd  = $disktype{$typ}{hd};
262
    my $sec = $disktype{$typ}{sec};
263
    my $bps = $disktype{$typ}{bps};
264
    printf "  %4s %4d %4d %4d %4d %7d %7d   %3s\n",
265
      $typ, $cyl, $hd, $sec, $bps,
266
      ($cyl*$hd*$sec), ($cyl*$hd*$sec*$bps)/1024,
267
      ($disktype{$typ}{bad} ? 'yes' : ' no');
268
  }
269
 
270
  print "\n";
271 32 wfjm
  print "  RM02 is accepted as an alias for RM03 (same capacity)\n";
272
  print "  RP04 is accepted as an alias for RP05 (same capacity)\n";
273 30 wfjm
 
274
  print "\n";
275 22 wfjm
  print "currently supported initialization patterns:\n";
276 31 wfjm
  print "  zero  all zero (will cause explicit disk space allocation)\n";
277 22 wfjm
  print "  ones  all ones\n";
278
  print "  dead  alternating 0xdead 0xbeaf pattern\n";
279
  print "  test  writes unique groups of 8 16bit words\n";
280
  print "\n";
281
  print "For further details consults the create_disk man page.\n";
282
  return;
283
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.