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

Last change on this file since 57 was 57, checked in by mulligan, 11 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.