e3d98a3e5f/vm/tiny/retro.c
| d0b60129b7d59d8ddce40480bea5e66d39c76d52 | e3d98a3e5f26a50eabeb6eaa559aa3f396ae02ce | ||
|---|---|---|---|
303 | opcode = vm->image[vm->ip]; | 303 | opcode = vm->image[vm->ip]; |
304 | 304 | ||
305 | switch(opcode) { | 305 | switch(opcode) { |
306 | /***************************************************/ | ||
307 | /* NOP Does Nothing. Used for padding */ | ||
308 | /* Opcode: 0 Stack: - Address: - */ | ||
309 | case VM_NOP: | 306 | case VM_NOP: |
310 | break; | 307 | break; |
311 | |||
312 | /***************************************************/ | ||
313 | /* LIT Push the value in the following cell to */ | ||
314 | /* the stack */ | ||
315 | /* Opcode: 1 n Stack: -n Address: - */ | ||
316 | case VM_LIT: | 308 | case VM_LIT: |
317 | vm->sp++; | 309 | vm->sp++; |
318 | vm->ip++; | 310 | vm->ip++; |
319 | TOS = vm->image[vm->ip]; | 311 | TOS = vm->image[vm->ip]; |
320 | break; | 312 | break; |
321 | |||
322 | /***************************************************/ | ||
323 | /* DUP Duplicate the value on the top of the */ | ||
324 | /* stack */ | ||
325 | /* Opcode: 2 Stack: n-nn Address: - */ | ||
326 | case VM_DUP: | 313 | case VM_DUP: |
327 | vm->sp++; | 314 | vm->sp++; |
328 | vm->data[vm->sp] = NOS; | 315 | vm->data[vm->sp] = NOS; |
329 | break; | 316 | break; |
330 | |||
331 | /***************************************************/ | ||
332 | /* DROP Drop the value on the top of the stack */ | ||
333 | /* Opcode: 3 Stack: n- Address: - */ | ||
334 | case VM_DROP: | 317 | case VM_DROP: |
335 | DROP | 318 | DROP |
336 | break; | 319 | break; |
337 | |||
338 | /***************************************************/ | ||
339 | /* SWAP Exchange the top two values on the stack */ | ||
340 | /* Opcode: 4 Stack: xy-yx Address: - */ | ||
341 | case VM_SWAP: | 320 | case VM_SWAP: |
342 | a = TOS; | 321 | a = TOS; |
343 | TOS = NOS; | 322 | TOS = NOS; |
344 | NOS = a; | 323 | NOS = a; |
345 | break; | 324 | break; |
346 | |||
347 | /***************************************************/ | ||
348 | /* PUSH Move the top value on the stack to the */ | ||
349 | /* address stack. Remove it from the data */ | ||
350 | /* stack. */ | ||
351 | /* Opcode: 5 Stack: n- Address: -n */ | ||
352 | case VM_PUSH: | 325 | case VM_PUSH: |
353 | vm->rsp++; | 326 | vm->rsp++; |
354 | TORS = TOS; | 327 | TORS = TOS; |
355 | DROP | 328 | DROP |
356 | break; | 329 | break; |
357 | |||
358 | /***************************************************/ | ||
359 | /* POP Move the top value from the address */ | ||
360 | /* stack to the data stack. Remove it from */ | ||
361 | /* the address stack. */ | ||
362 | /* Opcode: 6 Stack: -n Address: n- */ | ||
363 | case VM_POP: | 330 | case VM_POP: |
364 | vm->sp++; | 331 | vm->sp++; |
365 | TOS = TORS; | 332 | TOS = TORS; |
366 | vm->rsp--; | 333 | vm->rsp--; |
367 | break; | 334 | break; |
368 | |||
369 | /***************************************************/ | ||
370 | /* CALL Call a subroutine whose address is given */ | ||
371 | /* in the following cell. Push the address */ | ||
372 | /* following this instruction to the address*/ | ||
373 | /* stack. */ | ||
374 | /* Opcode: 7 a Stack: - Address: -a */ | ||
375 | case VM_CALL: | 335 | case VM_CALL: |
376 | vm->ip++; | 336 | vm->ip++; |
377 | vm->rsp++; | 337 | vm->rsp++; |
... | ... | ||
386 | vm->ip++; | 346 | vm->ip++; |
387 | } | 347 | } |
388 | break; | 348 | break; |
389 | |||
390 | /***************************************************/ | ||
391 | /* JUMP Unconditional jump to the address given */ | ||
392 | /* in the following cell. */ | ||
393 | /* Opcode: 8 a Stack: - Address: - */ | ||
394 | case VM_JUMP: | 349 | case VM_JUMP: |
395 | vm->ip++; | 350 | vm->ip++; |
396 | vm->ip = vm->image[vm->ip] - 1; | 351 | vm->ip = vm->image[vm->ip] - 1; |
... | ... | ||
403 | vm->ip++; | 358 | vm->ip++; |
404 | } | 359 | } |
405 | break; | 360 | break; |
406 | |||
407 | /***************************************************/ | ||
408 | /* ; Return from a subroutine. Control is */ | ||
409 | /* passed to the address on the top of the */ | ||
410 | /* address stack. */ | ||
411 | /* Opcode: 9 Stack: - Address: a- */ | ||
412 | case VM_RETURN: | 361 | case VM_RETURN: |
413 | vm->ip = TORS; | 362 | vm->ip = TORS; |
414 | vm->rsp--; | 363 | vm->rsp--; |
415 | break; | 364 | break; |
416 | |||
417 | /***************************************************/ | ||
418 | /* >JUMP Jump to the address in the following */ | ||
419 | /* cell if NOS > TOS. */ | ||
420 | /* Opcode: 10 a Stack: xy- Address: - */ | ||
421 | case VM_GT_JUMP: | 365 | case VM_GT_JUMP: |
422 | vm->ip++; | 366 | vm->ip++; |
423 | if(NOS > TOS) | 367 | if(NOS > TOS) |
424 | vm->ip = vm->image[vm->ip] - 1; | 368 | vm->ip = vm->image[vm->ip] - 1; |
425 | DROP DROP | 369 | DROP DROP |
426 | break; | 370 | break; |
427 | |||
428 | /***************************************************/ | ||
429 | /* <JUMP Jump to the address in the following */ | ||
430 | /* cell if NOS < TOS. */ | ||
431 | /* Opcode: 11 a Stack: xy- Address: - */ | ||
432 | case VM_LT_JUMP: | 371 | case VM_LT_JUMP: |
433 | vm->ip++; | 372 | vm->ip++; |
434 | if(NOS < TOS) | 373 | if(NOS < TOS) |
435 | vm->ip = vm->image[vm->ip] - 1; | 374 | vm->ip = vm->image[vm->ip] - 1; |
436 | DROP DROP | 375 | DROP DROP |
437 | break; | 376 | break; |
438 | |||
439 | /***************************************************/ | ||
440 | /* !JUMP Jump to the address in the following */ | ||
441 | /* cell if NOS <> TOS. */ | ||
442 | /* Opcode: 12 a Stack: xy- Address: - */ | ||
443 | case VM_NE_JUMP: | 377 | case VM_NE_JUMP: |
444 | vm->ip++; | 378 | vm->ip++; |
445 | if(TOS != NOS) | 379 | if(TOS != NOS) |
446 | vm->ip = vm->image[vm->ip] - 1; | 380 | vm->ip = vm->image[vm->ip] - 1; |
447 | DROP DROP | 381 | DROP DROP |
448 | break; | 382 | break; |
449 | |||
450 | /***************************************************/ | ||
451 | /* =JUMP Jump to the address in the following */ | ||
452 | /* cell if NOS = TOS. */ | ||
453 | /* Opcode: 13 a Stack: xy- Address: - */ | ||
454 | case VM_EQ_JUMP: | 383 | case VM_EQ_JUMP: |
455 | vm->ip++; | 384 | vm->ip++; |
456 | if(TOS == NOS) | 385 | if(TOS == NOS) |
457 | vm->ip = vm->image[vm->ip] - 1; | 386 | vm->ip = vm->image[vm->ip] - 1; |
458 | DROP DROP | 387 | DROP DROP |
459 | break; | 388 | break; |
460 | |||
461 | /***************************************************/ | ||
462 | /* @ Fetch a value from a memory location */ | ||
463 | /* Opcode: 14 Stack: a-n Address: - */ | ||
464 | case VM_FETCH: | 389 | case VM_FETCH: |
465 | TOS = vm->image[TOS]; | 390 | TOS = vm->image[TOS]; |
466 | break; | 391 | break; |
467 | |||
468 | /***************************************************/ | ||
469 | /* ! Store a value to a memory location */ | ||
470 | /* Opcode: 15 Stack: na- Address: - */ | ||
471 | case VM_STORE: | 392 | case VM_STORE: |
472 | vm->image[TOS] = NOS; | 393 | vm->image[TOS] = NOS; |
473 | DROP DROP | 394 | DROP DROP |
474 | break; | 395 | break; |
475 | |||
476 | /***************************************************/ | ||
477 | /* + Add TOS and NOS, leaving the result */ | ||
478 | /* Opcode: 16 Stack: xy-z Address: - */ | ||
479 | case VM_ADD: | 396 | case VM_ADD: |
480 | NOS += TOS; | 397 | NOS += TOS; |
481 | DROP | 398 | DROP |
482 | break; | 399 | break; |
483 | |||
484 | /***************************************************/ | ||
485 | /* - Subtract TOS from NOS, leaving the result*/ | ||
486 | /* Opcode: 17 Stack: xy-z Address: - */ | ||
487 | case VM_SUB: | 400 | case VM_SUB: |
488 | NOS -= TOS; | 401 | NOS -= TOS; |
489 | DROP | 402 | DROP |
490 | break; | 403 | break; |
491 | |||
492 | /***************************************************/ | ||
493 | /* * Multiply TOS by NOS, leaving the result */ | ||
494 | /* Opcode: 18 Stack: xy-z Address: - */ | ||
495 | case VM_MUL: | 404 | case VM_MUL: |
496 | NOS *= TOS; | 405 | NOS *= TOS; |
497 | DROP | 406 | DROP |
498 | break; | 407 | break; |
499 | |||
500 | /***************************************************/ | ||
501 | /* /MOD Divide NOS by TOS, leaving the quotient */ | ||
502 | /* and remainder. */ | ||
503 | /* Opcode: 19 Stack: xy-qr Address: - */ | ||
504 | case VM_DIVMOD: | 408 | case VM_DIVMOD: |
505 | a = TOS; | 409 | a = TOS; |
506 | b = NOS; | 410 | b = NOS; |
507 | TOS = b / a; | 411 | TOS = b / a; |
508 | NOS = b % a; | 412 | NOS = b % a; |
509 | break; | 413 | break; |
510 | |||
511 | /***************************************************/ | ||
512 | /* AND Perform a bitwise and operation on TOS */ | ||
513 | /* and NOS. */ | ||
514 | /* Opcode: 20 Stack: xy-z Address: - */ | ||
515 | case VM_AND: | 414 | case VM_AND: |
516 | a = TOS; | 415 | a = TOS; |
517 | b = NOS; | 416 | b = NOS; |
518 | DROP | 417 | DROP |
519 | TOS = a & b; | 418 | TOS = a & b; |
520 | break; | 419 | break; |
521 | |||
522 | /***************************************************/ | ||
523 | /* OR Perform a bitwise or operation on TOS */ | ||
524 | /* and NOS. */ | ||
525 | /* Opcode: 21 Stack: xy-z Address: - */ | ||
526 | case VM_OR: | 420 | case VM_OR: |
527 | a = TOS; | 421 | a = TOS; |
528 | b = NOS; | 422 | b = NOS; |
529 | DROP | 423 | DROP |
530 | TOS = a | b; | 424 | TOS = a | b; |
531 | break; | 425 | break; |
532 | |||
533 | /***************************************************/ | ||
534 | /* XOR Perform a bitwise xor operation on TOS */ | ||
535 | /* and NOS. */ | ||
536 | /* Opcode: 22 Stack: xy-z Address: - */ | ||
537 | case VM_XOR: | 426 | case VM_XOR: |
538 | a = TOS; | 427 | a = TOS; |
539 | b = NOS; | 428 | b = NOS; |
540 | DROP | 429 | DROP |
541 | TOS = a ^ b; | 430 | TOS = a ^ b; |
542 | break; | 431 | break; |
543 | |||
544 | /***************************************************/ | ||
545 | /* << Shift NOS left by TOS bits. */ | ||
546 | /* Opcode: 23 Stack: xy-z Address: - */ | ||
547 | case VM_SHL: | 432 | case VM_SHL: |
548 | a = TOS; | 433 | a = TOS; |
549 | b = NOS; | 434 | b = NOS; |
550 | DROP | 435 | DROP |
551 | TOS = b << a; | 436 | TOS = b << a; |
552 | break; | 437 | break; |
553 | |||
554 | /***************************************************/ | ||
555 | /* >> Shift NOS right by TOS bits. */ | ||
556 | /* Opcode: 24 Stack: xy-z Address: - */ | ||
557 | case VM_SHR: | 438 | case VM_SHR: |
558 | a = TOS; | 439 | a = TOS; |
559 | b = NOS; | 440 | b = NOS; |
560 | DROP | 441 | DROP |
561 | TOS = b >>= a; | 442 | TOS = b >>= a; |
562 | break; | 443 | break; |
563 | |||
564 | /***************************************************/ | ||
565 | /* 0; Return from a subroutine if TOS = 0. */ | ||
566 | /* If TOS = 0, DROP TOS. */ | ||
567 | /* If TOS <> 0, do nothing */ | ||
568 | /* Opcode: 25 Stack: n- Address: a- */ | ||
569 | /* Stack: n-n Address: - */ | ||
570 | case VM_ZERO_EXIT: | 444 | case VM_ZERO_EXIT: |
571 | if (TOS == 0) { | 445 | if (TOS == 0) { |
572 | DROP | 446 | DROP |
... | ... | ||
574 | vm->rsp--; | 448 | vm->rsp--; |
575 | } | 449 | } |
576 | break; | 450 | break; |
577 | |||
578 | /***************************************************/ | ||
579 | /* 1+ Increase TOS by 1 */ | ||
580 | /* Opcode: 26 Stack: x-y Address: - */ | ||
581 | case VM_INC: | 451 | case VM_INC: |
582 | TOS += 1; | 452 | TOS += 1; |
583 | break; | 453 | break; |
584 | |||
585 | /***************************************************/ | ||
586 | /* 1- Decrease TOS by 1 */ | ||
587 | /* Opcode: 27 Stack: x-y Address: - */ | ||
588 | case VM_DEC: | 454 | case VM_DEC: |
589 | TOS -= 1; | 455 | TOS -= 1; |
590 | break; | 456 | break; |
591 | |||
592 | /***************************************************/ | ||
593 | /* IN Read a value from an I/O port */ | ||
594 | /* Opcode: 28 Stack: p-n Address: - */ | ||
595 | case VM_IN: | 457 | case VM_IN: |
596 | a = TOS; | 458 | a = TOS; |
597 | TOS = vm->ports[a]; | 459 | TOS = vm->ports[a]; |
598 | vm->ports[a] = 0; | 460 | vm->ports[a] = 0; |
599 | break; | 461 | break; |
600 | |||
601 | /***************************************************/ | ||
602 | /* OUT Send a value to an I/O port */ | ||
603 | /* Opcode: 29 Stack: np- Address: - */ | ||
604 | case VM_OUT: | 462 | case VM_OUT: |
605 | vm->ports[0] = 0; | 463 | vm->ports[0] = 0; |
606 | vm->ports[TOS] = NOS; | 464 | vm->ports[TOS] = NOS; |
607 | DROP DROP | 465 | DROP DROP |
608 | break; | 466 | break; |
609 | |||
610 | /***************************************************/ | ||
611 | /* WAIT Wait for an I/O event to occur. */ | ||
612 | /* Opcode: 30 Stack: - Address: - */ | ||
613 | case VM_WAIT: | 467 | case VM_WAIT: |
614 | if (vm->ports[0] == 1) | 468 | if (vm->ports[0] == 1) |
615 | break; | 469 | break; |
... | ... | ||
713 | vm->ports[8] = 0; | 567 | vm->ports[8] = 0; |
714 | } | 568 | } |
715 | break; | 569 | break; |
716 | |||
717 | |||
718 | /***************************************************/ | ||
719 | /* IMPLICIT CALL */ | ||
720 | /* If we don't recognize the opcode, treat it as a */ | ||
721 | /* subroutine address and CALL it. */ | ||
722 | /* Opcode: * a Stack: - Address: -a */ | ||
723 | default: | 570 | default: |
724 | vm->rsp++; | 571 | vm->rsp++; |
725 | TORS = vm->ip; | 572 | TORS = vm->ip; |
... | ... | ||
769 | for (vm->ip = 0; vm->ip < IMAGE_SIZE; vm->ip++) | 616 | for (vm->ip = 0; vm->ip < IMAGE_SIZE; vm->ip++) |
770 | vm_process(vm); | 617 | vm_process(vm); |
771 | 618 | ||
772 | /* Once done, cleanup */ | ||
773 | dev_cleanup(); | 619 | dev_cleanup(); |
774 | return 0; | 620 | return 0; |
775 | } | 621 | } |
Download diff