# dmach --- Burroughs D-machine simulator

include "dmach_def.r.i"

   include "dmach_com.r.i"

   call initialize_simulation

   for (Clock = 1; Clock <= Max_clock; Clock = Clock + 1) {
      call initiate_clock_cycle
      call micro_fetch
      if (Micro_instruction == HALT)
         break
      call adder_op
      if (M_type_1)
         call execute_type_1
      else
         call execute_type_2
      call trace_info
      call select_successor_address
      call terminate_clock_cycle
      }

   call terminate_simulation

   stop
   end


# adder_op --- perform adder operation

   subroutine adder_op

   include "dmach_com.r.i"

   integer op_type (16)

   data op_type / _
      ARITH, LOGIC, LOGIC, ARITH, LOGIC, ARITH, LOGIC, LOGIC,
      LOGIC, LOGIC, ARITH, LOGIC, ARITH, LOGIC, LOGIC, ARITH /

   call x_input_select
   call y_input_select

   case Lu_adder_op {

      #  0 : X + Y
      if (Lu_inhibit_carry)
         Adder_output = add_without_carry (X_input, Y_input)
      else
         Adder_output = X_input + Y_input

      #  1 : ~(X | Y)
      Adder_output = not (or (X_input, Y_input))

      #  2 : ~X & Y
      Adder_output = and (not (X_input), Y_input)

      #  3 : X + Y + 1
      if (Lu_inhibit_carry)
         Adder_output = add_without_carry (X_input, Y_input + 1)
      else
         Adder_output = X_input + Y_input + 1

      #  4 : ~(X & Y)
      Adder_output = not (and (X_input, Y_input))

      #  5 : X + (X | Y)
      if (Lu_inhibit_carry)
         Adder_output = add_without_carry (X_input, or (X_input, Y_input))
      else
         Adder_output = X_input + or (X_input, Y_input)

      #  6 : X xor Y
      Adder_output = xor (X_input, Y_input)

      #  7 : X & ~Y
      Adder_output = and (X_input, not (Y_input))

      #  8 : ~X | Y
      Adder_output = or (not (X_input), Y_input)

      #  9 : X & Y | ~(X | Y)
      Adder_output = or (and (X_input, Y_input),
                           not (or (X_input, Y_input)))

      # 10 : X + (X & Y)
      if (Lu_inhibit_carry)
         Adder_output = add_without_carry (X_input,
                                             and (X_input, Y_input))
      else
         Adder_output = X_input + and (X_input, Y_input)

      # 11 : X & Y
      Adder_output = and (X_input, Y_input)

      # 12 : X - Y - 1
      Adder_output = X_input - Y_input - 1

      # 13 : X | ~Y
      Adder_output = or (X_input, not (Y_input))

      # 14 : X | Y
      Adder_output = or (X_input, Y_input)

      # 15 : X - Y
      if (Lu_inhibit_carry)
         Adder_output = add_without_carry (X_input, - Y_input)
      else
         Adder_output = X_input - Y_input
      }
   else
      call error ("in adder_op: can't happen.")

   Carry_in  = xor (X_input, Y_input, Adder_output)
   Carry_out = xor (and (X_input, Y_input), and (Adder_output, Carry_in))

   if (op_type (Lu_adder_op) == ARITH & ~ Lu_inhibit_carry)
      Aov = xor (Carry_in, Carry_out) < 0

   Mst = Adder_output < 0
   Lst = and (Adder_output, 1) ~= 0
   Abt = Adder_output == ALL_BITS_TRUE

   return
   end


# add_without_carry --- perform addition without byte carries

   longint function add_without_carry (x, y)
   longint x, y

   integer i, xx, yy

   add_without_carry = 0
   xx = x
   yy = y
   do i = 1, 4; {
      add_without_carry = xor (add_without_carry,
                               ls (rt (xx + yy, 8), i - 1))
      xx = rs (xx, 8)
      yy = rs (yy, 8)
      }

   return
   end


# barrel_switch --- simulate operation of barrel switch

   subroutine barrel_switch

   include "dmach_com.r.i"

   case Lu_shift_select {
      Bsw_output = Adder_output
      Bsw_output = rs (Adder_output, Sar)
      Bsw_output = ls (Adder_output, 32 - Sar)
      Bsw_output = xor ( _
                      ls (Adder_output, 32 - Sar),
                      rs (Adder_output, Sar))
      }
   else
      call error ("in barrel_switch: can't happen.")

   return
   end


