View Javadoc

1   package com.tapina.robe.runtime.instruction;
2   
3   import com.tapina.robe.runtime.Instruction;
4   import com.tapina.robe.runtime.Environment;
5   import com.tapina.robe.runtime.Condition;
6   
7   import java.io.Writer;
8   import java.io.IOException;
9   
10  /***
11   * Created by IntelliJ IDEA.
12   * User: gareth
13   * Date: Sep 2, 2003
14   * Time: 5:05:25 PM
15   */
16  public final class MultipleTransferInstruction extends Instruction {
17      private final MultipleTransfer transfer;
18      private final int[] registers;
19      private final MultipleAddressSource addressSource;
20      private final boolean useBaseValue;
21      private final boolean psrForceUser;
22  
23      public final static MultipleTransfer LDM = new MultipleTransfer() {
24          public boolean transfer(Environment env, int[] destinationRegisters, int address, int baseRegisterValue, boolean useBaseValue, boolean psrForceUser) {
25              final int[] R = env.getCpu().R;
26              final int count = destinationRegisters.length;
27              final int[] values = env.getMemoryMap().getWords(address, count);
28              for (int i = 0; i < count; i++) {
29                  if (destinationRegisters[i] == 15 && !psrForceUser) {
30                      env.getCpu().setPC(values[i]);
31                  } else {
32                      R[destinationRegisters[i]] = values[i];
33                  }
34              }
35              return destinationRegisters[destinationRegisters.length - 1] == 15;
36          }
37  
38          public void dumpJavaSource(Writer out, int[] destinationRegisters, boolean useBaseValue, boolean psrForceUser) throws IOException {
39              final int count = destinationRegisters.length;
40              out.write("final int[] values = memoryMap.loadWords(address, " + count + ");\n");
41              if (destinationRegisters[count - 1] == 15 && !psrForceUser) {
42                  dumpLoop(count - 1, out, destinationRegisters);
43                  out.write("cpu.setPC(values[" + (count - 1) + "]);\n");
44              } else {
45                  dumpLoop(count, out, destinationRegisters);
46              }
47              if (destinationRegisters[count - 1] == 15) {
48                  out.write("return;");
49              }
50          }
51  
52          private void dumpLoop(int count, Writer out, int[] destinationRegisters) throws IOException {
53              for (int i = 0; i < count; i++) {
54                  out.write("R[" + destinationRegisters[i] + "] = values[" + i + "];\n");
55              }
56          }
57  
58      };
59  
60      public final static MultipleTransfer STM = new MultipleTransfer() {
61          public boolean transfer(Environment env, int[] destinationRegisters, int address, int baseRegisterValue, boolean useBaseValue, boolean psrForceUser) {
62              final int[] R = env.getCpu().R;
63              final int count = destinationRegisters.length;
64              int[] values = new int[count];
65              for (int i = 0; i < count; i++) {
66                  values[i] = (i == 0 && useBaseValue) ? baseRegisterValue : R[destinationRegisters[i]];
67              }
68              env.getMemoryMap().storeWords(address, values); // TODO: This extends the block afterwards backwards by mistake
69              return false;
70          }
71  
72          public void dumpJavaSource(Writer out, int[] destinationRegisters, boolean useBaseValue, boolean psrForceUser) throws IOException {
73              final int count = destinationRegisters.length;
74              out.write("final int[] values = new int[] {\n");
75              for (int i = 0; i < count; i++) {
76                  if (i == 0 && useBaseValue) {
77                      out.write("baseRegisterValue");
78                  } else {
79                      out.write("R[" + destinationRegisters[i] + "]");
80                  }
81                  if (i < count - 1) {
82                      out.write(",\n");
83                  } else {
84                      out.write(" };\n");
85                  }
86              }
87              out.write("memoryMap.storeWords(address, values);\n");
88          }
89      };
90  
91      public MultipleTransferInstruction(Condition condition, MultipleTransfer transfer, int[] registers,
92                                         MultipleAddressSource addressSource, boolean useBaseValue, boolean psrForceUser) {
93          super(condition);
94          this.transfer = transfer;
95          this.registers = registers;
96          this.addressSource = addressSource;
97          this.useBaseValue = useBaseValue;
98          this.psrForceUser = psrForceUser;
99      }
100 
101     protected final boolean execute(Environment environment) {
102         final int baseRegisterValue = environment.getCpu().R[addressSource.getBaseRegister()];
103         return transfer.transfer(environment, registers, addressSource.getTransferAddress(environment.getCpu()),
104                 baseRegisterValue, useBaseValue, psrForceUser);
105     }
106 
107     public void dumpJavaSourceUnconditional(Writer out) throws IOException {
108         out.write("final int baseRegisterValue = R[" + addressSource.getBaseRegister() + "];\n");
109         addressSource.dumpJavaSource("address", out);
110         transfer.dumpJavaSource(out, registers, useBaseValue, psrForceUser);
111     }
112 }