DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦1062b9bf9⟧ TextFile

    Length: 19968 (0x4e00)
    Types: TextFile
    Names: »tcreatetask«

Derivation

└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ.  Detaljer om "HC8000" projekt.
    └─⟦0364f57e3⟧ 
        └─⟦ef5fa0e68⟧ »jtas« 
└─⟦667bb35d6⟧ Bits:30007480 RC8000 Dump tape fra HCØ.
    └─⟦4334b4c0b⟧ 
        └─⟦ef5fa0e68⟧ »jtas« 
            └─⟦this⟧ 

TextFile




createtask

 
begin
 
  ! call:
      <task name> = createtask <program name>
 
    createtask creates an internal process, loads fp and makes it start
    <program name>, which is supposed to execute the "initialization code",
    load all "effective code" of <program name> and send a message to
    createtask. the code is then written on a file named <task name>.

    if execution is stopped in an error situation (by 'fatal_error') the
    mode bis are ok.no warning.yes and bit 11 is unchanged. otherwise bit
    11 is cleared.

    version 3   14.11.80  !


  !sections 10
\f





  !   p r o c e d u r e   d e c l a r a t i o n s   !


  ! main procedures !

  procedure read_command (.w3.; w2);

  procedure initialize (.w3.);

  procedure create_child (.w3.);

  procedure run_program (.w3.);

  procedure dump_core (.w3.);


  ! common procedures !

  procedure fatal_error (.w3.; w2; w1; w0);


  !   p r o c e d u r e   d e c l a r a t i o n s   e n d   !
\f




  !   d a t a    d e c l a r a t i o n s   p a g e   1   !

  incode

    word
    task_size_sg,         ! task size in segments !
    task_size_hw,         !       -      halfwords !
    task_free_core,       ! free core in task !
    task_entry,           ! entry address of task !
    fp_start,             ! fp start (of parent process) !
    output_on := 1,       ! = 0 if no output is wanted !
    ch_first_log_addr,    ! first log. addr. of child !
    ch_first_addr,        ! first addr. of child !
    ch_size,              ! size of child process !
    ch_prd_addr,          ! process descr. addr. for child !
    c_look_up_result;     ! result of 'c' look up !

    text (12) prog_name;     ! input file name !
    text (12) task_name;     ! output file name !
    text (12) ch_name;       ! child process name !
    text (12) c_name := "c"; ! name of 'c' entry !

    text (17) start_text := "'10'createtask start";
    text (15) task_text  := " - task started";
    text (22) free_text  := " - free core in task: ";
    text ( 3) hw_text    := " hw";
    text (16) end_text   := "createtask end'10''10'";

    array (0:9) c_entry_tail of word;  ! for entry tail of 'c' !

  !   d a t a    d e c l a r a t i o n s   e n d   !
\f




  !   s t a r t   m a i n p r o g   !

  begin
    ! w2 points to start of fp command stack, w3 to program name !
    if w0 := (w3).byte <> 6 ! "=" ! then output_on := w3 := 0;
    ch_first_addr := w1;  ! = first free byte !
    fp_start := w2;       ! = top free byte !
    write(.w3., w0:=address(start_text));  w2 := 10;  fp(33-2);  ! end current output !

    ! read and test calling command !
    read_command (.w3., w2:=fp_start);

    ! set task_size_sg, task_size_hw, ch_first_log_addr and ch_size !
    initialize (.w3.);
 
    ! store entry of 'c' - it is changed by fp in child !
    c_entry_tail(w1:=0);  w3 := address(c_name);
    monitor(42); ! look up entry !  c_look_up_result := w0;
 
    ! create child process - load and start fp and set ch_prd_addr !
    create_child (.w3.);
    write(.w3., w0:=address(task_text));  w2 := 10;  fp(33-2);  ! end current output !

    ! run algol program - set task_entry and task_free_core !
    run_program (.w3.);
    write(.w3., w0:=address(free_text));
    write(.w3., w0:=task_free_core);
    write(.w3., w0:=address(hw_text));  w2 := 10;  fp(33-2);  ! end current output !

    ! dump loaded core image !
    if w3 := output_on <> 0 then dump_core (.w3.);

    ! reset 'c' entry !
    c_entry_tail(w1:=0);  w3 := address(c_name);
    monitor(48); ! remove entry !
    if w0 := c_look_up_result = 0 then monitor(40); ! create entry !
 
    write(.w3., w0:=address(end_text));

    ! clear mode bit 11 - supposed to be set by algoltask !
    w0 := (w3:=fp(51)).word;  if w1 := w0 and 4096 <> 0 then (w3).word := w0 xor 4096;
  end;
 
  !   m a i n p r o g   e n d   !
