comparison src/cpu.c @ 46:51672bd41cdd

Rework data segment setup to allow a stack segment and to add space for push and pop instructions
author Michael Pavone <pavone@retrodev.com>
date Tue, 30 Aug 2016 20:50:54 -0700
parents 6e7bfe83d2b0
children 9a3b9d86dabf
comparison
equal deleted inserted replaced
45:5338b9affd09 46:51672bd41cdd
125 } 125 }
126 126
127 void vector_fetch(cpu *context) 127 void vector_fetch(cpu *context)
128 { 128 {
129 context->exception_pc = context->regs[REG_PC] - 2; 129 context->exception_pc = context->regs[REG_PC] - 2;
130 context->exception_pch = context->pc_msb >> 16; 130 context->exception_pc_msb = context->pc_msb;
131 context->exception_sr = context->regs[REG_SR]; 131 context->exception_sr = context->regs[REG_SR];
132 context->regs[REG_SR] &= ~(STATUS_INT0_ENABLE | STATUS_INT1_ENABLE); 132 context->regs[REG_SR] &= ~(STATUS_INT0_ENABLE | STATUS_INT1_ENABLE);
133 context->regs[REG_PC] = cpu_read_16(context, context->vector_base + context->exception * 2); 133 context->regs[REG_PC] = cpu_read_16(context, (context->vector_base + context->exception * 2) & 0xFFFF);
134 context->pc_msb = 0; 134 context->pc_msb = 0;
135 context->state = STATE_NEED_FETCH; 135 context->state = STATE_NEED_FETCH;
136 } 136 }
137 137
138 uint16_t sign_extend(uint16_t val) 138 uint16_t sign_extend(uint16_t val)
234 { 234 {
235 case RETI: 235 case RETI:
236 context->regs[dst] = context->exception_ur; 236 context->regs[dst] = context->exception_ur;
237 context->regs[REG_PC] = context->exception_pc; 237 context->regs[REG_PC] = context->exception_pc;
238 context->regs[REG_SR] = context->exception_sr; 238 context->regs[REG_SR] = context->exception_sr;
239 context->pc_msb = context->exception_pc_msb;
239 context->state = STATE_NEED_FETCH; 240 context->state = STATE_NEED_FETCH;
240 return; 241 return;
241 case TRAPI: 242 case TRAPI:
242 context->state = STATE_EXCEPTION_START; 243 context->state = STATE_EXCEPTION_START;
243 context->exception = dst; 244 context->exception = dst;
244 return; 245 return;
246 case PUSH:
247 break;
248 case POP:
249 break;
250 case GETPCH:
251 context->regs[dst] = context->exception_pc_msb >> 8 | context->pc_msb >> 16;
252 break;
253 case SETPCH:
254 context->exception_pc_msb = context->regs[dst] << 8 & 0x7F0000;
255 context->pc_msb = context->regs[dst] << 16 & 0x7F0000;
256 context->state = STATE_NEED_FETCH;
257 return;
245 case GETEPC: 258 case GETEPC:
246 context->regs[dst] = context->exception_pc; 259 context->regs[dst] = context->exception_pc;
247 break; 260 break;
248 case SETEPC: 261 case SETEPC:
249 context->exception_pc = context->regs[dst]; 262 context->exception_pc = context->regs[dst];
270 context->regs[dst] = context->vector_base; 283 context->regs[dst] = context->vector_base;
271 break; 284 break;
272 case SETVBR: 285 case SETVBR:
273 context->vector_base = context->regs[dst]; 286 context->vector_base = context->regs[dst];
274 break; 287 break;
275 case GETDATABANKS:
276 context->regs[dst] = context->data_high_msb >> 7 | context->data_low_msb >> 15;
277 break;
278 case SETDATABANKS:
279 context->data_high_msb = (context->regs[dst] & 0xFF00) << 7;
280 context->data_low_msb = (context->regs[dst] & 0xFF) << 15;
281 break;
282 default:
283 context->state = STATE_EXCEPTION_START;
284 context->exception = EXCEPTION_INVALID_INSTRUCTION;
285 return;
286 } 288 }
287 if (dst == REG_PC) { 289 if (dst == REG_PC) {
288 context->state = STATE_NEED_FETCH; 290 context->state = STATE_NEED_FETCH;
289 } 291 }
290 } 292 }
388 uint32_t get_data_address(cpu *context, uint8_t a, uint8_t b) 390 uint32_t get_data_address(cpu *context, uint8_t a, uint8_t b)
389 { 391 {
390 uint32_t address = context->regs[a] + context->regs[b]; 392 uint32_t address = context->regs[a] + context->regs[b];
391 if (a == REG_PC || b == REG_PC) { 393 if (a == REG_PC || b == REG_PC) {
392 address |= context->pc_msb; 394 address |= context->pc_msb;
395 } else if (a == REG_SP || b == REG_SP) {
396 address |= context->regs[REG_SR] << 8 & 0x7F0000;
393 } else if (address & 0x8000) { 397 } else if (address & 0x8000) {
394 address = (address & 0x7FFF) | context->data_high_msb; 398 address = (address & 0x7FFF) | (context->regs[REG_DB] << 15 & 0x7F8000);
395 } else { 399 } else {
396 address |= context->data_low_msb; 400 address |= context->regs[REG_DB] << 7 & 0x7F8000;
397 } 401 }
398 return address; 402 return address;
399 } 403 }
400 404
401 void run_instruction(cpu *context) 405 void run_instruction(cpu *context)