annotate emu/iset.c @ 42:792da050d8c4 tip

more dox
author james <jb302@eecs.qmul.ac.uk>
date Tue, 22 Apr 2014 14:25:14 +0100
parents 2e35be400012
children
rev   line source
jb302@28 1 /* iset.c
jb302@28 2 * IR functions */
jb302@28 3 #include <stdlib.h>
jb302@28 4 #include "iset.h"
jb302@28 5 #include "mem.h"
jb302@28 6
jb302@28 7 /* useful macros */
jb302@28 8 #define NNN (IR & 0x07)
jb302@28 9 #define MMM ((IR & 0x38) >> 3)
jb302@28 10
jb302@28 11 /* 0x00 - NOP */
jb302@28 12 void
jb302@28 13 NOP(void) {
jb302@28 14 }
jb302@28 15
jb302@28 16 /* 0x08 - SET C
jb302@28 17 * 0x0A - SET BS
jb302@28 18 * 0x0C - SET IE */
jb302@28 19 void
jb302@28 20 SET(void) {
jb302@28 21 switch (IR) {
jb302@28 22
jb302@28 23 case 0x08:
jb302@29 24 set_flag(C, 0x01);
jb302@28 25 break;
jb302@28 26
jb302@28 27 case 0x0A:
jb302@29 28 set_flag(BS, 0x01);
jb302@28 29 break;
jb302@28 30
jb302@28 31 case 0x0C:
jb302@29 32 set_flag(IE, 0x01);
jb302@28 33 break;
jb302@28 34
jb302@28 35 default:
jb302@28 36 break;
jb302@28 37 }
jb302@28 38 }
jb302@28 39
jb302@28 40 /* 0x09 - CLR C
jb302@28 41 * 0x0B - CLR BS
jb302@28 42 * 0x0D - CLR IE */
jb302@28 43 void
jb302@28 44 CLR(void) {
jb302@28 45 switch (IR) {
jb302@28 46
jb302@28 47 case 0x09:
jb302@29 48 set_flag(C, 0x00);
jb302@28 49 break;
jb302@28 50
jb302@28 51 case 0x0B:
jb302@29 52 set_flag(BS, 0x00);
jb302@28 53 break;
jb302@28 54
jb302@28 55 case 0x0D:
jb302@29 56 set_flag(IE, 0x00);
jb302@28 57 break;
jb302@28 58
jb302@28 59 default:
jb302@28 60 break;
jb302@28 61 }
jb302@28 62 }
jb302@28 63
jb302@28 64 /* 0x0E - CPL C
jb302@28 65 * 0x0F - CPL A */
jb302@28 66 void
jb302@28 67 CPL(void) {
jb302@28 68 switch (IR) {
jb302@28 69
jb302@28 70 case 0x0E:
jb302@29 71 if (get_flag(C) == 0) {
jb302@29 72 set_flag(C, 0x01);
jb302@28 73 }
jb302@28 74 else {
jb302@29 75 set_flag(C, 0x00);
jb302@28 76 }
jb302@28 77
jb302@28 78 case 0x0F:
jb302@28 79 A = ~A;
jb302@28 80 break;
jb302@28 81
jb302@28 82 default:
jb302@28 83 break;
jb302@28 84 }
jb302@28 85 }
jb302@28 86
jb302@28 87 /* 0x10 - XCSD */
jb302@28 88 void
jb302@28 89 XCSD(void) {
jb302@28 90 tmpw = get_wide(SP);
jb302@28 91 set_wide(SP, get_wide(DPTR));
jb302@28 92 set_wide(DPTR, tmpw);
jb302@28 93 }
jb302@28 94
jb302@28 95 /* 0x11 - SFA */
jb302@28 96 void
jb302@28 97 SFA(void) {
jb302@28 98 A = flags;
jb302@28 99 }
jb302@28 100
jb302@28 101 /* 0x12 - LAF */
jb302@28 102 void
jb302@28 103 LAF(void) {
jb302@28 104 flags = A;
jb302@28 105 }
jb302@28 106
jb302@28 107 /* 0b00010XXX - special MOVs
jb302@28 108 * 0b00011XXX - direct, indirect and indexed MOVs
jb302@28 109 * 0b00100nnn - register-indirect MOVs - MOV @DPTR, Rn
jb302@28 110 * 0b00101nnn - immediate movs - MOV Rn, #data8
jb302@28 111 * 0b00110nnn - MOV Rn, A
jb302@28 112 * 0b00111nnn - MOV A, Rn
jb302@28 113 * 0b01mmmnnn - 64 register move instructions
jb302@28 114 *
jb302@28 115 * this is a mess */
jb302@28 116 void
jb302@28 117 MOV(void) {
jb302@28 118 switch (IR & 0x40) {
jb302@28 119
jb302@28 120 case 0x00:
jb302@28 121 switch (IR & 0xF8) {
jb302@28 122
jb302@29 123 /* 0b00010XXX - special MOVs*/
jb302@28 124 case 0x10:
jb302@28 125 switch (NNN) {
jb302@28 126
jb302@28 127 /* MOV DPTR, SP */
jb302@28 128 case 3:
jb302@28 129 set_wide(DPTR, get_wide(SP));
jb302@28 130 break;
jb302@28 131
jb302@28 132 /* MOV SP, DPTR */
jb302@28 133 case 4:
jb302@28 134 set_wide(SP, get_wide(DPTR));
jb302@28 135 break;
jb302@28 136
jb302@28 137 /* MOV A, #data8 */
jb302@28 138 case 5:
jb302@28 139 A = fetch();
jb302@28 140 break;
jb302@28 141
jb302@28 142 /* MOV SP, #data16 */
jb302@28 143 case 6:
jb302@28 144 set_wide(SP, fetch_wide());
jb302@28 145 break;
jb302@28 146
jb302@28 147 /* MOV DPTR, #data16 */
jb302@28 148 case 7:
jb302@28 149 set_wide(DPTR, fetch_wide());
jb302@28 150 break;
jb302@28 151
jb302@28 152 default:
jb302@28 153 break;
jb302@28 154 }
jb302@28 155 break;
jb302@28 156
jb302@29 157 /* 0b00011XXX - direct, indirect and indexed MOVs*/
jb302@28 158 case 0x18:
jb302@28 159 switch (NNN) {
jb302@28 160
jb302@28 161 /* MOV A, addr16 */
jb302@28 162 case 0:
jb302@28 163 set_wide(TMP, fetch_wide());
jb302@28 164 A = mem[get_wide(TMP)];
jb302@28 165 break;
jb302@28 166
jb302@28 167 /* MOV addr16, A */
jb302@28 168 case 1:
jb302@28 169 set_wide(TMP, fetch_wide());
jb302@28 170 mem[get_wide(TMP)] = A;
jb302@28 171 break;
jb302@28 172
jb302@28 173 /* MOV A, @A+DPTR */
jb302@28 174 case 2:
jb302@29 175 set_wide(TMP, A + get_wide(DPTR));
jb302@29 176 A = mem[get_wide(TMP)];
jb302@28 177 break;
jb302@28 178
jb302@28 179 /* MOV A, @A+PC */
jb302@28 180 case 3:
jb302@29 181 set_wide(TMP, A + get_wide(PC));
jb302@29 182 A = mem[TMP];
jb302@28 183 break;
jb302@28 184
jb302@28 185 /* MOV A, @addr16 */
jb302@28 186 case 4:
jb302@28 187 set_wide(TMP, fetch_wide());
jb302@28 188 A = mem[mem[get_wide(TMP)]];
jb302@28 189 break;
jb302@28 190
jb302@28 191 /* MOV @addr16, A */
jb302@28 192 case 5:
jb302@28 193 set_wide(TMP, fetch_wide());
jb302@28 194 mem[mem[get_wide(TMP)]] = A;
jb302@28 195 break;
jb302@28 196
jb302@28 197 /* MOV A, @DPTR */
jb302@28 198 case 6:
jb302@29 199 set_wide(TMP, get_wide(DPTR));
jb302@29 200 A = mem[get_wide(TMP)];
jb302@28 201 break;
jb302@28 202
jb302@28 203 /* MOV @DPTR, A */
jb302@28 204 case 7:
jb302@29 205 set_wide(TMP, get_wide(DPTR));
jb302@29 206 mem[get_wide(TMP)] = A;
jb302@28 207 break;
jb302@28 208
jb302@28 209 default:
jb302@28 210 break;
jb302@28 211 }
jb302@28 212 break;
jb302@28 213
jb302@29 214 /* 0b00100nnn - MOV @DPTR, Rn*/
jb302@28 215 case 0x20:
jb302@29 216 set_wide(TMP, get_wide(DPTR));
jb302@30 217 mem[get_wide(TMP)] = get_reg(NNN);
jb302@28 218 break;
jb302@28 219
jb302@29 220 /* 0b00101nnn - immediate movs - MOV Rn, #data8*/
jb302@28 221 case 0x28:
jb302@29 222 set_reg(NNN, fetch());
jb302@28 223 break;
jb302@28 224
jb302@29 225 /* 0b00110nnn - MOV Rn, A */
jb302@28 226 case 0x30:
jb302@29 227 set_reg(NNN, A);
jb302@28 228 break;
jb302@28 229
jb302@30 230 /* 0b00111nnn MOV A, Rn */
jb302@28 231 case 0x38:
jb302@29 232 A = get_reg(NNN);
jb302@28 233 break;
jb302@28 234
jb302@28 235 default:
jb302@28 236 break;
jb302@28 237 }
jb302@29 238 break;;
jb302@28 239
jb302@30 240 /* 0b01mmmnnn MOV Rm Rn
jb302@30 241 * if m == n: MOV Rm, @DPTR */
jb302@28 242 case 0x40:
jb302@29 243 if (NNN == MMM) {
jb302@29 244 set_wide(TMP, get_wide(DPTR));
jb302@29 245 set_reg(NNN, mem[get_wide(TMP)]);
jb302@29 246 }
jb302@29 247 else {
jb302@29 248 set_reg(MMM, get_reg(NNN));
jb302@29 249 }
jb302@28 250 break;
jb302@28 251
jb302@28 252 default:
jb302@28 253 break;
jb302@28 254 }
jb302@28 255 }
jb302@28 256
jb302@30 257
jb302@30 258 /* 0x80 - ANL A, R0
jb302@30 259 * 0x81 - ANL A, R1
jb302@30 260 * 0x82 - ANL A, R2
jb302@30 261 * 0x83 - ANL A, R3
jb302@30 262 * 0x84 - ANL A, DPH
jb302@30 263 * 0x85 - ANL A, DPL
jb302@30 264 * 0x86 - ANL A, #data8
jb302@30 265 * 0x87 - ANL A, @DPTR */
jb302@28 266 void
jb302@28 267 ANL(void) {
jb302@30 268 if (NNN < 6) {
jb302@30 269 A = A & get_reg(NNN);
jb302@30 270 }
jb302@30 271 else {
jb302@30 272 switch (NNN) {
jb302@30 273
jb302@30 274 case 6:
jb302@30 275 A = A & fetch();
jb302@30 276 break;
jb302@30 277
jb302@30 278 case 7:
jb302@30 279 set_wide(TMP, get_wide(DPTR));
jb302@30 280 A = A & mem[TMP];
jb302@30 281 break;
jb302@30 282 }
jb302@30 283 }
jb302@30 284 set_zp(A);
jb302@28 285 }
jb302@28 286
jb302@30 287 /* 0x88 - ORL A, R0
jb302@30 288 * 0x89 - ORL A, R1
jb302@30 289 * 0x8A - ORL A, R2
jb302@30 290 * 0x8B - ORL A, R3
jb302@30 291 * 0x8C - ORL A, DPH
jb302@30 292 * 0x8D - ORL A, DPL
jb302@30 293 * 0x8E - ORL A, #data8
jb302@30 294 * 0x8F - ORL A, @DPTR */
jb302@28 295 void
jb302@28 296 ORL(void) {
jb302@30 297 if (NNN < 6) {
jb302@30 298 A = A | get_reg(NNN);
jb302@30 299 }
jb302@30 300 else {
jb302@30 301 switch (NNN) {
jb302@30 302
jb302@30 303 case 6:
jb302@30 304 A = A | fetch();
jb302@30 305 break;
jb302@30 306
jb302@30 307 case 7:
jb302@30 308 set_wide(TMP, get_wide(DPTR));
jb302@30 309 A = A | mem[TMP];
jb302@30 310 break;
jb302@30 311 }
jb302@30 312 }
jb302@30 313 set_zp(A);
jb302@28 314 }
jb302@28 315
jb302@30 316 /* 0x90 - XRL A, R0
jb302@30 317 * 0x91 - XRL A, R1
jb302@30 318 * 0x92 - XRL A, R2
jb302@30 319 * 0x93 - XRL A, R3
jb302@30 320 * 0x94 - XRL A, DPH
jb302@30 321 * 0x95 - XRL A, DPL
jb302@30 322 * 0x96 - XRL A, #data8
jb302@30 323 * 0x97 - XRL A, @DPTR */
jb302@28 324 void
jb302@28 325 XRL(void) {
jb302@30 326 if (NNN < 6) {
jb302@30 327 A = A ^ get_reg(NNN);
jb302@30 328 }
jb302@30 329 else {
jb302@30 330 switch (NNN) {
jb302@30 331
jb302@30 332 case 6:
jb302@30 333 A = A ^ fetch();
jb302@30 334 break;
jb302@28 335
jb302@30 336 case 7:
jb302@30 337 set_wide(TMP, get_wide(DPTR));
jb302@30 338 A = A ^ mem[TMP];
jb302@30 339 break;
jb302@30 340 }
jb302@30 341 }
jb302@30 342 set_zp(A);
jb302@28 343 }
jb302@28 344
jb302@28 345 /* 0x98 - RL A */
jb302@28 346 void
jb302@28 347 RL(void) {
jb302@28 348 A = (A << 1) | (A >> 7);
jb302@28 349 }
jb302@28 350
jb302@28 351 /* 0x99 - RLC A */
jb302@28 352 void
jb302@28 353 RLC(void) {
jb302@30 354 tmpb = A;
jb302@30 355 A = (A << 1) | get_flag(C);
jb302@30 356 set_flag(C, tmpb >> 7);
jb302@28 357 }
jb302@28 358
jb302@28 359 /* 0x9A - RR A */
jb302@28 360 void
jb302@28 361 RR(void) {
jb302@28 362 A = (A >> 1) | (A << 7);
jb302@28 363 }
jb302@28 364
jb302@28 365 /* 0x9B - RRC A */
jb302@28 366 void
jb302@28 367 RRC(void) {
jb302@30 368 tmpb = A;
jb302@30 369 A = (A >> 1) | (get_flag(C) << 7);
jb302@30 370 set_flag(C, tmpb & 0x01);
jb302@28 371 }
jb302@28 372
jb302@28 373 /* 0x9C - INC DPTR
jb302@28 374 * 0x9E - INC A */
jb302@28 375 void
jb302@30 376 INC(void) {
jb302@30 377 switch (IR) {
jb302@30 378
jb302@30 379 case 0x9C:
jb302@30 380 tmpw = get_wide(DPTR);
jb302@30 381 if ((tmpw + 1) > 0xFFFF) {
jb302@30 382 set_flag(OV, 1);
jb302@30 383 }
jb302@30 384 set_wide(DPTR, tmpw + 1);
jb302@30 385 set_zp(DPL);
jb302@30 386 set_zp(DPH);
jb302@30 387 break;
jb302@30 388
jb302@30 389 case 0x9E:
jb302@30 390 if ((A + 1) > 0xFF) {
jb302@30 391 set_flag(OV, 1);
jb302@30 392 }
jb302@30 393 A++;
jb302@30 394 set_zp(A);
jb302@30 395
jb302@30 396 }
jb302@28 397 }
jb302@28 398
jb302@28 399 /* 0x9D - DEC DPTR
jb302@28 400 * 0x9F - DEC A */
jb302@28 401 void
jb302@28 402 DEC(void) {
jb302@30 403 switch (IR) {
jb302@30 404
jb302@30 405 case 0x9D:
jb302@30 406 tmpw = get_wide(DPTR);
jb302@30 407 if ((tmpw - 1) < 0) {
jb302@30 408 set_flag(OV, 1);
jb302@30 409 }
jb302@30 410 set_wide(DPTR, tmpw - 1);
jb302@30 411 set_zp(DPL);
jb302@30 412 set_zp(DPH);
jb302@30 413
jb302@30 414 case 0x9F:
jb302@30 415 if ((A - 1) < 0) {
jb302@30 416 set_flag(OV, 1);
jb302@30 417 }
jb302@30 418 A--;
jb302@30 419 set_zp(A);
jb302@30 420 }
jb302@28 421 }
jb302@28 422
jb302@30 423 /* 0xA0 - ADD A, R0
jb302@30 424 * 0xA1 - ADD A, R1
jb302@30 425 * 0xA2 - ADD A, R2
jb302@30 426 * 0xA3 - ADD A, R3
jb302@30 427 * 0xA4 - ADD A, DPH
jb302@30 428 * 0xA5 - ADD A, DPL
jb302@30 429 * 0xA6 - ADD A, #data8
jb302@30 430 * 0xA7 - ADD A, @DPTR */
jb302@28 431 void
jb302@28 432 ADD(void) {
jb302@30 433 if (NNN < 6) {
jb302@31 434 if ((A + get_reg(NNN)) > 0xFF) {
jb302@31 435 set_flag(OV, 1);
jb302@31 436 }
jb302@31 437 else {
jb302@31 438 set_flag(OV, 0);
jb302@30 439 }
jb302@30 440 A = A + get_reg(NNN);
jb302@30 441 set_zp(A);
jb302@30 442 }
jb302@30 443 else {
jb302@30 444 switch (NNN) {
jb302@30 445
jb302@30 446 case 6:
jb302@31 447 tmpb = fetch();
jb302@31 448 if ((A + tmpb) > 0xFF) {
jb302@31 449 set_flag(OV, 1);
jb302@31 450 }
jb302@31 451 else {
jb302@31 452 set_flag(OV, 0);
jb302@31 453 }
jb302@31 454 A = A + tmpb;
jb302@30 455 set_zp(A);
jb302@30 456 break;
jb302@30 457
jb302@30 458 case 7:
jb302@30 459 set_wide(TMP, get_wide(DPTR));
jb302@31 460 if ((A + mem[TMP]) > 0xFF) {
jb302@31 461 set_flag(OV, 1);
jb302@31 462 }
jb302@31 463 else {
jb302@31 464 set_flag(OV, 0);
jb302@31 465 }
jb302@30 466 A = A + mem[TMP];
jb302@30 467 set_zp(A);
jb302@30 468 break;
jb302@30 469 }
jb302@30 470 }
jb302@30 471
jb302@28 472 }
jb302@28 473
jb302@35 474 /* 0xA8 - ADDC A, R0
jb302@35 475 * 0xA9 - ADDC A, R1
jb302@35 476 * 0xAA - ADDC A, R2
jb302@35 477 * 0xAB - ADDC A, R3
jb302@35 478 * 0xAC - ADDC A, DPH
jb302@35 479 * 0xAD - ADDC A, DPL
jb302@35 480 * 0xAE - ADDC A, #data8
jb302@35 481 * 0xAF - ADDC A, @DPTR */
jb302@28 482 void
jb302@28 483 ADDC(void) {
jb302@35 484 if (NNN < 6) {
jb302@35 485 if ((A + get_reg(NNN) + get_flag(C)) > 0xFF) {
jb302@35 486 set_flag(C, 1);
jb302@35 487 }
jb302@35 488 else {
jb302@35 489 set_flag(C, 0);
jb302@35 490 }
jb302@35 491 A = A + get_reg(NNN) + get_flag(C);
jb302@35 492 set_zp(A);
jb302@35 493 }
jb302@35 494 else {
jb302@35 495 switch (NNN) {
jb302@35 496
jb302@35 497 case 6:
jb302@35 498 tmpb = fetch();
jb302@35 499 if ((A + tmpb + get_flag(C)) > 0xFF) {
jb302@35 500 set_flag(C, 1);
jb302@35 501 }
jb302@35 502 else {
jb302@35 503 set_flag(C, 0);
jb302@35 504 }
jb302@35 505 A = A + tmpb + get_flag(C);
jb302@35 506 set_zp(A);
jb302@35 507 break;
jb302@35 508
jb302@35 509 case 7:
jb302@35 510 set_wide(TMP, get_wide(DPTR));
jb302@35 511 if ((A + mem[TMP] + get_flag(C)) > 0xFF) {
jb302@35 512 set_flag(C, 1);
jb302@35 513 }
jb302@35 514 else {
jb302@35 515 set_flag(C, 0);
jb302@35 516 }
jb302@35 517 A = A + mem[TMP] + get_flag(C);
jb302@35 518 set_zp(A);
jb302@35 519 break;
jb302@35 520 }
jb302@35 521 }
jb302@35 522
jb302@35 523
jb302@28 524 }
jb302@28 525
jb302@30 526 /* 0xB0 - SUB A, R0
jb302@30 527 * 0xB1 - SUB A, R1
jb302@30 528 * 0xB2 - SUB A, R2
jb302@30 529 * 0xB3 - SUB A, R3
jb302@35 530 * 0xB4 - SB A, DPH
jb302@30 531 * 0xB5 - SUB A, DPL
jb302@30 532 * 0xB6 - SUB A, #data8
jb302@30 533 * 0xB7 - SUB A, @DPTR */
jb302@28 534 void
jb302@28 535 SUB(void) {
jb302@30 536 if (NNN < 6) {
jb302@31 537 if ((A - get_reg(NNN)) < 0){
jb302@34 538 set_flag(S, 1);
jb302@31 539 }
jb302@31 540 else {
jb302@34 541 set_flag(S, 0);
jb302@31 542 }
jb302@30 543 A = A - get_reg(NNN);
jb302@30 544 set_zp(A);
jb302@30 545 }
jb302@30 546 else {
jb302@30 547 switch (NNN) {
jb302@30 548
jb302@30 549 case 6:
jb302@31 550 tmpb = fetch();
jb302@31 551 if ((A - tmpb) < 0) {
jb302@34 552 set_flag(S, 1);
jb302@31 553 }
jb302@31 554 else {
jb302@34 555 set_flag(S, 0);
jb302@31 556 }
jb302@31 557 A = A - tmpb;
jb302@30 558 set_zp(A);
jb302@30 559 break;
jb302@30 560
jb302@30 561 case 7:
jb302@30 562 set_wide(TMP, get_wide(DPTR));
jb302@31 563 if ((A - mem[TMP]) < 0) {
jb302@34 564 set_flag(S, 1);
jb302@31 565 }
jb302@31 566 else {
jb302@34 567 set_flag(S, 0);
jb302@31 568 }
jb302@30 569 A = A - mem[TMP];
jb302@30 570 set_zp(A);
jb302@30 571 break;
jb302@30 572 }
jb302@30 573 }
jb302@28 574 }
jb302@28 575
jb302@35 576 /* 0xB8 - SUBB A, R0
jb302@35 577 * 0xB9 - SUBB A, R1
jb302@35 578 * 0xBA - SUBB A, R2
jb302@35 579 * 0xBB - SUBB A, R3
jb302@35 580 * 0xBC - SUBB A, DPH
jb302@35 581 * 0xBD - SUBB A, DPL
jb302@35 582 * 0xBE - SUBB A, #data8
jb302@35 583 * 0xBF - SUBB A, @DPTR */
jb302@28 584 void
jb302@28 585 SUBB(void) {
jb302@35 586 if (NNN < 6) {
jb302@35 587 if ((A - get_reg(NNN) - get_flag(C)) < 0){
jb302@35 588 set_flag(C, 1);
jb302@35 589 }
jb302@35 590 else {
jb302@35 591 set_flag(C, 0);
jb302@35 592 }
jb302@35 593 A = A - get_reg(NNN) -get_flag(C);
jb302@35 594 set_zp(A);
jb302@35 595 }
jb302@35 596 else {
jb302@35 597 switch (NNN) {
jb302@35 598
jb302@35 599 case 6:
jb302@35 600 tmpb = fetch();
jb302@35 601 if ((A - tmpb - get_flag(C)) < 0) {
jb302@35 602 set_flag(C, 1);
jb302@35 603 }
jb302@35 604 else {
jb302@35 605 set_flag(C, 0);
jb302@35 606 }
jb302@35 607 A = A - tmpb - get_flag(C);
jb302@35 608 set_zp(A);
jb302@35 609 break;
jb302@35 610
jb302@35 611 case 7:
jb302@35 612 set_wide(TMP, get_wide(DPTR));
jb302@35 613 if ((A - mem[TMP] - get_flag(C)) < 0) {
jb302@35 614 set_flag(C, 1);
jb302@35 615 }
jb302@35 616 else {
jb302@35 617 set_flag(C, 0);
jb302@35 618 }
jb302@35 619 A = A - mem[TMP] - get_flag(C);
jb302@35 620 set_zp(A);
jb302@35 621 break;
jb302@35 622 }
jb302@35 623 }
jb302@28 624 }
jb302@28 625
jb302@28 626 void
jb302@28 627 PJMP(void) {
jb302@28 628 /* implement me */
jb302@28 629 }
jb302@28 630
jb302@28 631 void
jb302@28 632 PCALL(void) {
jb302@28 633 /* implement me */
jb302@28 634 }
jb302@28 635
jb302@28 636 /* 0xD0 - DJNZ R0, rel8
jb302@28 637 * 0xD1 - DJNZ R1, rel8
jb302@28 638 * 0xD2 - DJNZ R2, rel8
jb302@28 639 * 0xD3 - DJNZ R3, rel8 */
jb302@28 640 void
jb302@28 641 DJNZ(void) {
jb302@35 642 set_reg(NNN, get_reg(NNN) - 1);
jb302@35 643 if (get_reg(NNN) == 0) {
jb302@35 644 set_wide(PC, get_wide(PC) + (signed char)fetch() - 1);
jb302@35 645 }
jb302@35 646 else {
jb302@35 647 inc_pc(1);
jb302@35 648 }
jb302@28 649 }
jb302@28 650
jb302@35 651 /* 0xD4 - CJNE R0, #data, rel8
jb302@35 652 * 0xD5 - CJNE R1, #data, rel8
jb302@35 653 * 0xD6 - CJNE R2, #data, rel8
jb302@35 654 * 0xD7 - CJNE R3, #data, rel8
jb302@35 655 * 0xDF - CJNE A, #data8, rel8 */
jb302@28 656 void
jb302@28 657 CJNE(void) {
jb302@35 658 switch(IR) {
jb302@35 659
jb302@35 660 case 0xDF:
jb302@35 661 tmpb = fetch();
jb302@35 662 if (tmpb != A) {
jb302@35 663 set_wide(PC, get_wide(PC) + (signed char)fetch() - 1);
jb302@35 664 }
jb302@35 665 else {
jb302@35 666 inc_pc(1);
jb302@35 667 }
jb302@35 668 break;
jb302@35 669
jb302@35 670
jb302@35 671 default:
jb302@35 672 tmpb = fetch();
jb302@35 673 if (tmpb != get_reg(NNN - 4)) {
jb302@35 674 set_wide(PC, get_wide(PC) + (signed char)fetch() - 1);
jb302@35 675 }
jb302@35 676 else {
jb302@35 677 inc_pc(1);
jb302@35 678 }
jb302@35 679 break;
jb302@35 680 }
jb302@28 681 }
jb302@28 682
jb302@28 683 /* 0xD8 - LJMP addr16 */
jb302@28 684 void
jb302@28 685 LJMP(void) {
jb302@35 686 set_wide(PC, fetch_wide());
jb302@28 687 }
jb302@28 688
jb302@35 689 /* 0xD9 - LCALL addr16 */
jb302@28 690 void
jb302@28 691 LCALL(void) {
jb302@35 692 /* push PC to stack */
jb302@35 693 mem[get_wide(SP)] = get_reg(PCL);
jb302@35 694 set_wide(SP, get_wide(SP) + 1);
jb302@35 695 mem[get_wide(SP)] = get_reg(PCH);
jb302@35 696 set_wide(SP, get_wide(SP) + 1);
jb302@35 697 /* jmp */
jb302@35 698 set_wide(PC, fetch_wide());
jb302@28 699 }
jb302@28 700
jb302@35 701 /* 0xDA - RET */
jb302@28 702 void
jb302@28 703 RET(void) {
jb302@35 704 /* get PC from stack */
jb302@35 705 set_wide(SP, get_wide(SP) - 1);
jb302@35 706 tmpb = mem[get_wide(SP)]; /* PCH */
jb302@35 707 set_wide(SP, get_wide(SP) - 1);
jb302@35 708 set_wide(PC, MWIDE(tmpb, mem[get_wide(SP)]));
jb302@28 709 }
jb302@28 710
jb302@28 711 void
jb302@28 712 RETI(void) {
jb302@28 713 /* implement me */
jb302@28 714 }
jb302@28 715
jb302@28 716 /* 0xDC - SJMP rel8 */
jb302@28 717 void
jb302@28 718 SJMP(void) {
jb302@34 719 /* -1 because the fetch() increments the PC */
jb302@34 720 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
jb302@28 721 }
jb302@28 722
jb302@28 723 /* 0xDD - JMP @A+DPTR
jb302@28 724 * 0xDE - JMP @DPTR */
jb302@28 725 void
jb302@28 726 JMP(void) {
jb302@34 727 switch(IR) {
jb302@34 728
jb302@34 729 case 0xDD:
jb302@34 730 set_wide(PC, A + get_wide(DPTR));
jb302@34 731 break;
jb302@34 732
jb302@34 733 case 0xDE:
jb302@34 734 set_wide(PC, get_wide(DPTR));
jb302@34 735 break;
jb302@34 736 }
jb302@28 737 }
jb302@28 738
jb302@34 739 /* 0xE0 - JZ rel8 */
jb302@28 740 void
jb302@34 741 JZ(void) {
jb302@34 742 if (get_flag(Z) == 1) {
jb302@34 743 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
jb302@34 744 }
jb302@34 745 /* skip rel8 if jump not needed */
jb302@34 746 else {
jb302@34 747 inc_pc(1);
jb302@34 748 }
jb302@28 749 }
jb302@28 750
jb302@34 751 /* 0xE1 - JNZ rel8 */
jb302@28 752 void
jb302@28 753 JNZ(void) {
jb302@34 754 if (get_flag(Z) == 0) {
jb302@34 755 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
jb302@34 756 }
jb302@34 757 else {
jb302@34 758 inc_pc(1);
jb302@34 759 }
jb302@28 760 }
jb302@28 761
jb302@34 762 /* 0xE2 - JC rel8 */
jb302@28 763 void
jb302@34 764 JC(void) {
jb302@34 765 if (get_flag(C) == 1) {
jb302@34 766 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
jb302@34 767 }
jb302@34 768 else {
jb302@34 769 inc_pc(1);
jb302@34 770 }
jb302@28 771 }
jb302@28 772
jb302@34 773 /* 0xE3 - JNC rel8 */
jb302@28 774 void
jb302@34 775 JNC(void) {
jb302@34 776 if (get_flag(C) == 0) {
jb302@34 777 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
jb302@34 778 }
jb302@34 779 else {
jb302@34 780 inc_pc(1);
jb302@34 781 }
jb302@28 782 }
jb302@28 783
jb302@34 784 /* 0xE4 - JPO rel8 */
jb302@28 785 void
jb302@34 786 JPO(void) {
jb302@34 787 /* P = 1 when parity even */
jb302@34 788 if (get_flag(P) == 0) {
jb302@34 789 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
jb302@34 790 }
jb302@34 791 else {
jb302@34 792 inc_pc(1);
jb302@34 793 }
jb302@34 794
jb302@28 795 }
jb302@28 796
jb302@34 797 /* 0xE5 - JPE rel8 */
jb302@28 798 void
jb302@28 799 JPE(void) {
jb302@34 800 if (get_flag(P) == 1) {
jb302@34 801 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
jb302@34 802 }
jb302@34 803 else {
jb302@34 804 inc_pc(1);
jb302@34 805 }
jb302@28 806 }
jb302@28 807
jb302@34 808 /* 0xE6 - JS rel8 */
jb302@28 809 void
jb302@34 810 JS(void) {
jb302@34 811 if (get_flag(S) == 1) {
jb302@34 812 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
jb302@34 813 }
jb302@34 814 else {
jb302@34 815 inc_pc(1);
jb302@34 816 }
jb302@28 817 }
jb302@28 818
jb302@34 819 /* 0xE7 - JNS rel8 */
jb302@28 820 void
jb302@28 821 JNS(void) {
jb302@34 822 if (get_flag(S) == 0) {
jb302@34 823 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
jb302@34 824 }
jb302@34 825 else {
jb302@34 826 inc_pc(1);
jb302@34 827 }
jb302@28 828 }
jb302@28 829
jb302@35 830 /* 0xE8 - PUSH R0
jb302@35 831 * 0xE9 - PUSH R1
jb302@35 832 * 0xEA - PUSH R2
jb302@35 833 * 0xEB - PUSH R3
jb302@35 834 * 0xEC - PUSH DPH
jb302@35 835 * 0xED - PUSH DPL
jb302@35 836 * 0xEE - PUSH A
jb302@35 837 * 0xEF - PUSH FLAGS */
jb302@28 838 void
jb302@28 839 PUSH(void) {
jb302@35 840 if (NNN < 6) {
jb302@35 841 mem[get_wide(SP)] = get_reg(NNN);
jb302@35 842 set_wide(SP, get_wide(SP) + 1);
jb302@35 843
jb302@35 844 }
jb302@35 845 else {
jb302@35 846 switch(IR) {
jb302@35 847
jb302@35 848 case 0xEE:
jb302@35 849 mem[get_wide(SP)] = A;
jb302@35 850 set_wide(SP, get_wide(SP) + 1);
jb302@35 851 break;
jb302@35 852
jb302@35 853 case 0xEF:
jb302@35 854 mem[get_wide(SP)] = flags;
jb302@35 855 set_wide(SP, get_wide(SP) + 1);
jb302@35 856 break;
jb302@35 857
jb302@35 858 default:
jb302@35 859 break;
jb302@35 860 }
jb302@35 861 }
jb302@28 862 }
jb302@28 863
jb302@35 864 /* 0xF0 - POP R0
jb302@35 865 * 0xF1 - POP R1
jb302@35 866 * 0xF2 - POP R2
jb302@35 867 * 0xF3 - POP R3
jb302@35 868 * 0xF4 - POP DPH
jb302@35 869 * 0xF5 - POP DPL
jb302@35 870 * 0xF6 - POP A
jb302@35 871 * 0xF7 - POP FLAGS */
jb302@28 872 void
jb302@35 873 POP(void) {
jb302@35 874 if (NNN < 6) {
jb302@35 875 set_wide(SP, get_wide(SP) - 1);
jb302@35 876 set_reg(NNN, mem[get_wide(SP)]);
jb302@35 877 }
jb302@35 878 else {
jb302@35 879 switch(IR) {
jb302@35 880
jb302@35 881 case 0xF6:
jb302@35 882 set_wide(SP, get_wide(SP) - 1);
jb302@35 883 A = mem[get_wide(SP)];
jb302@35 884 break;
jb302@35 885
jb302@35 886 case 0xF7:
jb302@35 887 set_wide(SP, get_wide(SP) - 1);
jb302@35 888 flags = mem[get_wide(SP)];
jb302@35 889 break;
jb302@35 890
jb302@35 891 default:
jb302@35 892 break;
jb302@35 893 }
jb302@35 894 }
jb302@28 895 }
jb302@28 896
jb302@35 897
jb302@35 898 /* 0xF8 - MUL R0, R1 */
jb302@28 899 void
jb302@35 900 MUL(void) {
jb302@42 901 tmpw = regs[R0] * regs[R1];
jb302@42 902 regs[R0] = GHIGH(tmpw);
jb302@42 903 regs[R1] = GLOW(tmpw);
jb302@28 904 }
jb302@28 905
jb302@35 906 /* 0xF9 - DIV R0, R1 */
jb302@28 907 void
jb302@35 908 DIV(void) {
jb302@42 909 tmpw = regs[R0] / regs[R1];
jb302@42 910 regs[R0] = GHIGH(tmpw);
jb302@42 911 regs[R1] = GLOW(tmpw);
jb302@28 912 }
jb302@28 913
jb302@35 914 /* 0xFA - DA A */
jb302@28 915 void
jb302@35 916 DA(void) {
jb302@42 917 if (((A & 0xF) > 9) | get_flag(AC) == 1) {
jb302@42 918 A = A + 6;
jb302@42 919 }
jb302@42 920 if (((A & 0xF0) > 9) | get_flag(C) == 1) {
jb302@42 921 A = A + 0x60;
jb302@42 922 }
jb302@28 923 }
jb302@28 924
jb302@35 925 /* 0xFC - IN port_addr */
jb302@28 926 void
jb302@35 927 IN(void) {
jb302@35 928 /* implement me */
jb302@28 929 }
jb302@28 930
jb302@35 931 /* 0xFD - OUT port_addr */
jb302@28 932 void
jb302@28 933 OUT(void) {
jb302@35 934 /* implement me */
jb302@28 935 }
jb302@28 936
jb302@35 937 /* 0xFE INT vect8 */
jb302@28 938 void
jb302@35 939 INT(void) {
jb302@35 940 /* implement me */
jb302@28 941 }
jb302@28 942
jb302@28 943 /* 0xFF - HLT */
jb302@28 944 void
jb302@28 945 HLT(void) {
jb302@42 946 exit(0);
jb302@28 947 }