\f


 
 
  !   p r o c e d u r e   r e a d _ c o m m a n d   !
 
  body of read_command
 
  begin
    ! tests fp command and copies names and options to command arrays
          w2 call   : ptr to start of command stack.
             return : ptr to word after commands read.
       w0,w1 return : undef. !
    incode
      ref return;
 
    begin  return := w3;

      if w3 := b.output_on <> 0 then ! read task name !
      begin
        ! test text follows  (-,10) !
        if w0,=(w2+1).byte <> 10 then fatal_error(.w3., w2:=1, w1:=0, w0);
        w3 :=address(b.task_name);
        (w3).double := f1 := (w2+1).double;  (w3+4).double := f1 := (w2+4).double;  w2 + 4;
      end;

      ! test text follows (-,10) !
      if w0,=(w2+1).byte <> 10 then fatal_error(.w3., w2:=1, w1:=0, w0);
      w2 + 9;  ! skip byte and 'algoltask1' !

      ! test space - text follows  (4,10) !
      if w0:=(w2).word <> w1:= 4 lshift 12 + 10 then fatal_error(.w3., w2:=1, w1:=0, w0);
      w3 :=address(b.prog_name);
      (w3).double := f1 := (w2+2).double;  f1 := (w2+4).double;  w1 or 10;
      (w3+4).double := f1;  w2 + 4;

      ! no options (yet) !
      if w0:=(w2).byte <> -2 ! = ")" ! then
      if w0 <> -4 ! = end of stack ! then 
      if w0 <> 2 ! = nl ! then fatal_error(.w3., w2:=1, w1:=0, w0);
      w2 + 2;

      w3 := return;
    end;
  end;
 
  !   p r o c e d u r e   r e a d _ c o m m a n d   e n d   !
\f


 
 
  !   p r o c e d u r e   i n i t i a l i z e   p a g e   1   !
 
  body of initialize
 
  begin
    ! reads task size and first logical address in tosssysdef1/2 entries.
      sets ch_size and test if we have room for the task (with fp etc).
      w0,w1,w2 return : undef. !

    incode
      ref return;
      array (0:9) entry_tail of word;
      text (12) sys_def_1 := "tosssysdef1";
      text (12) sys_def_2 := "tosssysdef2";

    begin
      return := w3;
 
      ! read task size in tosssysdef1 entry !
      entry_tail (w1:=0);
      w3 := address(sys_def_1);
      monitor(42);  ! look up entry !
      if w0 <> 0 then fatal_error(.w3., w2:=4, w1:=42, w0);
      b.task_size_sg := w0 := (w1+12).byte;
      w0 * 512;  b.task_size_hw := w0;
 
      ! read first logical address in tosssysdef2 entry !
      entry_tail (w1:=0);
      w3 := address(sys_def_2);
      monitor(42);  ! look up entry !
      if w0 <> 0 then fatal_error(.w3., w2:=4, w1:=42, w0);
      b.ch_first_log_addr := w0 := (w1+12).word;
\f




  !   p r o c e d u r e   i n i t i a l i z e   p a g e   2   !

      ! test if we have enough room !
      ! child size := task size + 1536 (fp) + 1024 (in/out) + 12 (fp commands) - 6 (end words) !
      b.ch_size := w1 := b.task_size_hw + 2566;
      w0 := b.ch_firstaddr + w1;  ! top of child !
      if w0 > b.fp_start then fatal_error(.w3., w2:=3, w1:=0, w0);

      ! generate wrk-name for task process !
      w3 := address(b.ch_name);
      monitor(68);
      if w0 <> 0 then fatal_error(.w3., w2:=0, w1:=68, w0);

      w3 := return;
    end;
  end;

  !   p r o c e d u r e   i n i t i a l i z e   e n d   !