# condition_adjust --- manipulate static conditions

   subroutine condition_adjust

   include "dmach_com.r.i"

   integer caj

   include "bit_field_dcl.r.i"

   caj = bit_field (Nano_instruction (1), 8, 10) + 1

   case caj {
      ;
      Lc2 = TRUE
      Gc2 = TRUE
     {Gc1 = FALSE; Gc2 = FALSE}
      Int = TRUE
      Lc3 = TRUE
      Gc1 = TRUE
      Lc1 = TRUE
      }
   else
      call error ("in condition_adjust: can't happen.")

   return
   end


# dump_s_memory --- dump contents of S-memory per user instructions

   subroutine dump_s_memory

   include "dmach_com.r.i"

   integer saddr, eaddr, i, j

   call input (STDIN,
      "*nS-memory dump -- Enter illegl start addr to quit*n.")
   repeat {
      call input (STDIN, "*nStarting address (1-2048): *i.", saddr)
      if (saddr < 1 | saddr > S_MEMORY_SIZE)
         break
      call input (STDIN, "Ending address           : *i.", eaddr)
      if (eaddr < 1 | eaddr > S_MEMORY_SIZE) {
         call remark ("Ending address out of range.")
         next
         }
      elif (saddr > eaddr) {
         call remark ("Addresses in backward order.")
         next
         }
      j = 0
      do i = saddr, eaddr; {
         if (mod (j, 4) == 0)    # list 4 words per line
            call print (STDOUT, "*n*4i.", i)
         if (Octal_output)
            call print (STDOUT, "*15,-8l.", S_memory (i))
         else
            call print (STDOUT, "*15l.", S_memory (i))
         j = j + 1
         }
      if (mod (j, 4) ~= 1)
         call putch (NEWLINE, STDOUT)
      }

   return
   end


# execute_type_1 --- simulate execution of a type 1 instruction

   subroutine execute_type_1

   include "dmach_com.r.i"

   call nano_fetch
   call set_condition

   if (N_lu_conditional & ~ Condition)
      Current_phase = 2    # in addition to phase 1
   else {
      Current_phase = 3    # in addition to phase 1
      Next_non_phase_1_fetch_addr = Micro_fetch_addr
      call barrel_switch
      call update_destinations
      call update_lu_controls
      }

   if (~ N_mdop_conditional | Condition) {
      call condition_adjust
      call mem_dev_operation
      }

   return
   end


# execute_type_2 --- simulate execution of a type 2 instruction

   subroutine execute_type_2

   include "dmach_com.r.i"
   include "bit_field_dcl.r.i"

   Current_phase = 2

   if (M_set_sar)
      Sar = xor (ls (bit_field (Micro_instruction, 3, 5), 2),
                     bit_field (Micro_instruction, 7, 8))

   if (M_set_lit)
      Lit = bit_field (Micro_instruction, 8, 16)

   if (M_set_ampcr)
      Ampcr = bit_field (Micro_instruction, 5, 16)

   return
   end


