Mercurial > repos > simple16
diff src/cpu.c @ 43:6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 27 Aug 2016 22:38:31 -0700 |
parents | 5683d9ba9acc |
children | 51672bd41cdd |
line wrap: on
line diff
--- a/src/cpu.c Mon Apr 11 23:35:51 2016 -0700 +++ b/src/cpu.c Sat Aug 27 22:38:31 2016 -0700 @@ -35,7 +35,7 @@ return context; } -uint16_t cpu_read_16(cpu *context, uint16_t address) +uint16_t cpu_read_16(cpu *context, uint32_t address) { context->cycles += context->clock_inc; if (address & 1) { @@ -53,7 +53,7 @@ return 0xFFFF; } -uint8_t cpu_read_8(cpu *context, uint16_t address) +uint8_t cpu_read_8(cpu *context, uint32_t address) { context->cycles += context->clock_inc; memory_region *cur = context->mem_regions; @@ -66,7 +66,7 @@ return 0xFF; } -void cpu_write_16(cpu *context, uint16_t address, uint16_t value) +void cpu_write_16(cpu *context, uint32_t address, uint16_t value) { context->cycles += context->clock_inc; if (address & 1) { @@ -85,7 +85,7 @@ } } -void cpu_write_8(cpu *context, uint16_t address, uint8_t value) +void cpu_write_8(cpu *context, uint32_t address, uint8_t value) { context->cycles += context->clock_inc; memory_region *cur = context->mem_regions; @@ -119,7 +119,7 @@ void fetch_instruction(cpu *context) { - context->prefetch = cpu_read_16(context, context->regs[REG_PC]); + context->prefetch = cpu_read_16(context, context->pc_msb | context->regs[REG_PC]); context->regs[REG_PC] += 2; context->state = STATE_NORMAL; } @@ -127,9 +127,11 @@ void vector_fetch(cpu *context) { context->exception_pc = context->regs[REG_PC] - 2; + context->exception_pch = context->pc_msb >> 16; context->exception_sr = context->regs[REG_SR]; context->regs[REG_SR] &= ~(STATUS_INT0_ENABLE | STATUS_INT1_ENABLE); context->regs[REG_PC] = cpu_read_16(context, context->vector_base + context->exception * 2); + context->pc_msb = 0; context->state = STATE_NEED_FETCH; } @@ -236,10 +238,6 @@ context->regs[REG_SR] = context->exception_sr; context->state = STATE_NEED_FETCH; return; - case TRAP: - context->state = STATE_EXCEPTION_START; - context->exception = context->regs[dst]; - return; case TRAPI: context->state = STATE_EXCEPTION_START; context->exception = dst; @@ -274,6 +272,13 @@ case SETVBR: context->vector_base = context->regs[dst]; break; + case GETDATABANKS: + context->regs[dst] = context->data_high_msb >> 7 | context->data_low_msb >> 15; + break; + case SETDATABANKS: + context->data_high_msb = (context->regs[dst] & 0xFF00) << 7; + context->data_low_msb = (context->regs[dst] & 0xFF) << 15; + break; default: context->state = STATE_EXCEPTION_START; context->exception = EXCEPTION_INVALID_INSTRUCTION; @@ -321,12 +326,11 @@ return; } break; - case IN: - context->regs[dst] = cpu_read_port(context, context->regs[a]); + case LONGJMP: + context->regs[REG_PC] = context->regs[a]; + context->pc_msb = (context->regs[dst] & 0x7F) << 16; + context->state = STATE_NEED_FETCH; break; - case OUT: - cpu_write_port(context, context->regs[a], context->regs[dst]); - return; case INI: context->regs[dst] = cpu_read_port(context, a); break; @@ -346,6 +350,10 @@ context->regs[dst] = context->regs[dst] | format_immediate(a); update_flags_bitwise(context, context->regs[dst]); break; + case XORI: + context->regs[dst] = context->regs[dst] ^ format_immediate(a); + update_flags_bitwise(context, context->regs[dst]); + break; case LSI: shift = a & 7; if (!shift) { @@ -377,6 +385,19 @@ } } +uint32_t get_data_address(cpu *context, uint8_t a, uint8_t b) +{ + uint32_t address = context->regs[a] + context->regs[b]; + if (a == REG_PC || b == REG_PC) { + address |= context->pc_msb; + } else if (address & 0x8000) { + address = (address & 0x7FFF) | context->data_high_msb; + } else { + address |= context->data_low_msb; + } + return address; +} + void run_instruction(cpu *context) { uint16_t instruction = context->prefetch; @@ -396,16 +417,16 @@ context->regs[dst] |= a << 12 | b << 8; break; case LD8: - context->regs[dst] = cpu_read_8(context, context->regs[a] + context->regs[b]); + context->regs[dst] = cpu_read_8(context, get_data_address(context, a, b)); break; case LD16: - context->regs[dst] = cpu_read_16(context, context->regs[a] + context->regs[b]); + context->regs[dst] = cpu_read_16(context, get_data_address(context, a, b)); break; case STR8: - cpu_write_8(context, context->regs[a] + context->regs[b], context->regs[dst]); + cpu_write_8(context, get_data_address(context, a, b), context->regs[dst]); return; case STR16: - cpu_write_16(context, context->regs[a] + context->regs[b], context->regs[dst]); + cpu_write_16(context,get_data_address(context, a, b), context->regs[dst]); return; case ADD: tmp = context->regs[a] + context->regs[b];