Mercurial > repos > simple16
annotate src/cpu.c @ 50:8e39a877c651
Switch from RGB 444 to RGB 565 for palette entries
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 31 Aug 2016 20:29:45 -0700 |
parents | 9a3b9d86dabf |
children | bce01001a8c1 |
rev | line source |
---|---|
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1 #include <stdint.h> |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
2 #include <stdlib.h> |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
3 #include <string.h> |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
4 #include <stdio.h> |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
5 #include "cpu.h" |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
7 enum { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
8 EXCEPTION_INTERRUPT_0, |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 EXCEPTION_INTERRUPT_1, |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 EXCEPTION_UNALIGNED_READ, |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
11 EXCEPTION_INVALID_INSTRUCTION |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
12 }; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
13 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 enum { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
15 STATE_NEED_FETCH, |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
16 STATE_NORMAL, |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
17 STATE_EXCEPTION_START |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 }; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 #define STATUS_INT0_ENABLE 1 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
21 #define STATUS_INT1_ENABLE 2 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
22 #define FLAG_Z 4 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 #define FLAG_C 8 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 #define FLAG_N 16 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
26 cpu* alloc_cpu(uint32_t clock_divider, uint32_t num_regions, memory_region *regions) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 size_t alloc_size = sizeof(cpu) + sizeof(memory_region) * num_regions; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 cpu *context = malloc(alloc_size); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 memset(context, 0, alloc_size); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 context->clock_inc = clock_divider; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 context->num_mem_regions = num_regions; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 memcpy(context->mem_regions, regions, num_regions*sizeof(memory_region)); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 return context; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
36 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
37 |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
38 uint16_t cpu_read_16(cpu *context, uint32_t address) |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
40 context->cycles += context->clock_inc; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 if (address & 1) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 context->exception = EXCEPTION_UNALIGNED_READ; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 context->state = STATE_EXCEPTION_START; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
44 return 0xFFFF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 memory_region *cur = context->mem_regions; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 for (memory_region *end = cur + context->num_mem_regions; cur < end; cur++) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 if (address >= cur->start && address <= cur->end && (cur->flags & MEM_READ)) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 return cur->base[address - cur->start] << 8 | cur->base[address - cur->start + 1]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 return 0xFFFF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
54 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
56 uint8_t cpu_read_8(cpu *context, uint32_t address) |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 context->cycles += context->clock_inc; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 memory_region *cur = context->mem_regions; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 for (memory_region *end = cur + context->num_mem_regions; cur < end; cur++) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 if (address >= cur->start && address <= cur->end && (cur->flags & MEM_READ)) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 return cur->base[address - cur->start]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 return 0xFF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
69 void cpu_write_16(cpu *context, uint32_t address, uint16_t value) |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 context->cycles += context->clock_inc; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 if (address & 1) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
73 context->exception = EXCEPTION_UNALIGNED_READ; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 context->state = STATE_EXCEPTION_START; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
76 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 memory_region *cur = context->mem_regions; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 for (memory_region *end = cur + context->num_mem_regions; cur < end; cur++) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 if (address >= cur->start && address <= cur->end && (cur->flags & MEM_WRITE)) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 cur->base[address - cur->start] = value >> 8; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 cur->base[address - cur->start + 1] = value; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
88 void cpu_write_8(cpu *context, uint32_t address, uint8_t value) |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 context->cycles += context->clock_inc; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 memory_region *cur = context->mem_regions; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 for (memory_region *end = cur + context->num_mem_regions; cur < end; cur++) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 if (address >= cur->start && address <= cur->end && (cur->flags & MEM_WRITE)) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 cur->base[address - cur->start] = value; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 uint16_t cpu_read_port(cpu *context, uint8_t port) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 { |
20 | 103 context->cycles += context->clock_inc; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 port &= 0xF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 if (context->port_handlers[port].read) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 return context->port_handlers[port].read(context, port); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 return 0xFFFF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
109 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
110 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
111 void cpu_write_port(cpu *context, uint8_t port, uint16_t value) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 { |
20 | 113 context->cycles += context->clock_inc; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 port &= 0xF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 if (context->port_handlers[port].write) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
116 context->port_handlers[port].write(context, port, value); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
117 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
118 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
119 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
120 void fetch_instruction(cpu *context) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
121 { |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
122 context->prefetch = cpu_read_16(context, context->pc_msb | context->regs[REG_PC]); |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 context->regs[REG_PC] += 2; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 context->state = STATE_NORMAL; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
125 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 void vector_fetch(cpu *context) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 context->exception_pc = context->regs[REG_PC] - 2; |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
130 context->exception_pc_msb = context->pc_msb; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
131 context->exception_sr = context->regs[REG_SR]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
132 context->regs[REG_SR] &= ~(STATUS_INT0_ENABLE | STATUS_INT1_ENABLE); |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
133 context->regs[REG_PC] = cpu_read_16(context, (context->vector_base + context->exception * 2) & 0xFFFF); |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
134 context->pc_msb = 0; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
135 context->state = STATE_NEED_FETCH; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
136 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
137 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
138 uint16_t sign_extend(uint16_t val) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
139 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
140 if (val & 0x80) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 return val | 0xFF00; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
142 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 return val; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
144 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
146 void update_flags_arith(cpu *context, uint32_t result) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
147 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
148 context->regs[REG_SR] &= ~(FLAG_N|FLAG_C|FLAG_Z); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
149 if (!(result & 0xFFFF)) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
150 context->regs[REG_SR] |= FLAG_Z; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
151 } |
13
d8ae30286d17
Fix flag calculation and condition code tests
Michael Pavone <pavone@retrodev.com>
parents:
6
diff
changeset
|
152 if (result & 0x8000) { |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 context->regs[REG_SR] |= FLAG_N; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
154 } |
13
d8ae30286d17
Fix flag calculation and condition code tests
Michael Pavone <pavone@retrodev.com>
parents:
6
diff
changeset
|
155 if (result & 0x10000) { |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
156 context->regs[REG_SR] |= FLAG_C; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
157 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
158 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
159 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 void update_flags_bitwise(cpu *context, uint32_t result) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
161 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
162 context->regs[REG_SR] &= ~(FLAG_N|FLAG_Z); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
163 if (!(result & 0xFFFF)) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
164 context->regs[REG_SR] |= FLAG_Z; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 if (result &= 0x8000) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
167 context->regs[REG_SR] |= FLAG_N; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
169 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
170 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
171 void run_bcc(cpu *context, uint8_t condition, uint8_t a, uint8_t b) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
173 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
174 uint8_t doit = 0; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
175 switch (condition) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
176 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 case COND_ALWAYS: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 doit = 1; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
179 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
180 case COND_NEVER: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
181 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
182 case COND_ZERO: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
183 doit = context->regs[REG_SR] & FLAG_Z; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
184 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
185 case COND_NZERO: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
186 doit = !(context->regs[REG_SR] & FLAG_Z); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
187 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
188 case COND_NEG: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
189 doit = context->regs[REG_SR] & FLAG_N; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
190 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
191 case COND_POS: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
192 doit = !(context->regs[REG_SR] & FLAG_N); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
193 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
194 case COND_CARRY: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
195 doit = context->regs[REG_SR] & FLAG_C; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
196 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
197 case COND_NCARRY: |
13
d8ae30286d17
Fix flag calculation and condition code tests
Michael Pavone <pavone@retrodev.com>
parents:
6
diff
changeset
|
198 doit = !(context->regs[REG_SR] & FLAG_C); |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
199 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
200 case COND_GREATER: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
201 //not zero and not carry |
13
d8ae30286d17
Fix flag calculation and condition code tests
Michael Pavone <pavone@retrodev.com>
parents:
6
diff
changeset
|
202 doit = !(context->regs[REG_SR] & FLAG_Z) && !(context->regs[REG_SR] & FLAG_C); |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
203 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
204 case COND_LEQ: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
205 //zero or carry |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
206 doit = (context->regs[REG_SR] & FLAG_Z) || (context->regs[REG_SR] & FLAG_C); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
207 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
208 default: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
209 context->exception = EXCEPTION_INVALID_INSTRUCTION; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
210 context->state = STATE_EXCEPTION_START; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
211 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
212 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
213 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
214 if (doit) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
215 context->regs[REG_PC] += sign_extend(a << 4 | b) * 2; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
216 context->state = STATE_NEED_FETCH; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
217 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
218 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
219 |
2
6204c81e2933
Revert changes to handling of immediate versions of bitwise instructions. Replace asri with cmpi.
Michael Pavone <pavone@retrodev.com>
parents:
0
diff
changeset
|
220 uint16_t format_immediate(uint16_t val) |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
221 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
222 if (val & 8) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
223 val |= 0xFFF0; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
224 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
225 if (!val) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
226 val = 8; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
227 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
228 return val; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
229 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
230 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
231 void run_single_reg(cpu *context, uint8_t dst, uint8_t op) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
232 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
233 switch(op) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
234 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
235 case RETI: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
236 context->regs[dst] = context->exception_ur; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
237 context->regs[REG_PC] = context->exception_pc; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
238 context->regs[REG_SR] = context->exception_sr; |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
239 context->pc_msb = context->exception_pc_msb; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
240 context->state = STATE_NEED_FETCH; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
241 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
242 case TRAPI: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
243 context->state = STATE_EXCEPTION_START; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
244 context->exception = dst; |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
245 return; |
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
246 case PUSH: |
48 | 247 context->regs[REG_SP] -= 2; |
248 cpu_write_16(context, (context->regs[REG_SR] << 8 & 0x7F0000) | context->regs[REG_SP], context->regs[dst]); | |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
249 break; |
48 | 250 case POP: { |
251 uint16_t sp = context->regs[REG_SP]; | |
252 context->regs[REG_SP] += 2; | |
253 context->regs[dst] = cpu_read_16(context, (context->regs[REG_SR] << 8 & 0x7F0000) | sp); | |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
254 break; |
48 | 255 } |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
256 case GETPCH: |
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
257 context->regs[dst] = context->exception_pc_msb >> 8 | context->pc_msb >> 16; |
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
258 break; |
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
259 case SETPCH: |
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
260 context->exception_pc_msb = context->regs[dst] << 8 & 0x7F0000; |
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
261 context->pc_msb = context->regs[dst] << 16 & 0x7F0000; |
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
262 context->state = STATE_NEED_FETCH; |
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
263 return; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
264 case GETEPC: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
265 context->regs[dst] = context->exception_pc; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
266 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
267 case SETEPC: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
268 context->exception_pc = context->regs[dst]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
269 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
270 case GETESR: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
271 context->regs[dst] = context->exception_sr; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
272 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
273 case SETESR: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
274 context->exception_sr = context->regs[dst]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
275 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
276 case GETEUR: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
277 context->regs[dst] = context->exception_ur; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
278 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
279 case SETEUR: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
280 context->exception_ur = context->regs[dst]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
281 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
282 case GETENUM: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
283 context->regs[dst] = context->exception; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
284 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
285 case SETENUM: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
286 context->exception = context->regs[dst]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
287 break; |
25
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
288 case GETVBR: |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
289 context->regs[dst] = context->vector_base; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
290 break; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
291 case SETVBR: |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
292 context->vector_base = context->regs[dst]; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
293 break; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
294 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
295 if (dst == REG_PC) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
296 context->state = STATE_NEED_FETCH; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
297 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
298 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
299 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
300 void run_single_source(cpu *context, uint8_t dst, uint8_t a, uint8_t op) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
301 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
302 uint32_t tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
303 uint8_t shift; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
304 switch(op) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
305 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
306 case MOVE: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
307 context->regs[dst] = context->regs[a]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
308 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
309 case NEG: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
310 tmp = -context->regs[a]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
311 context->regs[dst] = tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
312 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
313 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
314 case NOT: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
315 context->regs[dst] = ~context->regs[a]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
316 update_flags_bitwise(context, context->regs[dst]); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
317 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
318 case CMP: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
319 tmp = context->regs[dst] - context->regs[a]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
320 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
321 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
322 case CALL: |
36
5683d9ba9acc
Fix call instruction for the case in which A reg == DST reg
Michael Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
323 tmp = context->regs[REG_PC] - 2; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
324 context->regs[REG_PC] = context->regs[a]; |
36
5683d9ba9acc
Fix call instruction for the case in which A reg == DST reg
Michael Pavone <pavone@retrodev.com>
parents:
26
diff
changeset
|
325 context->regs[dst] = tmp; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
326 context->state = STATE_NEED_FETCH; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
327 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
328 case SWAP: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
329 tmp = context->regs[dst]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
330 context->regs[dst] = context->regs[a]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
331 context->regs[a] = tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
332 if (a == REG_PC) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
333 context->state = STATE_NEED_FETCH; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
334 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
335 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
336 break; |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
337 case LONGJMP: |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
338 context->regs[REG_PC] = context->regs[a]; |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
339 context->pc_msb = (context->regs[dst] & 0x7F) << 16; |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
340 context->state = STATE_NEED_FETCH; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
341 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
342 case INI: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
343 context->regs[dst] = cpu_read_port(context, a); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
344 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
345 case OUTI: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
346 cpu_write_port(context, a, context->regs[dst]); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
347 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
348 case ADDI: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
349 tmp = context->regs[dst] + format_immediate(a); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
350 context->regs[dst] = tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
351 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
352 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
353 case ANDI: |
2
6204c81e2933
Revert changes to handling of immediate versions of bitwise instructions. Replace asri with cmpi.
Michael Pavone <pavone@retrodev.com>
parents:
0
diff
changeset
|
354 context->regs[dst] = context->regs[dst] & format_immediate(a); |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
355 update_flags_bitwise(context, context->regs[dst]); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
356 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
357 case ORI: |
2
6204c81e2933
Revert changes to handling of immediate versions of bitwise instructions. Replace asri with cmpi.
Michael Pavone <pavone@retrodev.com>
parents:
0
diff
changeset
|
358 context->regs[dst] = context->regs[dst] | format_immediate(a); |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
359 update_flags_bitwise(context, context->regs[dst]); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
360 break; |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
361 case XORI: |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
362 context->regs[dst] = context->regs[dst] ^ format_immediate(a); |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
363 update_flags_bitwise(context, context->regs[dst]); |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
364 break; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
365 case LSI: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
366 shift = a & 7; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
367 if (!shift) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
368 shift = 8; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
369 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
370 if (a & 8) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
371 tmp = context->regs[dst] >> shift; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
372 tmp |= (context->regs[dst] >> (shift - 1)) << 16 & 0x10000; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
373 } else { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
374 tmp = context->regs[dst] << (a & 7); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
375 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
376 context->regs[dst] = tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
377 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
378 break; |
2
6204c81e2933
Revert changes to handling of immediate versions of bitwise instructions. Replace asri with cmpi.
Michael Pavone <pavone@retrodev.com>
parents:
0
diff
changeset
|
379 case CMPI: |
6204c81e2933
Revert changes to handling of immediate versions of bitwise instructions. Replace asri with cmpi.
Michael Pavone <pavone@retrodev.com>
parents:
0
diff
changeset
|
380 tmp = a; |
6204c81e2933
Revert changes to handling of immediate versions of bitwise instructions. Replace asri with cmpi.
Michael Pavone <pavone@retrodev.com>
parents:
0
diff
changeset
|
381 if (a & 8) { |
6204c81e2933
Revert changes to handling of immediate versions of bitwise instructions. Replace asri with cmpi.
Michael Pavone <pavone@retrodev.com>
parents:
0
diff
changeset
|
382 a |= 0xFFF0; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
383 } |
2
6204c81e2933
Revert changes to handling of immediate versions of bitwise instructions. Replace asri with cmpi.
Michael Pavone <pavone@retrodev.com>
parents:
0
diff
changeset
|
384 tmp = context->regs[dst] - a; |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
385 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
386 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
387 case SINGLE_REG: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
388 run_single_reg(context, dst, a); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
389 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
390 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
391 if (dst == REG_PC) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
392 context->state = STATE_NEED_FETCH; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
393 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
394 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
395 |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
396 uint32_t get_data_address(cpu *context, uint8_t a, uint8_t b) |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
397 { |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
398 uint32_t address = context->regs[a] + context->regs[b]; |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
399 if (a == REG_PC || b == REG_PC) { |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
400 address |= context->pc_msb; |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
401 } else if (a == REG_SP || b == REG_SP) { |
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
402 address |= context->regs[REG_SR] << 8 & 0x7F0000; |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
403 } else if (address & 0x8000) { |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
404 address = (address & 0x7FFF) | (context->regs[REG_DB] << 15 & 0x7F8000); |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
405 } else { |
46
51672bd41cdd
Rework data segment setup to allow a stack segment and to add space for push and pop instructions
Michael Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
406 address |= context->regs[REG_DB] << 7 & 0x7F8000; |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
407 } |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
408 return address; |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
409 } |
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
410 |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
411 void run_instruction(cpu *context) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
412 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
413 uint16_t instruction = context->prefetch; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
414 fetch_instruction(context); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
415 uint8_t dst = instruction >> 12; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
416 uint8_t a = instruction >> 8 & 0xF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
417 uint8_t b = instruction >> 4 & 0xF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
418 uint8_t op = instruction & 0xF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
419 uint32_t tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
420 switch (op) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
421 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
422 case LDIM: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
423 context->regs[dst] = sign_extend(a << 4 | b); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
424 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
425 case LDIMH: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
426 context->regs[dst] &= 0xFF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
427 context->regs[dst] |= a << 12 | b << 8; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
428 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
429 case LD8: |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
430 context->regs[dst] = cpu_read_8(context, get_data_address(context, a, b)); |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
431 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
432 case LD16: |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
433 context->regs[dst] = cpu_read_16(context, get_data_address(context, a, b)); |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
434 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
435 case STR8: |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
436 cpu_write_8(context, get_data_address(context, a, b), context->regs[dst]); |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
437 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
438 case STR16: |
43
6e7bfe83d2b0
Changed the design to vastly simplify the video hardware and support a 23-bit address space on the CPU
Michael Pavone <pavone@retrodev.com>
parents:
36
diff
changeset
|
439 cpu_write_16(context,get_data_address(context, a, b), context->regs[dst]); |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
440 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
441 case ADD: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
442 tmp = context->regs[a] + context->regs[b]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
443 context->regs[dst] = tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
444 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
445 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
446 case ADC: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
447 tmp = context->regs[a] + context->regs[b] + (context->regs[REG_SR] & FLAG_C ? 1 : 0); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
448 context->regs[dst] = tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
449 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
450 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
451 case AND: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
452 context->regs[dst] = context->regs[a] & context->regs[b]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
453 update_flags_bitwise(context, context->regs[dst]); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
454 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
455 case OR: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
456 context->regs[dst] = context->regs[a] | context->regs[b]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
457 update_flags_bitwise(context, context->regs[dst]); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
458 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
459 case XOR: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
460 context->regs[dst] = context->regs[a] ^ context->regs[b]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
461 update_flags_bitwise(context, context->regs[dst]); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
462 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
463 case LSL: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
464 tmp = context->regs[a] << context->regs[b]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
465 context->regs[dst] = tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
466 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
467 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
468 case LSR: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
469 tmp = context->regs[a] >> context->regs[b]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
470 tmp |= (context->regs[a] >> (context->regs[b] - 1)) << 16 & 0x10000; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
471 context->regs[dst] = tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
472 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
473 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
474 case ASR: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
475 tmp = context->regs[a]; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
476 if (tmp & 0x8000) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
477 tmp |= 0xFFFF0000; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
478 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
479 tmp = tmp >> context->regs[b] & 0xFFFF; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
480 tmp |= (context->regs[a] >> (context->regs[b] - 1)) << 16 & 0x10000; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
481 context->regs[dst] = tmp; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
482 update_flags_arith(context, tmp); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
483 break; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
484 case BCC: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
485 run_bcc(context, dst, a, b); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
486 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
487 case SINGLE_SOURCE: |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
488 run_single_source(context, dst, a, b); |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
489 return; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
490 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
491 if (dst == REG_PC) { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
492 context->state = STATE_NEED_FETCH; |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
493 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
494 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
495 |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
496 void run_cpu(cpu *context, uint32_t target_cycle) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
497 { |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
498 while (context->cycles < target_cycle) |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
499 { |
25
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
500 context->current_target = target_cycle; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
501 context->pending_interrupts = get_current_interrupts(context); |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
502 uint32_t int_cycle = next_interrupt_cycle(context, (~context->pending_interrupts) & 0x3); |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
503 if (int_cycle < context->current_target) { |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
504 context->current_target = int_cycle; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
505 } |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
506 while (context->cycles < context->current_target) |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
507 { |
25
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
508 switch (context->state) |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
509 { |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
510 case STATE_NEED_FETCH: |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
511 fetch_instruction(context); |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
512 break; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
513 case STATE_NORMAL: |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
514 if (context->regs[REG_SR] & context->pending_interrupts) { |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
515 context->state = STATE_EXCEPTION_START; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
516 context->exception = context->pending_interrupts & 1 ? EXCEPTION_INTERRUPT_0 : EXCEPTION_INTERRUPT_1; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
517 context->pending_interrupts &= ~(1 << context->exception); |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
518 ack_interrupt(context, context->exception); |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
519 } else { |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
520 run_instruction(context); |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
521 } |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
522 break; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
523 case STATE_EXCEPTION_START: |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
524 vector_fetch(context); |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
525 break; |
fb14515266f4
Implemented timer and timer interrupts. Added get/setvbr instructions. Fixed assembler bug. Moved mnemonics into a separate source file
Michael Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
526 } |
0
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
527 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
528 } |
7e44f7d5810b
Initial commit. CPU working well enough for simple hello world program.
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
529 } |