# initialize_simulation --- initialize the D-machine simulator

   subroutine initialize_simulation

   include "dmach_com.r.i"

   integer i
   character str (MAXLINE)

   call initialize_m_memory


   ### initialize the logic unit command registers:

   Lu_x_select = 1
   Lu_y_select = 1
   Lu_b_mask_high = 1
   Lu_b_mask_mid = 1
   Lu_b_mask_low = 1
   Lu_inhibit_carry = FALSE
   Lu_adder_op = 1
   Lu_shift_select = 1
   Lu_set_a1 = FALSE
   Lu_set_a2 = FALSE
   Lu_set_a3 = FALSE
   Lu_b_select = 1
   Lu_set_mir = FALSE
   Lu_set_ampcr = FALSE
   Lu_set_mar = FALSE
   Lu_lmar = FALSE
   Lu_set_br1 = FALSE
   Lu_set_br2 = FALSE
   Lu_ctr_select = 1
   Lu_sar_select = 1


   ### initialize the controlled logic components:

   A1 = 0
   A2 = 0
   A3 = 0
   B  = 0
   Ext = 0
   Mir = 0
   Sar = 0
   Lit = 0
   Ctr = 0
   Br1 = 0
   Br2 = 0
   Mar = 0
   Bmar = 0
   Gc1 = FALSE
   Gc2 = FALSE
   Lc1 = FALSE
   Lc2 = FALSE
   Lc3 = FALSE
   Cov = FALSE
   Sai = FALSE
   Rdc = FALSE
   Ex1 = FALSE
   Ex2 = FALSE
   Ex3 = FALSE
   Int = FALSE


   ### initialize the control logic components:

   Ampcr = 0
   Non_phase_1_fetch_addr = UNDEFINED
   Next_non_phase_1_fetch_addr = UNDEFINED
   Rdc_clock = 0
   Sai_clock = 0


   ### query user for option settings

   call input (STDIN, "Begin execution at address: *i.", Mpcr)
   Micro_fetch_addr = Mpcr
   call input (STDIN, "Number of clock cycles to simulate: *i.", Max_clock)
   call input (STDIN, "Number of cycles between traces: *i.", Trace_interval)
   call input (STDIN, "Begin tracing at address: *i.", Trace_start_addr)
   call input (STDIN, "End tracing at address: *i.", Trace_stop_addr)
   call input (STDIN, "Print S-memory and registers in octal? *s.", str)
   Octal_output = str (1) == 'y'c | str (1) == 'Y'c
   call input (STDIN, "Dump S-memory upon termination? *s.", str)
   Memory_dump = str (1) == 'y'c | str (1) == 'Y'c
   call initialize_s_memory

   return
   end


# initialize_m_memory --- read in the contents of micro- and nano-memory

   subroutine initialize_m_memory

   include "dmach_com.r.i"

   integer i, j, addr, n_addr, fd
   integer open, getlin, gctoi, getarg
   character line (MAXLINE), hex_file (MAXLINE)

   include "bit_field_dcl.r.i"

   if (getarg (1, hex_file, MAXLINE) == EOF)
      call error ("Usage: dmach <hex file>.")

   fd = open (hex_file, READ)
   if (fd == ERR)
      call cant (hex_file)

   while (getlin (line, fd) ~= EOF) {
DEBUG call print (ERROUT, "hex input: *s.", line)
      i = 1
      addr = gctoi (line, i, 10)
      M_memory (addr + 1) = gctoi (line, i, 16)
DEBUG call print (ERROUT, "M_mem (*i) = *,-16i.",
DEBUG       addr, M_memory (addr + 1))
      if (bit_field (M_memory (addr + 1), 1, 4) == 15) {    # type 1?
         n_addr = bit_field (M_memory (addr + 1), 5, 16)
         N_memory (1, n_addr + 1) = gctoi (line, i, 16)
         N_memory (2, n_addr + 1) = gctoi (line, i, 16)
         N_memory (3, n_addr + 1) = gctoi (line, i, 16)
         N_memory (4, n_addr + 1) = gctoi (line, i, 16)
DEBUG    call print (ERROUT, " N_mem (*i) = *,-16i *,-16i *,-16i *,-16i.",
DEBUG       n_addr, N_memory (1, n_addr + 1), N_memory (2, n_addr + 1),
DEBUG       N_memory (3, n_addr + 1), N_memory (4, n_addr + 1))
         }
DEBUG call putch (NEWLINE, ERROUT)
      }

   call close (fd)

   return
   end


# initialize_s_memory --- query the user for S-memory contents

   subroutine initialize_s_memory

   include "dmach_com.r.i"

   integer saddr, eaddr, i
   integer mapsu
   logical stdin_is_tty

   stdin_is_tty = mapsu (STDIN) == TTY

   call input (STDIN,
      "*nLoad S-memory -- Enter illegal start addr to quit*n.")
   repeat {
      call input (STDIN, "*nStarting address (1-2048): *i.", saddr)
      if (saddr < 1 | saddr > S_MEMORY_SIZE)
         break
      call input (STDIN, "Ending address           : *i.", eaddr)
      if (eaddr < 1 | eaddr > S_MEMORY_SIZE) {
         call remark ("Ending address out of range.")
         next
         }
      elif (saddr > eaddr) {
         call remark ("Addresses in backward order.")
         next
         }
      do i = saddr, eaddr; {
         if (stdin_is_tty)
            call print (ERROUT, "Smem (*i) = .", i)
         call input (STDIN, "*l.", S_memory (i))
         }
      }

   return
   end


