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);
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 }