1
0
Fork 0
forked from len0rd/rockbox

Lee Pilgrim's patch to enable the chip8 plugin for the simulator

I also code-policed it somewhat.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4207 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Daniel Stenberg 2004-01-08 13:03:04 +00:00
parent 0f68958b11
commit aac303e17b

View file

@ -20,7 +20,6 @@
#include "plugin.h" #include "plugin.h"
/* Only build for (correct) target */ /* Only build for (correct) target */
#ifndef SIMULATOR
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
static struct plugin_api* rb; /* here is a global api struct pointer */ static struct plugin_api* rb; /* here is a global api struct pointer */
@ -74,95 +73,100 @@ static void chip8_sound_off (void) { }
static void op_call (word opcode) static void op_call (word opcode)
{ {
chip8_regs.sp--; chip8_regs.sp--;
write_mem (chip8_regs.sp,chip8_regs.pc&0xff); write_mem (chip8_regs.sp,chip8_regs.pc&0xff);
chip8_regs.sp--; chip8_regs.sp--;
write_mem (chip8_regs.sp,chip8_regs.pc>>8); write_mem (chip8_regs.sp,chip8_regs.pc>>8);
chip8_regs.pc=opcode; chip8_regs.pc=opcode;
} }
static void op_jmp (word opcode) static void op_jmp (word opcode)
{ {
chip8_regs.pc=opcode; chip8_regs.pc=opcode;
} }
static void op_key (word opcode) static void op_key (word opcode)
{ {
byte key_value,cp_value; byte key_value,cp_value;
if ((opcode&0xff)==0x9e) if ((opcode&0xff)==0x9e)
cp_value=1; cp_value=1;
else if ((opcode&0xff)==0xa1) else if ((opcode&0xff)==0xa1)
cp_value=0; cp_value=0;
else else
return; return;
key_value=chip8_keys[get_reg_value(opcode)&0x0f]; key_value=chip8_keys[get_reg_value(opcode)&0x0f];
if (cp_value==key_value) chip8_regs.pc+=2; if (cp_value==key_value)
chip8_regs.pc+=2;
} }
static void op_skeq_const (word opcode) static void op_skeq_const (word opcode)
{ {
if (get_reg_value(opcode)==(opcode&0xff)) chip8_regs.pc+=2; if (get_reg_value(opcode)==(opcode&0xff))
chip8_regs.pc+=2;
} }
static void op_skne_const (word opcode) static void op_skne_const (word opcode)
{ {
if (get_reg_value(opcode)!=(opcode&0xff)) chip8_regs.pc+=2; if (get_reg_value(opcode)!=(opcode&0xff))
chip8_regs.pc+=2;
} }
static void op_skeq_reg (word opcode) static void op_skeq_reg (word opcode)
{ {
if (get_reg_value(opcode)==get_reg_value_2(opcode)) chip8_regs.pc+=2; if (get_reg_value(opcode)==get_reg_value_2(opcode))
chip8_regs.pc+=2;
} }
static void op_skne_reg (word opcode) static void op_skne_reg (word opcode)
{ {
if (get_reg_value(opcode)!=get_reg_value_2(opcode)) chip8_regs.pc+=2; if (get_reg_value(opcode)!=get_reg_value_2(opcode))
chip8_regs.pc+=2;
} }
static void op_mov_const (word opcode) static void op_mov_const (word opcode)
{ {
*get_reg_offset(opcode)=opcode&0xff; *get_reg_offset(opcode)=opcode&0xff;
} }
static void op_add_const (word opcode) static void op_add_const (word opcode)
{ {
*get_reg_offset(opcode)+=opcode&0xff; *get_reg_offset(opcode)+=opcode&0xff;
} }
static void op_mvi (word opcode) static void op_mvi (word opcode)
{ {
chip8_regs.i=opcode; chip8_regs.i=opcode;
} }
static void op_jmi (word opcode) static void op_jmi (word opcode)
{ {
chip8_regs.pc=opcode+chip8_regs.alg[0]; chip8_regs.pc=opcode+chip8_regs.alg[0];
} }
static void op_rand (word opcode) static void op_rand (word opcode)
{ {
*get_reg_offset(opcode)=rb->rand()&(opcode&0xff); *get_reg_offset(opcode)=rb->rand()&(opcode&0xff);
} }
static void math_or (byte *reg1,byte reg2) static void math_or (byte *reg1,byte reg2)
{ {
*reg1|=reg2; *reg1|=reg2;
} }
static void math_mov (byte *reg1,byte reg2) static void math_mov (byte *reg1,byte reg2)
{ {
*reg1=reg2; *reg1=reg2;
} }
static void math_nop (byte *reg1,byte reg2) static void math_nop (byte *reg1,byte reg2)
{ {
(void)reg1; (void)reg1;
(void)reg2; (void)reg2;
} }
static void math_and (byte *reg1,byte reg2) static void math_and (byte *reg1,byte reg2)
{ {
*reg1&=reg2; *reg1&=reg2;
} }
static void math_xor (byte *reg1,byte reg2) static void math_xor (byte *reg1,byte reg2)
@ -172,168 +176,172 @@ static void math_xor (byte *reg1,byte reg2)
static void math_add (byte *reg1,byte reg2) static void math_add (byte *reg1,byte reg2)
{ {
word tmp; word tmp;
tmp=*reg1+reg2; tmp=*reg1+reg2;
*reg1=(byte)tmp; *reg1=(byte)tmp;
chip8_regs.alg[15]=tmp>>8; chip8_regs.alg[15]=tmp>>8;
} }
static void math_sub (byte *reg1,byte reg2) static void math_sub (byte *reg1,byte reg2)
{ {
word tmp; word tmp;
tmp=*reg1-reg2; tmp=*reg1-reg2;
*reg1=(byte)tmp; *reg1=(byte)tmp;
chip8_regs.alg[15]=((byte)(tmp>>8))+1; chip8_regs.alg[15]=((byte)(tmp>>8))+1;
} }
static void math_shr (byte *reg1,byte reg2) static void math_shr (byte *reg1,byte reg2)
{ {
(void)reg2; (void)reg2;
chip8_regs.alg[15]=*reg1&1; chip8_regs.alg[15]=*reg1&1;
*reg1>>=1; *reg1>>=1;
} }
static void math_shl (byte *reg1,byte reg2) static void math_shl (byte *reg1,byte reg2)
{ {
(void)reg2; (void)reg2;
chip8_regs.alg[15]=*reg1>>7; chip8_regs.alg[15]=*reg1>>7;
*reg1<<=1; *reg1<<=1;
} }
static void math_rsb (byte *reg1,byte reg2) static void math_rsb (byte *reg1,byte reg2)
{ {
word tmp; word tmp;
tmp=reg2-*reg1; tmp=reg2-*reg1;
*reg1=(byte)tmp; *reg1=(byte)tmp;
chip8_regs.alg[15]=((byte)(tmp>>8))+1; chip8_regs.alg[15]=((byte)(tmp>>8))+1;
} }
static void op_system (word opcode) static void op_system (word opcode)
{ {
switch ((byte)opcode) switch ((byte)opcode)
{ {
case 0xe0: case 0xe0:
rb->memset (chip8_display,0,sizeof(chip8_display)); rb->memset (chip8_display,0,sizeof(chip8_display));
break; break;
case 0xee: case 0xee:
chip8_regs.pc=read_mem(chip8_regs.sp)<<8; chip8_regs.pc=read_mem(chip8_regs.sp)<<8;
chip8_regs.sp++; chip8_regs.sp++;
chip8_regs.pc+=read_mem(chip8_regs.sp); chip8_regs.pc+=read_mem(chip8_regs.sp);
chip8_regs.sp++; chip8_regs.sp++;
break; break;
} }
} }
static void op_misc (word opcode) static void op_misc (word opcode)
{ {
byte *reg,i,j; byte *reg,i,j;
reg=get_reg_offset(opcode); reg=get_reg_offset(opcode);
switch ((byte)opcode) switch ((byte)opcode)
{ {
case 0x07: case 0x07:
*reg=chip8_regs.delay; *reg=chip8_regs.delay;
break; break;
case 0x0a: case 0x0a:
if (chip8_key_pressed) if (chip8_key_pressed)
*reg=chip8_key_pressed-1; *reg=chip8_key_pressed-1;
else else
chip8_regs.pc-=2; chip8_regs.pc-=2;
break; break;
case 0x15: case 0x15:
chip8_regs.delay=*reg; chip8_regs.delay=*reg;
break; break;
case 0x18: case 0x18:
chip8_regs.sound=*reg; chip8_regs.sound=*reg;
if (chip8_regs.sound) chip8_sound_on(); if (chip8_regs.sound)
break; chip8_sound_on();
case 0x1e: break;
chip8_regs.i+=(*reg); case 0x1e:
break; chip8_regs.i+=(*reg);
case 0x29: break;
chip8_regs.i=((word)(*reg&0x0f))*5; case 0x29:
break; chip8_regs.i=((word)(*reg&0x0f))*5;
case 0x33: break;
i=*reg; case 0x33:
for (j=0;i>=100;i-=100) j++; i=*reg;
write_mem (chip8_regs.i,j); for (j=0;i>=100;i-=100)
for (j=0;i>=10;i-=10) j++; j++;
write_mem (chip8_regs.i+1,j); write_mem (chip8_regs.i,j);
write_mem (chip8_regs.i+2,i); for (j=0;i>=10;i-=10)
break; j++;
case 0x55: write_mem (chip8_regs.i+1,j);
for (i=0,j=(opcode>>8)&0x0f;i<=j;++i) write_mem (chip8_regs.i+2,i);
write_mem(chip8_regs.i+i,chip8_regs.alg[i]); break;
break; case 0x55:
case 0x65: for (i=0,j=(opcode>>8)&0x0f; i<=j; ++i)
for (i=0,j=(opcode>>8)&0x0f;i<=j;++i) write_mem(chip8_regs.i+i,chip8_regs.alg[i]);
chip8_regs.alg[i]=read_mem(chip8_regs.i+i); break;
break; case 0x65:
} for (i=0,j=(opcode>>8)&0x0f; i<=j; ++i)
chip8_regs.alg[i]=read_mem(chip8_regs.i+i);
break;
}
} }
static void op_sprite (word opcode) static void op_sprite (word opcode)
{ {
byte *q; byte *q;
byte n,x,x2,y,collision; byte n,x,x2,y,collision;
word p; word p;
x=get_reg_value(opcode)&63; x=get_reg_value(opcode)&63;
y=get_reg_value_2(opcode)&31; y=get_reg_value_2(opcode)&31;
p=chip8_regs.i; p=chip8_regs.i;
q=chip8_display+y*64; q=chip8_display+y*64;
n=opcode&0x0f; n=opcode&0x0f;
if (n+y>32) n=32-y; if (n+y>32)
for (collision=1;n;--n,q+=64) n=32-y;
{ for (collision=1;n;--n,q+=64)
for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&63) {
if (y&0x80) collision&=(q[x2]^=0xff); for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&63)
} if (y&0x80) collision&=(q[x2]^=0xff);
chip8_regs.alg[15]=collision^1; }
chip8_regs.alg[15]=collision^1;
} }
static math_fn math_opcodes[16]= static math_fn math_opcodes[16]=
{ {
math_mov, math_mov,
math_or, math_or,
math_and, math_and,
math_xor, math_xor,
math_add, math_add,
math_sub, math_sub,
math_shr, math_shr,
math_rsb, math_rsb,
math_nop, math_nop,
math_nop, math_nop,
math_nop, math_nop,
math_nop, math_nop,
math_nop, math_nop,
math_nop, math_nop,
math_shl, math_shl,
math_nop math_nop
}; };
static void op_math (word opcode) static void op_math (word opcode)
{ {
(*(math_opcodes[opcode&0x0f])) (*(math_opcodes[opcode&0x0f]))
(get_reg_offset(opcode),get_reg_value_2(opcode)); (get_reg_offset(opcode),get_reg_value_2(opcode));
} }
static opcode_fn main_opcodes[16]= static opcode_fn main_opcodes[16]=
{ {
op_system, op_system,
op_jmp, op_jmp,
op_call, op_call,
op_skeq_const, op_skeq_const,
op_skne_const, op_skne_const,
op_skeq_reg, op_skeq_reg,
op_mov_const, op_mov_const,
op_add_const, op_add_const,
op_math, op_math,
op_skne_reg, op_skne_reg,
op_mvi, op_mvi,
op_jmi, op_jmi,
op_rand, op_rand,
op_sprite, op_sprite,
op_key, op_key,
op_misc op_misc
}; };
/****************************************************************************/ /****************************************************************************/
@ -341,37 +349,36 @@ static opcode_fn main_opcodes[16]=
/****************************************************************************/ /****************************************************************************/
static void chip8_update_display(void) static void chip8_update_display(void)
{ {
int x,y,i; int x,y,i;
byte w; byte w;
byte* row; byte* row;
for (y=0;y<=7;++y) /* 32 rows */ for (y=0;y<=7;++y) /* 32 rows */
{
row = lcd_framebuf[y];
for (x=0;x<64;++x) /* 64 columns */
{
w = 0;
for (i=0;i<=3;i++)
{ {
w = w >> 2; row = lcd_framebuf[y];
if (chip8_display[x+(y*4+i)*64] != 0) for (x=0;x<64;++x) /* 64 columns */
{ {
w += 128+64; w = 0;
} for (i=0;i<=3;i++)
{
w = w >> 2;
if (chip8_display[x+(y*4+i)*64] != 0)
{
w += 128+64;
}
}
*row++ = w;
}
} }
*row++ = w; rb->lcd_blit(lcd_framebuf[0], 24, 0, 64, 8, 64);
}
}
rb->lcd_blit(lcd_framebuf[0], 24, 0, 64, 8, 64);
} }
static void chip8_keyboard(void) static void chip8_keyboard(void)
{ {
switch (rb->button_get(false)) switch (rb->button_get(false))
{ {
case BUTTON_OFF: /* Abort Emulator */ case BUTTON_OFF: /* Abort Emulator */
chip8_running = false; chip8_running = false;
break; break;
case BUTTON_UP: chip8_keys[2] = 1; break; case BUTTON_UP: chip8_keys[2] = 1; break;
@ -408,30 +415,34 @@ static void chip8_keyboard(void)
/****************************************************************************/ /****************************************************************************/
static void chip8_execute(void) static void chip8_execute(void)
{ {
byte i; byte i;
byte key_pressed=0; byte key_pressed=0;
word opcode; word opcode;
for (i = chip8_iperiod ; i ;--i) for (i = chip8_iperiod ; i ;--i)
{ /* Fetch the opcode */ { /* Fetch the opcode */
opcode=(read_mem(chip8_regs.pc)<<8)+read_mem(chip8_regs.pc+1); opcode=(read_mem(chip8_regs.pc)<<8)+read_mem(chip8_regs.pc+1);
chip8_regs.pc+=2; chip8_regs.pc+=2;
(*(main_opcodes[opcode>>12]))(opcode&0x0fff); /* Emulate this opcode */ (*(main_opcodes[opcode>>12]))(opcode&0x0fff); /* Emulate this opcode */
} }
/* Update timers */ /* Update timers */
if (chip8_regs.delay) --chip8_regs.delay; if (chip8_regs.delay)
if (chip8_regs.sound) --chip8_regs.sound; /* How could we make sound on the archos? */ --chip8_regs.delay;
if (chip8_regs.sound)
--chip8_regs.sound; /* How could we make sound on the archos? */
/* Update the machine status */ /* Update the machine status */
chip8_update_display(); chip8_update_display();
chip8_keyboard(); chip8_keyboard();
rb->yield(); /* we should regulate the speed by timer query, sleep/yield */ rb->yield(); /* we should regulate the speed by timer query, sleep/yield */
for (i=key_pressed=0;i<16;++i) /* check if a key was first */ for (i=key_pressed=0;i<16;++i) /* check if a key was first */
if (chip8_keys[i]) key_pressed=i+1; /* pressed */ if (chip8_keys[i])
if (key_pressed && key_pressed!=chip8_key_pressed) key_pressed=i+1; /* pressed */
chip8_key_pressed=key_pressed; if (key_pressed && key_pressed!=chip8_key_pressed)
else chip8_key_pressed=key_pressed;
chip8_key_pressed=0; else
chip8_key_pressed=0;
} }
/****************************************************************************/ /****************************************************************************/
@ -439,32 +450,32 @@ static void chip8_execute(void)
/****************************************************************************/ /****************************************************************************/
static void chip8_reset(void) static void chip8_reset(void)
{ {
static byte chip8_sprites[16*5]= static byte chip8_sprites[16*5]=
{ {
0xf9,0x99,0xf2,0x62,0x27, 0xf9,0x99,0xf2,0x62,0x27,
0xf1,0xf8,0xff,0x1f,0x1f, 0xf1,0xf8,0xff,0x1f,0x1f,
0x99,0xf1,0x1f,0x8f,0x1f, 0x99,0xf1,0x1f,0x8f,0x1f,
0xf8,0xf9,0xff,0x12,0x44, 0xf8,0xf9,0xff,0x12,0x44,
0xf9,0xf9,0xff,0x9f,0x1f, 0xf9,0xf9,0xff,0x9f,0x1f,
0xf9,0xf9,0x9e,0x9e,0x9e, 0xf9,0xf9,0x9e,0x9e,0x9e,
0xf8,0x88,0xfe,0x99,0x9e, 0xf8,0x88,0xfe,0x99,0x9e,
0xf8,0xf8,0xff,0x8f,0x88, 0xf8,0xf8,0xff,0x8f,0x88,
}; };
byte i; byte i;
for (i=0;i<16*5;++i) for (i=0;i<16*5;++i)
{ {
write_mem (i<<1,chip8_sprites[i]&0xf0); write_mem (i<<1,chip8_sprites[i]&0xf0);
write_mem ((i<<1)+1,chip8_sprites[i]<<4); write_mem ((i<<1)+1,chip8_sprites[i]<<4);
} }
rb->memset (chip8_regs.alg,0,sizeof(chip8_regs.alg)); rb->memset (chip8_regs.alg,0,sizeof(chip8_regs.alg));
rb->memset (chip8_keys,0,sizeof(chip8_keys)); rb->memset (chip8_keys,0,sizeof(chip8_keys));
chip8_key_pressed=0; chip8_key_pressed=0;
rb->memset (chip8_display,0,sizeof(chip8_display)); rb->memset (chip8_display,0,sizeof(chip8_display));
chip8_regs.delay=chip8_regs.sound=chip8_regs.i=0; chip8_regs.delay=chip8_regs.sound=chip8_regs.i=0;
chip8_regs.sp=0x1e0; chip8_regs.sp=0x1e0;
chip8_regs.pc=0x200; chip8_regs.pc=0x200;
chip8_sound_off (); chip8_sound_off ();
chip8_running=1; chip8_running=1;
} }
static bool chip8_init(char* file) static bool chip8_init(char* file)
@ -541,5 +552,4 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
return chip8_run(filename) ? PLUGIN_OK : PLUGIN_ERROR; return chip8_run(filename) ? PLUGIN_OK : PLUGIN_ERROR;
} }
#endif // #ifdef HAVE_LCD_BITMAP #endif /* #ifdef HAVE_LCD_BITMAP */
#endif // #ifndef SIMULATOR