# initiate_clock_cycle --- set up for a new clock cycle

   subroutine initiate_clock_cycle

   include "dmach_com.r.i"


   ### check for external events comming due in this cycle

   if (Rdc_clock == Clock) {
      Rdc = TRUE
      Rdc_clock = 0
      Ext = Memory_data
      }

   if (Sai_clock == Clock) {
      Sai = TRUE
      Sai_clock = 0
      }

   return
   end


# mem_dev_operation --- perform requested memory/device operation

   subroutine mem_dev_operation

   include "dmach_com.r.i"

   integer mdop, temp

   include "bit_field_dcl.r.i"

   mdop = bit_field (Nano_instruction (4), 3, 6)

   if (mdop == 0)    # nothing to do
      return

   if (mdop ~= 2 & mdop ~= 3 & mdop ~= 6 & mdop ~= 7) {
      call print (STDOUT,
         "*nError -- Bad external operation (*i)*n.", mdop)
      return
      }

   if (mdop == 2 | mdop == 6)    # MR1 or MW1
      Bmar = xor (ls (Br1, 8), Mar)
   else                          # MR2 or MW2
      Bmar = xor (ls (Br2, 8), Mar)

   if (Bmar < 1 | Bmar > S_MEMORY_SIZE) {
      call print (STDOUT, "*nError -- S-memory address out of range*n.")
      call terminate_simulation
      stop
      }

   if (mdop == 2 | mdop == 3) {  # memory read
      if (Rdc_clock ~= 0)
         call print (STDOUT, "*nError -- Memory not ready for read*n.")
      Memory_data = S_memory (Bmar)
      Rdc_clock = Clock + MEMORY_READ_CYCLE_TIME
      }
   else {
      if (Sai_clock ~= 0)
         call print (STDOUT, "*nError -- Memory not ready for write*n.")
      S_memory (Bmar) = Mir
      Sai_clock = Clock + MEMORY_WRITE_CYCLE_TIME
      }

   return
   end


# micro_fetch --- fetch and decode the next micro instruction

   subroutine micro_fetch

   include "dmach_com.r.i"
   include "bit_field_dcl.r.i"

   Micro_instruction = M_memory (Micro_fetch_addr + 1)

   M_type_1 = bit_field (Micro_instruction, 1, 4) == 15
   if (M_type_1) {
      M_set_sar = FALSE
      M_set_lit = FALSE
      M_set_ampcr = FALSE
      Nano_fetch_addr = bit_field (Micro_instruction, 5, 16)
      }
   else {
      M_set_sar = bit_field (Micro_instruction, 1, 2) == 0 _
                | bit_field (Micro_instruction, 1, 2) == 2
      M_set_lit = bit_field (Micro_instruction, 1, 2) == 2 _
                | bit_field (Micro_instruction, 1, 4) == 14
      M_set_ampcr = bit_field (Micro_instruction, 1, 4) == 12
      }

   return
   end


# nano_fetch --- fetch and decode next nano instruction

   subroutine nano_fetch

   include "dmach_com.r.i"
   include "bit_field_dcl.r.i"

   Nano_instruction (1) = N_memory (1, Nano_fetch_addr + 1)
   Nano_instruction (2) = N_memory (2, Nano_fetch_addr + 1)
   Nano_instruction (3) = N_memory (3, Nano_fetch_addr + 1)
   Nano_instruction (4) = N_memory (4, Nano_fetch_addr + 1)

   N_condition_select   = bit_field (Nano_instruction (1),  1,  4) + 1
   N_true_condition     = bit_field (Nano_instruction (1),  5,  5) == 1
   N_lu_conditional     = bit_field (Nano_instruction (1),  6,  6) == 1
   N_mdop_conditional   = bit_field (Nano_instruction (1),  7,  7) == 1

   return
   end


