Mercurial > repos > simple16
diff 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 |
line wrap: on
line diff
--- a/src/cpu.c Thu Mar 31 00:07:37 2016 -0700 +++ b/src/cpu.c Thu Mar 31 23:25:52 2016 -0700 @@ -268,6 +268,12 @@ case SETENUM: context->exception = context->regs[dst]; break; + case GETVBR: + context->regs[dst] = context->vector_base; + break; + case SETVBR: + context->vector_base = context->regs[dst]; + break; default: context->state = STATE_EXCEPTION_START; context->exception = EXCEPTION_INVALID_INSTRUCTION; @@ -370,18 +376,6 @@ } } -char * mnemonics[] = { - "ldim", "ldimh", "ld8", "ld16", "str8", "str16", "add", "adc", "and", "or", "xor", "lsl", "lsr", "asr", "bcc", "single" -}; - -char * mnemonics_single_src[] = { - "mov", "neg", "not", "cmp", "call", "swap", "in", "out", "ini", "outi", "addi", "andi", "ori", "lsi", "cmpi", "single reg" -}; - -char * mnemonics_single_reg[] = { - "reti", "trap", "trapi", "getepc", "setepc", "getesr", "setesr", "getenum", "setenum", "setuer", "getuer" -}; - void run_instruction(cpu *context) { uint16_t instruction = context->prefetch; @@ -471,17 +465,33 @@ { while (context->cycles < target_cycle) { - switch (context->state) + context->current_target = target_cycle; + context->pending_interrupts = get_current_interrupts(context); + uint32_t int_cycle = next_interrupt_cycle(context, (~context->pending_interrupts) & 0x3); + if (int_cycle < context->current_target) { + context->current_target = int_cycle; + } + while (context->cycles < context->current_target) { - case STATE_NEED_FETCH: - fetch_instruction(context); - break; - case STATE_NORMAL: - run_instruction(context); - break; - case STATE_EXCEPTION_START: - vector_fetch(context); - break; + switch (context->state) + { + case STATE_NEED_FETCH: + fetch_instruction(context); + break; + case STATE_NORMAL: + if (context->regs[REG_SR] & context->pending_interrupts) { + context->state = STATE_EXCEPTION_START; + context->exception = context->pending_interrupts & 1 ? EXCEPTION_INTERRUPT_0 : EXCEPTION_INTERRUPT_1; + context->pending_interrupts &= ~(1 << context->exception); + ack_interrupt(context, context->exception); + } else { + run_instruction(context); + } + break; + case STATE_EXCEPTION_START: + vector_fetch(context); + break; + } } } } \ No newline at end of file