source: Deliverables/D4.1/ASMInterpret.ml @ 57

Last change on this file since 57 was 57, checked in by mulligan, 8 years ago

More instructions implemented. Started cleaning up code by moving
related functions acting on datatypes (bits, etc.) into dedicated
modules.

File size: 32.7 KB
Line 
1open Physical;;
2open ASM;;
3open Pretty;;
4
5exception Fetch_exception of string
6
7type time = int;;
8
9type foo
10
11(* no differentiation between internal and external code memory *)
12type status =
13 { code_memory: byte WordMap.t;        (* can be reduced *)
14   low_internal_ram: byte Byte7Map.t;
15   high_internal_ram: byte Byte7Map.t;
16   external_ram: byte WordMap.t;
17
18   pc: word;
19
20   (* sfr *)
21   p0: byte;
22   sp: byte;
23   dpl: byte;
24   dph: byte;
25   pcon: byte;
26   tcon: byte;
27   tmod: byte;
28   tl0: byte;
29   tl1: byte;
30   th0: byte;
31   th1: byte;
32   p1: byte;
33   scon: byte;
34   sbuf: byte;
35   p2: byte;
36   ie: byte;
37   p3: byte;
38   ip: byte;
39   psw: byte;
40   acc: byte;
41   b: byte;
42
43   clock: time;
44   timer0: word;
45   timer1: word;
46   timer2: word;  (* can be missing *)
47   io: foo (*(time * ?line? -> ?val?)*)
48 }
49
50let carr status = let (c,_,_,_),_ = status.psw in c
51
52(* timings taken from SIEMENS *)
53
54let fetch pmem pc =
55 let next pc = pc ++ 1, WordMap.find pc pmem in
56 let instr = WordMap.find pc pmem in
57 let pc = pc ++ 1 in
58 try
59  match instr with
60     (a10,a9,a8,true),(false,false,false,true) ->
61      let pc,b1 = next pc in
62       ACALL (`ADDR11 (a10,a9,a8,b1)), pc, 2
63   | (false,false,true,false),(true,r1,r2,r3) ->
64      ADD (`A,`REG (r1,r2,r3)), pc, 1
65   | (false,false,true,false),(false,true,false,true) ->
66      let pc,b1 = next pc in
67       ADD (`A,`DIRECT b1), pc, 1
68   | (false,false,true,false),(false,true,true,i1) ->
69       ADD (`A,`INDIRECT i1), pc, 1
70   | (false,false,true,false),(false,true,false,false) ->
71      let pc,b1 = next pc in
72       ADD (`A,`DATA b1), pc, 1
73   | (false,false,true,true),(true,r1,r2,r3) ->
74       ADDC (`A,`REG (r1,r2,r3)), pc, 1
75   | (false,false,true,true),(false,true,false,true) ->
76      let pc,b1 = next pc in
77       ADDC (`A,`DIRECT b1), pc, 1
78   | (false,false,true,true),(false,true,true,i1) ->
79       ADDC (`A,`INDIRECT i1), pc, 1
80   | (false,false,true,true),(false,true,false,false) ->
81      let pc,b1 = next pc in
82       ADDC (`A,`DATA b1), pc, 1
83   | (a10,a9,a8,false),(false,false,false,true) ->
84      let pc,b1 = next pc in
85       AJMP (`ADDR11 (a10,a9,a8,b1)), pc, 2
86   | (false,true,false,true),(true,r1,r2,r3) ->
87      ANL (`U1 (`A, `REG (r1,r2,r3))), pc, 1
88   | (false,true,false,true),(false,true,false,true) ->
89      let pc,b1 = next pc in
90       ANL (`U1 (`A, `DIRECT b1)), pc, 1
91   | (false,true,false,true),(false,true,true,i1) ->
92       ANL (`U1 (`A, `INDIRECT i1)), pc, 1
93   | (false,true,false,true),(false,true,false,false) ->
94      let pc,b1 = next pc in
95       ANL (`U1 (`A, `DATA b1)), pc, 1
96   | (false,true,false,true),(false,false,true,false) ->
97      let pc,b1 = next pc in
98       ANL (`U2 (`DIRECT b1,`A)), pc, 1
99   | (false,true,false,true),(false,false,true,true) ->
100      let pc,b1 = next pc in
101      let pc,b2 = next pc in
102       ANL (`U2 (`DIRECT b1,`DATA b2)), pc, 2
103   | (true,false,false,false),(false,false,true,false) ->
104      let pc,b1 = next pc in
105       ANL (`U3 (`C,`BIT b1)), pc, 2
106   | (true,false,true,true),(false,false,false,false) ->
107      let pc,b1 = next pc in
108       ANL (`U3 (`C,`NBIT b1)), pc, 2
109   | (true,false,true,true),(false,true,false,true) ->
110      let       pc,b1 = next pc in
111      let pc,b2 = next pc in
112        CJNE (`U1 (`A, `DIRECT b1), `REL b2), pc, 2
113   | (true,false,true,true),(false,true,false,false) ->
114       let pc,b1 = next pc in
115       let pc,b2 = next pc in
116         CJNE (`U1 (`A, `DATA b1), `REL b2), pc, 2
117   | (true,false,true,true),(true,r1,r2,r3) ->
118       let pc,b1 = next pc in
119       let pc,b2 = next pc in
120         CJNE (`U2 (`REG(r1,r2,r3), `DATA b1), `REL b2), pc, 2
121   | (true,false,true,true),(false,true,true,i1) ->
122       let pc,b1 = next pc in
123       let pc,b2 = next pc in
124         CJNE (`U2 (`INDIRECT i1, `DATA b1), `REL b2), pc, 2
125   | (true,true,true,false),(false,true,false,false) ->
126         CLR `A, pc, 1
127   | (true,true,false,false),(false,false,true,true) ->
128         CLR `C, pc, 1
129   | (true,true,false,false),(false,false,true,false) ->
130       let pc,b1 = next pc in
131         CLR (`BIT b1), pc, 1
132   | (true,true,true,true),(false,true,false,false) ->
133         CPL `A, pc, 1
134   | (true,false,true,true),(false,false,true,true) ->
135         CPL `C, pc, 1
136   | (true,false,true,true),(false,false,true,false) ->
137       let pc,b1 = next pc in
138         CPL (`BIT b1), pc, 1
139   | (true,true,false,true),(false,true,false,false) ->
140         DA `A, pc, 1
141   | (false,false,false,true),(false,true,false,false) ->
142         DEC `A, pc, 1
143   | (false,false,false,true),(true,r1,r2,r3) ->
144         DEC (`REG(r1,r2,r3)), pc, 1
145   | (false,false,false,true),(false,true,false,true) ->
146       let pc,b1 = next pc in
147         DEC (`DIRECT b1), pc, 1
148   | (false,false,false,true),(false,true,true,i1) ->
149         DEC (`INDIRECT i1), pc, 1
150   | (true,false,false,false),(false,true,false,false) ->
151         DIV (`A, `B), pc, 4
152   | (true,true,false,true),(true,r1,r2,r3) ->
153       let pc,b1 = next pc in
154         DJNZ (`REG(r1,r2,r3), `REL b1), pc, 2
155   | (true,true,false,true),(false,true,false,true) ->
156       let pc,b1 = next pc in
157       let pc,b2 = next pc in
158         DJNZ (`DIRECT b1, `REL b2), pc, 2
159   | (false,false,false,false),(false,true,false,false) ->
160         INC `A, pc, 1
161   | (false,false,false,false),(true,r1,r2,r3) ->
162         INC (`REG(r1,r2,r3)), pc, 1
163   | (false,false,false,false),(false,true,false,true) ->
164       let pc,b1 = next pc in
165         INC (`DIRECT b1), pc, 1
166   | (false,false,false,false),(false,true,true,i1) ->
167         INC (`INDIRECT i1), pc, 1
168   | (true,false,true,false),(false,false,true,true) ->
169         INC `DPTR, pc, 2
170   | (false,false,true,false),(false,false,false,false) ->
171       let pc,b1 = next pc in
172       let pc,b2 = next pc in
173         JB (`BIT b1, `REL b2), pc, 2
174   | (false,false,false,true),(false,false,false,false) ->
175       let pc,b1 = next pc in
176       let pc,b2 = next pc in
177         JBC (`BIT b1, `REL b2), pc, 2
178   | (false,true,false,false),(false,false,false,false) ->
179       let pc,b1 = next pc in
180         JC (`REL b1), pc, 2
181   | (false,true,true,true),(false,false,true,true) ->
182         JMP `IND_DPTR, pc, 2
183   | (false,false,true,true),(false,false,false,false) ->
184       let pc,b1 = next pc in
185       let pc,b2 = next pc in
186         JNB (`BIT b1, `REL b2), pc, 2
187   | (false,true,false,true),(false,false,false,false) ->
188       let pc,b1 = next pc in
189         JNC (`REL b1), pc, 2
190   | (false,true,true,true),(false,false,false,false) ->
191       let pc,b1 = next pc in
192         JNZ (`REL b1), pc, 2
193   | (false,true,true,false),(false,false,false,false) ->
194       let pc,b1 = next pc in
195         JZ (`REL b1), pc, 2
196   | (false,false,false,true),(false,false,true,false) ->
197       let pc,b1 = next pc in
198       let pc,b2 = next pc in
199         LCALL (`ADDR16 (b1,b2)), pc, 2
200   | (false,false,false,false),(false,false,true,false) ->
201       let pc,b1 = next pc in
202       let pc,b2 = next pc in
203         LJMP (`ADDR16 (b1,b2)), pc, 2
204   | (true,true,true,false),(true,r1,r2,r3) ->
205         MOV (`U1 (`A, `REG(r1,r2,r3))), pc, 1
206   | (true,true,true,false),(false,true,false,true) ->
207       let pc,b1 = next pc in
208         MOV (`U1 (`A, `DIRECT b1)), pc, 1
209   | (true,true,true,false),(false,true,true,i1) ->
210         MOV (`U1 (`A, `INDIRECT i1)), pc, 1
211   | (false,true,true,true),(false,true,false,false) ->
212       let pc,b1 = next pc in
213         MOV (`U1 (`A, `DATA b1)), pc, 1
214   | (true,true,true,true),(true,r1,r2,r3) ->
215         MOV (`U2 (`REG(r1,r2,r3), `A)), pc, 1
216   | (true,false,true,false),(true,r1,r2,r3) ->
217       let pc,b1 = next pc in
218         MOV (`U2 (`REG(r1,r2,r3), (`DIRECT b1))), pc, 2
219   | (false,true,true,true),(true,r1,r2,r3) ->
220       let pc,b1 = next pc in
221         MOV (`U2 (`REG(r1,r2,r3), (`DATA b1))), pc, 1
222   | (true,true,true,true),(false,true,false,true) ->
223       let pc,b1 = next pc in
224         MOV (`U3 (`DIRECT b1, `A)), pc, 1
225   | (true,false,false,false),(true,r1,r2,r3) ->
226       let pc,b1 = next pc in
227         MOV (`U3 (`DIRECT b1, `REG(r1,r2,r3))), pc, 2
228   | (true,false,false,false),(false,true,false,true) ->
229       let pc,b1 = next pc in
230       let pc,b2 = next pc in
231         MOV (`U3 (`DIRECT b1, `DIRECT b2)), pc, 2
232   | (true,false,false,false),(false,true,true,i1) ->
233       let pc,b1 = next pc in
234         MOV (`U3 (`DIRECT b1, `INDIRECT i1)), pc, 2
235   | (false,true,true,true),(false,true,false,true) ->
236       let pc,b1 = next pc in
237       let pc,b2 = next pc in
238         MOV (`U3 (`DIRECT b1, `DATA b2)), pc, 2
239   | (true,true,true,true),(false,true,true,i1) ->
240         MOV (`U2 (`INDIRECT i1, `A)), pc, 1
241   | (true,false,true,false),(false,true,true,i1) ->
242       let pc,b1 = next pc in
243         MOV (`U2 (`INDIRECT i1, `DIRECT b1)), pc, 2
244   | (false,true,true,true),(false,true,true,i1) ->
245       let pc,b1 = next pc in
246         MOV (`U2 (`INDIRECT i1, `DATA b1)), pc, 1
247   | (true,false,true,false),(false,false,true,false) ->
248       let pc,b1 = next pc in
249         MOV (`U5 (`C, `BIT b1)), pc, 1
250   | (true,false,false,true),(false,false,true,false) ->
251       let pc,b1 = next pc in
252         MOV (`U6 (`BIT b1, `C)), pc, 2
253   | (true,false,false,true),(false,false,false,false) ->
254       let pc,b1 = next pc in
255       let pc,b2 = next pc in
256         MOV (`U4 (`DPTR, `DATA16(b1,b2))), pc, 2
257   | (true,false,false,true),(false,false,true,true) ->
258         MOVC (`A, `A_DPTR), pc, 2
259   | (true,false,false,false),(false,false,true,true) ->
260         MOVC (`A, `A_PC), pc, 2
261   | (true,true,true,false),(false,false,true,i1) ->
262         MOVX (`U1 (`A, `EXT_INDIRECT i1)), pc, 2
263   | (true,true,true,false),(false,false,false,false) ->
264         MOVX (`U1 (`A, `EXT_IND_DPTR)), pc, 2
265   | (true,true,true,true),(false,false,true,i1) ->
266         MOVX (`U2 (`EXT_INDIRECT i1, `A)), pc, 2
267   | (true,true,true,true),(false,false,false,false) ->
268         MOVX (`U2 (`EXT_IND_DPTR, `A)), pc, 2
269   | (true,false,true,false),(false,true,false,false) ->
270         MUL(`A, `B), pc, 4
271   | (false,false,false,false),(false,false,false,false) ->
272         NOP, pc, 1
273   | (false,true,false,false),(true,r1,r2,r3) ->
274         ORL (`U1(`A, `REG(r1,r2,r3))), pc, 1
275   | (false,true,false,false),(false,true,false,true) ->
276       let pc,b1 = next pc in
277         ORL (`U1(`A, `DIRECT b1)), pc, 1
278   | (false,true,false,false),(false,true,true,i1) ->
279         ORL (`U1(`A, `INDIRECT i1)), pc, 1
280   | (false,true,false,false),(false,true,false,false) ->
281       let pc,b1 = next pc in
282         ORL (`U1(`A, `DATA b1)), pc, 1
283   | (false,true,false,false),(false,false,true,false) ->
284       let pc,b1 = next pc in
285         ORL (`U2(`DIRECT b1, `A)), pc, 1
286   | (false,true,false,false),(false,false,true,true) ->
287       let pc,b1 = next pc in
288       let pc,b2 = next pc in
289         ORL (`U2 (`DIRECT b1, `DATA b2)), pc, 2
290   | (false,true,true,true),(false,false,true,false) ->
291       let pc,b1 = next pc in
292         ORL (`U3 (`C, `BIT b1)), pc, 2
293   | (true,false,true,false),(false,false,false,false) ->
294       let pc,b1 = next pc in
295         ORL (`U3 (`C, `NBIT b1)), pc, 2
296   | (true,true,false,true),(false,false,false,false) ->
297       let pc,b1 = next pc in
298         POP (`DIRECT b1), pc, 2
299   | (true,true,false,false),(false,false,false,false) ->
300       let pc,b1 = next pc in
301         PUSH (`DIRECT b1), pc, 2
302   | (false,false,true,false),(false,false,true,false) ->
303         RET, pc, 2
304   | (false,false,true,true),(false,false,true,false) ->
305         RETI, pc, 2
306   | (false,false,true,false),(false,false,true,true) ->
307         RL `A, pc, 1
308   | (false,false,true,true),(false,false,true,true) ->
309         RLC `A, pc, 1
310   | (false,false,false,false),(false,false,true,true) ->
311         RR `A, pc, 1
312   | (false,false,false,true),(false,false,true,true) ->
313         RRC `A, pc, 1
314   | (true,true,false,true),(false,false,true,true) ->
315         SETB `C, pc, 1
316   | (true,true,false,true),(false,false,true,false) ->
317       let pc,b1 = next pc in
318         SETB (`BIT b1), pc, 1
319   | (true,false,false,false),(false,false,false,false) ->
320       let pc,b1 = next pc in
321         SJMP (`REL b1), pc, 2
322   | (true,false,false,true),(true,r1,r2,r3) ->
323       SUBB (`A, `REG(r1,r2,r3)), pc, 1
324   | (true,false,false,true),(false,true,false,true) ->
325       let pc,b1 = next pc in
326         SUBB (`A, `DIRECT b1), pc, 1
327   | (true,false,false,true),(false,true,true,i1) ->
328         SUBB (`A, `INDIRECT i1), pc, 1
329   | (true,false,false,true),(false,true,false,false) ->
330       let pc,b1 = next pc in
331         SUBB (`A, `DATA b1), pc, 1
332   | (true,true,false,false),(false,true,false,false) ->
333         SWAP `A, pc, 1
334   | (true,true,false,false),(true,r1,r2,r3) ->
335         XCH (`A, `REG(r1,r2,r3)), pc, 1
336   | (true,true,false,false),(false,true,false,true) ->
337       let pc,b1 = next pc in
338         XCH (`A, `DIRECT b1), pc, 1
339   | (true,true,false,false),(false,true,true,i1) ->
340         XCH (`A, `INDIRECT i1), pc, 1
341   | (true,true,false,true),(false,true,true,i1) ->
342         XCHD(`A, `INDIRECT i1), pc, 1
343   | (false,true,true,false),(true,r1,r2,r3) ->
344         XRL(`U1(`A, `REG(r1,r2,r3))), pc, 1
345   | (false,true,true,false),(false,true,false,true) ->
346       let pc,b1 = next pc in
347         XRL(`U1(`A, `DIRECT b1)), pc, 1
348   | (false,true,true,false),(false,true,true,i1) ->
349         XRL(`U1(`A, `INDIRECT i1)), pc, 1
350   | (false,true,true,false),(false,true,false,false) ->
351       let pc,b1 = next pc in
352         XRL(`U1(`A, `DATA b1)), pc, 1
353   | (false,true,true,false),(false,false,true,false) ->
354       let pc,b1 = next pc in
355         XRL(`U2(`DIRECT b1, `A)), pc, 1
356   | (false,true,true,false),(false,false,true,true) ->
357       let pc,b1 = next pc in
358       let pc,b2 = next pc in
359         XRL(`U2(`DIRECT b1, `DATA b2)), pc, 2
360 with
361  Not_found -> raise (Fetch_exception "Key not found")
362;;
363
364let assembly1 =
365 function
366    ACALL (`ADDR11 (a10,a9,a8,b1)) ->
367     [(a10,a9,a8,true),(false,false,false,true); b1]
368  | ADD (`A,`REG (r1,r2,r3)) ->
369     [(false,false,true,false),(true,r1,r2,r3)]
370  | ADD (`A, `DIRECT b1) ->
371     [(false,false,true,false),(false,true,false,true); b1]
372  | ADD (`A, `INDIRECT i1) ->
373     [(false,false,true,false),(false,true,true,i1)]
374  | ADD (`A, `DATA b1) ->
375     [(false,false,true,false),(false,true,false,false); b1]
376  | ADDC (`A, `REG(r1,r2,r3)) ->
377     [(false,false,true,true),(true,r1,r2,r3)]
378  | ADDC (`A, `DIRECT b1) ->
379     [(false,false,true,true),(false,true,false,true); b1]
380  | ADDC (`A,`INDIRECT i1) ->
381     [(false,false,true,true),(false,true,true,i1)]
382  | ADDC (`A,`DATA b1) ->
383     [(false,false,true,true),(false,true,false,false); b1]
384  | AJMP (`ADDR11 (a10,a9,a8,b1)) ->
385     [(a10,a9,a8,false),(false,false,false,true)]
386  | ANL (`U1 (`A, `REG (r1,r2,r3))) ->
387     [(false,true,false,true),(true,r1,r2,r3)]
388  | ANL (`U1 (`A, `DIRECT b1)) ->
389     [(false,true,false,true),(false,true,false,true); b1]
390  | ANL (`U1 (`A, `INDIRECT i1)) ->
391     [(false,true,false,true),(false,true,true,i1)]
392  | ANL (`U1 (`A, `DATA b1)) ->
393     [(false,true,false,true),(false,true,false,false); b1]
394  | ANL (`U2 (`DIRECT b1,`A)) ->
395     [(false,true,false,true),(false,false,true,false); b1]
396  | ANL (`U2 (`DIRECT b1,`DATA b2)) ->
397     [(false,true,false,true),(false,false,true,true); b1; b2]
398  | ANL (`U3 (`C,`BIT b1)) ->
399     [(true,false,false,false),(false,false,true,false);  b1]
400  | ANL (`U3 (`C,`NBIT b1)) ->
401    [(true,false,true,true),(false,false,false,false);  b1]
402  | CJNE (`U1 (`A, `DIRECT b1), `REL b2) ->
403    [(true,false,true,true),(false,true,false,true); b1; b2]
404  | CJNE (`U1 (`A, `DATA b1), `REL b2) ->
405    [(true,false,true,true),(false,true,false,false); b1; b2]
406  | CJNE (`U2 (`REG(r1,r2,r3), `DATA b1), `REL b2) ->
407    [(true,false,true,true),(true,r1,r2,r3); b1; b2]
408  | CJNE (`U2 (`INDIRECT i1, `DATA b1), `REL b2) ->
409    [(true,false,true,true),(false,true,true,i1); b1; b2]
410  | CLR `A ->
411    [(true,true,true,false),(false,true,false,false)]
412  | CLR `C ->
413    [(true,true,false,false),(false,false,true,true)]
414  | CLR (`BIT b1) ->
415    [(true,true,false,false),(false,false,true,false);  b1]
416  | CPL `A ->
417    [(true,true,true,true),(false,true,false,false)]
418  | CPL `C ->
419    [(true,false,true,true),(false,false,true,true)]
420  | CPL (`BIT b1) ->
421    [(true,false,true,true),(false,false,true,false); b1]
422  | DA `A ->
423    [(true,true,false,true),(false,true,false,false)]
424  | DEC `A ->
425    [(false,false,false,true),(false,true,false,false)]
426  | DEC (`REG(r1,r2,r3)) ->
427    [(false,false,false,true),(true,r1,r2,r3)]
428  | DEC (`DIRECT b1) ->
429    [(false,false,false,true),(false,true,false,true); b1]
430  | DEC (`INDIRECT i1) ->
431    [(false,false,false,true),(false,true,true,i1)]
432  | DIV (`A, `B) ->
433    [(true,false,false,false),(false,true,false,false)]
434  | DJNZ (`REG(r1,r2,r3), `REL b1) ->
435    [(true,true,false,true),(true,r1,r2,r3); b1]
436  | DJNZ (`DIRECT b1, `REL b2) ->
437    [(true,true,false,true),(false,true,false,true); b1; b2]
438  | INC `A ->
439    [(false,false,false,false),(false,true,false,false)]
440  | INC (`REG(r1,r2,r3)) ->
441    [(false,false,false,false),(true,r1,r2,r3)]
442  | INC (`DIRECT b1) ->
443    [(false,false,false,false),(false,true,false,true); b1]
444  | INC (`INDIRECT i1) ->
445    [(false,false,false,false),(false,true,true,i1)]
446  | INC `DPTR ->
447    [(true,false,true,false),(false,false,true,true)]
448  | JB (`BIT b1, `REL b2) ->
449    [(false,false,true,false),(false,false,false,false);  b1; b2]
450  | JBC (`BIT b1, `REL b2) ->
451    [(false,false,false,true),(false,false,false,false);  b1; b2]
452  | JC (`REL b1) ->
453    [(false,true,false,false),(false,false,false,false); b1]
454  | JMP `IND_DPTR ->
455    [(false,true,true,true),(false,false,true,true)]
456  | JNB (`BIT b1, `REL b2) ->
457    [(false,false,true,true),(false,false,false,false);  b1; b2]
458  | JNC (`REL b1) ->
459    [(false,true,false,true),(false,false,false,false); b1]
460  | JNZ (`REL b1) ->
461    [(false,true,true,true),(false,false,false,false); b1]
462  | JZ (`REL b1) ->
463    [(false,true,true,false),(false,false,false,false); b1]
464  | LCALL (`ADDR16 (b1,b2)) ->
465    [(false,false,false,true),(false,false,true,false); b1; b2]
466  | LJMP (`ADDR16 (b1,b2)) ->
467    [(false,false,false,false),(false,false,true,false); b1; b2]
468  | MOV (`U1 (`A, `REG(r1,r2,r3))) ->
469    [(true,true,true,false),(true,r1,r2,r3)]
470  | MOV (`U1 (`A, `DIRECT b1)) ->
471    [(true,true,true,false),(false,true,false,true); b1]
472  | MOV (`U1 (`A, `INDIRECT i1)) ->
473    [(true,true,true,false),(false,true,true,i1)]
474  | MOV (`U1 (`A, `DATA b1)) ->
475    [(false,true,true,true),(false,true,false,false); b1]
476  | MOV (`U2 (`REG(r1,r2,r3), `A)) ->
477    [(true,true,true,true),(true,r1,r2,r3)]
478  | MOV (`U2 (`REG(r1,r2,r3), (`DIRECT b1))) ->
479    [(true,false,true,false),(true,r1,r2,r3); b1]
480  | MOV (`U2 (`REG(r1,r2,r3), (`DATA b1))) ->
481    [(false,true,true,true),(true,r1,r2,r3); b1]
482  | MOV (`U3 (`DIRECT b1, `A)) ->
483    [(true,true,true,true),(false,true,false,true); b1]
484  | MOV (`U3 (`DIRECT b1, `REG(r1,r2,r3))) ->
485    [(true,false,false,false),(true,r1,r2,r3); b1]
486  | MOV (`U3 (`DIRECT b1, `DIRECT b2)) ->
487    [(true,false,false,false),(false,true,false,true); b1; b2]
488  | MOV (`U3 (`DIRECT b1, `INDIRECT i1)) ->
489    [(true,false,false,false),(false,true,true,i1); b1]
490  | MOV (`U3 (`DIRECT b1, `DATA b2)) ->
491    [(false,true,true,true),(false,true,false,true); b1; b2]
492  | MOV (`U2 (`INDIRECT i1, `A)) ->
493    [(true,true,true,true),(false,true,true,i1)]
494  | MOV (`U2 (`INDIRECT i1, `DIRECT b1)) ->
495    [(true,false,true,false),(false,true,true,i1); b1]
496  | MOV (`U2 (`INDIRECT i1, `DATA b1)) ->
497    [(false,true,true,true),(false,true,true,i1); b1]
498  | MOV (`U5 (`C, `BIT b1)) ->
499    [(true,false,true,false),(false,false,true,false);  b1]
500  | MOV (`U6 (`BIT b1, `C)) ->
501    [(true,false,false,true),(false,false,true,false);  b1]
502  | MOV (`U4 (`DPTR, `DATA16(b1,b2))) ->
503    [(true,false,false,true),(false,false,false,false); b1; b2]
504  | MOVC (`A, `A_DPTR) ->
505    [(true,false,false,true),(false,false,true,true)]
506  | MOVC (`A, `A_PC) ->
507    [(true,false,false,false),(false,false,true,true)]
508  | MOVX (`U1 (`A, `EXT_INDIRECT i1)) ->
509    [(true,true,true,false),(false,false,true,i1)]
510  | MOVX (`U1 (`A, `EXT_IND_DPTR)) ->
511    [(true,true,true,false),(false,false,false,false)]
512  | MOVX (`U2 (`EXT_INDIRECT i1, `A)) ->
513    [(true,true,true,true),(false,false,true,i1)]
514  | MOVX (`U2 (`EXT_IND_DPTR, `A)) ->
515    [(true,true,true,true),(false,false,false,false)]
516  | MUL(`A, `B) ->
517    [(true,false,true,false),(false,true,false,false)]
518  | NOP ->
519    [(false,false,false,false),(false,false,false,false)]
520  | ORL (`U1(`A, `REG(r1,r2,r3))) ->
521    [(false,true,false,false),(true,r1,r2,r3)]
522  | ORL (`U1(`A, `DIRECT b1)) ->
523    [(false,true,false,false),(false,true,false,true); b1]
524  | ORL (`U1(`A, `INDIRECT i1)) ->
525    [(false,true,false,false),(false,true,true,i1)]
526  | ORL (`U1(`A, `DATA b1)) ->
527    [(false,true,false,false),(false,true,false,false); b1]
528  | ORL (`U2(`DIRECT b1, `A)) ->
529    [(false,true,false,false),(false,false,true,false); b1]
530  | ORL (`U2 (`DIRECT b1, `DATA b2)) ->
531    [(false,true,false,false),(false,false,true,true); b1; b2]
532  | ORL (`U3 (`C, `BIT b1)) ->
533    [(false,true,true,true),(false,false,true,false);  b1]
534  | ORL (`U3 (`C, `NBIT b1)) ->
535    [(true,false,true,false),(false,false,false,false);  b1]
536  | POP (`DIRECT b1) ->
537    [(true,true,false,true),(false,false,false,false); b1]
538  | PUSH (`DIRECT b1) ->
539    [(true,true,false,false),(false,false,false,false); b1]
540  | RET ->
541    [(false,false,true,false),(false,false,true,false)]
542  | RETI ->
543    [(false,false,true,true),(false,false,true,false)]
544  | RL `A ->
545    [(false,false,true,false),(false,false,true,true)]
546  | RLC `A ->
547    [(false,false,true,true),(false,false,true,true)]
548  | RR `A ->
549    [(false,false,false,false),(false,false,true,true)]
550  | RRC `A ->
551    [(false,false,false,true),(false,false,true,true)]
552  | SETB `C ->
553    [(true,true,false,true),(false,false,true,true)]
554  | SETB (`BIT b1) ->
555    [(true,true,false,true),(false,false,true,false);  b1]
556  | SJMP (`REL b1) ->
557    [(true,false,false,false),(false,false,false,false); b1]
558  | SUBB (`A, `REG(r1,r2,r3)) ->
559    [(true,false,false,true),(true,r1,r2,r3)]
560  | SUBB (`A, `DIRECT b1) ->
561    [(true,false,false,true),(false,true,false,true); b1]
562  | SUBB (`A, `INDIRECT i1) ->
563    [(true,false,false,true),(false,true,true,i1)]
564  | SUBB (`A, `DATA b1) ->
565    [(true,false,false,true),(false,true,false,false); b1]
566  | SWAP `A ->
567    [(true,true,false,false),(false,true,false,false)]
568  | XCH (`A, `REG(r1,r2,r3)) ->
569    [(true,true,false,false),(true,r1,r2,r3)]
570  | XCH (`A, `DIRECT b1) ->
571    [(true,true,false,false),(false,true,false,true); b1]
572  | XCH (`A, `INDIRECT i1) ->
573    [(true,true,false,false),(false,true,true,i1)]
574  | XCHD(`A, `INDIRECT i1) ->
575    [(true,true,false,true),(false,true,true,i1)]
576  | XRL(`U1(`A, `REG(r1,r2,r3))) ->
577    [(false,true,true,false),(true,r1,r2,r3)]
578  | XRL(`U1(`A, `DIRECT b1)) ->
579    [(false,true,true,false),(false,true,false,true); b1]
580  | XRL(`U1(`A, `INDIRECT i1)) ->
581    [(false,true,true,false),(false,true,true,i1)]
582  | XRL(`U1(`A, `DATA b1)) ->
583    [(false,true,true,false),(false,true,false,false); b1]
584  | XRL(`U2(`DIRECT b1, `A)) ->
585    [(false,true,true,false),(false,false,true,false); b1]
586  | XRL(`U2(`DIRECT b1, `DATA b2)) ->
587    [(false,true,true,false),(false,false,true,true); b1; b2]
588;;
589
590let address_of_register status (b1,b2,b3) =
591 let (_,_,rs1,rs0),_ = status.psw in
592 let base =
593  match rs1,rs0 with
594     false,false -> 0x00
595   | false,true  -> 0x08
596   | true,false  -> 0x10
597   | true,true   -> 0x18
598 in
599  byte7_of_int (base + int_of_nibble (false,b1,b2,b3))
600;;
601
602let fetch_register status reg =
603 let addr = address_of_register status reg in
604  Byte7Map.find addr status.low_internal_ram
605;;
606
607let set_register status v reg =
608 let addr = address_of_register status reg in
609  { status with low_internal_ram =
610     Byte7Map.add addr v status.low_internal_ram }
611;;
612
613let fetch_arg8 status = 
614 function
615    `DIRECT addr ->
616      (match addr with
617         (false,r1,r2,r3),n1 ->
618           Byte7Map.find (r1,r2,r3,n1) status.low_internal_ram
619       | (true,r1,r2,r3),n1 ->
620           (*CSC: SFR access, TO BE IMPLEMENTED *)
621           assert false)
622  | `INDIRECT b ->
623     let addr = fetch_register status (false,false,b) in
624     (match addr with 
625         (false,r1,r2,r3),n1 ->
626           Byte7Map.find (r1,r2,r3,n1) status.low_internal_ram
627       | (true,r1,r2,r3),n1 ->
628           Byte7Map.find (r1,r2,r3,n1) status.high_internal_ram)
629  | `REG (b1,b2,b3) ->
630      fetch_register status (b1,b2,b3)
631  | `A -> status.acc
632  | `B -> status.b
633  | `DATA b -> b
634  | `A_DPTR ->
635     let dpr = status.dph,status.dpl in
636     (* CSC: what is the right behaviour in case of overflow?
637        assert false for now. Try to understand what DEC really does *)
638     let addr = dpr ++ (int_of_byte status.acc) in
639      WordMap.find addr status.external_ram
640  | `A_PC ->
641     (* CSC: what is the right behaviour in case of overflow?
642        assert false for now *)
643     let addr = status.pc ++ (int_of_byte status.acc) in
644      WordMap.find addr status.external_ram
645  | `IND_DPTR ->
646     let dpr = status.dph,status.dpl in
647      WordMap.find dpr status.external_ram
648;;
649
650let fetch_arg16 status =
651  function
652                `DATA16 w -> w
653
654let fetch_arg1 status =
655  function
656    `BIT addr
657  | `NBIT addr as x ->
658     let res =
659      (match addr with
660         (false,r1,r2,r3),n1 ->
661           let addr = (int_of_byte7 (r1,r2,r3,n1)) in
662           let addr' = byte7_of_int ((addr / 8) + 32) in
663            nth_bit (addr mod 8) (Byte7Map.find addr' status.low_internal_ram)
664       | (true,r1,r2,r3),n1 ->
665           (*CSC: SFR access, TO BE IMPLEMENTED *)
666           assert false)
667    in (match x with `BIT _ -> res | _ -> not res)
668  | `C ->
669       let ((b1,_,_,_),_) = status.psw in
670         b1
671
672let set_arg1 status v =
673  function
674    `BIT addr ->
675      (match addr with
676         (false,r1,r2,r3),n1 ->
677           let addr = (int_of_byte7 (r1,r2,r3,n1)) in
678           let addr' = byte7_of_int ((addr / 8) + 32) in
679            { status with low_internal_ram =
680                Byte7Map.add addr' (set_nth_bit (addr mod 8) v (Byte7Map.find addr' status.low_internal_ram)) status.low_internal_ram }
681                        | (true,r1,r2,r3),n1 ->
682           (*CSC: SFR access, TO BE IMPLEMENTED *)
683           (* assert false for now. Try to understand what DEC really does *)
684           assert false)
685    | `C ->
686       let ((_,b2,b3,b4),n2) = status.psw in
687         { status with psw = (v,b2,b3,b4),n2 }
688
689let set_arg8 status v =
690 function
691    `DIRECT addr ->
692      (match addr with
693         (false,r1,r2,r3),n1 ->
694           { status with low_internal_ram =
695              Byte7Map.add (r1,r2,r3,n1) v status.low_internal_ram }
696       | (true,r1,r2,r3),n1 ->
697           (*CSC: SFR access, TO BE IMPLEMENTED *)
698           (* assert false for now. Try to understand what DEC really does *)
699           assert false)
700  | `INDIRECT b ->
701     let addr = fetch_register status (false,false,b) in
702     (match addr with 
703         (false,r1,r2,r3),n1 ->
704           { status with low_internal_ram =
705              Byte7Map.add (r1,r2,r3,n1) v status.low_internal_ram }
706       | (true,r1,r2,r3),n1 ->
707           { status with high_internal_ram =
708              Byte7Map.add (r1,r2,r3,n1) v status.high_internal_ram })
709  | `REG (b1,b2,b3) ->
710      set_register status v (b1,b2,b3)
711  | `A -> { status with acc = v }
712  | `B -> { status with b = v }
713  | `IND_DPTR ->
714     let dpr = status.dph,status.dpl in
715      { status with external_ram =
716        WordMap.add dpr v status.external_ram }
717;;
718
719let set_arg16 status (dh, dl) =
720        function
721                `DPTR ->
722                        { status with dph = dh; dpl = dl }
723
724let set_flags status c ac ov =
725 { status with psw =
726    let (_c,oac,fo,rs1),(rs0,_ov,ud,p) = status.psw in
727    let ac = match ac with None -> oac | Some v -> v in
728     (c,ac,fo,rs1),(rs0,ov,ud,p)
729 }
730;;
731
732let execute1 status =
733 let instr,pc,ticks = fetch status.code_memory status.pc in
734 let status = { status with clock = status.clock + ticks; pc = pc } in
735  match instr with
736     ADD (`A,d1) ->
737      let v,c,ac,ov =
738       add8_with_c (fetch_arg8 status `A) (fetch_arg8 status d1) false
739      in
740       set_flags (set_arg8 status v `A) c (Some ac) ov
741   | ADDC (`A,d1) ->
742      let v,c,ac,ov =
743       add8_with_c (fetch_arg8 status `A) (fetch_arg8 status d1) (carr status)
744      in
745       set_flags (set_arg8 status v `A) c (Some ac) ov
746   | SUBB (`A,d1) ->
747      let v,c,ac,ov =
748       subb8_with_c (fetch_arg8 status `A) (fetch_arg8 status d1) (carr status)
749      in
750       set_flags (set_arg8 status v `A) c (Some ac) ov
751(*
752   | INC `DPTR -> assert false
753*)
754   | INC ((`A | `REG _ | `DIRECT _ | `INDIRECT _) as d) ->
755      let b = fetch_arg8 status d in
756      let res = inc b in
757       set_arg8 status res d
758   | DEC d ->
759      let b = fetch_arg8 status d in
760      let res = dec b in
761       set_arg8 status res d
762 | MUL (`A,`B) ->
763    let acc = int_of_byte status.acc in
764    let b = int_of_byte status.b in
765    let prod = acc * b in
766    let ov = prod > 255 in
767    let l = byte_of_int (prod mod 256) in
768    let h = byte_of_int (prod / 256) in
769    let status = { status with acc = l ; b = h } in
770     set_flags status false None ov
771 | DIV (`A,`B) ->
772    let acc = int_of_byte status.acc in
773    let b = int_of_byte status.b in
774     if b = 0 then
775      (* CSC: acc and b undefined! we leave them as they are... *)
776      set_flags status false None true
777     else
778      let q = byte_of_int (acc / b) in
779      let r = byte_of_int (acc mod b) in
780      let status = { status with acc = q ; b = r } in
781       set_flags status false None false
782
783(*
784 | DA  of acc
785
786 (* logical operations *)
787 | ANL of
788    (acc * [ reg | direct | indirect | data ],
789     direct * [ acc | data ],
790     carry * [ bit | nbit]) union3
791 | ORL of
792    (acc * [ reg | direct | indirect ],
793     direct * [ acc | data ],
794     carry * [ bit | nbit]) union3
795 | XRL of
796    (acc * [ reg | direct | indirect ],
797     direct * [ acc | data ]) union2
798*)
799 | CLR `A ->
800     set_arg8 status ((false,false,false,false),(false,false,false,false)) `A
801 | CLR `C ->
802     set_arg1 status false `C
803 | CLR ((`BIT b) as a) ->
804     set_arg1 status false a
805(*
806 | CPL of [ acc | carry | bit ]
807*)
808 | RL `A ->
809     let (b1,b2,b3,b4),(b5,b6,b7,b8) = status.acc in
810       { status with acc = (b2,b3,b4,b5),(b6,b7,b8,b1) }
811 | RLC `A ->
812     let old_carry = carr status in
813     let (b1,b2,b3,b4),(b5,b6,b7,b8) = status.acc in
814     let new_status = set_arg1 status b1 `C in
815       { new_status with acc = (b2,b3,b4,b5),(b6,b7,b8,old_carry) }
816 | RR `A ->
817     let (b1,b2,b3,b4),(b5,b6,b7,b8) = status.acc in
818       { status with acc = (b8,b1,b2,b3),(b4,b5,b6,b7) }
819 | RRC `A ->
820     let old_carry = carr status in
821     let (b1,b2,b3,b4),(b5,b6,b7,b8) = status.acc in
822     let new_status = set_arg1 status b8 `C in
823       { new_status with acc = (old_carry,b1,b2,b3),(b4,b5,b6,b7) }
824 | SWAP `A ->
825     let (acc_n_1, acc_n_2) = status.acc in
826       { status with acc = (acc_n_2, acc_n_1) }
827 | MOV(`U1(b1, b2)) ->
828                let arg = fetch_arg8 status b2 in
829      set_arg8 status arg b1
830 | MOV(`U2(b1, b2)) ->
831                let arg = fetch_arg8 status b2 in
832      set_arg8 status arg b1
833 | MOV(`U3(b1, b2)) ->
834                let arg = fetch_arg8 status b2 in
835      set_arg8 status arg b1
836 | MOV(`U4(b1,b2)) ->
837    let arg = fetch_arg16 status b2 in
838      set_arg16 status arg b1
839 | MOV(`U5(b1,b2))->
840    let arg = fetch_arg1 status b2 in
841      set_arg1 status arg b1
842 | MOV(`U6(b1,b2))->
843    let arg = fetch_arg1 status b2 in
844      set_arg1 status arg b1
845
846 (* data transfer *)
847(*
848 | MOVC of acc * [ acc_dptr | acc_pc ]
849 | MOVX of (acc * [ indirect | indirect_dptr ],
850            [ indirect | indirect_dptr ] * acc) union2
851*)
852 | SETB a -> set_arg1 status true a
853(*
854 | PUSH of direct
855 | POP of direct
856*)
857
858 | XCH(`A, arg) ->
859     let old_arg = fetch_arg8 status arg in
860     let old_acc = status.acc in
861     let new_status = set_arg8 status old_acc arg in
862       { status with acc = old_arg }
863(*
864 | XCHD of acc * indirect
865*)
866 (* program branching *)
867 | JC (`REL rel) ->
868     let cy = carr status in
869       if cy = true then
870         { status with pc = status.pc ++ (int_of_byte rel) }
871       else
872         status
873 | JNC (`REL rel) ->
874     let cy = carr status in
875       if cy = false then
876         { status with pc = status.pc ++ (int_of_byte rel) }
877       else
878         status
879(*
880 | JB of rel
881 | JNB of rel
882 | JBC of bit * rel
883 | ACALL of addr11
884 | LCALL of addr16
885 | RET
886 | RETI
887 | AJMP of addr11
888*)
889 | LJMP (`ADDR16 (lb,hb)) ->
890     { status with pc = (lb,hb) }
891(*
892 | SJMP of rel
893 | JMP of indirect_dptr
894*)
895 | JZ (`REL rel) ->
896     if status.acc = ((false,false,false,false),(false,false,false,false)) then
897                         { status with pc = status.pc ++ (int_of_byte rel) }
898     else
899       status
900 | JNZ (`REL rel) ->
901     if status.acc <> ((false,false,false,false),(false,false,false,false)) then
902                         { status with pc = status.pc ++ (int_of_byte rel) }
903     else
904       status
905 | CJNE ((`U1 (`A, ag)), `REL rel) ->
906     let ag_val = fetch_arg8 status ag in
907     let acc_val = status.acc in
908     let new_carry = acc_val < ag_val in
909       if ag_val <> acc_val then
910         { status with pc = status.pc ++ (int_of_byte rel) }
911       else
912         status
913 | CJNE ((`U2 (ag, `DATA d)), `REL rel) ->
914     let ag_val = fetch_arg8 status ag in
915     let new_carry = ag_val < d in
916       if ag_val <> d then
917         { status with pc = status.pc ++ (int_of_byte rel) }
918       else
919         status
920(*
921 | DJNZ of [ reg | direct ] * rel
922*)
923 | NOP -> status
924;;
Note: See TracBrowser for help on using the repository browser.