# print_state --- print the state of the D-machine

   subroutine print_state

   include "dmach_com.r.i"

   call print (STDOUT,
      "*nClock: *5i               Phase 1 addr: *4i.",
      Clock, Micro_fetch_addr)
   if (Non_phase_1_fetch_addr ~= UNDEFINED)
      call print (STDOUT, "            Phase *i addr: *4i.",
         Current_phase, Non_phase_1_fetch_addr)
   call putch (NEWLINE, STDOUT)

   if (Octal_output) {
      call print (STDOUT,
         "A1: *11,-8l     Lit :  *3,8i     Ctr :  *3,8i"_
         "Sar :   *2,8i     Ampc: *4,8i*n.",
         A1, Lit, Ctr, Sar, Ampcr)

      call print (STDOUT,
         "A2: *11,-8l     Br1 :  *3,8i     Br2 :  *3,8i"_
         "Mar :  *3,8i     Bmar: *4,8i*n.",
         A2, Br1, Br2, Mar, Bmar)

      call print (STDOUT,
         "A3: *11,-8l     B   : *11,-8l             Mir : *11,-8l*n.",
         A3, B, Mir)
      }

   else {      # output format is decimal
      call print (STDOUT,
         "A1: *11l     Lit :  *3i     Ctr :  *3i"_
         "Sar :   *2i     Ampc: *4i*n.",
         A1, Lit, Ctr, Sar, Ampcr)

      call print (STDOUT,
         "A2: *11l     Br1 :  *3i     Br2 :  *3i"_
         "Mar :  *3i     Bmar: *4i*n.",
         A2, Br1, Br2, Mar, Bmar)

      call print (STDOUT,
         "A3: *11l     B   : *11l             Mir: *11l*n.",
         A3, B, Mir)
      }

   call print (STDOUT,
      "Mst  Lst  Abt  Aov  Cov  Sai  Rdc  Gc1"_
      "Gc2  Lc1  Lc2  Lc3  Ex1  Ex2  Ex3  Int*n.")

   call print (STDOUT,
      " *i    *i    *i    *i    *i    *i    *i    *i   .",
      Mst, Lst, Abt, Aov, Cov, Sai, Rdc, Gc1)

   call print (STDOUT,
      " *i    *i    *i    *i    *i    *i    *i    *i*n.",
      Gc2, Lc1, Lc2, Lc3, Ex1, Ex2, Ex3, Int)

   return
   end


# select_successor_address --- select next micro instruction address

   subroutine select_successor_address

   include "dmach_com.r.i"

   integer successor, temp

   include "bit_field_dcl.r.i"

   if (~ M_type_1) {    # this was a type 2 instruction
      Mpcr = Mpcr + 1   # successor is STEP
      Micro_fetch_addr = Mpcr
      }
   else {               # this was a type 1 instruction
      if (Condition)
         successor = bit_field (Nano_instruction (1), 11, 13) + 1
      else
         successor = bit_field (Nano_instruction (1), 14, 16) + 1

      case successor {
         ;                                # WAIT
         Mpcr = Mpcr + 1                  # STEP
         {                                # SAVE
            Ampcr = Mpcr
            Mpcr = Mpcr + 1
            }
         Mpcr = Mpcr + 2                  # SKIP
         Mpcr = Ampcr + 1                 # JUMP
         Micro_fetch_addr = Ampcr + 1     # EXEC
         {                                # CALL
            temp = Mpcr
            Mpcr = Ampcr + 1
            Ampcr = temp
            }
         Mpcr = Ampcr + 2                 # RETN
         }
      else
         call error ("in select_successor_address: can't happen.")

      if (successor ~= 6)  # if not EXEC then ...
         Micro_fetch_addr = Mpcr
      }

   return
   end


# set_condition --- decide if conditional commands are to be performed

   subroutine set_condition

   include "dmach_com.r.i"

   logical test

   case N_condition_select {
      test = Gc1
      test = Gc2
     {test = Lc1; Lc1 = FALSE}
     {test = Lc2; Lc2 = FALSE}
      test = Mst
      test = Lst
      test = Abt
      test = Aov
     {test = Cov; Cov = FALSE}
     {test = Sai; Sai = FALSE}
     {test = Rdc; Rdc = FALSE}
     {test = Lc3; Lc3 = FALSE}
     {test = Ex1; Ex1 = FALSE}
     {test = Int; Int = FALSE}
     {test = Ex2; Ex2 = FALSE}
     {test = Ex3; Ex3 = FALSE}
      }
   else
      call error ("in set_condition: can't happen.")

   if (N_true_condition)
      Condition = test
   else
      Condition = ~test

   return
   end


