jb302@39
|
1 #include <stdio.h>
|
jb302@39
|
2 #include <reg52.h>
|
jb302@39
|
3
|
jb302@39
|
4 #define MAIN
|
jb302@39
|
5 #include "mem.h"
|
jb302@39
|
6 #include "iset.h"
|
jb302@39
|
7
|
jb302@39
|
8 /* fill instruction table
|
jb302@39
|
9 * MCS-51 - this needs to be stored in code memory */
|
jb302@39
|
10
|
jb302@39
|
11 FUNCTION_TABLE const code iset = {
|
jb302@39
|
12 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
|
jb302@39
|
13 SET, CLR, SET, CLR, SET, CLR, CPL, CPL,
|
jb302@39
|
14 XCSD, SFA, LAF, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
15 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
16 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
17 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
18 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
19 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
20 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
21 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
22 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
23 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
24 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
25 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
26 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
27 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
|
jb302@39
|
28 ANL, ANL, ANL, ANL, ANL, ANL, ANL, ANL,
|
jb302@39
|
29 ORL, ORL, ORL, ORL, ORL, ORL, ORL, ORL,
|
jb302@39
|
30 XRL, XRL, XRL, XRL, XRL, XRL, XRL, XRL,
|
jb302@39
|
31 RL, RLC, RR, RRC, INC, DEC, INC, DEC,
|
jb302@39
|
32 ADD, ADD, ADD, ADD, ADD, ADD, ADD, ADD,
|
jb302@39
|
33 ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC,
|
jb302@39
|
34 SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
|
jb302@39
|
35 SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB,
|
jb302@39
|
36 PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP,
|
jb302@39
|
37 PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL,
|
jb302@39
|
38 DJNZ, DJNZ, DJNZ, DJNZ, CJNE, CJNE, CJNE, CJNE,
|
jb302@39
|
39 LJMP, LCALL, RET, RETI, SJMP, JMP, JMP, CJNE,
|
jb302@39
|
40 JZ, JNZ, JC, JNC, JPO, JPE, JS, JNS,
|
jb302@39
|
41 PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH,
|
jb302@39
|
42 POP, POP, POP, POP, POP, POP, POP, POP,
|
jb302@39
|
43 MUL, DIV, DA, NOP, IN, OUT, INT, HLT
|
jb302@39
|
44 };
|
jb302@39
|
45
|
jb302@39
|
46 BYTE pause; /* becomes 1 when we hit a break point in run mode */
|
jb302@39
|
47 BYTE free_run; /* free run if not 0 */
|
jb302@39
|
48 BYTE pause; /* pause flag */
|
jb302@39
|
49 WIDE addrc; /* address counter */
|
jb302@39
|
50 BYTE args[4]; /* dbg args */
|
jb302@39
|
51
|
jb302@39
|
52 WIDE bp[8] = { 0xFFFF,
|
jb302@39
|
53 0xFFFF,
|
jb302@39
|
54 0xFFFF,
|
jb302@39
|
55 0xFFFF,
|
jb302@39
|
56 0xFFFF,
|
jb302@39
|
57 0xFFFF,
|
jb302@39
|
58 0xFFFF,
|
jb302@39
|
59 0xFFFF
|
jb302@39
|
60 };
|
jb302@39
|
61
|
jb302@39
|
62
|
jb302@39
|
63 void
|
jb302@39
|
64 snd(BYTE c) {
|
jb302@39
|
65 putchar(c);
|
jb302@39
|
66 }
|
jb302@39
|
67
|
jb302@39
|
68 BYTE
|
jb302@39
|
69 rcv(void) {
|
jb302@39
|
70 return getchar();
|
jb302@39
|
71 }
|
jb302@39
|
72
|
jb302@39
|
73 void
|
jb302@39
|
74 step(void) {
|
jb302@39
|
75 IR = fetch();
|
jb302@39
|
76 iset.ops[IR]();
|
jb302@39
|
77 }
|
jb302@39
|
78
|
jb302@39
|
79 void
|
jb302@39
|
80 run(void) {
|
jb302@39
|
81 while (pause != 1) {
|
jb302@39
|
82 step();
|
jb302@39
|
83 for (addrc = 0; addrc < 8; addrc++) {
|
jb302@39
|
84 if (bp[addrc] == get_wide(PC)) {
|
jb302@39
|
85 pause = 1;
|
jb302@39
|
86 }
|
jb302@39
|
87 }
|
jb302@39
|
88 }
|
jb302@39
|
89 }
|
jb302@39
|
90
|
jb302@39
|
91 void controller() {
|
jb302@39
|
92 if (free_run == 0) {
|
jb302@39
|
93 switch (rcv()) {
|
jb302@39
|
94
|
jb302@39
|
95 /* step */
|
jb302@39
|
96 case 0x00:
|
jb302@39
|
97 step();
|
jb302@39
|
98 break;
|
jb302@39
|
99
|
jb302@39
|
100 /* run for length steps*/
|
jb302@39
|
101 case 0x01:
|
jb302@39
|
102 run();
|
jb302@39
|
103 break;
|
jb302@39
|
104
|
jb302@39
|
105 /* set reg */
|
jb302@39
|
106 case 0x02:
|
jb302@39
|
107 args[0] = rcv(); /* reg */
|
jb302@39
|
108 args[1] = rcv(); /* val */
|
jb302@39
|
109 regs[args[0]] = args[1];
|
jb302@39
|
110 break;
|
jb302@39
|
111
|
jb302@39
|
112 /* get reg */
|
jb302@39
|
113 case 0x03:
|
jb302@39
|
114 args[0] = rcv(); /* reg */
|
jb302@39
|
115 snd(regs[args[0]]);
|
jb302@39
|
116 break;
|
jb302@39
|
117
|
jb302@39
|
118 /* set flag */
|
jb302@39
|
119 case 0x04:
|
jb302@39
|
120 args[0] = rcv(); /* flag */
|
jb302@39
|
121 args[1] = rcv(); /* on? */
|
jb302@39
|
122 set_flag(args[0], args[1]);
|
jb302@39
|
123 break;
|
jb302@39
|
124
|
jb302@39
|
125 /* get flag */
|
jb302@39
|
126 case 0x05:
|
jb302@39
|
127 args[0] = rcv(); /* flag */
|
jb302@39
|
128 snd(get_flag(args[0]));
|
jb302@39
|
129 break;
|
jb302@39
|
130
|
jb302@39
|
131 /* write mem block */
|
jb302@39
|
132 case 0x06:
|
jb302@39
|
133 args[0] = rcv(); /* addr high */
|
jb302@39
|
134 args[1] = rcv(); /* addr low */
|
jb302@39
|
135 args[2] = rcv(); /* length high */
|
jb302@39
|
136 args[3] = rcv(); /* length low */
|
jb302@39
|
137 tmpw = MWIDE(args[0], args[1]);
|
jb302@39
|
138 for (addrc = tmpw; addrc < tmpw + MWIDE(args[2], args[3]); addrc++) {
|
jb302@39
|
139 if (addrc >= 0xFFFF) {
|
jb302@39
|
140 break;
|
jb302@39
|
141 }
|
jb302@39
|
142 mem[addrc] = rcv();
|
jb302@39
|
143 }
|
jb302@39
|
144 break;
|
jb302@39
|
145
|
jb302@39
|
146 /* read mem block */
|
jb302@39
|
147 case 0x07:
|
jb302@39
|
148 args[0] = rcv(); /* addr high */
|
jb302@39
|
149 args[1] = rcv(); /* addr low */
|
jb302@39
|
150 args[2] = rcv(); /* length high */
|
jb302@39
|
151 args[3] = rcv(); /* length low */
|
jb302@39
|
152 tmpw = MWIDE(args[0], args[1]);
|
jb302@39
|
153 for (addrc = tmpw; addrc < tmpw + MWIDE(args[2], args[3]); addrc++) {
|
jb302@39
|
154 if (addrc >= 0xFFFF) {
|
jb302@39
|
155 break;
|
jb302@39
|
156 }
|
jb302@39
|
157 snd(mem[addrc]);
|
jb302@39
|
158 }
|
jb302@39
|
159 break;
|
jb302@39
|
160
|
jb302@39
|
161 /* get A */
|
jb302@39
|
162 case 0x08:
|
jb302@39
|
163 snd(A);
|
jb302@39
|
164 break;
|
jb302@39
|
165
|
jb302@39
|
166 /* get flags */
|
jb302@39
|
167 case 0x09:
|
jb302@39
|
168 snd(flags);
|
jb302@39
|
169 break;
|
jb302@39
|
170
|
jb302@39
|
171 /* get instruction register */
|
jb302@39
|
172 case 0x0A:
|
jb302@39
|
173 snd(IR);
|
jb302@39
|
174 break;
|
jb302@39
|
175
|
jb302@39
|
176 /* run for length */
|
jb302@39
|
177 case 0x0B:
|
jb302@39
|
178 args[0] = rcv(); /* length high */
|
jb302@39
|
179 args[1] = rcv(); /* length low */
|
jb302@39
|
180 for (tmpw = 0 ; tmpw < MWIDE(args[0], args[1]) ; tmpw++) {
|
jb302@39
|
181 step();
|
jb302@39
|
182 }
|
jb302@39
|
183 break;
|
jb302@39
|
184
|
jb302@39
|
185 case 0x0C:
|
jb302@39
|
186 free_run = 1;
|
jb302@39
|
187 break;
|
jb302@39
|
188
|
jb302@39
|
189 /* set break point */
|
jb302@39
|
190 case 0x0D:
|
jb302@39
|
191 args[0] = rcv(); /* bp index */
|
jb302@39
|
192 args[1] = rcv(); /* address high */
|
jb302@39
|
193 args[2] = rcv(); /* address low */
|
jb302@39
|
194 if (args[0] > 7) {
|
jb302@39
|
195 break;
|
jb302@39
|
196 }
|
jb302@39
|
197 bp[args[0]] = MWIDE(args[1], args[2]);
|
jb302@39
|
198 break;
|
jb302@39
|
199
|
jb302@39
|
200 /* test cmd */
|
jb302@39
|
201 case 0x54:
|
jb302@39
|
202 snd('A');
|
jb302@39
|
203 break;
|
jb302@39
|
204 }
|
jb302@39
|
205 }
|
jb302@39
|
206 else {
|
jb302@39
|
207 step();
|
jb302@39
|
208 }
|
jb302@39
|
209 }
|
jb302@39
|
210
|
jb302@39
|
211 void
|
jb302@39
|
212 main(void) {
|
jb302@39
|
213 /* serial set up
|
jb302@39
|
214 * SCON - mode 1, 8-bit UART, enable rcvr
|
jb302@39
|
215 * TMOD - timer 1, mode 2, 8-bit reload
|
jb302@39
|
216 * TH1 - reload value for 1200 baud @ 12MHz
|
jb302@39
|
217 * TR1 - timer 1 run
|
jb302@39
|
218 * TI - set TI to send first char of UART */
|
jb302@39
|
219 /* dont go into free run on restart */
|
jb302@39
|
220 free_run = 0;
|
jb302@39
|
221 SCON = 0x50;
|
jb302@39
|
222 TMOD |= 0x20;
|
jb302@39
|
223 TH1 = 0xE8;
|
jb302@39
|
224 TR1 = 1;
|
jb302@39
|
225 TI = 1;
|
jb302@39
|
226 for (;;) {
|
jb302@39
|
227 controller();
|
jb302@39
|
228 }
|
jb302@39
|
229 }
|
jb302@39
|
230
|