diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/chip8.c | 612 |
1 files changed, 306 insertions, 306 deletions
diff --git a/apps/plugins/chip8.c b/apps/plugins/chip8.c index f90030df32..4ae32f1502 100644 --- a/apps/plugins/chip8.c +++ b/apps/plugins/chip8.c | |||
@@ -75,7 +75,7 @@ EXTERN struct chip8_regs_struct chip8_regs; | |||
75 | #ifdef CHIP8_SUPER | 75 | #ifdef CHIP8_SUPER |
76 | #define CHIP8_WIDTH 128 | 76 | #define CHIP8_WIDTH 128 |
77 | #define CHIP8_HEIGHT 64 | 77 | #define CHIP8_HEIGHT 64 |
78 | EXTERN byte chip8_super; /* != 0 if in SCHIP display mode */ | 78 | EXTERN byte chip8_super; /* != 0 if in SCHIP display mode */ |
79 | #else | 79 | #else |
80 | #define CHIP8_WIDTH 64 | 80 | #define CHIP8_WIDTH 64 |
81 | #define CHIP8_HEIGHT 32 | 81 | #define CHIP8_HEIGHT 32 |
@@ -129,7 +129,7 @@ EXTERN void chip8_debug (word opcode,struct chip8_regs_struct *regs); | |||
129 | */ | 129 | */ |
130 | 130 | ||
131 | #ifndef STATIC | 131 | #ifndef STATIC |
132 | #include <stdlib.h> /* for memset, etc. */ | 132 | #include <stdlib.h> /* for memset, etc. */ |
133 | #include <string.h> | 133 | #include <string.h> |
134 | #define STATIC | 134 | #define STATIC |
135 | #endif | 135 | #endif |
@@ -148,7 +148,7 @@ STATIC byte chip8_keys[16]; /* if 1, key is held down */ | |||
148 | STATIC byte chip8_display[CHIP8_WIDTH*CHIP8_HEIGHT]; /* 0xff if pixel is set, */ | 148 | STATIC byte chip8_display[CHIP8_WIDTH*CHIP8_HEIGHT]; /* 0xff if pixel is set, */ |
149 | /* 0x00 otherwise */ | 149 | /* 0x00 otherwise */ |
150 | #ifdef CHIP8_SUPER | 150 | #ifdef CHIP8_SUPER |
151 | STATIC byte chip8_super; /* != 0 if in SCHIP display mode */ | 151 | STATIC byte chip8_super; /* != 0 if in SCHIP display mode */ |
152 | #endif | 152 | #endif |
153 | STATIC byte chip8_mem[4096]; /* machine memory. program */ | 153 | STATIC byte chip8_mem[4096]; /* machine memory. program */ |
154 | /* is loaded at 0x200 */ | 154 | /* is loaded at 0x200 */ |
@@ -179,7 +179,7 @@ static void op_call (word opcode) | |||
179 | chip8_regs.pc=opcode; | 179 | chip8_regs.pc=opcode; |
180 | #ifdef CHIP8_DEBUG | 180 | #ifdef CHIP8_DEBUG |
181 | if(chip8_regs.sp < 0x1c0) | 181 | if(chip8_regs.sp < 0x1c0) |
182 | printf("warning: more than 16 subroutine calls, sp=%x\n", chip8_regs.sp); | 182 | printf("warning: more than 16 subroutine calls, sp=%x\n", chip8_regs.sp); |
183 | #endif | 183 | #endif |
184 | } | 184 | } |
185 | 185 | ||
@@ -199,14 +199,14 @@ static void op_key (word opcode) | |||
199 | else if ((opcode&0xff)==0xa1) /* sknp */ | 199 | else if ((opcode&0xff)==0xa1) /* sknp */ |
200 | cp_value=0; | 200 | cp_value=0; |
201 | else { | 201 | else { |
202 | DBG_(printf("unhandled key opcode 0x%x\n", opcode)); | 202 | DBG_(printf("unhandled key opcode 0x%x\n", opcode)); |
203 | return; | 203 | return; |
204 | } | 204 | } |
205 | key = get_reg_value(opcode)&0x0f; | 205 | key = get_reg_value(opcode)&0x0f; |
206 | #ifdef CHIP8_DEBUG | 206 | #ifdef CHIP8_DEBUG |
207 | if (!tested[key]) { | 207 | if (!tested[key]) { |
208 | tested[key] = 1; | 208 | tested[key] = 1; |
209 | DBG_(printf("testing key %d\n", key)); | 209 | DBG_(printf("testing key %d\n", key)); |
210 | } | 210 | } |
211 | #endif | 211 | #endif |
212 | key_value=chip8_keys[key]; | 212 | key_value=chip8_keys[key]; |
@@ -336,10 +336,10 @@ static void scroll_down(word opcode) | |||
336 | byte *dst = chip8_display + CHIP8_WIDTH*CHIP8_HEIGHT -1; | 336 | byte *dst = chip8_display + CHIP8_WIDTH*CHIP8_HEIGHT -1; |
337 | byte *src = dst - n*CHIP8_WIDTH; | 337 | byte *src = dst - n*CHIP8_WIDTH; |
338 | while(src >= chip8_display) { | 338 | while(src >= chip8_display) { |
339 | *dst-- = *src--; | 339 | *dst-- = *src--; |
340 | } | 340 | } |
341 | while(dst >= chip8_display) { | 341 | while(dst >= chip8_display) { |
342 | *dst-- = 0; | 342 | *dst-- = 0; |
343 | } | 343 | } |
344 | } | 344 | } |
345 | /* SUPER: scroll 4 pixels left! */ | 345 | /* SUPER: scroll 4 pixels left! */ |
@@ -350,15 +350,15 @@ static void scroll_left(void) | |||
350 | byte *eol = chip8_display + CHIP8_WIDTH; | 350 | byte *eol = chip8_display + CHIP8_WIDTH; |
351 | byte *eoi = chip8_display + CHIP8_WIDTH*CHIP8_HEIGHT; | 351 | byte *eoi = chip8_display + CHIP8_WIDTH*CHIP8_HEIGHT; |
352 | while(eol <= eoi) { | 352 | while(eol <= eoi) { |
353 | src+=4; | 353 | src+=4; |
354 | while(src < eol) { | 354 | while(src < eol) { |
355 | *dst++ = *src++; | 355 | *dst++ = *src++; |
356 | } | 356 | } |
357 | *dst++ = 0; | 357 | *dst++ = 0; |
358 | *dst++ = 0; | 358 | *dst++ = 0; |
359 | *dst++ = 0; | 359 | *dst++ = 0; |
360 | *dst++ = 0; | 360 | *dst++ = 0; |
361 | eol += CHIP8_WIDTH; | 361 | eol += CHIP8_WIDTH; |
362 | } | 362 | } |
363 | } | 363 | } |
364 | static void scroll_right(void) | 364 | static void scroll_right(void) |
@@ -367,15 +367,15 @@ static void scroll_right(void) | |||
367 | byte *src = dst; | 367 | byte *src = dst; |
368 | byte *bol = chip8_display + CHIP8_WIDTH*(CHIP8_HEIGHT-1); | 368 | byte *bol = chip8_display + CHIP8_WIDTH*(CHIP8_HEIGHT-1); |
369 | while(bol >= chip8_display) { | 369 | while(bol >= chip8_display) { |
370 | src-=4; | 370 | src-=4; |
371 | while(src >= bol) { | 371 | while(src >= bol) { |
372 | *dst-- = *src--; | 372 | *dst-- = *src--; |
373 | } | 373 | } |
374 | *dst-- = 0; | 374 | *dst-- = 0; |
375 | *dst-- = 0; | 375 | *dst-- = 0; |
376 | *dst-- = 0; | 376 | *dst-- = 0; |
377 | *dst-- = 0; | 377 | *dst-- = 0; |
378 | bol -= CHIP8_WIDTH; | 378 | bol -= CHIP8_WIDTH; |
379 | } | 379 | } |
380 | } | 380 | } |
381 | #endif | 381 | #endif |
@@ -386,25 +386,25 @@ static void op_system (word opcode) | |||
386 | { | 386 | { |
387 | #ifdef CHIP8_SUPER | 387 | #ifdef CHIP8_SUPER |
388 | case 0xfb: | 388 | case 0xfb: |
389 | scroll_right(); | 389 | scroll_right(); |
390 | break; | 390 | break; |
391 | case 0xfc: | 391 | case 0xfc: |
392 | scroll_left(); | 392 | scroll_left(); |
393 | break; | 393 | break; |
394 | case 0xfd: | 394 | case 0xfd: |
395 | DBG_(printf("SUPER: quit the emulator\n")); | 395 | DBG_(printf("SUPER: quit the emulator\n")); |
396 | chip8_reset(); | 396 | chip8_reset(); |
397 | break; | 397 | break; |
398 | case 0xfe: | 398 | case 0xfe: |
399 | DBG_(printf("SUPER: set CHIP-8 graphic mode\n")); | 399 | DBG_(printf("SUPER: set CHIP-8 graphic mode\n")); |
400 | memset (chip8_display,0,sizeof(chip8_display)); | 400 | memset (chip8_display,0,sizeof(chip8_display)); |
401 | chip8_super = 0; | 401 | chip8_super = 0; |
402 | break; | 402 | break; |
403 | case 0xff: | 403 | case 0xff: |
404 | DBG_(printf("SUPER: set SCHIP graphic mode\n")); | 404 | DBG_(printf("SUPER: set SCHIP graphic mode\n")); |
405 | memset (chip8_display,0,sizeof(chip8_display)); | 405 | memset (chip8_display,0,sizeof(chip8_display)); |
406 | chip8_super = 1; | 406 | chip8_super = 1; |
407 | break; | 407 | break; |
408 | #endif | 408 | #endif |
409 | case 0xe0: | 409 | case 0xe0: |
410 | memset (chip8_display,0,sizeof(chip8_display)); | 410 | memset (chip8_display,0,sizeof(chip8_display)); |
@@ -417,15 +417,15 @@ static void op_system (word opcode) | |||
417 | break; | 417 | break; |
418 | default: | 418 | default: |
419 | #ifdef CHIP8_SUPER | 419 | #ifdef CHIP8_SUPER |
420 | if ((opcode & 0xF0) == 0xC0) | 420 | if ((opcode & 0xF0) == 0xC0) |
421 | scroll_down(opcode); | 421 | scroll_down(opcode); |
422 | else | 422 | else |
423 | #endif | 423 | #endif |
424 | { | 424 | { |
425 | DBG_(printf("unhandled system opcode 0x%x\n", opcode)); | 425 | DBG_(printf("unhandled system opcode 0x%x\n", opcode)); |
426 | chip8_running = 3; | 426 | chip8_running = 3; |
427 | } | 427 | } |
428 | break; | 428 | break; |
429 | } | 429 | } |
430 | } | 430 | } |
431 | 431 | ||
@@ -438,41 +438,41 @@ static void op_misc (word opcode) | |||
438 | reg=get_reg_offset(opcode); | 438 | reg=get_reg_offset(opcode); |
439 | switch ((byte)opcode) | 439 | switch ((byte)opcode) |
440 | { | 440 | { |
441 | case 0x07: /* gdelay */ | 441 | case 0x07: /* gdelay */ |
442 | *reg=chip8_regs.delay; | 442 | *reg=chip8_regs.delay; |
443 | break; | 443 | break; |
444 | case 0x0a: /* key */ | 444 | case 0x0a: /* key */ |
445 | #ifdef CHIP8_DEBUG | 445 | #ifdef CHIP8_DEBUG |
446 | if(firstwait) { | 446 | if(firstwait) { |
447 | printf("waiting for key press\n"); | 447 | printf("waiting for key press\n"); |
448 | firstwait = 0; | 448 | firstwait = 0; |
449 | } | 449 | } |
450 | #endif | 450 | #endif |
451 | if (chip8_key_pressed) | 451 | if (chip8_key_pressed) |
452 | *reg=chip8_key_pressed-1; | 452 | *reg=chip8_key_pressed-1; |
453 | else | 453 | else |
454 | chip8_regs.pc-=2; | 454 | chip8_regs.pc-=2; |
455 | break; | 455 | break; |
456 | case 0x15: /* sdelay */ | 456 | case 0x15: /* sdelay */ |
457 | chip8_regs.delay=*reg; | 457 | chip8_regs.delay=*reg; |
458 | break; | 458 | break; |
459 | case 0x18: /* ssound */ | 459 | case 0x18: /* ssound */ |
460 | chip8_regs.sound=*reg; | 460 | chip8_regs.sound=*reg; |
461 | if (chip8_regs.sound) | 461 | if (chip8_regs.sound) |
462 | chip8_sound_on(); | 462 | chip8_sound_on(); |
463 | break; | 463 | break; |
464 | case 0x1e: /* adi */ | 464 | case 0x1e: /* adi */ |
465 | chip8_regs.i+=(*reg); | 465 | chip8_regs.i+=(*reg); |
466 | break; | 466 | break; |
467 | case 0x29: /* font */ | 467 | case 0x29: /* font */ |
468 | chip8_regs.i=((word)(*reg&0x0f))*5; | 468 | chip8_regs.i=((word)(*reg&0x0f))*5; |
469 | break; | 469 | break; |
470 | #ifdef CHIP8_SUPER | 470 | #ifdef CHIP8_SUPER |
471 | case 0x30: /* xfont */ | 471 | case 0x30: /* xfont */ |
472 | chip8_regs.i=((word)(*reg&0x0f))*10+0x50; | 472 | chip8_regs.i=((word)(*reg&0x0f))*10+0x50; |
473 | break; | 473 | break; |
474 | #endif | 474 | #endif |
475 | case 0x33: /* bcd */ | 475 | case 0x33: /* bcd */ |
476 | i=*reg; | 476 | i=*reg; |
477 | for (j=0;i>=100;i-=100) | 477 | for (j=0;i>=100;i-=100) |
478 | j++; | 478 | j++; |
@@ -482,25 +482,25 @@ static void op_misc (word opcode) | |||
482 | write_mem (chip8_regs.i+1,j); | 482 | write_mem (chip8_regs.i+1,j); |
483 | write_mem (chip8_regs.i+2,i); | 483 | write_mem (chip8_regs.i+2,i); |
484 | break; | 484 | break; |
485 | case 0x55: /* str */ | 485 | case 0x55: /* str */ |
486 | for (i=0,j=(opcode>>8)&0x0f; i<=j; ++i) | 486 | for (i=0,j=(opcode>>8)&0x0f; i<=j; ++i) |
487 | write_mem(chip8_regs.i+i,chip8_regs.alg[i]); | 487 | write_mem(chip8_regs.i+i,chip8_regs.alg[i]); |
488 | break; | 488 | break; |
489 | case 0x65: /* ldr */ | 489 | case 0x65: /* ldr */ |
490 | for (i=0,j=(opcode>>8)&0x0f; i<=j; ++i) | 490 | for (i=0,j=(opcode>>8)&0x0f; i<=j; ++i) |
491 | chip8_regs.alg[i]=read_mem(chip8_regs.i+i); | 491 | chip8_regs.alg[i]=read_mem(chip8_regs.i+i); |
492 | break; | 492 | break; |
493 | #ifdef CHIP8_SUPER | 493 | #ifdef CHIP8_SUPER |
494 | case 0x75: | 494 | case 0x75: |
495 | DBG_(printf("SUPER: save V0..V%x (X<8) in the HP48 flags\n", (opcode>>8)&0x0f)); | 495 | DBG_(printf("SUPER: save V0..V%x (X<8) in the HP48 flags\n", (opcode>>8)&0x0f)); |
496 | break; | 496 | break; |
497 | case 0x85: | 497 | case 0x85: |
498 | DBG_(printf("SUPER: load V0..V%x (X<8) from the HP48 flags\n", (opcode>>8)&0x0f)); | 498 | DBG_(printf("SUPER: load V0..V%x (X<8) from the HP48 flags\n", (opcode>>8)&0x0f)); |
499 | break; | 499 | break; |
500 | #endif | 500 | #endif |
501 | default: | 501 | default: |
502 | DBG_(printf("unhandled misc opcode 0x%x\n", opcode)); | 502 | DBG_(printf("unhandled misc opcode 0x%x\n", opcode)); |
503 | break; | 503 | break; |
504 | } | 504 | } |
505 | } | 505 | } |
506 | 506 | ||
@@ -515,59 +515,59 @@ static void op_sprite (word opcode) | |||
515 | n=opcode&0x0f; | 515 | n=opcode&0x0f; |
516 | #ifdef CHIP8_SUPER | 516 | #ifdef CHIP8_SUPER |
517 | if (chip8_super) { | 517 | if (chip8_super) { |
518 | /*printf("SUPER: sprite(%x)\n", opcode);*/ | 518 | /*printf("SUPER: sprite(%x)\n", opcode);*/ |
519 | x &= 128-1; | 519 | x &= 128-1; |
520 | y &= 64-1; | 520 | y &= 64-1; |
521 | q=chip8_display+y*CHIP8_WIDTH; | 521 | q=chip8_display+y*CHIP8_WIDTH; |
522 | if(n == 0) | 522 | if(n == 0) |
523 | { /* 16x16 sprite */ | 523 | { /* 16x16 sprite */ |
524 | n = 16; | 524 | n = 16; |
525 | if (n+y>64) | 525 | if (n+y>64) |
526 | n=64-y; | 526 | n=64-y; |
527 | for (collision=1;n;--n,q+=CHIP8_WIDTH) | 527 | for (collision=1;n;--n,q+=CHIP8_WIDTH) |
528 | { | 528 | { |
529 | /* first 8 bits */ | 529 | /* first 8 bits */ |
530 | for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&(CHIP8_WIDTH-1)) | 530 | for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&(CHIP8_WIDTH-1)) |
531 | if (y&0x80) | 531 | if (y&0x80) |
532 | collision&=(q[x2]^=0xff); | 532 | collision&=(q[x2]^=0xff); |
533 | x2=(x+8)&(CHIP8_WIDTH-1); | 533 | x2=(x+8)&(CHIP8_WIDTH-1); |
534 | /* last 8 bits */ | 534 | /* last 8 bits */ |
535 | for (y=read_mem(p++);y;y<<=1,x2=(x2+1)&(CHIP8_WIDTH-1)) | 535 | for (y=read_mem(p++);y;y<<=1,x2=(x2+1)&(CHIP8_WIDTH-1)) |
536 | if (y&0x80) | 536 | if (y&0x80) |
537 | collision&=(q[x2]^=0xff); | 537 | collision&=(q[x2]^=0xff); |
538 | } | 538 | } |
539 | } | 539 | } |
540 | else { | 540 | else { |
541 | /* 8xn sprite */ | 541 | /* 8xn sprite */ |
542 | if (n+y>64) | 542 | if (n+y>64) |
543 | n=64-y; | 543 | n=64-y; |
544 | for (collision=1;n;--n,q+=CHIP8_WIDTH) | 544 | for (collision=1;n;--n,q+=CHIP8_WIDTH) |
545 | { | 545 | { |
546 | for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&(CHIP8_WIDTH-1)) | 546 | for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&(CHIP8_WIDTH-1)) |
547 | if (y&0x80) | 547 | if (y&0x80) |
548 | collision&=(q[x2]^=0xff); | 548 | collision&=(q[x2]^=0xff); |
549 | } | 549 | } |
550 | } | 550 | } |
551 | } | 551 | } |
552 | else { | 552 | else { |
553 | x &= 64-1; | 553 | x &= 64-1; |
554 | y &= 32-1; | 554 | y &= 32-1; |
555 | q=chip8_display+y*CHIP8_WIDTH*2; | 555 | q=chip8_display+y*CHIP8_WIDTH*2; |
556 | if(n == 0) | 556 | if(n == 0) |
557 | n = 16; | 557 | n = 16; |
558 | if (n+y>32) | 558 | if (n+y>32) |
559 | n=32-y; | 559 | n=32-y; |
560 | for (collision=1;n;--n,q+=CHIP8_WIDTH*2) | 560 | for (collision=1;n;--n,q+=CHIP8_WIDTH*2) |
561 | { | 561 | { |
562 | for (y=read_mem(p++),x2=x*2;y;y<<=1,x2=(x2+2)&(CHIP8_WIDTH-1)) | 562 | for (y=read_mem(p++),x2=x*2;y;y<<=1,x2=(x2+2)&(CHIP8_WIDTH-1)) |
563 | if (y&0x80) { | 563 | if (y&0x80) { |
564 | q[x2]^=0xff; | 564 | q[x2]^=0xff; |
565 | q[x2+1]^=0xff; | 565 | q[x2+1]^=0xff; |
566 | q[x2+CHIP8_WIDTH]^=0xff; | 566 | q[x2+CHIP8_WIDTH]^=0xff; |
567 | q[x2+CHIP8_WIDTH+1]^=0xff; | 567 | q[x2+CHIP8_WIDTH+1]^=0xff; |
568 | collision &= q[x2]|q[x2+1]|q[x2+CHIP8_WIDTH]|q[x2+CHIP8_WIDTH+1]; | 568 | collision &= q[x2]|q[x2+1]|q[x2+CHIP8_WIDTH]|q[x2+CHIP8_WIDTH+1]; |
569 | } | 569 | } |
570 | } | 570 | } |
571 | } | 571 | } |
572 | #else | 572 | #else |
573 | x &= 64-1; | 573 | x &= 64-1; |
@@ -579,7 +579,7 @@ static void op_sprite (word opcode) | |||
579 | { | 579 | { |
580 | for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&(CHIP8_WIDTH-1)) | 580 | for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&(CHIP8_WIDTH-1)) |
581 | if (y&0x80) | 581 | if (y&0x80) |
582 | collision&=(q[x2]^=0xff); | 582 | collision&=(q[x2]^=0xff); |
583 | } | 583 | } |
584 | #endif | 584 | #endif |
585 | chip8_regs.alg[15]=collision^1; | 585 | chip8_regs.alg[15]=collision^1; |
@@ -650,163 +650,163 @@ STATIC void chip8_debug (word opcode,struct chip8_regs_struct *regs) | |||
650 | printf ("PC=%04X: %04X - ",regs->pc,opcode); | 650 | printf ("PC=%04X: %04X - ",regs->pc,opcode); |
651 | switch (opcode>>12) { | 651 | switch (opcode>>12) { |
652 | case 0: | 652 | case 0: |
653 | if ((opcode&0xff0) == 0xc0) { | 653 | if ((opcode&0xff0) == 0xc0) { |
654 | printf ("SCD %01X ; Scroll down n lines",opcode&0xf); | 654 | printf ("SCD %01X ; Scroll down n lines",opcode&0xf); |
655 | } | 655 | } |
656 | else switch (opcode&0xfff) { | 656 | else switch (opcode&0xfff) { |
657 | case 0xe0: | 657 | case 0xe0: |
658 | printf ("CLS ; Clear screen"); | 658 | printf ("CLS ; Clear screen"); |
659 | break; | 659 | break; |
660 | case 0xee: | 660 | case 0xee: |
661 | printf ("RET ; Return from subroutine call"); | 661 | printf ("RET ; Return from subroutine call"); |
662 | break; | 662 | break; |
663 | case 0xfb: | 663 | case 0xfb: |
664 | printf("SCR ; Scroll right"); | 664 | printf("SCR ; Scroll right"); |
665 | break; | 665 | break; |
666 | case 0xfc: | 666 | case 0xfc: |
667 | printf("SCL ; Scroll left"); | 667 | printf("SCL ; Scroll left"); |
668 | break; | 668 | break; |
669 | case 0xfd: | 669 | case 0xfd: |
670 | printf("EXIT ; Terminate the interpreter"); | 670 | printf("EXIT ; Terminate the interpreter"); |
671 | break; | 671 | break; |
672 | case 0xfe: | 672 | case 0xfe: |
673 | printf("LOW ; Disable extended screen mode"); | 673 | printf("LOW ; Disable extended screen mode"); |
674 | break; | 674 | break; |
675 | case 0xff: | 675 | case 0xff: |
676 | printf("HIGH ; Enable extended screen mode"); | 676 | printf("HIGH ; Enable extended screen mode"); |
677 | break; | 677 | break; |
678 | default: | 678 | default: |
679 | printf ("SYS %03X ; Unknown system call",opcode&0xff); | 679 | printf ("SYS %03X ; Unknown system call",opcode&0xff); |
680 | } | 680 | } |
681 | break; | 681 | break; |
682 | case 1: | 682 | case 1: |
683 | printf ("JP %03X ; Jump to address",opcode&0xfff); | 683 | printf ("JP %03X ; Jump to address",opcode&0xfff); |
684 | break; | 684 | break; |
685 | case 2: | 685 | case 2: |
686 | printf ("CALL %03X ; Call subroutine",opcode&0xfff); | 686 | printf ("CALL %03X ; Call subroutine",opcode&0xfff); |
687 | break; | 687 | break; |
688 | case 3: | 688 | case 3: |
689 | printf ("SE %s,%02X ; Skip if register == constant",v1,opcode&0xff); | 689 | printf ("SE %s,%02X ; Skip if register == constant",v1,opcode&0xff); |
690 | break; | 690 | break; |
691 | case 4: | 691 | case 4: |
692 | printf ("SNE %s,%02X ; Skip if register <> constant",v1,opcode&0xff); | 692 | printf ("SNE %s,%02X ; Skip if register <> constant",v1,opcode&0xff); |
693 | break; | 693 | break; |
694 | case 5: | 694 | case 5: |
695 | printf ("SE %s,%s ; Skip if register == register",v1,v2); | 695 | printf ("SE %s,%s ; Skip if register == register",v1,v2); |
696 | break; | 696 | break; |
697 | case 6: | 697 | case 6: |
698 | printf ("LD %s,%02X ; Set VX = Byte",v1,opcode&0xff); | 698 | printf ("LD %s,%02X ; Set VX = Byte",v1,opcode&0xff); |
699 | break; | 699 | break; |
700 | case 7: | 700 | case 7: |
701 | printf ("ADD %s,%02X ; Set VX = VX + Byte",v1,opcode&0xff); | 701 | printf ("ADD %s,%02X ; Set VX = VX + Byte",v1,opcode&0xff); |
702 | break; | 702 | break; |
703 | case 8: | 703 | case 8: |
704 | switch (opcode&0x0f) { | 704 | switch (opcode&0x0f) { |
705 | case 0: | 705 | case 0: |
706 | printf ("LD %s,%s ; Set VX = VY, VF updates",v1,v2); | 706 | printf ("LD %s,%s ; Set VX = VY, VF updates",v1,v2); |
707 | break; | 707 | break; |
708 | case 1: | 708 | case 1: |
709 | printf ("OR %s,%s ; Set VX = VX | VY, VF updates",v1,v2); | 709 | printf ("OR %s,%s ; Set VX = VX | VY, VF updates",v1,v2); |
710 | break; | 710 | break; |
711 | case 2: | 711 | case 2: |
712 | printf ("AND %s,%s ; Set VX = VX & VY, VF updates",v1,v2); | 712 | printf ("AND %s,%s ; Set VX = VX & VY, VF updates",v1,v2); |
713 | break; | 713 | break; |
714 | case 3: | 714 | case 3: |
715 | printf ("XOR %s,%s ; Set VX = VX ^ VY, VF updates",v1,v2); | 715 | printf ("XOR %s,%s ; Set VX = VX ^ VY, VF updates",v1,v2); |
716 | break; | 716 | break; |
717 | case 4: | 717 | case 4: |
718 | printf ("ADD %s,%s ; Set VX = VX + VY, VF = carry",v1,v2); | 718 | printf ("ADD %s,%s ; Set VX = VX + VY, VF = carry",v1,v2); |
719 | break; | 719 | break; |
720 | case 5: | 720 | case 5: |
721 | printf ("SUB %s,%s ; Set VX = VX - VY, VF = !borrow",v1,v2); | 721 | printf ("SUB %s,%s ; Set VX = VX - VY, VF = !borrow",v1,v2); |
722 | break; | 722 | break; |
723 | case 6: | 723 | case 6: |
724 | printf ("SHR %s,%s ; Set VX = VX >> 1, VF = carry",v1,v2); | 724 | printf ("SHR %s,%s ; Set VX = VX >> 1, VF = carry",v1,v2); |
725 | break; | 725 | break; |
726 | case 7: | 726 | case 7: |
727 | printf ("SUBN %s,%s ; Set VX = VY - VX, VF = !borrow",v1,v2); | 727 | printf ("SUBN %s,%s ; Set VX = VY - VX, VF = !borrow",v1,v2); |
728 | break; | 728 | break; |
729 | case 14: | 729 | case 14: |
730 | printf ("SHL %s,%s ; Set VX = VX << 1, VF = carry",v1,v2); | 730 | printf ("SHL %s,%s ; Set VX = VX << 1, VF = carry",v1,v2); |
731 | break; | 731 | break; |
732 | default: | 732 | default: |
733 | printf ("Illegal opcode"); | 733 | printf ("Illegal opcode"); |
734 | } | 734 | } |
735 | break; | 735 | break; |
736 | case 9: | 736 | case 9: |
737 | printf ("SNE %s,%s ; Skip next instruction iv VX!=VY",v1,v2); | 737 | printf ("SNE %s,%s ; Skip next instruction iv VX!=VY",v1,v2); |
738 | break; | 738 | break; |
739 | case 10: | 739 | case 10: |
740 | printf ("LD I,%03X ; Set I = Addr",opcode&0xfff); | 740 | printf ("LD I,%03X ; Set I = Addr",opcode&0xfff); |
741 | break; | 741 | break; |
742 | case 11: | 742 | case 11: |
743 | printf ("JP V0,%03X ; Jump to Addr + V0",opcode&0xfff); | 743 | printf ("JP V0,%03X ; Jump to Addr + V0",opcode&0xfff); |
744 | break; | 744 | break; |
745 | case 12: | 745 | case 12: |
746 | printf ("RND %s,%02X ; Set VX = random & Byte",v1,opcode&0xff); | 746 | printf ("RND %s,%02X ; Set VX = random & Byte",v1,opcode&0xff); |
747 | break; | 747 | break; |
748 | case 13: | 748 | case 13: |
749 | printf ("DRW %s,%s,%X ; Draw n byte sprite stored at [i] at VX,VY. Set VF = collision",v1,v2,opcode&0x0f); | 749 | printf ("DRW %s,%s,%X ; Draw n byte sprite stored at [i] at VX,VY. Set VF = collision",v1,v2,opcode&0x0f); |
750 | break; | 750 | break; |
751 | case 14: | 751 | case 14: |
752 | switch (opcode&0xff) { | 752 | switch (opcode&0xff) { |
753 | case 0x9e: | 753 | case 0x9e: |
754 | printf ("SKP %s ; Skip next instruction if key VX down",v1); | 754 | printf ("SKP %s ; Skip next instruction if key VX down",v1); |
755 | break; | 755 | break; |
756 | case 0xa1: | 756 | case 0xa1: |
757 | printf ("SKNP %s ; Skip next instruction if key VX up",v1); | 757 | printf ("SKNP %s ; Skip next instruction if key VX up",v1); |
758 | break; | 758 | break; |
759 | default: | 759 | default: |
760 | printf ("%04X ; Illegal opcode", opcode); | 760 | printf ("%04X ; Illegal opcode", opcode); |
761 | } | 761 | } |
762 | break; | 762 | break; |
763 | case 15: | 763 | case 15: |
764 | switch (opcode&0xff) { | 764 | switch (opcode&0xff) { |
765 | case 0x07: | 765 | case 0x07: |
766 | printf ("LD %s,DT ; Set VX = delaytimer",v1); | 766 | printf ("LD %s,DT ; Set VX = delaytimer",v1); |
767 | break; | 767 | break; |
768 | case 0x0a: | 768 | case 0x0a: |
769 | printf ("LD %s,K ; Set VX = key, wait for keypress",v1); | 769 | printf ("LD %s,K ; Set VX = key, wait for keypress",v1); |
770 | break; | 770 | break; |
771 | case 0x15: | 771 | case 0x15: |
772 | printf ("LD DT,%s ; Set delaytimer = VX",v1); | 772 | printf ("LD DT,%s ; Set delaytimer = VX",v1); |
773 | break; | 773 | break; |
774 | case 0x18: | 774 | case 0x18: |
775 | printf ("LD ST,%s ; Set soundtimer = VX",v1); | 775 | printf ("LD ST,%s ; Set soundtimer = VX",v1); |
776 | break; | 776 | break; |
777 | case 0x1e: | 777 | case 0x1e: |
778 | printf ("ADD I,%s ; Set I = I + VX",v1); | 778 | printf ("ADD I,%s ; Set I = I + VX",v1); |
779 | break; | 779 | break; |
780 | case 0x29: | 780 | case 0x29: |
781 | printf ("LD LF,%s ; Point I to 5 byte numeric sprite for value in VX",v1); | 781 | printf ("LD LF,%s ; Point I to 5 byte numeric sprite for value in VX",v1); |
782 | break; | 782 | break; |
783 | case 0x30: | 783 | case 0x30: |
784 | printf ("LD HF,%s ; Point I to 10 byte numeric sprite for value in VX",v1); | 784 | printf ("LD HF,%s ; Point I to 10 byte numeric sprite for value in VX",v1); |
785 | break; | 785 | break; |
786 | case 0x33: | 786 | case 0x33: |
787 | printf ("LD B,%s ; Store BCD of VX in [I], [I+1], [I+2]",v1); | 787 | printf ("LD B,%s ; Store BCD of VX in [I], [I+1], [I+2]",v1); |
788 | break; | 788 | break; |
789 | case 0x55: | 789 | case 0x55: |
790 | printf ("LD [I],%s ; Store V0..VX in [I]..[I+X]",v1); | 790 | printf ("LD [I],%s ; Store V0..VX in [I]..[I+X]",v1); |
791 | break; | 791 | break; |
792 | case 0x65: | 792 | case 0x65: |
793 | printf ("LD %s,[I] ; Read V0..VX from [I]..[I+X]",v1); | 793 | printf ("LD %s,[I] ; Read V0..VX from [I]..[I+X]",v1); |
794 | break; | 794 | break; |
795 | case 0x75: | 795 | case 0x75: |
796 | printf ("LD R,%s ; Store V0..VX in RPL user flags (X<=7)",v1); | 796 | printf ("LD R,%s ; Store V0..VX in RPL user flags (X<=7)",v1); |
797 | break; | 797 | break; |
798 | case 0x85: | 798 | case 0x85: |
799 | printf ("LD %s,R ; Read V0..VX from RPL user flags (X<=7)",v1); | 799 | printf ("LD %s,R ; Read V0..VX from RPL user flags (X<=7)",v1); |
800 | break; | 800 | break; |
801 | default: | 801 | default: |
802 | printf ("%04X ; Illegal opcode", opcode); | 802 | printf ("%04X ; Illegal opcode", opcode); |
803 | } | 803 | } |
804 | break; | 804 | break; |
805 | } | 805 | } |
806 | printf ("\n; Registers: "); | 806 | printf ("\n; Registers: "); |
807 | for (i=0;i<16;++i) printf ("%02x ",(regs->alg[i])&0xff); | 807 | for (i=0;i<16;++i) printf ("%02x ",(regs->alg[i])&0xff); |
808 | printf ("\n; Index: %03x Stack:%03x Delay:%02x Sound:%02x\n", | 808 | printf ("\n; Index: %03x Stack:%03x Delay:%02x Sound:%02x\n", |
809 | regs->i&0xfff,regs->sp&0xfff,regs->delay&0xff,regs->sound&0xff); | 809 | regs->i&0xfff,regs->sp&0xfff,regs->delay&0xff,regs->sound&0xff); |
810 | } | 810 | } |
811 | #endif | 811 | #endif |
812 | 812 | ||
@@ -820,15 +820,15 @@ STATIC void chip8_execute(void) | |||
820 | word opcode; | 820 | word opcode; |
821 | for (i = chip8_iperiod ; i ;--i) | 821 | for (i = chip8_iperiod ; i ;--i) |
822 | { | 822 | { |
823 | /* Fetch the opcode */ | 823 | /* Fetch the opcode */ |
824 | opcode=(read_mem(chip8_regs.pc)<<8)+read_mem(chip8_regs.pc+1); | 824 | opcode=(read_mem(chip8_regs.pc)<<8)+read_mem(chip8_regs.pc+1); |
825 | #ifdef CHIP8_DEBUG | 825 | #ifdef CHIP8_DEBUG |
826 | /* Check if trap address has been reached */ | 826 | /* Check if trap address has been reached */ |
827 | if ((chip8_regs.pc&4095)==chip8_trap) | 827 | if ((chip8_regs.pc&4095)==chip8_trap) |
828 | chip8_trace=1; | 828 | chip8_trace=1; |
829 | /* Call the debugger if chip8_trace!=0 */ | 829 | /* Call the debugger if chip8_trace!=0 */ |
830 | if (chip8_trace) | 830 | if (chip8_trace) |
831 | chip8_debug (opcode,&chip8_regs); | 831 | chip8_debug (opcode,&chip8_regs); |
832 | #endif | 832 | #endif |
833 | chip8_regs.pc+=2; | 833 | chip8_regs.pc+=2; |
834 | (*(main_opcodes[opcode>>12]))(opcode&0x0fff); /* Emulate this opcode */ | 834 | (*(main_opcodes[opcode>>12]))(opcode&0x0fff); /* Emulate this opcode */ |
@@ -844,7 +844,7 @@ STATIC void chip8_execute(void) | |||
844 | chip8_interrupt (); | 844 | chip8_interrupt (); |
845 | 845 | ||
846 | for (i=key_pressed=0;i<16;++i) /* check if a key was first */ | 846 | for (i=key_pressed=0;i<16;++i) /* check if a key was first */ |
847 | if (chip8_keys[i]) /* pressed */ | 847 | if (chip8_keys[i]) /* pressed */ |
848 | key_pressed=i+1; | 848 | key_pressed=i+1; |
849 | if (key_pressed && key_pressed!=chip8_key_pressed) | 849 | if (key_pressed && key_pressed!=chip8_key_pressed) |
850 | chip8_key_pressed=key_pressed; | 850 | chip8_key_pressed=key_pressed; |
@@ -871,16 +871,16 @@ STATIC void chip8_reset(void) | |||
871 | #ifdef CHIP8_SUPER | 871 | #ifdef CHIP8_SUPER |
872 | static byte schip_sprites[10*10]= | 872 | static byte schip_sprites[10*10]= |
873 | { | 873 | { |
874 | 0x3C, 0x7E, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x7E, 0x3C, /* 0 */ | 874 | 0x3C, 0x7E, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x7E, 0x3C, /* 0 */ |
875 | 0x18, 0x38, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, /* 1 */ | 875 | 0x18, 0x38, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, /* 1 */ |
876 | 0x3E, 0x7F, 0xC3, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xFF, 0xFF, /* 2 */ | 876 | 0x3E, 0x7F, 0xC3, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xFF, 0xFF, /* 2 */ |
877 | 0x3C, 0x7E, 0xC3, 0x03, 0x0E, 0x0E, 0x03, 0xC3, 0x7E, 0x3C, /* 3 */ | 877 | 0x3C, 0x7E, 0xC3, 0x03, 0x0E, 0x0E, 0x03, 0xC3, 0x7E, 0x3C, /* 3 */ |
878 | 0x06, 0x0E, 0x1E, 0x36, 0x66, 0xC6, 0xFF, 0xFF, 0x06, 0x06, /* 4 */ | 878 | 0x06, 0x0E, 0x1E, 0x36, 0x66, 0xC6, 0xFF, 0xFF, 0x06, 0x06, /* 4 */ |
879 | 0xFF, 0xFF, 0xC0, 0xC0, 0xFC, 0xFE, 0x03, 0xC3, 0x7E, 0x3C, /* 5 */ | 879 | 0xFF, 0xFF, 0xC0, 0xC0, 0xFC, 0xFE, 0x03, 0xC3, 0x7E, 0x3C, /* 5 */ |
880 | 0x3E, 0x7C, 0xC0, 0xC0, 0xFC, 0xFE, 0xC3, 0xC3, 0x7E, 0x3C, /* 6 */ | 880 | 0x3E, 0x7C, 0xC0, 0xC0, 0xFC, 0xFE, 0xC3, 0xC3, 0x7E, 0x3C, /* 6 */ |
881 | 0xFF, 0xFF, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x60, 0x60, /* 7 */ | 881 | 0xFF, 0xFF, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x60, 0x60, /* 7 */ |
882 | 0x3C, 0x7E, 0xC3, 0xC3, 0x7E, 0x7E, 0xC3, 0xC3, 0x7E, 0x3C, /* 8 */ | 882 | 0x3C, 0x7E, 0xC3, 0xC3, 0x7E, 0x7E, 0xC3, 0xC3, 0x7E, 0x3C, /* 8 */ |
883 | 0x3C, 0x7E, 0xC3, 0xC3, 0x7F, 0x3F, 0x03, 0x03, 0x3E, 0x7C, /* 9 */ | 883 | 0x3C, 0x7E, 0xC3, 0xC3, 0x7F, 0x3F, 0x03, 0x03, 0x3E, 0x7C, /* 9 */ |
884 | }; /* 8x10 pixel font patterns (only 10) */ | 884 | }; /* 8x10 pixel font patterns (only 10) */ |
885 | #endif | 885 | #endif |
886 | byte i; | 886 | byte i; |
@@ -1325,11 +1325,11 @@ static void chip8_interrupt (void) | |||
1325 | newtimer = *rb->current_tick; | 1325 | newtimer = *rb->current_tick; |
1326 | if (TIME_AFTER(timer, newtimer)) | 1326 | if (TIME_AFTER(timer, newtimer)) |
1327 | { | 1327 | { |
1328 | rb->sleep(timer - newtimer); | 1328 | rb->sleep(timer - newtimer); |
1329 | } | 1329 | } |
1330 | else | 1330 | else |
1331 | { | 1331 | { |
1332 | rb->yield(); | 1332 | rb->yield(); |
1333 | } | 1333 | } |
1334 | starttimer = newtimer - runtime; | 1334 | starttimer = newtimer - runtime; |
1335 | } | 1335 | } |
@@ -1343,13 +1343,13 @@ static bool chip8_init(const char* file) | |||
1343 | 1343 | ||
1344 | fd = rb->open(file, O_RDONLY); | 1344 | fd = rb->open(file, O_RDONLY); |
1345 | if (fd < 0) { | 1345 | if (fd < 0) { |
1346 | rb->lcd_puts(0, 6, "File Error."); | 1346 | rb->lcd_puts(0, 6, "File Error."); |
1347 | return false; | 1347 | return false; |
1348 | } | 1348 | } |
1349 | numread = rb->read(fd, chip8_mem+0x200, 4096-0x200); | 1349 | numread = rb->read(fd, chip8_mem+0x200, 4096-0x200); |
1350 | if (numread==-1) { | 1350 | if (numread==-1) { |
1351 | rb->lcd_puts(0, 6, "I/O Error."); | 1351 | rb->lcd_puts(0, 6, "I/O Error."); |
1352 | return false; | 1352 | return false; |
1353 | } | 1353 | } |
1354 | 1354 | ||
1355 | rb->close(fd); | 1355 | rb->close(fd); |
@@ -1357,34 +1357,34 @@ static bool chip8_init(const char* file) | |||
1357 | char c8kname[MAX_PATH]; | 1357 | char c8kname[MAX_PATH]; |
1358 | rb->strcpy(c8kname, file); | 1358 | rb->strcpy(c8kname, file); |
1359 | for(i=0; i<16; i++) { | 1359 | for(i=0; i<16; i++) { |
1360 | chip8_virtual_keys[i] = 0; | 1360 | chip8_virtual_keys[i] = 0; |
1361 | chip8_keymap[i] = i; | 1361 | chip8_keymap[i] = i; |
1362 | } | 1362 | } |
1363 | len = rb->strlen(c8kname); | 1363 | len = rb->strlen(c8kname); |
1364 | c8kname[len-2] = '8'; | 1364 | c8kname[len-2] = '8'; |
1365 | c8kname[len-1] = 'k'; | 1365 | c8kname[len-1] = 'k'; |
1366 | fd = rb->open(c8kname, O_RDONLY); | 1366 | fd = rb->open(c8kname, O_RDONLY); |
1367 | if (fd >= 0) { | 1367 | if (fd >= 0) { |
1368 | rb->lcd_puts(0, 6, "File&Keymap OK."); | 1368 | rb->lcd_puts(0, 6, "File&Keymap OK."); |
1369 | numread = rb->read(fd, chip8_keymap, 16); | 1369 | numread = rb->read(fd, chip8_keymap, 16); |
1370 | rb->close(fd); | 1370 | rb->close(fd); |
1371 | } | 1371 | } |
1372 | else | 1372 | else |
1373 | { | 1373 | { |
1374 | rb->lcd_puts(0, 6, "File OK."); | 1374 | rb->lcd_puts(0, 6, "File OK."); |
1375 | } | 1375 | } |
1376 | for(i=0; i<16; i++) { | 1376 | for(i=0; i<16; i++) { |
1377 | if (chip8_keymap[i] >= '0' | 1377 | if (chip8_keymap[i] >= '0' |
1378 | && chip8_keymap[i] <= '9') | 1378 | && chip8_keymap[i] <= '9') |
1379 | chip8_keymap[i] -= '0'; | 1379 | chip8_keymap[i] -= '0'; |
1380 | else if (chip8_keymap[i] >= 'A' | 1380 | else if (chip8_keymap[i] >= 'A' |
1381 | && chip8_keymap[i] <= 'F') | 1381 | && chip8_keymap[i] <= 'F') |
1382 | chip8_keymap[i] -= 'A' - 10; | 1382 | chip8_keymap[i] -= 'A' - 10; |
1383 | else if (chip8_keymap[i] >= 'a' | 1383 | else if (chip8_keymap[i] >= 'a' |
1384 | && chip8_keymap[i] <= 'f') | 1384 | && chip8_keymap[i] <= 'f') |
1385 | chip8_keymap[i] -= 'a' - 10; | 1385 | chip8_keymap[i] -= 'a' - 10; |
1386 | else | 1386 | else |
1387 | chip8_keymap[i] %= 16; | 1387 | chip8_keymap[i] %= 16; |
1388 | } | 1388 | } |
1389 | return true; | 1389 | return true; |
1390 | } | 1390 | } |
@@ -1438,10 +1438,10 @@ bool chip8_run(const char* file) | |||
1438 | #endif | 1438 | #endif |
1439 | 1439 | ||
1440 | if (chip8_running == 3) { | 1440 | if (chip8_running == 3) { |
1441 | /* unsupported instruction */ | 1441 | /* unsupported instruction */ |
1442 | rb->splash(HZ, "Error: Unsupported" | 1442 | rb->splash(HZ, "Error: Unsupported" |
1443 | #ifndef CHIP8_SUPER | 1443 | #ifndef CHIP8_SUPER |
1444 | " CHIP-8 instruction. (maybe S-CHIP)" | 1444 | " CHIP-8 instruction. (maybe S-CHIP)" |
1445 | #else | 1445 | #else |
1446 | " (S)CHIP-8 instruction." | 1446 | " (S)CHIP-8 instruction." |
1447 | #endif | 1447 | #endif |