| 1 | // Copyright © 2004-2006 University of Helsinki, Department of Computer Science | |
| 2 | // Copyright © 2012 various contributors | |
| 3 | // This software is released under GNU Lesser General Public License 2.1. | |
| 4 | // The license text is at http://www.gnu.org/licenses/lgpl-2.1.html | |
| 5 | ||
| 6 | package fi.helsinki.cs.titokone; | |
| 7 | ||
| 8 | import java.util.LinkedList; | |
| 9 | ||
| 10 | /** | |
| 11 | * This class produces objects describing what has changed due to the last | |
| 12 | * command having been run. | |
| 13 | */ | |
| 14 | public class RunDebugger { | |
| 15 | ||
| 16 | /** | |
| 17 | * constant numerical value for operation type NOP | |
| 18 | */ | |
| 19 | public static final short NO_OPERATION = 0; | |
| 20 | /** | |
| 21 | * constant numerical value for Data transfer operation type | |
| 22 | */ | |
| 23 | public static final short DATA_TRANSFER_OPERATION = 1; | |
| 24 | /** | |
| 25 | * constant numerical value for ALU-operation type | |
| 26 | */ | |
| 27 | public static final short ALU_OPERATION = 2; | |
| 28 | /** | |
| 29 | * constant numerical value for Comparing operation type | |
| 30 | */ | |
| 31 | public static final short COMP_OPERATION = 3; | |
| 32 | /** | |
| 33 | * constant numerical value for branching operation type | |
| 34 | */ | |
| 35 | public static final short BRANCH_OPERATION = 4; | |
| 36 | /** | |
| 37 | * constant numerical value for subroutines operation type | |
| 38 | */ | |
| 39 | public static final short SUB_OPERATION = 5; | |
| 40 | /** | |
| 41 | * constant numerical value for stack operation type | |
| 42 | */ | |
| 43 | public static final short STACK_OPERATION = 6; | |
| 44 | /** | |
| 45 | * constant numerical value for SVC operation type | |
| 46 | */ | |
| 47 | public static final short SVC_OPERATION = 7; | |
| 48 | ||
| 49 | /** | |
| 50 | * constant short for supervisor call Halt | |
| 51 | */ | |
| 52 | public static final short SVC_HALT = 11; | |
| 53 | /** | |
| 54 | * constant short for supervisor call Read | |
| 55 | */ | |
| 56 | public static final short SVC_READ = 12; | |
| 57 | /** | |
| 58 | * constant short for supervisor call Write | |
| 59 | */ | |
| 60 | public static final short SVC_WRITE = 13; | |
| 61 | /** | |
| 62 | * constant short for supervisor call Time | |
| 63 | */ | |
| 64 | public static final short SVC_TIME = 14; | |
| 65 | /** | |
| 66 | * constant short for supervisor call Date | |
| 67 | */ | |
| 68 | public static final short SVC_DATE = 15; | |
| 69 | ||
| 70 | ||
| 71 | /** | |
| 72 | * constant String for comment line memory addressing | |
| 73 | */ | |
| 74 | private static final String DIRECT = "direct"; | |
| 75 | /** | |
| 76 | * constant String for comment line memory addressing | |
| 77 | */ | |
| 78 | private static final String DIRECT_ADDRESSING = "direct addressing"; | |
| 79 | /** | |
| 80 | * constant String for comment line memory addressing | |
| 81 | */ | |
| 82 | private static final String INDIRECT_ADDRESSING = "indirect addressing"; | |
| 83 | /** | |
| 84 | * String for memory part of comment | |
| 85 | */ | |
| 86 | private String memoryComment; | |
| 87 | /** | |
| 88 | * String array for the comment message | |
| 89 | */ | |
| 90 | 3 | private String[] parameters = new String[3]; |
| 91 | private int deviceValue; | |
| 92 | ||
| 93 | /** | |
| 94 | * Runinfo for each command line of the program | |
| 95 | */ | |
| 96 | private RunInfo info; | |
| 97 | /** | |
| 98 | * List of changed memory lines | |
| 99 | */ | |
| 100 | 2 | private LinkedList<Object[]> changedMemoryLines = new LinkedList<Object[]>(); |
| 101 | /** | |
| 102 | * Compare bit tells compare status of status register. | |
| 103 | * 0 - greater, 1 - equal, 2 - less. | |
| 104 | */ | |
| 105 | 3 | private int compareBit = -1; |
| 106 | ||
| 107 | /** | |
| 108 | * This constructor initializes the RunDebugger. | |
| 109 | */ | |
| 110 | public RunDebugger() { | |
| 111 | } | |
| 112 | ||
| 113 | /** | |
| 114 | * This method tells debugger that a new cycle has been started. | |
| 115 | * | |
| 116 | * @param lineNumber Tells the number of the current command line in memory. | |
| 117 | * @param lineContents String containing symbolic command. | |
| 118 | */ | |
| 119 | public void cycleStart(int lineNumber, String lineContents) { | |
| 120 | 2 | this.parameters[1] = lineContents; |
| 121 | 2 | info = new RunInfo(lineNumber, lineContents); |
| 122 | } | |
| 123 | ||
| 124 | /** | |
| 125 | * This method sets the type of operation. | |
| 126 | * | |
| 127 | * @param opcode Operation code of command. | |
| 128 | */ | |
| 129 | public void setOperationType(int opcode) { | |
| 130 | 1 | info.setOperationType(opcode); |
| 131 | } | |
| 132 | ||
| 133 | /** | |
| 134 | * This method tells what was operation run and its parts. | |
| 135 | * | |
| 136 | * @param command TTK91 command. | |
| 137 | */ | |
| 138 | public void runCommand(int command) { | |
| 139 | // cut up the command | |
| 140 | 1 | Instruction insn = new Instruction(command); |
| 141 | ||
| 142 | 1 | info.setBinary(command); |
| 143 | 2 | info.setFirstOperand(insn.getRj()); |
| 144 | 2 | info.setIndexRegister(insn.getRi()); |
| 145 | 2 | info.setADDR(insn.getAddr()); |
| 146 | 2 | info.setNumberOfFetches(insn.getM()); |
| 147 | 2 | info.setColonString(insn.toColonString()); |
| 148 | ||
| 149 | 1 | switch (insn.getM()) { |
| 150 | case 0: | |
| 151 | 1 | memoryComment = DIRECT; |
| 152 | break; | |
| 153 | ||
| 154 | case 1: | |
| 155 | 1 | memoryComment = DIRECT_ADDRESSING; |
| 156 | break; | |
| 157 | ||
| 158 | case 2: | |
| 159 | 1 | memoryComment = INDIRECT_ADDRESSING; |
| 160 | break; | |
| 161 | ||
| 162 | } | |
| 163 | ||
| 164 | 7 | this.parameters[0] = insn.toColonString() + " "; |
| 165 | 7 | this.parameters[2] = "R" + insn.getRi(); |
| 166 | ||
| 167 | } | |
| 168 | ||
| 169 | /** | |
| 170 | * This method tells debugger what value was found from the ADDR part of | |
| 171 | * the command. | |
| 172 | * | |
| 173 | * @param value int containing the value. | |
| 174 | */ | |
| 175 | public void setValueAtADDR(int value) { | |
| 176 | 1 | info.setValueAtADDR(value); |
| 177 | } | |
| 178 | ||
| 179 | /** | |
| 180 | * This method tells debugger that one or more registers were changed. | |
| 181 | * If value has not changed, value is null, | |
| 182 | * otherwise changed value is in current index | |
| 183 | * | |
| 184 | * @param registers Array containing new values. | |
| 185 | */ | |
| 186 | public void setRegisters(int[] registers) { | |
| 187 | 1 | info.setRegisters(registers); |
| 188 | } | |
| 189 | ||
| 190 | /** | |
| 191 | * This method tells debugger that one or more memorylines were changed. | |
| 192 | * First cell contains number of the line and second the new value.. | |
| 193 | * | |
| 194 | * @param row The index of the changed line in memory. | |
| 195 | * @param changedMemoryLine The changed memory line. | |
| 196 | */ | |
| 197 | public void addChangedMemoryLine(int row, MemoryLine changedMemoryLine) { | |
| 198 | 2 | Object[] entry = new Object[2]; |
| 199 | 3 | entry[0] = new Integer(row); |
| 200 | 2 | entry[1] = changedMemoryLine; |
| 201 | 1 | changedMemoryLines.add(entry); |
| 202 | } | |
| 203 | ||
| 204 | /** | |
| 205 | * This method sets the result of ALU operation. | |
| 206 | * | |
| 207 | * @param result Value of result. | |
| 208 | */ | |
| 209 | public void setALUResult(int result) { | |
| 210 | 1 | info.setALUResult(result); |
| 211 | } | |
| 212 | ||
| 213 | /** | |
| 214 | * This method tells what was the result of compare operation. | |
| 215 | * | |
| 216 | * @param whichBit Number of SR bit set. | |
| 217 | */ | |
| 218 | public void setCompareResult(int whichBit) { | |
| 219 | 1 | compareBit = whichBit; |
| 220 | } | |
| 221 | ||
| 222 | /** | |
| 223 | * This method sets value of second memory fetch. Indirect memory | |
| 224 | * accessing mode needs two memory fetches. | |
| 225 | * | |
| 226 | * @param secondFetchValue Value which have got at second memory fetch. | |
| 227 | */ | |
| 228 | public void setSecondFetchValue(int secondFetchValue) { | |
| 229 | 1 | info.setSecondFetchValue(secondFetchValue); |
| 230 | } | |
| 231 | ||
| 232 | /** | |
| 233 | * This method tells debugger that something was read from the given | |
| 234 | * device. Devices are STDIN and KBD. | |
| 235 | * | |
| 236 | * @param deviceNumber Number of the device. | |
| 237 | * @param value Value written. | |
| 238 | */ | |
| 239 | public void setIN(int deviceNumber, int value) { | |
| 240 | 1 | this.deviceValue = value; |
| 241 | ||
| 242 | switch (deviceNumber) { | |
| 243 | case Processor.KBD: | |
| 244 | 5 | info.setIN(new Message("keyboard").toString(), Processor.KBD, value); |
| 245 | break; | |
| 246 | ||
| 247 | case Processor.STDIN: | |
| 248 | 5 | info.setIN(new Message("stdin").toString(), Processor.STDIN, value); |
| 249 | break; | |
| 250 | } | |
| 251 | } | |
| 252 | ||
| 253 | /** | |
| 254 | * This method tells debugger that something was written to the given | |
| 255 | * device. Devices are STDOUT and CRT. | |
| 256 | * | |
| 257 | * @param deviceNumber Number of the device. | |
| 258 | * @param value Value written. | |
| 259 | */ | |
| 260 | public void setOUT(int deviceNumber, int value) { | |
| 261 | 1 | this.deviceValue = value; |
| 262 | ||
| 263 | switch (deviceNumber) { | |
| 264 | ||
| 265 | case Processor.CRT: | |
| 266 | 5 | info.setOUT(new Message("display").toString(), Processor.CRT, value); |
| 267 | break; | |
| 268 | ||
| 269 | case Processor.STDOUT: | |
| 270 | 5 | info.setOUT(new Message("stdout").toString(), Processor.STDOUT, value); |
| 271 | break; | |
| 272 | } | |
| 273 | ||
| 274 | ||
| 275 | } | |
| 276 | ||
| 277 | /** | |
| 278 | * This method tells debugger which SVC operation was done. | |
| 279 | * | |
| 280 | * @param operation Int containing operation type. | |
| 281 | */ | |
| 282 | public void setSVCOperation(int operation) { | |
| 283 | switch (operation) { | |
| 284 | case SVC_HALT: | |
| 285 | 1 | info.setSVCOperation("Halt"); |
| 286 | break; | |
| 287 | ||
| 288 | case SVC_READ: | |
| 289 | 1 | info.setSVCOperation("Read"); |
| 290 | break; | |
| 291 | ||
| 292 | case SVC_WRITE: | |
| 293 | 1 | info.setSVCOperation("Write"); |
| 294 | break; | |
| 295 | ||
| 296 | case SVC_TIME: | |
| 297 | 1 | info.setSVCOperation("Time"); |
| 298 | break; | |
| 299 | ||
| 300 | case SVC_DATE: | |
| 301 | 1 | info.setSVCOperation("Date"); |
| 302 | break; | |
| 303 | ||
| 304 | } | |
| 305 | } | |
| 306 | ||
| 307 | /** | |
| 308 | * Sets the comment message of the current RunInfo. | |
| 309 | */ | |
| 310 | ||
| 311 | private void setComments() { | |
| 312 | 2 | if (info.isExternalOp()) { |
| 313 | 2 | String[] param = new String[4]; |
| 314 | 4 | param[0] = parameters[0]; |
| 315 | 4 | param[1] = parameters[1]; |
| 316 | 4 | param[2] = parameters[2]; |
| 317 | 6 | param[3] = "" + this.deviceValue; |
| 318 | ||
| 319 | 8 | info.setComments(new Message("{0}{1} Indexing {2}, " + memoryComment + ", value {3}.", param).toString()); |
| 320 | } else { | |
| 321 | 8 | info.setComments(new Message("{0}{1} Indexing {2}, " + memoryComment + ".", parameters).toString()); |
| 322 | } | |
| 323 | } | |
| 324 | ||
| 325 | /** | |
| 326 | * Sets value of new PC. | |
| 327 | * | |
| 328 | * @param newPC Value of new PC. | |
| 329 | */ | |
| 330 | public void setNewPC(int newPC) { | |
| 331 | 1 | info.setNewPC(newPC); |
| 332 | } | |
| 333 | ||
| 334 | /** | |
| 335 | * This method return the current runinfo | |
| 336 | * after the line is executed | |
| 337 | * | |
| 338 | * @return RunInfo of the current line. | |
| 339 | */ | |
| 340 | public RunInfo cycleEnd() { | |
| 341 | 1 | this.setComments(); |
| 342 | 1 | info.setChangedMemoryLines(changedMemoryLines); |
| 343 | 1 | info.setCompareOperation(compareBit); |
| 344 | 2 | changedMemoryLines = new LinkedList<Object[]>(); |
| 345 | 1 | return info; |
| 346 | } | |
| 347 | } | |
Mutations | ||
| 90 |
Substituted 3 with 4 : SURVIVED Removed assignment to member variable parameters : SURVIVED Substituted 3 with 4 : SURVIVED |
|
| 100 |
Removed assignment to member variable changedMemoryLines : SURVIVED removed call to java/util/LinkedList::<init> : SURVIVED |
|
| 105 |
Substituted -1 with 1 : SURVIVED Substituted -1 with 0 : SURVIVED Removed assignment to member variable compareBit : SURVIVED |
|
| 120 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 121 |
removed call to fi/helsinki/cs/titokone/RunInfo::<init> : NO_COVERAGE Removed assignment to member variable info : NO_COVERAGE |
|
| 130 |
removed call to fi/helsinki/cs/titokone/RunInfo::setOperationType : NO_COVERAGE |
|
| 140 |
removed call to fi/helsinki/cs/titokone/Instruction::<init> : NO_COVERAGE |
|
| 142 |
removed call to fi/helsinki/cs/titokone/RunInfo::setBinary : NO_COVERAGE |
|
| 143 |
removed call to fi/helsinki/cs/titokone/Instruction::getRj : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::setFirstOperand : NO_COVERAGE |
|
| 144 |
removed call to fi/helsinki/cs/titokone/Instruction::getRi : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::setIndexRegister : NO_COVERAGE |
|
| 145 |
removed call to fi/helsinki/cs/titokone/RunInfo::setADDR : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Instruction::getAddr : NO_COVERAGE |
|
| 146 |
removed call to fi/helsinki/cs/titokone/Instruction::getM : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::setNumberOfFetches : NO_COVERAGE |
|
| 147 |
removed call to fi/helsinki/cs/titokone/Instruction::toColonString : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::setColonString : NO_COVERAGE |
|
| 149 |
removed call to fi/helsinki/cs/titokone/Instruction::getM : NO_COVERAGE |
|
| 151 |
Removed assignment to member variable memoryComment : NO_COVERAGE |
|
| 155 |
Removed assignment to member variable memoryComment : NO_COVERAGE |
|
| 159 |
Removed assignment to member variable memoryComment : NO_COVERAGE |
|
| 164 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE removed call to java/lang/StringBuilder::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::toString : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Instruction::toColonString : NO_COVERAGE |
|
| 165 |
removed call to java/lang/StringBuilder::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::toString : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Instruction::getRi : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE |
|
| 176 |
removed call to fi/helsinki/cs/titokone/RunInfo::setValueAtADDR : NO_COVERAGE |
|
| 187 |
removed call to fi/helsinki/cs/titokone/RunInfo::setRegisters : NO_COVERAGE |
|
| 198 |
Substituted 2 with 3 : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE |
|
| 199 |
Substituted 0 with 1 : NO_COVERAGE removed call to java/lang/Integer::<init> : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 200 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 201 |
removed call to java/util/LinkedList::add : NO_COVERAGE |
|
| 210 |
removed call to fi/helsinki/cs/titokone/RunInfo::setALUResult : NO_COVERAGE |
|
| 219 |
Removed assignment to member variable compareBit : NO_COVERAGE |
|
| 229 |
removed call to fi/helsinki/cs/titokone/RunInfo::setSecondFetchValue : NO_COVERAGE |
|
| 240 |
Removed assignment to member variable deviceValue : NO_COVERAGE |
|
| 244 |
removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::setIN : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE |
|
| 248 |
removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::setIN : NO_COVERAGE Replaced constant value of 6 with 7 : NO_COVERAGE Substituted 6 with 7 : NO_COVERAGE |
|
| 261 |
Removed assignment to member variable deviceValue : NO_COVERAGE |
|
| 266 |
removed call to fi/helsinki/cs/titokone/RunInfo::setOUT : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 270 |
Replaced constant value of 7 with 8 : NO_COVERAGE Substituted 7 with 8 : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::setOUT : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE |
|
| 285 |
removed call to fi/helsinki/cs/titokone/RunInfo::setSVCOperation : NO_COVERAGE |
|
| 289 |
removed call to fi/helsinki/cs/titokone/RunInfo::setSVCOperation : NO_COVERAGE |
|
| 293 |
removed call to fi/helsinki/cs/titokone/RunInfo::setSVCOperation : NO_COVERAGE |
|
| 297 |
removed call to fi/helsinki/cs/titokone/RunInfo::setSVCOperation : NO_COVERAGE |
|
| 301 |
removed call to fi/helsinki/cs/titokone/RunInfo::setSVCOperation : NO_COVERAGE |
|
| 312 |
removed call to fi/helsinki/cs/titokone/RunInfo::isExternalOp : NO_COVERAGE negated conditional : NO_COVERAGE |
|
| 313 |
Substituted 4 with 5 : NO_COVERAGE Substituted 4 with 5 : NO_COVERAGE |
|
| 314 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 315 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 316 |
Substituted 2 with 3 : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE |
|
| 317 |
removed call to java/lang/StringBuilder::toString : NO_COVERAGE removed call to java/lang/StringBuilder::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE Substituted 3 with 4 : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE Substituted 3 with 4 : NO_COVERAGE |
|
| 319 |
removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::toString : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::setComments : NO_COVERAGE |
|
| 321 |
removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::setComments : NO_COVERAGE removed call to java/lang/StringBuilder::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::toString : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE |
|
| 331 |
removed call to fi/helsinki/cs/titokone/RunInfo::setNewPC : NO_COVERAGE |
|
| 341 |
removed call to fi/helsinki/cs/titokone/RunDebugger::setComments : NO_COVERAGE |
|
| 342 |
removed call to fi/helsinki/cs/titokone/RunInfo::setChangedMemoryLines : NO_COVERAGE |
|
| 343 |
removed call to fi/helsinki/cs/titokone/RunInfo::setCompareOperation : NO_COVERAGE |
|
| 344 |
removed call to java/util/LinkedList::<init> : NO_COVERAGE Removed assignment to member variable changedMemoryLines : NO_COVERAGE |
|
| 345 |
mutated return of Object value for fi/helsinki/cs/titokone/RunDebugger::cycleEnd to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |