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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [tools/] [bin/] [create_disk] - Blame information for rev 25

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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