\f


 
 
  !   p r o c e d u r e   c r e a t e _ c h i l d   p a g e   1   !
 
  body of create_child
 
  begin
    ! creates a child process, loads fp and starts it.
      w0,w1,w2 return : undef. !
 
    incode
      ref return, mtr_buff_addr;
      word fp_size, fp_entry;
      array (0:9) parameters of word;
      array (0:7) mess_buff of word := 0 0 0 0 0 0 0 0;
      text (12) fp_name := "fp";
 
    begin
      return := w3;
 
      ! create child process !
      parameters(w1:=0);  w3 := (w2:=fp(16)).word; ! own prd. addr. !
      (w1).word := w0 := b.ch_first_addr;    ! first address !
      (w1+2).word := w0 + b.ch_size;         ! top address !
      (w1+2).byte := w0 ,= (w3+26).byte - 2; ! buffer claim !
      (w1+1).byte := w0 ,= (w3+1).byte;      ! area claim !
      (w1+1).word := w0 := 0;                ! int. claim, funct. mask !
      (w1+2).word := w0 := (w3+5).word;      ! protection reg./key !
      (w1+2).word := w0 := (w3+40).word;     ! bases       !
      (w1+2).word := w0 := (w3+2).word;      !   =         !
      (w1+2).word := w0 := (w3-6).word;      !     parent  !
      (w1+2).word := w0 := (w3+2).word;      !       bases !

      parameters(w1:=0);  w3 := address(b.ch_name);
      monitor(56);  ! create internal process !
      if w0 <> 0 then fatal_error(.w3., w2:=6, w1:=56, w0);
      ! get child process description address !
      monitor(4);  ! process description !
      if w0 = 0 then fatal_error(.w3., w2:=0, w1:=4, w0);
      b.ch_prd_addr := w0;
\f




  !   p r o c e d u r e   c r e a t e _ c h i l d   p a g e   2   !

      ! lookup fp - get size and entry address !
      parameters(w1:=0);  w3 := address(fp_name);
      monitor(42);  ! look up entry !
      if w0 <> 0 then fatal_error(.w3., w2:=12, w1:=42, w0);
      parameters(w3:=9);
      fp_size := w0 := (w3).word;  fp_entry := w0 ,= (w3-1).byte;
 
      ! read-message into mess buffer !
      mess_buff(w3:=0);
      (w3).word := w2 := 3 lshift 12;       ! operation = input !
      (w3+2).word := w2 := b.ch_first_addr; ! first byte !
      (w3+2).word := w2 + fp_size;          ! top byte !
      (w3+2).word := w2 :=0;                ! segment no. !

      ! start reading of fp !
      mess_buff(w1:=0);
      w3 := address(fp_name);
      monitor(16);  ! send message !
      if w2 = 0 then fatal_error(.w3., w2:=5, w1:=16, w0:=0);

      monitor(18);  ! wait answer !
      if w0 <> 1 then fatal_error(.w3., w2:=12, w1:=18, w0);

      ! set child registers !
      parameters(w1:=0);
      (w1).word   := w0 := (w2:=fp(16)).word;  ! own prd. addr. !
      (w1+2).word := w0;
      (w1+2).word := w0;
      (w1+2).word := w0 := b.ch_prd_addr;
      (w1+2).word := w0 := 0;
      w0 := b.ch_first_addr;  (w1+2).word := w0 + fp_entry;
 
      parameters(w1:=0);  w3 := address(b.ch_name);
      monitor(62);  ! modify child process !
      if w0 <> 0 then fatal_error(.w3., w2:=0, w1:=62, w0);
\f




  !   p r o c e d u r e   c r e a t e _ c h i l d   p a g e   3   !

      ! address base := first child addr. - first log. child addr. !
      w1 := b.ch_first_addr - b.ch_first_log_addr;
      monitor(98);  ! change address base !
      if w0 <> 0 then fatal_error(.w3., w2:=0, w1:=98, w0);

      monitor(58);  ! start internal process !
      if w0 <> 0 then fatal_error(.w3., w2:=0, w1:=58, w0);

      mess_buff(w1:=0);
      monitor(20);  ! wait message !
      if w2 = 0 then fatal_error(.w3., w2:=5, w1:=20, w0);
      if w0 <> b.ch_prd_addr then fatal_error(.w3., w2:=0, w1:=20, w0);
      mtr_buff_addr := w2;

      ! is fp asking for input !
      if w0 := (w1).byte <> 3 then fatal_error(.w3., w2:=2, w1:=0, w0);
      ! send <program name> to fp !
      w2 := (w1+2).word - b.ch_first_log_addr + b.ch_first_addr - 2;
      w3 := address(b.prog_name) - 2;
      for w1 := 1 step 1 upto 7 do (w2+2).word := w0 := (w3+2).word;
      mess_buff(w2:=0);
      (w2).word := w3 := 0;
      (w2+2).word := w3 := 8;  ! size in hw !
      (w2+2).word := w0 := 12; ! size in char !
      (w2+2).word := w3 := 0;

      w0 := 1; ! result = normal answer !
      mess_buff(w1:=0);
      w2 := mtr_buff_addr;
      monitor(22); ! send answer !
 
      w3 := return;
    end;
  end;

  !   p r o c e d u r e   c r e a t e _ c h i l d   e n d   !