# terminate_clock_cycle --- clean up at the end of a clock cycle

   subroutine terminate_clock_cycle

   include "dmach_com.r.i"

   Non_phase_1_fetch_addr = Next_non_phase_1_fetch_addr

   return
   end


# terminate_simulation --- clean up the D-machine simulator

   subroutine terminate_simulation

   include "dmach_com.r.i"

   call print (STDOUT, "*nEnd of Simulation - Machine State is:*n.")
   call print_state
   if (Memory_dump)
      call dump_s_memory

   return
   end


# trace_info --- print trace information for last cycle per options

   subroutine trace_info

   include "dmach_com.r.i"

   if (Micro_fetch_addr >= Trace_start_addr
     && Micro_fetch_addr <= Trace_stop_addr
     && mod (Clock, Trace_interval) == 0)
      call print_state

   return
   end


# update_b_register --- select the input to the B register

   subroutine update_b_register

   include "dmach_com.r.i"

   case Lu_b_select {
      ;                                   # No change
      B = 0                               # BC4
      B = Adder_output                    # BAD
      B = 0                               # BC8
      B = or (Bsw_output, Adder_output)   # BBA
      B = Bsw_output                      # B
      B = Ext                             # BEX
      B = Mir                             # BMI
      B = or (Bsw_output, Ext)            # BBE
      B = or (Bsw_output, Mir)            # BBI
      }
   else
      call error ("in update_b_register: can't happen.")

   return
   end


# update_ctr --- update the Ctr register

   subroutine update_ctr

   include "dmach_com.r.i"

   case Lu_ctr_select {
      ;
      {  # ~ Lit
         Cov = FALSE
         Ctr = and (not (Lit), MASK_LOW_BYTE)
         }
      {  # Inc
         Ctr = Ctr + 1
         if (Ctr > 255) {
            Ctr = 0
            Cov = TRUE
            }
         }
      {  # ~ Bsw
         Cov = FALSE
         Ctr = and (not (Bsw_output), MASK_LOW_BYTE)
         }
      }
   else
      call error ("in update_ctr: can't happen.")

   return
   end


# update_destinations --- clock all selected destination registers

   subroutine update_destinations

   include "dmach_com.r.i"

   if (Lu_set_a1)
      A1 = Bsw_output
   if (Lu_set_a2)
      A2 = Bsw_output
   if (Lu_set_a3)
      A3 = Bsw_output

   call update_b_register

   if (Lu_set_mir)
      Mir = Bsw_output
   if (Lu_set_ampcr)
      Ampcr = and (Bsw_output, MASK_LOW_12_BITS)
   if (Lu_set_br1)
      Br1 = and (rs (Bsw_output, 8), MASK_LOW_BYTE)
   if (Lu_set_br2)
      Br2 = and (rs (Bsw_output, 8), MASK_LOW_BYTE)
   if (Lu_set_mar)
      if (Lu_lmar)
         Mar = Lit
      else
         Mar = and (Bsw_output, MASK_LOW_BYTE)

   call update_ctr
   call update_sar

   return
   end


