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