comparison src/cpu.c @ 25:fb14515266f4

Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
author Michael Pavone <pavone@retrodev.com>
date Thu, 31 Mar 2016 23:25:52 -0700
parents a9364f5ee81a
children 083347ccd508
comparison
equal deleted inserted replaced
24:4c9dbfa30a66 25:fb14515266f4
266 context->regs[dst] = context->exception; 266 context->regs[dst] = context->exception;
267 break; 267 break;
268 case SETENUM: 268 case SETENUM:
269 context->exception = context->regs[dst]; 269 context->exception = context->regs[dst];
270 break; 270 break;
271 case GETVBR:
272 context->regs[dst] = context->vector_base;
273 break;
274 case SETVBR:
275 context->vector_base = context->regs[dst];
276 break;
271 default: 277 default:
272 context->state = STATE_EXCEPTION_START; 278 context->state = STATE_EXCEPTION_START;
273 context->exception = EXCEPTION_INVALID_INSTRUCTION; 279 context->exception = EXCEPTION_INVALID_INSTRUCTION;
274 return; 280 return;
275 } 281 }
367 } 373 }
368 if (dst == REG_PC) { 374 if (dst == REG_PC) {
369 context->state = STATE_NEED_FETCH; 375 context->state = STATE_NEED_FETCH;
370 } 376 }
371 } 377 }
372
373 char * mnemonics[] = {
374 "ldim", "ldimh", "ld8", "ld16", "str8", "str16", "add", "adc", "and", "or", "xor", "lsl", "lsr", "asr", "bcc", "single"
375 };
376
377 char * mnemonics_single_src[] = {
378 "mov", "neg", "not", "cmp", "call", "swap", "in", "out", "ini", "outi", "addi", "andi", "ori", "lsi", "cmpi", "single reg"
379 };
380
381 char * mnemonics_single_reg[] = {
382 "reti", "trap", "trapi", "getepc", "setepc", "getesr", "setesr", "getenum", "setenum", "setuer", "getuer"
383 };
384 378
385 void run_instruction(cpu *context) 379 void run_instruction(cpu *context)
386 { 380 {
387 uint16_t instruction = context->prefetch; 381 uint16_t instruction = context->prefetch;
388 fetch_instruction(context); 382 fetch_instruction(context);
469 463
470 void run_cpu(cpu *context, uint32_t target_cycle) 464 void run_cpu(cpu *context, uint32_t target_cycle)
471 { 465 {
472 while (context->cycles < target_cycle) 466 while (context->cycles < target_cycle)
473 { 467 {
474 switch (context->state) 468 context->current_target = target_cycle;
469 context->pending_interrupts = get_current_interrupts(context);
470 uint32_t int_cycle = next_interrupt_cycle(context, (~context->pending_interrupts) & 0x3);
471 if (int_cycle < context->current_target) {
472 context->current_target = int_cycle;
473 }
474 while (context->cycles < context->current_target)
475 { 475 {
476 case STATE_NEED_FETCH: 476 switch (context->state)
477 fetch_instruction(context); 477 {
478 break; 478 case STATE_NEED_FETCH:
479 case STATE_NORMAL: 479 fetch_instruction(context);
480 run_instruction(context); 480 break;
481 break; 481 case STATE_NORMAL:
482 case STATE_EXCEPTION_START: 482 if (context->regs[REG_SR] & context->pending_interrupts) {
483 vector_fetch(context); 483 context->state = STATE_EXCEPTION_START;
484 break; 484 context->exception = context->pending_interrupts & 1 ? EXCEPTION_INTERRUPT_0 : EXCEPTION_INTERRUPT_1;
485 } 485 context->pending_interrupts &= ~(1 << context->exception);
486 } 486 ack_interrupt(context, context->exception);
487 } 487 } else {
488 run_instruction(context);
489 }
490 break;
491 case STATE_EXCEPTION_START:
492 vector_fetch(context);
493 break;
494 }
495 }
496 }
497 }