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

Last change on this file since 62 was 62, checked in by mulligan, 10 years ago

Many additions to Bit, Nibble and Byte API, as well as more instructions
added to ASMInterpret execute function.

File size: 33.8 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 | CPL `A ->
806     let acc_val = fetch_arg8 status `A in
807       { status with acc = complement acc_val }
808 | CPL `C ->
809     let ag_val = fetch_arg1 status `C in
810       set_arg1 status (not ag_val) `C
811 | CPL (`BIT b) ->
812     let ag_val = fetch_arg1 status (`BIT b) in
813       set_arg1 status (not ag_val) (`BIT b)
814 | RL `A ->
815     let (b1,b2,b3,b4),(b5,b6,b7,b8) = status.acc in
816       { status with acc = (b2,b3,b4,b5),(b6,b7,b8,b1) }
817 | RLC `A ->
818     let old_carry = carr status in
819     let (b1,b2,b3,b4),(b5,b6,b7,b8) = status.acc in
820     let new_status = set_arg1 status b1 `C in
821       { new_status with acc = (b2,b3,b4,b5),(b6,b7,b8,old_carry) }
822 | RR `A ->
823     let (b1,b2,b3,b4),(b5,b6,b7,b8) = status.acc in
824       { status with acc = (b8,b1,b2,b3),(b4,b5,b6,b7) }
825 | RRC `A ->
826     let old_carry = carr status in
827     let (b1,b2,b3,b4),(b5,b6,b7,b8) = status.acc in
828     let new_status = set_arg1 status b8 `C in
829       { new_status with acc = (old_carry,b1,b2,b3),(b4,b5,b6,b7) }
830 | SWAP `A ->
831     let (acc_n_1, acc_n_2) = status.acc in
832       { status with acc = (acc_n_2, acc_n_1) }
833 | MOV(`U1(b1, b2)) ->
834                let arg = fetch_arg8 status b2 in
835      set_arg8 status arg b1
836 | MOV(`U2(b1, b2)) ->
837                let arg = fetch_arg8 status b2 in
838      set_arg8 status arg b1
839 | MOV(`U3(b1, b2)) ->
840                let arg = fetch_arg8 status b2 in
841      set_arg8 status arg b1
842 | MOV(`U4(b1,b2)) ->
843    let arg = fetch_arg16 status b2 in
844      set_arg16 status arg b1
845 | MOV(`U5(b1,b2))->
846    let arg = fetch_arg1 status b2 in
847      set_arg1 status arg b1
848 | MOV(`U6(b1,b2))->
849    let arg = fetch_arg1 status b2 in
850      set_arg1 status arg b1
851
852 (* data transfer *)
853(*
854 | MOVC of acc * [ acc_dptr | acc_pc ]
855 | MOVX of (acc * [ indirect | indirect_dptr ],
856            [ indirect | indirect_dptr ] * acc) union2
857*)
858 | SETB a -> set_arg1 status true a
859(*
860 | PUSH of direct
861 | POP of direct
862*)
863
864 | XCH(`A, arg) ->
865     let old_arg = fetch_arg8 status arg in
866     let old_acc = status.acc in
867     let new_status = set_arg8 status old_acc arg in
868       { new_status with acc = old_arg }
869(*
870 | XCHD of acc * indirect
871*)
872 (* program branching *)
873 | JC (`REL rel) ->
874     let cy = carr status in
875       if cy = true then
876         { status with pc = status.pc ++ (int_of_byte rel) }
877       else
878         status
879 | JNC (`REL rel) ->
880     let cy = carr status in
881       if cy = false then
882         { status with pc = status.pc ++ (int_of_byte rel) }
883       else
884         status
885 | JB ((`BIT b1), (`REL rel)) ->
886     let val_bit = fetch_arg1 status (`BIT b1) in
887       if val_bit = true then
888         { status with pc = status.pc ++ (int_of_byte rel) }
889       else
890         status
891 | JNB ((`BIT b1), (`REL rel)) ->
892     let val_bit = fetch_arg1 status (`BIT b1) in
893       if val_bit = false then
894         { status with pc = status.pc ++ (int_of_byte rel) }
895       else
896         status
897 | JBC ((`BIT b1), (`REL rel)) ->
898    let val_bit = fetch_arg1 status (`BIT b1) in
899    let new_status = set_arg1 status false (`BIT b1) in
900       if val_bit = true then
901         { new_status with pc = status.pc ++ (int_of_byte rel) }
902       else
903         new_status
904(*
905 | ACALL of addr11
906 | LCALL of addr16
907 | RET
908 | RETI
909 | AJMP of addr11
910*)
911 | LJMP (`ADDR16 (lb,hb)) ->
912     { status with pc = (lb,hb) }
913(*
914 | SJMP of rel
915 | JMP of indirect_dptr
916*)
917 | JZ (`REL rel) ->
918     if status.acc = ((false,false,false,false),(false,false,false,false)) then
919                         { status with pc = status.pc ++ (int_of_byte rel) }
920     else
921       status
922 | JNZ (`REL rel) ->
923     if status.acc <> ((false,false,false,false),(false,false,false,false)) then
924                         { status with pc = status.pc ++ (int_of_byte rel) }
925     else
926       status
927 | CJNE ((`U1 (`A, ag)), `REL rel) ->
928     let ag_val = fetch_arg8 status ag in
929     let acc_val = status.acc in
930     let (b1,b2,b3,b4),n2 = status.psw in
931     let new_carry = acc_val < ag_val in
932       if ag_val <> acc_val then
933         { status with pc = status.pc ++ (int_of_byte rel); psw = (new_carry, b2, b3, b4),n2 }
934       else
935         { status with psw = (new_carry, b2, b3, b4),n2 }
936 | CJNE ((`U2 (ag, `DATA d)), `REL rel) ->
937     let ag_val = fetch_arg8 status ag in
938     let (b1,b2,b3,b4),n2 = status.psw in
939     let new_carry = ag_val < d in
940       if ag_val <> d then
941         { status with pc = status.pc ++ (int_of_byte rel); psw = (new_carry, b2, b3, b4),n2 }
942       else
943         { status with psw = (new_carry, b2, b3, b4),n2 }
944(*
945 | DJNZ of [ reg | direct ] * rel
946*)
947 | NOP -> status
948;;
Note: See TracBrowser for help on using the repository browser.