Mercurial > repos > simple16
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) |