├── README.md └── avr-simulator.js /README.md: -------------------------------------------------------------------------------- 1 | avr-simulator 2 | ============= 3 | avr-simulator is an AVR microcontroller simulator written in JavaScript, designed for educational purposes. 4 | 5 | Using 6 | ----- 7 | ``` 8 | 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /avr-simulator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * 8-bit AVR Instruction set written in Javascript 5 | * by Andor Polgar (hngrhorace) 2013 6 | * 7 | * 8 | * 9 | * Nomenclature 10 | * 11 | * Status register (SREG) 12 | * SREG: Status register 13 | * C: Carry Flag 14 | * Z: Zero Flag 15 | * N: Negative Flag 16 | * V: Two's complement overflow indicator 17 | * S: N ^ V, For signed tests 18 | * H: Half Carry Flag 19 | * T: Transfer bit used by BLD and BST instructions 20 | * I: Global Interrupt Enable/Disable Flag 21 | * 22 | * Registers and Operands 23 | * Rd: Destination (and source) register in the Register File 24 | * Rr: Source register 25 | * R: Result after instruction is executed 26 | * K: Constant data 27 | * k: Constant address 28 | * b: Bit in the Register File or I/O Register (3-bit) 29 | * s: Bit in the Status Register (3-bit) 30 | * X, Y, Z: Indirect Address Register 31 | * A: I/O location address 32 | * q: Displacement for direct addressing (6-bit) 33 | * 34 | */ 35 | var avr = { 36 | /** Program counter */ 37 | PC: 0, 38 | /** SPH - Stack Pointer Low */ 39 | spl: 0x5d, 40 | /** SPH - Stack Pointer High */ 41 | sph: 0x5e, 42 | /** 43 | * SREG - Status Register 44 | * 0 1 2 3 4 5 6 7 45 | * .-------.-------.-------.-------.-------.-------.-------.-------. 46 | * | C | Z | N | V | S | H | T | I | 47 | * '-------'-------'-------'-------'-------'-------'-------'-------' 48 | * C - Carry flag 49 | * Z - Zero flag 50 | * N - Negative Flag 51 | * V - Two's Complement Overflow Flag 52 | * S - Sign Bit 53 | * H - Half Carry Flag 54 | * T - Bit Copy Storage 55 | * I - Global interrupt enable 56 | */ 57 | sreg: 0x5f, 58 | /* 59 | * Data Space 60 | * 61 | * 0 1 2 3 4 5 6 7 62 | * .-------.-------.-------.-------.-------.-------.-------.-------. 63 | * | LSB | | | | | | | MSB | 64 | * '-------'-------'-------'-------'-------'-------'-------'-------' 65 | */ 66 | dataspace: { 67 | /** 68 | * Register Space 0x00 - 0xFF 69 | */ 70 | 71 | /* 72 | * General Purpose Register File 0x00 - 0x1f 73 | * MSB LSB */ 74 | 0x00: [false, false, false, false, false, false, false, false], /* R0 */ 75 | 0x01: [false, false, false, false, false, false, false, false], /* R1 */ 76 | 0x02: [false, false, false, false, false, false, false, false], /* R2 */ 77 | 0x03: [false, false, false, false, false, false, false, false], /* R3 */ 78 | 0x04: [false, false, false, false, false, false, false, false], /* R4 */ 79 | 0x05: [false, false, false, false, false, false, false, false], /* R5 */ 80 | 0x06: [false, false, false, false, false, false, false, false], /* R6 */ 81 | 0x07: [false, false, false, false, false, false, false, false], /* R7 */ 82 | 0x08: [false, false, false, false, false, false, false, false], /* R8 */ 83 | 0x09: [false, false, false, false, false, false, false, false], /* R9 */ 84 | 0x0a: [false, false, false, false, false, false, false, false], /* R10 */ 85 | 0x0b: [false, false, false, false, false, false, false, false], /* R11 */ 86 | 0x0c: [false, false, false, false, false, false, false, false], /* R12 */ 87 | 0x0d: [false, false, false, false, false, false, false, false], /* R13 */ 88 | 0x0e: [false, false, false, false, false, false, false, false], /* R14 */ 89 | 0x0f: [false, false, false, false, false, false, false, false], /* R15 */ 90 | 91 | 0x10: [false, false, false, false, false, false, false, false], /* R16 */ 92 | 0x11: [false, false, false, false, false, false, false, false], /* R17 */ 93 | 0x12: [false, false, false, false, false, false, false, false], /* R18 */ 94 | 0x13: [false, false, false, false, false, false, false, false], /* R19 */ 95 | 0x14: [false, false, false, false, false, false, false, false], /* R20 */ 96 | 0x15: [false, false, false, false, false, false, false, false], /* R21 */ 97 | 0x16: [false, false, false, false, false, false, false, false], /* R22 */ 98 | 0x17: [false, false, false, false, false, false, false, false], /* R23 */ 99 | 0x18: [false, false, false, false, false, false, false, false], /* R24 */ 100 | 0x19: [false, false, false, false, false, false, false, false], /* R25 */ 101 | 0x1a: [false, false, false, false, false, false, false, false], /* R26 X-register Low Byte */ 102 | 0x1b: [false, false, false, false, false, false, false, false], /* R27 X-register High Byte */ 103 | 0x1c: [false, false, false, false, false, false, false, false], /* R28 Y-register Low Byte */ 104 | 0x1d: [false, false, false, false, false, false, false, false], /* R29 Y-register High Byte */ 105 | 0x1e: [false, false, false, false, false, false, false, false], /* R30 Z-register Low Byte */ 106 | 0x1f: [false, false, false, false, false, false, false, false], /* R31 Z-register High Byte */ 107 | 108 | 0x20: [false, false, false, false, false, false, false, false], 109 | 0x21: [false, false, false, false, false, false, false, false], 110 | 0x22: [false, false, false, false, false, false, false, false], 111 | 0x23: [false, false, false, false, false, false, false, false], 112 | 0x24: [false, false, false, false, false, false, false, false], 113 | 0x25: [false, false, false, false, false, false, false, false], 114 | 0x26: [false, false, false, false, false, false, false, false], 115 | 0x27: [false, false, false, false, false, false, false, false], 116 | 0x28: [false, false, false, false, false, false, false, false], 117 | 0x29: [false, false, false, false, false, false, false, false], 118 | 0x2a: [false, false, false, false, false, false, false, false], 119 | 0x2b: [false, false, false, false, false, false, false, false], 120 | 0x2c: [false, false, false, false, false, false, false, false], 121 | 0x2d: [false, false, false, false, false, false, false, false], 122 | 0x2e: [false, false, false, false, false, false, false, false], 123 | 0x2f: [false, false, false, false, false, false, false, false], 124 | 0x30: [false, false, false, false, false, false, false, false], 125 | 0x31: [false, false, false, false, false, false, false, false], 126 | 0x32: [false, false, false, false, false, false, false, false], 127 | 0x33: [false, false, false, false, false, false, false, false], 128 | 0x34: [false, false, false, false, false, false, false, false], 129 | 0x35: [false, false, false, false, false, false, false, false], 130 | 0x36: [false, false, false, false, false, false, false, false], 131 | 0x37: [false, false, false, false, false, false, false, false], 132 | 0x38: [false, false, false, false, false, false, false, false], 133 | 0x39: [false, false, false, false, false, false, false, false], 134 | 0x3a: [false, false, false, false, false, false, false, false], 135 | 0x3b: [false, false, false, false, false, false, false, false], 136 | 0x3c: [false, false, false, false, false, false, false, false], 137 | 0x3d: [false, false, false, false, false, false, false, false], 138 | 0x3e: [false, false, false, false, false, false, false, false], 139 | 0x3f: [false, false, false, false, false, false, false, false], 140 | 0x40: [false, false, false, false, false, false, false, false], 141 | 0x41: [false, false, false, false, false, false, false, false], 142 | 0x42: [false, false, false, false, false, false, false, false], 143 | 0x43: [false, false, false, false, false, false, false, false], 144 | 0x44: [false, false, false, false, false, false, false, false], 145 | 0x45: [false, false, false, false, false, false, false, false], 146 | 0x46: [false, false, false, false, false, false, false, false], 147 | 0x47: [false, false, false, false, false, false, false, false], 148 | 0x48: [false, false, false, false, false, false, false, false], 149 | 0x49: [false, false, false, false, false, false, false, false], 150 | 0x4a: [false, false, false, false, false, false, false, false], 151 | 0x4b: [false, false, false, false, false, false, false, false], 152 | 0x4c: [false, false, false, false, false, false, false, false], 153 | 0x4d: [false, false, false, false, false, false, false, false], 154 | 0x4e: [false, false, false, false, false, false, false, false], 155 | 0x4f: [false, false, false, false, false, false, false, false], 156 | 0x50: [false, false, false, false, false, false, false, false], 157 | 0x51: [false, false, false, false, false, false, false, false], 158 | 0x52: [false, false, false, false, false, false, false, false], 159 | 0x53: [false, false, false, false, false, false, false, false], 160 | 0x54: [false, false, false, false, false, false, false, false], 161 | 0x55: [false, false, false, false, false, false, false, false], 162 | 0x56: [false, false, false, false, false, false, false, false], 163 | 0x57: [false, false, false, false, false, false, false, false], 164 | 0x58: [false, false, false, false, false, false, false, false], 165 | 0x59: [false, false, false, false, false, false, false, false], 166 | 0x5a: [false, false, false, false, false, false, false, false], 167 | 0x5b: [false, false, false, false, false, false, false, false], 168 | 0x5c: [false, false, false, false, false, false, false, false], 169 | 0x5d: [false, false, false, false, false, false, false, false], 170 | 0x5e: [false, false, false, false, false, false, false, false], 171 | 0x5f: [false, false, false, false, false, false, false, false], 172 | 0x60: [false, false, false, false, false, false, false, false], 173 | 0x61: [false, false, false, false, false, false, false, false], 174 | 0x62: [false, false, false, false, false, false, false, false], 175 | 0x63: [false, false, false, false, false, false, false, false], 176 | 0x64: [false, false, false, false, false, false, false, false], 177 | 0x65: [false, false, false, false, false, false, false, false], 178 | 0x66: [false, false, false, false, false, false, false, false], 179 | 0x67: [false, false, false, false, false, false, false, false], 180 | 0x68: [false, false, false, false, false, false, false, false], 181 | 0x69: [false, false, false, false, false, false, false, false], 182 | 0x6a: [false, false, false, false, false, false, false, false], 183 | 0x6b: [false, false, false, false, false, false, false, false], 184 | 0x6c: [false, false, false, false, false, false, false, false], 185 | 0x6d: [false, false, false, false, false, false, false, false], 186 | 0x6e: [false, false, false, false, false, false, false, false], 187 | 0x6f: [false, false, false, false, false, false, false, false], 188 | 0x70: [false, false, false, false, false, false, false, false], 189 | 0x71: [false, false, false, false, false, false, false, false], 190 | 0x72: [false, false, false, false, false, false, false, false], 191 | 0x73: [false, false, false, false, false, false, false, false], 192 | 0x74: [false, false, false, false, false, false, false, false], 193 | 0x75: [false, false, false, false, false, false, false, false], 194 | 0x76: [false, false, false, false, false, false, false, false], 195 | 0x77: [false, false, false, false, false, false, false, false], 196 | 0x78: [false, false, false, false, false, false, false, false], 197 | 0x79: [false, false, false, false, false, false, false, false], 198 | 0x7a: [false, false, false, false, false, false, false, false], 199 | 0x7b: [false, false, false, false, false, false, false, false], 200 | 0x7c: [false, false, false, false, false, false, false, false], 201 | 0x7d: [false, false, false, false, false, false, false, false], 202 | 0x7e: [false, false, false, false, false, false, false, false], 203 | 0x7f: [false, false, false, false, false, false, false, false], 204 | 0x80: [false, false, false, false, false, false, false, false], 205 | 0x81: [false, false, false, false, false, false, false, false], 206 | 0x82: [false, false, false, false, false, false, false, false], 207 | 0x83: [false, false, false, false, false, false, false, false], 208 | 0x84: [false, false, false, false, false, false, false, false], 209 | 0x85: [false, false, false, false, false, false, false, false], 210 | 0x86: [false, false, false, false, false, false, false, false], 211 | 0x87: [false, false, false, false, false, false, false, false], 212 | 0x88: [false, false, false, false, false, false, false, false], 213 | 0x89: [false, false, false, false, false, false, false, false], 214 | 0x8a: [false, false, false, false, false, false, false, false], 215 | 0x8b: [false, false, false, false, false, false, false, false], 216 | 0x8c: [false, false, false, false, false, false, false, false], 217 | 0x8d: [false, false, false, false, false, false, false, false], 218 | 0x8e: [false, false, false, false, false, false, false, false], 219 | 0x8f: [false, false, false, false, false, false, false, false], 220 | 0x90: [false, false, false, false, false, false, false, false], 221 | 0x91: [false, false, false, false, false, false, false, false], 222 | 0x92: [false, false, false, false, false, false, false, false], 223 | 0x93: [false, false, false, false, false, false, false, false], 224 | 0x94: [false, false, false, false, false, false, false, false], 225 | 0x95: [false, false, false, false, false, false, false, false], 226 | 0x96: [false, false, false, false, false, false, false, false], 227 | 0x97: [false, false, false, false, false, false, false, false], 228 | 0x98: [false, false, false, false, false, false, false, false], 229 | 0x99: [false, false, false, false, false, false, false, false], 230 | 0x9a: [false, false, false, false, false, false, false, false], 231 | 0x9b: [false, false, false, false, false, false, false, false], 232 | 0x9c: [false, false, false, false, false, false, false, false], 233 | 0x9d: [false, false, false, false, false, false, false, false], 234 | 0x9e: [false, false, false, false, false, false, false, false], 235 | 0x9f: [false, false, false, false, false, false, false, false], 236 | 0xa0: [false, false, false, false, false, false, false, false], 237 | 0xa1: [false, false, false, false, false, false, false, false], 238 | 0xa2: [false, false, false, false, false, false, false, false], 239 | 0xa3: [false, false, false, false, false, false, false, false], 240 | 0xa4: [false, false, false, false, false, false, false, false], 241 | 0xa5: [false, false, false, false, false, false, false, false], 242 | 0xa6: [false, false, false, false, false, false, false, false], 243 | 0xa7: [false, false, false, false, false, false, false, false], 244 | 0xa8: [false, false, false, false, false, false, false, false], 245 | 0xa9: [false, false, false, false, false, false, false, false], 246 | 0xaa: [false, false, false, false, false, false, false, false], 247 | 0xab: [false, false, false, false, false, false, false, false], 248 | 0xac: [false, false, false, false, false, false, false, false], 249 | 0xad: [false, false, false, false, false, false, false, false], 250 | 0xae: [false, false, false, false, false, false, false, false], 251 | 0xaf: [false, false, false, false, false, false, false, false], 252 | 0xb0: [false, false, false, false, false, false, false, false], 253 | 0xb1: [false, false, false, false, false, false, false, false], 254 | 0xb2: [false, false, false, false, false, false, false, false], 255 | 0xb3: [false, false, false, false, false, false, false, false], 256 | 0xb4: [false, false, false, false, false, false, false, false], 257 | 0xb5: [false, false, false, false, false, false, false, false], 258 | 0xb6: [false, false, false, false, false, false, false, false], 259 | 0xb7: [false, false, false, false, false, false, false, false], 260 | 0xb8: [false, false, false, false, false, false, false, false], 261 | 0xb9: [false, false, false, false, false, false, false, false], 262 | 0xba: [false, false, false, false, false, false, false, false], 263 | 0xbb: [false, false, false, false, false, false, false, false], 264 | 0xbc: [false, false, false, false, false, false, false, false], 265 | 0xbd: [false, false, false, false, false, false, false, false], 266 | 0xbe: [false, false, false, false, false, false, false, false], 267 | 0xbf: [false, false, false, false, false, false, false, false], 268 | 0xc0: [false, false, false, false, false, false, false, false], 269 | 0xc1: [false, false, false, false, false, false, false, false], 270 | 0xc2: [false, false, false, false, false, false, false, false], 271 | 0xc3: [false, false, false, false, false, false, false, false], 272 | 0xc4: [false, false, false, false, false, false, false, false], 273 | 0xc5: [false, false, false, false, false, false, false, false], 274 | 0xc6: [false, false, false, false, false, false, false, false], 275 | 0xc7: [false, false, false, false, false, false, false, false], 276 | 0xc8: [false, false, false, false, false, false, false, false], 277 | 0xc9: [false, false, false, false, false, false, false, false], 278 | 0xca: [false, false, false, false, false, false, false, false], 279 | 0xcb: [false, false, false, false, false, false, false, false], 280 | 0xcc: [false, false, false, false, false, false, false, false], 281 | 0xcd: [false, false, false, false, false, false, false, false], 282 | 0xce: [false, false, false, false, false, false, false, false], 283 | 0xcf: [false, false, false, false, false, false, false, false], 284 | 0xd0: [false, false, false, false, false, false, false, false], 285 | 0xd1: [false, false, false, false, false, false, false, false], 286 | 0xd2: [false, false, false, false, false, false, false, false], 287 | 0xd3: [false, false, false, false, false, false, false, false], 288 | 0xd4: [false, false, false, false, false, false, false, false], 289 | 0xd5: [false, false, false, false, false, false, false, false], 290 | 0xd6: [false, false, false, false, false, false, false, false], 291 | 0xd7: [false, false, false, false, false, false, false, false], 292 | 0xd8: [false, false, false, false, false, false, false, false], 293 | 0xd9: [false, false, false, false, false, false, false, false], 294 | 0xda: [false, false, false, false, false, false, false, false], 295 | 0xdb: [false, false, false, false, false, false, false, false], 296 | 0xdc: [false, false, false, false, false, false, false, false], 297 | 0xdd: [false, false, false, false, false, false, false, false], 298 | 0xde: [false, false, false, false, false, false, false, false], 299 | 0xdf: [false, false, false, false, false, false, false, false], 300 | 0xe0: [false, false, false, false, false, false, false, false], 301 | 0xe1: [false, false, false, false, false, false, false, false], 302 | 0xe2: [false, false, false, false, false, false, false, false], 303 | 0xe3: [false, false, false, false, false, false, false, false], 304 | 0xe4: [false, false, false, false, false, false, false, false], 305 | 0xe5: [false, false, false, false, false, false, false, false], 306 | 0xe6: [false, false, false, false, false, false, false, false], 307 | 0xe7: [false, false, false, false, false, false, false, false], 308 | 0xe8: [false, false, false, false, false, false, false, false], 309 | 0xe9: [false, false, false, false, false, false, false, false], 310 | 0xea: [false, false, false, false, false, false, false, false], 311 | 0xeb: [false, false, false, false, false, false, false, false], 312 | 0xec: [false, false, false, false, false, false, false, false], 313 | 0xed: [false, false, false, false, false, false, false, false], 314 | 0xee: [false, false, false, false, false, false, false, false], 315 | 0xef: [false, false, false, false, false, false, false, false], 316 | 0xf0: [false, false, false, false, false, false, false, false], 317 | 0xf1: [false, false, false, false, false, false, false, false], 318 | 0xf2: [false, false, false, false, false, false, false, false], 319 | 0xf3: [false, false, false, false, false, false, false, false], 320 | 0xf4: [false, false, false, false, false, false, false, false], 321 | 0xf5: [false, false, false, false, false, false, false, false], 322 | 0xf6: [false, false, false, false, false, false, false, false], 323 | 0xf7: [false, false, false, false, false, false, false, false], 324 | 0xf8: [false, false, false, false, false, false, false, false], 325 | 0xf9: [false, false, false, false, false, false, false, false], 326 | 0xfa: [false, false, false, false, false, false, false, false], 327 | 0xfb: [false, false, false, false, false, false, false, false], 328 | 0xfc: [false, false, false, false, false, false, false, false], 329 | 0xfd: [false, false, false, false, false, false, false, false], 330 | 0xfe: [false, false, false, false, false, false, false, false], 331 | 0xff: [false, false, false, false, false, false, false, false] 332 | }, 333 | /** 334 | * ADC – Add with Carry 335 | * 336 | * Adds two registers and the contents of the C Flag and places the result in the destination register Rd. 337 | * 338 | * @param _Rd 0 < d < 31 339 | * @param _Rr 0 < r < 31 340 | */ 341 | adc: function(_Rd, _Rr) { 342 | 343 | var Rd = this.dataspace[_Rd]; 344 | var Rr = this.dataspace[_Rr]; 345 | var R = [false, false, false, false, false, false, false, false]; 346 | var C = [false, false, false, false, false, false, false, false]; 347 | var SREG = this.dataspace[SREG]; 348 | 349 | /* Operation: Rd <- Rd + Rr + C */ 350 | C[0] = SREG[0]; 351 | 352 | R[0] = !!(Rd[0] ^ Rr[0]); 353 | C[1] = Rd[0] && Rr[0]; 354 | 355 | R[1] = !!(Rd[1] ^ Rr[1] ^ C[1]); 356 | C[2] = (Rd[1] || Rr[1]) && C[1]; 357 | 358 | R[2] = !!(Rd[2] ^ Rr[2] ^ C[2]); 359 | C[3] = (Rd[2] || Rr[2]) && C[2]; 360 | 361 | R[3] = !!(Rd[3] ^ Rr[3] ^ C[3]); 362 | C[4] = (Rd[3] || Rr[3]) && C[3]; 363 | 364 | R[4] = !!(Rd[4] ^ Rr[4] ^ C[4]); 365 | C[5] = (Rd[4] || Rr[4]) && C[4]; 366 | 367 | R[5] = !!(Rd[5] ^ Rr[5] ^ C[5]); 368 | C[6] = (Rd[5] || Rr[5]) && C[5]; 369 | 370 | R[6] = !!(Rd[6] ^ Rr[6] ^ C[6]); 371 | C[7] = (Rd[6] || Rr[6]) && C[6]; 372 | 373 | R[7] = !!(Rd[7] ^ Rr[7] ^ C[7]); 374 | 375 | /* C: Set if there was carry from the MSB of the result; cleared otherwise. */ 376 | this.dataspace[SREG][0] = Rd[7] && Rr[7] || Rr[7] && !R[7] || !R[7] && Rd[7]; 377 | /* Z: Set if the result is $00; cleared otherwise. */ 378 | SREG[1] = !R[7] && !R[6] && !R[5] && !R[4] && !R[3] && !R[2] && !R[1] && R[0]; 379 | /* N: Set if MSB of the result is set; cleared otherwise. */ 380 | SREG[2] = R[7]; 381 | /* V: Set if two’s complement overflow resulted from the operation; cleared otherwise. */ 382 | SREG[3] = Rd[7] && Rr[7] && !Rr[7] || !Rd[7] && !Rr[7] && R[7]; 383 | /* S: N ^ V, For signed tests. */ 384 | SREG[4] = !!(SREG[2] ^ SREG[3]); 385 | /* H: Set if there was a carry from bit 3; cleared otherwise. */ 386 | SREG[5] = Rd[3] && Rr[3] || Rr[3] && !R[3] || !R[3] && Rd[3]; 387 | 388 | /* Program Counter: PC <- PC + 1 */ 389 | this.PC++; 390 | 391 | this.dataspace[_Rd] = R; 392 | this.dataspace[this.sreg] = SREG; 393 | }, 394 | /** 395 | * ADD – Add without Carry 396 | * 397 | * Adds two registers without the C Flag and places the result in the destination register Rd 398 | * 399 | * @param _Rd 0 < d < 31 400 | * @param _Rr 0 < r < 31 401 | */ 402 | add: function(_Rd, _Rr) { 403 | 404 | var Rd = this.dataspace[_Rd]; 405 | var Rr = this.dataspace[_Rr]; 406 | var R = [false, false, false, false, false, false, false, false]; 407 | var C = [false, false, false, false, false, false, false, false]; 408 | var SREG = this.dataspace[this.sreg]; 409 | 410 | /* Operation: Rd <- Rd + Rr */ 411 | C[0] = false; 412 | 413 | R[0] = !!(Rd[0] ^ Rr[0]); 414 | C[1] = Rd[0] && Rr[0]; 415 | 416 | R[1] = !!(Rd[1] ^ Rr[1] ^ C[1]); 417 | C[2] = (Rd[1] || Rr[1]) && C[1]; 418 | 419 | R[2] = !!(Rd[2] ^ Rr[2] ^ C[2]); 420 | C[3] = (Rd[2] || Rr[2]) && C[2]; 421 | 422 | R[3] = !!(Rd[3] ^ Rr[3] ^ C[3]); 423 | C[4] = (Rd[3] || Rr[3]) && C[3]; 424 | 425 | R[4] = !!(Rd[4] ^ Rr[4] ^ C[4]); 426 | C[5] = (Rd[4] || Rr[4]) && C[4]; 427 | 428 | R[5] = !!(Rd[5] ^ Rr[5] ^ C[5]); 429 | C[6] = (Rd[5] || Rr[5]) && C[5]; 430 | 431 | R[6] = !!(Rd[6] ^ Rr[6] ^ C[6]); 432 | C[7] = (Rd[6] || Rr[6]) && C[6]; 433 | 434 | R[7] = !!(Rd[7] ^ Rr[7] ^ C[7]); 435 | 436 | /* C: Set if there was carry from the MSB of the result; cleared otherwise. */ 437 | SREG[0] = Rd[7] && Rr[7] || Rr[7] && !R[7] || !R[7] && Rd[7]; 438 | /* Z: Set if the result is $00; cleared otherwise. */ 439 | SREG[1] = !R[7] && !R[6] && !R[5] && !R[4] && !R[3] && !R[2] && !R[1] && R[0]; 440 | /* N: Set if MSB of the result is set; cleared otherwise. */ 441 | SREG[2] = R[7]; 442 | /* V: Set if two’s complement overflow resulted from the operation; cleared otherwise. */ 443 | SREG[3] = Rd[7] && Rr[7] && !Rr[7] || !Rd[7] && !Rr[7] && R[7]; 444 | /* S: N ^ V, For signed tests. */ 445 | SREG[4] = !!(SREG[2] ^ SREG[3]); 446 | /* H: Set if there was a carry from bit 3; cleared otherwise. */ 447 | SREG[5] = Rd[3] && Rr[3] || Rr[3] && !R[3] || !R[3] && Rd[3]; 448 | 449 | /* Program Counter: PC <- PC + 1 */ 450 | this.PC++; 451 | 452 | this.dataspace[_Rd] = R; 453 | this.dataspace[this.sreg] = SREG; 454 | }, 455 | /** 456 | * ADIW – Add Immediate to Word 457 | * 458 | * Adds an immediate value (0 - 63) to a register pair and places the result in the register pair. 459 | * This instruction operates on the upper four register pairs, 460 | * and is well suited for operations on the pointer registers. 461 | * This instruction is not available in all devices. 462 | * Refer to the device specific instruction set summary. 463 | * 464 | * @param _Rd d e {24,26,28,30} 465 | * @param _Rr 0 <= K <= 63 466 | */ 467 | adiw: function(_Rd, _Rr) { 468 | 469 | var Rd = this.dataspace[_Rd]; 470 | var Rr = this.dataspace[_Rr]; 471 | var SREG = this.dataspace[this.sreg]; 472 | 473 | /* Program Counter: PC <- PC + 1 */ 474 | this.PC++; 475 | }, 476 | /** 477 | * AND – Logical AND 478 | * 479 | * Performs the logical AND between the contents of register Rd and register Rr 480 | * and places the result in the destination register Rd. 481 | * 482 | * @param _Rd Destination register 483 | * @param _Rr 484 | */ 485 | and: function(_Rd, _Rr) { 486 | 487 | var Rd = this.dataspace[_Rd]; 488 | var Rr = this.dataspace[_Rr]; 489 | var SREG = this.dataspace[this.sreg]; 490 | 491 | /* Operation: Rd <- Rd && Rr */ 492 | Rd[0] = Rd[0] && Rr[0]; 493 | Rd[1] = Rd[1] && Rr[1]; 494 | Rd[2] = Rd[2] && Rr[2]; 495 | Rd[3] = Rd[3] && Rr[3]; 496 | Rd[4] = Rd[4] && Rr[4]; 497 | Rd[5] = Rd[5] && Rr[5]; 498 | Rd[6] = Rd[6] && Rr[6]; 499 | Rd[7] = Rd[7] && Rr[7]; 500 | 501 | /* @TODO */ 502 | SREG[4]; 503 | /* Cleared */ 504 | SREG[3] = false; 505 | /* Set if MSB of the result is set; cleared otherwise. */ 506 | SREG[2] = Rd[7]; 507 | /* Set if the result is $00; cleared otherwise. */ 508 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && !Rd[0]; 509 | 510 | /* Program Counter: PC <- PC + 1 */ 511 | this.PC++; 512 | 513 | this.dataspace[_Rd] = Rd; 514 | this.dataspace[this.sreg] = SREG; 515 | }, 516 | /** 517 | * ANDI – Logical AND with Immediate 518 | * 519 | * Performs the logical AND between the contents of register Rd and a constant 520 | * and places the result in the destination register Rd. 521 | * 522 | * @param _Rd 523 | * @param K 524 | */ 525 | andi: function(_Rd, K) { 526 | 527 | var Rd = this.dataspace[_Rd]; 528 | var SREG = this.dataspace[this.sreg]; 529 | 530 | /* Operation: Rd <- Rd && K */ 531 | Rd[0] = Rd[0] && K[0]; 532 | Rd[1] = Rd[1] && K[1]; 533 | Rd[2] = Rd[2] && K[2]; 534 | Rd[3] = Rd[3] && K[3]; 535 | Rd[4] = Rd[4] && K[4]; 536 | Rd[5] = Rd[5] && K[5]; 537 | Rd[6] = Rd[6] && K[6]; 538 | Rd[7] = Rd[7] && K[7]; 539 | 540 | /* @TODO */ 541 | SREG[4]; 542 | /* Cleared */ 543 | SREG[3] = false; 544 | /* Set if MSB of the result is set; cleared otherwise. */ 545 | SREG[2] = Rd[7]; 546 | /* Set if the result is $00; cleared otherwise. */ 547 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && !Rd[0]; 548 | 549 | /* Program Counter: PC <- PC + 1 */ 550 | this.PC++; 551 | 552 | this.dataspace[_Rd] = Rd; 553 | this.dataspace[this.sreg] = SREG; 554 | }, 555 | /** 556 | * ASR – Arithmetic Shift Right 557 | * 558 | * Shifts all bits in Rd one place to the right. Bit 7 is held constant. 559 | * Bit 0 is loaded into the C Flag of the SREG. 560 | * This operation effectively divides a signed value by two without changing its sign. 561 | * The Carry Flag can be used to round the result. 562 | * 563 | * @param _Rd 0 <= d <= 31 564 | */ 565 | asr: function(_Rd) { 566 | 567 | var Rd = this.dataspace[_Rd]; 568 | var SREG = this.dataspace[this.sreg]; 569 | 570 | /* C: Set if, before the shift, the LSB of RD was set; cleared otherwise. */ 571 | SREG[0] = Rd[0]; 572 | 573 | /* Operation */ 574 | Rd[0] = Rd[1]; 575 | Rd[1] = Rd[2]; 576 | Rd[2] = Rd[3]; 577 | Rd[3] = Rd[4]; 578 | Rd[4] = Rd[5]; 579 | Rd[5] = Rd[6]; 580 | Rd[6] = Rd[7]; 581 | Rd[7] = Rd[7]; 582 | 583 | /* Z: Set if the result is $00; cleared otherwise. */ 584 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && !Rd[0]; 585 | /* N: Set if MSB of the result is set; cleared otherwise. */ 586 | SREG[2] = Rd[7]; 587 | /* V: N ^ C (For N and C after the shift) */ 588 | SREG[3] = !!(SREG[2] ^ SREG[0]); 589 | /* S: N ^ V, For signed test */ 590 | SREG[4] = !!(SREG[2] ^ SREG[3]); 591 | 592 | /* Program Counter: PC <- PC + 1 */ 593 | this.PC++; 594 | 595 | this.dataspace[_Rd] = Rd; 596 | this.dataspace[this.sreg] = SREG; 597 | }, 598 | /** 599 | * BCLR – Bit Clear in SREG 600 | * 601 | * Bit clear in SREG 602 | * 603 | * @param s 604 | */ 605 | bclr: function(s) { 606 | 607 | /* @TODO */ 608 | this.dataspace[this.sreg][s] = false; 609 | 610 | /* Program Counter: PC <- PC + 1 */ 611 | this.PC++; 612 | }, 613 | /** 614 | * BLD – Bit Load from the T Flag in SREG to a Bit in Register 615 | * 616 | * Copies the T Flag in the SREG (Status Register) to bit b in register Rd. 617 | * 618 | * @param _Rd 0 <= d <= 31 619 | * @param b 0 <= b <= 7 620 | */ 621 | bld: function(_Rd, b) { 622 | 623 | /* Operation: Rd(b) <- T */ 624 | this.dataspace[_Rd] = this.dataspace[this.sreg][6]; 625 | 626 | /* Program Counter: PC <- PC + 1 */ 627 | this.PC++; 628 | }, 629 | /** 630 | * BRBC – Branch if Bit in SREG is Cleared 631 | * 632 | * Conditional relative branch. 633 | * Tests a single bit in SREG and branches relatively to PC if the bit is cleared. 634 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 635 | * The parameter k is the offset from PC and is represented in two’s complement form. 636 | * 637 | * @param s 638 | * @param k 639 | */ 640 | brbc: function(s, k) { 641 | 642 | /* Operation: If SREG(s) = 0 then PC <- PC + k + 1, else PC <- PC + 1 */ 643 | if (this.dataspace[this.sreg][s] === false) { 644 | this.PC = this.PC + k; 645 | } 646 | 647 | /* Program Counter: PC <- PC + 1 */ 648 | this.PC++; 649 | }, 650 | /** 651 | * BRBS – Branch if Bit in SREG is Set 652 | * 653 | * Conditional relative branch. 654 | * Tests a single bit in SREG and branches relatively to PC if the bit is set. 655 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 656 | * The parameter k is the offset from PC and is represented in two’s complement form. 657 | * 658 | * @param s 659 | * @param k 660 | */ 661 | brbs: function(s, k) { 662 | 663 | /* Operation: If SREG(s) = 1 then PC <- PC + k + 1, else PC <- PC + 1 */ 664 | if (this.dataspace[this.sreg][s] === true) { 665 | this.PC = this.PC + k; 666 | } 667 | 668 | /* Program Counter: PC <- PC + 1 */ 669 | this.PC++; 670 | }, 671 | /** 672 | * BRCC – Branch if Carry Cleared 673 | * 674 | * Conditional relative branch. 675 | * Tests the Carry Flag (C) and branches relatively to PC if C is cleared. 676 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 677 | * The parameter k is the offset from PC and is represented in two’s complement form. 678 | * (Equivalent to instruction BRBC 0,k). 679 | * 680 | * @param k 681 | */ 682 | brcc: function(k) { 683 | 684 | /* Operation: If C = 0 then PC <- PC + k + 1, else PC <- PC + 1 */ 685 | if (this.dataspace[this.sreg][0] === false) { 686 | this.PC = this.PC + k; 687 | } 688 | 689 | /* Program Counter: PC <- PC + 1 */ 690 | this.PC++; 691 | }, 692 | /** 693 | * BRCS – Branch if Carry Set 694 | * 695 | * Conditional relative branch. 696 | * Tests the Carry Flag (C) and branches relatively to PC if C is set. 697 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 698 | * The parameter k is the offset from PC and is represented in two’s complement form. 699 | * (Equivalent to instruction BRBS 0,k). 700 | * 701 | * @param k 702 | */ 703 | brcs: function(k) { 704 | 705 | /* Operation: If C = 1 then PC <- PC + k + 1, else PC <- PC + 1 */ 706 | if (this.dataspace[this.sreg][0] === true) { 707 | this.PC = this.PC + k; 708 | } 709 | 710 | /* Program Counter: PC <- PC + 1 */ 711 | this.PC++; 712 | }, 713 | /** 714 | * BREAK – Break 715 | * 716 | * The BREAK instruction is used by the On-chip Debug system, and is normally not used in the application software. 717 | * When the BREAK instruction is executed, the AVR CPU is set in the Stopped Mode. 718 | * This gives the On-chip Debugger access to internal resources. 719 | * If any Lock bits are set, or either the JTAGEN or OCDEN Fuses are unprogrammed, 720 | * the CPU will treat the BREAK instruction as a NOP and will not enter the Stopped mode. 721 | */ 722 | 'break': function() { 723 | 724 | /* Program Counter: PC <- PC + 1 */ 725 | this.PC++; 726 | }, 727 | /** 728 | * BREQ – Branch if Equal 729 | * 730 | * Conditional relative branch. 731 | * Tests the Zero Flag (Z) and branches relatively to PC if Z is set. 732 | * If the instruction is executed immediately after any of the instructions CP, CPI, SUB or SUBI, 733 | * the branch will occur if and only if the unsigned or signed binary number represented in Rd was equal 734 | * to the unsigned or signed binary number represented in Rr. 735 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 736 | * The parameter k is the offset from PC and is represented in two’s complement form. 737 | * (Equivalent to instruction BRBS 1,k). 738 | * 739 | * @param {type} k 740 | * @returns {undefined} 741 | */ 742 | breq: function(k) { 743 | 744 | /* Operation: If Rd = Rr (Z = 1) then PC <- PC + k + 1, else PC <- PC + 1 */ 745 | if (this.dataspace[this.sreg][1] === true) { 746 | this.PC = this.PC + k; 747 | } 748 | 749 | /* Program Counter: PC <- PC + 1 */ 750 | this.PC++; 751 | }, 752 | /** 753 | * BRGE – Branch if Greater or Equal (Signed) 754 | * 755 | * Conditional relative branch. 756 | * Tests the Signed Flag (S) and branches relatively to PC if S is cleared. 757 | * If the instruction is executed immediately after any of the instructions CP, CPI, SUB or SUBI, 758 | * the branch will occur if and only if the signed binary number represented in Rd was greater than or equal 759 | * to the signed binary number represented in Rr. 760 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 761 | * The parameter k is the offset from PC and is represented in two’s complement form. 762 | * Equivalent to instruction BRBC 4,k). 763 | * 764 | * @param {type} k 765 | */ 766 | brge: function(k) { 767 | 768 | /* Operation: If Rd ≥ Rr (N ⊕ V = 0) then PC <- PC + k + 1, else PC <- PC + 1 */ 769 | if (this.dataspace[this.sreg][4] === false) { 770 | this.PC = this.PC + k; 771 | } 772 | 773 | /* Program Counter: PC <- PC + 1 */ 774 | this.PC++; 775 | }, 776 | /** 777 | * BRHC – Branch if Half Carry Flag is Cleared 778 | * 779 | * Conditional relative branch. 780 | * Tests the Half Carry Flag (H) and branches relatively to PC if H is cleared. 781 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 782 | * The parameter k is the offset from PC and is represented in two’s complement form. 783 | * (Equivalent to instruction BRBC 5,k). 784 | * 785 | * @param k 786 | */ 787 | brhc: function(k) { 788 | 789 | /* Operation: If H = 0 then PC <- PC + k + 1, else PC <- PC + 1 */ 790 | if (this.dataspace[this.sreg][5] === false) { 791 | this.PC = this.PC + k; 792 | } 793 | 794 | /* Program Counter: PC <- PC + 1 */ 795 | this.PC++; 796 | }, 797 | /** 798 | * BRHS – Branch if Half Carry Flag is Set 799 | * 800 | * Conditional relative branch. 801 | * Tests the Half Carry Flag (H) and branches relatively to PC if H is set. 802 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 803 | * The parameter k is the offset from PC and is represented in two’s complement form. 804 | * (Equivalent to instruction BRBS 5,k). 805 | * 806 | * @param k 807 | */ 808 | brhs: function(k) { 809 | 810 | /* Operation: If H = 1 then PC <- PC + k + 1, else PC <- PC + 1 */ 811 | if (this.dataspace[this.sreg][5] === true) { 812 | this.PC = this.PC + k; 813 | } 814 | 815 | /* Program Counter: PC <- PC + 1 */ 816 | this.PC++; 817 | }, 818 | /** 819 | * BRID – Branch if Global Interrupt is Disabled 820 | * 821 | * Conditional relative branch. 822 | * Tests the Global Interrupt Flag (I) and branches relatively to PC if I is cleared. 823 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 824 | * The parameter k is the offset from PC and is represented in two’s complement form. 825 | * (Equivalent to instruction BRBC 7,k). 826 | * 827 | * @param k 828 | */ 829 | brid: function(k) { 830 | 831 | /* If I = 0 then PC <- PC + k + 1, else PC <- PC + 1 */ 832 | if (this.dataspace[this.sreg][7] === false) { 833 | this.PC = this.PC + k; 834 | } 835 | 836 | /* Program Counter: PC <- PC + 1 */ 837 | this.PC++; 838 | }, 839 | /** 840 | * BRIE – Branch if Global Interrupt is Enabled 841 | * 842 | * Conditional relative branch. 843 | * Tests the Global Interrupt Flag (I) and branches relatively to PC if I is set. 844 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 845 | * The parameter k is the offset from PC and is represented in two’s complement form. 846 | * (Equivalent to instruction BRBS 7,k). 847 | * 848 | * @param k 849 | */ 850 | brie: function(k) { 851 | 852 | /* If I = 1 then PC <- PC + k + 1, else PC <- PC + 1 */ 853 | if (this.dataspace[this.sreg][7] === true) { 854 | this.PC = this.PC + k; 855 | } 856 | 857 | /* Program Counter: PC <- PC + 1 */ 858 | this.PC++; 859 | }, 860 | /** 861 | * BRLO – Branch if Lower (Unsigned) 862 | * 863 | * Conditional relative branch. 864 | * Tests the Carry Flag (C) and branches relatively to PC if C is set. 865 | * If the instruction is executed immediately after any of the instructions CP, CPI, SUB or SUBI, 866 | * the branch will occur if and only if the unsigned binary number represented in Rd was smaller 867 | * than the unsigned binary number represented in Rr. 868 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 869 | * The parameter k is the offset from PC and is represented in two’s complement form. 870 | * (Equivalent to instruction BRBS 0,k). 871 | * 872 | * @param k 873 | */ 874 | brlo: function(k) { 875 | 876 | /* Operation: If Rd < Rr (C = 1) then PC <- PC + k + 1, else PC <- PC + 1 */ 877 | if (this.dataspace[this.sreg][0] === true) { 878 | this.PC = this.PC + k; 879 | } 880 | 881 | /* Program Counter: PC <- PC + 1 */ 882 | this.PC++; 883 | }, 884 | /** 885 | * BRLT – Branch if Less Than (Signed) 886 | * 887 | * Conditional relative branch. 888 | * Tests the Signed Flag (S) and branches relatively to PC if S is set. 889 | * If the instruction is executed immediately after any of the instructions CP, CPI, SUB or SUBI, 890 | * the branch will occur if and only if the signed binary number represented in Rd was less 891 | * than the signed binary number represented in Rr. 892 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 893 | * The parameter k is the offset from PC and is represented in two’s complement form. 894 | * (Equivalent to instruction BRBS 4,k). 895 | * 896 | * @param k 897 | */ 898 | brlt: function(k) { 899 | 900 | /* Operation: If Rd < Rr (N ⊕ V = 1) then PC ← PC + k + 1, else PC ← PC + 1 */ 901 | if (this.dataspace[this.sreg][4] === true) { 902 | this.PC = this.PC + k; 903 | } 904 | 905 | /* Program Counter: PC <- PC + 1 */ 906 | this.PC++; 907 | }, 908 | /** 909 | * BRMI – Branch if Minus 910 | * 911 | * Conditional relative branch. 912 | * Tests the Negative Flag (N) and branches relatively to PC if N is set. 913 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 914 | * The parameter k is the offset from PC and is represented in two’s complement form. 915 | * (Equivalent to instruction BRBS 2,k). 916 | * 917 | * @param k 918 | */ 919 | brmi: function(k) { 920 | 921 | /* If N = 1 then PC <- PC + k + 1, else PC <- PC + 1 */ 922 | if (this.dataspace[this.sreg][2] === true) { 923 | this.PC = this.PC + k; 924 | } 925 | 926 | /* Program Counter: PC <- PC + 1 */ 927 | this.PC++; 928 | }, 929 | /** 930 | * BRNE – Branch if Not Equal 931 | * 932 | * Conditional relative branch. 933 | * Tests the Zero Flag (Z) and branches relatively to PC if Z is cleared. 934 | * If the instruction is executed immediately after any of the instructions CP, CPI, SUB or SUBI, 935 | * the branch will occur if and only if the unsigned or signed binary number represented in Rd was not equal 936 | * to the unsigned or signed binary number represented in Rr. 937 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 938 | * The parameter k is the offset from PC and is represented in two’s complement form. 939 | * (Equivalent to instruction BRBC 1,k). 940 | * 941 | * @param k 942 | */ 943 | brne: function(k) { 944 | 945 | /* If Rd != Rr (Z = 0) then PC <- PC + k + 1, else PC <- PC + 1 */ 946 | if (this.dataspace[this.sreg][1] === false) { 947 | this.PC = this.PC + k; 948 | } 949 | 950 | /* Program Counter: PC <- PC + 1 */ 951 | this.PC++; 952 | }, 953 | /** 954 | * BRPL – Branch if Plus 955 | * 956 | * Conditional relative branch. 957 | * Tests the Negative Flag (N) and branches relatively to PC if N is cleared. 958 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 959 | * The parameter k is the offset from PC and is brepresented in two’s complement form. 960 | * (Equivalent to instruction BRBC 2,k). 961 | * 962 | * @param k 963 | */ 964 | brpl: function(k) { 965 | 966 | /* Operation: If N = 0 then PC <- PC + k + 1, else PC <- PC + 1 */ 967 | if (this.dataspace[this.sreg][2] === false) { 968 | this.PC = this.PC + k; 969 | } 970 | 971 | /* Program Counter: PC <- PC + 1 */ 972 | this.PC++; 973 | }, 974 | /** 975 | * BRSH – Branch if Same or Higher (Unsigned) 976 | * 977 | * Conditional relative branch. 978 | * Tests the Carry Flag (C) and branches relatively to PC if C is cleared. 979 | * If the instruction is executed immediately after execution of any of the instructions CP, CPI, SUB or SUBI, 980 | * the branch will occur if and only if the unsigned binary number represented in Rd was greater than or equal 981 | * to the unsigned binary number represented in Rr. 982 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 983 | * The parameter k is the offset from PC and is represented in two’s complement form. 984 | * (Equivalent to instruction BRBC 0,k). 985 | * 986 | * @param k 987 | */ 988 | brsh: function(k) { 989 | 990 | /* Operation: If Rd >= Rr (C = 0) then PC <- PC + k + 1, else PC <- PC + 1 */ 991 | if (this.dataspace[this.sreg][0] === false) { 992 | this.PC = this.PC + k; 993 | } 994 | 995 | /* Program Counter: PC <- PC + 1 */ 996 | this.PC++; 997 | }, 998 | /** 999 | * BRTC – Branch if the T Flag is Cleared 1000 | * 1001 | * Conditional relative branch. 1002 | * Tests the T Flag and branches relatively to PC if T is cleared. 1003 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 1004 | * The parameter k is the offset from PC and is represented in two’s complement form. 1005 | * (Equivalent to instruction BRBC 6,k). 1006 | * 1007 | * @param k 1008 | */ 1009 | brtc: function(k) { 1010 | 1011 | /* Operation: If T = 0 then PC <- PC + k + 1, else PC <- PC + 1 */ 1012 | if (this.dataspace[this.sreg][6] === false) { 1013 | this.PC = this.PC + k; 1014 | } 1015 | 1016 | /* Program Counter: PC <- PC + 1 */ 1017 | this.PC++; 1018 | }, 1019 | /** 1020 | * BRTS – Branch if the T Flag is Set 1021 | * 1022 | * Conditional relative branch. 1023 | * Tests the T Flag and branches relatively to PC if T is set. 1024 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 1025 | * The parameter k is the offset from PC and is represented in two’s complement form. 1026 | * (Equivalent to instruction BRBS 6,k). 1027 | * 1028 | * @param k 1029 | */ 1030 | brts: function(k) { 1031 | 1032 | /* Operation: If T = 1 then PC <- PC + k + 1, else PC <- PC + 1 */ 1033 | if (this.dataspace[this.sreg][6] === true) { 1034 | this.PC = this.PC + k; 1035 | } 1036 | 1037 | /* Program Counter: PC <- PC + 1 */ 1038 | this.PC++; 1039 | }, 1040 | /** 1041 | * BVRC - Branch if Overflow Cleared 1042 | * 1043 | * Conditional relative branch. 1044 | * Tests the Overflow Flag (V) and branches relatively to PC if V is cleared. 1045 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 1046 | * The parameter k is the offset from PC and is represented in two’s complement form. 1047 | * (Equivalent to instruction BRBC 3,k). 1048 | * 1049 | * @param k 1050 | */ 1051 | brvc: function(k) { 1052 | 1053 | /* Operation: If V = 0 then PC <- PC + k + 1, else PC <- PC + 1 */ 1054 | if (this.dataspace[this.sreg][3] === false) { 1055 | this.PC = this.PC + k; 1056 | } 1057 | 1058 | /* Program Counter: PC <- PC + 1 */ 1059 | this.PC++; 1060 | }, 1061 | /** 1062 | * BRVS – Branch if Overflow Set 1063 | * 1064 | * Conditional relative branch. 1065 | * Tests the Overflow Flag (V) and branches relatively to PC if V is set. 1066 | * This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). 1067 | * The parameter k is the offset from PC and is represented in two’s complement form. 1068 | * (Equivalent to instruction BRBS 3,k) 1069 | * 1070 | * @param k 1071 | */ 1072 | brvs: function(k) { 1073 | 1074 | /** Operation: If V = 1 then PC <- PC + k + 1, else PC <- PC + 1 */ 1075 | if (this.dataspace[this.sreg][3] === true) { 1076 | this.PC = this.PC + k; 1077 | } 1078 | 1079 | /* Program Counter: PC <- PC + 1 */ 1080 | this.PC++; 1081 | }, 1082 | /** 1083 | * BSET – Bit Set in SREG 1084 | * 1085 | * Sets a single Flag or bit in SREG. 1086 | * 1087 | * @param s 1088 | */ 1089 | bset: function(s) { 1090 | 1091 | this.dataspace[this.sreg][s] = true; 1092 | /* @TODO */ 1093 | 1094 | /* Program Counter: PC <- PC + 1 */ 1095 | this.PC++; 1096 | }, 1097 | /** 1098 | * BST – Bit Store from Bit in Register to T Flag in SREG 1099 | * 1100 | * Stores bit b from Rd to the T Flag in SREG (Status Register). 1101 | * 1102 | * @param _Rd 1103 | * @param b 1104 | */ 1105 | bst: function(_Rd, b) { 1106 | 1107 | this.dataspace[this.sreg][6] = _Rd[b]; 1108 | 1109 | /* Program Counter: PC <- PC + 1 */ 1110 | this.PC++; 1111 | }, 1112 | /** 1113 | * CALL - Long Call to a Subroutine 1114 | * 1115 | * Calls to a subroutine within the entire Program memory. 1116 | * The return address (to the instruction after the CALL) will be stored onto the Stack. 1117 | * (See also RCALL). 1118 | * The Stack Pointer uses a post-decrement scheme during CALL. 1119 | * 1120 | * This instruction is not available in all devices. 1121 | * Refer to the device specific instruction set summary. 1122 | * 1123 | * @param k 0 <= k <= 64K || 4M 1124 | */ 1125 | call: function(k) { 1126 | 1127 | /* Operation: PC <- k */ 1128 | this.PC = k; 1129 | 1130 | /* @TODO */ 1131 | 1132 | 1133 | }, 1134 | /** 1135 | * CBI - Clear Bit in I/O Register 1136 | * 1137 | * Clears a specified bit in an I/O Register. 1138 | * This instruction operates on the lower 32 I/O Registers – addresses 0-31. 1139 | * 1140 | * @param A 0 <= A <= 31 1141 | * @param b 0 <= b <= 7 1142 | */ 1143 | cbi: function(A, b) { 1144 | 1145 | /* @TODO */ 1146 | 1147 | 1148 | }, 1149 | /** 1150 | * CBR – Clear Bits in Register 1151 | * 1152 | * Clears the specified bits in register Rd. 1153 | * Performs the logical AND between the contents of register Rd and the complement of the constant mask K. 1154 | * The result will be placed in register Rd. 1155 | * 1156 | * @param _Rd 16 <= d <= 31 1157 | * @param K 0 <= K <= 255 1158 | */ 1159 | cbr: function(_Rd, K) { 1160 | 1161 | var Rd = this.dataspace[_Rd]; 1162 | var SREG = this.dataspace[this.sreg]; 1163 | 1164 | /* Operation: Rd <- Rd && ($FF - K) */ 1165 | Rd[0] = Rd[0] && !K[0]; 1166 | Rd[1] = Rd[1] && !K[1]; 1167 | Rd[2] = Rd[2] && !K[2]; 1168 | Rd[3] = Rd[3] && !K[3]; 1169 | Rd[4] = Rd[4] && !K[4]; 1170 | Rd[5] = Rd[5] && !K[5]; 1171 | Rd[6] = Rd[6] && !K[6]; 1172 | Rd[7] = Rd[7] && !K[7]; 1173 | 1174 | /* Z: Set if the result is $00; cleared otherwise */ 1175 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && Rd[0]; 1176 | /* N: Set if MSB of the result is set; celared otherwise */ 1177 | SREG[2] = Rd[7]; 1178 | /* V: Celared */ 1179 | SREG[3] = false; 1180 | /* S: N ^ V, For signed tests. */ 1181 | SREG[4] = !!(SREG[2] ^ SREG[3]); 1182 | 1183 | /* Program Counter: PC <- PC + 1 */ 1184 | this.PC++; 1185 | 1186 | this.dataspace[_Rd] = Rd; 1187 | this.dataspace[this.sreg] = SREG; 1188 | }, 1189 | /** 1190 | * CLC – Clear Carry Flag 1191 | * 1192 | * Clears the Carry Flag (C) in SREG (Status Register). 1193 | */ 1194 | clc: function() { 1195 | 1196 | /* Carry Flag cleared */ 1197 | this.dataspace[this.sreg][0] = false; 1198 | 1199 | /* Program Counter: PC <- PC + 1 */ 1200 | this.PC++; 1201 | }, 1202 | /** 1203 | * CLH – Clear Half Carry Flag 1204 | * 1205 | * Clears the Half Carry Flag (H) in SREG (Status Register). 1206 | */ 1207 | clh: function() { 1208 | 1209 | /* Half Carry Flag cleared */ 1210 | this.dataspace[this.sreg][5] = false; 1211 | 1212 | /* Program Counter: PC <- PC + 1 */ 1213 | this.PC++; 1214 | }, 1215 | /** 1216 | * CLI – Clear Global Interrupt Flag 1217 | * 1218 | * Clears the Global Interrupt Flag (I) in SREG (Status Register). 1219 | * The interrupts will be immediately disabled. 1220 | * No interrupt will be executed after the CLI instruction, 1221 | * even if it occurs simultaneously with the CLI instruction. 1222 | */ 1223 | cli: function() { 1224 | 1225 | /* Global Interrupt Flag cleared */ 1226 | this.dataspace[this.sreg][7] = false; 1227 | 1228 | /* Program Counter: PC <- PC + 1 */ 1229 | this.PC++; 1230 | }, 1231 | /** 1232 | * CLN – Clear Negative Flag 1233 | * 1234 | * Clears the Negative Flag (N) in SREG (Status Register). 1235 | */ 1236 | cln: function() { 1237 | 1238 | /* Negative Flag cleared */ 1239 | this.dataspace[this.sreg][2] = false; 1240 | 1241 | /* Program Counter: PC <- PC + 1 */ 1242 | this.PC++; 1243 | }, 1244 | /** 1245 | * CLR – Clear Register 1246 | * 1247 | * Clears a register. 1248 | * This instruction performs an Exclusive OR between a register and itself. 1249 | * This will clear all bits in the register. 1250 | * 1251 | * @param _Rd Destination register 1252 | */ 1253 | clr: function(_Rd) { 1254 | 1255 | var Rd = this.dataspace[_Rd]; 1256 | var SREG = this.dataspace[this.sreg]; 1257 | 1258 | /* Operation: Rd <- Rd != Rd */ 1259 | Rd[0] = Rd[0] !== Rd[0]; 1260 | Rd[1] = Rd[1] !== Rd[1]; 1261 | Rd[2] = Rd[2] !== Rd[2]; 1262 | Rd[3] = Rd[3] !== Rd[3]; 1263 | Rd[4] = Rd[4] !== Rd[4]; 1264 | Rd[5] = Rd[5] !== Rd[5]; 1265 | Rd[6] = Rd[6] !== Rd[6]; 1266 | Rd[7] = Rd[7] !== Rd[7]; 1267 | 1268 | /* @TODO */ 1269 | SREG[4] = false; 1270 | SREG[3] = false; 1271 | SREG[2] = false; 1272 | SREG[1] = true; 1273 | 1274 | /* Program Counter: PC <- PC + 1 */ 1275 | this.PC++; 1276 | 1277 | this.dataspace[_Rd] = Rd; 1278 | this.dataspace[this.sreg] = SREG; 1279 | }, 1280 | /** 1281 | * CLS – Clear Signed Flag 1282 | * 1283 | * Clears the Signed Flag (S) in SREG (Status Register). 1284 | */ 1285 | cls: function() { 1286 | 1287 | /* Signed Flag cleared */ 1288 | this.dataspace[this.sreg][4] = false; 1289 | 1290 | /* Program Counter: PC <- PC + 1 */ 1291 | this.PC++; 1292 | }, 1293 | /** 1294 | * CLT – Clear T Flag 1295 | * 1296 | * Clears the T Flag in SREG (Status Register). 1297 | */ 1298 | clt: function() { 1299 | 1300 | /* T Flag cleared */ 1301 | this.dataspace[this.sreg][6] = false; 1302 | 1303 | /* Program Counter: PC <- PC + 1 */ 1304 | this.PC++; 1305 | }, 1306 | /** 1307 | * CLV – Clear Overflow Flag 1308 | * 1309 | * Clears the Overflow Flag (V) in SREG (Status Register). 1310 | */ 1311 | clv: function() { 1312 | 1313 | /* Overflow Flag cleared */ 1314 | this.dataspace[this.sreg][3] = false; 1315 | 1316 | /* Program Counter: PC <- PC + 1 */ 1317 | this.PC++; 1318 | }, 1319 | /** 1320 | * CLZ – Clear Zero Flag 1321 | * 1322 | * Clears the Zero Flag (Z) in SREG (Status Register). 1323 | */ 1324 | clz: function() { 1325 | 1326 | /* Zero Flag cleared */ 1327 | this.dataspace[this.sreg][1] = false; 1328 | 1329 | /* Program Counter: PC <- PC + 1 */ 1330 | this.PC++; 1331 | }, 1332 | /** 1333 | * COM - One's Complement 1334 | * 1335 | * This instruction performs a One’s Complement of register Rd. 1336 | * 1337 | * @param _Rd 0 <= d <= 31 1338 | */ 1339 | com: function(_Rd) { 1340 | 1341 | var Rd = this.dataspace[_Rd]; 1342 | var SREG = this.dataspace[this.sreg]; 1343 | 1344 | /* Operation Rd <- $FF - Rd */ 1345 | Rd[0] = !Rd[0]; 1346 | Rd[1] = !Rd[1]; 1347 | Rd[2] = !Rd[2]; 1348 | Rd[3] = !Rd[3]; 1349 | Rd[4] = !Rd[4]; 1350 | Rd[5] = !Rd[5]; 1351 | Rd[6] = !Rd[6]; 1352 | Rd[7] = !Rd[7]; 1353 | 1354 | /* C: Set */ 1355 | SREG[0] = true; 1356 | /* Z: Set if the result is $00; cleared otherwise */ 1357 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && Rd[0]; 1358 | /* N: Set if MSB of the result is set; celared otherwise */ 1359 | SREG[2] = Rd[7]; 1360 | /* V: Celared */ 1361 | SREG[3] = false; 1362 | /* S: N ^ V, For signed tests. */ 1363 | SREG[4] = !!(SREG[2] ^ SREG[3]); 1364 | 1365 | /* Program Counter: PC <- PC + 1 */ 1366 | this.PC++; 1367 | 1368 | this.dataspace[_Rd] = Rd; 1369 | this.dataspace[this.sreg] = SREG; 1370 | }, 1371 | /** 1372 | * CP - Compare 1373 | * 1374 | * This instruction performs a compare between two registers Rd and Rr. None of the registers are changed. 1375 | * All conditional branches can be used after this instruction. 1376 | * 1377 | * @param _Rd 0 <= d <= 31 1378 | * @param _Rr 0 <= r <= 31 1379 | */ 1380 | cp: function(_Rd, _Rr) { 1381 | 1382 | var Rd = this.dataspace[_Rd]; 1383 | var Rr = this.dataspace[_Rr]; 1384 | var R = [false, false, false, false, false, false, false, false]; 1385 | var SREG = this.dataspace[this.sreg]; 1386 | 1387 | /* Operation: Rd - Rr */ 1388 | 1389 | /* @TODO */ 1390 | 1391 | /* C: Set if the absolute value of the contents of Rr is larger than the absolute value of Rd; cleared otherwise. */ 1392 | SREG[0] = !Rd[7] && Rr[7] || Rr[7] && R[7] || R[7] && !Rd[7]; 1393 | /* Z: Set if the result is $00; cleared otherwise */ 1394 | SREG[1] = !R[7] && !R[6] && !R[5] && !R[4] && !R[3] && !R[2] && !R[1] && R[0]; 1395 | /* N: Set if MSB of the result is set; cleared otherwise */ 1396 | SREG[2] = R[7]; 1397 | /* V: Set if two’s complement overflow resulted from the operation; cleared otherwise. */ 1398 | SREG[3] = Rd[7] && !Rr[7] && !R[7] || !Rd[7] && Rr[7] && R[7]; 1399 | /* S: N ^ V, For signed tests. */ 1400 | SREG[4] = !!(SREG[2] ^ SREG[3]); 1401 | /* H: Set if there was a borrow from bit 3; cleared otherwise */ 1402 | SREG[5] = !Rd[3] && Rr[3] || Rr[3] && R[3] || R[3] && !Rd[3]; 1403 | 1404 | /* Program Counter: PC <- PC + 1 */ 1405 | this.PC++; 1406 | }, 1407 | /** 1408 | * CPC - Compare with Carry 1409 | * 1410 | * This instruction performs a compare between two registers Rd and Rr and also takes into account the previous carry. 1411 | * None of the registers are changed. 1412 | * All conditional branches can be used after this instruction. 1413 | * 1414 | * @param _Rd 0 <= d <= 31 1415 | * @param _Rr 0 <= r <= 31 1416 | */ 1417 | cpc: function(_Rd, _Rr) { 1418 | 1419 | var Rd = this.dataspace[_Rd]; 1420 | var Rr = this.dataspace[_Rr]; 1421 | var R = [false, false, false, false, false, false, false, false]; 1422 | var SREG = this.dataspace[this.sreg]; 1423 | 1424 | /* Operation: Rd - Rr - C */ 1425 | 1426 | 1427 | /* @TODO */ 1428 | 1429 | /* C: Set if the absolute value of the contents of Rr is larger than the absolute value of Rd; cleared otherwise. */ 1430 | SREG[0] = !Rd[7] && Rr[7] || Rr[7] && R[7] || R[7] && !Rd[7]; 1431 | /* Z: Set if the result is $00; cleared otherwise */ 1432 | SREG[1] = !R[7] && !R[6] && !R[5] && !R[4] && !R[3] && !R[2] && !R[1] && R[0]; 1433 | /* N: Set if MSB of the result is set; cleared otherwise */ 1434 | SREG[2] = R[7]; 1435 | /* V: Set if two’s complement overflow resulted from the operation; cleared otherwise. */ 1436 | SREG[3] = Rd[7] && !Rr[7] && !R[7] || !Rd[7] && Rr[7] && R[7]; 1437 | /* S: N ^ V, For signed tests. */ 1438 | SREG[4] = !!(SREG[2] ^ SREG[3]); 1439 | /* H: Set if there was a borrow from bit 3; cleared otherwise */ 1440 | SREG[5] = !Rd[3] && Rr[3] || Rr[3] && R[3] || R[3] && !Rd[3]; 1441 | 1442 | /* Program Counter: PC <- PC + 1 */ 1443 | this.PC++; 1444 | 1445 | this.dataspace[this.sreg] = SREG; 1446 | }, 1447 | /** 1448 | * CPI - Compare with Immediate 1449 | * 1450 | * This instruction performs a compare between register Rd and a constant. 1451 | * The register is not changed. 1452 | * All conditional branches can be used after this instruction. 1453 | * 1454 | * @param _Rd 16 <= d <= 31 1455 | * @param K 0 <= K <= 255 1456 | */ 1457 | cpi: function(_Rd, K) { 1458 | 1459 | var Rd = this.dataspace[_Rd]; 1460 | var SREG = this.dataspace[this.sreg]; 1461 | 1462 | /* Operation: Rd - K */ 1463 | 1464 | /* @TODO */ 1465 | 1466 | /* C: Set if the absolute value of K is larger than the absolute value of Rd; cleared otherwise. */ 1467 | SREG[0] = !Rd[7] && K[7] || K[7] && R[7] || R[7] && !Rd[7]; 1468 | /* Z: Set if the result is $00; cleared otherwise */ 1469 | SREG[1] = !R[7] && !R[6] && !R[5] && !R[4] && !R[3] && !R[2] && !R[1] && R[0]; 1470 | /* N: Set if MSB of the result is set; cleared otherwise */ 1471 | SREG[2] = R[7]; 1472 | /* V: Set if two’s complement overflow resulted from the operation; cleared otherwise. */ 1473 | SREG[3] = Rd[7] && !K[7] && !R[7] || !Rd[7] && K[7] && R[7]; 1474 | /* S: N ^ V, For signed tests. */ 1475 | SREG[4] = !!(SREG[2] ^ SREG[3]); 1476 | /* H: Set if there was a borrow from bit 3; cleared otherwise */ 1477 | SREG[5] = !Rd[3] && K[3] || K[3] && R[3] || R[3] && !Rd[3]; 1478 | 1479 | /* Program Counter: PC <- PC + 1 */ 1480 | this.PC++; 1481 | 1482 | this.dataspace[this.sreg] = SREG; 1483 | }, 1484 | /** 1485 | * CPSE - Compare Skip if Equal 1486 | * 1487 | * This instruction performs a compare between two registers Rd and Rr, 1488 | * and skips the next instruction if Rd = Rr. 1489 | * 1490 | * @param _Rd 0 <= d <= 31 1491 | * @param _Rr 0 <= r <= 31 1492 | */ 1493 | cpse: function(_Rd, _Rr) { 1494 | 1495 | var Rd = this.dataspace[_Rd]; 1496 | var Rr = this.dataspace[_Rr]; 1497 | var SREG = this.dataspace[this.sreg]; 1498 | 1499 | /* Operation if Rd = Rr then PC <- PC + 2 (or 3) else PC <- PC + 1 */ 1500 | if ( 1501 | Rd[0] === Rr[0] && 1502 | Rd[1] === Rr[1] && 1503 | Rd[2] === Rr[2] && 1504 | Rd[3] === Rr[3] && 1505 | Rd[4] === Rr[4] && 1506 | Rd[5] === Rr[5] && 1507 | Rd[6] === Rr[6] && 1508 | Rd[7] === Rr[7] 1509 | ) { 1510 | /* Program Counter: PC <- PC + 2, Skip a one word instruction */ 1511 | this.PC += 2; 1512 | } 1513 | else { 1514 | /* Program Counter: PC <- PC + 1, Condition false - no skip */ 1515 | this.PC++; 1516 | } 1517 | }, 1518 | /** 1519 | * DEC - Decrement 1520 | * 1521 | * Subtracts one -1- from the contents of register Rd and places the result in the destination register Rd. 1522 | * The C Flag in SREG is not affected by the operation, 1523 | * thus allowing the DEC instruction to be used on a loop counter in multiple-precision computations. 1524 | * When operating on unsigned values, only BREQ and BRNE branches can be expected to perform consistently. 1525 | * When operating on two’s complement values, all signed branches are available. 1526 | * 1527 | * @param _Rd 0 <= d <= 31 1528 | */ 1529 | dec: function(_Rd) { 1530 | 1531 | /* Operation: Rd <- Rd - 1 */ 1532 | 1533 | /* @TODO */ 1534 | 1535 | 1536 | /* Program Counter: PC <- PC + 1 */ 1537 | this.PC++; 1538 | }, 1539 | /** 1540 | * DES – Data Encryption Standard 1541 | * 1542 | * 1543 | * 1544 | * 1545 | * 1546 | * 1547 | * @param K 1548 | */ 1549 | des: function(K) { 1550 | 1551 | /* @TODO */ 1552 | 1553 | }, 1554 | /** 1555 | * EICALL – Extended Indirect Call to Subroutine 1556 | * 1557 | * 1558 | * 1559 | * 1560 | */ 1561 | eicall: function() { 1562 | 1563 | /* @TODO */ 1564 | 1565 | }, 1566 | /** 1567 | * EIJMP – Extended Indirect Jump 1568 | * 1569 | * 1570 | */ 1571 | eijmp: function() { 1572 | 1573 | 1574 | /* @TODO */ 1575 | }, 1576 | /** 1577 | * ELPM – Extended Load Program Memory 1578 | * 1579 | * 1580 | * 1581 | */ 1582 | elpm: function() { 1583 | 1584 | /* @TODO */ 1585 | }, 1586 | /** 1587 | * EOR – Exclusive OR 1588 | * 1589 | * Performs the logical EOR between the contents of register Rd and register Rr 1590 | * and places the result in the destination register Rd. 1591 | * 1592 | * @param _Rd 1593 | * @param _Rr 1594 | */ 1595 | eor: function(_Rd, _Rr) { 1596 | 1597 | var Rd = this.dataspace[_Rd]; 1598 | var Rr = this.dataspace[_Rr]; 1599 | var SREG = this.dataspace[this.sreg]; 1600 | 1601 | /* Operation: Rd <- Rd != Rr */ 1602 | Rd[0] = Rd[0] !== Rr[0]; 1603 | Rd[1] = Rd[1] !== Rr[1]; 1604 | Rd[2] = Rd[2] !== Rr[2]; 1605 | Rd[3] = Rd[3] !== Rr[3]; 1606 | Rd[4] = Rd[4] !== Rr[4]; 1607 | Rd[5] = Rd[5] !== Rr[5]; 1608 | Rd[6] = Rd[6] !== Rr[6]; 1609 | Rd[7] = Rd[7] !== Rr[7]; 1610 | 1611 | /* @TODO */ 1612 | SREG[4]; 1613 | /* Cleared */ 1614 | SREG[3] = false; 1615 | /* Set if MSB of the result is set; cleared otherwise. */ 1616 | SREG[2] = Rd[7]; 1617 | /* Set if the result is $00; cleared otherwise. */ 1618 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && !Rd[0]; 1619 | 1620 | /* Program Counter: PC <- PC + 1 */ 1621 | this.PC++; 1622 | 1623 | this.dataspace[_Rd] = Rd; 1624 | this.dataspace[this.sreg] = SREG; 1625 | }, 1626 | /** 1627 | * FMUL – Fractional Multiply Unsigned 1628 | */ 1629 | fmul: function() { 1630 | 1631 | /* @TODO */ 1632 | }, 1633 | /** 1634 | * FMULS – Fractional Multiply Signed 1635 | * 1636 | */ 1637 | fmuls: function() { 1638 | 1639 | 1640 | /* @TODO */ 1641 | 1642 | }, 1643 | /** 1644 | * FMULSU – Fractional Multiply Signed with Unsigned 1645 | */ 1646 | fmulsu: function() { 1647 | 1648 | /* @TODO */ 1649 | }, 1650 | /** 1651 | * ICALL – Indirect Call to Subroutine 1652 | * 1653 | */ 1654 | icall: function() { 1655 | 1656 | /* @TODO */ 1657 | }, 1658 | /** 1659 | * IJMP – Indirect Jump 1660 | */ 1661 | ijmp: function() { 1662 | 1663 | /* @TODO */ 1664 | }, 1665 | /** 1666 | * IN - Load an I/O Location to Register 1667 | * 1668 | * Loads data from the I/O Space (Ports, Timers, Configuration Registers etc.) 1669 | * into register Rd in the Register File. 1670 | * 1671 | * @param _Rd 0 <= d <= 31 1672 | * @param A 0 <= A <= 63 1673 | */ 1674 | in: function(_Rd, A) { 1675 | 1676 | var Rd = this.dataspace[Rd]; 1677 | var A = this.io[A]; 1678 | 1679 | /* Operation: Rd <- I/O(A) */ 1680 | Rd[0] = A[0]; 1681 | Rd[1] = A[1]; 1682 | Rd[2] = A[2]; 1683 | Rd[3] = A[3]; 1684 | Rd[4] = A[4]; 1685 | Rd[5] = A[5]; 1686 | Rd[6] = A[6]; 1687 | Rd[7] = A[7]; 1688 | 1689 | /* Program Counter: PC <- PC + 1 */ 1690 | this.PC++; 1691 | 1692 | this.dataspace[_Rd] = Rd; 1693 | }, 1694 | /** 1695 | * INC – Increment 1696 | * 1697 | * Adds one -1- to the contents of register Rd and places the result in the destination register Rd. 1698 | * The C Flag in SREG is not affected by the operation, 1699 | * thus allowing the INC instruction to be used on a loop counter in multiple-precision computations. 1700 | * When operating on unsigned numbers, only BREQ and BRNE branches can be expected to perform consistently. 1701 | * When operating on two’s complement values, all signed branches are available. 1702 | * 1703 | * @param _Rd 0 <= d <= 31 1704 | */ 1705 | inc: function(_Rd) { 1706 | 1707 | var Rd = this.dataspace[_Rd]; 1708 | var R = [false, false, false, false, false, false, false, false]; 1709 | var C = [false, false, false, false, false, false, false, false]; 1710 | var SREG = this.dataspace[this.sreg]; 1711 | 1712 | /* Operation: Rd <- Rd + 1 */ 1713 | C[0] = false; 1714 | 1715 | R[0] = !Rd[0]; 1716 | C[1] = Rd[0]; 1717 | 1718 | R[1] = !!(Rd[1] ^ C[1]); 1719 | C[2] = Rd[1] && C[1]; 1720 | 1721 | R[2] = !!(Rd[2] ^ C[2]); 1722 | C[3] = Rd[2] && C[2]; 1723 | 1724 | R[3] = !!(Rd[3] ^ C[3]); 1725 | C[4] = Rd[3] && C[3]; 1726 | 1727 | R[4] = !!(Rd[4] ^ C[4]); 1728 | C[5] = Rd[4] && C[4]; 1729 | 1730 | R[5] = !!(Rd[5] ^ C[5]); 1731 | C[6] = Rd[5] && C[5]; 1732 | 1733 | R[6] = !!(Rd[6] ^ C[6]); 1734 | C[7] = Rd[6] && C[6]; 1735 | 1736 | R[7] = !!(Rd[7] ^ C[7]); 1737 | 1738 | /* Z: Set if the result is $00; cleared otherwise. */ 1739 | SREG[1] = !R[7] && !R[6] && !R[5] && !R[4] && !R[3] && !R[2] && !R[1] && R[0]; 1740 | /* N: Set if MSB of the result is set; cleared otherwise. */ 1741 | SREG[2] = R[7]; 1742 | /* V: Set if two’s complement overflow resulted from the operation; cleared otherwise. */ 1743 | SREG[3] = R[7] && !R[6] && !R[5] && !R[4] && !R[3] && !R[2] && !R[1] && !R[0]; 1744 | /* S: N ^ V, For signed tests. */ 1745 | SREG[4] = !!(SREG[2] ^ SREG[3]); 1746 | 1747 | /* Program Counter: PC <- PC + 1 */ 1748 | this.PC++; 1749 | 1750 | this.dataspace[_Rd] = R; 1751 | this.dataspace[this.sreg] = SREG; 1752 | }, 1753 | /** 1754 | * JMP – Jump 1755 | * 1756 | * Jump to an address within the entire 4M (words) Program memory. 1757 | * See also RJMP. 1758 | * 1759 | * @param k 1760 | */ 1761 | jmp: function(k) { 1762 | 1763 | /* @TODO */ 1764 | 1765 | /* Program Counter: PC <- k */ 1766 | this.PC = k; 1767 | 1768 | }, 1769 | /** 1770 | * LAC - Load And Clear 1771 | * 1772 | * @param Z 1773 | * @param _Rd 0 <= d <= 31 1774 | */ 1775 | lac: function(Z, _Rd) { 1776 | 1777 | /* Operation: (Z) <- Rd && ($FF - (Z)) */ 1778 | 1779 | /* @TODO */ 1780 | 1781 | /* Program Counter: PC <- PC + 1 */ 1782 | this.PC++; 1783 | }, 1784 | /** 1785 | * LAS - Load And Set 1786 | * 1787 | * @param Z 1788 | * @param _Rd 0 <= d <= 31 1789 | */ 1790 | las: function(Z, _Rd) { 1791 | 1792 | /* Operation: (Z) <- Rd v (Z), Rd <- (Z) */ 1793 | 1794 | /* @TODO */ 1795 | 1796 | /* Program Counter: PC <- PC + 1 */ 1797 | this.PC++; 1798 | }, 1799 | /** 1800 | * LAT - Load And Toggle 1801 | * 1802 | * @param Z 1803 | * @param _Rd 0 <= d <= 31 1804 | */ 1805 | lat: function(Z, _Rd) { 1806 | 1807 | /* @TODO */ 1808 | 1809 | 1810 | /* Program Counter: PC <- PC + 1 */ 1811 | this.PC++; 1812 | }, 1813 | /** 1814 | * LD - Load Indirect from Data Space to Register using Index X 1815 | */ 1816 | ld: function() { 1817 | 1818 | /* @TODO */ 1819 | }, 1820 | /** 1821 | * LDI – Load Immediate 1822 | * 1823 | * Loads an 8 bit constant directly to register 16 to 31. 1824 | * 1825 | * @param {type} _Rd 1826 | * @param {type} K 1827 | */ 1828 | ldi: function(_Rd, K) { 1829 | 1830 | var Rd = this.dataspace[_Rd]; 1831 | 1832 | /* Operation Rd <- K */ 1833 | Rd[0] = K[0]; 1834 | Rd[1] = K[1]; 1835 | Rd[2] = K[2]; 1836 | Rd[3] = K[3]; 1837 | Rd[4] = K[4]; 1838 | Rd[5] = K[5]; 1839 | Rd[6] = K[6]; 1840 | Rd[7] = K[7]; 1841 | 1842 | /* Program Counter: PC <- PC + 1 */ 1843 | this.PC++; 1844 | 1845 | this.dataspace[_Rd] = Rd; 1846 | }, 1847 | /** 1848 | * LDS - Load Direct from Data Space 1849 | * 1850 | * Loads one byte from the data space to a register. 1851 | * For parts with SRAM, the data space consists of the Register File, 1852 | * I/O memory and internal SRAM (and external SRAM if applicable) 1853 | * For parts without SRAM, the data space consists of the register file only. 1854 | * The EEPROM has a separate address space. 1855 | * 1856 | * A 16-bit address must be supplied. 1857 | * Memory access is limited to the current data segment of 64K bytes. 1858 | * The LDS instruction uses the RAMPD Register to access memory above 64K bytes. 1859 | * To access another data segment in devices with more than 64K bytes data space, 1860 | * the RAMPD in register in the I/O area has to be changed. 1861 | * 1862 | * This instruction is not available in all devices. 1863 | * Refer to the device specific instruction set summary. 1864 | * 1865 | * @param _Rd 0 <= d <= 31 1866 | * @param k 0 <= k <= 65535 1867 | */ 1868 | lds: function(_Rd, k) { 1869 | 1870 | var Rd = this.dataspace[_Rd]; 1871 | 1872 | /* @TODO */ 1873 | 1874 | /* Operation: Rd <- (k) */ 1875 | Rd[0] = this.ds[k][0]; 1876 | Rd[1] = this.ds[k][1]; 1877 | Rd[2] = this.ds[k][2]; 1878 | Rd[3] = this.ds[k][3]; 1879 | Rd[4] = this.ds[k][4]; 1880 | Rd[5] = this.ds[k][5]; 1881 | Rd[6] = this.ds[k][6]; 1882 | Rd[7] = this.ds[k][7]; 1883 | 1884 | /* Program Counter: PC <- PC + 1 */ 1885 | this.PC++; 1886 | 1887 | this.dataspace[_Rd] = Rd; 1888 | }, 1889 | /** 1890 | * LPM - Load Program Memory 1891 | * 1892 | */ 1893 | lpm: function() { 1894 | 1895 | /* @TODO */ 1896 | 1897 | /* Program Counter: PC <- PC + 1 */ 1898 | this.PC++; 1899 | }, 1900 | /** 1901 | * Logical Shift Left 1902 | * 1903 | * Shifts all bits in Rd one place to the left. 1904 | * Bit 0 is cleared. 1905 | * Bit 7 is loaded into the C Flag of the SREG. 1906 | * This operation effectively multiplies signed and unsigned values by two. 1907 | * 1908 | * @param _Rd 1909 | */ 1910 | lsl: function(_Rd) { 1911 | 1912 | var Rd = this.dataspace[_Rd]; 1913 | var SREG = this.dataspace[this.sreg]; 1914 | 1915 | /* Set if, before the shift, the MSB of Rd was set; cleared otherwise. */ 1916 | SREG[0] = Rd[7]; 1917 | 1918 | /* Operation */ 1919 | Rd[7] = Rd[6]; 1920 | Rd[6] = Rd[5]; 1921 | Rd[5] = Rd[4]; 1922 | Rd[4] = Rd[3]; 1923 | Rd[3] = Rd[2]; 1924 | Rd[2] = Rd[1]; 1925 | Rd[1] = Rd[0]; 1926 | Rd[0] = false; 1927 | 1928 | /* @TODO */ 1929 | SREG[5] = Rd[3]; 1930 | /* For signed tests. */ 1931 | SREG[4] = !!(SREG[2] ^ SREG[3]); 1932 | /* For N and C after the shift. */ 1933 | SREG[3] = !!(SREG[2] ^ SREG[0]); 1934 | /* Set if MSB of the result is set; cleared otherwise. */ 1935 | SREG[2] = Rd[7]; 1936 | /* Set if the result is $00; cleared otherwise */ 1937 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && !Rd[0]; 1938 | 1939 | /* Program Counter: PC <- PC + 1 */ 1940 | this.PC++; 1941 | 1942 | this.dataspace[_Rd] = Rd; 1943 | this.dataspace[this.sreg] = SREG; 1944 | }, 1945 | /** 1946 | * Logical Shift Right 1947 | * 1948 | * Shifts all bits in Rd one place to the right. 1949 | * Bit 7 is cleared. 1950 | * Bit 0 is loaded into the C Flag of the SREG. 1951 | * This operation effectively divides an unsigned value by two. 1952 | * The C Flag can be used to round the result. 1953 | * 1954 | * @param _Rd 1955 | */ 1956 | lsr: function(_Rd) { 1957 | 1958 | var Rd = this.dataspace[_Rd]; 1959 | var SREG = this.dataspace[this.sreg]; 1960 | 1961 | /* Set if, before the shift, the LSB of Rd was set; cleared otherwise */ 1962 | SREG[0] = Rd[0]; 1963 | 1964 | /* Operation */ 1965 | Rd[0] = Rd[1]; 1966 | Rd[1] = Rd[2]; 1967 | Rd[2] = Rd[3]; 1968 | Rd[3] = Rd[4]; 1969 | Rd[4] = Rd[5]; 1970 | Rd[5] = Rd[6]; 1971 | Rd[6] = Rd[7]; 1972 | Rd[7] = false; 1973 | 1974 | /* @TODO */ 1975 | /* For signed tests. */ 1976 | SREG[4] = !!(SREG[2] ^ SREG[3]); 1977 | /* For N and C after the shift. */ 1978 | SREG[3] = !!(SREG[2] ^ SREG[0]); 1979 | SREG[2] = false; 1980 | /* Set if the result is $00; cleared otherwise */ 1981 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && !Rd[0]; 1982 | 1983 | /* Program Counter: PC <- PC + 1 */ 1984 | this.PC++; 1985 | 1986 | this.dataspace[_Rd] = Rd; 1987 | this.dataspace[this.sreg] = SREG; 1988 | }, 1989 | /** 1990 | * MOV – Copy Registe 1991 | * 1992 | * This instruction makes a copy of one register into another. 1993 | * The source register Rr is left unchanged, 1994 | * while the destination register Rd is loaded with a copy of Rr. 1995 | * 1996 | * @param _Rd 1997 | * @param _Rr 1998 | */ 1999 | mov: function(_Rd, _Rr) { 2000 | 2001 | var Rd = this.dataspace[_Rd]; 2002 | var Rr = this.dataspace[_Rr]; 2003 | 2004 | /* Operation: Rd <- Rr */ 2005 | Rd[0] = Rr[0]; 2006 | Rd[1] = Rr[1]; 2007 | Rd[2] = Rr[2]; 2008 | Rd[3] = Rr[3]; 2009 | Rd[4] = Rr[4]; 2010 | Rd[5] = Rr[5]; 2011 | Rd[6] = Rr[6]; 2012 | Rd[7] = Rr[7]; 2013 | 2014 | /* Program Counter: PC <- PC + 1 */ 2015 | this.PC++; 2016 | 2017 | this.dataspace[_Rd] = Rd; 2018 | }, 2019 | /** 2020 | * MOVW – Copy Register Word 2021 | * 2022 | * This instruction makes a copy of one register pair into another register pair. 2023 | * The source register pair Rr+1:Rr is left unchanged, 2024 | * while the destination register pair Rd+1:Rd is loaded with a copy of Rr + 1:Rr. 2025 | * 2026 | * @param _Rd 2027 | * @param _Rr 2028 | */ 2029 | movw: function(_Rd, _Rr) { 2030 | 2031 | var Rd = this.dataspace[_Rd]; 2032 | var Rd1 = this.dataspace[_Rd + 1]; 2033 | var Rr = this.dataspace[_Rr]; 2034 | var Rr1 = this.dataspace[_Rr + 1]; 2035 | 2036 | /* Operation: Rd+1:Rd <- Rr+1:Rr */ 2037 | /* @TODO */ 2038 | 2039 | /* Program Counter: PC <- PC + 1 */ 2040 | this.PC++; 2041 | }, 2042 | mul: function() { 2043 | /* @TODO */ 2044 | 2045 | 2046 | /* Program Counter: PC <- PC + 1 */ 2047 | this.PC++; 2048 | }, 2049 | muls: function() { 2050 | /* @TODO */ 2051 | 2052 | /* Program Counter: PC <- PC + 1 */ 2053 | this.PC++; 2054 | }, 2055 | mulsu: function() { 2056 | 2057 | /* @TODO */ 2058 | 2059 | /* Program Counter: PC <- PC + 1 */ 2060 | this.PC++; 2061 | }, 2062 | neg: function() { 2063 | 2064 | /* @TODO */ 2065 | 2066 | /* Program Counter: PC <- PC + 1 */ 2067 | this.PC++; 2068 | }, 2069 | /** 2070 | * NOP – No Operation 2071 | * 2072 | * This instruction performs a single cycle No Operation. 2073 | */ 2074 | nop: function() { 2075 | 2076 | /* Program Counter: PC <- PC + 1 */ 2077 | this.PC++; 2078 | }, 2079 | /** 2080 | * OR – Logical OR 2081 | * 2082 | * Performs the logical OR between the contents of register Rd and register Rr 2083 | * and places the result in the destination register Rd. 2084 | * 2085 | * @param _Rd 2086 | * @param _Rr 2087 | */ 2088 | or: function(_Rd, _Rr) { 2089 | 2090 | var Rd = this.dataspace[_Rd]; 2091 | var Rr = this.dataspace[_Rr]; 2092 | var SREG = this.dataspace[this.sreg]; 2093 | 2094 | /* Operation: Rd <- Rd || Rr */ 2095 | Rd[0] = Rd[0] || Rr[0]; 2096 | Rd[1] = Rd[1] || Rr[1]; 2097 | Rd[2] = Rd[2] || Rr[2]; 2098 | Rd[3] = Rd[3] || Rr[3]; 2099 | Rd[4] = Rd[4] || Rr[4]; 2100 | Rd[5] = Rd[5] || Rr[5]; 2101 | Rd[6] = Rd[6] || Rr[6]; 2102 | Rd[7] = Rd[7] || Rr[7]; 2103 | 2104 | /* @TODO */ 2105 | SREG[4]; 2106 | /* Cleared */ 2107 | SREG[3] = false; 2108 | /* Set if MSB of the result is set; cleared otherwise. */ 2109 | SREG[2] = Rd[7]; 2110 | /* Set if the result is $00; cleared otherwise. */ 2111 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && !Rd[0]; 2112 | 2113 | /* Program Counter: PC <- PC + 1 */ 2114 | this.PC++; 2115 | 2116 | this.dataspace[_Rd] = Rd; 2117 | this.dataspace[this.sreg] = SREG; 2118 | }, 2119 | /** 2120 | * ORI – Logical OR with Immediate 2121 | * 2122 | * Performs the logical OR between the contents of register Rd and a constant 2123 | * and places the result in the destination register Rd. 2124 | * 2125 | * @param _Rd 2126 | * @param K 2127 | */ 2128 | ori: function(_Rd, K) { 2129 | 2130 | var Rd = this.dataspace[_Rd]; 2131 | var SREG = this.dataspace[this.sreg]; 2132 | 2133 | /* Operation: Rd <- Rd v K */ 2134 | Rd[0] = Rd[0] || K[0]; 2135 | Rd[1] = Rd[1] || K[1]; 2136 | Rd[2] = Rd[2] || K[2]; 2137 | Rd[3] = Rd[3] || K[3]; 2138 | Rd[4] = Rd[4] || K[4]; 2139 | Rd[5] = Rd[5] || K[5]; 2140 | Rd[6] = Rd[6] || K[6]; 2141 | Rd[7] = Rd[7] || K[7]; 2142 | 2143 | /* @TODO */ 2144 | SREG[4]; 2145 | /* Cleared */ 2146 | SREG[3] = false; 2147 | /* Set if MSB of the result is set; cleared otherwise. */ 2148 | SREG[2] = Rd[7]; 2149 | /* Set if the result is $00; cleared otherwise. */ 2150 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && !Rd[0]; 2151 | 2152 | /* Program Counter: PC <- PC + 1 */ 2153 | this.PC++; 2154 | 2155 | this.dataspace[_Rd] = Rd; 2156 | this.dataspace[this.sreg] = SREG; 2157 | }, 2158 | /** 2159 | * OUT – Store Register to I/O Location 2160 | * 2161 | * Stores data from register Rr in the Register File to I/O Space (Ports, Timers, Configuration Registers etc.). 2162 | * 2163 | * @param A 2164 | * @param _Rr 2165 | */ 2166 | out: function(A, _Rr) { 2167 | 2168 | /* @TODO */ 2169 | 2170 | }, 2171 | /** 2172 | * POP – Pop Register from Stack 2173 | * 2174 | * This instruction loads register Rd with a byte from the STACK. 2175 | * The Stack Pointer is pre-incremented by 1 before the POP. 2176 | * 2177 | * @param _Rd 2178 | */ 2179 | pop: function(_Rd) { 2180 | 2181 | var SPL = this.dataspace[this.spl]; 2182 | var SPH = this.dataspace[this.sph]; 2183 | var C = [false, false, false, false, false, false, false, false]; 2184 | 2185 | C[0] = false; 2186 | 2187 | SPL[0] = !SPL[0]; 2188 | C[1] = SPL[0]; 2189 | 2190 | SPL[1] = !!(SPL[1] ^ C[1]); 2191 | C[2] = SPL[1] && C[1]; 2192 | 2193 | SPL[2] = !!(SPL[2] ^ C[2]); 2194 | C[3] = SPL[2] && C[2]; 2195 | 2196 | SPL[3] = !!(SPL[3] ^ C[3]); 2197 | C[4] = SPL[3] && C[3]; 2198 | 2199 | SPL[4] = !!(SPL[4] ^ C[4]); 2200 | C[5] = SPL[4] && C[4]; 2201 | 2202 | SPL[5] = !!(SPL[5] ^ C[5]); 2203 | C[6] = SPL[5] && C[5]; 2204 | 2205 | SPL[6] = !!(SPL[6] ^ C[6]); 2206 | C[7] = SPL[6] && C[6]; 2207 | 2208 | SPL[7] = !!(SPL[7] ^ C[7]); 2209 | 2210 | /* @TODO */ 2211 | 2212 | /* Program Counter: PC <- PC + 1 */ 2213 | this.PC++; 2214 | }, 2215 | /** 2216 | * PUSH – Push Register on Stack 2217 | * 2218 | * This instruction stores the contents of register Rr on the STACK. 2219 | * The Stack Pointer is post-decremented by 1 after the PUSH. 2220 | * 2221 | * @param _Rr 2222 | */ 2223 | push: function(_Rr) { 2224 | 2225 | /* @TODO */ 2226 | 2227 | var Rr = this.dataspace[_Rr]; 2228 | var SPL = this.dataspace[this.spl]; 2229 | var SPH = this.dataspace[this.sph]; 2230 | 2231 | 2232 | 2233 | 2234 | 2235 | 2236 | 2237 | /* Program Counter: PC <- PC + 1 */ 2238 | this.PC++; 2239 | }, 2240 | rcall: function() { 2241 | 2242 | /* @TODO */ 2243 | 2244 | 2245 | 2246 | /* Program Counter: PC <- PC + 1 */ 2247 | this.PC++; 2248 | }, 2249 | ret: function() { 2250 | 2251 | /* @TODO */ 2252 | 2253 | /* Program Counter: PC <- PC + 1 */ 2254 | this.PC++; 2255 | }, 2256 | reti: function() { 2257 | 2258 | /* @TODO */ 2259 | 2260 | /* Program Counter: PC <- PC + 1 */ 2261 | this.PC++; 2262 | }, 2263 | /** 2264 | * RJMP – Relative Jump 2265 | * 2266 | * Relative jump to an address within PC - 2K +1 and PC + 2K (words). 2267 | * For AVR microcontrollers with Program memory not exceeding 4K words (8K bytes) this instruction can address 2268 | * the entire memory from every address location. See also JMP. 2269 | * 2270 | * @param k -2K <= k <= 2K 2271 | */ 2272 | rjmp: function(k) { 2273 | 2274 | /* Program Counter: PC ← PC + k + 1 */ 2275 | this.PC += k + 1; 2276 | }, 2277 | /** 2278 | * ROL – Rotate Left trough Carry 2279 | * 2280 | * Shifts all bits in Rd one place to the left. 2281 | * The C Flag is shifted into bit 0 of Rd. 2282 | * Bit 7 is shifted into the C Flag. 2283 | * This operation, combined with LSL, effectively multiplies multi-byte signed and unsigned values by two. 2284 | * 2285 | * @param _Rd 2286 | */ 2287 | rol: function(_Rd) { 2288 | 2289 | var Rd = this.dataspace[_Rd]; 2290 | var SREG = this.dataspace[this.sreg]; 2291 | 2292 | /* Rd3 */ 2293 | SREG[5] = Rd[3]; 2294 | /* Set if, before the shift, the MSB of Rd was set; cleared otherwise. */ 2295 | SREG[0] = Rd[7]; 2296 | 2297 | /* Operation: C <- b7 <- ... <- b0 <- C */ 2298 | Rd[7] = Rd[6]; 2299 | Rd[6] = Rd[5]; 2300 | Rd[5] = Rd[4]; 2301 | Rd[4] = Rd[3]; 2302 | Rd[3] = Rd[2]; 2303 | Rd[2] = Rd[1]; 2304 | Rd[1] = Rd[0]; 2305 | Rd[0] = SREG[0]; 2306 | 2307 | /* Set if MSB of the result is set; cleared otherwise. */ 2308 | SREG[2] = Rd[7]; 2309 | /* N ^ C (For N and C after the shift) */ 2310 | SREG[3] = !!(SREG[2] ^ SREG[0]); 2311 | /* N ^ V, For signed tests. */ 2312 | SREG[4] = !!(SREG[2] ^ SREG[3]); 2313 | /* Set if the result is $00; cleared otherwise. */ 2314 | SREG[1] = !Rd[0] && !Rd[1] && !Rd[2] && !Rd[3] && !Rd[4] && !Rd[5] && !Rd[6] && !Rd[7]; 2315 | 2316 | /* Program counter: PC <- PC + 1 */ 2317 | this.PC++; 2318 | 2319 | /* Save changes */ 2320 | this.dataspace[_Rd] = Rd; 2321 | this.dataspace[this.sreg] = SREG; 2322 | }, 2323 | /** 2324 | * ROR – Rotate Right through Carry 2325 | * 2326 | * Shifts all bits in Rd one place to the right. 2327 | * The C Flag is shifted into bit 7 of Rd. 2328 | * Bit 0 is shifted into the C Flag. 2329 | * This operation, combined with ASR, effectively divides multi-byte signed values by two. 2330 | * Combined with LSR it effectively divides multibyte unsigned values by two. 2331 | * The Carry Flag can be used to round the result. 2332 | * 2333 | * @param _Rd 2334 | */ 2335 | ror: function(_Rd) { 2336 | 2337 | var Rd = this.dataspace[_Rd]; 2338 | var SREG = this.dataspace[this.sreg]; 2339 | 2340 | /* Rd3 */ 2341 | SREG[5] = Rd[3]; 2342 | /* Set if, before the shift, the MSB of Rd was set; cleared otherwise. */ 2343 | SREG[0] = Rd[0]; 2344 | 2345 | Rd[0] = Rd[1]; 2346 | Rd[1] = Rd[2]; 2347 | Rd[2] = Rd[3]; 2348 | Rd[3] = Rd[4]; 2349 | Rd[4] = Rd[5]; 2350 | Rd[5] = Rd[6]; 2351 | Rd[6] = Rd[7]; 2352 | Rd[7] = SREG[0]; 2353 | 2354 | /* Set if MSB of the result is set; cleared otherwise. */ 2355 | SREG[2] = Rd[7]; 2356 | /* N ^ C (For N and C after the shift) */ 2357 | SREG[3] = !!(SREG[2] ^ SREG[0]); 2358 | /* N ^ V, For signed tests. */ 2359 | SREG[4] = !!(SREG[2] ^ SREG[3]); 2360 | /* Set if the result is $00; cleared otherwise. */ 2361 | SREG[1] = !Rd[0] && !Rd[1] && !Rd[2] && !Rd[3] && !Rd[4] && !Rd[5] && !Rd[6] && !Rd[7]; 2362 | 2363 | /* Program counter: PC <- PC + 1 */ 2364 | this.PC++; 2365 | 2366 | /* Save changes */ 2367 | this.dataspace[_Rd] = Rd; 2368 | this.dataspace[this.sreg] = SREG; 2369 | }, 2370 | /** 2371 | * SBC – Subtract with Carry 2372 | * 2373 | * Subtracts two registers and subtracts with the C Flag and places the result in the destination register Rd. 2374 | * 2375 | * @param _Rd 2376 | * @param _Rr 2377 | */ 2378 | sbc: function(_Rd, _Rr) { 2379 | 2380 | /* Operation: Rd <- Rd - Rr - C */ 2381 | 2382 | /* @TODO */ 2383 | 2384 | /* Program Counter: PC <- PC + 1 */ 2385 | this.PC++; 2386 | }, 2387 | /** 2388 | * SBCI – Subtract Immediate with Carry 2389 | * 2390 | * Subtracts a constant from a register and subtracts with the C Flag 2391 | * and places the result in the destination register Rd. 2392 | * 2393 | * @param _Rd 16 <= d <= 31 2394 | * @param K 0 <= K <= 255 2395 | */ 2396 | sbci: function(_Rd, K) { 2397 | 2398 | /* Operation: Rd <- Rd - K - C */ 2399 | 2400 | /* @TODO */ 2401 | 2402 | /* Program Counter: PC <- PC + 1 */ 2403 | this.PC++; 2404 | }, 2405 | /** 2406 | * SBI – Set Bit in I/O Register 2407 | * 2408 | * Sets a specified bit in an I/O Register. 2409 | * This instruction operates on the lower 32 I/O Registers – addresses 0-31 2410 | * 2411 | * @param A 0 <= A <= 31 2412 | * @param b 0 <= b <= 7 2413 | */ 2414 | sbi: function(A, b) { 2415 | 2416 | /* Operation: I/O(A,b) <- 1 */ 2417 | this.io[A][b] = true; 2418 | 2419 | /* Program Counter: PC <- PC + 1 */ 2420 | this.PC++; 2421 | }, 2422 | /** 2423 | * SBIC – Skip if Bit in I/O Register is Cleared 2424 | * 2425 | * This instruction tests a single bit in an I/O Register and skips the next instruction if the bit is cleared. 2426 | * This instruction operates on the lower 32 I/O Registers – addresses 0-31. 2427 | * 2428 | * @param A 0 <= A <= 31 2429 | * @param b 0 <= b <= 7 2430 | */ 2431 | sbic: function(A, b) { 2432 | 2433 | /* Operation: If I/O(A,b) = 0 then PC <- PC + 2 (or 3) else PC <- PC + 1 */ 2434 | if (this.io[A][b] === false) { 2435 | /* Program Counter: PC <- PC + 2, Skip a one word instruction */ 2436 | this.PC += 2; 2437 | } 2438 | else { 2439 | /* Program Counter: PC <- PC + 1, Condition false - no skip */ 2440 | this.PC++; 2441 | } 2442 | }, 2443 | /** 2444 | * SBIS – Skip if Bit in I/O Register is Set 2445 | * 2446 | * This instruction tests a single bit in an I/O Register and skips the next instruction if the bit is set. 2447 | * This instruction operates on the lower 32 I/O Registers – addresses 0-31. 2448 | * 2449 | * @param A 0 <= A <= 31 2450 | * @param b 0 <= b <= 7 2451 | */ 2452 | sbis: function(A, b) { 2453 | 2454 | /* Operation: If I/O(A,b) = 1 then PC <- PC + 2 (or 3) else PC <- PC + 1 */ 2455 | if (this.io[A][b] === true) { 2456 | /* Program Counter: PC <- PC + 2, Skip a one word instruction */ 2457 | this.PC += 2; 2458 | } 2459 | else { 2460 | /* Program Counter: PC <- PC + 1, Condition false - no skip */ 2461 | this.PC++; 2462 | } 2463 | }, 2464 | /** 2465 | * SBIW - SBIW – Subtract Immediate from Word 2466 | * 2467 | * Subtracts an immediate value (0-63) from a register pair and places the result in the register pair. 2468 | * This instruction operates on the upper four register pairs, 2469 | * and is well suited for operations on the Pointer Registers. 2470 | * This instruction is not available in all devices. 2471 | * Refer to the device specific instruction set summary. 2472 | * 2473 | * @param _Rd Rd e {24,26,28,30} 2474 | * @param K 0 <= K <= 63 2475 | */ 2476 | sbiw: function(_Rd, K) { 2477 | 2478 | /* @TODO */ 2479 | 2480 | }, 2481 | /** 2482 | * SBR - Set Bits in Register 2483 | * 2484 | * Sets specified bits in register Rd. 2485 | * Performs the logical ORI between the contents of register Rd and a constant mask K 2486 | * and places the result in the destination register Rd. 2487 | * 2488 | * @param {type} _Rd 2489 | * @param {type} K 2490 | */ 2491 | sbr: function(_Rd, K) { 2492 | 2493 | var Rd = this.dataspace[_Rd]; 2494 | var SREG = this.dataspace[this.ssreg]; 2495 | 2496 | /* Operation: Rd <- Rd v K */ 2497 | Rd[0] = Rd[0] || K[0]; 2498 | Rd[1] = Rd[1] || K[1]; 2499 | Rd[2] = Rd[2] || K[2]; 2500 | Rd[3] = Rd[3] || K[3]; 2501 | Rd[4] = Rd[4] || K[4]; 2502 | Rd[5] = Rd[5] || K[5]; 2503 | Rd[6] = Rd[6] || K[6]; 2504 | Rd[7] = Rd[7] || K[7]; 2505 | 2506 | /* Z: Set if the result is $00; cleared othervise. */ 2507 | SREG[1] = !Rd[7] && !Rd[6] && !Rd[5] && !Rd[4] && !Rd[3] && !Rd[2] && !Rd[1] && !Rd[0]; 2508 | /* N: Set if MSB of the result is set; cleared othervise. */ 2509 | SREG[2] = Rd[7]; 2510 | /* V: Cleared */ 2511 | SREG[3] = false; 2512 | /* S: N ^ V, For signed tests. */ 2513 | SREG[4] = !!(this.dataspace[2] ^ this.dataspace[3]); 2514 | 2515 | /* Program Counter: PC <- PC + 1 */ 2516 | this.PC++; 2517 | 2518 | this.dataspace[_Rd] = Rd; 2519 | this.dataspace[this.sreg] = SREG; 2520 | }, 2521 | /** 2522 | * SBRC – Skip if Bit in Register is Cleared 2523 | * 2524 | * This instruction tests a single bit in a register and skips the next instruction if the bit is cleared. 2525 | * 2526 | * @param _Rr 2527 | * @param b 2528 | */ 2529 | sbrc: function(_Rr, b) { 2530 | 2531 | /* Operation: If Rr(b) = 0 then PC <- PC + 2 (or 3) else PC <- PC + 1 */ 2532 | if (this.dataspace[_Rr][b] === false) { 2533 | /* Program Counter: PC <- PC + 2, Skip a one word instruction */ 2534 | this.PC += 2; 2535 | } else { 2536 | /* Program Counter: PC <- PC + 1, Condition false - no skip */ 2537 | this.PC++; 2538 | } 2539 | }, 2540 | /** 2541 | * SBRS – Skip if Bit in Register is Set 2542 | * 2543 | * This instruction tests a single bit in a register and skips the next instruction if the bit is set. 2544 | * 2545 | * @param _Rr 2546 | * @param b 2547 | */ 2548 | sbrs: function(_Rr, b) { 2549 | 2550 | /* Operation: If Rr(b) = 1 then PC <- PC + 2 (or 3) else PC <- PC + 1 */ 2551 | if (this.dataspace[_Rr][b] === true) { 2552 | /* Program Counter: PC <- PC + 2, Skip a one word instruction */ 2553 | this.PC += 2; 2554 | } else { 2555 | /* Program Counter: PC <- PC + 1, Condition false - no skip */ 2556 | this.PC++; 2557 | } 2558 | }, 2559 | /** 2560 | * SEC – Set Carry Flag 2561 | * 2562 | * Sets the Carry Flag (C) in SREG (Status Register). 2563 | */ 2564 | sec: function() { 2565 | 2566 | /* Operation: C <- 1 */ 2567 | this.dataspace[this.sreg][0] = true; 2568 | 2569 | /* Program counter: PC <- PC + 1 */ 2570 | this.PC++; 2571 | }, 2572 | /** 2573 | * SEH – Set Half Carry Flag 2574 | * 2575 | * Sets the Half Carry (H) in SREG (Status Register). 2576 | */ 2577 | seh: function() { 2578 | 2579 | /* Operation: H <- 1 */ 2580 | this.dataspace[this.sreg][5] = true; 2581 | 2582 | /* Program counter: PC <- PC + 1 */ 2583 | this.PC++; 2584 | }, 2585 | /** 2586 | * SEI – Set Global Interrupt Flag 2587 | * 2588 | * Sets the Global Interrupt Flag (I) in SREG (Status Register). 2589 | * The instruction following SEI will be executed before any pending interrupts. 2590 | */ 2591 | sei: function() { 2592 | 2593 | /* Operation: I <- 1 */ 2594 | this.dataspace[this.sreg][7] = true; 2595 | 2596 | /* Program counter: PC <- PC + 1 */ 2597 | this.PC++; 2598 | }, 2599 | /** 2600 | * SEN – Set Negative Flag 2601 | * 2602 | * Sets the Negative Flag (N) in SREG (Status Register). 2603 | */ 2604 | sen: function() { 2605 | 2606 | /* Operation: N <- 1 */ 2607 | this.dataspace[this.sreg][2] = true; 2608 | 2609 | /* Program counter: PC <- PC + 1 */ 2610 | this.PC++; 2611 | }, 2612 | /** 2613 | * SER – Set all Bits in Register 2614 | * 2615 | * Loads $FF directly to register Rd. 2616 | * 2617 | * @param _Rd 2618 | */ 2619 | ser: function(_Rd) { 2620 | 2621 | var Rd = this.dataspace[_Rd]; 2622 | 2623 | /* Operation: Rd <- $FF */ 2624 | Rd[0] = true; 2625 | Rd[1] = true; 2626 | Rd[2] = true; 2627 | Rd[3] = true; 2628 | Rd[4] = true; 2629 | Rd[5] = true; 2630 | Rd[6] = true; 2631 | Rd[7] = true; 2632 | 2633 | /* Program counter: PC <- PC + 1 */ 2634 | this.PC++; 2635 | 2636 | this.dataspace[_Rd] = Rd; 2637 | }, 2638 | /** 2639 | * SES – Set Signed Flag 2640 | * 2641 | * Sets the Signed Flag (S) in SREG (Status Register). 2642 | */ 2643 | ses: function() { 2644 | 2645 | /* Operation: S <- 1 */ 2646 | SREG[4] = true; 2647 | 2648 | /* Program counter: PC <- PC + 1 */ 2649 | this.PC++; 2650 | }, 2651 | /** 2652 | * SET – Set T Flag 2653 | * 2654 | * Sets the T Flag in SREG (Status Register) 2655 | */ 2656 | set: function() { 2657 | 2658 | /* Operation: T <- 1 */ 2659 | SREG[6] = true; 2660 | 2661 | /* Program counter: PC <- PC + 1 */ 2662 | this.PC++; 2663 | }, 2664 | /** 2665 | * SEV – Set Overflow Flag 2666 | * 2667 | * Sets the Overflow Flag (V) in SREG (Status Register). 2668 | */ 2669 | sev: function() { 2670 | 2671 | /* Operation: V <- 1 */ 2672 | SREG[3] = true; 2673 | 2674 | /* Program counter: PC <- PC + 1 */ 2675 | this.PC++; 2676 | }, 2677 | /** 2678 | * SEZ – Set Zero Flag 2679 | * 2680 | * Sets the Zero Flag (Z) in SREG (Status Register). 2681 | */ 2682 | sez: function() { 2683 | 2684 | /* Operation: Z <- 1 */ 2685 | SREG[1] = true; 2686 | 2687 | /* Program counter: PC <- PC + 1 */ 2688 | this.PC++; 2689 | }, 2690 | /** 2691 | * SLEEP 2692 | * 2693 | * This instruction sets the circuit in sleep mode defined by the MCU Control Register 2694 | */ 2695 | sleep: function() { 2696 | 2697 | /* @TODO */ 2698 | 2699 | /* Program Counter: PC <- PC + 1 */ 2700 | this.PC++; 2701 | }, 2702 | /** 2703 | * SPM – Store Program Memory 2704 | * 2705 | */ 2706 | spm: function() { 2707 | /* @TODO */ 2708 | 2709 | /* Program Counter: PC <- PC + 1 */ 2710 | this.PC++; 2711 | }, 2712 | /** 2713 | * ST (STD) – Store Indirect From Register to Data Space using Index Z 2714 | * 2715 | */ 2716 | st: function() { 2717 | /* @TODO */ 2718 | 2719 | /* Program Counter: PC <- PC + 1 */ 2720 | this.PC++; 2721 | }, 2722 | /** 2723 | * STS – Store Direct to Data Space 2724 | * 2725 | * Stores one byte from a Register to the data space. 2726 | * For parts with SRAM, the data space consists of the Register File, I/O memory and internal SRAM 2727 | * (and external SRAM if applicable). 2728 | * For parts without SRAM, the data space consists of the Register File only. 2729 | * The EEPROM has a separate address space. 2730 | * 2731 | * A 16-bit address must be supplied. 2732 | * Memory access is limited to the current data segment of 64K bytes. 2733 | * The STS instruction uses the RAMPD Register to access memory above 64K bytes. 2734 | * To access another data segment in devices with more than 64K bytes data space, 2735 | * the RAMPD in register in the I/O area has to be changed. 2736 | * 2737 | * This instruction is not available in all devices. Refer to the device specific instruction set summary 2738 | * 2739 | * @param k 0 <= k <= 65535 2740 | * @param _Rr 16 <= r <= 31 2741 | */ 2742 | sts: function(k, _Rr) { 2743 | 2744 | this.memory[k] = this.dataspace[_Rr]; 2745 | 2746 | /* @TODO */ 2747 | 2748 | /* Program Counter: PC <- PC + 2 */ 2749 | this.PC += 2; 2750 | }, 2751 | /** 2752 | * SUB – Subtract without Carry 2753 | * 2754 | * Subtracts two registers and places the result in the destination register Rd 2755 | * 2756 | * @param _Rd 2757 | * @param _Rr 2758 | */ 2759 | sub: function(_Rd, _Rr) { 2760 | 2761 | 2762 | var Rd = this.dataspace[_Rd]; 2763 | var Rr = this.dataspace[_Rr]; 2764 | var C = [false, false, false, false, false, false, false, false]; 2765 | var R = [false, false, false, false, false, false, false, false]; 2766 | var SREG = this.dataspace[this.sreg]; 2767 | 2768 | /* Operation Rd <- Rd + Rr */ 2769 | C[0] = false; 2770 | 2771 | R[0] = !!(Rd[0] ^ Rr[0]); 2772 | C[1] = !Rd[0] && Rr[0]; 2773 | 2774 | R[1] = !!(Rd[1] ^ Rr[1] ^ C[1]); 2775 | C[2] = C[1] && !!(Rd[1] ^ Rr[1]) || (!Rd[1] && Rr[1]); 2776 | 2777 | R[2] = !!(Rd[2] ^ Rr[2] ^ C[2]); 2778 | C[3] = C[2] && !!(Rd[2] ^ Rr[2]) || (!Rd[2] && Rr[2]); 2779 | 2780 | R[3] = !!(Rd[3] ^ Rr[3] ^ C[3]); 2781 | C[4] = C[3] && !!(Rd[3] ^ Rr[3]) || (!Rd[3] && Rr[3]); 2782 | 2783 | R[4] = !!(Rd[4] ^ Rr[4] ^ C[4]); 2784 | C[5] = C[4] && !!(Rd[4] ^ Rr[4]) || (!Rd[4] && Rr[4]); 2785 | 2786 | R[5] = !!(Rd[5] ^ Rr[5] ^ C[5]); 2787 | C[6] = C[5] && !!(Rd[5] ^ Rr[5]) || (!Rd[5] && Rr[5]); 2788 | 2789 | R[6] = !!(Rd[6] ^ Rr[6] ^ C[6]); 2790 | C[7] = C[6] && !!(Rd[6] ^ Rr[6]) || (!Rd[6] && Rr[6]); 2791 | 2792 | R[7] = !!(Rd[7] ^ Rr[7] ^ C[7]); 2793 | 2794 | /* C: */ 2795 | SREG[0] = C[7] && !!(Rd[7] ^ Rr[7]) || (!Rd[7] && Rr[7]); 2796 | /* @TODO */ 2797 | 2798 | /* Program Counter: PC <- PC + 1 */ 2799 | this.PC++; 2800 | 2801 | this.dataspace[_Rd] = R; 2802 | this.dataspace[this.sreg] = SREG; 2803 | }, 2804 | /** 2805 | * SUBI – Subtract Immediate 2806 | * 2807 | * Subtracts a register and a constant and places the result in the destination register Rd. 2808 | * This instruction is working on Register R16 to R31 2809 | * and is very well suited for operations on the X, Y and Z-pointers 2810 | * 2811 | * @param _Rd 2812 | * @param K 2813 | */ 2814 | subi: function(_Rd, K) { 2815 | 2816 | /* @TODO */ 2817 | 2818 | /* Program Counter: PC <- PC + 1 */ 2819 | this.PC++; 2820 | }, 2821 | /** 2822 | * SWAP – Swap Nibbles 2823 | * 2824 | * Swaps high and low nibbles in a register 2825 | * 2826 | * @param _Rd 2827 | */ 2828 | swap: function(_Rd) { 2829 | 2830 | var Rd = this.dataspace[_Rd]; 2831 | var R = [false, false, false, false, false, false, false, false]; 2832 | 2833 | /* Operation: R(7:4) <- Rd(3:0), R(3:0) <- Rd(7:4) */ 2834 | R[7] = Rd[3]; 2835 | R[6] = Rd[2]; 2836 | R[5] = Rd[1]; 2837 | R[4] = Rd[0]; 2838 | 2839 | R[3] = Rd[7]; 2840 | R[2] = Rd[6]; 2841 | R[1] = Rd[5]; 2842 | R[0] = Rd[4]; 2843 | 2844 | /* Program Counter: PC <- PC + 1 */ 2845 | this.PC++; 2846 | 2847 | this.dataspace[_Rd] = R; 2848 | }, 2849 | /** 2850 | * TST - Test for Zero or Minus 2851 | * 2852 | * Tests if a register is zero or negative. 2853 | * Performs a logical AND between a register and itself. 2854 | * The register will remain unchanged. 2855 | * 2856 | * @param _Rd 2857 | */ 2858 | tst: function(_Rd) { 2859 | 2860 | var Rd = this.dataspace[_Rd]; 2861 | var SREG = this.dataspace[this.sreg]; 2862 | 2863 | /* Operation: Rd <- Rd && Rd */ 2864 | Rd[0] = Rd[0] && Rd[0]; 2865 | Rd[1] = Rd[1] && Rd[1]; 2866 | Rd[2] = Rd[2] && Rd[2]; 2867 | Rd[3] = Rd[3] && Rd[3]; 2868 | Rd[4] = Rd[4] && Rd[4]; 2869 | Rd[5] = Rd[5] && Rd[5]; 2870 | Rd[6] = Rd[6] && Rd[6]; 2871 | Rd[7] = Rd[7] && Rd[7]; 2872 | 2873 | /* Z: Set if the result is $00; cleared otherwise. */ 2874 | SREG[1] = !Rd[0] && !Rd[1] && !Rd[2] && !Rd[3] && !Rd[4] && !Rd[5] && !Rd[6] && !Rd[7]; 2875 | /* N: Set if MSB of the result is set; cleared otherwis. */ 2876 | SREG[2] = Rd[7]; 2877 | /* V: Cleared */ 2878 | SREG[3] = false; 2879 | /* S: N ^ V, For signed tests. */ 2880 | SREG[4] = !!(SREG[2] ^ SREG[3]); 2881 | 2882 | /* Program Counter: PC <- PC + 1 */ 2883 | this.PC++; 2884 | 2885 | this.dataspace[_Rd] = Rd; 2886 | this.dataspace[this.sreg] = SREG; 2887 | }, 2888 | /** 2889 | * This instruction resets the Watchdog Timer. 2890 | * This instruction must be executed within a limited time given by the WD prescaler. 2891 | * See the Watchdog Timer hardware specification. 2892 | */ 2893 | wd: function() { 2894 | /* @TODO */ 2895 | 2896 | /* Operation: WD timer restart. */ 2897 | 2898 | /* Program Counter: PC <- PC + 1 */ 2899 | this.PC++; 2900 | } 2901 | }; 2902 | --------------------------------------------------------------------------------