# update_lu_controls --- update logic unit control register

   subroutine update_lu_controls

   include "dmach_com.r.i"
   include "bit_field_dcl.r.i"

   Lu_x_select           = bit_field (Nano_instruction (2),  1,  3) + 1
   Lu_y_select           = bit_field (Nano_instruction (2),  6,  8) + 1
   Lu_b_mask_high        = bit_field (Nano_instruction (2),  4,  5) + 1
   Lu_b_mask_mid         = bit_field (Nano_instruction (2),  6,  6) + 1
   Lu_b_mask_low         = bit_field (Nano_instruction (2),  9, 10) + 1
   Lu_inhibit_carry      = bit_field (Nano_instruction (2), 11, 11) == 1
   Lu_adder_op           = bit_field (Nano_instruction (2), 12, 15) + 1
   Lu_shift_select       = bit_field (Nano_instruction (2), 16, 16) * 2 _
                         + bit_field (Nano_instruction (3),  1,  1) + 1
   Lu_set_a1             = bit_field (Nano_instruction (3),  2,  2) == 1
   Lu_set_a2             = bit_field (Nano_instruction (3),  3,  3) == 1
   Lu_set_a3             = bit_field (Nano_instruction (3),  4,  4) == 1
   Lu_b_select           = bit_field (Nano_instruction (3),  5,  8) - 5
   if (Lu_b_select < 0)
      Lu_b_select = Lu_b_select + 6
   Lu_set_mir            = bit_field (Nano_instruction (3),  9,  9) == 1
   Lu_set_ampcr          = bit_field (Nano_instruction (3), 10, 10) == 1
   Lu_set_mar            = bit_field (Nano_instruction (3), 13, 13) == 1
   Lu_lmar               = bit_field (Nano_instruction (3), 13, 14) == 2
   Lu_set_br1            = bit_field (Nano_instruction (3), 11, 11) == 1
   Lu_set_br2            = bit_field (Nano_instruction (3), 12, 12) == 1
   Lu_ctr_select         = bit_field (Nano_instruction (3), 15, 16) + 1
   if (Lu_ctr_select == 2   # from Lit or Barrel Switch?
     && bit_field (Nano_instruction (3), 14, 14) == 1)
      Lu_ctr_select = 4
   Lu_sar_select         = bit_field (Nano_instruction (4),  1,  2) + 1

   return
   end


# update_sar --- update the Shift Amount Register

   subroutine update_sar

   include "dmach_com.r.i"

   case Lu_sar_select {
      ;                 # No change
      Sar = 32 - Sar    # CSAR
      Sar = and ( _     # SAR
               xor ( _
                  and (rs (Bsw_output, 1), not (MASK_LOW_2_BITS)),
                  and (Bsw_output, MASK_LOW_2_BITS)),
               MASK_LOW_5_BITS)
      }
   else
      call error ("in update_sar: can't happen.")

   return
   end


# x_input_select --- select the X adder input

   subroutine x_input_select

   include "dmach_com.r.i"

   case Lu_x_select {
      X_input = 0
      X_input = Lit
      X_input = Ext
      X_input = ls (Ctr, 24)
      X_input = xor (ls (Ctr, 24), Lit)
      X_input = A1
      X_input = A2
      X_input = A3
      }
   else
      call error ("in x_input_select: can't happen.")

   return
   end


# y_input_from_masked_b_register --- the name is self-explanatory

   subroutine y_input_from_masked_b_register

   include "dmach_com.r.i"

   longint b_high, b_mid, b_low

   case Lu_b_mask_high {
      b_high = 0                             # B.0xx
      b_high = and (B, MASK_HIGH_BIT)        # B.Txx
      b_high = and (not (B), MASK_HIGH_BIT)  # B.Fxx
      b_high = MASK_HIGH_BIT                 # B.1xx
      }
   else
      call error ("in y_input_from_masked_b_register: can't happen.")

   case Lu_b_mask_mid {
      b_mid = 0                              # B.x0x
      b_mid = and (B, MASK_CENTER_BITS)      # B.xTx
      }
   else
      call error ("in y_input_from_masked_b_register: can't happen.")

   case Lu_b_mask_low {
      b_low = 0                              # B.xx0
      b_low = and (B, MASK_LOW_BIT)          # B.xxT
      b_low = and (not (B), MASK_LOW_BIT)    # B.xxF
      b_low = MASK_LOW_BIT                   # B.xx1
      }
   else
      call error ("in y_input_from_masked_b_register: can't happen.")

   Y_input = xor (b_high, b_mid, b_low)

   return
   end


# y_input_select --- select the Y adder input

   subroutine y_input_select

   include "dmach_com.r.i"

   case Lu_y_select {
      call y_input_from_masked_b_register
      Y_input = Lit
      Y_input = Ext
      Y_input = ls (Ctr, 24)
      call y_input_from_masked_b_register
      Y_input = xor (ls (Ctr, 24), Lit)
      Y_input = Ampcr
      Y_input = Bmar
      }

   return
   end
