summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2004-01-08 13:03:04 +0000
committerDaniel Stenberg <daniel@haxx.se>2004-01-08 13:03:04 +0000
commitaac303e17bf0a0429095a5168a1ecb77a89f4c41 (patch)
tree7b5b4e1bf7371c3d722edfbe42bf35a711fae16b /apps/plugins
parent0f68958b11bfc0c23027666e85c4d0ff99d6bef1 (diff)
downloadrockbox-aac303e17bf0a0429095a5168a1ecb77a89f4c41.tar.gz
rockbox-aac303e17bf0a0429095a5168a1ecb77a89f4c41.zip
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
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/chip8.c454
1 files changed, 232 insertions, 222 deletions
diff --git a/apps/plugins/chip8.c b/apps/plugins/chip8.c
index 585295c405..d19e03d762 100644
--- a/apps/plugins/chip8.c
+++ b/apps/plugins/chip8.c
@@ -20,7 +20,6 @@
20#include "plugin.h" 20#include "plugin.h"
21 21
22/* Only build for (correct) target */ 22/* Only build for (correct) target */
23#ifndef SIMULATOR
24#ifdef HAVE_LCD_BITMAP 23#ifdef HAVE_LCD_BITMAP
25 24
26static struct plugin_api* rb; /* here is a global api struct pointer */ 25static struct plugin_api* rb; /* here is a global api struct pointer */
@@ -74,95 +73,100 @@ static void chip8_sound_off (void) { }
74 73
75static void op_call (word opcode) 74static void op_call (word opcode)
76{ 75{
77 chip8_regs.sp--; 76 chip8_regs.sp--;
78 write_mem (chip8_regs.sp,chip8_regs.pc&0xff); 77 write_mem (chip8_regs.sp,chip8_regs.pc&0xff);
79 chip8_regs.sp--; 78 chip8_regs.sp--;
80 write_mem (chip8_regs.sp,chip8_regs.pc>>8); 79 write_mem (chip8_regs.sp,chip8_regs.pc>>8);
81 chip8_regs.pc=opcode; 80 chip8_regs.pc=opcode;
82} 81}
83 82
84static void op_jmp (word opcode) 83static void op_jmp (word opcode)
85{ 84{
86 chip8_regs.pc=opcode; 85 chip8_regs.pc=opcode;
87} 86}
88 87
89static void op_key (word opcode) 88static void op_key (word opcode)
90{ 89{
91 byte key_value,cp_value; 90 byte key_value,cp_value;
92 if ((opcode&0xff)==0x9e) 91 if ((opcode&0xff)==0x9e)
93 cp_value=1; 92 cp_value=1;
94 else if ((opcode&0xff)==0xa1) 93 else if ((opcode&0xff)==0xa1)
95 cp_value=0; 94 cp_value=0;
96 else 95 else
97 return; 96 return;
98 key_value=chip8_keys[get_reg_value(opcode)&0x0f]; 97 key_value=chip8_keys[get_reg_value(opcode)&0x0f];
99 if (cp_value==key_value) chip8_regs.pc+=2; 98 if (cp_value==key_value)
99 chip8_regs.pc+=2;
100} 100}
101 101
102static void op_skeq_const (word opcode) 102static void op_skeq_const (word opcode)
103{ 103{
104 if (get_reg_value(opcode)==(opcode&0xff)) chip8_regs.pc+=2; 104 if (get_reg_value(opcode)==(opcode&0xff))
105 chip8_regs.pc+=2;
105} 106}
106 107
107static void op_skne_const (word opcode) 108static void op_skne_const (word opcode)
108{ 109{
109 if (get_reg_value(opcode)!=(opcode&0xff)) chip8_regs.pc+=2; 110 if (get_reg_value(opcode)!=(opcode&0xff))
111 chip8_regs.pc+=2;
110} 112}
111 113
112static void op_skeq_reg (word opcode) 114static void op_skeq_reg (word opcode)
113{ 115{
114 if (get_reg_value(opcode)==get_reg_value_2(opcode)) chip8_regs.pc+=2; 116 if (get_reg_value(opcode)==get_reg_value_2(opcode))
117 chip8_regs.pc+=2;
115} 118}
116 119
117static void op_skne_reg (word opcode) 120static void op_skne_reg (word opcode)
118{ 121{
119 if (get_reg_value(opcode)!=get_reg_value_2(opcode)) chip8_regs.pc+=2; 122 if (get_reg_value(opcode)!=get_reg_value_2(opcode))
123 chip8_regs.pc+=2;
120} 124}
121 125
122static void op_mov_const (word opcode) 126static void op_mov_const (word opcode)
123{ 127{
124 *get_reg_offset(opcode)=opcode&0xff; 128 *get_reg_offset(opcode)=opcode&0xff;
125} 129}
126 130
127static void op_add_const (word opcode) 131static void op_add_const (word opcode)
128{ 132{
129 *get_reg_offset(opcode)+=opcode&0xff; 133 *get_reg_offset(opcode)+=opcode&0xff;
130} 134}
131 135
132static void op_mvi (word opcode) 136static void op_mvi (word opcode)
133{ 137{
134 chip8_regs.i=opcode; 138 chip8_regs.i=opcode;
135} 139}
136 140
137static void op_jmi (word opcode) 141static void op_jmi (word opcode)
138{ 142{
139 chip8_regs.pc=opcode+chip8_regs.alg[0]; 143 chip8_regs.pc=opcode+chip8_regs.alg[0];
140} 144}
141 145
142static void op_rand (word opcode) 146static void op_rand (word opcode)
143{ 147{
144 *get_reg_offset(opcode)=rb->rand()&(opcode&0xff); 148 *get_reg_offset(opcode)=rb->rand()&(opcode&0xff);
145} 149}
146 150
147static void math_or (byte *reg1,byte reg2) 151static void math_or (byte *reg1,byte reg2)
148{ 152{
149 *reg1|=reg2; 153 *reg1|=reg2;
150} 154}
151 155
152static void math_mov (byte *reg1,byte reg2) 156static void math_mov (byte *reg1,byte reg2)
153{ 157{
154 *reg1=reg2; 158 *reg1=reg2;
155} 159}
156 160
157static void math_nop (byte *reg1,byte reg2) 161static void math_nop (byte *reg1,byte reg2)
158{ 162{
159 (void)reg1; 163 (void)reg1;
160 (void)reg2; 164 (void)reg2;
161} 165}
162 166
163static void math_and (byte *reg1,byte reg2) 167static void math_and (byte *reg1,byte reg2)
164{ 168{
165 *reg1&=reg2; 169 *reg1&=reg2;
166} 170}
167 171
168static void math_xor (byte *reg1,byte reg2) 172static void math_xor (byte *reg1,byte reg2)
@@ -172,168 +176,172 @@ static void math_xor (byte *reg1,byte reg2)
172 176
173static void math_add (byte *reg1,byte reg2) 177static void math_add (byte *reg1,byte reg2)
174{ 178{
175 word tmp; 179 word tmp;
176 tmp=*reg1+reg2; 180 tmp=*reg1+reg2;
177 *reg1=(byte)tmp; 181 *reg1=(byte)tmp;
178 chip8_regs.alg[15]=tmp>>8; 182 chip8_regs.alg[15]=tmp>>8;
179} 183}
180 184
181static void math_sub (byte *reg1,byte reg2) 185static void math_sub (byte *reg1,byte reg2)
182{ 186{
183 word tmp; 187 word tmp;
184 tmp=*reg1-reg2; 188 tmp=*reg1-reg2;
185 *reg1=(byte)tmp; 189 *reg1=(byte)tmp;
186 chip8_regs.alg[15]=((byte)(tmp>>8))+1; 190 chip8_regs.alg[15]=((byte)(tmp>>8))+1;
187} 191}
188 192
189static void math_shr (byte *reg1,byte reg2) 193static void math_shr (byte *reg1,byte reg2)
190{ 194{
191 (void)reg2; 195 (void)reg2;
192 chip8_regs.alg[15]=*reg1&1; 196 chip8_regs.alg[15]=*reg1&1;
193 *reg1>>=1; 197 *reg1>>=1;
194} 198}
195 199
196static void math_shl (byte *reg1,byte reg2) 200static void math_shl (byte *reg1,byte reg2)
197{ 201{
198 (void)reg2; 202 (void)reg2;
199 chip8_regs.alg[15]=*reg1>>7; 203 chip8_regs.alg[15]=*reg1>>7;
200 *reg1<<=1; 204 *reg1<<=1;
201} 205}
202 206
203static void math_rsb (byte *reg1,byte reg2) 207static void math_rsb (byte *reg1,byte reg2)
204{ 208{
205 word tmp; 209 word tmp;
206 tmp=reg2-*reg1; 210 tmp=reg2-*reg1;
207 *reg1=(byte)tmp; 211 *reg1=(byte)tmp;
208 chip8_regs.alg[15]=((byte)(tmp>>8))+1; 212 chip8_regs.alg[15]=((byte)(tmp>>8))+1;
209} 213}
210 214
211static void op_system (word opcode) 215static void op_system (word opcode)
212{ 216{
213 switch ((byte)opcode) 217 switch ((byte)opcode)
214 { 218 {
215 case 0xe0: 219 case 0xe0:
216 rb->memset (chip8_display,0,sizeof(chip8_display)); 220 rb->memset (chip8_display,0,sizeof(chip8_display));
217 break; 221 break;
218 case 0xee: 222 case 0xee:
219 chip8_regs.pc=read_mem(chip8_regs.sp)<<8; 223 chip8_regs.pc=read_mem(chip8_regs.sp)<<8;
220 chip8_regs.sp++; 224 chip8_regs.sp++;
221 chip8_regs.pc+=read_mem(chip8_regs.sp); 225 chip8_regs.pc+=read_mem(chip8_regs.sp);
222 chip8_regs.sp++; 226 chip8_regs.sp++;
223 break; 227 break;
224 } 228 }
225} 229}
226 230
227static void op_misc (word opcode) 231static void op_misc (word opcode)
228{ 232{
229 byte *reg,i,j; 233 byte *reg,i,j;
230 reg=get_reg_offset(opcode); 234 reg=get_reg_offset(opcode);
231 switch ((byte)opcode) 235 switch ((byte)opcode)
232 { 236 {
233 case 0x07: 237 case 0x07:
234 *reg=chip8_regs.delay; 238 *reg=chip8_regs.delay;
235 break; 239 break;
236 case 0x0a: 240 case 0x0a:
237 if (chip8_key_pressed) 241 if (chip8_key_pressed)
238 *reg=chip8_key_pressed-1; 242 *reg=chip8_key_pressed-1;
239 else 243 else
240 chip8_regs.pc-=2; 244 chip8_regs.pc-=2;
241 break; 245 break;
242 case 0x15: 246 case 0x15:
243 chip8_regs.delay=*reg; 247 chip8_regs.delay=*reg;
244 break; 248 break;
245 case 0x18: 249 case 0x18:
246 chip8_regs.sound=*reg; 250 chip8_regs.sound=*reg;
247 if (chip8_regs.sound) chip8_sound_on(); 251 if (chip8_regs.sound)
248 break; 252 chip8_sound_on();
249 case 0x1e: 253 break;
250 chip8_regs.i+=(*reg); 254 case 0x1e:
251 break; 255 chip8_regs.i+=(*reg);
252 case 0x29: 256 break;
253 chip8_regs.i=((word)(*reg&0x0f))*5; 257 case 0x29:
254 break; 258 chip8_regs.i=((word)(*reg&0x0f))*5;
255 case 0x33: 259 break;
256 i=*reg; 260 case 0x33:
257 for (j=0;i>=100;i-=100) j++; 261 i=*reg;
258 write_mem (chip8_regs.i,j); 262 for (j=0;i>=100;i-=100)
259 for (j=0;i>=10;i-=10) j++; 263 j++;
260 write_mem (chip8_regs.i+1,j); 264 write_mem (chip8_regs.i,j);
261 write_mem (chip8_regs.i+2,i); 265 for (j=0;i>=10;i-=10)
262 break; 266 j++;
263 case 0x55: 267 write_mem (chip8_regs.i+1,j);
264 for (i=0,j=(opcode>>8)&0x0f;i<=j;++i) 268 write_mem (chip8_regs.i+2,i);
265 write_mem(chip8_regs.i+i,chip8_regs.alg[i]); 269 break;
266 break; 270 case 0x55:
267 case 0x65: 271 for (i=0,j=(opcode>>8)&0x0f; i<=j; ++i)
268 for (i=0,j=(opcode>>8)&0x0f;i<=j;++i) 272 write_mem(chip8_regs.i+i,chip8_regs.alg[i]);
269 chip8_regs.alg[i]=read_mem(chip8_regs.i+i); 273 break;
270 break; 274 case 0x65:
271 } 275 for (i=0,j=(opcode>>8)&0x0f; i<=j; ++i)
276 chip8_regs.alg[i]=read_mem(chip8_regs.i+i);
277 break;
278 }
272} 279}
273 280
274static void op_sprite (word opcode) 281static void op_sprite (word opcode)
275{ 282{
276 byte *q; 283 byte *q;
277 byte n,x,x2,y,collision; 284 byte n,x,x2,y,collision;
278 word p; 285 word p;
279 x=get_reg_value(opcode)&63; 286 x=get_reg_value(opcode)&63;
280 y=get_reg_value_2(opcode)&31; 287 y=get_reg_value_2(opcode)&31;
281 p=chip8_regs.i; 288 p=chip8_regs.i;
282 q=chip8_display+y*64; 289 q=chip8_display+y*64;
283 n=opcode&0x0f; 290 n=opcode&0x0f;
284 if (n+y>32) n=32-y; 291 if (n+y>32)
285 for (collision=1;n;--n,q+=64) 292 n=32-y;
286 { 293 for (collision=1;n;--n,q+=64)
287 for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&63) 294 {
288 if (y&0x80) collision&=(q[x2]^=0xff); 295 for (y=read_mem(p++),x2=x;y;y<<=1,x2=(x2+1)&63)
289 } 296 if (y&0x80) collision&=(q[x2]^=0xff);
290 chip8_regs.alg[15]=collision^1; 297 }
298 chip8_regs.alg[15]=collision^1;
291} 299}
292 300
293static math_fn math_opcodes[16]= 301static math_fn math_opcodes[16]=
294{ 302{
295 math_mov, 303 math_mov,
296 math_or, 304 math_or,
297 math_and, 305 math_and,
298 math_xor, 306 math_xor,
299 math_add, 307 math_add,
300 math_sub, 308 math_sub,
301 math_shr, 309 math_shr,
302 math_rsb, 310 math_rsb,
303 math_nop, 311 math_nop,
304 math_nop, 312 math_nop,
305 math_nop, 313 math_nop,
306 math_nop, 314 math_nop,
307 math_nop, 315 math_nop,
308 math_nop, 316 math_nop,
309 math_shl, 317 math_shl,
310 math_nop 318 math_nop
311}; 319};
312 320
313static void op_math (word opcode) 321static void op_math (word opcode)
314{ 322{
315 (*(math_opcodes[opcode&0x0f])) 323 (*(math_opcodes[opcode&0x0f]))
316 (get_reg_offset(opcode),get_reg_value_2(opcode)); 324 (get_reg_offset(opcode),get_reg_value_2(opcode));
317} 325}
318 326
319static opcode_fn main_opcodes[16]= 327static opcode_fn main_opcodes[16]=
320{ 328{
321 op_system, 329 op_system,
322 op_jmp, 330 op_jmp,
323 op_call, 331 op_call,
324 op_skeq_const, 332 op_skeq_const,
325 op_skne_const, 333 op_skne_const,
326 op_skeq_reg, 334 op_skeq_reg,
327 op_mov_const, 335 op_mov_const,
328 op_add_const, 336 op_add_const,
329 op_math, 337 op_math,
330 op_skne_reg, 338 op_skne_reg,
331 op_mvi, 339 op_mvi,
332 op_jmi, 340 op_jmi,
333 op_rand, 341 op_rand,
334 op_sprite, 342 op_sprite,
335 op_key, 343 op_key,
336 op_misc 344 op_misc
337}; 345};
338 346
339/****************************************************************************/ 347/****************************************************************************/
@@ -341,37 +349,36 @@ static opcode_fn main_opcodes[16]=
341/****************************************************************************/ 349/****************************************************************************/
342static void chip8_update_display(void) 350static void chip8_update_display(void)
343{ 351{
344 int x,y,i; 352 int x,y,i;
345 byte w; 353 byte w;
346 byte* row; 354 byte* row;
347 355
348 for (y=0;y<=7;++y) /* 32 rows */ 356 for (y=0;y<=7;++y) /* 32 rows */
349 {
350 row = lcd_framebuf[y];
351 for (x=0;x<64;++x) /* 64 columns */
352 {
353 w = 0;
354 for (i=0;i<=3;i++)
355 { 357 {
356 w = w >> 2; 358 row = lcd_framebuf[y];
357 if (chip8_display[x+(y*4+i)*64] != 0) 359 for (x=0;x<64;++x) /* 64 columns */
358 { 360 {
359 w += 128+64; 361 w = 0;
360 } 362 for (i=0;i<=3;i++)
363 {
364 w = w >> 2;
365 if (chip8_display[x+(y*4+i)*64] != 0)
366 {
367 w += 128+64;
368 }
369 }
370 *row++ = w;
371 }
361 } 372 }
362 *row++ = w; 373 rb->lcd_blit(lcd_framebuf[0], 24, 0, 64, 8, 64);
363 }
364 }
365 rb->lcd_blit(lcd_framebuf[0], 24, 0, 64, 8, 64);
366} 374}
367 375
368
369static void chip8_keyboard(void) 376static void chip8_keyboard(void)
370{ 377{
371 switch (rb->button_get(false)) 378 switch (rb->button_get(false))
372 { 379 {
373 case BUTTON_OFF: /* Abort Emulator */ 380 case BUTTON_OFF: /* Abort Emulator */
374 chip8_running = false; 381 chip8_running = false;
375 break; 382 break;
376 383
377 case BUTTON_UP: chip8_keys[2] = 1; break; 384 case BUTTON_UP: chip8_keys[2] = 1; break;
@@ -408,30 +415,34 @@ static void chip8_keyboard(void)
408/****************************************************************************/ 415/****************************************************************************/
409static void chip8_execute(void) 416static void chip8_execute(void)
410{ 417{
411 byte i; 418 byte i;
412 byte key_pressed=0; 419 byte key_pressed=0;
413 word opcode; 420 word opcode;
414 for (i = chip8_iperiod ; i ;--i) 421 for (i = chip8_iperiod ; i ;--i)
415 { /* Fetch the opcode */ 422 { /* Fetch the opcode */
416 opcode=(read_mem(chip8_regs.pc)<<8)+read_mem(chip8_regs.pc+1); 423 opcode=(read_mem(chip8_regs.pc)<<8)+read_mem(chip8_regs.pc+1);
417 424
418 chip8_regs.pc+=2; 425 chip8_regs.pc+=2;
419 (*(main_opcodes[opcode>>12]))(opcode&0x0fff); /* Emulate this opcode */ 426 (*(main_opcodes[opcode>>12]))(opcode&0x0fff); /* Emulate this opcode */
420 } 427 }
421 /* Update timers */ 428 /* Update timers */
422 if (chip8_regs.delay) --chip8_regs.delay; 429 if (chip8_regs.delay)
423 if (chip8_regs.sound) --chip8_regs.sound; /* How could we make sound on the archos? */ 430 --chip8_regs.delay;
431
432 if (chip8_regs.sound)
433 --chip8_regs.sound; /* How could we make sound on the archos? */
424 /* Update the machine status */ 434 /* Update the machine status */
425 chip8_update_display(); 435 chip8_update_display();
426 chip8_keyboard(); 436 chip8_keyboard();
427 rb->yield(); /* we should regulate the speed by timer query, sleep/yield */ 437 rb->yield(); /* we should regulate the speed by timer query, sleep/yield */
428 438
429 for (i=key_pressed=0;i<16;++i) /* check if a key was first */ 439 for (i=key_pressed=0;i<16;++i) /* check if a key was first */
430 if (chip8_keys[i]) key_pressed=i+1; /* pressed */ 440 if (chip8_keys[i])
431 if (key_pressed && key_pressed!=chip8_key_pressed) 441 key_pressed=i+1; /* pressed */
432 chip8_key_pressed=key_pressed; 442 if (key_pressed && key_pressed!=chip8_key_pressed)
433 else 443 chip8_key_pressed=key_pressed;
434 chip8_key_pressed=0; 444 else
445 chip8_key_pressed=0;
435} 446}
436 447
437/****************************************************************************/ 448/****************************************************************************/
@@ -439,32 +450,32 @@ static void chip8_execute(void)
439/****************************************************************************/ 450/****************************************************************************/
440static void chip8_reset(void) 451static void chip8_reset(void)
441{ 452{
442 static byte chip8_sprites[16*5]= 453 static byte chip8_sprites[16*5]=
443 { 454 {
444 0xf9,0x99,0xf2,0x62,0x27, 455 0xf9,0x99,0xf2,0x62,0x27,
445 0xf1,0xf8,0xff,0x1f,0x1f, 456 0xf1,0xf8,0xff,0x1f,0x1f,
446 0x99,0xf1,0x1f,0x8f,0x1f, 457 0x99,0xf1,0x1f,0x8f,0x1f,
447 0xf8,0xf9,0xff,0x12,0x44, 458 0xf8,0xf9,0xff,0x12,0x44,
448 0xf9,0xf9,0xff,0x9f,0x1f, 459 0xf9,0xf9,0xff,0x9f,0x1f,
449 0xf9,0xf9,0x9e,0x9e,0x9e, 460 0xf9,0xf9,0x9e,0x9e,0x9e,
450 0xf8,0x88,0xfe,0x99,0x9e, 461 0xf8,0x88,0xfe,0x99,0x9e,
451 0xf8,0xf8,0xff,0x8f,0x88, 462 0xf8,0xf8,0xff,0x8f,0x88,
452 }; 463 };
453 byte i; 464 byte i;
454 for (i=0;i<16*5;++i) 465 for (i=0;i<16*5;++i)
455 { 466 {
456 write_mem (i<<1,chip8_sprites[i]&0xf0); 467 write_mem (i<<1,chip8_sprites[i]&0xf0);
457 write_mem ((i<<1)+1,chip8_sprites[i]<<4); 468 write_mem ((i<<1)+1,chip8_sprites[i]<<4);
458 } 469 }
459 rb->memset (chip8_regs.alg,0,sizeof(chip8_regs.alg)); 470 rb->memset (chip8_regs.alg,0,sizeof(chip8_regs.alg));
460 rb->memset (chip8_keys,0,sizeof(chip8_keys)); 471 rb->memset (chip8_keys,0,sizeof(chip8_keys));
461 chip8_key_pressed=0; 472 chip8_key_pressed=0;
462 rb->memset (chip8_display,0,sizeof(chip8_display)); 473 rb->memset (chip8_display,0,sizeof(chip8_display));
463 chip8_regs.delay=chip8_regs.sound=chip8_regs.i=0; 474 chip8_regs.delay=chip8_regs.sound=chip8_regs.i=0;
464 chip8_regs.sp=0x1e0; 475 chip8_regs.sp=0x1e0;
465 chip8_regs.pc=0x200; 476 chip8_regs.pc=0x200;
466 chip8_sound_off (); 477 chip8_sound_off ();
467 chip8_running=1; 478 chip8_running=1;
468} 479}
469 480
470static bool chip8_init(char* file) 481static bool chip8_init(char* file)
@@ -541,5 +552,4 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
541 return chip8_run(filename) ? PLUGIN_OK : PLUGIN_ERROR; 552 return chip8_run(filename) ? PLUGIN_OK : PLUGIN_ERROR;
542} 553}
543 554
544#endif // #ifdef HAVE_LCD_BITMAP 555#endif /* #ifdef HAVE_LCD_BITMAP */
545#endif // #ifndef SIMULATOR