\f




  !   p r o c e d u r e   r u n _ p r o g r a m   p a g e   1   !

  body of run_program

  begin
    ! waits for a message from set_entry (or fp if something vent wrong).
      if message is "ok" the task is ready to be dumped, otherwise an
      error message is written.
      w0,w1,w2 return : undef. !

    incode
      ref return, text_start;
      word mtr_buff_addr;
      array (0:7) mess_buff of word;
      array (0:7) mess_buff_1 of word;
      array (0:5) process_name of word;

    begin
      return := w3;
 
      mess_buff(w1:=0);
      process_name(w3:=0);
      monitor(20);  ! wait message !
      if w2 = 0 then fatal_error(.w3., w2:=5, w1:=20, w0);
      if w0 <> b.ch_prd_addr then fatal_error(.w3., w2:=0, w1:=20, w0);
      mtr_buff_addr := w2;
 
      ! stop_child !
      monitor(60);  ! stop intternal process !
      if w2 = 0 then fatal_error(.w3., w2:=5, w1:=60, w0:=0);
      if w0 <> 0 then fatal_error(.w3., w2:=0, w1:=60, w0);
      mess_buff_1(w1:=0);
      monitor(18); ! wait answer !
\f




  !   p r o c e d u r e   r u n _ p r o g r a m   p a g e   2   !

      ! send dummy answer to received message !
      w2 := mtr_buff_addr;
      w0 := 2;  ! dummy answer !
      monitor(22);  ! send answer !
 
      ! remove child process !
      monitor(64);  ! remove process !
      if w0 <> 0 then fatal_error(.w3., w2:=0, w1:=64, w0);

      mess_buff(w2:=0);  w0 ,= (w2).byte;

      if w0 = 5 then ! output message !
      begin
        w1 := b.ch_first_log_addr - b.ch_first_addr;
        w0 := (w2+2).word - w1;  text_start := w0;
        if w0 >= w3 := b.ch_first_addr then if w0 <= w3 + b.ch_size then
        begin
          w3 := (w2+2).word - w1 + 2;  (w3).byte := w1 := 0;
          write(.w3., w0:=text_start);
          fatal_error(.w3., w2:=14, w1:=0, w0);
        end;
      end;

      if w0 = 101 then ! error message from set_entry !
      begin
        if w0 := (w2+2).word = 1 then w2 := 7 else w2 := 8;
        fatal_error(.w3., w2, w1:=0, w0);
      end;

      if w0 <> 100 then fatal_error(.w3., w2:=9, w1:=0, w0);

      ! else task run ok !
      b.task_free_core := w0 := (w2+2).word;
      b.task_entry := w0 := (w2+2).word;
 
      w3 := return;
    end;
  end;
 
  !   p r o c e d u r e   r u n _ p r o g r a m   e n d   !
\f




  !   p r o c e d u r e   d u m p _ c o r e   p a g e   1   !
 
  body of dump_core
 
  begin
    ! writes code image on file with name in b.task_name.
      w0,w1,w2 return: undef. !
 
    incode
      ref return;
      array (0:9) entry_tail of word := 0 0 0 0 0 0 0 0 0 0;
      array (0:7) mess_buff of word := 0 0 0 0 0 0 0 0;
 
    begin
      return := w3;

      entry_tail(w1:=0);
      (w1).word := w3 := b.task_size_sg;
      w3 := address(b.task_name);
 
      monitor(52);  ! create area process !
      if w0 = 3 then  ! entry does not exist !
      begin
        monitor(40);  ! create entry !
        if w0 = 4  then fatal_error(.w3., w2:=10, w1:=40, w0);
        if w0 <> 0 then fatal_error(.w3., w2:=0,  w1:=40, w0);
        monitor(52);  ! create area process !
      end;
      if w0 = 1  then fatal_error(.w3., w2:=11, w1:=52, w0);
      if w0 <> 0 then fatal_error(.w3., w2:=0,  w1:=52, w0);

      monitor(8);  ! reserve area process !
      if w0 <> 0 then   ! process cannot be reserved !
      begin
        monitor(40);  ! create entry !
        if w0 = 4  then fatal_error(.w3., w2:=10, w1:=40, w0);
        if w0 <> 0 then if w0 <> 3 then fatal_error(.w3., w2:=0,  w1:=40, w0);
        monitor(52);  ! create area process !
        if w0 = 1  then fatal_error(.w3., w2:=11, w1:=52, w0);
        if w0 <> 0 then fatal_error(.w3., w2:=0,  w1:=52, w0);
        monitor(8);  ! reserve area process !
      end;
      if w0 <> 0 then fatal_error(.w3., w2:=0, w1:=8, w0);
