📄 chip8.c
字号:
/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: chip8.c,v 1.6 2004/02/21 22:30:07 hohensoh Exp $ * * Orginal from Vision-8 Emulator / Copyright (C) 1997-1999 Marcel de Kogel * Modified for Archos by Blueloop (a.wenger@gmx.de) * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/#include "plugin.h"/* Only build for (correct) target */#ifdef HAVE_LCD_BITMAP #ifndef SIMULATOR /* not unless lcd_blit() is implemented and mp3_xx stubbed */static struct plugin_api* rb; /* here is a global api struct pointer */unsigned char lcd_framebuf[8][64]; /* frame buffer in hardware fomat */typedef unsigned char byte; /* sizeof(byte)==1 */typedef unsigned short word; /* sizeof(word)>=2 */struct chip8_regs_struct{ byte alg[16]; /* 16 general registers */ byte delay,sound; /* delay and sound timer */ word i; /* index register */ word pc; /* program counter */ word sp; /* stack pointer */};static struct chip8_regs_struct chip8_regs;#define chip8_iperiod 10 /* number of opcodes per */ /* timeslice (1/50sec.) */static byte chip8_key_pressed;static byte chip8_keys[16]; /* if 1, key is held down */static byte chip8_display[64*32]; /* 0xff if pixel is set, */ /* 0x00 otherwise */static byte chip8_mem[4096]; /* machine memory. program */ /* is loaded at 0x200 */#define read_mem(a) (chip8_mem[(a)&4095])#define write_mem(a,v) (chip8_mem[(a)&4095]=(v))static byte chip8_running; /* Flag for End-of-Emulation */#define get_reg_offset(opcode) (chip8_regs.alg+(opcode>>8))#define get_reg_value(opcode) (*get_reg_offset(opcode))#define get_reg_offset_2(opcode) (chip8_regs.alg+((opcode>>4)&0x0f))#define get_reg_value_2(opcode) (*get_reg_offset_2(opcode))typedef void (*opcode_fn) (word opcode);typedef void (*math_fn) (byte *reg1,byte reg2);static bool is_playing;/* one frame of bitswapped mp3 data */static unsigned char beep[]={255,223, 28, 35, 0,192,210, 35,226, 72,188,242, 1,128,166, 16, 68,146,252,151, 19, 10,180,245,127, 96,184, 3,184, 30, 0,118, 59,128,121,102, 6,212, 0, 97, 6, 42, 65, 28,134,192,145, 57, 38,136, 73, 29, 38,132, 15, 21, 70, 91,185, 99,198, 15,192, 83, 6, 33,129, 20, 6, 97, 33, 4, 6,245,128, 92, 6, 24, 0, 86, 6, 56,129, 44, 24,224, 25, 13, 48, 50, 82,180, 11,251,106,249, 59, 24, 82,175,223,252,119, 76,134,120,236,149,250,247,115,254,145,173,174,168,180,255,107,195, 89, 24, 25, 48,131,192, 61, 48, 64, 10,176, 49, 64, 1,152, 50, 32, 8,140, 48, 16, 5,129, 51,196,187, 41,177, 23,138, 70, 50, 8, 10,242, 48,192, 3,248,226, 0, 20,100, 18, 96, 41, 96, 78,102, 7,201,122, 76,119, 20,137, 37,177, 15,132,224, 20, 17,191, 67,147,187,116,211, 41,169, 63,172,182,186,217,155,111,140,104,254,111,181,184,144, 17,148, 21,101,166,227,100, 86, 85, 85, 85}; /* callback to request more mp3 data */void callback(unsigned char** start, int* size){ *start = beep; /* give it the same frame again */ *size = sizeof(beep);}/****************************************************************************//* Turn sound on *//****************************************************************************/static void chip8_sound_on (void) { if (!is_playing) rb->mp3_play_pause(true); /* kickoff audio */}/****************************************************************************//* Turn sound off *//****************************************************************************/static void chip8_sound_off (void) { if (!is_playing) rb->mp3_play_pause(false); /* pause audio */}static void op_call (word opcode){ chip8_regs.sp--; write_mem (chip8_regs.sp,chip8_regs.pc&0xff); chip8_regs.sp--; write_mem (chip8_regs.sp,chip8_regs.pc>>8); chip8_regs.pc=opcode;}static void op_jmp (word opcode){ chip8_regs.pc=opcode;}static void op_key (word opcode){ byte key_value,cp_value; if ((opcode&0xff)==0x9e) cp_value=1; else if ((opcode&0xff)==0xa1) cp_value=0; else return; key_value=chip8_keys[get_reg_value(opcode)&0x0f]; if (cp_value==key_value) chip8_regs.pc+=2;}static void op_skeq_const (word opcode){ if (get_reg_value(opcode)==(opcode&0xff)) chip8_regs.pc+=2;}static void op_skne_const (word opcode){ if (get_reg_value(opcode)!=(opcode&0xff)) chip8_regs.pc+=2;}static void op_skeq_reg (word opcode){ if (get_reg_value(opcode)==get_reg_value_2(opcode)) chip8_regs.pc+=2;}static void op_skne_reg (word opcode){ if (get_reg_value(opcode)!=get_reg_value_2(opcode)) chip8_regs.pc+=2;}static void op_mov_const (word opcode){ *get_reg_offset(opcode)=opcode&0xff;}static void op_add_const (word opcode){ *get_reg_offset(opcode)+=opcode&0xff;}static void op_mvi (word opcode){ chip8_regs.i=opcode;}static void op_jmi (word opcode){ chip8_regs.pc=opcode+chip8_regs.alg[0];}static void op_rand (word opcode){ *get_reg_offset(opcode)=rb->rand()&(opcode&0xff);}static void math_or (byte *reg1,byte reg2){ *reg1|=reg2;}static void math_mov (byte *reg1,byte reg2){ *reg1=reg2;}static void math_nop (byte *reg1,byte reg2){ (void)reg1; (void)reg2;}static void math_and (byte *reg1,byte reg2){ *reg1&=reg2;}static void math_xor (byte *reg1,byte reg2){ *reg1^=reg2;}static void math_add (byte *reg1,byte reg2){ word tmp; tmp=*reg1+reg2; *reg1=(byte)tmp; chip8_regs.alg[15]=tmp>>8;}static void math_sub (byte *reg1,byte reg2){ word tmp; tmp=*reg1-reg2; *reg1=(byte)tmp; chip8_regs.alg[15]=((byte)(tmp>>8))+1;}static void math_shr (byte *reg1,byte reg2){ (void)reg2; chip8_regs.alg[15]=*reg1&1; *reg1>>=1;}static void math_shl (byte *reg1,byte reg2){ (void)reg2; chip8_regs.alg[15]=*reg1>>7; *reg1<<=1;}static void math_rsb (byte *reg1,byte reg2){ word tmp; tmp=reg2-*reg1; *reg1=(byte)tmp; chip8_regs.alg[15]=((byte)(tmp>>8))+1;}static void op_system (word opcode){ switch ((byte)opcode) { case 0xe0: rb->memset (chip8_display,0,sizeof(chip8_display)); break; case 0xee: chip8_regs.pc=read_mem(chip8_regs.sp)<<8; chip8_regs.sp++; chip8_regs.pc+=read_mem(chip8_regs.sp); chip8_regs.sp++; break; }}static void op_misc (word opcode){ byte *reg,i,j; reg=get_reg_offset(opcode); switch ((byte)opcode) { case 0x07: *reg=chip8_regs.delay; break; case 0x0a: if (chip8_key_pressed) *reg=chip8_key_pressed-1; else chip8_regs.pc-=2; break; case 0x15: chip8_regs.delay=*reg; break; case 0x18: chip8_regs.sound=*reg; if (chip8_regs.sound) chip8_sound_on(); break; case 0x1e: chip8_regs.i+=(*reg); break; case 0x29: chip8_regs.i=((word)(*reg&0x0f))*5; break; case 0x33: i=*reg; for (j=0;i>=100;i-=100) j++; write_mem (chip8_regs.i,j); for (j=0;i>=10;i-=10) j++; write_mem (chip8_regs.i+1,j); write_mem (chip8_regs.i+2,i); break; case 0x55:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -