diff --git a/build/unixv0.simh b/build/unixv0.simh index 79ff03c..ddd4927 100644 --- a/build/unixv0.simh +++ b/build/unixv0.simh @@ -1,5 +1,11 @@ +set cpu 8k +set cpu eae +set cpu history=100 +show cpu + set rb ena att rb image.fs -load -S a.rim show dev + +load -S a.rim dep pc 0100 diff --git a/src/sys/sop.s b/src/sys/sop.s index 047a1ba..ada9499 100644 --- a/src/sys/sop.s +++ b/src/sys/sop.s @@ -39,7 +39,7 @@ lls = 0640600 " EAE: long left shift llss = 0660600 " EAE: long left shift, signed als = 0640700 " EAE: AC left shift alss = 0660700 " EAE: AC left shift, signed -mul = 0653323 " EAE: multiply +mul = 0653122 " EAE: multiply idiv = 0653323 " EAE: integer divide lacq = 0641002 " EAE: load AC with MQ clq = 0650000 " EAE: clear MQ diff --git a/tools/mkfs7 b/tools/mkfs7 index 96b6ae1..e295813 100755 --- a/tools/mkfs7 +++ b/tools/mkfs7 @@ -14,17 +14,13 @@ Getopt::Long::Configure qw(gnu_getopt); # Constants use constant NUMBLOCKS => 8000; # Number of blocks on a surface use constant WORDSPERBLK => 64; # 64 words per block -use constant NUMINODEBLKS => 710; # Blocks 1 to 710 for i-nodes -#use constant FIRSTINODEBLK => 1; # First i-node block number +use constant NUMINODEBLKS => 710; # Number of i-nodes use constant FIRSTINODEBLK => 2; # First i-node block number use constant INODESIZE => 12; # Size of an i-node use constant INODESPERBLK => int(WORDSPERBLK / INODESIZE); use constant DIRENTSIZE => 8; # Size of an directory entry use constant DIRENTSPERBLK => WORDSPERBLK / DIRENTSIZE; -use constant ROOT_UID => -1; # Native root user-id -use constant MAXINT => 0777777; # Biggest unsigned integer - use constant DD_INUM => 2; # I-number of the dd directory # i-node field offsets @@ -148,8 +144,7 @@ sub fill_inode { my ( $inum, $perms, $filetype, $uid, $size, @blklist ) = @_; die("Too many blocks\n") if ( @blklist > 7 ); - # Deal with the root user-id - $uid = MAXINT if ( $uid == ROOT_UID ); + $uid &= 0777777; # truncate negative UID to 18 bits # Calculate the block number and word offset for this $inum = allocate_inode() if ( !defined($inum) ); @@ -176,6 +171,12 @@ sub fill_inode { return ($inum); } +sub increment_file_length { + my ( $inum, $incr) = @_; + my ( $blocknum, $offset ) = get_inode_block_offset($inum); + $Block[$blocknum][ $offset + I_SIZE ] += $incr; +} + # Convert an ASCII string into an array of 18-bit word values # where two characters are packed into each word. Put NUL in # if the string has an odd number of characters. Return the array @@ -241,6 +242,8 @@ sub add_direntry { # Move up to the next position in the directory. $dirref->[1] += D_NUMWORDS; + increment_file_length( $dirref->[2], D_NUMWORDS ); # update directory inode i.size + # If we have filled the directory up, allocate another block to it if ( $dirref->[1] == WORDSPERBLK ) { my ($nextblock) = allocate_blocks(WORDSPERBLK); @@ -535,6 +538,7 @@ sub dump_image { foreach my $blocknum ( 0 .. NUMBLOCKS - 1 ) { foreach my $offset ( 0 .. WORDSPERBLK-1 ) { my $word = $Block[$blocknum][$offset] || 0; + # SIMH format packs word in a little-endian 32-bit int my $packedword = pack( "CCCC", $word & 0xff, ( $word >> 8 ) & 0xff,