\f




  !   p r o c e d u r e   d u m p _ c o r e   p a g e   2   !

      entry_tail(w2:=0);
      f1 := (w1:=108).double lshift 5;  (w2+10).word := w0; ! short clock !
      (w2+6).byte := w0 := 17; ! contents key !
      (w2+2).word := w0 := b.task_size_sg; ! load length !
      entry_tail(w1:=0);
      monitor(44);  ! change entry !
      if w0 <> 0 then fatal_error(.w3., w2:=0, w1:=44, w0);
 
      ! dump task !
      ! write-message into mess buffer !
      mess_buff(w3:=0);
      (w3).word := w2 := 5 lshift 12;              ! operation = output !
      (w3+2).word := w1 := b.ch_first_addr + 1536; ! first byte !
      (w3+2).word := w1 + b.task_size_hw;          ! top byte !
      (w3+2).word := w2 :=0;                       ! segment no. !

      ! set last word of dump !
      (w1-2).word := w0 := b.task_entry;

      ! start writing !
      mess_buff(w1:=0);  w3 := address(b.task_name);
      monitor(16);  ! send message !
      if w2 = 0 then fatal_error(.w3., w2:=5, w1:=16, w0:=0);

      monitor(18);  ! wait answer !
      if w0 <> 1 then fatal_error(.w3., w2:=13, w1:=18, w0);

      w3 := return;
    end;
  end;

  !   p r o c e d u r e   d u m p _ c o r e   e n d   !
\f


 
 
  !   p r o c e d u r e   f a t a l _ e r r o r   p a g e   1  !
 
  body of fatal_error
 
  begin
    ! writes an error message and stops execution
            w2 call   : if > 0 error text number
            w1 call   : if > 0 monitor call number
            w0 call   : if w1 > 0 monitor call result !
 
    incode
    word error_no, mtr_call_no, result;
 
    text (4) error_text    := "*** ";

    text (24) fp1_text_1   := "error in fp command line";
    text (26) fp2_text_2   := "fp trouble in childprocess";
    text (12) core_text_3  := "lack of core";
    text (21) sysdef_text_4:= "tosssysdef1/2 problem";
    text (21) buff_text_5  := "buffer claim exceeded";
    text (23) int_text_6   := "internal process claims";
    text (26) eff1_text_7  := "str'95'eff'95'start called twice";
    text (28) eff2_text_8  := "str'95'eff'95'start was not called";
    text (25) mess_text_9  := "unknown message from task";
    text (15) claim_text_10:= "claims exceeded";
    text (20) area_text_11 := "area claims exceeded";
    text (10) fp_text_12   := "fp trouble";
    text (11) write_text_13:= "write error";
    text (13) prog_text_14 := "error in task";

    text (13) mtr_text     := "monitor call ";
    text (11) result_text  := " - result =";

    text (20) stop_text    := "createtask stopped'10''10'";
\f




  !   p r o c e d u r e   f a t a l _ e r r o r   p a g e   2  !

    begin
      error_no := w2;  mtr_call_no := w1;  result := w0;

      write(.w3., w0:=address(error_text));

      if w2 > 0 then
      begin
        case w2 := error_no of
        begin
          write (.w3., w0:=address(fp1_text_1));
          write (.w3., w0:=address(fp2_text_2));
          write (.w3., w0:=address(core_text_3));
          write (.w3., w0:=address(sysdef_text_4));
          write (.w3., w0:=address(buff_text_5));
          write (.w3., w0:=address(int_text_6));
          write (.w3., w0:=address(eff1_text_7));
          write (.w3., w0:=address(eff2_text_8));
          write (.w3., w0:=address(mess_text_9));
          write (.w3., w0:=address(claim_text_10));
          write (.w3., w0:=address(area_text_11));
          write (.w3., w0:=address(fp_text_12));
          write (.w3., w0:=address(write_text_13));
          write (.w3., w0:=address(prog_text_14));
        end;
        write(.w3., w2:=10);  ! nl !
      end;

      if w1 := mtr_call_no > 0 then
      begin
        layout (0, 32, 2);
        write(.w3., w0:=address(mtr_text));
        write(.w3., w0:=mtr_call_no);
        write(.w3., w0:=address(result_text));
        write(.w3., w0:=result);
        write(.w3., w2:=10);  ! nl !
      end;

      write (.w3., w0:=address(stop_text));
      w2 := 3; fp(7);  ! stop execution with ok.no warning.yes !
    end;
  end;
 
  !   p r o c e d u r e   f a t a l _ e r r o r   e n d   !
\f




end.

▶EOF◀