%include "dkmain.imp-nolist"
%include "writedk.imp-noList"

{%begin
  %integer startByte, FILSYSSTART
  %byteinteger %array buf(1:32)
  %integer %array value(1:8)
  %integer iList1, fList1, fList2
  %integer fsize, initsize
  %integer initBlockNum
  %integer i, j, k
  %integer index, address  { for fill in 10 addresses of /sh

%routine Inode( %integer ino, mode )
  buffer( (ino-(ROOTINO-1)) * 64 + 1 ) = (mode<< 4) !! 1
  buffer( (ino-(ROOTINO-1)) * 64 + 2 ) = 8_377
 { mode : directory==4, c==2, b==6, regular.file==8
 { (rwx)= 0777 = $100 !! 8_377 }
 {      = 16_1ff
 { (rwx)= 0700 = $100 !! 8_300 }
 {      = 16_1C0
%end

%routine Nlink( %integer ino, lk )
  buffer( (ino-(ROOTINO-1)) * 64 + 4 ) = lk    { nlink
%end

  %routine FillSize( %integer ino, fsize )
    buffer((ino-(ROOTINO-1))*64+8+1)=fsize >> 24
    buffer((ino-(ROOTINO-1))*64+8+2)=fsize >> 16 & 16_FF
    buffer((ino-(ROOTINO-1))*64+8+3)=fsize >>  8 & 16_FF
    buffer((ino-(ROOTINO-1))*64+8+4)=fsize       & 16_FF
printstring("  fsize=");
write(fsize,0)
newline
  %end

  %routine FillAddr( %integer ino, fList )
    buffer((ino-(ROOTINO-1))*64+12+1)=fList >> 16  { 3 bytes for addr of first data block}
    buffer((ino-(ROOTINO-1))*64+12+2)=fList >>  8 & 16_FF 
    buffer((ino-(ROOTINO-1))*64+12+3)=fList & 16_000000FF
  %end

  %routine FillNextAddr( %integer index, address )
    buffer( index +1)=address >> 16  { 3 bytes for addr of first data block}
    buffer( index +2)=address >>  8 & 16_FF 
    buffer( index +3)=address & 16_000000FF
  %end

%routine CpStr( %integer i, len, %string(255) s )
  %for k= 1,1,len %cycle
     buffer(i+k-1) = byteinteger( addr(s(k)) )
  %repeat
%end

{main}
  init

phex(SUPERB)
  FILSYSSTART = SUPERB + 1

{  prompt(" init file size: ");
{  read(initsize);
{  prompt(" sh   file size: ");
{  read(fsize);

   initsize = filesize( "b.init" )
write(initsize,6);
   fsize = filesize( "b.sh" )
write(fsize,6);

  iList1 = FILSYSSTART ;
  fList1 = iList1 + NICINOD
write(fList1, 6)

    buffer(i) = 0 %for i= 1, 1, 512

  Inode( 2, 4 ) {dir .=..=/
  Nlink( 2, 3 ) {    . .. /dev/.. => 3 links
    FillSize( 2, 7*16 )  {7 entries @ 16 bytes
    FillAddr( 2, fList1 )

  Inode( 1, 8 ) { -  /init
  Nlink( 1, 1 )
    FillSize( 1, initsize )
    index = ( 1-(ROOTINO-1) )*64 + 12
    initBlockNum = (initsize + 511) >> 9  
       write(  initBlockNum, 0 ); newline
    { fill in `initBlockNum' addresses:
                 { fList1 used later; so can't assign here
    %for address = fList1+2, 1, fList1+2 -1 +initBlockNum  %cycle
         FillNextAddr( index, address )
         index = index + 3
    %repeat

  Inode( 3, 8 ) {-   /sh 
  Nlink( 3, 1 )
    FillSize( 3, fsize )
    index = ( 3-(ROOTINO-1) )*64 + 12
    { fill in 10 addresses & 2ndary blk address: 
    fList2 = fList1 +2 +initBlockNum   { +2          for 2 dir blocks;
                                       { +initBlockNum for /init
    %for address = fList2, 1, fList2 + 10 %cycle
         FillNextAddr( index, address )
         index = index + 3
    %repeat

  Inode( 4, 4 ) {dir /dev
  Nlink( 4, 2 ) {    /dev . => 2 links
    FillSize( 4, 6*16 )  {6 entries @ 16 bytes
    FillAddr( 4, fList1 + 1 )

  Inode( 5, 2 ) {cdev /dev/tty = /dev/console
  Nlink( 5, 2 )

  Inode( 6, 2 ) {cdev /dev/null
  Nlink( 6, 1 )

  Inode( 7, 6 ) {bdev /dev/fs
  Nlink( 7, 1 )

  WriteDisk( iList1 )
newline
phex4(iList1)

{  Inode( 9, 4 ) {dir /tmp

{write content of directory block of '/'}

    buffer(i) = 0 %for i= 1, 1, 512

  buffer( 2) = 2      { inode of / = 2
  CpStr(  3, 1, "." )
                      { NB: /dev/.. = inode of /
 
  buffer(18) = 2      { inode of / = 2
  CpStr( 19, 2, ".." )

  buffer(34) = 1
  CpStr( 35, 4, "init" )
 
  buffer(50) = 3
  CpStr( 51, 2, "sh" )
 
  buffer(66) = 4
  CpStr( 67, 3, "dev" )
 
{  buffer(82) = 6
{  CpStr( 83, 3, "usr" )
 
{  buffer(114) = 9
{  CpStr( 115, 3, "tmp" )
  WriteDisk( fList1 )
newline
phex4(fList1);

{write content of directory block of '/dev'}
    buffer(i) = 0 %for i= 1, 1, 512
  buffer( 2) = 4
  CpStr(  3, 1, "." )
 
  buffer(18) = 2
  CpStr( 19, 2, ".." )
 
  buffer(34) = 5
  CpStr( 35, 7, "console" )
 
  buffer(50) = 5
  CpStr( 51, 3, "tty" )
 
  buffer(66) = 6
  CpStr( 67, 4, "null" )
 
  buffer(82) = 7
  CpStr( 83, 2, "fs" )

  WriteDisk( fList1 + 1 )
newline
phex4(fList1 + 1)
newline

  bye
%endofprogram
