Previous 199869 Revisions Next

r28739 Wednesday 19th March, 2014 at 20:38:22 UTC by Oliver Stöneberg
more *.c -> *.inc renaming / added some missing dependencies in cpu.mak (nw)
[src/emu/cpu]cpu.mak
[src/emu/cpu/dsp32]dsp32.c dsp32ops.c dsp32ops.inc*
[src/emu/cpu/dsp56k]dsp56k.c dsp56ops.c dsp56ops.inc*
[src/emu/cpu/e132xs]e132xs.c e132xsop.c e132xsop.inc*
[src/emu/cpu/i386]i386.c i386op16.c i386op16.inc* i386op32.c i386op32.inc* i386ops.c i386ops.inc* i486ops.c i486ops.inc* pentops.c pentops.inc* x87ops.c x87ops.inc*
[src/emu/cpu/i860]i860.c i860dec.c i860dec.inc*
[src/emu/cpu/lh5801]5801tbl.c 5801tbl.inc* lh5801.c
[src/emu/cpu/m6800]6800ops.c 6800ops.inc* 6800tbl.c 6800tbl.inc* m6800.c
[src/emu/cpu/m68000]m68kcpu.c m68kfpu.c m68kfpu.inc*
[src/emu/cpu/m6805]6805ops.c 6805ops.inc* m6805.c
[src/emu/cpu/mc68hc11]hc11ops.c hc11ops.inc* mc68hc11.c
[src/emu/cpu/mcs51]mcs51.c mcs51ops.c mcs51ops.inc*
[src/emu/cpu/nec]nec.c necinstr.c necinstr.inc* v25.c v25instr.c v25instr.inc*

trunk/src/emu/cpu/e132xs/e132xsop.c
r28738r28739
1#define LOCAL_DECODE_INIT \
2   struct regs_decode decode_state; \
3   struct regs_decode *decode = &decode_state; \
4\
5   /* clear 'current regs / flags' */ \
6   decode->src = 0; \
7   decode->dst = 0; \
8   decode->src_value = 0; \
9   decode->next_src_value = 0; \
10   decode->dst_value = 0; \
11   decode->next_dst_value = 0; \
12   decode->sub_type = 0; \
13   decode->extra.u = 0; \
14   decode->src_is_local = 0; \
15   decode->dst_is_local = 0; \
16   decode->same_src_dst = 0; \
17   decode->same_src_dstf = 0; \
18   decode->same_srcf_dst = 0;
19
20void hyperstone_device::op00()
21{
22   LOCAL_DECODE_INIT;
23   RRdecode(decode, 0, 0);
24   hyperstone_chk(decode);
25}
26
27void hyperstone_device::op01()
28{
29   LOCAL_DECODE_INIT;
30   RRdecode(decode, 0, 1);
31   hyperstone_chk(decode);
32}
33
34void hyperstone_device::op02()
35{
36   LOCAL_DECODE_INIT;
37   RRdecode(decode, 1, 0);
38   hyperstone_chk(decode);
39}
40
41void hyperstone_device::op03()
42{
43   LOCAL_DECODE_INIT;
44   RRdecode(decode, 1, 1);
45   hyperstone_chk(decode);
46}
47
48void hyperstone_device::op04()
49{
50   LOCAL_DECODE_INIT;
51   RRdecode(decode, 0, 0);
52   hyperstone_movd(decode);
53}
54
55void hyperstone_device::op05()
56{
57   LOCAL_DECODE_INIT;
58   RRdecode(decode, 0, 1);
59   hyperstone_movd(decode);
60}
61
62void hyperstone_device::op06()
63{
64   LOCAL_DECODE_INIT;
65   RRdecode(decode, 1, 0);
66   hyperstone_movd(decode);
67}
68
69void hyperstone_device::op07()
70{
71   LOCAL_DECODE_INIT;
72   RRdecode(decode, 1, 1);
73   hyperstone_movd(decode);
74}
75
76void hyperstone_device::op08()
77{
78   LOCAL_DECODE_INIT;
79   RRdecode(decode, 0, 0);
80   hyperstone_divu(decode);
81}
82
83void hyperstone_device::op09()
84{
85   LOCAL_DECODE_INIT;
86   RRdecode(decode, 0, 1);
87   hyperstone_divu(decode);
88}
89
90void hyperstone_device::op0a()
91{
92   LOCAL_DECODE_INIT;
93   RRdecode(decode, 1, 0);
94   hyperstone_divu(decode);
95}
96
97void hyperstone_device::op0b()
98{
99   LOCAL_DECODE_INIT;
100   RRdecode(decode, 1, 1);
101   hyperstone_divu(decode);
102}
103
104void hyperstone_device::op0c()
105{
106   LOCAL_DECODE_INIT;
107   RRdecode(decode, 0, 0);
108   hyperstone_divs(decode);
109}
110
111void hyperstone_device::op0d()
112{
113   LOCAL_DECODE_INIT;
114   RRdecode(decode, 0, 1);
115   hyperstone_divs(decode);
116}
117
118void hyperstone_device::op0e()
119{
120   LOCAL_DECODE_INIT;
121   RRdecode(decode, 1, 0);
122   hyperstone_divs(decode);
123}
124
125void hyperstone_device::op0f()
126{
127   LOCAL_DECODE_INIT;
128   RRdecode(decode, 1, 1);
129   hyperstone_divs(decode);
130}
131
132
133
134void hyperstone_device::op10()
135{
136   LOCAL_DECODE_INIT;
137   RRlimdecode(decode, 0, 0);
138   hyperstone_xm(decode);
139}
140
141void hyperstone_device::op11()
142{
143   LOCAL_DECODE_INIT;
144   RRlimdecode(decode, 0, 1);
145   hyperstone_xm(decode);
146}
147
148void hyperstone_device::op12()
149{
150   LOCAL_DECODE_INIT;
151   RRlimdecode(decode, 1, 0);
152   hyperstone_xm(decode);
153}
154
155void hyperstone_device::op13()
156{
157   LOCAL_DECODE_INIT;
158   RRlimdecode(decode, 1, 1);
159   hyperstone_xm(decode);
160}
161
162void hyperstone_device::op14()
163{
164   LOCAL_DECODE_INIT;
165   RRconstdecode(decode, 0, 0);
166   hyperstone_mask(decode);
167}
168
169void hyperstone_device::op15()
170{
171   LOCAL_DECODE_INIT;
172   RRconstdecode(decode, 0, 1);
173   hyperstone_mask(decode);
174}
175
176void hyperstone_device::op16()
177{
178   LOCAL_DECODE_INIT;
179   RRconstdecode(decode, 1, 0);
180   hyperstone_mask(decode);
181}
182
183void hyperstone_device::op17()
184{
185   LOCAL_DECODE_INIT;
186   RRconstdecode(decode, 1, 1);
187   hyperstone_mask(decode);
188}
189
190void hyperstone_device::op18()
191{
192   LOCAL_DECODE_INIT;
193   RRconstdecode(decode, 0, 0);
194   hyperstone_sum(decode);
195}
196
197void hyperstone_device::op19()
198{
199   LOCAL_DECODE_INIT;
200   RRconstdecode(decode, 0, 1);
201   hyperstone_sum(decode);
202}
203
204void hyperstone_device::op1a()
205{
206   LOCAL_DECODE_INIT;
207   RRconstdecode(decode, 1, 0);
208   hyperstone_sum(decode);
209}
210
211void hyperstone_device::op1b()
212{
213   LOCAL_DECODE_INIT;
214   RRconstdecode(decode, 1, 1);
215   hyperstone_sum(decode);
216}
217
218void hyperstone_device::op1c()
219{
220   LOCAL_DECODE_INIT;
221   RRconstdecode(decode, 0, 0);
222   hyperstone_sums(decode);
223}
224
225void hyperstone_device::op1d()
226{
227   LOCAL_DECODE_INIT;
228   RRconstdecode(decode, 0, 1);
229   hyperstone_sums(decode);
230}
231
232void hyperstone_device::op1e()
233{
234   LOCAL_DECODE_INIT;
235   RRconstdecode(decode, 1, 0);
236   hyperstone_sums(decode);
237}
238
239void hyperstone_device::op1f()
240{
241   LOCAL_DECODE_INIT;
242   RRconstdecode(decode, 1, 1);
243   hyperstone_sums(decode);
244}
245
246
247
248void hyperstone_device::op20()
249{
250   LOCAL_DECODE_INIT;
251   RRdecode(decode, 0, 0);
252   hyperstone_cmp(decode);
253}
254
255void hyperstone_device::op21()
256{
257   LOCAL_DECODE_INIT;
258   RRdecode(decode, 0, 1);
259   hyperstone_cmp(decode);
260}
261
262void hyperstone_device::op22()
263{
264   LOCAL_DECODE_INIT;
265   RRdecode(decode, 1, 0);
266   hyperstone_cmp(decode);
267}
268
269void hyperstone_device::op23()
270{
271   LOCAL_DECODE_INIT;
272   RRdecode(decode, 1, 1);
273   hyperstone_cmp(decode);
274}
275
276void hyperstone_device::op24()
277{
278   LOCAL_DECODE_INIT;
279   RRdecodewithHflag(decode, 0, 0);
280   hyperstone_mov(decode);
281}
282
283void hyperstone_device::op25()
284{
285   LOCAL_DECODE_INIT;
286   RRdecodewithHflag(decode, 0, 1);
287   hyperstone_mov(decode);
288}
289
290void hyperstone_device::op26()
291{
292   LOCAL_DECODE_INIT;
293   RRdecodewithHflag(decode, 1, 0);
294   hyperstone_mov(decode);
295}
296
297void hyperstone_device::op27()
298{
299   LOCAL_DECODE_INIT;
300   RRdecodewithHflag(decode, 1, 1);
301   hyperstone_mov(decode);
302}
303
304void hyperstone_device::op28()
305{
306   LOCAL_DECODE_INIT;
307   RRdecode(decode, 0, 0);
308   hyperstone_add(decode);
309}
310
311void hyperstone_device::op29()
312{
313   LOCAL_DECODE_INIT;
314   RRdecode(decode, 0, 1);
315   hyperstone_add(decode);
316}
317
318void hyperstone_device::op2a()
319{
320   LOCAL_DECODE_INIT;
321   RRdecode(decode, 1, 0);
322   hyperstone_add(decode);
323}
324
325void hyperstone_device::op2b()
326{
327   LOCAL_DECODE_INIT;
328   RRdecode(decode, 1, 1);
329   hyperstone_add(decode);
330}
331
332void hyperstone_device::op2c()
333{
334   LOCAL_DECODE_INIT;
335   RRdecode(decode, 0, 0);
336   hyperstone_adds(decode);
337}
338
339void hyperstone_device::op2d()
340{
341   LOCAL_DECODE_INIT;
342   RRdecode(decode, 0, 1);
343   hyperstone_adds(decode);
344}
345
346void hyperstone_device::op2e()
347{
348   LOCAL_DECODE_INIT;
349   RRdecode(decode, 1, 0);
350   hyperstone_adds(decode);
351}
352
353void hyperstone_device::op2f()
354{
355   LOCAL_DECODE_INIT;
356   RRdecode(decode, 1, 1);
357   hyperstone_adds(decode);
358}
359
360
361
362void hyperstone_device::op30()
363{
364   LOCAL_DECODE_INIT;
365   RRdecode(decode, 0, 0);
366   hyperstone_cmpb(decode);
367}
368
369void hyperstone_device::op31()
370{
371   LOCAL_DECODE_INIT;
372   RRdecode(decode, 0, 1);
373   hyperstone_cmpb(decode);
374}
375
376void hyperstone_device::op32()
377{
378   LOCAL_DECODE_INIT;
379   RRdecode(decode, 1, 0);
380   hyperstone_cmpb(decode);
381}
382
383void hyperstone_device::op33()
384{
385   LOCAL_DECODE_INIT;
386   RRdecode(decode, 1, 1);
387   hyperstone_cmpb(decode);
388}
389
390void hyperstone_device::op34()
391{
392   LOCAL_DECODE_INIT;
393   RRdecode(decode, 0, 0);
394   hyperstone_andn(decode);
395}
396
397void hyperstone_device::op35()
398{
399   LOCAL_DECODE_INIT;
400   RRdecode(decode, 0, 1);
401   hyperstone_andn(decode);
402}
403
404void hyperstone_device::op36()
405{
406   LOCAL_DECODE_INIT;
407   RRdecode(decode, 1, 0);
408   hyperstone_andn(decode);
409}
410
411void hyperstone_device::op37()
412{
413   LOCAL_DECODE_INIT;
414   RRdecode(decode, 1, 1);
415   hyperstone_andn(decode);
416}
417
418void hyperstone_device::op38()
419{
420   LOCAL_DECODE_INIT;
421   RRdecode(decode, 0, 0);
422   hyperstone_or(decode);
423}
424
425void hyperstone_device::op39()
426{
427   LOCAL_DECODE_INIT;
428   RRdecode(decode, 0, 1);
429   hyperstone_or(decode);
430}
431
432void hyperstone_device::op3a()
433{
434   LOCAL_DECODE_INIT;
435   RRdecode(decode, 1, 0);
436   hyperstone_or(decode);
437}
438
439void hyperstone_device::op3b()
440{
441   LOCAL_DECODE_INIT;
442   RRdecode(decode, 1, 1);
443   hyperstone_or(decode);
444}
445
446void hyperstone_device::op3c()
447{
448   LOCAL_DECODE_INIT;
449   RRdecode(decode, 0, 0);
450   hyperstone_xor(decode);
451}
452
453void hyperstone_device::op3d()
454{
455   LOCAL_DECODE_INIT;
456   RRdecode(decode, 0, 1);
457   hyperstone_xor(decode);
458}
459
460void hyperstone_device::op3e()
461{
462   LOCAL_DECODE_INIT;
463   RRdecode(decode, 1, 0);
464   hyperstone_xor(decode);
465}
466
467void hyperstone_device::op3f()
468{
469   LOCAL_DECODE_INIT;
470   RRdecode(decode, 1, 1);
471   hyperstone_xor(decode);
472}
473
474
475
476void hyperstone_device::op40()
477{
478   LOCAL_DECODE_INIT;
479   RRdecode(decode, 0, 0);
480   hyperstone_subc(decode);
481}
482
483void hyperstone_device::op41()
484{
485   LOCAL_DECODE_INIT;
486   RRdecode(decode, 0, 1);
487   hyperstone_subc(decode);
488}
489
490void hyperstone_device::op42()
491{
492   LOCAL_DECODE_INIT;
493   RRdecode(decode, 1, 0);
494   hyperstone_subc(decode);
495}
496
497void hyperstone_device::op43()
498{
499   LOCAL_DECODE_INIT;
500   RRdecode(decode, 1, 1);
501   hyperstone_subc(decode);
502}
503
504void hyperstone_device::op44()
505{
506   LOCAL_DECODE_INIT;
507   RRdecode(decode, 0, 0);
508   hyperstone_not(decode);
509}
510
511void hyperstone_device::op45()
512{
513   LOCAL_DECODE_INIT;
514   RRdecode(decode, 0, 1);
515   hyperstone_not(decode);
516}
517
518void hyperstone_device::op46()
519{
520   LOCAL_DECODE_INIT;
521   RRdecode(decode, 1, 0);
522   hyperstone_not(decode);
523}
524
525void hyperstone_device::op47()
526{
527   LOCAL_DECODE_INIT;
528   RRdecode(decode, 1, 1);
529   hyperstone_not(decode);
530}
531
532void hyperstone_device::op48()
533{
534   LOCAL_DECODE_INIT;
535   RRdecode(decode, 0, 0);
536   hyperstone_sub(decode);
537}
538
539void hyperstone_device::op49()
540{
541   LOCAL_DECODE_INIT;
542   RRdecode(decode, 0, 1);
543   hyperstone_sub(decode);
544}
545
546void hyperstone_device::op4a()
547{
548   LOCAL_DECODE_INIT;
549   RRdecode(decode, 1, 0);
550   hyperstone_sub(decode);
551}
552
553void hyperstone_device::op4b()
554{
555   LOCAL_DECODE_INIT;
556   RRdecode(decode, 1, 1);
557   hyperstone_sub(decode);
558}
559
560void hyperstone_device::op4c()
561{
562   LOCAL_DECODE_INIT;
563   RRdecode(decode, 0, 0);
564   hyperstone_subs(decode);
565}
566
567void hyperstone_device::op4d()
568{
569   LOCAL_DECODE_INIT;
570   RRdecode(decode, 0, 1);
571   hyperstone_subs(decode);
572}
573
574void hyperstone_device::op4e()
575{
576   LOCAL_DECODE_INIT;
577   RRdecode(decode, 1, 0);
578   hyperstone_subs(decode);
579}
580
581void hyperstone_device::op4f()
582{
583   LOCAL_DECODE_INIT;
584   RRdecode(decode, 1, 1);
585   hyperstone_subs(decode);
586}
587
588
589
590void hyperstone_device::op50()
591{
592   LOCAL_DECODE_INIT;
593   RRdecode(decode, 0, 0);
594   hyperstone_addc(decode);
595}
596
597void hyperstone_device::op51()
598{
599   LOCAL_DECODE_INIT;
600   RRdecode(decode, 0, 1);
601   hyperstone_addc(decode);
602}
603
604void hyperstone_device::op52()
605{
606   LOCAL_DECODE_INIT;
607   RRdecode(decode, 1, 0);
608   hyperstone_addc(decode);
609}
610
611void hyperstone_device::op53()
612{
613   LOCAL_DECODE_INIT;
614   RRdecode(decode, 1, 1);
615   hyperstone_addc(decode);
616}
617
618void hyperstone_device::op54()
619{
620   LOCAL_DECODE_INIT;
621   RRdecode(decode, 0, 0);
622   hyperstone_and(decode);
623}
624
625void hyperstone_device::op55()
626{
627   LOCAL_DECODE_INIT;
628   RRdecode(decode, 0, 1);
629   hyperstone_and(decode);
630}
631
632void hyperstone_device::op56()
633{
634   LOCAL_DECODE_INIT;
635   RRdecode(decode, 1, 0);
636   hyperstone_and(decode);
637}
638
639void hyperstone_device::op57()
640{
641   LOCAL_DECODE_INIT;
642   RRdecode(decode, 1, 1);
643   hyperstone_and(decode);
644}
645
646void hyperstone_device::op58()
647{
648   LOCAL_DECODE_INIT;
649   RRdecode(decode, 0, 0);
650   hyperstone_neg(decode);
651}
652
653void hyperstone_device::op59()
654{
655   LOCAL_DECODE_INIT;
656   RRdecode(decode, 0, 1);
657   hyperstone_neg(decode);
658}
659
660void hyperstone_device::op5a()
661{
662   LOCAL_DECODE_INIT;
663   RRdecode(decode, 1, 0);
664   hyperstone_neg(decode);
665}
666
667void hyperstone_device::op5b()
668{
669   LOCAL_DECODE_INIT;
670   RRdecode(decode, 1, 1);
671   hyperstone_neg(decode);
672}
673
674void hyperstone_device::op5c()
675{
676   LOCAL_DECODE_INIT;
677   RRdecode(decode, 0, 0);
678   hyperstone_negs(decode);
679}
680
681void hyperstone_device::op5d()
682{
683   LOCAL_DECODE_INIT;
684   RRdecode(decode, 0, 1);
685   hyperstone_negs(decode);
686}
687
688void hyperstone_device::op5e()
689{
690   LOCAL_DECODE_INIT;
691   RRdecode(decode, 1, 0);
692   hyperstone_negs(decode);
693}
694
695void hyperstone_device::op5f()
696{
697   LOCAL_DECODE_INIT;
698   RRdecode(decode, 1, 1);
699   hyperstone_negs(decode);
700}
701
702
703
704void hyperstone_device::op60()
705{
706   LOCAL_DECODE_INIT;
707   Rimmdecode(decode, 0, 0);
708   hyperstone_cmpi(decode);
709}
710
711void hyperstone_device::op61()
712{
713   LOCAL_DECODE_INIT;
714   Rimmdecode(decode, 0, 1);
715   hyperstone_cmpi(decode);
716}
717
718void hyperstone_device::op62()
719{
720   LOCAL_DECODE_INIT;
721   Rimmdecode(decode, 1, 0);
722   hyperstone_cmpi(decode);
723}
724
725void hyperstone_device::op63()
726{
727   LOCAL_DECODE_INIT;
728   Rimmdecode(decode, 1, 1);
729   hyperstone_cmpi(decode);
730}
731
732void hyperstone_device::op64()
733{
734   LOCAL_DECODE_INIT;
735   RimmdecodewithHflag(decode, 0, 0);
736   hyperstone_movi(decode);
737}
738
739void hyperstone_device::op65()
740{
741   LOCAL_DECODE_INIT;
742   RimmdecodewithHflag(decode, 0, 1);
743   hyperstone_movi(decode);
744}
745
746void hyperstone_device::op66()
747{
748   LOCAL_DECODE_INIT;
749   RimmdecodewithHflag(decode, 1, 0);
750   hyperstone_movi(decode);
751}
752
753void hyperstone_device::op67()
754{
755   LOCAL_DECODE_INIT;
756   RimmdecodewithHflag(decode, 1, 1);
757   hyperstone_movi(decode);
758}
759
760void hyperstone_device::op68()
761{
762   LOCAL_DECODE_INIT;
763   Rimmdecode(decode, 0, 0);
764   hyperstone_addi(decode);
765}
766
767void hyperstone_device::op69()
768{
769   LOCAL_DECODE_INIT;
770   Rimmdecode(decode, 0, 1);
771   hyperstone_addi(decode);
772}
773
774void hyperstone_device::op6a()
775{
776   LOCAL_DECODE_INIT;
777   Rimmdecode(decode, 1, 0);
778   hyperstone_addi(decode);
779}
780
781void hyperstone_device::op6b()
782{
783   LOCAL_DECODE_INIT;
784   Rimmdecode(decode, 1, 1);
785   hyperstone_addi(decode);
786}
787
788void hyperstone_device::op6c()
789{
790   LOCAL_DECODE_INIT;
791   Rimmdecode(decode, 0, 0);
792   hyperstone_addsi(decode);
793}
794
795void hyperstone_device::op6d()
796{
797   LOCAL_DECODE_INIT;
798   Rimmdecode(decode, 0, 1);
799   hyperstone_addsi(decode);
800}
801
802void hyperstone_device::op6e()
803{
804   LOCAL_DECODE_INIT;
805   Rimmdecode(decode, 1, 0);
806   hyperstone_addsi(decode);
807}
808
809void hyperstone_device::op6f()
810{
811   LOCAL_DECODE_INIT;
812   Rimmdecode(decode, 1, 1);
813   hyperstone_addsi(decode);
814}
815
816
817
818void hyperstone_device::op70()
819{
820   LOCAL_DECODE_INIT;
821   Rimmdecode(decode, 0, 0);
822   hyperstone_cmpbi(decode);
823}
824
825void hyperstone_device::op71()
826{
827   LOCAL_DECODE_INIT;
828   Rimmdecode(decode, 0, 1);
829   hyperstone_cmpbi(decode);
830}
831
832void hyperstone_device::op72()
833{
834   LOCAL_DECODE_INIT;
835   Rimmdecode(decode, 1, 0);
836   hyperstone_cmpbi(decode);
837}
838
839void hyperstone_device::op73()
840{
841   LOCAL_DECODE_INIT;
842   Rimmdecode(decode, 1, 1);
843   hyperstone_cmpbi(decode);
844}
845
846void hyperstone_device::op74()
847{
848   LOCAL_DECODE_INIT;
849   Rimmdecode(decode, 0, 0);
850   hyperstone_andni(decode);
851}
852
853void hyperstone_device::op75()
854{
855   LOCAL_DECODE_INIT;
856   Rimmdecode(decode, 0, 1);
857   hyperstone_andni(decode);
858}
859
860void hyperstone_device::op76()
861{
862   LOCAL_DECODE_INIT;
863   Rimmdecode(decode, 1, 0);
864   hyperstone_andni(decode);
865}
866
867void hyperstone_device::op77()
868{
869   LOCAL_DECODE_INIT;
870   Rimmdecode(decode, 1, 1);
871   hyperstone_andni(decode);
872}
873
874void hyperstone_device::op78()
875{
876   LOCAL_DECODE_INIT;
877   Rimmdecode(decode, 0, 0);
878   hyperstone_ori(decode);
879}
880
881void hyperstone_device::op79()
882{
883   LOCAL_DECODE_INIT;
884   Rimmdecode(decode, 0, 1);
885   hyperstone_ori(decode);
886}
887
888void hyperstone_device::op7a()
889{
890   LOCAL_DECODE_INIT;
891   Rimmdecode(decode, 1, 0);
892   hyperstone_ori(decode);
893}
894
895void hyperstone_device::op7b()
896{
897   LOCAL_DECODE_INIT;
898   Rimmdecode(decode, 1, 1);
899   hyperstone_ori(decode);
900}
901
902void hyperstone_device::op7c()
903{
904   LOCAL_DECODE_INIT;
905   Rimmdecode(decode, 0, 0);
906   hyperstone_xori(decode);
907}
908
909void hyperstone_device::op7d()
910{
911   LOCAL_DECODE_INIT;
912   Rimmdecode(decode, 0, 1);
913   hyperstone_xori(decode);
914}
915
916void hyperstone_device::op7e()
917{
918   LOCAL_DECODE_INIT;
919   Rimmdecode(decode, 1, 0);
920   hyperstone_xori(decode);
921}
922
923void hyperstone_device::op7f()
924{
925   LOCAL_DECODE_INIT;
926   Rimmdecode(decode, 1, 1);
927   hyperstone_xori(decode);
928}
929
930
931
932void hyperstone_device::op80()
933{
934   LOCAL_DECODE_INIT;
935   Lndecode(decode);
936   hyperstone_shrdi(decode);
937}
938
939void hyperstone_device::op81()
940{
941   LOCAL_DECODE_INIT;
942   Lndecode(decode);
943   hyperstone_shrdi(decode);
944}
945
946void hyperstone_device::op82()
947{
948   LOCAL_DECODE_INIT;
949   LLdecode(decode);
950   hyperstone_shrd(decode);
951}
952
953void hyperstone_device::op83()
954{
955   LOCAL_DECODE_INIT;
956   LLdecode(decode);
957   hyperstone_shr(decode);
958}
959
960void hyperstone_device::op84()
961{
962   LOCAL_DECODE_INIT;
963   Lndecode(decode);
964   hyperstone_sardi(decode);
965}
966
967void hyperstone_device::op85()
968{
969   LOCAL_DECODE_INIT;
970   Lndecode(decode);
971   hyperstone_sardi(decode);
972}
973
974void hyperstone_device::op86()
975{
976   LOCAL_DECODE_INIT;
977   LLdecode(decode);
978   hyperstone_sard(decode);
979}
980
981void hyperstone_device::op87()
982{
983   LOCAL_DECODE_INIT;
984   LLdecode(decode);
985   hyperstone_sar(decode);
986}
987
988void hyperstone_device::op88()
989{
990   LOCAL_DECODE_INIT;
991   Lndecode(decode);
992   hyperstone_shldi(decode);
993}
994
995void hyperstone_device::op89()
996{
997   LOCAL_DECODE_INIT;
998   Lndecode(decode);
999   hyperstone_shldi(decode);
1000}
1001
1002void hyperstone_device::op8a()
1003{
1004   LOCAL_DECODE_INIT;
1005   LLdecode(decode);
1006   hyperstone_shld(decode);
1007}
1008
1009void hyperstone_device::op8b()
1010{
1011   LOCAL_DECODE_INIT;
1012   LLdecode(decode);
1013   hyperstone_shl(decode);
1014}
1015
1016void hyperstone_device::op8c()
1017{
1018   LOCAL_DECODE_INIT;
1019   no_decode(decode);
1020   reserved(decode);
1021}
1022
1023void hyperstone_device::op8d()
1024{
1025   LOCAL_DECODE_INIT;
1026   no_decode(decode);
1027   reserved(decode);
1028}
1029
1030void hyperstone_device::op8e()
1031{
1032   LOCAL_DECODE_INIT;
1033   LLdecode(decode);
1034   hyperstone_testlz(decode);
1035}
1036
1037void hyperstone_device::op8f()
1038{
1039   LOCAL_DECODE_INIT;
1040   LLdecode(decode);
1041   hyperstone_rol(decode);
1042}
1043
1044
1045
1046void hyperstone_device::op90()
1047{
1048   LOCAL_DECODE_INIT;
1049   RRdisdecode(decode, 0, 0);
1050   hyperstone_ldxx1(decode);
1051}
1052
1053void hyperstone_device::op91()
1054{
1055   LOCAL_DECODE_INIT;
1056   RRdisdecode(decode, 0, 1);
1057   hyperstone_ldxx1(decode);
1058}
1059
1060void hyperstone_device::op92()
1061{
1062   LOCAL_DECODE_INIT;
1063   RRdisdecode(decode, 1, 0);
1064   hyperstone_ldxx1(decode);
1065}
1066
1067void hyperstone_device::op93()
1068{
1069   LOCAL_DECODE_INIT;
1070   RRdisdecode(decode, 1, 1);
1071   hyperstone_ldxx1(decode);
1072}
1073
1074void hyperstone_device::op94()
1075{
1076   LOCAL_DECODE_INIT;
1077   RRdisdecode(decode, 0, 0);
1078   hyperstone_ldxx2(decode);
1079}
1080
1081void hyperstone_device::op95()
1082{
1083   LOCAL_DECODE_INIT;
1084   RRdisdecode(decode, 0, 1);
1085   hyperstone_ldxx2(decode);
1086}
1087
1088void hyperstone_device::op96()
1089{
1090   LOCAL_DECODE_INIT;
1091   RRdisdecode(decode, 1, 0);
1092   hyperstone_ldxx2(decode);
1093}
1094
1095void hyperstone_device::op97()
1096{
1097   LOCAL_DECODE_INIT;
1098   RRdisdecode(decode, 1, 1);
1099   hyperstone_ldxx2(decode);
1100}
1101
1102void hyperstone_device::op98()
1103{
1104   LOCAL_DECODE_INIT;
1105   RRdisdecode(decode, 0, 0);
1106   hyperstone_stxx1(decode);
1107}
1108
1109void hyperstone_device::op99()
1110{
1111   LOCAL_DECODE_INIT;
1112   RRdisdecode(decode, 0, 1);
1113   hyperstone_stxx1(decode);
1114}
1115
1116void hyperstone_device::op9a()
1117{
1118   LOCAL_DECODE_INIT;
1119   RRdisdecode(decode, 1, 0);
1120   hyperstone_stxx1(decode);
1121}
1122
1123void hyperstone_device::op9b()
1124{
1125   LOCAL_DECODE_INIT;
1126   RRdisdecode(decode, 1, 1);
1127   hyperstone_stxx1(decode);
1128}
1129
1130void hyperstone_device::op9c()
1131{
1132   LOCAL_DECODE_INIT;
1133   RRdisdecode(decode, 0, 0);
1134   hyperstone_stxx2(decode);
1135}
1136
1137void hyperstone_device::op9d()
1138{
1139   LOCAL_DECODE_INIT;
1140   RRdisdecode(decode, 0, 1);
1141   hyperstone_stxx2(decode);
1142}
1143
1144void hyperstone_device::op9e()
1145{
1146   LOCAL_DECODE_INIT;
1147   RRdisdecode(decode, 1, 0);
1148   hyperstone_stxx2(decode);
1149}
1150
1151void hyperstone_device::op9f()
1152{
1153   LOCAL_DECODE_INIT;
1154   RRdisdecode(decode, 1, 1);
1155   hyperstone_stxx2(decode);
1156}
1157
1158
1159
1160void hyperstone_device::opa0()
1161{
1162   LOCAL_DECODE_INIT;
1163   Rndecode(decode, 0);
1164   hyperstone_shri(decode);
1165}
1166
1167void hyperstone_device::opa1()
1168{
1169   LOCAL_DECODE_INIT;
1170   Rndecode(decode, 0);
1171   hyperstone_shri(decode);
1172}
1173
1174void hyperstone_device::opa2()
1175{
1176   LOCAL_DECODE_INIT;
1177   Rndecode(decode, 1);
1178   hyperstone_shri(decode);
1179}
1180
1181void hyperstone_device::opa3()
1182{
1183   LOCAL_DECODE_INIT;
1184   Rndecode(decode, 1);
1185   hyperstone_shri(decode);
1186}
1187
1188void hyperstone_device::opa4()
1189{
1190   LOCAL_DECODE_INIT;
1191   Rndecode(decode, 0);
1192   hyperstone_sari(decode);
1193}
1194
1195void hyperstone_device::opa5()
1196{
1197   LOCAL_DECODE_INIT;
1198   Rndecode(decode, 0);
1199   hyperstone_sari(decode);
1200}
1201
1202void hyperstone_device::opa6()
1203{
1204   LOCAL_DECODE_INIT;
1205   Rndecode(decode, 1);
1206   hyperstone_sari(decode);
1207}
1208
1209void hyperstone_device::opa7()
1210{
1211   LOCAL_DECODE_INIT;
1212   Rndecode(decode, 1);
1213   hyperstone_sari(decode);
1214}
1215
1216void hyperstone_device::opa8()
1217{
1218   LOCAL_DECODE_INIT;
1219   Rndecode(decode, 0);
1220   hyperstone_shli(decode);
1221}
1222
1223void hyperstone_device::opa9()
1224{
1225   LOCAL_DECODE_INIT;
1226   Rndecode(decode, 0);
1227   hyperstone_shli(decode);
1228}
1229
1230void hyperstone_device::opaa()
1231{
1232   LOCAL_DECODE_INIT;
1233   Rndecode(decode, 1);
1234   hyperstone_shli(decode);
1235}
1236
1237void hyperstone_device::opab()
1238{
1239   LOCAL_DECODE_INIT;
1240   Rndecode(decode, 1);
1241   hyperstone_shli(decode);
1242}
1243
1244void hyperstone_device::opac()
1245{
1246   LOCAL_DECODE_INIT;
1247   no_decode(decode);
1248   reserved(decode);
1249}
1250
1251void hyperstone_device::opad()
1252{
1253   LOCAL_DECODE_INIT;
1254   no_decode(decode);
1255   reserved(decode);
1256}
1257
1258void hyperstone_device::opae()
1259{
1260   LOCAL_DECODE_INIT;
1261   no_decode(decode);
1262   reserved(decode);
1263}
1264
1265void hyperstone_device::opaf()
1266{
1267   LOCAL_DECODE_INIT;
1268   no_decode(decode);
1269   reserved(decode);
1270}
1271
1272
1273
1274void hyperstone_device::opb0()
1275{
1276   LOCAL_DECODE_INIT;
1277   RRdecode(decode, 0, 0);
1278   hyperstone_mulu(decode);
1279}
1280
1281void hyperstone_device::opb1()
1282{
1283   LOCAL_DECODE_INIT;
1284   RRdecode(decode, 0, 1);
1285   hyperstone_mulu(decode);
1286}
1287
1288void hyperstone_device::opb2()
1289{
1290   LOCAL_DECODE_INIT;
1291   RRdecode(decode, 1, 0);
1292   hyperstone_mulu(decode);
1293}
1294
1295void hyperstone_device::opb3()
1296{
1297   LOCAL_DECODE_INIT;
1298   RRdecode(decode, 1, 1);
1299   hyperstone_mulu(decode);
1300}
1301
1302void hyperstone_device::opb4()
1303{
1304   LOCAL_DECODE_INIT;
1305   RRdecode(decode, 0, 0);
1306   hyperstone_muls(decode);
1307}
1308
1309void hyperstone_device::opb5()
1310{
1311   LOCAL_DECODE_INIT;
1312   RRdecode(decode, 0, 1);
1313   hyperstone_muls(decode);
1314}
1315
1316void hyperstone_device::opb6()
1317{
1318   LOCAL_DECODE_INIT;
1319   RRdecode(decode, 1, 0);
1320   hyperstone_muls(decode);
1321}
1322
1323void hyperstone_device::opb7()
1324{
1325   LOCAL_DECODE_INIT;
1326   RRdecode(decode, 1, 1);
1327   hyperstone_muls(decode);
1328}
1329
1330void hyperstone_device::opb8()
1331{
1332   LOCAL_DECODE_INIT;
1333   Rndecode(decode, 0);
1334   hyperstone_set(decode);
1335}
1336
1337void hyperstone_device::opb9()
1338{
1339   LOCAL_DECODE_INIT;
1340   Rndecode(decode, 0);
1341   hyperstone_set(decode);
1342}
1343
1344void hyperstone_device::opba()
1345{
1346   LOCAL_DECODE_INIT;
1347   Rndecode(decode, 1);
1348   hyperstone_set(decode);
1349}
1350
1351void hyperstone_device::opbb()
1352{
1353   LOCAL_DECODE_INIT;
1354   Rndecode(decode, 1);
1355   hyperstone_set(decode);
1356}
1357
1358void hyperstone_device::opbc()
1359{
1360   LOCAL_DECODE_INIT;
1361   RRdecode(decode, 0, 0);
1362   hyperstone_mul(decode);
1363}
1364
1365void hyperstone_device::opbd()
1366{
1367   LOCAL_DECODE_INIT;
1368   RRdecode(decode, 0, 1);
1369   hyperstone_mul(decode);
1370}
1371
1372void hyperstone_device::opbe()
1373{
1374   LOCAL_DECODE_INIT;
1375   RRdecode(decode, 1, 0);
1376   hyperstone_mul(decode);
1377}
1378
1379void hyperstone_device::opbf()
1380{
1381   LOCAL_DECODE_INIT;
1382   RRdecode(decode, 1, 1);
1383   hyperstone_mul(decode);
1384}
1385
1386
1387
1388void hyperstone_device::opc0()
1389{
1390   LOCAL_DECODE_INIT;
1391   LLdecode(decode);
1392   hyperstone_fadd(decode);
1393}
1394
1395void hyperstone_device::opc1()
1396{
1397   LOCAL_DECODE_INIT;
1398   LLdecode(decode);
1399   hyperstone_faddd(decode);
1400}
1401
1402void hyperstone_device::opc2()
1403{
1404   LOCAL_DECODE_INIT;
1405   LLdecode(decode);
1406   hyperstone_fsub(decode);
1407}
1408
1409void hyperstone_device::opc3()
1410{
1411   LOCAL_DECODE_INIT;
1412   LLdecode(decode);
1413   hyperstone_fsubd(decode);
1414}
1415
1416void hyperstone_device::opc4()
1417{
1418   LOCAL_DECODE_INIT;
1419   LLdecode(decode);
1420   hyperstone_fmul(decode);
1421}
1422
1423void hyperstone_device::opc5()
1424{
1425   LOCAL_DECODE_INIT;
1426   LLdecode(decode);
1427   hyperstone_fmuld(decode);
1428}
1429
1430void hyperstone_device::opc6()
1431{
1432   LOCAL_DECODE_INIT;
1433   LLdecode(decode);
1434   hyperstone_fdiv(decode);
1435}
1436
1437void hyperstone_device::opc7()
1438{
1439   LOCAL_DECODE_INIT;
1440   LLdecode(decode);
1441   hyperstone_fdivd(decode);
1442}
1443
1444void hyperstone_device::opc8()
1445{
1446   LOCAL_DECODE_INIT;
1447   LLdecode(decode);
1448   hyperstone_fcmp(decode);
1449}
1450
1451void hyperstone_device::opc9()
1452{
1453   LOCAL_DECODE_INIT;
1454   LLdecode(decode);
1455   hyperstone_fcmpd(decode);
1456}
1457
1458void hyperstone_device::opca()
1459{
1460   LOCAL_DECODE_INIT;
1461   LLdecode(decode);
1462   hyperstone_fcmpu(decode);
1463}
1464
1465void hyperstone_device::opcb()
1466{
1467   LOCAL_DECODE_INIT;
1468   LLdecode(decode);
1469   hyperstone_fcmpud(decode);
1470}
1471
1472void hyperstone_device::opcc()
1473{
1474   LOCAL_DECODE_INIT;
1475   LLdecode(decode);
1476   hyperstone_fcvt(decode);
1477}
1478
1479void hyperstone_device::opcd()
1480{
1481   LOCAL_DECODE_INIT;
1482   LLdecode(decode);
1483   hyperstone_fcvtd(decode);
1484}
1485
1486void hyperstone_device::opce()
1487{
1488   LOCAL_DECODE_INIT;
1489   LLextdecode(decode);
1490   hyperstone_extend(decode);
1491}
1492
1493void hyperstone_device::opcf()
1494{
1495   LOCAL_DECODE_INIT;
1496   LLdecode(decode);
1497   hyperstone_do(decode);
1498}
1499
1500
1501
1502void hyperstone_device::opd0()
1503{
1504   LOCAL_DECODE_INIT;
1505   LRdecode(decode, 0);
1506   hyperstone_ldwr(decode);
1507}
1508
1509void hyperstone_device::opd1()
1510{
1511   LOCAL_DECODE_INIT;
1512   LRdecode(decode, 1);
1513   hyperstone_ldwr(decode);
1514}
1515
1516void hyperstone_device::opd2()
1517{
1518   LOCAL_DECODE_INIT;
1519   LRdecode(decode, 0);
1520   hyperstone_lddr(decode);
1521}
1522
1523void hyperstone_device::opd3()
1524{
1525   LOCAL_DECODE_INIT;
1526   LRdecode(decode, 1);
1527   hyperstone_lddr(decode);
1528}
1529
1530void hyperstone_device::opd4()
1531{
1532   LOCAL_DECODE_INIT;
1533   LRdecode(decode, 0);
1534   hyperstone_ldwp(decode);
1535}
1536
1537void hyperstone_device::opd5()
1538{
1539   LOCAL_DECODE_INIT;
1540   LRdecode(decode, 1);
1541   hyperstone_ldwp(decode);
1542}
1543
1544void hyperstone_device::opd6()
1545{
1546   LOCAL_DECODE_INIT;
1547   LRdecode(decode, 0);
1548   hyperstone_lddp(decode);
1549}
1550
1551void hyperstone_device::opd7()
1552{
1553   LOCAL_DECODE_INIT;
1554   LRdecode(decode, 1);
1555   hyperstone_lddp(decode);
1556}
1557
1558void hyperstone_device::opd8()
1559{
1560   LOCAL_DECODE_INIT;
1561   LRdecode(decode, 0);
1562   hyperstone_stwr(decode);
1563}
1564
1565void hyperstone_device::opd9()
1566{
1567   LOCAL_DECODE_INIT;
1568   LRdecode(decode, 1);
1569   hyperstone_stwr(decode);
1570}
1571
1572void hyperstone_device::opda()
1573{
1574   LOCAL_DECODE_INIT;
1575   LRdecode(decode, 0);
1576   hyperstone_stdr(decode);
1577}
1578
1579void hyperstone_device::opdb()
1580{
1581   LOCAL_DECODE_INIT;
1582   LRdecode(decode, 1);
1583   hyperstone_stdr(decode);
1584}
1585
1586void hyperstone_device::opdc()
1587{
1588   LOCAL_DECODE_INIT;
1589   LRdecode(decode, 0);
1590   hyperstone_stwp(decode);
1591}
1592
1593void hyperstone_device::opdd()
1594{
1595   LOCAL_DECODE_INIT;
1596   LRdecode(decode, 1);
1597   hyperstone_stwp(decode);
1598}
1599
1600void hyperstone_device::opde()
1601{
1602   LOCAL_DECODE_INIT;
1603   LRdecode(decode, 0);
1604   hyperstone_stdp(decode);
1605}
1606
1607void hyperstone_device::opdf()
1608{
1609   LOCAL_DECODE_INIT;
1610   LRdecode(decode, 1);
1611   hyperstone_stdp(decode);
1612}
1613
1614
1615
1616void hyperstone_device::ope0()
1617{
1618   LOCAL_DECODE_INIT;
1619   PCreldecode(decode);
1620   hyperstone_dbv(decode);
1621}
1622
1623void hyperstone_device::ope1()
1624{
1625   LOCAL_DECODE_INIT;
1626   PCreldecode(decode);
1627   hyperstone_dbnv(decode);
1628}
1629
1630void hyperstone_device::ope2()
1631{
1632   LOCAL_DECODE_INIT;
1633   PCreldecode(decode);
1634   hyperstone_dbe(decode);
1635}
1636
1637void hyperstone_device::ope3()
1638{
1639   LOCAL_DECODE_INIT;
1640   PCreldecode(decode);
1641   hyperstone_dbne(decode);
1642}
1643
1644void hyperstone_device::ope4()
1645{
1646   LOCAL_DECODE_INIT;
1647   PCreldecode(decode);
1648   hyperstone_dbc(decode);
1649}
1650
1651void hyperstone_device::ope5()
1652{
1653   LOCAL_DECODE_INIT;
1654   PCreldecode(decode);
1655   hyperstone_dbnc(decode);
1656}
1657
1658void hyperstone_device::ope6()
1659{
1660   LOCAL_DECODE_INIT;
1661   PCreldecode(decode);
1662   hyperstone_dbse(decode);
1663}
1664
1665void hyperstone_device::ope7()
1666{
1667   LOCAL_DECODE_INIT;
1668   PCreldecode(decode);
1669   hyperstone_dbht(decode);
1670}
1671
1672void hyperstone_device::ope8()
1673{
1674   LOCAL_DECODE_INIT;
1675   PCreldecode(decode);
1676   hyperstone_dbn(decode);
1677}
1678
1679void hyperstone_device::ope9()
1680{
1681   LOCAL_DECODE_INIT;
1682   PCreldecode(decode);
1683   hyperstone_dbnn(decode);
1684}
1685
1686void hyperstone_device::opea()
1687{
1688   LOCAL_DECODE_INIT;
1689   PCreldecode(decode);
1690   hyperstone_dble(decode);
1691}
1692
1693void hyperstone_device::opeb()
1694{
1695   LOCAL_DECODE_INIT;
1696   PCreldecode(decode);
1697   hyperstone_dbgt(decode);
1698}
1699
1700void hyperstone_device::opec()
1701{
1702   LOCAL_DECODE_INIT;
1703   PCreldecode(decode);
1704   hyperstone_dbr(decode);
1705}
1706
1707void hyperstone_device::oped()
1708{
1709   LOCAL_DECODE_INIT;
1710   LLdecode(decode);
1711   hyperstone_frame(decode);
1712}
1713
1714void hyperstone_device::opee()
1715{
1716   LOCAL_DECODE_INIT;
1717   LRconstdecode(decode, 0);
1718   hyperstone_call(decode);
1719}
1720
1721void hyperstone_device::opef()
1722{
1723   LOCAL_DECODE_INIT;
1724   LRconstdecode(decode, 1);
1725   hyperstone_call(decode);
1726}
1727
1728
1729
1730void hyperstone_device::opf0()
1731{
1732   LOCAL_DECODE_INIT;
1733   PCreldecode(decode);
1734   hyperstone_bv(decode);
1735}
1736
1737void hyperstone_device::opf1()
1738{
1739   LOCAL_DECODE_INIT;
1740   PCreldecode(decode);
1741   hyperstone_bnv(decode);
1742}
1743
1744void hyperstone_device::opf2()
1745{
1746   LOCAL_DECODE_INIT;
1747   PCreldecode(decode);
1748   hyperstone_be(decode);
1749}
1750
1751void hyperstone_device::opf3()
1752{
1753   LOCAL_DECODE_INIT;
1754   PCreldecode(decode);
1755   hyperstone_bne(decode);
1756}
1757
1758void hyperstone_device::opf4()
1759{
1760   LOCAL_DECODE_INIT;
1761   PCreldecode(decode);
1762   hyperstone_bc(decode);
1763}
1764
1765void hyperstone_device::opf5()
1766{
1767   LOCAL_DECODE_INIT;
1768   PCreldecode(decode);
1769   hyperstone_bnc(decode);
1770}
1771
1772void hyperstone_device::opf6()
1773{
1774   LOCAL_DECODE_INIT;
1775   PCreldecode(decode);
1776   hyperstone_bse(decode);
1777}
1778
1779void hyperstone_device::opf7()
1780{
1781   LOCAL_DECODE_INIT;
1782   PCreldecode(decode);
1783   hyperstone_bht(decode);
1784}
1785
1786void hyperstone_device::opf8()
1787{
1788   LOCAL_DECODE_INIT;
1789   PCreldecode(decode);
1790   hyperstone_bn(decode);
1791}
1792
1793void hyperstone_device::opf9()
1794{
1795   LOCAL_DECODE_INIT;
1796   PCreldecode(decode);
1797   hyperstone_bnn(decode);
1798}
1799
1800void hyperstone_device::opfa()
1801{
1802   LOCAL_DECODE_INIT;
1803   PCreldecode(decode);
1804   hyperstone_ble(decode);
1805}
1806
1807void hyperstone_device::opfb()
1808{
1809   LOCAL_DECODE_INIT;
1810   PCreldecode(decode);
1811   hyperstone_bgt(decode);
1812}
1813
1814void hyperstone_device::opfc()
1815{
1816   LOCAL_DECODE_INIT;
1817   PCreldecode(decode);
1818   hyperstone_br(decode);
1819}
1820
1821void hyperstone_device::opfd()
1822{
1823   LOCAL_DECODE_INIT;
1824   PCadrdecode(decode);
1825   hyperstone_trap(decode);
1826}
1827
1828void hyperstone_device::opfe()
1829{
1830   LOCAL_DECODE_INIT;
1831   PCadrdecode(decode);
1832   hyperstone_trap(decode);
1833}
1834
1835void hyperstone_device::opff()
1836{
1837   LOCAL_DECODE_INIT;
1838   PCadrdecode(decode);
1839   hyperstone_trap(decode);
1840}
1841
1842const hyperstone_device::ophandler hyperstone_device::s_opcodetable[256] =
1843{
1844   &hyperstone_device::op00, &hyperstone_device::op01, &hyperstone_device::op02, &hyperstone_device::op03,
1845   &hyperstone_device::op04, &hyperstone_device::op05, &hyperstone_device::op06, &hyperstone_device::op07,
1846   &hyperstone_device::op08, &hyperstone_device::op09, &hyperstone_device::op0a, &hyperstone_device::op0b,
1847   &hyperstone_device::op0c, &hyperstone_device::op0d, &hyperstone_device::op0e, &hyperstone_device::op0f,
1848
1849   &hyperstone_device::op10, &hyperstone_device::op11, &hyperstone_device::op12, &hyperstone_device::op13,
1850   &hyperstone_device::op14, &hyperstone_device::op15, &hyperstone_device::op16, &hyperstone_device::op17,
1851   &hyperstone_device::op18, &hyperstone_device::op19, &hyperstone_device::op1a, &hyperstone_device::op1b,
1852   &hyperstone_device::op1c, &hyperstone_device::op1d, &hyperstone_device::op1e, &hyperstone_device::op1f,
1853
1854   &hyperstone_device::op20, &hyperstone_device::op21, &hyperstone_device::op22, &hyperstone_device::op23,
1855   &hyperstone_device::op24, &hyperstone_device::op25, &hyperstone_device::op26, &hyperstone_device::op27,
1856   &hyperstone_device::op28, &hyperstone_device::op29, &hyperstone_device::op2a, &hyperstone_device::op2b,
1857   &hyperstone_device::op2c, &hyperstone_device::op2d, &hyperstone_device::op2e, &hyperstone_device::op2f,
1858
1859   &hyperstone_device::op30, &hyperstone_device::op31, &hyperstone_device::op32, &hyperstone_device::op33,
1860   &hyperstone_device::op34, &hyperstone_device::op35, &hyperstone_device::op36, &hyperstone_device::op37,
1861   &hyperstone_device::op38, &hyperstone_device::op39, &hyperstone_device::op3a, &hyperstone_device::op3b,
1862   &hyperstone_device::op3c, &hyperstone_device::op3d, &hyperstone_device::op3e, &hyperstone_device::op3f,
1863
1864   &hyperstone_device::op40, &hyperstone_device::op41, &hyperstone_device::op42, &hyperstone_device::op43,
1865   &hyperstone_device::op44, &hyperstone_device::op45, &hyperstone_device::op46, &hyperstone_device::op47,
1866   &hyperstone_device::op48, &hyperstone_device::op49, &hyperstone_device::op4a, &hyperstone_device::op4b,
1867   &hyperstone_device::op4c, &hyperstone_device::op4d, &hyperstone_device::op4e, &hyperstone_device::op4f,
1868
1869   &hyperstone_device::op50, &hyperstone_device::op51, &hyperstone_device::op52, &hyperstone_device::op53,
1870   &hyperstone_device::op54, &hyperstone_device::op55, &hyperstone_device::op56, &hyperstone_device::op57,
1871   &hyperstone_device::op58, &hyperstone_device::op59, &hyperstone_device::op5a, &hyperstone_device::op5b,
1872   &hyperstone_device::op5c, &hyperstone_device::op5d, &hyperstone_device::op5e, &hyperstone_device::op5f,
1873
1874   &hyperstone_device::op60, &hyperstone_device::op61, &hyperstone_device::op62, &hyperstone_device::op63,
1875   &hyperstone_device::op64, &hyperstone_device::op65, &hyperstone_device::op66, &hyperstone_device::op67,
1876   &hyperstone_device::op68, &hyperstone_device::op69, &hyperstone_device::op6a, &hyperstone_device::op6b,
1877   &hyperstone_device::op6c, &hyperstone_device::op6d, &hyperstone_device::op6e, &hyperstone_device::op6f,
1878
1879   &hyperstone_device::op70, &hyperstone_device::op71, &hyperstone_device::op72, &hyperstone_device::op73,
1880   &hyperstone_device::op74, &hyperstone_device::op75, &hyperstone_device::op76, &hyperstone_device::op77,
1881   &hyperstone_device::op78, &hyperstone_device::op79, &hyperstone_device::op7a, &hyperstone_device::op7b,
1882   &hyperstone_device::op7c, &hyperstone_device::op7d, &hyperstone_device::op7e, &hyperstone_device::op7f,
1883
1884   &hyperstone_device::op80, &hyperstone_device::op81, &hyperstone_device::op82, &hyperstone_device::op83,
1885   &hyperstone_device::op84, &hyperstone_device::op85, &hyperstone_device::op86, &hyperstone_device::op87,
1886   &hyperstone_device::op88, &hyperstone_device::op89, &hyperstone_device::op8a, &hyperstone_device::op8b,
1887   &hyperstone_device::op8c, &hyperstone_device::op8d, &hyperstone_device::op8e, &hyperstone_device::op8f,
1888
1889   &hyperstone_device::op90, &hyperstone_device::op91, &hyperstone_device::op92, &hyperstone_device::op93,
1890   &hyperstone_device::op94, &hyperstone_device::op95, &hyperstone_device::op96, &hyperstone_device::op97,
1891   &hyperstone_device::op98, &hyperstone_device::op99, &hyperstone_device::op9a, &hyperstone_device::op9b,
1892   &hyperstone_device::op9c, &hyperstone_device::op9d, &hyperstone_device::op9e, &hyperstone_device::op9f,
1893
1894   &hyperstone_device::opa0, &hyperstone_device::opa1, &hyperstone_device::opa2, &hyperstone_device::opa3,
1895   &hyperstone_device::opa4, &hyperstone_device::opa5, &hyperstone_device::opa6, &hyperstone_device::opa7,
1896   &hyperstone_device::opa8, &hyperstone_device::opa9, &hyperstone_device::opaa, &hyperstone_device::opab,
1897   &hyperstone_device::opac, &hyperstone_device::opad, &hyperstone_device::opae, &hyperstone_device::opaf,
1898
1899   &hyperstone_device::opb0, &hyperstone_device::opb1, &hyperstone_device::opb2, &hyperstone_device::opb3,
1900   &hyperstone_device::opb4, &hyperstone_device::opb5, &hyperstone_device::opb6, &hyperstone_device::opb7,
1901   &hyperstone_device::opb8, &hyperstone_device::opb9, &hyperstone_device::opba, &hyperstone_device::opbb,
1902   &hyperstone_device::opbc, &hyperstone_device::opbd, &hyperstone_device::opbe, &hyperstone_device::opbf,
1903
1904   &hyperstone_device::opc0, &hyperstone_device::opc1, &hyperstone_device::opc2, &hyperstone_device::opc3,
1905   &hyperstone_device::opc4, &hyperstone_device::opc5, &hyperstone_device::opc6, &hyperstone_device::opc7,
1906   &hyperstone_device::opc8, &hyperstone_device::opc9, &hyperstone_device::opca, &hyperstone_device::opcb,
1907   &hyperstone_device::opcc, &hyperstone_device::opcd, &hyperstone_device::opce, &hyperstone_device::opcf,
1908
1909   &hyperstone_device::opd0, &hyperstone_device::opd1, &hyperstone_device::opd2, &hyperstone_device::opd3,
1910   &hyperstone_device::opd4, &hyperstone_device::opd5, &hyperstone_device::opd6, &hyperstone_device::opd7,
1911   &hyperstone_device::opd8, &hyperstone_device::opd9, &hyperstone_device::opda, &hyperstone_device::opdb,
1912   &hyperstone_device::opdc, &hyperstone_device::opdd, &hyperstone_device::opde, &hyperstone_device::opdf,
1913
1914   &hyperstone_device::ope0, &hyperstone_device::ope1, &hyperstone_device::ope2, &hyperstone_device::ope3,
1915   &hyperstone_device::ope4, &hyperstone_device::ope5, &hyperstone_device::ope6, &hyperstone_device::ope7,
1916   &hyperstone_device::ope8, &hyperstone_device::ope9, &hyperstone_device::opea, &hyperstone_device::opeb,
1917   &hyperstone_device::opec, &hyperstone_device::oped, &hyperstone_device::opee, &hyperstone_device::opef,
1918
1919   &hyperstone_device::opf0, &hyperstone_device::opf1, &hyperstone_device::opf2, &hyperstone_device::opf3,
1920   &hyperstone_device::opf4, &hyperstone_device::opf5, &hyperstone_device::opf6, &hyperstone_device::opf7,
1921   &hyperstone_device::opf8, &hyperstone_device::opf9, &hyperstone_device::opfa, &hyperstone_device::opfb,
1922   &hyperstone_device::opfc, &hyperstone_device::opfd, &hyperstone_device::opfe, &hyperstone_device::opff
1923};
trunk/src/emu/cpu/e132xs/e132xs.c
r28738r28739
48614861}
48624862
48634863
4864#include "e132xsop.c"
4864#include "e132xsop.inc"
48654865
48664866//**************************************************************************
48674867//  CORE EXECUTION LOOP
trunk/src/emu/cpu/e132xs/e132xsop.inc
r0r28739
1#define LOCAL_DECODE_INIT \
2   struct regs_decode decode_state; \
3   struct regs_decode *decode = &decode_state; \
4\
5   /* clear 'current regs / flags' */ \
6   decode->src = 0; \
7   decode->dst = 0; \
8   decode->src_value = 0; \
9   decode->next_src_value = 0; \
10   decode->dst_value = 0; \
11   decode->next_dst_value = 0; \
12   decode->sub_type = 0; \
13   decode->extra.u = 0; \
14   decode->src_is_local = 0; \
15   decode->dst_is_local = 0; \
16   decode->same_src_dst = 0; \
17   decode->same_src_dstf = 0; \
18   decode->same_srcf_dst = 0;
19
20void hyperstone_device::op00()
21{
22   LOCAL_DECODE_INIT;
23   RRdecode(decode, 0, 0);
24   hyperstone_chk(decode);
25}
26
27void hyperstone_device::op01()
28{
29   LOCAL_DECODE_INIT;
30   RRdecode(decode, 0, 1);
31   hyperstone_chk(decode);
32}
33
34void hyperstone_device::op02()
35{
36   LOCAL_DECODE_INIT;
37   RRdecode(decode, 1, 0);
38   hyperstone_chk(decode);
39}
40
41void hyperstone_device::op03()
42{
43   LOCAL_DECODE_INIT;
44   RRdecode(decode, 1, 1);
45   hyperstone_chk(decode);
46}
47
48void hyperstone_device::op04()
49{
50   LOCAL_DECODE_INIT;
51   RRdecode(decode, 0, 0);
52   hyperstone_movd(decode);
53}
54
55void hyperstone_device::op05()
56{
57   LOCAL_DECODE_INIT;
58   RRdecode(decode, 0, 1);
59   hyperstone_movd(decode);
60}
61
62void hyperstone_device::op06()
63{
64   LOCAL_DECODE_INIT;
65   RRdecode(decode, 1, 0);
66   hyperstone_movd(decode);
67}
68
69void hyperstone_device::op07()
70{
71   LOCAL_DECODE_INIT;
72   RRdecode(decode, 1, 1);
73   hyperstone_movd(decode);
74}
75
76void hyperstone_device::op08()
77{
78   LOCAL_DECODE_INIT;
79   RRdecode(decode, 0, 0);
80   hyperstone_divu(decode);
81}
82
83void hyperstone_device::op09()
84{
85   LOCAL_DECODE_INIT;
86   RRdecode(decode, 0, 1);
87   hyperstone_divu(decode);
88}
89
90void hyperstone_device::op0a()
91{
92   LOCAL_DECODE_INIT;
93   RRdecode(decode, 1, 0);
94   hyperstone_divu(decode);
95}
96
97void hyperstone_device::op0b()
98{
99   LOCAL_DECODE_INIT;
100   RRdecode(decode, 1, 1);
101   hyperstone_divu(decode);
102}
103
104void hyperstone_device::op0c()
105{
106   LOCAL_DECODE_INIT;
107   RRdecode(decode, 0, 0);
108   hyperstone_divs(decode);
109}
110
111void hyperstone_device::op0d()
112{
113   LOCAL_DECODE_INIT;
114   RRdecode(decode, 0, 1);
115   hyperstone_divs(decode);
116}
117
118void hyperstone_device::op0e()
119{
120   LOCAL_DECODE_INIT;
121   RRdecode(decode, 1, 0);
122   hyperstone_divs(decode);
123}
124
125void hyperstone_device::op0f()
126{
127   LOCAL_DECODE_INIT;
128   RRdecode(decode, 1, 1);
129   hyperstone_divs(decode);
130}
131
132
133
134void hyperstone_device::op10()
135{
136   LOCAL_DECODE_INIT;
137   RRlimdecode(decode, 0, 0);
138   hyperstone_xm(decode);
139}
140
141void hyperstone_device::op11()
142{
143   LOCAL_DECODE_INIT;
144   RRlimdecode(decode, 0, 1);
145   hyperstone_xm(decode);
146}
147
148void hyperstone_device::op12()
149{
150   LOCAL_DECODE_INIT;
151   RRlimdecode(decode, 1, 0);
152   hyperstone_xm(decode);
153}
154
155void hyperstone_device::op13()
156{
157   LOCAL_DECODE_INIT;
158   RRlimdecode(decode, 1, 1);
159   hyperstone_xm(decode);
160}
161
162void hyperstone_device::op14()
163{
164   LOCAL_DECODE_INIT;
165   RRconstdecode(decode, 0, 0);
166   hyperstone_mask(decode);
167}
168
169void hyperstone_device::op15()
170{
171   LOCAL_DECODE_INIT;
172   RRconstdecode(decode, 0, 1);
173   hyperstone_mask(decode);
174}
175
176void hyperstone_device::op16()
177{
178   LOCAL_DECODE_INIT;
179   RRconstdecode(decode, 1, 0);
180   hyperstone_mask(decode);
181}
182
183void hyperstone_device::op17()
184{
185   LOCAL_DECODE_INIT;
186   RRconstdecode(decode, 1, 1);
187   hyperstone_mask(decode);
188}
189
190void hyperstone_device::op18()
191{
192   LOCAL_DECODE_INIT;
193   RRconstdecode(decode, 0, 0);
194   hyperstone_sum(decode);
195}
196
197void hyperstone_device::op19()
198{
199   LOCAL_DECODE_INIT;
200   RRconstdecode(decode, 0, 1);
201   hyperstone_sum(decode);
202}
203
204void hyperstone_device::op1a()
205{
206   LOCAL_DECODE_INIT;
207   RRconstdecode(decode, 1, 0);
208   hyperstone_sum(decode);
209}
210
211void hyperstone_device::op1b()
212{
213   LOCAL_DECODE_INIT;
214   RRconstdecode(decode, 1, 1);
215   hyperstone_sum(decode);
216}
217
218void hyperstone_device::op1c()
219{
220   LOCAL_DECODE_INIT;
221   RRconstdecode(decode, 0, 0);
222   hyperstone_sums(decode);
223}
224
225void hyperstone_device::op1d()
226{
227   LOCAL_DECODE_INIT;
228   RRconstdecode(decode, 0, 1);
229   hyperstone_sums(decode);
230}
231
232void hyperstone_device::op1e()
233{
234   LOCAL_DECODE_INIT;
235   RRconstdecode(decode, 1, 0);
236   hyperstone_sums(decode);
237}
238
239void hyperstone_device::op1f()
240{
241   LOCAL_DECODE_INIT;
242   RRconstdecode(decode, 1, 1);
243   hyperstone_sums(decode);
244}
245
246
247
248void hyperstone_device::op20()
249{
250   LOCAL_DECODE_INIT;
251   RRdecode(decode, 0, 0);
252   hyperstone_cmp(decode);
253}
254
255void hyperstone_device::op21()
256{
257   LOCAL_DECODE_INIT;
258   RRdecode(decode, 0, 1);
259   hyperstone_cmp(decode);
260}
261
262void hyperstone_device::op22()
263{
264   LOCAL_DECODE_INIT;
265   RRdecode(decode, 1, 0);
266   hyperstone_cmp(decode);
267}
268
269void hyperstone_device::op23()
270{
271   LOCAL_DECODE_INIT;
272   RRdecode(decode, 1, 1);
273   hyperstone_cmp(decode);
274}
275
276void hyperstone_device::op24()
277{
278   LOCAL_DECODE_INIT;
279   RRdecodewithHflag(decode, 0, 0);
280   hyperstone_mov(decode);
281}
282
283void hyperstone_device::op25()
284{
285   LOCAL_DECODE_INIT;
286   RRdecodewithHflag(decode, 0, 1);
287   hyperstone_mov(decode);
288}
289
290void hyperstone_device::op26()
291{
292   LOCAL_DECODE_INIT;
293   RRdecodewithHflag(decode, 1, 0);
294   hyperstone_mov(decode);
295}
296
297void hyperstone_device::op27()
298{
299   LOCAL_DECODE_INIT;
300   RRdecodewithHflag(decode, 1, 1);
301   hyperstone_mov(decode);
302}
303
304void hyperstone_device::op28()
305{
306   LOCAL_DECODE_INIT;
307   RRdecode(decode, 0, 0);
308   hyperstone_add(decode);
309}
310
311void hyperstone_device::op29()
312{
313   LOCAL_DECODE_INIT;
314   RRdecode(decode, 0, 1);
315   hyperstone_add(decode);
316}
317
318void hyperstone_device::op2a()
319{
320   LOCAL_DECODE_INIT;
321   RRdecode(decode, 1, 0);
322   hyperstone_add(decode);
323}
324
325void hyperstone_device::op2b()
326{
327   LOCAL_DECODE_INIT;
328   RRdecode(decode, 1, 1);
329   hyperstone_add(decode);
330}
331
332void hyperstone_device::op2c()
333{
334   LOCAL_DECODE_INIT;
335   RRdecode(decode, 0, 0);
336   hyperstone_adds(decode);
337}
338
339void hyperstone_device::op2d()
340{
341   LOCAL_DECODE_INIT;
342   RRdecode(decode, 0, 1);
343   hyperstone_adds(decode);
344}
345
346void hyperstone_device::op2e()
347{
348   LOCAL_DECODE_INIT;
349   RRdecode(decode, 1, 0);
350   hyperstone_adds(decode);
351}
352
353void hyperstone_device::op2f()
354{
355   LOCAL_DECODE_INIT;
356   RRdecode(decode, 1, 1);
357   hyperstone_adds(decode);
358}
359
360
361
362void hyperstone_device::op30()
363{
364   LOCAL_DECODE_INIT;
365   RRdecode(decode, 0, 0);
366   hyperstone_cmpb(decode);
367}
368
369void hyperstone_device::op31()
370{
371   LOCAL_DECODE_INIT;
372   RRdecode(decode, 0, 1);
373   hyperstone_cmpb(decode);
374}
375
376void hyperstone_device::op32()
377{
378   LOCAL_DECODE_INIT;
379   RRdecode(decode, 1, 0);
380   hyperstone_cmpb(decode);
381}
382
383void hyperstone_device::op33()
384{
385   LOCAL_DECODE_INIT;
386   RRdecode(decode, 1, 1);
387   hyperstone_cmpb(decode);
388}
389
390void hyperstone_device::op34()
391{
392   LOCAL_DECODE_INIT;
393   RRdecode(decode, 0, 0);
394   hyperstone_andn(decode);
395}
396
397void hyperstone_device::op35()
398{
399   LOCAL_DECODE_INIT;
400   RRdecode(decode, 0, 1);
401   hyperstone_andn(decode);
402}
403
404void hyperstone_device::op36()
405{
406   LOCAL_DECODE_INIT;
407   RRdecode(decode, 1, 0);
408   hyperstone_andn(decode);
409}
410
411void hyperstone_device::op37()
412{
413   LOCAL_DECODE_INIT;
414   RRdecode(decode, 1, 1);
415   hyperstone_andn(decode);
416}
417
418void hyperstone_device::op38()
419{
420   LOCAL_DECODE_INIT;
421   RRdecode(decode, 0, 0);
422   hyperstone_or(decode);
423}
424
425void hyperstone_device::op39()
426{
427   LOCAL_DECODE_INIT;
428   RRdecode(decode, 0, 1);
429   hyperstone_or(decode);
430}
431
432void hyperstone_device::op3a()
433{
434   LOCAL_DECODE_INIT;
435   RRdecode(decode, 1, 0);
436   hyperstone_or(decode);
437}
438
439void hyperstone_device::op3b()
440{
441   LOCAL_DECODE_INIT;
442   RRdecode(decode, 1, 1);
443   hyperstone_or(decode);
444}
445
446void hyperstone_device::op3c()
447{
448   LOCAL_DECODE_INIT;
449   RRdecode(decode, 0, 0);
450   hyperstone_xor(decode);
451}
452
453void hyperstone_device::op3d()
454{
455   LOCAL_DECODE_INIT;
456   RRdecode(decode, 0, 1);
457   hyperstone_xor(decode);
458}
459
460void hyperstone_device::op3e()
461{
462   LOCAL_DECODE_INIT;
463   RRdecode(decode, 1, 0);
464   hyperstone_xor(decode);
465}
466
467void hyperstone_device::op3f()
468{
469   LOCAL_DECODE_INIT;
470   RRdecode(decode, 1, 1);
471   hyperstone_xor(decode);
472}
473
474
475
476void hyperstone_device::op40()
477{
478   LOCAL_DECODE_INIT;
479   RRdecode(decode, 0, 0);
480   hyperstone_subc(decode);
481}
482
483void hyperstone_device::op41()
484{
485   LOCAL_DECODE_INIT;
486   RRdecode(decode, 0, 1);
487   hyperstone_subc(decode);
488}
489
490void hyperstone_device::op42()
491{
492   LOCAL_DECODE_INIT;
493   RRdecode(decode, 1, 0);
494   hyperstone_subc(decode);
495}
496
497void hyperstone_device::op43()
498{
499   LOCAL_DECODE_INIT;
500   RRdecode(decode, 1, 1);
501   hyperstone_subc(decode);
502}
503
504void hyperstone_device::op44()
505{
506   LOCAL_DECODE_INIT;
507   RRdecode(decode, 0, 0);
508   hyperstone_not(decode);
509}
510
511void hyperstone_device::op45()
512{
513   LOCAL_DECODE_INIT;
514   RRdecode(decode, 0, 1);
515   hyperstone_not(decode);
516}
517
518void hyperstone_device::op46()
519{
520   LOCAL_DECODE_INIT;
521   RRdecode(decode, 1, 0);
522   hyperstone_not(decode);
523}
524
525void hyperstone_device::op47()
526{
527   LOCAL_DECODE_INIT;
528   RRdecode(decode, 1, 1);
529   hyperstone_not(decode);
530}
531
532void hyperstone_device::op48()
533{
534   LOCAL_DECODE_INIT;
535   RRdecode(decode, 0, 0);
536   hyperstone_sub(decode);
537}
538
539void hyperstone_device::op49()
540{
541   LOCAL_DECODE_INIT;
542   RRdecode(decode, 0, 1);
543   hyperstone_sub(decode);
544}
545
546void hyperstone_device::op4a()
547{
548   LOCAL_DECODE_INIT;
549   RRdecode(decode, 1, 0);
550   hyperstone_sub(decode);
551}
552
553void hyperstone_device::op4b()
554{
555   LOCAL_DECODE_INIT;
556   RRdecode(decode, 1, 1);
557   hyperstone_sub(decode);
558}
559
560void hyperstone_device::op4c()
561{
562   LOCAL_DECODE_INIT;
563   RRdecode(decode, 0, 0);
564   hyperstone_subs(decode);
565}
566
567void hyperstone_device::op4d()
568{
569   LOCAL_DECODE_INIT;
570   RRdecode(decode, 0, 1);
571   hyperstone_subs(decode);
572}
573
574void hyperstone_device::op4e()
575{
576   LOCAL_DECODE_INIT;
577   RRdecode(decode, 1, 0);
578   hyperstone_subs(decode);
579}
580
581void hyperstone_device::op4f()
582{
583   LOCAL_DECODE_INIT;
584   RRdecode(decode, 1, 1);
585   hyperstone_subs(decode);
586}
587
588
589
590void hyperstone_device::op50()
591{
592   LOCAL_DECODE_INIT;
593   RRdecode(decode, 0, 0);
594   hyperstone_addc(decode);
595}
596
597void hyperstone_device::op51()
598{
599   LOCAL_DECODE_INIT;
600   RRdecode(decode, 0, 1);
601   hyperstone_addc(decode);
602}
603
604void hyperstone_device::op52()
605{
606   LOCAL_DECODE_INIT;
607   RRdecode(decode, 1, 0);
608   hyperstone_addc(decode);
609}
610
611void hyperstone_device::op53()
612{
613   LOCAL_DECODE_INIT;
614   RRdecode(decode, 1, 1);
615   hyperstone_addc(decode);
616}
617
618void hyperstone_device::op54()
619{
620   LOCAL_DECODE_INIT;
621   RRdecode(decode, 0, 0);
622   hyperstone_and(decode);
623}
624
625void hyperstone_device::op55()
626{
627   LOCAL_DECODE_INIT;
628   RRdecode(decode, 0, 1);
629   hyperstone_and(decode);
630}
631
632void hyperstone_device::op56()
633{
634   LOCAL_DECODE_INIT;
635   RRdecode(decode, 1, 0);
636   hyperstone_and(decode);
637}
638
639void hyperstone_device::op57()
640{
641   LOCAL_DECODE_INIT;
642   RRdecode(decode, 1, 1);
643   hyperstone_and(decode);
644}
645
646void hyperstone_device::op58()
647{
648   LOCAL_DECODE_INIT;
649   RRdecode(decode, 0, 0);
650   hyperstone_neg(decode);
651}
652
653void hyperstone_device::op59()
654{
655   LOCAL_DECODE_INIT;
656   RRdecode(decode, 0, 1);
657   hyperstone_neg(decode);
658}
659
660void hyperstone_device::op5a()
661{
662   LOCAL_DECODE_INIT;
663   RRdecode(decode, 1, 0);
664   hyperstone_neg(decode);
665}
666
667void hyperstone_device::op5b()
668{
669   LOCAL_DECODE_INIT;
670   RRdecode(decode, 1, 1);
671   hyperstone_neg(decode);
672}
673
674void hyperstone_device::op5c()
675{
676   LOCAL_DECODE_INIT;
677   RRdecode(decode, 0, 0);
678   hyperstone_negs(decode);
679}
680
681void hyperstone_device::op5d()
682{
683   LOCAL_DECODE_INIT;
684   RRdecode(decode, 0, 1);
685   hyperstone_negs(decode);
686}
687
688void hyperstone_device::op5e()
689{
690   LOCAL_DECODE_INIT;
691   RRdecode(decode, 1, 0);
692   hyperstone_negs(decode);
693}
694
695void hyperstone_device::op5f()
696{
697   LOCAL_DECODE_INIT;
698   RRdecode(decode, 1, 1);
699   hyperstone_negs(decode);
700}
701
702
703
704void hyperstone_device::op60()
705{
706   LOCAL_DECODE_INIT;
707   Rimmdecode(decode, 0, 0);
708   hyperstone_cmpi(decode);
709}
710
711void hyperstone_device::op61()
712{
713   LOCAL_DECODE_INIT;
714   Rimmdecode(decode, 0, 1);
715   hyperstone_cmpi(decode);
716}
717
718void hyperstone_device::op62()
719{
720   LOCAL_DECODE_INIT;
721   Rimmdecode(decode, 1, 0);
722   hyperstone_cmpi(decode);
723}
724
725void hyperstone_device::op63()
726{
727   LOCAL_DECODE_INIT;
728   Rimmdecode(decode, 1, 1);
729   hyperstone_cmpi(decode);
730}
731
732void hyperstone_device::op64()
733{
734   LOCAL_DECODE_INIT;
735   RimmdecodewithHflag(decode, 0, 0);
736   hyperstone_movi(decode);
737}
738
739void hyperstone_device::op65()
740{
741   LOCAL_DECODE_INIT;
742   RimmdecodewithHflag(decode, 0, 1);
743   hyperstone_movi(decode);
744}
745
746void hyperstone_device::op66()
747{
748   LOCAL_DECODE_INIT;
749   RimmdecodewithHflag(decode, 1, 0);
750   hyperstone_movi(decode);
751}
752
753void hyperstone_device::op67()
754{
755   LOCAL_DECODE_INIT;
756   RimmdecodewithHflag(decode, 1, 1);
757   hyperstone_movi(decode);
758}
759
760void hyperstone_device::op68()
761{
762   LOCAL_DECODE_INIT;
763   Rimmdecode(decode, 0, 0);
764   hyperstone_addi(decode);
765}
766
767void hyperstone_device::op69()
768{
769   LOCAL_DECODE_INIT;
770   Rimmdecode(decode, 0, 1);
771   hyperstone_addi(decode);
772}
773
774void hyperstone_device::op6a()
775{
776   LOCAL_DECODE_INIT;
777   Rimmdecode(decode, 1, 0);
778   hyperstone_addi(decode);
779}
780
781void hyperstone_device::op6b()
782{
783   LOCAL_DECODE_INIT;
784   Rimmdecode(decode, 1, 1);
785   hyperstone_addi(decode);
786}
787
788void hyperstone_device::op6c()
789{
790   LOCAL_DECODE_INIT;
791   Rimmdecode(decode, 0, 0);
792   hyperstone_addsi(decode);
793}
794
795void hyperstone_device::op6d()
796{
797   LOCAL_DECODE_INIT;
798   Rimmdecode(decode, 0, 1);
799   hyperstone_addsi(decode);
800}
801
802void hyperstone_device::op6e()
803{
804   LOCAL_DECODE_INIT;
805   Rimmdecode(decode, 1, 0);
806   hyperstone_addsi(decode);
807}
808
809void hyperstone_device::op6f()
810{
811   LOCAL_DECODE_INIT;
812   Rimmdecode(decode, 1, 1);
813   hyperstone_addsi(decode);
814}
815
816
817
818void hyperstone_device::op70()
819{
820   LOCAL_DECODE_INIT;
821   Rimmdecode(decode, 0, 0);
822   hyperstone_cmpbi(decode);
823}
824
825void hyperstone_device::op71()
826{
827   LOCAL_DECODE_INIT;
828   Rimmdecode(decode, 0, 1);
829   hyperstone_cmpbi(decode);
830}
831
832void hyperstone_device::op72()
833{
834   LOCAL_DECODE_INIT;
835   Rimmdecode(decode, 1, 0);
836   hyperstone_cmpbi(decode);
837}
838
839void hyperstone_device::op73()
840{
841   LOCAL_DECODE_INIT;
842   Rimmdecode(decode, 1, 1);
843   hyperstone_cmpbi(decode);
844}
845
846void hyperstone_device::op74()
847{
848   LOCAL_DECODE_INIT;
849   Rimmdecode(decode, 0, 0);
850   hyperstone_andni(decode);
851}
852
853void hyperstone_device::op75()
854{
855   LOCAL_DECODE_INIT;
856   Rimmdecode(decode, 0, 1);
857   hyperstone_andni(decode);
858}
859
860void hyperstone_device::op76()
861{
862   LOCAL_DECODE_INIT;
863   Rimmdecode(decode, 1, 0);
864   hyperstone_andni(decode);
865}
866
867void hyperstone_device::op77()
868{
869   LOCAL_DECODE_INIT;
870   Rimmdecode(decode, 1, 1);
871   hyperstone_andni(decode);
872}
873
874void hyperstone_device::op78()
875{
876   LOCAL_DECODE_INIT;
877   Rimmdecode(decode, 0, 0);
878   hyperstone_ori(decode);
879}
880
881void hyperstone_device::op79()
882{
883   LOCAL_DECODE_INIT;
884   Rimmdecode(decode, 0, 1);
885   hyperstone_ori(decode);
886}
887
888void hyperstone_device::op7a()
889{
890   LOCAL_DECODE_INIT;
891   Rimmdecode(decode, 1, 0);
892   hyperstone_ori(decode);
893}
894
895void hyperstone_device::op7b()
896{
897   LOCAL_DECODE_INIT;
898   Rimmdecode(decode, 1, 1);
899   hyperstone_ori(decode);
900}
901
902void hyperstone_device::op7c()
903{
904   LOCAL_DECODE_INIT;
905   Rimmdecode(decode, 0, 0);
906   hyperstone_xori(decode);
907}
908
909void hyperstone_device::op7d()
910{
911   LOCAL_DECODE_INIT;
912   Rimmdecode(decode, 0, 1);
913   hyperstone_xori(decode);
914}
915
916void hyperstone_device::op7e()
917{
918   LOCAL_DECODE_INIT;
919   Rimmdecode(decode, 1, 0);
920   hyperstone_xori(decode);
921}
922
923void hyperstone_device::op7f()
924{
925   LOCAL_DECODE_INIT;
926   Rimmdecode(decode, 1, 1);
927   hyperstone_xori(decode);
928}
929
930
931
932void hyperstone_device::op80()
933{
934   LOCAL_DECODE_INIT;
935   Lndecode(decode);
936   hyperstone_shrdi(decode);
937}
938
939void hyperstone_device::op81()
940{
941   LOCAL_DECODE_INIT;
942   Lndecode(decode);
943   hyperstone_shrdi(decode);
944}
945
946void hyperstone_device::op82()
947{
948   LOCAL_DECODE_INIT;
949   LLdecode(decode);
950   hyperstone_shrd(decode);
951}
952
953void hyperstone_device::op83()
954{
955   LOCAL_DECODE_INIT;
956   LLdecode(decode);
957   hyperstone_shr(decode);
958}
959
960void hyperstone_device::op84()
961{
962   LOCAL_DECODE_INIT;
963   Lndecode(decode);
964   hyperstone_sardi(decode);
965}
966
967void hyperstone_device::op85()
968{
969   LOCAL_DECODE_INIT;
970   Lndecode(decode);
971   hyperstone_sardi(decode);
972}
973
974void hyperstone_device::op86()
975{
976   LOCAL_DECODE_INIT;
977   LLdecode(decode);
978   hyperstone_sard(decode);
979}
980
981void hyperstone_device::op87()
982{
983   LOCAL_DECODE_INIT;
984   LLdecode(decode);
985   hyperstone_sar(decode);
986}
987
988void hyperstone_device::op88()
989{
990   LOCAL_DECODE_INIT;
991   Lndecode(decode);
992   hyperstone_shldi(decode);
993}
994
995void hyperstone_device::op89()
996{
997   LOCAL_DECODE_INIT;
998   Lndecode(decode);
999   hyperstone_shldi(decode);
1000}
1001
1002void hyperstone_device::op8a()
1003{
1004   LOCAL_DECODE_INIT;
1005   LLdecode(decode);
1006   hyperstone_shld(decode);
1007}
1008
1009void hyperstone_device::op8b()
1010{
1011   LOCAL_DECODE_INIT;
1012   LLdecode(decode);
1013   hyperstone_shl(decode);
1014}
1015
1016void hyperstone_device::op8c()
1017{
1018   LOCAL_DECODE_INIT;
1019   no_decode(decode);
1020   reserved(decode);
1021}
1022
1023void hyperstone_device::op8d()
1024{
1025   LOCAL_DECODE_INIT;
1026   no_decode(decode);
1027   reserved(decode);
1028}
1029
1030void hyperstone_device::op8e()
1031{
1032   LOCAL_DECODE_INIT;
1033   LLdecode(decode);
1034   hyperstone_testlz(decode);
1035}
1036
1037void hyperstone_device::op8f()
1038{
1039   LOCAL_DECODE_INIT;
1040   LLdecode(decode);
1041   hyperstone_rol(decode);
1042}
1043
1044
1045
1046void hyperstone_device::op90()
1047{
1048   LOCAL_DECODE_INIT;
1049   RRdisdecode(decode, 0, 0);
1050   hyperstone_ldxx1(decode);
1051}
1052
1053void hyperstone_device::op91()
1054{
1055   LOCAL_DECODE_INIT;
1056   RRdisdecode(decode, 0, 1);
1057   hyperstone_ldxx1(decode);
1058}
1059
1060void hyperstone_device::op92()
1061{
1062   LOCAL_DECODE_INIT;
1063   RRdisdecode(decode, 1, 0);
1064   hyperstone_ldxx1(decode);
1065}
1066
1067void hyperstone_device::op93()
1068{
1069   LOCAL_DECODE_INIT;
1070   RRdisdecode(decode, 1, 1);
1071   hyperstone_ldxx1(decode);
1072}
1073
1074void hyperstone_device::op94()
1075{
1076   LOCAL_DECODE_INIT;
1077   RRdisdecode(decode, 0, 0);
1078   hyperstone_ldxx2(decode);
1079}
1080
1081void hyperstone_device::op95()
1082{
1083   LOCAL_DECODE_INIT;
1084   RRdisdecode(decode, 0, 1);
1085   hyperstone_ldxx2(decode);
1086}
1087
1088void hyperstone_device::op96()
1089{
1090   LOCAL_DECODE_INIT;
1091   RRdisdecode(decode, 1, 0);
1092   hyperstone_ldxx2(decode);
1093}
1094
1095void hyperstone_device::op97()
1096{
1097   LOCAL_DECODE_INIT;
1098   RRdisdecode(decode, 1, 1);
1099   hyperstone_ldxx2(decode);
1100}
1101
1102void hyperstone_device::op98()
1103{
1104   LOCAL_DECODE_INIT;
1105   RRdisdecode(decode, 0, 0);
1106   hyperstone_stxx1(decode);
1107}
1108
1109void hyperstone_device::op99()
1110{
1111   LOCAL_DECODE_INIT;
1112   RRdisdecode(decode, 0, 1);
1113   hyperstone_stxx1(decode);
1114}
1115
1116void hyperstone_device::op9a()
1117{
1118   LOCAL_DECODE_INIT;
1119   RRdisdecode(decode, 1, 0);
1120   hyperstone_stxx1(decode);
1121}
1122
1123void hyperstone_device::op9b()
1124{
1125   LOCAL_DECODE_INIT;
1126   RRdisdecode(decode, 1, 1);
1127   hyperstone_stxx1(decode);
1128}
1129
1130void hyperstone_device::op9c()
1131{
1132   LOCAL_DECODE_INIT;
1133   RRdisdecode(decode, 0, 0);
1134   hyperstone_stxx2(decode);
1135}
1136
1137void hyperstone_device::op9d()
1138{
1139   LOCAL_DECODE_INIT;
1140   RRdisdecode(decode, 0, 1);
1141   hyperstone_stxx2(decode);
1142}
1143
1144void hyperstone_device::op9e()
1145{
1146   LOCAL_DECODE_INIT;
1147   RRdisdecode(decode, 1, 0);
1148   hyperstone_stxx2(decode);
1149}
1150
1151void hyperstone_device::op9f()
1152{
1153   LOCAL_DECODE_INIT;
1154   RRdisdecode(decode, 1, 1);
1155   hyperstone_stxx2(decode);
1156}
1157
1158
1159
1160void hyperstone_device::opa0()
1161{
1162   LOCAL_DECODE_INIT;
1163   Rndecode(decode, 0);
1164   hyperstone_shri(decode);
1165}
1166
1167void hyperstone_device::opa1()
1168{
1169   LOCAL_DECODE_INIT;
1170   Rndecode(decode, 0);
1171   hyperstone_shri(decode);
1172}
1173
1174void hyperstone_device::opa2()
1175{
1176   LOCAL_DECODE_INIT;
1177   Rndecode(decode, 1);
1178   hyperstone_shri(decode);
1179}
1180
1181void hyperstone_device::opa3()
1182{
1183   LOCAL_DECODE_INIT;
1184   Rndecode(decode, 1);
1185   hyperstone_shri(decode);
1186}
1187
1188void hyperstone_device::opa4()
1189{
1190   LOCAL_DECODE_INIT;
1191   Rndecode(decode, 0);
1192   hyperstone_sari(decode);
1193}
1194
1195void hyperstone_device::opa5()
1196{
1197   LOCAL_DECODE_INIT;
1198   Rndecode(decode, 0);
1199   hyperstone_sari(decode);
1200}
1201
1202void hyperstone_device::opa6()
1203{
1204   LOCAL_DECODE_INIT;
1205   Rndecode(decode, 1);
1206   hyperstone_sari(decode);
1207}
1208
1209void hyperstone_device::opa7()
1210{
1211   LOCAL_DECODE_INIT;
1212   Rndecode(decode, 1);
1213   hyperstone_sari(decode);
1214}
1215
1216void hyperstone_device::opa8()
1217{
1218   LOCAL_DECODE_INIT;
1219   Rndecode(decode, 0);
1220   hyperstone_shli(decode);
1221}
1222
1223void hyperstone_device::opa9()
1224{
1225   LOCAL_DECODE_INIT;
1226   Rndecode(decode, 0);
1227   hyperstone_shli(decode);
1228}
1229
1230void hyperstone_device::opaa()
1231{
1232   LOCAL_DECODE_INIT;
1233   Rndecode(decode, 1);
1234   hyperstone_shli(decode);
1235}
1236
1237void hyperstone_device::opab()
1238{
1239   LOCAL_DECODE_INIT;
1240   Rndecode(decode, 1);
1241   hyperstone_shli(decode);
1242}
1243
1244void hyperstone_device::opac()
1245{
1246   LOCAL_DECODE_INIT;
1247   no_decode(decode);
1248   reserved(decode);
1249}
1250
1251void hyperstone_device::opad()
1252{
1253   LOCAL_DECODE_INIT;
1254   no_decode(decode);
1255   reserved(decode);
1256}
1257
1258void hyperstone_device::opae()
1259{
1260   LOCAL_DECODE_INIT;
1261   no_decode(decode);
1262   reserved(decode);
1263}
1264
1265void hyperstone_device::opaf()
1266{
1267   LOCAL_DECODE_INIT;
1268   no_decode(decode);
1269   reserved(decode);
1270}
1271
1272
1273
1274void hyperstone_device::opb0()
1275{
1276   LOCAL_DECODE_INIT;
1277   RRdecode(decode, 0, 0);
1278   hyperstone_mulu(decode);
1279}
1280
1281void hyperstone_device::opb1()
1282{
1283   LOCAL_DECODE_INIT;
1284   RRdecode(decode, 0, 1);
1285   hyperstone_mulu(decode);
1286}
1287
1288void hyperstone_device::opb2()
1289{
1290   LOCAL_DECODE_INIT;
1291   RRdecode(decode, 1, 0);
1292   hyperstone_mulu(decode);
1293}
1294
1295void hyperstone_device::opb3()
1296{
1297   LOCAL_DECODE_INIT;
1298   RRdecode(decode, 1, 1);
1299   hyperstone_mulu(decode);
1300}
1301
1302void hyperstone_device::opb4()
1303{
1304   LOCAL_DECODE_INIT;
1305   RRdecode(decode, 0, 0);
1306   hyperstone_muls(decode);
1307}
1308
1309void hyperstone_device::opb5()
1310{
1311   LOCAL_DECODE_INIT;
1312   RRdecode(decode, 0, 1);
1313   hyperstone_muls(decode);
1314}
1315
1316void hyperstone_device::opb6()
1317{
1318   LOCAL_DECODE_INIT;
1319   RRdecode(decode, 1, 0);
1320   hyperstone_muls(decode);
1321}
1322
1323void hyperstone_device::opb7()
1324{
1325   LOCAL_DECODE_INIT;
1326   RRdecode(decode, 1, 1);
1327   hyperstone_muls(decode);
1328}
1329
1330void hyperstone_device::opb8()
1331{
1332   LOCAL_DECODE_INIT;
1333   Rndecode(decode, 0);
1334   hyperstone_set(decode);
1335}
1336
1337void hyperstone_device::opb9()
1338{
1339   LOCAL_DECODE_INIT;
1340   Rndecode(decode, 0);
1341   hyperstone_set(decode);
1342}
1343
1344void hyperstone_device::opba()
1345{
1346   LOCAL_DECODE_INIT;
1347   Rndecode(decode, 1);
1348   hyperstone_set(decode);
1349}
1350
1351void hyperstone_device::opbb()
1352{
1353   LOCAL_DECODE_INIT;
1354   Rndecode(decode, 1);
1355   hyperstone_set(decode);
1356}
1357
1358void hyperstone_device::opbc()
1359{
1360   LOCAL_DECODE_INIT;
1361   RRdecode(decode, 0, 0);
1362   hyperstone_mul(decode);
1363}
1364
1365void hyperstone_device::opbd()
1366{
1367   LOCAL_DECODE_INIT;
1368   RRdecode(decode, 0, 1);
1369   hyperstone_mul(decode);
1370}
1371
1372void hyperstone_device::opbe()
1373{
1374   LOCAL_DECODE_INIT;
1375   RRdecode(decode, 1, 0);
1376   hyperstone_mul(decode);
1377}
1378
1379void hyperstone_device::opbf()
1380{
1381   LOCAL_DECODE_INIT;
1382   RRdecode(decode, 1, 1);
1383   hyperstone_mul(decode);
1384}
1385
1386
1387
1388void hyperstone_device::opc0()
1389{
1390   LOCAL_DECODE_INIT;
1391   LLdecode(decode);
1392   hyperstone_fadd(decode);
1393}
1394
1395void hyperstone_device::opc1()
1396{
1397   LOCAL_DECODE_INIT;
1398   LLdecode(decode);
1399   hyperstone_faddd(decode);
1400}
1401
1402void hyperstone_device::opc2()
1403{
1404   LOCAL_DECODE_INIT;
1405   LLdecode(decode);
1406   hyperstone_fsub(decode);
1407}
1408
1409void hyperstone_device::opc3()
1410{
1411   LOCAL_DECODE_INIT;
1412   LLdecode(decode);
1413   hyperstone_fsubd(decode);
1414}
1415
1416void hyperstone_device::opc4()
1417{
1418   LOCAL_DECODE_INIT;
1419   LLdecode(decode);
1420   hyperstone_fmul(decode);
1421}
1422
1423void hyperstone_device::opc5()
1424{
1425   LOCAL_DECODE_INIT;
1426   LLdecode(decode);
1427   hyperstone_fmuld(decode);
1428}
1429
1430void hyperstone_device::opc6()
1431{
1432   LOCAL_DECODE_INIT;
1433   LLdecode(decode);
1434   hyperstone_fdiv(decode);
1435}
1436
1437void hyperstone_device::opc7()
1438{
1439   LOCAL_DECODE_INIT;
1440   LLdecode(decode);
1441   hyperstone_fdivd(decode);
1442}
1443
1444void hyperstone_device::opc8()
1445{
1446   LOCAL_DECODE_INIT;
1447   LLdecode(decode);
1448   hyperstone_fcmp(decode);
1449}
1450
1451void hyperstone_device::opc9()
1452{
1453   LOCAL_DECODE_INIT;
1454   LLdecode(decode);
1455   hyperstone_fcmpd(decode);
1456}
1457
1458void hyperstone_device::opca()
1459{
1460   LOCAL_DECODE_INIT;
1461   LLdecode(decode);
1462   hyperstone_fcmpu(decode);
1463}
1464
1465void hyperstone_device::opcb()
1466{
1467   LOCAL_DECODE_INIT;
1468   LLdecode(decode);
1469   hyperstone_fcmpud(decode);
1470}
1471
1472void hyperstone_device::opcc()
1473{
1474   LOCAL_DECODE_INIT;
1475   LLdecode(decode);
1476   hyperstone_fcvt(decode);
1477}
1478
1479void hyperstone_device::opcd()
1480{
1481   LOCAL_DECODE_INIT;
1482   LLdecode(decode);
1483   hyperstone_fcvtd(decode);
1484}
1485
1486void hyperstone_device::opce()
1487{
1488   LOCAL_DECODE_INIT;
1489   LLextdecode(decode);
1490   hyperstone_extend(decode);
1491}
1492
1493void hyperstone_device::opcf()
1494{
1495   LOCAL_DECODE_INIT;
1496   LLdecode(decode);
1497   hyperstone_do(decode);
1498}
1499
1500
1501
1502void hyperstone_device::opd0()
1503{
1504   LOCAL_DECODE_INIT;
1505   LRdecode(decode, 0);
1506   hyperstone_ldwr(decode);
1507}
1508
1509void hyperstone_device::opd1()
1510{
1511   LOCAL_DECODE_INIT;
1512   LRdecode(decode, 1);
1513   hyperstone_ldwr(decode);
1514}
1515
1516void hyperstone_device::opd2()
1517{
1518   LOCAL_DECODE_INIT;
1519   LRdecode(decode, 0);
1520   hyperstone_lddr(decode);
1521}
1522
1523void hyperstone_device::opd3()
1524{
1525   LOCAL_DECODE_INIT;
1526   LRdecode(decode, 1);
1527   hyperstone_lddr(decode);
1528}
1529
1530void hyperstone_device::opd4()
1531{
1532   LOCAL_DECODE_INIT;
1533   LRdecode(decode, 0);
1534   hyperstone_ldwp(decode);
1535}
1536
1537void hyperstone_device::opd5()
1538{
1539   LOCAL_DECODE_INIT;
1540   LRdecode(decode, 1);
1541   hyperstone_ldwp(decode);
1542}
1543
1544void hyperstone_device::opd6()
1545{
1546   LOCAL_DECODE_INIT;
1547   LRdecode(decode, 0);
1548   hyperstone_lddp(decode);
1549}
1550
1551void hyperstone_device::opd7()
1552{
1553   LOCAL_DECODE_INIT;
1554   LRdecode(decode, 1);
1555   hyperstone_lddp(decode);
1556}
1557
1558void hyperstone_device::opd8()
1559{
1560   LOCAL_DECODE_INIT;
1561   LRdecode(decode, 0);
1562   hyperstone_stwr(decode);
1563}
1564
1565void hyperstone_device::opd9()
1566{
1567   LOCAL_DECODE_INIT;
1568   LRdecode(decode, 1);
1569   hyperstone_stwr(decode);
1570}
1571
1572void hyperstone_device::opda()
1573{
1574   LOCAL_DECODE_INIT;
1575   LRdecode(decode, 0);
1576   hyperstone_stdr(decode);
1577}
1578
1579void hyperstone_device::opdb()
1580{
1581   LOCAL_DECODE_INIT;
1582   LRdecode(decode, 1);
1583   hyperstone_stdr(decode);
1584}
1585
1586void hyperstone_device::opdc()
1587{
1588   LOCAL_DECODE_INIT;
1589   LRdecode(decode, 0);
1590   hyperstone_stwp(decode);
1591}
1592
1593void hyperstone_device::opdd()
1594{
1595   LOCAL_DECODE_INIT;
1596   LRdecode(decode, 1);
1597   hyperstone_stwp(decode);
1598}
1599
1600void hyperstone_device::opde()
1601{
1602   LOCAL_DECODE_INIT;
1603   LRdecode(decode, 0);
1604   hyperstone_stdp(decode);
1605}
1606
1607void hyperstone_device::opdf()
1608{
1609   LOCAL_DECODE_INIT;
1610   LRdecode(decode, 1);
1611   hyperstone_stdp(decode);
1612}
1613
1614
1615
1616void hyperstone_device::ope0()
1617{
1618   LOCAL_DECODE_INIT;
1619   PCreldecode(decode);
1620   hyperstone_dbv(decode);
1621}
1622
1623void hyperstone_device::ope1()
1624{
1625   LOCAL_DECODE_INIT;
1626   PCreldecode(decode);
1627   hyperstone_dbnv(decode);
1628}
1629
1630void hyperstone_device::ope2()
1631{
1632   LOCAL_DECODE_INIT;
1633   PCreldecode(decode);
1634   hyperstone_dbe(decode);
1635}
1636
1637void hyperstone_device::ope3()
1638{
1639   LOCAL_DECODE_INIT;
1640   PCreldecode(decode);
1641   hyperstone_dbne(decode);
1642}
1643
1644void hyperstone_device::ope4()
1645{
1646   LOCAL_DECODE_INIT;
1647   PCreldecode(decode);
1648   hyperstone_dbc(decode);
1649}
1650
1651void hyperstone_device::ope5()
1652{
1653   LOCAL_DECODE_INIT;
1654   PCreldecode(decode);
1655   hyperstone_dbnc(decode);
1656}
1657
1658void hyperstone_device::ope6()
1659{
1660   LOCAL_DECODE_INIT;
1661   PCreldecode(decode);
1662   hyperstone_dbse(decode);
1663}
1664
1665void hyperstone_device::ope7()
1666{
1667   LOCAL_DECODE_INIT;
1668   PCreldecode(decode);
1669   hyperstone_dbht(decode);
1670}
1671
1672void hyperstone_device::ope8()
1673{
1674   LOCAL_DECODE_INIT;
1675   PCreldecode(decode);
1676   hyperstone_dbn(decode);
1677}
1678
1679void hyperstone_device::ope9()
1680{
1681   LOCAL_DECODE_INIT;
1682   PCreldecode(decode);
1683   hyperstone_dbnn(decode);
1684}
1685
1686void hyperstone_device::opea()
1687{
1688   LOCAL_DECODE_INIT;
1689   PCreldecode(decode);
1690   hyperstone_dble(decode);
1691}
1692
1693void hyperstone_device::opeb()
1694{
1695   LOCAL_DECODE_INIT;
1696   PCreldecode(decode);
1697   hyperstone_dbgt(decode);
1698}
1699
1700void hyperstone_device::opec()
1701{
1702   LOCAL_DECODE_INIT;
1703   PCreldecode(decode);
1704   hyperstone_dbr(decode);
1705}
1706
1707void hyperstone_device::oped()
1708{
1709   LOCAL_DECODE_INIT;
1710   LLdecode(decode);
1711   hyperstone_frame(decode);
1712}
1713
1714void hyperstone_device::opee()
1715{
1716   LOCAL_DECODE_INIT;
1717   LRconstdecode(decode, 0);
1718   hyperstone_call(decode);
1719}
1720
1721void hyperstone_device::opef()
1722{
1723   LOCAL_DECODE_INIT;
1724   LRconstdecode(decode, 1);
1725   hyperstone_call(decode);
1726}
1727
1728
1729
1730void hyperstone_device::opf0()
1731{
1732   LOCAL_DECODE_INIT;
1733   PCreldecode(decode);
1734   hyperstone_bv(decode);
1735}
1736
1737void hyperstone_device::opf1()
1738{
1739   LOCAL_DECODE_INIT;
1740   PCreldecode(decode);
1741   hyperstone_bnv(decode);
1742}
1743
1744void hyperstone_device::opf2()
1745{
1746   LOCAL_DECODE_INIT;
1747   PCreldecode(decode);
1748   hyperstone_be(decode);
1749}
1750
1751void hyperstone_device::opf3()
1752{
1753   LOCAL_DECODE_INIT;
1754   PCreldecode(decode);
1755   hyperstone_bne(decode);
1756}
1757
1758void hyperstone_device::opf4()
1759{
1760   LOCAL_DECODE_INIT;
1761   PCreldecode(decode);
1762   hyperstone_bc(decode);
1763}
1764
1765void hyperstone_device::opf5()
1766{
1767   LOCAL_DECODE_INIT;
1768   PCreldecode(decode);
1769   hyperstone_bnc(decode);
1770}
1771
1772void hyperstone_device::opf6()
1773{
1774   LOCAL_DECODE_INIT;
1775   PCreldecode(decode);
1776   hyperstone_bse(decode);
1777}
1778
1779void hyperstone_device::opf7()
1780{
1781   LOCAL_DECODE_INIT;
1782   PCreldecode(decode);
1783   hyperstone_bht(decode);
1784}
1785
1786void hyperstone_device::opf8()
1787{
1788   LOCAL_DECODE_INIT;
1789   PCreldecode(decode);
1790   hyperstone_bn(decode);
1791}
1792
1793void hyperstone_device::opf9()
1794{
1795   LOCAL_DECODE_INIT;
1796   PCreldecode(decode);
1797   hyperstone_bnn(decode);
1798}
1799
1800void hyperstone_device::opfa()
1801{
1802   LOCAL_DECODE_INIT;
1803   PCreldecode(decode);
1804   hyperstone_ble(decode);
1805}
1806
1807void hyperstone_device::opfb()
1808{
1809   LOCAL_DECODE_INIT;
1810   PCreldecode(decode);
1811   hyperstone_bgt(decode);
1812}
1813
1814void hyperstone_device::opfc()
1815{
1816   LOCAL_DECODE_INIT;
1817   PCreldecode(decode);
1818   hyperstone_br(decode);
1819}
1820
1821void hyperstone_device::opfd()
1822{
1823   LOCAL_DECODE_INIT;
1824   PCadrdecode(decode);
1825   hyperstone_trap(decode);
1826}
1827
1828void hyperstone_device::opfe()
1829{
1830   LOCAL_DECODE_INIT;
1831   PCadrdecode(decode);
1832   hyperstone_trap(decode);
1833}
1834
1835void hyperstone_device::opff()
1836{
1837   LOCAL_DECODE_INIT;
1838   PCadrdecode(decode);
1839   hyperstone_trap(decode);
1840}
1841
1842const hyperstone_device::ophandler hyperstone_device::s_opcodetable[256] =
1843{
1844   &hyperstone_device::op00, &hyperstone_device::op01, &hyperstone_device::op02, &hyperstone_device::op03,
1845   &hyperstone_device::op04, &hyperstone_device::op05, &hyperstone_device::op06, &hyperstone_device::op07,
1846   &hyperstone_device::op08, &hyperstone_device::op09, &hyperstone_device::op0a, &hyperstone_device::op0b,
1847   &hyperstone_device::op0c, &hyperstone_device::op0d, &hyperstone_device::op0e, &hyperstone_device::op0f,
1848
1849   &hyperstone_device::op10, &hyperstone_device::op11, &hyperstone_device::op12, &hyperstone_device::op13,
1850   &hyperstone_device::op14, &hyperstone_device::op15, &hyperstone_device::op16, &hyperstone_device::op17,
1851   &hyperstone_device::op18, &hyperstone_device::op19, &hyperstone_device::op1a, &hyperstone_device::op1b,
1852   &hyperstone_device::op1c, &hyperstone_device::op1d, &hyperstone_device::op1e, &hyperstone_device::op1f,
1853
1854   &hyperstone_device::op20, &hyperstone_device::op21, &hyperstone_device::op22, &hyperstone_device::op23,
1855   &hyperstone_device::op24, &hyperstone_device::op25, &hyperstone_device::op26, &hyperstone_device::op27,
1856   &hyperstone_device::op28, &hyperstone_device::op29, &hyperstone_device::op2a, &hyperstone_device::op2b,
1857   &hyperstone_device::op2c, &hyperstone_device::op2d, &hyperstone_device::op2e, &hyperstone_device::op2f,
1858
1859   &hyperstone_device::op30, &hyperstone_device::op31, &hyperstone_device::op32, &hyperstone_device::op33,
1860   &hyperstone_device::op34, &hyperstone_device::op35, &hyperstone_device::op36, &hyperstone_device::op37,
1861   &hyperstone_device::op38, &hyperstone_device::op39, &hyperstone_device::op3a, &hyperstone_device::op3b,
1862   &hyperstone_device::op3c, &hyperstone_device::op3d, &hyperstone_device::op3e, &hyperstone_device::op3f,
1863
1864   &hyperstone_device::op40, &hyperstone_device::op41, &hyperstone_device::op42, &hyperstone_device::op43,
1865   &hyperstone_device::op44, &hyperstone_device::op45, &hyperstone_device::op46, &hyperstone_device::op47,
1866   &hyperstone_device::op48, &hyperstone_device::op49, &hyperstone_device::op4a, &hyperstone_device::op4b,
1867   &hyperstone_device::op4c, &hyperstone_device::op4d, &hyperstone_device::op4e, &hyperstone_device::op4f,
1868
1869   &hyperstone_device::op50, &hyperstone_device::op51, &hyperstone_device::op52, &hyperstone_device::op53,
1870   &hyperstone_device::op54, &hyperstone_device::op55, &hyperstone_device::op56, &hyperstone_device::op57,
1871   &hyperstone_device::op58, &hyperstone_device::op59, &hyperstone_device::op5a, &hyperstone_device::op5b,
1872   &hyperstone_device::op5c, &hyperstone_device::op5d, &hyperstone_device::op5e, &hyperstone_device::op5f,
1873
1874   &hyperstone_device::op60, &hyperstone_device::op61, &hyperstone_device::op62, &hyperstone_device::op63,
1875   &hyperstone_device::op64, &hyperstone_device::op65, &hyperstone_device::op66, &hyperstone_device::op67,
1876   &hyperstone_device::op68, &hyperstone_device::op69, &hyperstone_device::op6a, &hyperstone_device::op6b,
1877   &hyperstone_device::op6c, &hyperstone_device::op6d, &hyperstone_device::op6e, &hyperstone_device::op6f,
1878
1879   &hyperstone_device::op70, &hyperstone_device::op71, &hyperstone_device::op72, &hyperstone_device::op73,
1880   &hyperstone_device::op74, &hyperstone_device::op75, &hyperstone_device::op76, &hyperstone_device::op77,
1881   &hyperstone_device::op78, &hyperstone_device::op79, &hyperstone_device::op7a, &hyperstone_device::op7b,
1882   &hyperstone_device::op7c, &hyperstone_device::op7d, &hyperstone_device::op7e, &hyperstone_device::op7f,
1883
1884   &hyperstone_device::op80, &hyperstone_device::op81, &hyperstone_device::op82, &hyperstone_device::op83,
1885   &hyperstone_device::op84, &hyperstone_device::op85, &hyperstone_device::op86, &hyperstone_device::op87,
1886   &hyperstone_device::op88, &hyperstone_device::op89, &hyperstone_device::op8a, &hyperstone_device::op8b,
1887   &hyperstone_device::op8c, &hyperstone_device::op8d, &hyperstone_device::op8e, &hyperstone_device::op8f,
1888
1889   &hyperstone_device::op90, &hyperstone_device::op91, &hyperstone_device::op92, &hyperstone_device::op93,
1890   &hyperstone_device::op94, &hyperstone_device::op95, &hyperstone_device::op96, &hyperstone_device::op97,
1891   &hyperstone_device::op98, &hyperstone_device::op99, &hyperstone_device::op9a, &hyperstone_device::op9b,
1892   &hyperstone_device::op9c, &hyperstone_device::op9d, &hyperstone_device::op9e, &hyperstone_device::op9f,
1893
1894   &hyperstone_device::opa0, &hyperstone_device::opa1, &hyperstone_device::opa2, &hyperstone_device::opa3,
1895   &hyperstone_device::opa4, &hyperstone_device::opa5, &hyperstone_device::opa6, &hyperstone_device::opa7,
1896   &hyperstone_device::opa8, &hyperstone_device::opa9, &hyperstone_device::opaa, &hyperstone_device::opab,
1897   &hyperstone_device::opac, &hyperstone_device::opad, &hyperstone_device::opae, &hyperstone_device::opaf,
1898
1899   &hyperstone_device::opb0, &hyperstone_device::opb1, &hyperstone_device::opb2, &hyperstone_device::opb3,
1900   &hyperstone_device::opb4, &hyperstone_device::opb5, &hyperstone_device::opb6, &hyperstone_device::opb7,
1901   &hyperstone_device::opb8, &hyperstone_device::opb9, &hyperstone_device::opba, &hyperstone_device::opbb,
1902   &hyperstone_device::opbc, &hyperstone_device::opbd, &hyperstone_device::opbe, &hyperstone_device::opbf,
1903
1904   &hyperstone_device::opc0, &hyperstone_device::opc1, &hyperstone_device::opc2, &hyperstone_device::opc3,
1905   &hyperstone_device::opc4, &hyperstone_device::opc5, &hyperstone_device::opc6, &hyperstone_device::opc7,
1906   &hyperstone_device::opc8, &hyperstone_device::opc9, &hyperstone_device::opca, &hyperstone_device::opcb,
1907   &hyperstone_device::opcc, &hyperstone_device::opcd, &hyperstone_device::opce, &hyperstone_device::opcf,
1908
1909   &hyperstone_device::opd0, &hyperstone_device::opd1, &hyperstone_device::opd2, &hyperstone_device::opd3,
1910   &hyperstone_device::opd4, &hyperstone_device::opd5, &hyperstone_device::opd6, &hyperstone_device::opd7,
1911   &hyperstone_device::opd8, &hyperstone_device::opd9, &hyperstone_device::opda, &hyperstone_device::opdb,
1912   &hyperstone_device::opdc, &hyperstone_device::opdd, &hyperstone_device::opde, &hyperstone_device::opdf,
1913
1914   &hyperstone_device::ope0, &hyperstone_device::ope1, &hyperstone_device::ope2, &hyperstone_device::ope3,
1915   &hyperstone_device::ope4, &hyperstone_device::ope5, &hyperstone_device::ope6, &hyperstone_device::ope7,
1916   &hyperstone_device::ope8, &hyperstone_device::ope9, &hyperstone_device::opea, &hyperstone_device::opeb,
1917   &hyperstone_device::opec, &hyperstone_device::oped, &hyperstone_device::opee, &hyperstone_device::opef,
1918
1919   &hyperstone_device::opf0, &hyperstone_device::opf1, &hyperstone_device::opf2, &hyperstone_device::opf3,
1920   &hyperstone_device::opf4, &hyperstone_device::opf5, &hyperstone_device::opf6, &hyperstone_device::opf7,
1921   &hyperstone_device::opf8, &hyperstone_device::opf9, &hyperstone_device::opfa, &hyperstone_device::opfb,
1922   &hyperstone_device::opfc, &hyperstone_device::opfd, &hyperstone_device::opfe, &hyperstone_device::opff
1923};
Property changes on: trunk/src/emu/cpu/e132xs/e132xsop.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/nec/necinstr.c
r28738r28739
1#define OP(num,func_name) void nec_common_device::func_name()
2
3OP( 0x00, i_add_br8  ) { DEF_br8;   ADDB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
4OP( 0x01, i_add_wr16 ) { DEF_wr16;  ADDW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
5OP( 0x02, i_add_r8b  ) { DEF_r8b;   ADDB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
6OP( 0x03, i_add_r16w ) { DEF_r16w;  ADDW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
7OP( 0x04, i_add_ald8 ) { DEF_ald8;  ADDB;   Breg(AL)=dst;           CLKS(4,4,2);                }
8OP( 0x05, i_add_axd16) { DEF_axd16; ADDW;   Wreg(AW)=dst;           CLKS(4,4,2);                }
9OP( 0x06, i_push_es  ) { PUSH(Sreg(DS1));   CLKS(12,8,3);   }
10OP( 0x07, i_pop_es   ) { POP(Sreg(DS1));    CLKS(12,8,5);   }
11
12OP( 0x08, i_or_br8   ) { DEF_br8;   ORB;    PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
13OP( 0x09, i_or_wr16  ) { DEF_wr16;  ORW;    PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
14OP( 0x0a, i_or_r8b   ) { DEF_r8b;   ORB;    RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
15OP( 0x0b, i_or_r16w  ) { DEF_r16w;  ORW;    RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
16OP( 0x0c, i_or_ald8  ) { DEF_ald8;  ORB;    Breg(AL)=dst;           CLKS(4,4,2);                }
17OP( 0x0d, i_or_axd16 ) { DEF_axd16; ORW;    Wreg(AW)=dst;           CLKS(4,4,2);                }
18OP( 0x0e, i_push_cs  ) { PUSH(Sreg(PS));    CLKS(12,8,3);   }
19OP( 0x0f, i_pre_nec  ) { UINT32 ModRM, tmp, tmp2;
20   switch (FETCH()) {
21      case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
22      case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
23      case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2);  PutbackRMByte(ModRM,tmp);   break; /* Clr */
24      case 0x13 : BITOP_WORD; CLKS(5,5,4); tmp2 = Breg(CL) & 0xf; tmp &= ~(1<<tmp2);  PutbackRMWord(ModRM,tmp);   break; /* Clr */
25      case 0x14 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; tmp |= (1<<tmp2);   PutbackRMByte(ModRM,tmp);   break; /* Set */
26      case 0x15 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; tmp |= (1<<tmp2);   PutbackRMWord(ModRM,tmp);   break; /* Set */
27      case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT;            PutbackRMByte(ModRM,tmp);   break; /* Not */
28      case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT;            PutbackRMWord(ModRM,tmp);   break; /* Not */
29
30      case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7;    m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
31      case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf;    m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
32      case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7;    tmp &= ~(1<<tmp2);      PutbackRMByte(ModRM,tmp);   break; /* Clr */
33      case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf;    tmp &= ~(1<<tmp2);      PutbackRMWord(ModRM,tmp);   break; /* Clr */
34      case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7;    tmp |= (1<<tmp2);       PutbackRMByte(ModRM,tmp);   break; /* Set */
35      case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf;    tmp |= (1<<tmp2);       PutbackRMWord(ModRM,tmp);   break; /* Set */
36      case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7;    BIT_NOT;                PutbackRMByte(ModRM,tmp);   break; /* Not */
37      case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf;    BIT_NOT;                PutbackRMWord(ModRM,tmp);   break; /* Not */
38
39      case 0x20 : ADD4S; CLKS(7,7,2); break;
40      case 0x22 : SUB4S; CLKS(7,7,2); break;
41      case 0x26 : CMP4S; CLKS(7,7,2); break;
42      case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break;
43      case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4);   PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break;
44      case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break;
45      case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break;
46      case 0xe0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC()); break;
47      case 0xf0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC()); break;
48      case 0xff : ModRM = FETCH(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC()); break;
49      default:    logerror("%06x: Unknown V20 instruction\n",PC()); break;
50   }
51}
52
53OP( 0x10, i_adc_br8  ) { DEF_br8;   src+=CF;    ADDB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
54OP( 0x11, i_adc_wr16 ) { DEF_wr16;  src+=CF;    ADDW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
55OP( 0x12, i_adc_r8b  ) { DEF_r8b;   src+=CF;    ADDB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
56OP( 0x13, i_adc_r16w ) { DEF_r16w;  src+=CF;    ADDW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
57OP( 0x14, i_adc_ald8 ) { DEF_ald8;  src+=CF;    ADDB;   Breg(AL)=dst;           CLKS(4,4,2);                }
58OP( 0x15, i_adc_axd16) { DEF_axd16; src+=CF;    ADDW;   Wreg(AW)=dst;           CLKS(4,4,2);                }
59OP( 0x16, i_push_ss  ) { PUSH(Sreg(SS));        CLKS(12,8,3);   }
60OP( 0x17, i_pop_ss   ) { POP(Sreg(SS));     CLKS(12,8,5);   m_no_interrupt=1; }
61
62OP( 0x18, i_sbb_br8  ) { DEF_br8;   src+=CF;    SUBB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
63OP( 0x19, i_sbb_wr16 ) { DEF_wr16;  src+=CF;    SUBW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
64OP( 0x1a, i_sbb_r8b  ) { DEF_r8b;   src+=CF;    SUBB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
65OP( 0x1b, i_sbb_r16w ) { DEF_r16w;  src+=CF;    SUBW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
66OP( 0x1c, i_sbb_ald8 ) { DEF_ald8;  src+=CF;    SUBB;   Breg(AL)=dst;           CLKS(4,4,2);                }
67OP( 0x1d, i_sbb_axd16) { DEF_axd16; src+=CF;    SUBW;   Wreg(AW)=dst;           CLKS(4,4,2);    }
68OP( 0x1e, i_push_ds  ) { PUSH(Sreg(DS0));       CLKS(12,8,3);   }
69OP( 0x1f, i_pop_ds   ) { POP(Sreg(DS0));        CLKS(12,8,5);   }
70
71OP( 0x20, i_and_br8  ) { DEF_br8;   ANDB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
72OP( 0x21, i_and_wr16 ) { DEF_wr16;  ANDW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
73OP( 0x22, i_and_r8b  ) { DEF_r8b;   ANDB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
74OP( 0x23, i_and_r16w ) { DEF_r16w;  ANDW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
75OP( 0x24, i_and_ald8 ) { DEF_ald8;  ANDB;   Breg(AL)=dst;           CLKS(4,4,2);                }
76OP( 0x25, i_and_axd16) { DEF_axd16; ANDW;   Wreg(AW)=dst;           CLKS(4,4,2);    }
77OP( 0x26, i_es       ) { m_seg_prefix=TRUE;    m_prefix_base=Sreg(DS1)<<4;    CLK(2);     (this->*s_nec_instruction[fetchop()])(); m_seg_prefix=FALSE; }
78OP( 0x27, i_daa      ) { ADJ4(6,0x60);                                  CLKS(3,3,2);    }
79
80OP( 0x28, i_sub_br8  ) { DEF_br8;   SUBB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
81OP( 0x29, i_sub_wr16 ) { DEF_wr16;  SUBW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
82OP( 0x2a, i_sub_r8b  ) { DEF_r8b;   SUBB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
83OP( 0x2b, i_sub_r16w ) { DEF_r16w;  SUBW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
84OP( 0x2c, i_sub_ald8 ) { DEF_ald8;  SUBB;   Breg(AL)=dst;           CLKS(4,4,2);                }
85OP( 0x2d, i_sub_axd16) { DEF_axd16; SUBW;   Wreg(AW)=dst;           CLKS(4,4,2);    }
86OP( 0x2e, i_cs       ) { m_seg_prefix=TRUE;    m_prefix_base=Sreg(PS)<<4; CLK(2);     (this->*s_nec_instruction[fetchop()])(); m_seg_prefix=FALSE; }
87OP( 0x2f, i_das      ) { ADJ4(-6,-0x60);                                CLKS(3,3,2);    }
88
89OP( 0x30, i_xor_br8  ) { DEF_br8;   XORB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
90OP( 0x31, i_xor_wr16 ) { DEF_wr16;  XORW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
91OP( 0x32, i_xor_r8b  ) { DEF_r8b;   XORB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
92OP( 0x33, i_xor_r16w ) { DEF_r16w;  XORW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
93OP( 0x34, i_xor_ald8 ) { DEF_ald8;  XORB;   Breg(AL)=dst;           CLKS(4,4,2);                }
94OP( 0x35, i_xor_axd16) { DEF_axd16; XORW;   Wreg(AW)=dst;           CLKS(4,4,2);    }
95OP( 0x36, i_ss       ) { m_seg_prefix=TRUE;    m_prefix_base=Sreg(SS)<<4; CLK(2);     (this->*s_nec_instruction[fetchop()])(); m_seg_prefix=FALSE; }
96OP( 0x37, i_aaa      ) { ADJB(6, (Breg(AL) > 0xf9) ? 2 : 1);        CLKS(7,7,4);    }
97
98OP( 0x38, i_cmp_br8  ) { DEF_br8;   SUBB;                   CLKM(2,2,2,11,11,6); }
99OP( 0x39, i_cmp_wr16 ) { DEF_wr16;  SUBW;                   CLKR(15,15,8,15,11,6,2,m_EA);}
100OP( 0x3a, i_cmp_r8b  ) { DEF_r8b;   SUBB;                   CLKM(2,2,2,11,11,6); }
101OP( 0x3b, i_cmp_r16w ) { DEF_r16w;  SUBW;                   CLKR(15,15,8,15,11,6,2,m_EA); }
102OP( 0x3c, i_cmp_ald8 ) { DEF_ald8;  SUBB;                   CLKS(4,4,2); }
103OP( 0x3d, i_cmp_axd16) { DEF_axd16; SUBW;                   CLKS(4,4,2);    }
104OP( 0x3e, i_ds       ) { m_seg_prefix=TRUE;    m_prefix_base=Sreg(DS0)<<4;    CLK(2);     (this->*s_nec_instruction[fetchop()])(); m_seg_prefix=FALSE; }
105OP( 0x3f, i_aas      ) { ADJB(-6, (Breg(AL) < 6) ? -2 : -1);        CLKS(7,7,4);    }
106
107OP( 0x40, i_inc_ax  ) { IncWordReg(AW);                     CLK(2); }
108OP( 0x41, i_inc_cx  ) { IncWordReg(CW);                     CLK(2); }
109OP( 0x42, i_inc_dx  ) { IncWordReg(DW);                     CLK(2); }
110OP( 0x43, i_inc_bx  ) { IncWordReg(BW);                     CLK(2); }
111OP( 0x44, i_inc_sp  ) { IncWordReg(SP);                     CLK(2); }
112OP( 0x45, i_inc_bp  ) { IncWordReg(BP);                     CLK(2); }
113OP( 0x46, i_inc_si  ) { IncWordReg(IX);                     CLK(2); }
114OP( 0x47, i_inc_di  ) { IncWordReg(IY);                     CLK(2); }
115
116OP( 0x48, i_dec_ax  ) { DecWordReg(AW);                     CLK(2); }
117OP( 0x49, i_dec_cx  ) { DecWordReg(CW);                     CLK(2); }
118OP( 0x4a, i_dec_dx  ) { DecWordReg(DW);                     CLK(2); }
119OP( 0x4b, i_dec_bx  ) { DecWordReg(BW);                     CLK(2); }
120OP( 0x4c, i_dec_sp  ) { DecWordReg(SP);                     CLK(2); }
121OP( 0x4d, i_dec_bp  ) { DecWordReg(BP);                     CLK(2); }
122OP( 0x4e, i_dec_si  ) { DecWordReg(IX);                     CLK(2); }
123OP( 0x4f, i_dec_di  ) { DecWordReg(IY);                     CLK(2); }
124
125OP( 0x50, i_push_ax ) { PUSH(Wreg(AW));                 CLKS(12,8,3); }
126OP( 0x51, i_push_cx ) { PUSH(Wreg(CW));                 CLKS(12,8,3); }
127OP( 0x52, i_push_dx ) { PUSH(Wreg(DW));                 CLKS(12,8,3); }
128OP( 0x53, i_push_bx ) { PUSH(Wreg(BW));                 CLKS(12,8,3); }
129OP( 0x54, i_push_sp ) { PUSH(Wreg(SP));                 CLKS(12,8,3); }
130OP( 0x55, i_push_bp ) { PUSH(Wreg(BP));                 CLKS(12,8,3); }
131OP( 0x56, i_push_si ) { PUSH(Wreg(IX));                 CLKS(12,8,3); }
132OP( 0x57, i_push_di ) { PUSH(Wreg(IY));                 CLKS(12,8,3); }
133
134OP( 0x58, i_pop_ax  ) { POP(Wreg(AW));                  CLKS(12,8,5); }
135OP( 0x59, i_pop_cx  ) { POP(Wreg(CW));                  CLKS(12,8,5); }
136OP( 0x5a, i_pop_dx  ) { POP(Wreg(DW));                  CLKS(12,8,5); }
137OP( 0x5b, i_pop_bx  ) { POP(Wreg(BW));                  CLKS(12,8,5); }
138OP( 0x5c, i_pop_sp  ) { POP(Wreg(SP));                  CLKS(12,8,5); }
139OP( 0x5d, i_pop_bp  ) { POP(Wreg(BP));                  CLKS(12,8,5); }
140OP( 0x5e, i_pop_si  ) { POP(Wreg(IX));                  CLKS(12,8,5); }
141OP( 0x5f, i_pop_di  ) { POP(Wreg(IY));                  CLKS(12,8,5); }
142
143OP( 0x60, i_pusha  ) {
144   unsigned tmp=Wreg(SP);
145   PUSH(Wreg(AW));
146   PUSH(Wreg(CW));
147   PUSH(Wreg(DW));
148   PUSH(Wreg(BW));
149   PUSH(tmp);
150   PUSH(Wreg(BP));
151   PUSH(Wreg(IX));
152   PUSH(Wreg(IY));
153   CLKS(67,35,20);
154}
155static unsigned nec_popa_tmp;
156OP( 0x61, i_popa  ) {
157   POP(Wreg(IY));
158   POP(Wreg(IX));
159   POP(Wreg(BP));
160   POP(nec_popa_tmp);
161   POP(Wreg(BW));
162   POP(Wreg(DW));
163   POP(Wreg(CW));
164   POP(Wreg(AW));
165   CLKS(75,43,22);
166}
167OP( 0x62, i_chkind  ) {
168   UINT32 low,high,tmp;
169   GetModRM;
170   low = GetRMWord(ModRM);
171   high= GetnextRMWord;
172   tmp= RegWord(ModRM);
173   if (tmp<low || tmp>high) {
174      nec_interrupt(NEC_CHKIND_VECTOR, BRK);
175   }
176   m_icount-=20;
177   logerror("%06x: bound %04x high %04x low %04x tmp\n",PC(),high,low,tmp);
178}
179OP( 0x64, i_repnc  ) {  UINT32 next = fetchop();   UINT16 c = Wreg(CW);
180   switch(next) { /* Segments */
181      case 0x26:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS1)<<4;    next = fetchop();  CLK(2); break;
182      case 0x2e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(PS)<<4; next = fetchop();  CLK(2); break;
183      case 0x36:  m_seg_prefix=TRUE; m_prefix_base=Sreg(SS)<<4; next = fetchop();  CLK(2); break;
184      case 0x3e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS0)<<4;    next = fetchop();  CLK(2); break;
185   }
186
187   switch(next) {
188      case 0x6c:  CLK(2); if (c) do { i_insb();  c--; } while (c>0 && !CF); Wreg(CW)=c; break;
189      case 0x6d:  CLK(2); if (c) do { i_insw();  c--; } while (c>0 && !CF); Wreg(CW)=c; break;
190      case 0x6e:  CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
191      case 0x6f:  CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
192      case 0xa4:  CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
193      case 0xa5:  CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
194      case 0xa6:  CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
195      case 0xa7:  CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
196      case 0xaa:  CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
197      case 0xab:  CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
198      case 0xac:  CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
199      case 0xad:  CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
200      case 0xae:  CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
201      case 0xaf:  CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
202      default:    logerror("%06x: REPNC invalid\n",PC());    (this->*s_nec_instruction[next])();
203   }
204   m_seg_prefix=FALSE;
205}
206
207OP( 0x65, i_repc  ) {   UINT32 next = fetchop();   UINT16 c = Wreg(CW);
208   switch(next) { /* Segments */
209      case 0x26:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS1)<<4;    next = fetchop();  CLK(2); break;
210      case 0x2e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(PS)<<4; next = fetchop();  CLK(2); break;
211      case 0x36:  m_seg_prefix=TRUE; m_prefix_base=Sreg(SS)<<4; next = fetchop();  CLK(2); break;
212      case 0x3e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS0)<<4;    next = fetchop();  CLK(2); break;
213   }
214
215   switch(next) {
216      case 0x6c:  CLK(2); if (c) do { i_insb();  c--; } while (c>0 && CF);   Wreg(CW)=c; break;
217      case 0x6d:  CLK(2); if (c) do { i_insw();  c--; } while (c>0 && CF);   Wreg(CW)=c; break;
218      case 0x6e:  CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
219      case 0x6f:  CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
220      case 0xa4:  CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
221      case 0xa5:  CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
222      case 0xa6:  CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
223      case 0xa7:  CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
224      case 0xaa:  CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
225      case 0xab:  CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
226      case 0xac:  CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
227      case 0xad:  CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
228      case 0xae:  CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
229      case 0xaf:  CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
230      default:    logerror("%06x: REPC invalid\n",PC()); (this->*s_nec_instruction[next])();
231   }
232   m_seg_prefix=FALSE;
233}
234
235OP( 0x68, i_push_d16 ) { UINT32 tmp;    tmp = FETCHWORD(); PUSH(tmp);   CLKW(12,12,5,12,8,5,Wreg(SP));  }
236OP( 0x69, i_imul_d16 ) { UINT32 tmp;    DEF_r16w;   tmp = FETCHWORD(); dst = (INT32)((INT16)src)*(INT32)((INT16)tmp); m_CarryVal = m_OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1);     RegWord(ModRM)=(WORD)dst;     m_icount-=(ModRM >=0xc0 )?38:47;}
237OP( 0x6a, i_push_d8  ) { UINT32 tmp = (WORD)((INT16)((INT8)FETCH()));   PUSH(tmp);  CLKW(11,11,5,11,7,3,Wreg(SP));  }
238OP( 0x6b, i_imul_d8  ) { UINT32 src2; DEF_r16w; src2= (WORD)((INT16)((INT8)FETCH())); dst = (INT32)((INT16)src)*(INT32)((INT16)src2); m_CarryVal = m_OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?31:39; }
239OP( 0x6c, i_insb     ) { PutMemB(DS1,Wreg(IY),read_port_byte(Wreg(DW))); Wreg(IY)+= -2 * m_DF + 1; CLK(8); }
240OP( 0x6d, i_insw     ) { PutMemW(DS1,Wreg(IY),read_port_word(Wreg(DW))); Wreg(IY)+= -4 * m_DF + 2; CLKS(18,10,8); }
241OP( 0x6e, i_outsb    ) { write_port_byte(Wreg(DW),GetMemB(DS0,Wreg(IX))); Wreg(IX)+= -2 * m_DF + 1; CLK(8); }
242OP( 0x6f, i_outsw    ) { write_port_word(Wreg(DW),GetMemW(DS0,Wreg(IX))); Wreg(IX)+= -4 * m_DF + 2; CLKS(18,10,8); }
243
244OP( 0x70, i_jo      ) { JMP( OF);               CLKS(4,4,3); }
245OP( 0x71, i_jno     ) { JMP(!OF);               CLKS(4,4,3); }
246OP( 0x72, i_jc      ) { JMP( CF);               CLKS(4,4,3); }
247OP( 0x73, i_jnc     ) { JMP(!CF);               CLKS(4,4,3); }
248OP( 0x74, i_jz      ) { JMP( ZF);               CLKS(4,4,3); }
249OP( 0x75, i_jnz     ) { JMP(!ZF);               CLKS(4,4,3); }
250OP( 0x76, i_jce     ) { JMP(CF || ZF);          CLKS(4,4,3); }
251OP( 0x77, i_jnce    ) { JMP(!(CF || ZF));       CLKS(4,4,3); }
252OP( 0x78, i_js      ) { JMP( SF);               CLKS(4,4,3); }
253OP( 0x79, i_jns     ) { JMP(!SF);               CLKS(4,4,3); }
254OP( 0x7a, i_jp      ) { JMP( PF);               CLKS(4,4,3); }
255OP( 0x7b, i_jnp     ) { JMP(!PF);               CLKS(4,4,3); }
256OP( 0x7c, i_jl      ) { JMP((SF!=OF)&&(!ZF));   CLKS(4,4,3); }
257OP( 0x7d, i_jnl     ) { JMP((ZF)||(SF==OF));    CLKS(4,4,3); }
258OP( 0x7e, i_jle     ) { JMP((ZF)||(SF!=OF));    CLKS(4,4,3); }
259OP( 0x7f, i_jnle    ) { JMP((SF==OF)&&(!ZF));   CLKS(4,4,3); }
260
261OP( 0x80, i_80pre   ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = FETCH();
262   if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7)
263   switch (ModRM & 0x38) {
264      case 0x00: ADDB;            PutbackRMByte(ModRM,dst);   break;
265      case 0x08: ORB;             PutbackRMByte(ModRM,dst);   break;
266      case 0x10: src+=CF; ADDB;   PutbackRMByte(ModRM,dst);   break;
267      case 0x18: src+=CF; SUBB;   PutbackRMByte(ModRM,dst);   break;
268      case 0x20: ANDB;            PutbackRMByte(ModRM,dst);   break;
269      case 0x28: SUBB;            PutbackRMByte(ModRM,dst);   break;
270      case 0x30: XORB;            PutbackRMByte(ModRM,dst);   break;
271      case 0x38: SUBB;            break;  /* CMP */
272   }
273}
274
275OP( 0x81, i_81pre   ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = FETCH(); src+= (FETCH() << 8);
276   if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,m_EA) else CLKW(26,26,11,26,18,7,m_EA)
277   switch (ModRM & 0x38) {
278      case 0x00: ADDW;            PutbackRMWord(ModRM,dst);   break;
279      case 0x08: ORW;             PutbackRMWord(ModRM,dst);   break;
280      case 0x10: src+=CF; ADDW;   PutbackRMWord(ModRM,dst);   break;
281      case 0x18: src+=CF; SUBW;   PutbackRMWord(ModRM,dst);   break;
282      case 0x20: ANDW;            PutbackRMWord(ModRM,dst);   break;
283      case 0x28: SUBW;            PutbackRMWord(ModRM,dst);   break;
284      case 0x30: XORW;            PutbackRMWord(ModRM,dst);   break;
285      case 0x38: SUBW;            break;  /* CMP */
286   }
287}
288
289OP( 0x82, i_82pre   ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = (BYTE)((INT8)FETCH());
290   if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7)
291   switch (ModRM & 0x38) {
292      case 0x00: ADDB;            PutbackRMByte(ModRM,dst);   break;
293      case 0x08: ORB;             PutbackRMByte(ModRM,dst);   break;
294      case 0x10: src+=CF; ADDB;   PutbackRMByte(ModRM,dst);   break;
295      case 0x18: src+=CF; SUBB;   PutbackRMByte(ModRM,dst);   break;
296      case 0x20: ANDB;            PutbackRMByte(ModRM,dst);   break;
297      case 0x28: SUBB;            PutbackRMByte(ModRM,dst);   break;
298      case 0x30: XORB;            PutbackRMByte(ModRM,dst);   break;
299      case 0x38: SUBB;            break;  /* CMP */
300   }
301}
302
303OP( 0x83, i_83pre   ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = (WORD)((INT16)((INT8)FETCH()));
304   if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,m_EA) else CLKW(26,26,11,26,18,7,m_EA)
305   switch (ModRM & 0x38) {
306      case 0x00: ADDW;            PutbackRMWord(ModRM,dst);   break;
307      case 0x08: ORW;             PutbackRMWord(ModRM,dst);   break;
308      case 0x10: src+=CF; ADDW;   PutbackRMWord(ModRM,dst);   break;
309      case 0x18: src+=CF; SUBW;   PutbackRMWord(ModRM,dst);   break;
310      case 0x20: ANDW;            PutbackRMWord(ModRM,dst);   break;
311      case 0x28: SUBW;            PutbackRMWord(ModRM,dst);   break;
312      case 0x30: XORW;            PutbackRMWord(ModRM,dst);   break;
313      case 0x38: SUBW;            break;  /* CMP */
314   }
315}
316
317OP( 0x84, i_test_br8  ) { DEF_br8;  ANDB;   CLKM(2,2,2,10,10,6);        }
318OP( 0x85, i_test_wr16 ) { DEF_wr16; ANDW;   CLKR(14,14,8,14,10,6,2,m_EA); }
319OP( 0x86, i_xchg_br8  ) { DEF_br8;  RegByte(ModRM)=dst; PutbackRMByte(ModRM,src); CLKM(3,3,3,16,18,8); }
320OP( 0x87, i_xchg_wr16 ) { DEF_wr16; RegWord(ModRM)=dst; PutbackRMWord(ModRM,src); CLKR(24,24,12,24,16,8,3,m_EA); }
321
322OP( 0x88, i_mov_br8   ) { UINT8  src; GetModRM; src = RegByte(ModRM);   PutRMByte(ModRM,src);   CLKM(2,2,2,9,9,3);          }
323OP( 0x89, i_mov_wr16  ) { UINT16 src; GetModRM; src = RegWord(ModRM);   PutRMWord(ModRM,src);   CLKR(13,13,5,13,9,3,2,m_EA);  }
324OP( 0x8a, i_mov_r8b   ) { UINT8  src; GetModRM; src = GetRMByte(ModRM); RegByte(ModRM)=src;     CLKM(2,2,2,11,11,5);        }
325OP( 0x8b, i_mov_r16w  ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); RegWord(ModRM)=src;     CLKR(15,15,7,15,11,5,2,m_EA);     }
326OP( 0x8c, i_mov_wsreg ) { GetModRM;
327   switch (ModRM & 0x38) {
328      case 0x00: PutRMWord(ModRM,Sreg(DS1)); CLKR(14,14,5,14,10,3,2,m_EA); break;
329      case 0x08: PutRMWord(ModRM,Sreg(PS)); CLKR(14,14,5,14,10,3,2,m_EA); break;
330      case 0x10: PutRMWord(ModRM,Sreg(SS)); CLKR(14,14,5,14,10,3,2,m_EA); break;
331      case 0x18: PutRMWord(ModRM,Sreg(DS0)); CLKR(14,14,5,14,10,3,2,m_EA); break;
332      default:   logerror("%06x: MOV Sreg - Invalid register\n",PC());
333   }
334}
335OP( 0x8d, i_lea       ) { UINT16 ModRM = FETCH(); (void)(this->*s_GetEA[ModRM])(); RegWord(ModRM)=m_EO;  CLKS(4,4,2); }
336OP( 0x8e, i_mov_sregw ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); CLKR(15,15,7,15,11,5,2,m_EA);
337   switch (ModRM & 0x38) {
338      case 0x00: Sreg(DS1) = src; break; /* mov es,ew */
339      case 0x08: Sreg(PS) = src; break; /* mov cs,ew */
340      case 0x10: Sreg(SS) = src; break; /* mov ss,ew */
341      case 0x18: Sreg(DS0) = src; break; /* mov ds,ew */
342      default:   logerror("%06x: MOV Sreg - Invalid register\n",PC());
343   }
344   m_no_interrupt=1;
345}
346OP( 0x8f, i_popw ) { UINT16 tmp; GetModRM; POP(tmp); PutRMWord(ModRM,tmp); m_icount-=21; }
347OP( 0x90, i_nop  ) { CLK(3); /* { if (m_MF == 0) printf("90 -> %06x: \n",PC()); }  */ }
348OP( 0x91, i_xchg_axcx ) { XchgAWReg(CW); CLK(3); }
349OP( 0x92, i_xchg_axdx ) { XchgAWReg(DW); CLK(3); }
350OP( 0x93, i_xchg_axbx ) { XchgAWReg(BW); CLK(3); }
351OP( 0x94, i_xchg_axsp ) { XchgAWReg(SP); CLK(3); }
352OP( 0x95, i_xchg_axbp ) { XchgAWReg(BP); CLK(3); }
353OP( 0x96, i_xchg_axsi ) { XchgAWReg(IX); CLK(3); }
354OP( 0x97, i_xchg_axdi ) { XchgAWReg(IY); CLK(3); }
355
356OP( 0x98, i_cbw       ) { Breg(AH) = (Breg(AL) & 0x80) ? 0xff : 0;      CLK(2); }
357OP( 0x99, i_cwd       ) { Wreg(DW) = (Breg(AH) & 0x80) ? 0xffff : 0;    CLK(4); }
358OP( 0x9a, i_call_far  ) { UINT32 tmp, tmp2; tmp = FETCHWORD(); tmp2 = FETCHWORD(); PUSH(Sreg(PS)); PUSH(m_ip); m_ip = (WORD)tmp; Sreg(PS) = (WORD)tmp2; CHANGE_PC; CLKW(29,29,13,29,21,9,Wreg(SP)); }
359OP( 0x9b, i_wait      ) { if (!m_poll_state) m_ip--; CLK(5); }
360OP( 0x9c, i_pushf     ) { UINT16 tmp = CompressFlags(); PUSH( tmp ); CLKS(12,8,3); }
361OP( 0x9d, i_popf      ) { UINT32 tmp; POP(tmp); ExpandFlags(tmp); CLKS(12,8,5); if (m_TF) nec_trap(); }
362OP( 0x9e, i_sahf      ) { UINT32 tmp = (CompressFlags() & 0xff00) | (Breg(AH) & 0xd5); ExpandFlags(tmp); CLKS(3,3,2); }
363OP( 0x9f, i_lahf      ) { Breg(AH) = CompressFlags() & 0xff; CLKS(3,3,2); }
364
365OP( 0xa0, i_mov_aldisp ) { UINT32 addr; addr = FETCHWORD(); Breg(AL) = GetMemB(DS0, addr); CLKS(10,10,5); }
366OP( 0xa1, i_mov_axdisp ) { UINT32 addr; addr = FETCHWORD(); Wreg(AW) = GetMemW(DS0, addr); CLKW(14,14,7,14,10,5,addr); }
367OP( 0xa2, i_mov_dispal ) { UINT32 addr; addr = FETCHWORD(); PutMemB(DS0, addr, Breg(AL));  CLKS(9,9,3); }
368OP( 0xa3, i_mov_dispax ) { UINT32 addr; addr = FETCHWORD(); PutMemW(DS0, addr, Wreg(AW));  CLKW(13,13,5,13,9,3,addr); }
369OP( 0xa4, i_movsb      ) { UINT32 tmp = GetMemB(DS0,Wreg(IX)); PutMemB(DS1,Wreg(IY), tmp); Wreg(IY) += -2 * m_DF + 1; Wreg(IX) += -2 * m_DF + 1; CLKS(8,8,6); }
370OP( 0xa5, i_movsw      ) { UINT32 tmp = GetMemW(DS0,Wreg(IX)); PutMemW(DS1,Wreg(IY), tmp); Wreg(IY) += -4 * m_DF + 2; Wreg(IX) += -4 * m_DF + 2; CLKS(16,16,10); }
371OP( 0xa6, i_cmpsb      ) { UINT32 src = GetMemB(DS1, Wreg(IY)); UINT32 dst = GetMemB(DS0, Wreg(IX)); SUBB; Wreg(IY) += -2 * m_DF + 1; Wreg(IX) += -2 * m_DF + 1; CLKS(14,14,14); }
372OP( 0xa7, i_cmpsw      ) { UINT32 src = GetMemW(DS1, Wreg(IY)); UINT32 dst = GetMemW(DS0, Wreg(IX)); SUBW; Wreg(IY) += -4 * m_DF + 2; Wreg(IX) += -4 * m_DF + 2; CLKS(14,14,14); }
373
374OP( 0xa8, i_test_ald8  ) { DEF_ald8;  ANDB; CLKS(4,4,2); }
375OP( 0xa9, i_test_axd16 ) { DEF_axd16; ANDW; CLKS(4,4,2); }
376OP( 0xaa, i_stosb      ) { PutMemB(DS1,Wreg(IY),Breg(AL));  Wreg(IY) += -2 * m_DF + 1; CLKS(4,4,3);  }
377OP( 0xab, i_stosw      ) { PutMemW(DS1,Wreg(IY),Wreg(AW));  Wreg(IY) += -4 * m_DF + 2; CLKW(8,8,5,8,4,3,Wreg(IY)); }
378OP( 0xac, i_lodsb      ) { Breg(AL) = GetMemB(DS0,Wreg(IX)); Wreg(IX) += -2 * m_DF + 1; CLKS(4,4,3);  }
379OP( 0xad, i_lodsw      ) { Wreg(AW) = GetMemW(DS0,Wreg(IX)); Wreg(IX) += -4 * m_DF + 2; CLKW(8,8,5,8,4,3,Wreg(IX)); }
380OP( 0xae, i_scasb      ) { UINT32 src = GetMemB(DS1, Wreg(IY)); UINT32 dst = Breg(AL); SUBB; Wreg(IY) += -2 * m_DF + 1; CLKS(4,4,3);  }
381OP( 0xaf, i_scasw      ) { UINT32 src = GetMemW(DS1, Wreg(IY)); UINT32 dst = Wreg(AW); SUBW; Wreg(IY) += -4 * m_DF + 2; CLKW(8,8,5,8,4,3,Wreg(IY)); }
382
383OP( 0xb0, i_mov_ald8  ) { Breg(AL) = FETCH();   CLKS(4,4,2); }
384OP( 0xb1, i_mov_cld8  ) { Breg(CL) = FETCH(); CLKS(4,4,2); }
385OP( 0xb2, i_mov_dld8  ) { Breg(DL) = FETCH(); CLKS(4,4,2); }
386OP( 0xb3, i_mov_bld8  ) { Breg(BL) = FETCH(); CLKS(4,4,2); }
387OP( 0xb4, i_mov_ahd8  ) { Breg(AH) = FETCH(); CLKS(4,4,2); }
388OP( 0xb5, i_mov_chd8  ) { Breg(CH) = FETCH(); CLKS(4,4,2); }
389OP( 0xb6, i_mov_dhd8  ) { Breg(DH) = FETCH(); CLKS(4,4,2); }
390OP( 0xb7, i_mov_bhd8  ) { Breg(BH) = FETCH();   CLKS(4,4,2); }
391
392OP( 0xb8, i_mov_axd16 ) { Breg(AL) = FETCH();    Breg(AH) = FETCH();    CLKS(4,4,2); }
393OP( 0xb9, i_mov_cxd16 ) { Breg(CL) = FETCH();    Breg(CH) = FETCH();    CLKS(4,4,2); }
394OP( 0xba, i_mov_dxd16 ) { Breg(DL) = FETCH();    Breg(DH) = FETCH();    CLKS(4,4,2); }
395OP( 0xbb, i_mov_bxd16 ) { Breg(BL) = FETCH();    Breg(BH) = FETCH();    CLKS(4,4,2); }
396OP( 0xbc, i_mov_spd16 ) { Wreg(SP) = FETCHWORD();   CLKS(4,4,2); }
397OP( 0xbd, i_mov_bpd16 ) { Wreg(BP) = FETCHWORD();   CLKS(4,4,2); }
398OP( 0xbe, i_mov_sid16 ) { Wreg(IX) = FETCHWORD();   CLKS(4,4,2); }
399OP( 0xbf, i_mov_did16 ) { Wreg(IY) = FETCHWORD();   CLKS(4,4,2); }
400
401OP( 0xc0, i_rotshft_bd8 ) {
402   UINT32 src, dst; UINT8 c;
403   GetModRM; src = (unsigned)GetRMByte(ModRM); dst=src;
404   c=FETCH();
405   CLKM(7,7,2,19,19,6);
406   if (c) switch (ModRM & 0x38) {
407      case 0x00: do { ROL_BYTE;  c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
408      case 0x08: do { ROR_BYTE;  c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
409      case 0x10: do { ROLC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
410      case 0x18: do { RORC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
411      case 0x20: SHL_BYTE(c); break;
412      case 0x28: SHR_BYTE(c); break;
413      case 0x30: logerror("%06x: Undefined opcode 0xc0 0x30 (SHLA)\n",PC()); break;
414      case 0x38: SHRA_BYTE(c); break;
415   }
416}
417
418OP( 0xc1, i_rotshft_wd8 ) {
419   UINT32 src, dst;  UINT8 c;
420   GetModRM; src = (unsigned)GetRMWord(ModRM); dst=src;
421   c=FETCH();
422   CLKM(7,7,2,27,19,6);
423   if (c) switch (ModRM & 0x38) {
424      case 0x00: do { ROL_WORD;  c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
425      case 0x08: do { ROR_WORD;  c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
426      case 0x10: do { ROLC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
427      case 0x18: do { RORC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
428      case 0x20: SHL_WORD(c); break;
429      case 0x28: SHR_WORD(c); break;
430      case 0x30: logerror("%06x: Undefined opcode 0xc1 0x30 (SHLA)\n",PC()); break;
431      case 0x38: SHRA_WORD(c); break;
432   }
433}
434
435OP( 0xc2, i_ret_d16  ) { UINT32 count = FETCH(); count += FETCH() << 8; POP(m_ip); Wreg(SP)+=count; CHANGE_PC; CLKS(24,24,10); }
436OP( 0xc3, i_ret      ) { POP(m_ip); CHANGE_PC; CLKS(19,19,10); }
437OP( 0xc4, i_les_dw   ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS1) = GetnextRMWord; CLKW(26,26,14,26,18,10,m_EA); }
438OP( 0xc5, i_lds_dw   ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS0) = GetnextRMWord; CLKW(26,26,14,26,18,10,m_EA); }
439OP( 0xc6, i_mov_bd8  ) { GetModRM; PutImmRMByte(ModRM); m_icount-=(ModRM >=0xc0 )?4:11; }
440OP( 0xc7, i_mov_wd16 ) { GetModRM; PutImmRMWord(ModRM); m_icount-=(ModRM >=0xc0 )?4:15; }
441
442OP( 0xc8, i_enter ) {
443   UINT32 nb = FETCH();
444   UINT32 i,level;
445
446   m_icount-=23;
447   nb += FETCH() << 8;
448   level = FETCH();
449   PUSH(Wreg(BP));
450   Wreg(BP)=Wreg(SP);
451   Wreg(SP) -= nb;
452   for (i=1;i<level;i++) {
453      PUSH(GetMemW(SS,Wreg(BP)-i*2));
454      m_icount-=16;
455   }
456   if (level) PUSH(Wreg(BP));
457}
458OP( 0xc9, i_leave ) {
459   Wreg(SP)=Wreg(BP);
460   POP(Wreg(BP));
461   m_icount-=8;
462}
463OP( 0xca, i_retf_d16  ) { UINT32 count = FETCH(); count += FETCH() << 8; POP(m_ip); POP(Sreg(PS)); Wreg(SP)+=count; CHANGE_PC; CLKS(32,32,16); }
464OP( 0xcb, i_retf      ) { POP(m_ip); POP(Sreg(PS)); CHANGE_PC; CLKS(29,29,16); }
465OP( 0xcc, i_int3      ) { nec_interrupt(3, BRK); CLKS(50,50,24); }
466OP( 0xcd, i_int       ) { nec_interrupt(FETCH(), BRK); CLKS(50,50,24); }
467OP( 0xce, i_into      ) { if (OF) { nec_interrupt(NEC_BRKV_VECTOR, BRK); CLKS(52,52,26); } else CLK(3); }
468OP( 0xcf, i_iret      ) { POP(m_ip); POP(Sreg(PS)); i_popf(); CHANGE_PC; CLKS(39,39,19); }
469
470OP( 0xd0, i_rotshft_b ) {
471   UINT32 src, dst; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
472   CLKM(6,6,2,16,16,7);
473   switch (ModRM & 0x38) {
474      case 0x00: ROL_BYTE;  PutbackRMByte(ModRM,(BYTE)dst); m_OverVal = (src^dst)&0x80; break;
475      case 0x08: ROR_BYTE;  PutbackRMByte(ModRM,(BYTE)dst); m_OverVal = (src^dst)&0x80; break;
476      case 0x10: ROLC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); m_OverVal = (src^dst)&0x80; break;
477      case 0x18: RORC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); m_OverVal = (src^dst)&0x80; break;
478      case 0x20: SHL_BYTE(1); m_OverVal = (src^dst)&0x80; break;
479      case 0x28: SHR_BYTE(1); m_OverVal = (src^dst)&0x80; break;
480      case 0x30: logerror("%06x: Undefined opcode 0xd0 0x30 (SHLA)\n",PC()); break;
481      case 0x38: SHRA_BYTE(1); m_OverVal = 0; break;
482   }
483}
484
485OP( 0xd1, i_rotshft_w ) {
486   UINT32 src, dst; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
487   CLKM(6,6,2,24,16,7);
488   switch (ModRM & 0x38) {
489      case 0x00: ROL_WORD;  PutbackRMWord(ModRM,(WORD)dst); m_OverVal = (src^dst)&0x8000; break;
490      case 0x08: ROR_WORD;  PutbackRMWord(ModRM,(WORD)dst); m_OverVal = (src^dst)&0x8000; break;
491      case 0x10: ROLC_WORD; PutbackRMWord(ModRM,(WORD)dst); m_OverVal = (src^dst)&0x8000; break;
492      case 0x18: RORC_WORD; PutbackRMWord(ModRM,(WORD)dst); m_OverVal = (src^dst)&0x8000; break;
493      case 0x20: SHL_WORD(1); m_OverVal = (src^dst)&0x8000;  break;
494      case 0x28: SHR_WORD(1); m_OverVal = (src^dst)&0x8000;  break;
495      case 0x30: logerror("%06x: Undefined opcode 0xd1 0x30 (SHLA)\n",PC()); break;
496      case 0x38: SHRA_WORD(1); m_OverVal = 0; break;
497   }
498}
499
500OP( 0xd2, i_rotshft_bcl ) {
501   UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
502   c=Breg(CL);
503   CLKM(7,7,2,19,19,6);
504   if (c) switch (ModRM & 0x38) {
505      case 0x00: do { ROL_BYTE;  c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
506      case 0x08: do { ROR_BYTE;  c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
507      case 0x10: do { ROLC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
508      case 0x18: do { RORC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
509      case 0x20: SHL_BYTE(c); break;
510      case 0x28: SHR_BYTE(c); break;
511      case 0x30: logerror("%06x: Undefined opcode 0xd2 0x30 (SHLA)\n",PC()); break;
512      case 0x38: SHRA_BYTE(c); break;
513   }
514}
515
516OP( 0xd3, i_rotshft_wcl ) {
517   UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
518   c=Breg(CL);
519   CLKM(7,7,2,27,19,6);
520   if (c) switch (ModRM & 0x38) {
521      case 0x00: do { ROL_WORD;  c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
522      case 0x08: do { ROR_WORD;  c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
523      case 0x10: do { ROLC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
524      case 0x18: do { RORC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
525      case 0x20: SHL_WORD(c); break;
526      case 0x28: SHR_WORD(c); break;
527      case 0x30: logerror("%06x: Undefined opcode 0xd3 0x30 (SHLA)\n",PC()); break;
528      case 0x38: SHRA_WORD(c); break;
529   }
530}
531
532OP( 0xd4, i_aam    ) { FETCH(); Breg(AH) = Breg(AL) / 10; Breg(AL) %= 10; SetSZPF_Word(Wreg(AW)); CLKS(15,15,12); }
533OP( 0xd5, i_aad    ) { FETCH(); Breg(AL) = Breg(AH) * 10 + Breg(AL); Breg(AH) = 0; SetSZPF_Byte(Breg(AL)); CLKS(7,7,8); }
534OP( 0xd6, i_setalc ) { Breg(AL) = (CF)?0xff:0x00; m_icount-=3; logerror("%06x: Undefined opcode (SETALC)\n",PC()); }
535OP( 0xd7, i_trans  ) { UINT32 dest = (Wreg(BW)+Breg(AL))&0xffff; Breg(AL) = GetMemB(DS0, dest); CLKS(9,9,5); }
536OP( 0xd8, i_fpo    ) { GetModRM; m_icount-=2;  logerror("%06x: Unimplemented floating point control %04x\n",PC(),ModRM); }
537
538OP( 0xe0, i_loopne ) { INT8 disp = (INT8)FETCH(); Wreg(CW)--; if (!ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); }
539OP( 0xe1, i_loope  ) { INT8 disp = (INT8)FETCH(); Wreg(CW)--; if ( ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); }
540OP( 0xe2, i_loop   ) { INT8 disp = (INT8)FETCH(); Wreg(CW)--; if (Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); }
541OP( 0xe3, i_jcxz   ) { INT8 disp = (INT8)FETCH(); if (Wreg(CW) == 0) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); }
542OP( 0xe4, i_inal   ) { UINT8 port = FETCH(); Breg(AL) = read_port_byte(port); CLKS(9,9,5);  }
543OP( 0xe5, i_inax   ) { UINT8 port = FETCH(); Wreg(AW) = read_port_word(port); CLKW(13,13,7,13,9,5,port); }
544OP( 0xe6, i_outal  ) { UINT8 port = FETCH(); write_port_byte(port, Breg(AL)); CLKS(8,8,3);  }
545OP( 0xe7, i_outax  ) { UINT8 port = FETCH(); write_port_word(port, Wreg(AW)); CLKW(12,12,5,12,8,3,port);    }
546
547OP( 0xe8, i_call_d16 ) { UINT32 tmp; tmp = FETCHWORD(); PUSH(m_ip); m_ip = (WORD)(m_ip+(INT16)tmp); CHANGE_PC; m_icount-=24; }
548OP( 0xe9, i_jmp_d16  ) { UINT32 tmp; tmp = FETCHWORD(); m_ip = (WORD)(m_ip+(INT16)tmp); CHANGE_PC; m_icount-=15; }
549OP( 0xea, i_jmp_far  ) { UINT32 tmp,tmp1; tmp = FETCHWORD(); tmp1 = FETCHWORD(); Sreg(PS) = (WORD)tmp1;     m_ip = (WORD)tmp; CHANGE_PC; m_icount-=27;  }
550OP( 0xeb, i_jmp_d8   ) { int tmp = (int)((INT8)FETCH()); m_icount-=12; m_ip = (WORD)(m_ip+tmp); }
551OP( 0xec, i_inaldx   ) { Breg(AL) = read_port_byte(Wreg(DW)); CLKS(8,8,5);}
552OP( 0xed, i_inaxdx   ) { Wreg(AW) = read_port_word(Wreg(DW)); CLKW(12,12,7,12,8,5,Wreg(DW)); }
553OP( 0xee, i_outdxal  ) { write_port_byte(Wreg(DW), Breg(AL)); CLKS(8,8,3);  }
554OP( 0xef, i_outdxax  ) { write_port_word(Wreg(DW), Wreg(AW)); CLKW(12,12,5,12,8,3,Wreg(DW)); }
555
556OP( 0xf0, i_lock     ) { logerror("%06x: Warning - BUSLOCK\n",PC()); m_no_interrupt=1; CLK(2); }
557OP( 0xf2, i_repne    ) { UINT32 next = fetchop(); UINT16 c = Wreg(CW);
558   switch(next) { /* Segments */
559      case 0x26:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS1)<<4;    next = fetchop();  CLK(2); break;
560      case 0x2e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(PS)<<4;     next = fetchop();  CLK(2); break;
561      case 0x36:  m_seg_prefix=TRUE; m_prefix_base=Sreg(SS)<<4;     next = fetchop();  CLK(2); break;
562      case 0x3e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS0)<<4;    next = fetchop();  CLK(2); break;
563   }
564
565   switch(next) {
566      case 0x6c:  CLK(2); if (c) do { i_insb();  c--; } while (c>0); Wreg(CW)=c; break;
567      case 0x6d:  CLK(2); if (c) do { i_insw();  c--; } while (c>0); Wreg(CW)=c; break;
568      case 0x6e:  CLK(2); if (c) do { i_outsb(); c--; } while (c>0); Wreg(CW)=c; break;
569      case 0x6f:  CLK(2); if (c) do { i_outsw(); c--; } while (c>0); Wreg(CW)=c; break;
570      case 0xa4:  CLK(2); if (c) do { i_movsb(); c--; } while (c>0); Wreg(CW)=c; break;
571      case 0xa5:  CLK(2); if (c) do { i_movsw(); c--; } while (c>0); Wreg(CW)=c; break;
572      case 0xa6:  CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && ZF==0);    Wreg(CW)=c; break;
573      case 0xa7:  CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && ZF==0);    Wreg(CW)=c; break;
574      case 0xaa:  CLK(2); if (c) do { i_stosb(); c--; } while (c>0); Wreg(CW)=c; break;
575      case 0xab:  CLK(2); if (c) do { i_stosw(); c--; } while (c>0); Wreg(CW)=c; break;
576      case 0xac:  CLK(2); if (c) do { i_lodsb(); c--; } while (c>0); Wreg(CW)=c; break;
577      case 0xad:  CLK(2); if (c) do { i_lodsw(); c--; } while (c>0); Wreg(CW)=c; break;
578      case 0xae:  CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && ZF==0);    Wreg(CW)=c; break;
579      case 0xaf:  CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && ZF==0);    Wreg(CW)=c; break;
580      default:    logerror("%06x: REPNE invalid\n",PC());    (this->*s_nec_instruction[next])();
581   }
582   m_seg_prefix=FALSE;
583}
584OP( 0xf3, i_repe     ) { UINT32 next = fetchop(); UINT16 c = Wreg(CW);
585   switch(next) { /* Segments */
586      case 0x26:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS1)<<4;    next = fetchop();  CLK(2); break;
587      case 0x2e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(PS)<<4; next = fetchop();  CLK(2); break;
588      case 0x36:  m_seg_prefix=TRUE; m_prefix_base=Sreg(SS)<<4; next = fetchop();  CLK(2); break;
589      case 0x3e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS0)<<4;    next = fetchop();  CLK(2); break;
590   }
591
592   switch(next) {
593      case 0x6c:  CLK(2); if (c) do { i_insb();  c--; } while (c>0); Wreg(CW)=c; break;
594      case 0x6d:  CLK(2); if (c) do { i_insw();  c--; } while (c>0); Wreg(CW)=c; break;
595      case 0x6e:  CLK(2); if (c) do { i_outsb(); c--; } while (c>0); Wreg(CW)=c; break;
596      case 0x6f:  CLK(2); if (c) do { i_outsw(); c--; } while (c>0); Wreg(CW)=c; break;
597      case 0xa4:  CLK(2); if (c) do { i_movsb(); c--; } while (c>0); Wreg(CW)=c; break;
598      case 0xa5:  CLK(2); if (c) do { i_movsw(); c--; } while (c>0); Wreg(CW)=c; break;
599      case 0xa6:  CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && ZF==1);    Wreg(CW)=c; break;
600      case 0xa7:  CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && ZF==1);    Wreg(CW)=c; break;
601      case 0xaa:  CLK(2); if (c) do { i_stosb(); c--; } while (c>0); Wreg(CW)=c; break;
602      case 0xab:  CLK(2); if (c) do { i_stosw(); c--; } while (c>0); Wreg(CW)=c; break;
603      case 0xac:  CLK(2); if (c) do { i_lodsb(); c--; } while (c>0); Wreg(CW)=c; break;
604      case 0xad:  CLK(2); if (c) do { i_lodsw(); c--; } while (c>0); Wreg(CW)=c; break;
605      case 0xae:  CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && ZF==1);    Wreg(CW)=c; break;
606      case 0xaf:  CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && ZF==1);    Wreg(CW)=c; break;
607      default:    logerror("%06x: REPE invalid\n",PC()); (this->*s_nec_instruction[next])();
608   }
609   m_seg_prefix=FALSE;
610}
611OP( 0xf4, i_hlt ) { logerror("%06x: HALT\n",PC()); m_halted=1; m_icount=0; }
612OP( 0xf5, i_cmc ) { m_CarryVal = !CF; CLK(2); }
613OP( 0xf6, i_f6pre ) { UINT32 tmp; UINT32 uresult,uresult2; INT32 result,result2;
614   GetModRM; tmp = GetRMByte(ModRM);
615   switch (ModRM & 0x38) {
616      case 0x00: tmp &= FETCH(); m_CarryVal = m_OverVal = 0; SetSZPF_Byte(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */
617      case 0x08: logerror("%06x: Undefined opcode 0xf6 0x08\n",PC()); break;
618      case 0x10: PutbackRMByte(ModRM,~tmp); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */
619      case 0x18: m_CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Byte(tmp); PutbackRMByte(ModRM,tmp&0xff); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */
620      case 0x20: uresult = Breg(AL)*tmp; Wreg(AW)=(WORD)uresult; m_CarryVal=m_OverVal=(Breg(AH)!=0); m_icount-=(ModRM >=0xc0 )?30:36; break; /* MULU */
621      case 0x28: result = (INT16)((INT8)Breg(AL))*(INT16)((INT8)tmp); Wreg(AW)=(WORD)result; m_CarryVal=m_OverVal=(Breg(AH)!=0); m_icount-=(ModRM >=0xc0 )?30:36; break; /* MUL */
622      case 0x30: if (tmp) { DIVUB; } else nec_interrupt(NEC_DIVIDE_VECTOR, BRK); m_icount-=(ModRM >=0xc0 )?43:53; break;
623      case 0x38: if (tmp) { DIVB;  } else nec_interrupt(NEC_DIVIDE_VECTOR, BRK); m_icount-=(ModRM >=0xc0 )?43:53; break;
624   }
625}
626
627OP( 0xf7, i_f7pre   ) { UINT32 tmp,tmp2; UINT32 uresult,uresult2; INT32 result,result2;
628   GetModRM; tmp = GetRMWord(ModRM);
629   switch (ModRM & 0x38) {
630      case 0x00: tmp2 = FETCHWORD(); tmp &= tmp2; m_CarryVal = m_OverVal = 0; SetSZPF_Word(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */
631      case 0x08: logerror("%06x: Undefined opcode 0xf7 0x08\n",PC()); break;
632      case 0x10: PutbackRMWord(ModRM,~tmp); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */
633      case 0x18: m_CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Word(tmp); PutbackRMWord(ModRM,tmp&0xffff); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */
634      case 0x20: uresult = Wreg(AW)*tmp; Wreg(AW)=uresult&0xffff; Wreg(DW)=((UINT32)uresult)>>16; m_CarryVal=m_OverVal=(Wreg(DW)!=0); m_icount-=(ModRM >=0xc0 )?30:36; break; /* MULU */
635      case 0x28: result = (INT32)((INT16)Wreg(AW))*(INT32)((INT16)tmp); Wreg(AW)=result&0xffff; Wreg(DW)=result>>16; m_CarryVal=m_OverVal=(Wreg(DW)!=0); m_icount-=(ModRM >=0xc0 )?30:36; break; /* MUL */
636      case 0x30: if (tmp) { DIVUW; } else nec_interrupt(NEC_DIVIDE_VECTOR, BRK); m_icount-=(ModRM >=0xc0 )?43:53; break;
637      case 0x38: if (tmp) { DIVW;  } else nec_interrupt(NEC_DIVIDE_VECTOR, BRK); m_icount-=(ModRM >=0xc0 )?43:53; break;
638   }
639}
640
641OP( 0xf8, i_clc   ) { m_CarryVal = 0;  CLK(2); }
642OP( 0xf9, i_stc   ) { m_CarryVal = 1;  CLK(2); }
643OP( 0xfa, i_di    ) { SetIF(0);         CLK(2); }
644OP( 0xfb, i_ei    ) { SetIF(1);         CLK(2); }
645OP( 0xfc, i_cld   ) { SetDF(0);         CLK(2); }
646OP( 0xfd, i_std   ) { SetDF(1);         CLK(2); }
647OP( 0xfe, i_fepre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMByte(ModRM);
648   switch(ModRM & 0x38) {
649      case 0x00: tmp1 = tmp+1; m_OverVal = (tmp==0x7f); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(2,2,2,16,16,7); break; /* INC */
650      case 0x08: tmp1 = tmp-1; m_OverVal = (tmp==0x80); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(2,2,2,16,16,7); break; /* DEC */
651      default:   logerror("%06x: FE Pre with unimplemented mod\n",PC());
652   }
653}
654OP( 0xff, i_ffpre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMWord(ModRM);
655   switch(ModRM & 0x38) {
656      case 0x00: tmp1 = tmp+1; m_OverVal = (tmp==0x7fff); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(2,2,2,24,16,7); break; /* INC */
657      case 0x08: tmp1 = tmp-1; m_OverVal = (tmp==0x8000); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(2,2,2,24,16,7); break; /* DEC */
658      case 0x10: PUSH(m_ip); m_ip = (WORD)tmp; CHANGE_PC; m_icount-=(ModRM >=0xc0 )?16:20; break; /* CALL */
659      case 0x18: tmp1 = Sreg(PS); Sreg(PS) = GetnextRMWord; PUSH(tmp1); PUSH(m_ip); m_ip = tmp; CHANGE_PC; m_icount-=(ModRM >=0xc0 )?16:26; break; /* CALL FAR */
660      case 0x20: m_ip = tmp; CHANGE_PC; m_icount-=13; break; /* JMP */
661      case 0x28: m_ip = tmp; Sreg(PS) = GetnextRMWord; CHANGE_PC; m_icount-=15; break; /* JMP FAR */
662      case 0x30: PUSH(tmp); m_icount-=4; break;
663      default:   logerror("%06x: FF Pre with unimplemented mod\n",PC());
664   }
665}
666
667void nec_common_device::i_invalid()
668{
669   m_icount-=10;
670   logerror("%06x: Invalid Opcode\n",PC());
671}
trunk/src/emu/cpu/nec/v25instr.c
r28738r28739
1#define GetRB   \
2   ModRM = FETCH();    \
3   if (ModRM >= 0xc0)  \
4      tmp = Wreg(Mod_RM.RM.w[ModRM]) & 0x7;   \
5   else {                          \
6      logerror("%06x: Invalid MODRM for register banking instruction\n",PC());   \
7      tmp = 0;    \
8   }
9
10#define RETRBI  \
11   tmp = (Wreg(PSW_SAVE) & 0x7000) >> 12;  \
12   m_ip = Wreg(PC_SAVE);  \
13   ExpandFlags(Wreg(PSW_SAVE));    \
14   SetRB(tmp); \
15   CHANGE_PC
16
17#define TSKSW   \
18   Wreg(PSW_SAVE) = CompressFlags();   \
19   Wreg(PC_SAVE) = m_ip;  \
20   SetRB(tmp); \
21   m_ip = Wreg(PC_SAVE);  \
22   ExpandFlags(Wreg(PSW_SAVE));    \
23   CHANGE_PC
24
25#define MOVSPA  \
26   tmp = (Wreg(PSW_SAVE) & 0x7000) >> 8;   \
27   Sreg(SS) = m_ram.w[tmp+SS];    \
28   Wreg(SP) = m_ram.w[tmp+SP]
29
30#define MOVSPB  \
31   tmp <<= 4;  \
32   m_ram.w[tmp+SS] = Sreg(SS);    \
33   m_ram.w[tmp+SP] = Wreg(SP)
34
35#define FINT    \
36   for(tmp = 1; tmp < 0x100; tmp <<= 1) {  \
37      if(m_ISPR & tmp) {     \
38         m_ISPR &= ~tmp;    \
39         break;  \
40      }   \
41   }
42
43OP( 0x0f, i_pre_v25  ) { UINT32 ModRM, tmp, tmp2;
44   switch (FETCH()) {
45      case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
46      case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
47      case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2);  PutbackRMByte(ModRM,tmp);   break; /* Clr */
48      case 0x13 : BITOP_WORD; CLKS(5,5,4); tmp2 = Breg(CL) & 0xf; tmp &= ~(1<<tmp2);  PutbackRMWord(ModRM,tmp);   break; /* Clr */
49      case 0x14 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; tmp |= (1<<tmp2);   PutbackRMByte(ModRM,tmp);   break; /* Set */
50      case 0x15 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; tmp |= (1<<tmp2);   PutbackRMWord(ModRM,tmp);   break; /* Set */
51      case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT;            PutbackRMByte(ModRM,tmp);   break; /* Not */
52      case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT;            PutbackRMWord(ModRM,tmp);   break; /* Not */
53
54      case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7;    m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
55      case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf;    m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
56      case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7;    tmp &= ~(1<<tmp2);      PutbackRMByte(ModRM,tmp);   break; /* Clr */
57      case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf;    tmp &= ~(1<<tmp2);      PutbackRMWord(ModRM,tmp);   break; /* Clr */
58      case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7;    tmp |= (1<<tmp2);       PutbackRMByte(ModRM,tmp);   break; /* Set */
59      case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf;    tmp |= (1<<tmp2);       PutbackRMWord(ModRM,tmp);   break; /* Set */
60      case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7;    BIT_NOT;                PutbackRMByte(ModRM,tmp);   break; /* Not */
61      case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf;    BIT_NOT;                PutbackRMWord(ModRM,tmp);   break; /* Not */
62
63      case 0x20 : ADD4S; CLKS(7,7,2); break;
64      case 0x22 : SUB4S; CLKS(7,7,2); break;
65      case 0x25 : MOVSPA; CLK(16); break;
66      case 0x26 : CMP4S; CLKS(7,7,2); break;
67      case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break;
68      case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4);   PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break;
69      case 0x2d : GetRB; nec_bankswitch(tmp); CLK(15); break;
70      case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break;
71      case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break;
72      case 0x91 : RETRBI; CLK(12); break;
73      case 0x92 : FINT; CLK(2); m_no_interrupt = 1; break;
74      case 0x94 : GetRB; TSKSW; CLK(20); break;
75      case 0x95 : GetRB; MOVSPB; CLK(11); break;
76      case 0x9e : logerror("%06x: STOP\n",PC()); m_icount=0; break;
77      default:    logerror("%06x: Unknown V25 instruction\n",PC()); break;
78   }
79}
80
81OP( 0x63, i_brkn   ) { nec_interrupt(FETCH(), BRKN); CLKS(50,50,24); }
82OP( 0xF1, i_brks   ) { nec_interrupt(FETCH(), BRKS); CLKS(50,50,24); }
trunk/src/emu/cpu/nec/nec.c
r28738r28739
305305/*                             OPCODES                                      */
306306/****************************************************************************/
307307
308#include "necinstr.c"
308#include "necinstr.inc"
309309
310310/*****************************************************************************/
311311
trunk/src/emu/cpu/nec/necinstr.inc
r0r28739
1#define OP(num,func_name) void nec_common_device::func_name()
2
3OP( 0x00, i_add_br8  ) { DEF_br8;   ADDB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
4OP( 0x01, i_add_wr16 ) { DEF_wr16;  ADDW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
5OP( 0x02, i_add_r8b  ) { DEF_r8b;   ADDB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
6OP( 0x03, i_add_r16w ) { DEF_r16w;  ADDW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
7OP( 0x04, i_add_ald8 ) { DEF_ald8;  ADDB;   Breg(AL)=dst;           CLKS(4,4,2);                }
8OP( 0x05, i_add_axd16) { DEF_axd16; ADDW;   Wreg(AW)=dst;           CLKS(4,4,2);                }
9OP( 0x06, i_push_es  ) { PUSH(Sreg(DS1));   CLKS(12,8,3);   }
10OP( 0x07, i_pop_es   ) { POP(Sreg(DS1));    CLKS(12,8,5);   }
11
12OP( 0x08, i_or_br8   ) { DEF_br8;   ORB;    PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
13OP( 0x09, i_or_wr16  ) { DEF_wr16;  ORW;    PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
14OP( 0x0a, i_or_r8b   ) { DEF_r8b;   ORB;    RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
15OP( 0x0b, i_or_r16w  ) { DEF_r16w;  ORW;    RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
16OP( 0x0c, i_or_ald8  ) { DEF_ald8;  ORB;    Breg(AL)=dst;           CLKS(4,4,2);                }
17OP( 0x0d, i_or_axd16 ) { DEF_axd16; ORW;    Wreg(AW)=dst;           CLKS(4,4,2);                }
18OP( 0x0e, i_push_cs  ) { PUSH(Sreg(PS));    CLKS(12,8,3);   }
19OP( 0x0f, i_pre_nec  ) { UINT32 ModRM, tmp, tmp2;
20   switch (FETCH()) {
21      case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
22      case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
23      case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2);  PutbackRMByte(ModRM,tmp);   break; /* Clr */
24      case 0x13 : BITOP_WORD; CLKS(5,5,4); tmp2 = Breg(CL) & 0xf; tmp &= ~(1<<tmp2);  PutbackRMWord(ModRM,tmp);   break; /* Clr */
25      case 0x14 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; tmp |= (1<<tmp2);   PutbackRMByte(ModRM,tmp);   break; /* Set */
26      case 0x15 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; tmp |= (1<<tmp2);   PutbackRMWord(ModRM,tmp);   break; /* Set */
27      case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT;            PutbackRMByte(ModRM,tmp);   break; /* Not */
28      case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT;            PutbackRMWord(ModRM,tmp);   break; /* Not */
29
30      case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7;    m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
31      case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf;    m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
32      case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7;    tmp &= ~(1<<tmp2);      PutbackRMByte(ModRM,tmp);   break; /* Clr */
33      case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf;    tmp &= ~(1<<tmp2);      PutbackRMWord(ModRM,tmp);   break; /* Clr */
34      case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7;    tmp |= (1<<tmp2);       PutbackRMByte(ModRM,tmp);   break; /* Set */
35      case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf;    tmp |= (1<<tmp2);       PutbackRMWord(ModRM,tmp);   break; /* Set */
36      case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7;    BIT_NOT;                PutbackRMByte(ModRM,tmp);   break; /* Not */
37      case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf;    BIT_NOT;                PutbackRMWord(ModRM,tmp);   break; /* Not */
38
39      case 0x20 : ADD4S; CLKS(7,7,2); break;
40      case 0x22 : SUB4S; CLKS(7,7,2); break;
41      case 0x26 : CMP4S; CLKS(7,7,2); break;
42      case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break;
43      case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4);   PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break;
44      case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break;
45      case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break;
46      case 0xe0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC()); break;
47      case 0xf0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC()); break;
48      case 0xff : ModRM = FETCH(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC()); break;
49      default:    logerror("%06x: Unknown V20 instruction\n",PC()); break;
50   }
51}
52
53OP( 0x10, i_adc_br8  ) { DEF_br8;   src+=CF;    ADDB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
54OP( 0x11, i_adc_wr16 ) { DEF_wr16;  src+=CF;    ADDW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
55OP( 0x12, i_adc_r8b  ) { DEF_r8b;   src+=CF;    ADDB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
56OP( 0x13, i_adc_r16w ) { DEF_r16w;  src+=CF;    ADDW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
57OP( 0x14, i_adc_ald8 ) { DEF_ald8;  src+=CF;    ADDB;   Breg(AL)=dst;           CLKS(4,4,2);                }
58OP( 0x15, i_adc_axd16) { DEF_axd16; src+=CF;    ADDW;   Wreg(AW)=dst;           CLKS(4,4,2);                }
59OP( 0x16, i_push_ss  ) { PUSH(Sreg(SS));        CLKS(12,8,3);   }
60OP( 0x17, i_pop_ss   ) { POP(Sreg(SS));     CLKS(12,8,5);   m_no_interrupt=1; }
61
62OP( 0x18, i_sbb_br8  ) { DEF_br8;   src+=CF;    SUBB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
63OP( 0x19, i_sbb_wr16 ) { DEF_wr16;  src+=CF;    SUBW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
64OP( 0x1a, i_sbb_r8b  ) { DEF_r8b;   src+=CF;    SUBB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
65OP( 0x1b, i_sbb_r16w ) { DEF_r16w;  src+=CF;    SUBW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
66OP( 0x1c, i_sbb_ald8 ) { DEF_ald8;  src+=CF;    SUBB;   Breg(AL)=dst;           CLKS(4,4,2);                }
67OP( 0x1d, i_sbb_axd16) { DEF_axd16; src+=CF;    SUBW;   Wreg(AW)=dst;           CLKS(4,4,2);    }
68OP( 0x1e, i_push_ds  ) { PUSH(Sreg(DS0));       CLKS(12,8,3);   }
69OP( 0x1f, i_pop_ds   ) { POP(Sreg(DS0));        CLKS(12,8,5);   }
70
71OP( 0x20, i_and_br8  ) { DEF_br8;   ANDB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
72OP( 0x21, i_and_wr16 ) { DEF_wr16;  ANDW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
73OP( 0x22, i_and_r8b  ) { DEF_r8b;   ANDB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
74OP( 0x23, i_and_r16w ) { DEF_r16w;  ANDW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
75OP( 0x24, i_and_ald8 ) { DEF_ald8;  ANDB;   Breg(AL)=dst;           CLKS(4,4,2);                }
76OP( 0x25, i_and_axd16) { DEF_axd16; ANDW;   Wreg(AW)=dst;           CLKS(4,4,2);    }
77OP( 0x26, i_es       ) { m_seg_prefix=TRUE;    m_prefix_base=Sreg(DS1)<<4;    CLK(2);     (this->*s_nec_instruction[fetchop()])(); m_seg_prefix=FALSE; }
78OP( 0x27, i_daa      ) { ADJ4(6,0x60);                                  CLKS(3,3,2);    }
79
80OP( 0x28, i_sub_br8  ) { DEF_br8;   SUBB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
81OP( 0x29, i_sub_wr16 ) { DEF_wr16;  SUBW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
82OP( 0x2a, i_sub_r8b  ) { DEF_r8b;   SUBB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
83OP( 0x2b, i_sub_r16w ) { DEF_r16w;  SUBW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
84OP( 0x2c, i_sub_ald8 ) { DEF_ald8;  SUBB;   Breg(AL)=dst;           CLKS(4,4,2);                }
85OP( 0x2d, i_sub_axd16) { DEF_axd16; SUBW;   Wreg(AW)=dst;           CLKS(4,4,2);    }
86OP( 0x2e, i_cs       ) { m_seg_prefix=TRUE;    m_prefix_base=Sreg(PS)<<4; CLK(2);     (this->*s_nec_instruction[fetchop()])(); m_seg_prefix=FALSE; }
87OP( 0x2f, i_das      ) { ADJ4(-6,-0x60);                                CLKS(3,3,2);    }
88
89OP( 0x30, i_xor_br8  ) { DEF_br8;   XORB;   PutbackRMByte(ModRM,dst);   CLKM(2,2,2,16,16,7);        }
90OP( 0x31, i_xor_wr16 ) { DEF_wr16;  XORW;   PutbackRMWord(ModRM,dst);   CLKR(24,24,11,24,16,7,2,m_EA);}
91OP( 0x32, i_xor_r8b  ) { DEF_r8b;   XORB;   RegByte(ModRM)=dst;         CLKM(2,2,2,11,11,6);        }
92OP( 0x33, i_xor_r16w ) { DEF_r16w;  XORW;   RegWord(ModRM)=dst;         CLKR(15,15,8,15,11,6,2,m_EA); }
93OP( 0x34, i_xor_ald8 ) { DEF_ald8;  XORB;   Breg(AL)=dst;           CLKS(4,4,2);                }
94OP( 0x35, i_xor_axd16) { DEF_axd16; XORW;   Wreg(AW)=dst;           CLKS(4,4,2);    }
95OP( 0x36, i_ss       ) { m_seg_prefix=TRUE;    m_prefix_base=Sreg(SS)<<4; CLK(2);     (this->*s_nec_instruction[fetchop()])(); m_seg_prefix=FALSE; }
96OP( 0x37, i_aaa      ) { ADJB(6, (Breg(AL) > 0xf9) ? 2 : 1);        CLKS(7,7,4);    }
97
98OP( 0x38, i_cmp_br8  ) { DEF_br8;   SUBB;                   CLKM(2,2,2,11,11,6); }
99OP( 0x39, i_cmp_wr16 ) { DEF_wr16;  SUBW;                   CLKR(15,15,8,15,11,6,2,m_EA);}
100OP( 0x3a, i_cmp_r8b  ) { DEF_r8b;   SUBB;                   CLKM(2,2,2,11,11,6); }
101OP( 0x3b, i_cmp_r16w ) { DEF_r16w;  SUBW;                   CLKR(15,15,8,15,11,6,2,m_EA); }
102OP( 0x3c, i_cmp_ald8 ) { DEF_ald8;  SUBB;                   CLKS(4,4,2); }
103OP( 0x3d, i_cmp_axd16) { DEF_axd16; SUBW;                   CLKS(4,4,2);    }
104OP( 0x3e, i_ds       ) { m_seg_prefix=TRUE;    m_prefix_base=Sreg(DS0)<<4;    CLK(2);     (this->*s_nec_instruction[fetchop()])(); m_seg_prefix=FALSE; }
105OP( 0x3f, i_aas      ) { ADJB(-6, (Breg(AL) < 6) ? -2 : -1);        CLKS(7,7,4);    }
106
107OP( 0x40, i_inc_ax  ) { IncWordReg(AW);                     CLK(2); }
108OP( 0x41, i_inc_cx  ) { IncWordReg(CW);                     CLK(2); }
109OP( 0x42, i_inc_dx  ) { IncWordReg(DW);                     CLK(2); }
110OP( 0x43, i_inc_bx  ) { IncWordReg(BW);                     CLK(2); }
111OP( 0x44, i_inc_sp  ) { IncWordReg(SP);                     CLK(2); }
112OP( 0x45, i_inc_bp  ) { IncWordReg(BP);                     CLK(2); }
113OP( 0x46, i_inc_si  ) { IncWordReg(IX);                     CLK(2); }
114OP( 0x47, i_inc_di  ) { IncWordReg(IY);                     CLK(2); }
115
116OP( 0x48, i_dec_ax  ) { DecWordReg(AW);                     CLK(2); }
117OP( 0x49, i_dec_cx  ) { DecWordReg(CW);                     CLK(2); }
118OP( 0x4a, i_dec_dx  ) { DecWordReg(DW);                     CLK(2); }
119OP( 0x4b, i_dec_bx  ) { DecWordReg(BW);                     CLK(2); }
120OP( 0x4c, i_dec_sp  ) { DecWordReg(SP);                     CLK(2); }
121OP( 0x4d, i_dec_bp  ) { DecWordReg(BP);                     CLK(2); }
122OP( 0x4e, i_dec_si  ) { DecWordReg(IX);                     CLK(2); }
123OP( 0x4f, i_dec_di  ) { DecWordReg(IY);                     CLK(2); }
124
125OP( 0x50, i_push_ax ) { PUSH(Wreg(AW));                 CLKS(12,8,3); }
126OP( 0x51, i_push_cx ) { PUSH(Wreg(CW));                 CLKS(12,8,3); }
127OP( 0x52, i_push_dx ) { PUSH(Wreg(DW));                 CLKS(12,8,3); }
128OP( 0x53, i_push_bx ) { PUSH(Wreg(BW));                 CLKS(12,8,3); }
129OP( 0x54, i_push_sp ) { PUSH(Wreg(SP));                 CLKS(12,8,3); }
130OP( 0x55, i_push_bp ) { PUSH(Wreg(BP));                 CLKS(12,8,3); }
131OP( 0x56, i_push_si ) { PUSH(Wreg(IX));                 CLKS(12,8,3); }
132OP( 0x57, i_push_di ) { PUSH(Wreg(IY));                 CLKS(12,8,3); }
133
134OP( 0x58, i_pop_ax  ) { POP(Wreg(AW));                  CLKS(12,8,5); }
135OP( 0x59, i_pop_cx  ) { POP(Wreg(CW));                  CLKS(12,8,5); }
136OP( 0x5a, i_pop_dx  ) { POP(Wreg(DW));                  CLKS(12,8,5); }
137OP( 0x5b, i_pop_bx  ) { POP(Wreg(BW));                  CLKS(12,8,5); }
138OP( 0x5c, i_pop_sp  ) { POP(Wreg(SP));                  CLKS(12,8,5); }
139OP( 0x5d, i_pop_bp  ) { POP(Wreg(BP));                  CLKS(12,8,5); }
140OP( 0x5e, i_pop_si  ) { POP(Wreg(IX));                  CLKS(12,8,5); }
141OP( 0x5f, i_pop_di  ) { POP(Wreg(IY));                  CLKS(12,8,5); }
142
143OP( 0x60, i_pusha  ) {
144   unsigned tmp=Wreg(SP);
145   PUSH(Wreg(AW));
146   PUSH(Wreg(CW));
147   PUSH(Wreg(DW));
148   PUSH(Wreg(BW));
149   PUSH(tmp);
150   PUSH(Wreg(BP));
151   PUSH(Wreg(IX));
152   PUSH(Wreg(IY));
153   CLKS(67,35,20);
154}
155static unsigned nec_popa_tmp;
156OP( 0x61, i_popa  ) {
157   POP(Wreg(IY));
158   POP(Wreg(IX));
159   POP(Wreg(BP));
160   POP(nec_popa_tmp);
161   POP(Wreg(BW));
162   POP(Wreg(DW));
163   POP(Wreg(CW));
164   POP(Wreg(AW));
165   CLKS(75,43,22);
166}
167OP( 0x62, i_chkind  ) {
168   UINT32 low,high,tmp;
169   GetModRM;
170   low = GetRMWord(ModRM);
171   high= GetnextRMWord;
172   tmp= RegWord(ModRM);
173   if (tmp<low || tmp>high) {
174      nec_interrupt(NEC_CHKIND_VECTOR, BRK);
175   }
176   m_icount-=20;
177   logerror("%06x: bound %04x high %04x low %04x tmp\n",PC(),high,low,tmp);
178}
179OP( 0x64, i_repnc  ) {  UINT32 next = fetchop();   UINT16 c = Wreg(CW);
180   switch(next) { /* Segments */
181      case 0x26:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS1)<<4;    next = fetchop();  CLK(2); break;
182      case 0x2e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(PS)<<4; next = fetchop();  CLK(2); break;
183      case 0x36:  m_seg_prefix=TRUE; m_prefix_base=Sreg(SS)<<4; next = fetchop();  CLK(2); break;
184      case 0x3e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS0)<<4;    next = fetchop();  CLK(2); break;
185   }
186
187   switch(next) {
188      case 0x6c:  CLK(2); if (c) do { i_insb();  c--; } while (c>0 && !CF); Wreg(CW)=c; break;
189      case 0x6d:  CLK(2); if (c) do { i_insw();  c--; } while (c>0 && !CF); Wreg(CW)=c; break;
190      case 0x6e:  CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
191      case 0x6f:  CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
192      case 0xa4:  CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
193      case 0xa5:  CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
194      case 0xa6:  CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
195      case 0xa7:  CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
196      case 0xaa:  CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
197      case 0xab:  CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
198      case 0xac:  CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
199      case 0xad:  CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
200      case 0xae:  CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
201      case 0xaf:  CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
202      default:    logerror("%06x: REPNC invalid\n",PC());    (this->*s_nec_instruction[next])();
203   }
204   m_seg_prefix=FALSE;
205}
206
207OP( 0x65, i_repc  ) {   UINT32 next = fetchop();   UINT16 c = Wreg(CW);
208   switch(next) { /* Segments */
209      case 0x26:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS1)<<4;    next = fetchop();  CLK(2); break;
210      case 0x2e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(PS)<<4; next = fetchop();  CLK(2); break;
211      case 0x36:  m_seg_prefix=TRUE; m_prefix_base=Sreg(SS)<<4; next = fetchop();  CLK(2); break;
212      case 0x3e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS0)<<4;    next = fetchop();  CLK(2); break;
213   }
214
215   switch(next) {
216      case 0x6c:  CLK(2); if (c) do { i_insb();  c--; } while (c>0 && CF);   Wreg(CW)=c; break;
217      case 0x6d:  CLK(2); if (c) do { i_insw();  c--; } while (c>0 && CF);   Wreg(CW)=c; break;
218      case 0x6e:  CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
219      case 0x6f:  CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
220      case 0xa4:  CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
221      case 0xa5:  CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
222      case 0xa6:  CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
223      case 0xa7:  CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
224      case 0xaa:  CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
225      case 0xab:  CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
226      case 0xac:  CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
227      case 0xad:  CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
228      case 0xae:  CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
229      case 0xaf:  CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && CF);   Wreg(CW)=c; break;
230      default:    logerror("%06x: REPC invalid\n",PC()); (this->*s_nec_instruction[next])();
231   }
232   m_seg_prefix=FALSE;
233}
234
235OP( 0x68, i_push_d16 ) { UINT32 tmp;    tmp = FETCHWORD(); PUSH(tmp);   CLKW(12,12,5,12,8,5,Wreg(SP));  }
236OP( 0x69, i_imul_d16 ) { UINT32 tmp;    DEF_r16w;   tmp = FETCHWORD(); dst = (INT32)((INT16)src)*(INT32)((INT16)tmp); m_CarryVal = m_OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1);     RegWord(ModRM)=(WORD)dst;     m_icount-=(ModRM >=0xc0 )?38:47;}
237OP( 0x6a, i_push_d8  ) { UINT32 tmp = (WORD)((INT16)((INT8)FETCH()));   PUSH(tmp);  CLKW(11,11,5,11,7,3,Wreg(SP));  }
238OP( 0x6b, i_imul_d8  ) { UINT32 src2; DEF_r16w; src2= (WORD)((INT16)((INT8)FETCH())); dst = (INT32)((INT16)src)*(INT32)((INT16)src2); m_CarryVal = m_OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?31:39; }
239OP( 0x6c, i_insb     ) { PutMemB(DS1,Wreg(IY),read_port_byte(Wreg(DW))); Wreg(IY)+= -2 * m_DF + 1; CLK(8); }
240OP( 0x6d, i_insw     ) { PutMemW(DS1,Wreg(IY),read_port_word(Wreg(DW))); Wreg(IY)+= -4 * m_DF + 2; CLKS(18,10,8); }
241OP( 0x6e, i_outsb    ) { write_port_byte(Wreg(DW),GetMemB(DS0,Wreg(IX))); Wreg(IX)+= -2 * m_DF + 1; CLK(8); }
242OP( 0x6f, i_outsw    ) { write_port_word(Wreg(DW),GetMemW(DS0,Wreg(IX))); Wreg(IX)+= -4 * m_DF + 2; CLKS(18,10,8); }
243
244OP( 0x70, i_jo      ) { JMP( OF);               CLKS(4,4,3); }
245OP( 0x71, i_jno     ) { JMP(!OF);               CLKS(4,4,3); }
246OP( 0x72, i_jc      ) { JMP( CF);               CLKS(4,4,3); }
247OP( 0x73, i_jnc     ) { JMP(!CF);               CLKS(4,4,3); }
248OP( 0x74, i_jz      ) { JMP( ZF);               CLKS(4,4,3); }
249OP( 0x75, i_jnz     ) { JMP(!ZF);               CLKS(4,4,3); }
250OP( 0x76, i_jce     ) { JMP(CF || ZF);          CLKS(4,4,3); }
251OP( 0x77, i_jnce    ) { JMP(!(CF || ZF));       CLKS(4,4,3); }
252OP( 0x78, i_js      ) { JMP( SF);               CLKS(4,4,3); }
253OP( 0x79, i_jns     ) { JMP(!SF);               CLKS(4,4,3); }
254OP( 0x7a, i_jp      ) { JMP( PF);               CLKS(4,4,3); }
255OP( 0x7b, i_jnp     ) { JMP(!PF);               CLKS(4,4,3); }
256OP( 0x7c, i_jl      ) { JMP((SF!=OF)&&(!ZF));   CLKS(4,4,3); }
257OP( 0x7d, i_jnl     ) { JMP((ZF)||(SF==OF));    CLKS(4,4,3); }
258OP( 0x7e, i_jle     ) { JMP((ZF)||(SF!=OF));    CLKS(4,4,3); }
259OP( 0x7f, i_jnle    ) { JMP((SF==OF)&&(!ZF));   CLKS(4,4,3); }
260
261OP( 0x80, i_80pre   ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = FETCH();
262   if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7)
263   switch (ModRM & 0x38) {
264      case 0x00: ADDB;            PutbackRMByte(ModRM,dst);   break;
265      case 0x08: ORB;             PutbackRMByte(ModRM,dst);   break;
266      case 0x10: src+=CF; ADDB;   PutbackRMByte(ModRM,dst);   break;
267      case 0x18: src+=CF; SUBB;   PutbackRMByte(ModRM,dst);   break;
268      case 0x20: ANDB;            PutbackRMByte(ModRM,dst);   break;
269      case 0x28: SUBB;            PutbackRMByte(ModRM,dst);   break;
270      case 0x30: XORB;            PutbackRMByte(ModRM,dst);   break;
271      case 0x38: SUBB;            break;  /* CMP */
272   }
273}
274
275OP( 0x81, i_81pre   ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = FETCH(); src+= (FETCH() << 8);
276   if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,m_EA) else CLKW(26,26,11,26,18,7,m_EA)
277   switch (ModRM & 0x38) {
278      case 0x00: ADDW;            PutbackRMWord(ModRM,dst);   break;
279      case 0x08: ORW;             PutbackRMWord(ModRM,dst);   break;
280      case 0x10: src+=CF; ADDW;   PutbackRMWord(ModRM,dst);   break;
281      case 0x18: src+=CF; SUBW;   PutbackRMWord(ModRM,dst);   break;
282      case 0x20: ANDW;            PutbackRMWord(ModRM,dst);   break;
283      case 0x28: SUBW;            PutbackRMWord(ModRM,dst);   break;
284      case 0x30: XORW;            PutbackRMWord(ModRM,dst);   break;
285      case 0x38: SUBW;            break;  /* CMP */
286   }
287}
288
289OP( 0x82, i_82pre   ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = (BYTE)((INT8)FETCH());
290   if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7)
291   switch (ModRM & 0x38) {
292      case 0x00: ADDB;            PutbackRMByte(ModRM,dst);   break;
293      case 0x08: ORB;             PutbackRMByte(ModRM,dst);   break;
294      case 0x10: src+=CF; ADDB;   PutbackRMByte(ModRM,dst);   break;
295      case 0x18: src+=CF; SUBB;   PutbackRMByte(ModRM,dst);   break;
296      case 0x20: ANDB;            PutbackRMByte(ModRM,dst);   break;
297      case 0x28: SUBB;            PutbackRMByte(ModRM,dst);   break;
298      case 0x30: XORB;            PutbackRMByte(ModRM,dst);   break;
299      case 0x38: SUBB;            break;  /* CMP */
300   }
301}
302
303OP( 0x83, i_83pre   ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = (WORD)((INT16)((INT8)FETCH()));
304   if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,m_EA) else CLKW(26,26,11,26,18,7,m_EA)
305   switch (ModRM & 0x38) {
306      case 0x00: ADDW;            PutbackRMWord(ModRM,dst);   break;
307      case 0x08: ORW;             PutbackRMWord(ModRM,dst);   break;
308      case 0x10: src+=CF; ADDW;   PutbackRMWord(ModRM,dst);   break;
309      case 0x18: src+=CF; SUBW;   PutbackRMWord(ModRM,dst);   break;
310      case 0x20: ANDW;            PutbackRMWord(ModRM,dst);   break;
311      case 0x28: SUBW;            PutbackRMWord(ModRM,dst);   break;
312      case 0x30: XORW;            PutbackRMWord(ModRM,dst);   break;
313      case 0x38: SUBW;            break;  /* CMP */
314   }
315}
316
317OP( 0x84, i_test_br8  ) { DEF_br8;  ANDB;   CLKM(2,2,2,10,10,6);        }
318OP( 0x85, i_test_wr16 ) { DEF_wr16; ANDW;   CLKR(14,14,8,14,10,6,2,m_EA); }
319OP( 0x86, i_xchg_br8  ) { DEF_br8;  RegByte(ModRM)=dst; PutbackRMByte(ModRM,src); CLKM(3,3,3,16,18,8); }
320OP( 0x87, i_xchg_wr16 ) { DEF_wr16; RegWord(ModRM)=dst; PutbackRMWord(ModRM,src); CLKR(24,24,12,24,16,8,3,m_EA); }
321
322OP( 0x88, i_mov_br8   ) { UINT8  src; GetModRM; src = RegByte(ModRM);   PutRMByte(ModRM,src);   CLKM(2,2,2,9,9,3);          }
323OP( 0x89, i_mov_wr16  ) { UINT16 src; GetModRM; src = RegWord(ModRM);   PutRMWord(ModRM,src);   CLKR(13,13,5,13,9,3,2,m_EA);  }
324OP( 0x8a, i_mov_r8b   ) { UINT8  src; GetModRM; src = GetRMByte(ModRM); RegByte(ModRM)=src;     CLKM(2,2,2,11,11,5);        }
325OP( 0x8b, i_mov_r16w  ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); RegWord(ModRM)=src;     CLKR(15,15,7,15,11,5,2,m_EA);     }
326OP( 0x8c, i_mov_wsreg ) { GetModRM;
327   switch (ModRM & 0x38) {
328      case 0x00: PutRMWord(ModRM,Sreg(DS1)); CLKR(14,14,5,14,10,3,2,m_EA); break;
329      case 0x08: PutRMWord(ModRM,Sreg(PS)); CLKR(14,14,5,14,10,3,2,m_EA); break;
330      case 0x10: PutRMWord(ModRM,Sreg(SS)); CLKR(14,14,5,14,10,3,2,m_EA); break;
331      case 0x18: PutRMWord(ModRM,Sreg(DS0)); CLKR(14,14,5,14,10,3,2,m_EA); break;
332      default:   logerror("%06x: MOV Sreg - Invalid register\n",PC());
333   }
334}
335OP( 0x8d, i_lea       ) { UINT16 ModRM = FETCH(); (void)(this->*s_GetEA[ModRM])(); RegWord(ModRM)=m_EO;  CLKS(4,4,2); }
336OP( 0x8e, i_mov_sregw ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); CLKR(15,15,7,15,11,5,2,m_EA);
337   switch (ModRM & 0x38) {
338      case 0x00: Sreg(DS1) = src; break; /* mov es,ew */
339      case 0x08: Sreg(PS) = src; break; /* mov cs,ew */
340      case 0x10: Sreg(SS) = src; break; /* mov ss,ew */
341      case 0x18: Sreg(DS0) = src; break; /* mov ds,ew */
342      default:   logerror("%06x: MOV Sreg - Invalid register\n",PC());
343   }
344   m_no_interrupt=1;
345}
346OP( 0x8f, i_popw ) { UINT16 tmp; GetModRM; POP(tmp); PutRMWord(ModRM,tmp); m_icount-=21; }
347OP( 0x90, i_nop  ) { CLK(3); /* { if (m_MF == 0) printf("90 -> %06x: \n",PC()); }  */ }
348OP( 0x91, i_xchg_axcx ) { XchgAWReg(CW); CLK(3); }
349OP( 0x92, i_xchg_axdx ) { XchgAWReg(DW); CLK(3); }
350OP( 0x93, i_xchg_axbx ) { XchgAWReg(BW); CLK(3); }
351OP( 0x94, i_xchg_axsp ) { XchgAWReg(SP); CLK(3); }
352OP( 0x95, i_xchg_axbp ) { XchgAWReg(BP); CLK(3); }
353OP( 0x96, i_xchg_axsi ) { XchgAWReg(IX); CLK(3); }
354OP( 0x97, i_xchg_axdi ) { XchgAWReg(IY); CLK(3); }
355
356OP( 0x98, i_cbw       ) { Breg(AH) = (Breg(AL) & 0x80) ? 0xff : 0;      CLK(2); }
357OP( 0x99, i_cwd       ) { Wreg(DW) = (Breg(AH) & 0x80) ? 0xffff : 0;    CLK(4); }
358OP( 0x9a, i_call_far  ) { UINT32 tmp, tmp2; tmp = FETCHWORD(); tmp2 = FETCHWORD(); PUSH(Sreg(PS)); PUSH(m_ip); m_ip = (WORD)tmp; Sreg(PS) = (WORD)tmp2; CHANGE_PC; CLKW(29,29,13,29,21,9,Wreg(SP)); }
359OP( 0x9b, i_wait      ) { if (!m_poll_state) m_ip--; CLK(5); }
360OP( 0x9c, i_pushf     ) { UINT16 tmp = CompressFlags(); PUSH( tmp ); CLKS(12,8,3); }
361OP( 0x9d, i_popf      ) { UINT32 tmp; POP(tmp); ExpandFlags(tmp); CLKS(12,8,5); if (m_TF) nec_trap(); }
362OP( 0x9e, i_sahf      ) { UINT32 tmp = (CompressFlags() & 0xff00) | (Breg(AH) & 0xd5); ExpandFlags(tmp); CLKS(3,3,2); }
363OP( 0x9f, i_lahf      ) { Breg(AH) = CompressFlags() & 0xff; CLKS(3,3,2); }
364
365OP( 0xa0, i_mov_aldisp ) { UINT32 addr; addr = FETCHWORD(); Breg(AL) = GetMemB(DS0, addr); CLKS(10,10,5); }
366OP( 0xa1, i_mov_axdisp ) { UINT32 addr; addr = FETCHWORD(); Wreg(AW) = GetMemW(DS0, addr); CLKW(14,14,7,14,10,5,addr); }
367OP( 0xa2, i_mov_dispal ) { UINT32 addr; addr = FETCHWORD(); PutMemB(DS0, addr, Breg(AL));  CLKS(9,9,3); }
368OP( 0xa3, i_mov_dispax ) { UINT32 addr; addr = FETCHWORD(); PutMemW(DS0, addr, Wreg(AW));  CLKW(13,13,5,13,9,3,addr); }
369OP( 0xa4, i_movsb      ) { UINT32 tmp = GetMemB(DS0,Wreg(IX)); PutMemB(DS1,Wreg(IY), tmp); Wreg(IY) += -2 * m_DF + 1; Wreg(IX) += -2 * m_DF + 1; CLKS(8,8,6); }
370OP( 0xa5, i_movsw      ) { UINT32 tmp = GetMemW(DS0,Wreg(IX)); PutMemW(DS1,Wreg(IY), tmp); Wreg(IY) += -4 * m_DF + 2; Wreg(IX) += -4 * m_DF + 2; CLKS(16,16,10); }
371OP( 0xa6, i_cmpsb      ) { UINT32 src = GetMemB(DS1, Wreg(IY)); UINT32 dst = GetMemB(DS0, Wreg(IX)); SUBB; Wreg(IY) += -2 * m_DF + 1; Wreg(IX) += -2 * m_DF + 1; CLKS(14,14,14); }
372OP( 0xa7, i_cmpsw      ) { UINT32 src = GetMemW(DS1, Wreg(IY)); UINT32 dst = GetMemW(DS0, Wreg(IX)); SUBW; Wreg(IY) += -4 * m_DF + 2; Wreg(IX) += -4 * m_DF + 2; CLKS(14,14,14); }
373
374OP( 0xa8, i_test_ald8  ) { DEF_ald8;  ANDB; CLKS(4,4,2); }
375OP( 0xa9, i_test_axd16 ) { DEF_axd16; ANDW; CLKS(4,4,2); }
376OP( 0xaa, i_stosb      ) { PutMemB(DS1,Wreg(IY),Breg(AL));  Wreg(IY) += -2 * m_DF + 1; CLKS(4,4,3);  }
377OP( 0xab, i_stosw      ) { PutMemW(DS1,Wreg(IY),Wreg(AW));  Wreg(IY) += -4 * m_DF + 2; CLKW(8,8,5,8,4,3,Wreg(IY)); }
378OP( 0xac, i_lodsb      ) { Breg(AL) = GetMemB(DS0,Wreg(IX)); Wreg(IX) += -2 * m_DF + 1; CLKS(4,4,3);  }
379OP( 0xad, i_lodsw      ) { Wreg(AW) = GetMemW(DS0,Wreg(IX)); Wreg(IX) += -4 * m_DF + 2; CLKW(8,8,5,8,4,3,Wreg(IX)); }
380OP( 0xae, i_scasb      ) { UINT32 src = GetMemB(DS1, Wreg(IY)); UINT32 dst = Breg(AL); SUBB; Wreg(IY) += -2 * m_DF + 1; CLKS(4,4,3);  }
381OP( 0xaf, i_scasw      ) { UINT32 src = GetMemW(DS1, Wreg(IY)); UINT32 dst = Wreg(AW); SUBW; Wreg(IY) += -4 * m_DF + 2; CLKW(8,8,5,8,4,3,Wreg(IY)); }
382
383OP( 0xb0, i_mov_ald8  ) { Breg(AL) = FETCH();   CLKS(4,4,2); }
384OP( 0xb1, i_mov_cld8  ) { Breg(CL) = FETCH(); CLKS(4,4,2); }
385OP( 0xb2, i_mov_dld8  ) { Breg(DL) = FETCH(); CLKS(4,4,2); }
386OP( 0xb3, i_mov_bld8  ) { Breg(BL) = FETCH(); CLKS(4,4,2); }
387OP( 0xb4, i_mov_ahd8  ) { Breg(AH) = FETCH(); CLKS(4,4,2); }
388OP( 0xb5, i_mov_chd8  ) { Breg(CH) = FETCH(); CLKS(4,4,2); }
389OP( 0xb6, i_mov_dhd8  ) { Breg(DH) = FETCH(); CLKS(4,4,2); }
390OP( 0xb7, i_mov_bhd8  ) { Breg(BH) = FETCH();   CLKS(4,4,2); }
391
392OP( 0xb8, i_mov_axd16 ) { Breg(AL) = FETCH();    Breg(AH) = FETCH();    CLKS(4,4,2); }
393OP( 0xb9, i_mov_cxd16 ) { Breg(CL) = FETCH();    Breg(CH) = FETCH();    CLKS(4,4,2); }
394OP( 0xba, i_mov_dxd16 ) { Breg(DL) = FETCH();    Breg(DH) = FETCH();    CLKS(4,4,2); }
395OP( 0xbb, i_mov_bxd16 ) { Breg(BL) = FETCH();    Breg(BH) = FETCH();    CLKS(4,4,2); }
396OP( 0xbc, i_mov_spd16 ) { Wreg(SP) = FETCHWORD();   CLKS(4,4,2); }
397OP( 0xbd, i_mov_bpd16 ) { Wreg(BP) = FETCHWORD();   CLKS(4,4,2); }
398OP( 0xbe, i_mov_sid16 ) { Wreg(IX) = FETCHWORD();   CLKS(4,4,2); }
399OP( 0xbf, i_mov_did16 ) { Wreg(IY) = FETCHWORD();   CLKS(4,4,2); }
400
401OP( 0xc0, i_rotshft_bd8 ) {
402   UINT32 src, dst; UINT8 c;
403   GetModRM; src = (unsigned)GetRMByte(ModRM); dst=src;
404   c=FETCH();
405   CLKM(7,7,2,19,19,6);
406   if (c) switch (ModRM & 0x38) {
407      case 0x00: do { ROL_BYTE;  c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
408      case 0x08: do { ROR_BYTE;  c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
409      case 0x10: do { ROLC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
410      case 0x18: do { RORC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
411      case 0x20: SHL_BYTE(c); break;
412      case 0x28: SHR_BYTE(c); break;
413      case 0x30: logerror("%06x: Undefined opcode 0xc0 0x30 (SHLA)\n",PC()); break;
414      case 0x38: SHRA_BYTE(c); break;
415   }
416}
417
418OP( 0xc1, i_rotshft_wd8 ) {
419   UINT32 src, dst;  UINT8 c;
420   GetModRM; src = (unsigned)GetRMWord(ModRM); dst=src;
421   c=FETCH();
422   CLKM(7,7,2,27,19,6);
423   if (c) switch (ModRM & 0x38) {
424      case 0x00: do { ROL_WORD;  c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
425      case 0x08: do { ROR_WORD;  c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
426      case 0x10: do { ROLC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
427      case 0x18: do { RORC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
428      case 0x20: SHL_WORD(c); break;
429      case 0x28: SHR_WORD(c); break;
430      case 0x30: logerror("%06x: Undefined opcode 0xc1 0x30 (SHLA)\n",PC()); break;
431      case 0x38: SHRA_WORD(c); break;
432   }
433}
434
435OP( 0xc2, i_ret_d16  ) { UINT32 count = FETCH(); count += FETCH() << 8; POP(m_ip); Wreg(SP)+=count; CHANGE_PC; CLKS(24,24,10); }
436OP( 0xc3, i_ret      ) { POP(m_ip); CHANGE_PC; CLKS(19,19,10); }
437OP( 0xc4, i_les_dw   ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS1) = GetnextRMWord; CLKW(26,26,14,26,18,10,m_EA); }
438OP( 0xc5, i_lds_dw   ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS0) = GetnextRMWord; CLKW(26,26,14,26,18,10,m_EA); }
439OP( 0xc6, i_mov_bd8  ) { GetModRM; PutImmRMByte(ModRM); m_icount-=(ModRM >=0xc0 )?4:11; }
440OP( 0xc7, i_mov_wd16 ) { GetModRM; PutImmRMWord(ModRM); m_icount-=(ModRM >=0xc0 )?4:15; }
441
442OP( 0xc8, i_enter ) {
443   UINT32 nb = FETCH();
444   UINT32 i,level;
445
446   m_icount-=23;
447   nb += FETCH() << 8;
448   level = FETCH();
449   PUSH(Wreg(BP));
450   Wreg(BP)=Wreg(SP);
451   Wreg(SP) -= nb;
452   for (i=1;i<level;i++) {
453      PUSH(GetMemW(SS,Wreg(BP)-i*2));
454      m_icount-=16;
455   }
456   if (level) PUSH(Wreg(BP));
457}
458OP( 0xc9, i_leave ) {
459   Wreg(SP)=Wreg(BP);
460   POP(Wreg(BP));
461   m_icount-=8;
462}
463OP( 0xca, i_retf_d16  ) { UINT32 count = FETCH(); count += FETCH() << 8; POP(m_ip); POP(Sreg(PS)); Wreg(SP)+=count; CHANGE_PC; CLKS(32,32,16); }
464OP( 0xcb, i_retf      ) { POP(m_ip); POP(Sreg(PS)); CHANGE_PC; CLKS(29,29,16); }
465OP( 0xcc, i_int3      ) { nec_interrupt(3, BRK); CLKS(50,50,24); }
466OP( 0xcd, i_int       ) { nec_interrupt(FETCH(), BRK); CLKS(50,50,24); }
467OP( 0xce, i_into      ) { if (OF) { nec_interrupt(NEC_BRKV_VECTOR, BRK); CLKS(52,52,26); } else CLK(3); }
468OP( 0xcf, i_iret      ) { POP(m_ip); POP(Sreg(PS)); i_popf(); CHANGE_PC; CLKS(39,39,19); }
469
470OP( 0xd0, i_rotshft_b ) {
471   UINT32 src, dst; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
472   CLKM(6,6,2,16,16,7);
473   switch (ModRM & 0x38) {
474      case 0x00: ROL_BYTE;  PutbackRMByte(ModRM,(BYTE)dst); m_OverVal = (src^dst)&0x80; break;
475      case 0x08: ROR_BYTE;  PutbackRMByte(ModRM,(BYTE)dst); m_OverVal = (src^dst)&0x80; break;
476      case 0x10: ROLC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); m_OverVal = (src^dst)&0x80; break;
477      case 0x18: RORC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); m_OverVal = (src^dst)&0x80; break;
478      case 0x20: SHL_BYTE(1); m_OverVal = (src^dst)&0x80; break;
479      case 0x28: SHR_BYTE(1); m_OverVal = (src^dst)&0x80; break;
480      case 0x30: logerror("%06x: Undefined opcode 0xd0 0x30 (SHLA)\n",PC()); break;
481      case 0x38: SHRA_BYTE(1); m_OverVal = 0; break;
482   }
483}
484
485OP( 0xd1, i_rotshft_w ) {
486   UINT32 src, dst; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
487   CLKM(6,6,2,24,16,7);
488   switch (ModRM & 0x38) {
489      case 0x00: ROL_WORD;  PutbackRMWord(ModRM,(WORD)dst); m_OverVal = (src^dst)&0x8000; break;
490      case 0x08: ROR_WORD;  PutbackRMWord(ModRM,(WORD)dst); m_OverVal = (src^dst)&0x8000; break;
491      case 0x10: ROLC_WORD; PutbackRMWord(ModRM,(WORD)dst); m_OverVal = (src^dst)&0x8000; break;
492      case 0x18: RORC_WORD; PutbackRMWord(ModRM,(WORD)dst); m_OverVal = (src^dst)&0x8000; break;
493      case 0x20: SHL_WORD(1); m_OverVal = (src^dst)&0x8000;  break;
494      case 0x28: SHR_WORD(1); m_OverVal = (src^dst)&0x8000;  break;
495      case 0x30: logerror("%06x: Undefined opcode 0xd1 0x30 (SHLA)\n",PC()); break;
496      case 0x38: SHRA_WORD(1); m_OverVal = 0; break;
497   }
498}
499
500OP( 0xd2, i_rotshft_bcl ) {
501   UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
502   c=Breg(CL);
503   CLKM(7,7,2,19,19,6);
504   if (c) switch (ModRM & 0x38) {
505      case 0x00: do { ROL_BYTE;  c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
506      case 0x08: do { ROR_BYTE;  c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
507      case 0x10: do { ROLC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
508      case 0x18: do { RORC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
509      case 0x20: SHL_BYTE(c); break;
510      case 0x28: SHR_BYTE(c); break;
511      case 0x30: logerror("%06x: Undefined opcode 0xd2 0x30 (SHLA)\n",PC()); break;
512      case 0x38: SHRA_BYTE(c); break;
513   }
514}
515
516OP( 0xd3, i_rotshft_wcl ) {
517   UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
518   c=Breg(CL);
519   CLKM(7,7,2,27,19,6);
520   if (c) switch (ModRM & 0x38) {
521      case 0x00: do { ROL_WORD;  c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
522      case 0x08: do { ROR_WORD;  c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
523      case 0x10: do { ROLC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
524      case 0x18: do { RORC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
525      case 0x20: SHL_WORD(c); break;
526      case 0x28: SHR_WORD(c); break;
527      case 0x30: logerror("%06x: Undefined opcode 0xd3 0x30 (SHLA)\n",PC()); break;
528      case 0x38: SHRA_WORD(c); break;
529   }
530}
531
532OP( 0xd4, i_aam    ) { FETCH(); Breg(AH) = Breg(AL) / 10; Breg(AL) %= 10; SetSZPF_Word(Wreg(AW)); CLKS(15,15,12); }
533OP( 0xd5, i_aad    ) { FETCH(); Breg(AL) = Breg(AH) * 10 + Breg(AL); Breg(AH) = 0; SetSZPF_Byte(Breg(AL)); CLKS(7,7,8); }
534OP( 0xd6, i_setalc ) { Breg(AL) = (CF)?0xff:0x00; m_icount-=3; logerror("%06x: Undefined opcode (SETALC)\n",PC()); }
535OP( 0xd7, i_trans  ) { UINT32 dest = (Wreg(BW)+Breg(AL))&0xffff; Breg(AL) = GetMemB(DS0, dest); CLKS(9,9,5); }
536OP( 0xd8, i_fpo    ) { GetModRM; m_icount-=2;  logerror("%06x: Unimplemented floating point control %04x\n",PC(),ModRM); }
537
538OP( 0xe0, i_loopne ) { INT8 disp = (INT8)FETCH(); Wreg(CW)--; if (!ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); }
539OP( 0xe1, i_loope  ) { INT8 disp = (INT8)FETCH(); Wreg(CW)--; if ( ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); }
540OP( 0xe2, i_loop   ) { INT8 disp = (INT8)FETCH(); Wreg(CW)--; if (Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); }
541OP( 0xe3, i_jcxz   ) { INT8 disp = (INT8)FETCH(); if (Wreg(CW) == 0) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); }
542OP( 0xe4, i_inal   ) { UINT8 port = FETCH(); Breg(AL) = read_port_byte(port); CLKS(9,9,5);  }
543OP( 0xe5, i_inax   ) { UINT8 port = FETCH(); Wreg(AW) = read_port_word(port); CLKW(13,13,7,13,9,5,port); }
544OP( 0xe6, i_outal  ) { UINT8 port = FETCH(); write_port_byte(port, Breg(AL)); CLKS(8,8,3);  }
545OP( 0xe7, i_outax  ) { UINT8 port = FETCH(); write_port_word(port, Wreg(AW)); CLKW(12,12,5,12,8,3,port);    }
546
547OP( 0xe8, i_call_d16 ) { UINT32 tmp; tmp = FETCHWORD(); PUSH(m_ip); m_ip = (WORD)(m_ip+(INT16)tmp); CHANGE_PC; m_icount-=24; }
548OP( 0xe9, i_jmp_d16  ) { UINT32 tmp; tmp = FETCHWORD(); m_ip = (WORD)(m_ip+(INT16)tmp); CHANGE_PC; m_icount-=15; }
549OP( 0xea, i_jmp_far  ) { UINT32 tmp,tmp1; tmp = FETCHWORD(); tmp1 = FETCHWORD(); Sreg(PS) = (WORD)tmp1;     m_ip = (WORD)tmp; CHANGE_PC; m_icount-=27;  }
550OP( 0xeb, i_jmp_d8   ) { int tmp = (int)((INT8)FETCH()); m_icount-=12; m_ip = (WORD)(m_ip+tmp); }
551OP( 0xec, i_inaldx   ) { Breg(AL) = read_port_byte(Wreg(DW)); CLKS(8,8,5);}
552OP( 0xed, i_inaxdx   ) { Wreg(AW) = read_port_word(Wreg(DW)); CLKW(12,12,7,12,8,5,Wreg(DW)); }
553OP( 0xee, i_outdxal  ) { write_port_byte(Wreg(DW), Breg(AL)); CLKS(8,8,3);  }
554OP( 0xef, i_outdxax  ) { write_port_word(Wreg(DW), Wreg(AW)); CLKW(12,12,5,12,8,3,Wreg(DW)); }
555
556OP( 0xf0, i_lock     ) { logerror("%06x: Warning - BUSLOCK\n",PC()); m_no_interrupt=1; CLK(2); }
557OP( 0xf2, i_repne    ) { UINT32 next = fetchop(); UINT16 c = Wreg(CW);
558   switch(next) { /* Segments */
559      case 0x26:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS1)<<4;    next = fetchop();  CLK(2); break;
560      case 0x2e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(PS)<<4;     next = fetchop();  CLK(2); break;
561      case 0x36:  m_seg_prefix=TRUE; m_prefix_base=Sreg(SS)<<4;     next = fetchop();  CLK(2); break;
562      case 0x3e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS0)<<4;    next = fetchop();  CLK(2); break;
563   }
564
565   switch(next) {
566      case 0x6c:  CLK(2); if (c) do { i_insb();  c--; } while (c>0); Wreg(CW)=c; break;
567      case 0x6d:  CLK(2); if (c) do { i_insw();  c--; } while (c>0); Wreg(CW)=c; break;
568      case 0x6e:  CLK(2); if (c) do { i_outsb(); c--; } while (c>0); Wreg(CW)=c; break;
569      case 0x6f:  CLK(2); if (c) do { i_outsw(); c--; } while (c>0); Wreg(CW)=c; break;
570      case 0xa4:  CLK(2); if (c) do { i_movsb(); c--; } while (c>0); Wreg(CW)=c; break;
571      case 0xa5:  CLK(2); if (c) do { i_movsw(); c--; } while (c>0); Wreg(CW)=c; break;
572      case 0xa6:  CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && ZF==0);    Wreg(CW)=c; break;
573      case 0xa7:  CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && ZF==0);    Wreg(CW)=c; break;
574      case 0xaa:  CLK(2); if (c) do { i_stosb(); c--; } while (c>0); Wreg(CW)=c; break;
575      case 0xab:  CLK(2); if (c) do { i_stosw(); c--; } while (c>0); Wreg(CW)=c; break;
576      case 0xac:  CLK(2); if (c) do { i_lodsb(); c--; } while (c>0); Wreg(CW)=c; break;
577      case 0xad:  CLK(2); if (c) do { i_lodsw(); c--; } while (c>0); Wreg(CW)=c; break;
578      case 0xae:  CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && ZF==0);    Wreg(CW)=c; break;
579      case 0xaf:  CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && ZF==0);    Wreg(CW)=c; break;
580      default:    logerror("%06x: REPNE invalid\n",PC());    (this->*s_nec_instruction[next])();
581   }
582   m_seg_prefix=FALSE;
583}
584OP( 0xf3, i_repe     ) { UINT32 next = fetchop(); UINT16 c = Wreg(CW);
585   switch(next) { /* Segments */
586      case 0x26:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS1)<<4;    next = fetchop();  CLK(2); break;
587      case 0x2e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(PS)<<4; next = fetchop();  CLK(2); break;
588      case 0x36:  m_seg_prefix=TRUE; m_prefix_base=Sreg(SS)<<4; next = fetchop();  CLK(2); break;
589      case 0x3e:  m_seg_prefix=TRUE; m_prefix_base=Sreg(DS0)<<4;    next = fetchop();  CLK(2); break;
590   }
591
592   switch(next) {
593      case 0x6c:  CLK(2); if (c) do { i_insb();  c--; } while (c>0); Wreg(CW)=c; break;
594      case 0x6d:  CLK(2); if (c) do { i_insw();  c--; } while (c>0); Wreg(CW)=c; break;
595      case 0x6e:  CLK(2); if (c) do { i_outsb(); c--; } while (c>0); Wreg(CW)=c; break;
596      case 0x6f:  CLK(2); if (c) do { i_outsw(); c--; } while (c>0); Wreg(CW)=c; break;
597      case 0xa4:  CLK(2); if (c) do { i_movsb(); c--; } while (c>0); Wreg(CW)=c; break;
598      case 0xa5:  CLK(2); if (c) do { i_movsw(); c--; } while (c>0); Wreg(CW)=c; break;
599      case 0xa6:  CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && ZF==1);    Wreg(CW)=c; break;
600      case 0xa7:  CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && ZF==1);    Wreg(CW)=c; break;
601      case 0xaa:  CLK(2); if (c) do { i_stosb(); c--; } while (c>0); Wreg(CW)=c; break;
602      case 0xab:  CLK(2); if (c) do { i_stosw(); c--; } while (c>0); Wreg(CW)=c; break;
603      case 0xac:  CLK(2); if (c) do { i_lodsb(); c--; } while (c>0); Wreg(CW)=c; break;
604      case 0xad:  CLK(2); if (c) do { i_lodsw(); c--; } while (c>0); Wreg(CW)=c; break;
605      case 0xae:  CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && ZF==1);    Wreg(CW)=c; break;
606      case 0xaf:  CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && ZF==1);    Wreg(CW)=c; break;
607      default:    logerror("%06x: REPE invalid\n",PC()); (this->*s_nec_instruction[next])();
608   }
609   m_seg_prefix=FALSE;
610}
611OP( 0xf4, i_hlt ) { logerror("%06x: HALT\n",PC()); m_halted=1; m_icount=0; }
612OP( 0xf5, i_cmc ) { m_CarryVal = !CF; CLK(2); }
613OP( 0xf6, i_f6pre ) { UINT32 tmp; UINT32 uresult,uresult2; INT32 result,result2;
614   GetModRM; tmp = GetRMByte(ModRM);
615   switch (ModRM & 0x38) {
616      case 0x00: tmp &= FETCH(); m_CarryVal = m_OverVal = 0; SetSZPF_Byte(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */
617      case 0x08: logerror("%06x: Undefined opcode 0xf6 0x08\n",PC()); break;
618      case 0x10: PutbackRMByte(ModRM,~tmp); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */
619      case 0x18: m_CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Byte(tmp); PutbackRMByte(ModRM,tmp&0xff); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */
620      case 0x20: uresult = Breg(AL)*tmp; Wreg(AW)=(WORD)uresult; m_CarryVal=m_OverVal=(Breg(AH)!=0); m_icount-=(ModRM >=0xc0 )?30:36; break; /* MULU */
621      case 0x28: result = (INT16)((INT8)Breg(AL))*(INT16)((INT8)tmp); Wreg(AW)=(WORD)result; m_CarryVal=m_OverVal=(Breg(AH)!=0); m_icount-=(ModRM >=0xc0 )?30:36; break; /* MUL */
622      case 0x30: if (tmp) { DIVUB; } else nec_interrupt(NEC_DIVIDE_VECTOR, BRK); m_icount-=(ModRM >=0xc0 )?43:53; break;
623      case 0x38: if (tmp) { DIVB;  } else nec_interrupt(NEC_DIVIDE_VECTOR, BRK); m_icount-=(ModRM >=0xc0 )?43:53; break;
624   }
625}
626
627OP( 0xf7, i_f7pre   ) { UINT32 tmp,tmp2; UINT32 uresult,uresult2; INT32 result,result2;
628   GetModRM; tmp = GetRMWord(ModRM);
629   switch (ModRM & 0x38) {
630      case 0x00: tmp2 = FETCHWORD(); tmp &= tmp2; m_CarryVal = m_OverVal = 0; SetSZPF_Word(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */
631      case 0x08: logerror("%06x: Undefined opcode 0xf7 0x08\n",PC()); break;
632      case 0x10: PutbackRMWord(ModRM,~tmp); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */
633      case 0x18: m_CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Word(tmp); PutbackRMWord(ModRM,tmp&0xffff); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */
634      case 0x20: uresult = Wreg(AW)*tmp; Wreg(AW)=uresult&0xffff; Wreg(DW)=((UINT32)uresult)>>16; m_CarryVal=m_OverVal=(Wreg(DW)!=0); m_icount-=(ModRM >=0xc0 )?30:36; break; /* MULU */
635      case 0x28: result = (INT32)((INT16)Wreg(AW))*(INT32)((INT16)tmp); Wreg(AW)=result&0xffff; Wreg(DW)=result>>16; m_CarryVal=m_OverVal=(Wreg(DW)!=0); m_icount-=(ModRM >=0xc0 )?30:36; break; /* MUL */
636      case 0x30: if (tmp) { DIVUW; } else nec_interrupt(NEC_DIVIDE_VECTOR, BRK); m_icount-=(ModRM >=0xc0 )?43:53; break;
637      case 0x38: if (tmp) { DIVW;  } else nec_interrupt(NEC_DIVIDE_VECTOR, BRK); m_icount-=(ModRM >=0xc0 )?43:53; break;
638   }
639}
640
641OP( 0xf8, i_clc   ) { m_CarryVal = 0;  CLK(2); }
642OP( 0xf9, i_stc   ) { m_CarryVal = 1;  CLK(2); }
643OP( 0xfa, i_di    ) { SetIF(0);         CLK(2); }
644OP( 0xfb, i_ei    ) { SetIF(1);         CLK(2); }
645OP( 0xfc, i_cld   ) { SetDF(0);         CLK(2); }
646OP( 0xfd, i_std   ) { SetDF(1);         CLK(2); }
647OP( 0xfe, i_fepre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMByte(ModRM);
648   switch(ModRM & 0x38) {
649      case 0x00: tmp1 = tmp+1; m_OverVal = (tmp==0x7f); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(2,2,2,16,16,7); break; /* INC */
650      case 0x08: tmp1 = tmp-1; m_OverVal = (tmp==0x80); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(2,2,2,16,16,7); break; /* DEC */
651      default:   logerror("%06x: FE Pre with unimplemented mod\n",PC());
652   }
653}
654OP( 0xff, i_ffpre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMWord(ModRM);
655   switch(ModRM & 0x38) {
656      case 0x00: tmp1 = tmp+1; m_OverVal = (tmp==0x7fff); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(2,2,2,24,16,7); break; /* INC */
657      case 0x08: tmp1 = tmp-1; m_OverVal = (tmp==0x8000); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(2,2,2,24,16,7); break; /* DEC */
658      case 0x10: PUSH(m_ip); m_ip = (WORD)tmp; CHANGE_PC; m_icount-=(ModRM >=0xc0 )?16:20; break; /* CALL */
659      case 0x18: tmp1 = Sreg(PS); Sreg(PS) = GetnextRMWord; PUSH(tmp1); PUSH(m_ip); m_ip = tmp; CHANGE_PC; m_icount-=(ModRM >=0xc0 )?16:26; break; /* CALL FAR */
660      case 0x20: m_ip = tmp; CHANGE_PC; m_icount-=13; break; /* JMP */
661      case 0x28: m_ip = tmp; Sreg(PS) = GetnextRMWord; CHANGE_PC; m_icount-=15; break; /* JMP FAR */
662      case 0x30: PUSH(tmp); m_icount-=4; break;
663      default:   logerror("%06x: FF Pre with unimplemented mod\n",PC());
664   }
665}
666
667void nec_common_device::i_invalid()
668{
669   m_icount-=10;
670   logerror("%06x: Invalid Opcode\n",PC());
671}
Property changes on: trunk/src/emu/cpu/nec/necinstr.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/nec/v25.c
r28738r28739
360360/*                             OPCODES                                      */
361361/****************************************************************************/
362362
363#include "necinstr.c"
364#include "v25instr.c"
363#include "necinstr.inc"
364#include "v25instr.inc"
365365
366366/*****************************************************************************/
367367
trunk/src/emu/cpu/nec/v25instr.inc
r0r28739
1#define GetRB   \
2   ModRM = FETCH();    \
3   if (ModRM >= 0xc0)  \
4      tmp = Wreg(Mod_RM.RM.w[ModRM]) & 0x7;   \
5   else {                          \
6      logerror("%06x: Invalid MODRM for register banking instruction\n",PC());   \
7      tmp = 0;    \
8   }
9
10#define RETRBI  \
11   tmp = (Wreg(PSW_SAVE) & 0x7000) >> 12;  \
12   m_ip = Wreg(PC_SAVE);  \
13   ExpandFlags(Wreg(PSW_SAVE));    \
14   SetRB(tmp); \
15   CHANGE_PC
16
17#define TSKSW   \
18   Wreg(PSW_SAVE) = CompressFlags();   \
19   Wreg(PC_SAVE) = m_ip;  \
20   SetRB(tmp); \
21   m_ip = Wreg(PC_SAVE);  \
22   ExpandFlags(Wreg(PSW_SAVE));    \
23   CHANGE_PC
24
25#define MOVSPA  \
26   tmp = (Wreg(PSW_SAVE) & 0x7000) >> 8;   \
27   Sreg(SS) = m_ram.w[tmp+SS];    \
28   Wreg(SP) = m_ram.w[tmp+SP]
29
30#define MOVSPB  \
31   tmp <<= 4;  \
32   m_ram.w[tmp+SS] = Sreg(SS);    \
33   m_ram.w[tmp+SP] = Wreg(SP)
34
35#define FINT    \
36   for(tmp = 1; tmp < 0x100; tmp <<= 1) {  \
37      if(m_ISPR & tmp) {     \
38         m_ISPR &= ~tmp;    \
39         break;  \
40      }   \
41   }
42
43OP( 0x0f, i_pre_v25  ) { UINT32 ModRM, tmp, tmp2;
44   switch (FETCH()) {
45      case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
46      case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
47      case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2);  PutbackRMByte(ModRM,tmp);   break; /* Clr */
48      case 0x13 : BITOP_WORD; CLKS(5,5,4); tmp2 = Breg(CL) & 0xf; tmp &= ~(1<<tmp2);  PutbackRMWord(ModRM,tmp);   break; /* Clr */
49      case 0x14 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; tmp |= (1<<tmp2);   PutbackRMByte(ModRM,tmp);   break; /* Set */
50      case 0x15 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; tmp |= (1<<tmp2);   PutbackRMWord(ModRM,tmp);   break; /* Set */
51      case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT;            PutbackRMByte(ModRM,tmp);   break; /* Not */
52      case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT;            PutbackRMWord(ModRM,tmp);   break; /* Not */
53
54      case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7;    m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
55      case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf;    m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */
56      case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7;    tmp &= ~(1<<tmp2);      PutbackRMByte(ModRM,tmp);   break; /* Clr */
57      case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf;    tmp &= ~(1<<tmp2);      PutbackRMWord(ModRM,tmp);   break; /* Clr */
58      case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7;    tmp |= (1<<tmp2);       PutbackRMByte(ModRM,tmp);   break; /* Set */
59      case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf;    tmp |= (1<<tmp2);       PutbackRMWord(ModRM,tmp);   break; /* Set */
60      case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7;    BIT_NOT;                PutbackRMByte(ModRM,tmp);   break; /* Not */
61      case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf;    BIT_NOT;                PutbackRMWord(ModRM,tmp);   break; /* Not */
62
63      case 0x20 : ADD4S; CLKS(7,7,2); break;
64      case 0x22 : SUB4S; CLKS(7,7,2); break;
65      case 0x25 : MOVSPA; CLK(16); break;
66      case 0x26 : CMP4S; CLKS(7,7,2); break;
67      case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break;
68      case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4);   PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break;
69      case 0x2d : GetRB; nec_bankswitch(tmp); CLK(15); break;
70      case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break;
71      case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break;
72      case 0x91 : RETRBI; CLK(12); break;
73      case 0x92 : FINT; CLK(2); m_no_interrupt = 1; break;
74      case 0x94 : GetRB; TSKSW; CLK(20); break;
75      case 0x95 : GetRB; MOVSPB; CLK(11); break;
76      case 0x9e : logerror("%06x: STOP\n",PC()); m_icount=0; break;
77      default:    logerror("%06x: Unknown V25 instruction\n",PC()); break;
78   }
79}
80
81OP( 0x63, i_brkn   ) { nec_interrupt(FETCH(), BRKN); CLKS(50,50,24); }
82OP( 0xF1, i_brks   ) { nec_interrupt(FETCH(), BRKS); CLKS(50,50,24); }
Property changes on: trunk/src/emu/cpu/nec/v25instr.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/mcs51/mcs51ops.c
r28738r28739
1/*******************************************************************************************
2 NOTE: All registers are accessed directly, instead of using the SFR_R() function for speed
3 Direct register access is availabe from the R_(register name) macros.. ex: ACC for the ACC
4 with the exception of the PC
5********************************************************************************************/
6
7//ACALL code addr                           /* 1: aaa1 0001 */
8OPHANDLER( acall )
9{
10   UINT8 addr = ROP_ARG(PC++);             //Grab code address byte
11   PUSH_PC();                              //Save PC to the stack
12   //Thanks Gerrit for help with this! :)
13   PC = (PC & 0xf800) | ((r & 0xe0) << 3) | addr;
14}
15
16//ADD A, #data                              /* 1: 0010 0100 */
17OPHANDLER( add_a_byte )
18{
19   UINT8 data = ROP_ARG(PC++);             //Grab data
20   UINT8 result = ACC + data;          //Add data to accumulator
21   DO_ADD_FLAGS(ACC,data,0);               //Set Flags
22   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
23}
24
25//ADD A, data addr                          /* 1: 0010 0101 */
26OPHANDLER( add_a_mem )
27{
28   UINT8 addr = ROP_ARG(PC++);             //Grab data address
29   UINT8 data = IRAM_R(addr);              //Grab data from data address
30   UINT8 result = ACC + data;          //Add data to accumulator
31   DO_ADD_FLAGS(ACC,data,0);               //Set Flags
32   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
33}
34
35//ADD A, @R0/@R1                            /* 1: 0010 011i */
36OPHANDLER( add_a_ir )
37{
38   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from memory pointed to by R0 or R1
39   UINT8 result = ACC + data;          //Add data to accumulator
40   DO_ADD_FLAGS(ACC,data,0);               //Set Flags
41   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
42}
43
44//ADD A, R0 to R7                           /* 1: 0010 1rrr */
45OPHANDLER( add_a_r )
46{
47   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
48   UINT8 result = ACC + data;          //Add data to accumulator
49   DO_ADD_FLAGS(ACC,data,0);               //Set Flags
50   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
51}
52
53//ADDC A, #data                             /* 1: 0011 0100 */
54OPHANDLER( addc_a_byte )
55{
56   UINT8 data = ROP_ARG(PC++);             //Grab data
57   UINT8 result = ACC + data + GET_CY; //Add data + carry flag to accumulator
58   DO_ADD_FLAGS(ACC,data,GET_CY);      //Set Flags
59   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
60}
61
62//ADDC A, data addr                         /* 1: 0011 0101 */
63OPHANDLER( addc_a_mem )
64{
65   UINT8 addr = ROP_ARG(PC++);             //Grab data address
66   UINT8 data = IRAM_R(addr);              //Grab data from data address
67   UINT8 result = ACC + data + GET_CY; //Add data + carry flag to accumulator
68   DO_ADD_FLAGS(ACC,data,GET_CY);      //Set Flags
69   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
70}
71
72//ADDC A, @R0/@R1                           /* 1: 0011 011i */
73OPHANDLER( addc_a_ir )
74{
75   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from memory pointed to by R0 or R1
76   UINT8 result = ACC + data + GET_CY; //Add data + carry flag to accumulator
77   DO_ADD_FLAGS(ACC,data,GET_CY);      //Set Flags
78   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
79}
80
81//ADDC A, R0 to R7                          /* 1: 0011 1rrr */
82OPHANDLER( addc_a_r )
83{
84   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
85   UINT8 result = ACC + data + GET_CY; //Add data + carry flag to accumulator
86   DO_ADD_FLAGS(ACC,data,GET_CY);      //Set Flags
87   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
88}
89
90//AJMP code addr                            /* 1: aaa0 0001 */
91OPHANDLER( ajmp )
92{
93   UINT8 addr = ROP_ARG(PC++);             //Grab code address byte
94   //Thanks Gerrit for help with this! :)
95   PC = (PC & 0xf800) | ((r & 0xe0) << 3) | addr;
96}
97
98//ANL data addr, A                          /* 1: 0101 0010 */
99OPHANDLER( anl_mem_a )
100{
101   UINT8 addr = ROP_ARG(PC++);             //Grab data address
102   UINT8 data = IRAM_R(addr);              //Grab data from data address
103   IRAM_W(addr,data & ACC);                //Set data address value to it's value Logical AND with ACC
104}
105
106//ANL data addr, #data                      /* 1: 0101 0011 */
107OPHANDLER( anl_mem_byte )
108{
109   UINT8 addr = ROP_ARG(PC++);             //Grab data address
110   UINT8 data = ROP_ARG(PC++);             //Grab data
111   UINT8 srcdata = IRAM_R(addr);           //Grab data from data address
112   IRAM_W(addr,srcdata & data);            //Set data address value to it's value Logical AND with Data
113}
114
115//ANL A, #data                              /* 1: 0101 0100 */
116OPHANDLER( anl_a_byte )
117{
118   UINT8 data = ROP_ARG(PC++);             //Grab data
119   SET_ACC(ACC & data);                //Set ACC to value of ACC Logical AND with Data
120}
121
122//ANL A, data addr                          /* 1: 0101 0101 */
123OPHANDLER( anl_a_mem )
124{
125   UINT8 addr = ROP_ARG(PC++);             //Grab data address
126   UINT8 data = IRAM_R(addr);              //Grab data from data address
127   SET_ACC(ACC & data);                //Set ACC to value of ACC Logical AND with Data
128}
129
130//ANL A, @RO/@R1                            /* 1: 0101 011i */
131OPHANDLER( anl_a_ir )
132{
133   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from address R0 or R1 points to
134   SET_ACC(ACC & data);                //Set ACC to value of ACC Logical AND with Data
135}
136
137//ANL A, RO to R7                           /* 1: 0101 1rrr */
138OPHANDLER( anl_a_r )
139{
140   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
141   SET_ACC(ACC & data);                //Set ACC to value of ACC Logical AND with Data
142}
143
144//ANL C, bit addr                           /* 1: 1000 0010 */
145OPHANDLER( anl_c_bitaddr )
146{
147   int cy = GET_CY;
148   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
149   UINT8 bit = BIT_R(addr);                //Grab bit data from bit address
150   SET_CY( (cy & bit) );                   //Set Carry flag to Carry Flag Value Logical AND with Bit
151}
152
153//ANL C,/bit addr                           /* 1: 1011 0000 */
154OPHANDLER( anl_c_nbitaddr )
155{
156   int cy = GET_CY;
157   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
158   UINT8 bit = BIT_R(addr);                //Grab bit data from bit address
159   bit = ((~bit)&1);                       //Complement bit
160   SET_CY( (cy & bit) );                   //Set Carry flag to Carry Flag Value Logical AND with Complemented Bit
161}
162
163//CJNE A, #data, code addr                  /* 1: 1011 0100 */
164OPHANDLER( cjne_a_byte )
165{
166   UINT8 data = ROP_ARG(PC++);             //Grab data
167   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
168
169   if(ACC != data)                     //Jump if values are not equal
170   {
171      PC = PC + rel_addr;
172   }
173
174   //Set carry flag to 1 if 1st compare value is < 2nd compare value
175   SET_CY( (ACC < data) );
176}
177
178//CJNE A, data addr, code addr              /* 1: 1011 0101 */
179OPHANDLER( cjne_a_mem )
180{
181   UINT8 addr = ROP_ARG(PC++);             //Grab data address
182   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
183   UINT8 data = IRAM_R(addr);              //Pull value from data address
184
185   if(ACC != data)                     //Jump if values are not equal
186   {
187      PC = PC + rel_addr;
188   }
189
190   //Set carry flag to 1 if 1st compare value is < 2nd compare value
191   SET_CY( (ACC < data) );
192}
193
194//CJNE @R0/@R1, #data, code addr            /* 1: 1011 011i */
195OPHANDLER( cjne_ir_byte )
196{
197   UINT8 data = ROP_ARG(PC++);             //Grab data
198   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
199   UINT8 srcdata = IRAM_IR(R_REG(r));      //Grab value pointed to by R0 or R1
200
201   if(srcdata != data)                     //Jump if values are not equal
202   {
203      PC = PC + rel_addr;
204   }
205
206   //Set carry flag to 1 if 1st compare value is < 2nd compare value
207   SET_CY( (srcdata < data) );
208}
209
210//CJNE R0 to R7, #data, code addr           /* 1: 1011 1rrr */
211OPHANDLER( cjne_r_byte )
212{
213   UINT8 data = ROP_ARG(PC++);             //Grab data
214   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
215   UINT8 srcdata = R_REG(r);                   //Grab value of R0 - R7
216
217   if(srcdata != data)                     //Jump if values are not equal
218   {
219      PC = PC + rel_addr;
220   }
221
222   //Set carry flag to 1 if 1st compare value is < 2nd compare value
223   SET_CY( (srcdata < data) );
224}
225
226//CLR bit addr                              /* 1: 1100 0010 */
227OPHANDLER( clr_bitaddr )
228{
229   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
230   BIT_W(addr,0);                          //Clear bit at specified bit address
231}
232
233//CLR C                                     /* 1: 1100 0011 */
234OPHANDLER( clr_c )
235{
236   SET_CY(0);                              //Clear Carry Flag
237}
238
239//CLR A                                     /* 1: 1110 0100 */
240OPHANDLER( clr_a )
241{
242   SET_ACC(0);                         //Clear Accumulator
243}
244
245//CPL bit addr                              /* 1: 1011 0010 */
246OPHANDLER( cpl_bitaddr )
247{
248   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
249   UINT8 data = (~BIT_R(addr))&1;
250   BIT_W(addr,data);                       //Complement bit at specified bit address
251}
252
253//CPL C                                     /* 1: 1011 0011 */
254OPHANDLER( cpl_c )
255{
256   UINT8 bit = (~GET_CY)&1;                //Complement Carry Flag
257   SET_CY(bit);
258}
259
260//CPL A                                     /* 1: 1111 0100 */
261OPHANDLER( cpl_a )
262{
263   UINT8 data = ((~ACC)&0xff);
264   SET_ACC(data);                      //Complement Accumulator
265}
266
267//DA A                                      /* 1: 1101 0100 */
268OPHANDLER( da_a )
269{
270/*From several sources, since none said the same thing:
271 The decimal adjust instruction is associated with the use of the ADD and ADDC instructions.
272 The eight-bit value in the accumulator is adjusted to form two BCD digits of four bits each.
273 If the accumulator contents bits 0-3 are greater than 9, OR the AC flag is set, then six is added to
274 produce a proper BCD digit.
275 If the carry is set, OR the four high bits 4-7 exceed nine, six is added to the value of these bits.
276 The carry flag will be set if the result is > 0x99, but not cleared otherwise */
277
278   UINT16 new_acc = ACC & 0xff;
279   if(GET_AC || (new_acc & 0x0f) > 0x09)
280      new_acc += 0x06;
281   if(GET_CY || ((new_acc & 0xf0) > 0x90) || (new_acc & ~0xff))
282      new_acc += 0x60;
283   SET_ACC(new_acc&0xff);
284   if(new_acc & ~0xff)
285   SET_CY(1);
286}
287
288//DEC A                                     /* 1: 0001 0100 */
289OPHANDLER( dec_a )
290{
291   SET_ACC(ACC-1);
292}
293
294//DEC data addr                             /* 1: 0001 0101 */
295OPHANDLER( dec_mem )
296{
297   UINT8 addr = ROP_ARG(PC++);             //Grab data address
298   UINT8 data = IRAM_R(addr);
299   IRAM_W(addr,data-1);
300}
301
302//DEC @R0/@R1                               /* 1: 0001 011i */
303OPHANDLER( dec_ir )
304{
305   UINT8 data = IRAM_IR(R_REG(r));
306   IRAM_W(R_REG(r),data-1);
307}
308
309//DEC R0 to R7                              /* 1: 0001 1rrr */
310OPHANDLER( dec_r )
311{
312   SET_REG(r, R_REG(r) - 1);
313}
314
315//DIV AB                                    /* 1: 1000 0100 */
316OPHANDLER( div_ab )
317{
318   if( B == 0 ) {
319      //Overflow flag is set!
320      SET_OV(1);
321      //Really the values are undefined according to the manual, but we'll just leave them as is..
322      //SET_ACC(0xff);
323      //SFR_W(B,0xff);
324   }
325   else {
326      int a = (int)ACC / B;
327      int b = (int)ACC % B;
328      //A gets quotient byte, B gets remainder byte
329      SET_ACC(a);
330      B = b;
331      //Overflow flag is cleared
332      SET_OV(0);
333   }
334   //Carry Flag is always cleared
335   SET_CY(0);
336}
337
338//DJNZ data addr, code addr                 /* 1: 1101 0101 */
339OPHANDLER( djnz_mem )
340{
341   UINT8 addr = ROP_ARG(PC++);             //Grab data address
342   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
343   IRAM_W(addr,IRAM_R(addr) - 1);          //Decrement value contained at data address
344   if(IRAM_R(addr) != 0)                   //Branch if contents of data address is not 0
345   {
346      PC = PC + rel_addr;
347   }
348}
349
350//DJNZ R0 to R7,code addr                   /* 1: 1101 1rrr */
351OPHANDLER( djnz_r )
352{
353   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
354   SET_REG(r ,R_REG(r) - 1);                   //Decrement value
355   if(R_REG(r) != 0)                           //Branch if contents of R0 - R7 is not 0
356   {
357      PC = PC + rel_addr;
358   }
359}
360
361//INC A                                     /* 1: 0000 0100 */
362OPHANDLER( inc_a )
363{
364   SET_ACC(ACC+1);
365}
366
367//INC data addr                             /* 1: 0000 0101 */
368OPHANDLER( inc_mem )
369{
370   UINT8 addr = ROP_ARG(PC++);             //Grab data address
371   UINT8 data = IRAM_R(addr);
372   IRAM_W(addr,data+1);
373}
374
375//INC @R0/@R1                               /* 1: 0000 011i */
376OPHANDLER( inc_ir )
377{
378   UINT8 data = IRAM_IR(R_REG(r));
379   IRAM_W(R_REG(r),data+1);
380}
381
382//INC R0 to R7                              /* 1: 0000 1rrr */
383OPHANDLER( inc_r )
384{
385   UINT8 data = R_REG(r);
386   SET_REG(r, data + 1);
387}
388
389//INC DPTR                                  /* 1: 1010 0011 */
390OPHANDLER( inc_dptr )
391{
392   UINT16 dptr = (DPTR)+1;
393   SET_DPTR(dptr);
394}
395
396//JB  bit addr, code addr                   /* 1: 0010 0000 */
397OPHANDLER( jb )
398{
399   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
400   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
401   if(BIT_R(addr))                         //If bit set at specified bit address, jump
402   {
403      PC = PC + rel_addr;
404   }
405}
406
407//JBC bit addr, code addr                   /* 1: 0001 0000 */
408OPHANDLER( jbc )
409{
410   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
411   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
412   if(BIT_R(addr)) {                       //If bit set at specified bit address, jump
413      PC = PC + rel_addr;
414      BIT_W(addr,0);                      //Clear Bit also
415   }
416}
417
418//JC code addr                              /* 1: 0100 0000 */
419OPHANDLER( jc )
420{
421   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
422   if(GET_CY)                              //Jump if Carry Flag Set
423   {
424      PC = PC + rel_addr;
425   }
426}
427
428//JMP @A+DPTR                               /* 1: 0111 0011 */
429OPHANDLER( jmp_iadptr )
430{
431   PC = ACC + DPTR;
432}
433
434//JNB bit addr, code addr                   /* 1: 0011 0000 */
435OPHANDLER( jnb )
436{
437   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
438   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
439   if(!BIT_R(addr))                        //If bit NOT set at specified bit address, jump
440   {
441      PC = PC + rel_addr;
442   }
443}
444
445//JNC code addr                             /* 1: 0101 0000 */
446OPHANDLER( jnc )
447{
448   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
449   if(!GET_CY)                             //Jump if Carry Flag not set
450   {
451      PC = PC + rel_addr;
452   }
453}
454
455//JNZ code addr                             /* 1: 0111 0000 */
456OPHANDLER( jnz )
457{
458   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
459   if(ACC != 0)                            //Branch if ACC is not 0
460   {
461      PC = PC+rel_addr;
462   }
463}
464
465//JZ code addr                              /* 1: 0110 0000 */
466OPHANDLER( jz )
467{
468   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
469   if(ACC == 0)                            //Branch if ACC is 0
470   {
471      PC = PC+rel_addr;
472   }
473}
474
475//LCALL code addr                           /* 1: 0001 0010 */
476OPHANDLER( lcall )
477{
478   UINT8 addr_hi, addr_lo;
479   addr_hi = ROP_ARG(PC++);
480   addr_lo = ROP_ARG(PC++);
481   PUSH_PC();
482   PC = (UINT16)((addr_hi<<8) | addr_lo);
483}
484
485//LJMP code addr                            /* 1: 0000 0010 */
486OPHANDLER( ljmp )
487{
488   UINT8 addr_hi, addr_lo;
489   addr_hi = ROP_ARG(PC++);
490   addr_lo = ROP_ARG(PC++);
491   PC = (UINT16)((addr_hi<<8) | addr_lo);
492}
493
494//MOV A, #data                              /* 1: 0111 0100 */
495OPHANDLER( mov_a_byte )
496{
497   UINT8 data = ROP_ARG(PC++);             //Grab data
498   SET_ACC(data);                      //Store data to ACC
499}
500
501//MOV A, data addr                          /* 1: 1110 0101 */
502OPHANDLER( mov_a_mem )
503{
504   UINT8 addr = ROP_ARG(PC++);             //Grab data address
505   SET_ACC(IRAM_R(addr));              //Store contents of data address to ACC
506}
507
508//MOV A,@RO/@R1                             /* 1: 1110 011i */
509OPHANDLER( mov_a_ir )
510{
511   SET_ACC(IRAM_IR(R_REG(r)));             //Store contents of address pointed by R0 or R1 to ACC
512}
513
514//MOV A,R0 to R7                            /* 1: 1110 1rrr */
515OPHANDLER( mov_a_r )
516{
517   SET_ACC(R_REG(r));                      //Store contents of R0 - R7 to ACC
518}
519
520//MOV data addr, #data                      /* 1: 0111 0101 */
521OPHANDLER( mov_mem_byte )
522{
523   UINT8 addr = ROP_ARG(PC++);             //Grab data address
524   UINT8 data = ROP_ARG(PC++);             //Grab data
525   IRAM_W(addr,data);                      //Store data to data address location
526}
527
528//MOV data addr, data addr                  /* 1: 1000 0101 */
529OPHANDLER( mov_mem_mem )
530{
531   //1st address is src, 2nd is dst, but the mov command works as mov dst,src)
532   UINT8 src,dst;
533   src = ROP_ARG(PC++);                    //Grab source data address
534   dst = ROP_ARG(PC++);                    //Grab destination data address
535   IRAM_W(dst,IRAM_R(src));                //Read source address contents and store to destination address
536}
537
538//MOV @R0/@R1, #data                        /* 1: 0111 011i */
539OPHANDLER( mov_ir_byte )
540{
541   UINT8 data = ROP_ARG(PC++);             //Grab data
542   IRAM_IW(R_REG(r),data);                 //Store data to address pointed by R0 or R1
543}
544
545//MOV R0 to R7, #data                       /* 1: 0111 1rrr */
546OPHANDLER( mov_r_byte )
547{
548   UINT8 data = ROP_ARG(PC++);             //Grab data
549   SET_REG(r, data);                           //Store to R0 - R7
550}
551
552//MOV data addr, @R0/@R1                    /* 1: 1000 011i */
553OPHANDLER( mov_mem_ir )
554{
555   UINT8 addr = ROP_ARG(PC++);             //Grab data address
556   IRAM_W(addr,IRAM_IR(R_REG(r)));         //Store contents pointed to by R0 or R1 to data address
557}
558
559//MOV data addr,R0 to R7                    /* 1: 1000 1rrr */
560OPHANDLER( mov_mem_r )
561{
562   UINT8 addr = ROP_ARG(PC++);             //Grab data address
563   IRAM_W(addr,R_REG(r));                  //Store contents of R0 - R7 to data address
564}
565
566//MOV DPTR, #data16                         /* 1: 1001 0000 */
567OPHANDLER( mov_dptr_byte )
568{
569   UINT8 data_hi, data_lo;
570   data_hi = ROP_ARG(PC++);                //Grab hi byte
571   data_lo = ROP_ARG(PC++);                //Grab lo byte
572   SET_DPTR((UINT16)((data_hi<<8)|data_lo));   //Store to DPTR
573}
574
575//MOV bit addr, C                           /* 1: 1001 0010 */
576OPHANDLER( mov_bitaddr_c )
577{
578   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
579   BIT_W(addr,GET_CY);                     //Store Carry Flag to Bit Address
580}
581
582//MOV @R0/@R1, data addr                    /* 1: 1010 011i */
583OPHANDLER( mov_ir_mem )
584{
585   UINT8 addr = ROP_ARG(PC++);             //Grab data address
586   IRAM_IW(R_REG(r),IRAM_R(addr));         //Store data from data address to address pointed to by R0 or R1
587}
588
589//MOV R0 to R7, data addr                   /* 1: 1010 1rrr */
590OPHANDLER( mov_r_mem )
591{
592   UINT8 addr = ROP_ARG(PC++);             //Grab data address
593   SET_REG(r, IRAM_R(addr));               //Store to R0 - R7
594}
595
596//MOV data addr, A                          /* 1: 1111 0101 */
597OPHANDLER( mov_mem_a )
598{
599   UINT8 addr = ROP_ARG(PC++);             //Grab data address
600   IRAM_W(addr,ACC);                       //Store A to data address
601}
602
603//MOV @R0/@R1, A                            /* 1: 1111 011i */
604OPHANDLER( mov_ir_a )
605{
606   IRAM_IW(R_REG(r),ACC);                  //Store A to location pointed to by R0 or R1
607}
608
609//MOV R0 to R7, A                           /* 1: 1111 1rrr */
610OPHANDLER( mov_r_a )
611{
612   SET_REG(r, ACC);                        //Store A to R0-R7
613}
614
615//MOVC A, @A + PC                           /* 1: 1000 0011 */
616OPHANDLER( movc_a_iapc )
617{
618   UINT8 data;
619   data = CODEMEM_R(ACC+PC);               //Move a byte from CODE(Program) Memory and store to ACC
620   SET_ACC(data);
621}
622
623//MOV C, bit addr                           /* 1: 1010 0010 */
624OPHANDLER( mov_c_bitaddr )
625{
626   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
627   SET_CY( (BIT_R(addr)) );                //Store Bit from Bit Address to Carry Flag
628}
629
630//MOVC A, @A + DPTR                         /* 1: 1001 0011 */
631OPHANDLER( movc_a_iadptr )
632{
633   UINT8 data;
634   data = CODEMEM_R(ACC + DPTR);           //Move a byte from CODE(Program) Memory and store to ACC
635   SET_ACC(data);
636}
637
638//MOVX A,@DPTR                              /* 1: 1110 0000 */
639//(Move External Ram 16 bit address to A)
640OPHANDLER( movx_a_idptr )
641{
642//  UINT8 byte = DATAMEM_R(R_DPTR);         //Grab 1 byte from External DATA memory pointed to by dptr
643   UINT32 addr = ERAM_ADDR(DPTR, 0xFFFF);
644   UINT8 byte = DATAMEM_R(addr);           //Grab 1 byte from External DATA memory pointed to by dptr
645   SET_ACC(byte);                      //Store to ACC
646}
647
648//MOVX A, @R0/@R1                           /* 1: 1110 001i */
649//(Move External Ram 8 bit address to A)
650OPHANDLER( movx_a_ir )
651{
652   UINT32 addr = ERAM_ADDR(R_REG(r),0xFF); //Grab address by reading location pointed to by R0 or R1
653   UINT8 byte = DATAMEM_R(addr);           //Grab 1 byte from External DATA memory pointed to by address
654   SET_ACC(byte);                      //Store to ACC
655}
656
657//MOVX @DPTR,A                              /* 1: 1111 0000 */
658//(Move A to External Ram 16 bit address)
659OPHANDLER( movx_idptr_a )
660{
661//  DATAMEM_W(R_DPTR, ACC);               //Store ACC to External DATA memory address pointed to by DPTR
662   UINT32 addr = ERAM_ADDR(DPTR, 0xFFFF);
663   DATAMEM_W(addr, ACC);               //Store ACC to External DATA memory address pointed to by DPTR
664}
665
666//MOVX @R0/@R1,A                            /* 1: 1111 001i */
667//(Move A to External Ram 8 bit address)
668OPHANDLER( movx_ir_a )
669{
670   UINT32 addr = ERAM_ADDR(R_REG(r),0xFF);   //Grab address by reading location pointed to by R0 or R1
671   DATAMEM_W(addr, ACC);                   //Store ACC to External DATA memory address
672}
673
674//MUL AB                                    /* 1: 1010 0100 */
675OPHANDLER( mul_ab )
676{
677   UINT16 result = ACC * B;
678   //A gets lo bits, B gets hi bits of result
679   B = (UINT8) ((result & 0xFF00) >> 8);
680   SET_ACC((UINT8)(result & 0x00FF));
681   //Set flags
682   SET_OV( ((result & 0x100) >> 8) );      //Set/Clear Overflow Flag if result > 255
683   SET_CY(0);                              //Carry Flag always cleared
684}
685
686//NOP                                       /* 1: 0000 0000 */
687OPHANDLER( nop )
688{
689}
690
691//ORL data addr, A                          /* 1: 0100 0010 */
692OPHANDLER( orl_mem_a )
693{
694   UINT8 addr = ROP_ARG(PC++);             //Grab data address
695   UINT8 data = IRAM_R(addr);              //Grab data from data address
696   IRAM_W(addr,data | ACC);                //Set data address value to it's value Logical OR with ACC
697}
698
699//ORL data addr, #data                      /* 1: 0100 0011 */
700OPHANDLER( orl_mem_byte )
701{
702   UINT8 addr = ROP_ARG(PC++);             //Grab data address
703   UINT8 data = ROP_ARG(PC++);             //Grab data
704   UINT8 srcdata = IRAM_R(addr);           //Grab data from data address
705   IRAM_W(addr,srcdata | data);            //Set data address value to it's value Logical OR with Data
706}
707
708//ORL A, #data                              /* 1: 0100 0100 */
709OPHANDLER( orl_a_byte )
710{
711   UINT8 data = ROP_ARG(PC++);             //Grab data
712   SET_ACC(ACC | data);                //Set ACC to value of ACC Logical OR with Data
713}
714
715//ORL A, data addr                          /* 1: 0100 0101 */
716OPHANDLER( orl_a_mem )
717{
718   UINT8 addr = ROP_ARG(PC++);             //Grab data address
719   UINT8 data = IRAM_R(addr);              //Grab data from data address
720   SET_ACC(ACC | data);                //Set ACC to value of ACC Logical OR with Data
721}
722
723//ORL A, @RO/@R1                            /* 1: 0100 011i */
724OPHANDLER( orl_a_ir )
725{
726   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from address R0 or R1 points to
727   SET_ACC(ACC | data);                //Set ACC to value of ACC Logical OR with Data
728}
729
730//ORL A, RO to R7                           /* 1: 0100 1rrr */
731OPHANDLER( orl_a_r )
732{
733   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
734   SET_ACC(ACC | data);                //Set ACC to value of ACC Logical OR with Data
735}
736
737//ORL C, bit addr                           /* 1: 0111 0010 */
738OPHANDLER( orl_c_bitaddr )
739{
740   int cy = GET_CY;
741   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
742   UINT8 bit = BIT_R(addr);                //Grab bit data from bit address
743   SET_CY( (cy | bit) );                   //Set Carry flag to Carry Flag Value Logical OR with Bit
744}
745
746//ORL C, /bit addr                          /* 1: 1010 0000 */
747OPHANDLER( orl_c_nbitaddr )
748{
749   int cy = GET_CY;
750   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
751   UINT8 bit = BIT_R(addr);                //Grab bit data from bit address
752   bit = ((~bit)&1);                       //Complement bit
753   SET_CY( (cy | bit) );                   //Set Carry flag to Carry Flag Value Logical OR with Complemented Bit
754}
755
756//POP data addr                             /* 1: 1101 0000 */
757OPHANDLER( pop )
758{
759   UINT8 addr = ROP_ARG(PC++);             //Grab data address
760   IRAM_W(addr, IRAM_IR(SP));              //Store to contents of data addr, data pointed to by Stack - IRAM_IR needed to access upper 128 bytes of stack
761   //IRAM_IW(addr, IRAM_IR(R_SP));         //Store to contents of data addr, data pointed to by Stack - doesn't work, sfr's are not restored this way and it's not an indirect access anyway
762   SP = SP-1;                              //Decrement SP
763}
764
765//PUSH data addr                            /* 1: 1100 0000 */
766OPHANDLER( push )
767{
768   UINT8 addr = ROP_ARG(PC++);             //Grab data address
769   UINT8 tmpSP = SP+1;                 //Grab and Increment Stack Pointer
770   SP = tmpSP;                         // ""
771   IRAM_IW(tmpSP, IRAM_R(addr));           //Store to stack contents of data address - IRAM_IW needed to store to upper 128 bytes of stack, however, can't use IRAM_IR because that won't store the sfrs and it's not an indirect access anyway
772}
773
774//RET                                       /* 1: 0010 0010 */
775OPHANDLER( ret )
776{
777   POP_PC();
778}
779
780//RETI                                      /* 1: 0011 0010 */
781OPHANDLER( reti )
782{
783   POP_PC();
784   CLEAR_CURRENT_IRQ();
785}
786
787//RL A                                      /* 1: 0010 0011 */
788OPHANDLER( rl_a )
789{
790   //Left Shift A, Bit 7 carries to Bit 0
791   int carry = ((ACC & 0x80) >> 7);
792   int data = (ACC<<1) & 0xfe;
793   SET_ACC( data | carry);
794}
795
796//RLC A                                     /* 1: 0011 0011 */
797OPHANDLER( rlc_a )
798{
799   //Left Shift A, Bit 7 goes to Carry Flag, Original Carry Flag goes to Bit 0 of ACC
800   int carry = ((ACC & 0x80) >> 7);
801   int data = ((ACC<<1) & 0xfe) | GET_CY;
802   SET_ACC( data);
803   SET_CY(carry);
804}
805
806//RR A                                      /* 1: 0000 0011 */
807OPHANDLER( rr_a )
808{
809   //Right Shift A, Bit 0 carries to Bit 7
810   int carry = ((ACC & 1) << 7);
811   int data = (ACC>>1) & 0x7f;
812   SET_ACC( data | carry);
813}
814
815//RRC A                                     /* 1: 0001 0011 */
816OPHANDLER( rrc_a )
817{
818   //Right Shift A, Bit 0 goes to Carry Flag, Bit 7 of ACC gets set to original Carry Flag
819   int carry = (ACC & 1);
820   int data = ((ACC>>1) & 0x7f) | (GET_CY<<7);
821   SET_ACC( data);
822   SET_CY(carry);
823}
824
825//SETB C                                    /* 1: 1101 0011 */
826OPHANDLER( setb_c )
827{
828   SET_CY(1);      //Set Carry Flag
829}
830
831//SETB bit addr                             /* 1: 1101 0010 */
832OPHANDLER( setb_bitaddr )
833{
834   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
835   BIT_W(addr,1);                          //Set Bit at Bit Address
836}
837
838//SJMP code addr                            /* 1: 1000 0000 */
839OPHANDLER( sjmp )
840{
841   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
842   PC = PC + rel_addr;                     //Update PC
843}
844
845//SUBB A, #data                             /* 1: 1001 0100 */
846OPHANDLER( subb_a_byte )
847{
848   UINT8 data = ROP_ARG(PC++);             //Grab data
849   UINT8 result = ACC - data - GET_CY; //Subtract data & carry flag from accumulator
850   DO_SUB_FLAGS(ACC,data,GET_CY);      //Set Flags
851   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
852
853}
854
855//SUBB A, data addr                         /* 1: 1001 0101 */
856OPHANDLER( subb_a_mem )
857{
858   UINT8 addr = ROP_ARG(PC++);             //Grab data address
859   UINT8 data = IRAM_R(addr);              //Grab data from data address
860   UINT8 result = ACC - data - GET_CY; //Subtract data & carry flag from accumulator
861   DO_SUB_FLAGS(ACC,data,GET_CY);      //Set Flags
862   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
863}
864
865//SUBB A, @R0/@R1                           /* 1: 1001 011i */
866OPHANDLER( subb_a_ir )
867{
868   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from memory pointed to by R0 or R1
869   UINT8 result = ACC - data - GET_CY; //Subtract data & carry flag from accumulator
870   DO_SUB_FLAGS(ACC,data,GET_CY);      //Set Flags
871   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
872}
873
874//SUBB A, R0 to R7                          /* 1: 1001 1rrr */
875OPHANDLER( subb_a_r )
876{
877   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
878   UINT8 result = ACC - data - GET_CY; //Subtract data & carry flag from accumulator
879   DO_SUB_FLAGS(ACC,data,GET_CY);      //Set Flags
880   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
881}
882
883//SWAP A                                    /* 1: 1100 0100 */
884OPHANDLER( swap_a )
885{
886   UINT8 a_nib_lo, a_nib_hi;
887   a_nib_hi = (ACC & 0x0f) << 4;           //Grab lo byte of ACC and move to hi
888   a_nib_lo = (ACC & 0xf0) >> 4;           //Grab hi byte of ACC and move to lo
889   SET_ACC( a_nib_hi | a_nib_lo);
890}
891
892//XCH A, data addr                          /* 1: 1100 0101 */
893OPHANDLER( xch_a_mem )
894{
895   UINT8 addr = ROP_ARG(PC++);             //Grab data address
896   UINT8 data = IRAM_R(addr);              //Grab data
897   UINT8 oldACC = ACC;                 //Hold value of ACC
898   SET_ACC(data);                      //Sets ACC to data
899   IRAM_W(addr,oldACC);                    //Sets data address to old value of ACC
900}
901
902//XCH A, @RO/@R1                            /* 1: 1100 011i */
903OPHANDLER( xch_a_ir )
904{
905   UINT8 data = IRAM_IR(R_REG(r));         //Grab data pointed to by R0 or R1
906   UINT8 oldACC = ACC;                 //Hold value of ACC
907   SET_ACC(data);                      //Sets ACC to data
908   IRAM_W(R_REG(r),oldACC);                    //Sets data address to old value of ACC
909}
910
911//XCH A, RO to R7                           /* 1: 1100 1rrr */
912OPHANDLER( xch_a_r )
913{
914   UINT8 data = R_REG(r);                  //Grab data from R0-R7
915   UINT8 oldACC = ACC;                 //Hold value of ACC
916   SET_ACC(data);                      //Sets ACC to data
917   SET_REG(r, oldACC);                     //Sets data address to old value of ACC
918}
919
920//XCHD A, @R0/@R1                           /* 1: 1101 011i */
921OPHANDLER( xchd_a_ir )
922{
923   UINT8 acc, ir_data;
924   ir_data = IRAM_IR(R_REG(r));                //Grab data pointed to by R0 or R1
925   acc = ACC;                          //Grab ACC value
926   SET_ACC( (acc & 0xf0) | (ir_data & 0x0f) );     //Set ACC to lower nibble of data pointed to by R0 or R1
927   IRAM_W(R_REG(r), (ir_data & 0xf0) | (acc & 0x0f) ); //Set data pointed to by R0 or R1 to lower nibble of ACC
928}
929
930//XRL data addr, A                          /* 1: 0110 0010 */
931OPHANDLER( xrl_mem_a )
932{
933   UINT8 addr = ROP_ARG(PC++);             //Grab data address
934   UINT8 data = IRAM_R(addr);              //Grab data from data address
935   IRAM_W(addr,data ^ ACC);                //Set data address value to it's value Logical XOR with ACC
936}
937
938//XRL data addr, #data                      /* 1: 0110 0011 */
939OPHANDLER( xrl_mem_byte )
940{
941   UINT8 addr = ROP_ARG(PC++);             //Grab data address
942   UINT8 data = ROP_ARG(PC++);             //Grab data
943   UINT8 srcdata = IRAM_R(addr);           //Grab data from data address
944   IRAM_W(addr,srcdata ^ data);            //Set data address value to it's value Logical XOR with Data
945}
946
947//XRL A, #data                              /* 1: 0110 0100 */
948OPHANDLER( xrl_a_byte )
949{
950   UINT8 data = ROP_ARG(PC++);             //Grab data
951   SET_ACC(ACC ^ data);                //Set ACC to value of ACC Logical XOR with Data
952}
953
954//XRL A, data addr                          /* 1: 0110 0101 */
955OPHANDLER( xrl_a_mem )
956{
957   UINT8 addr = ROP_ARG(PC++);             //Grab data address
958   UINT8 data = IRAM_R(addr);              //Grab data from data address
959   SET_ACC(ACC ^ data);                //Set ACC to value of ACC Logical XOR with Data
960}
961
962//XRL A, @R0/@R1                            /* 1: 0110 011i */
963OPHANDLER( xrl_a_ir )
964{
965   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from address R0 or R1 points to
966   SET_ACC(ACC ^ data);                //Set ACC to value of ACC Logical XOR with Data
967}
968
969//XRL A, R0 to R7                           /* 1: 0110 1rrr */
970OPHANDLER( xrl_a_r )
971{
972   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
973   SET_ACC(ACC ^ data);                //Set ACC to value of ACC Logical XOR with Data
974}
975
976//illegal opcodes
977OPHANDLER( illegal )
978{
979   LOG(("i8051 '%s': illegal opcode at 0x%03x: %02x\n", tag(), PC-1, r));
980}
trunk/src/emu/cpu/mcs51/mcs51ops.inc
r0r28739
1/*******************************************************************************************
2 NOTE: All registers are accessed directly, instead of using the SFR_R() function for speed
3 Direct register access is availabe from the R_(register name) macros.. ex: ACC for the ACC
4 with the exception of the PC
5********************************************************************************************/
6
7//ACALL code addr                           /* 1: aaa1 0001 */
8OPHANDLER( acall )
9{
10   UINT8 addr = ROP_ARG(PC++);             //Grab code address byte
11   PUSH_PC();                              //Save PC to the stack
12   //Thanks Gerrit for help with this! :)
13   PC = (PC & 0xf800) | ((r & 0xe0) << 3) | addr;
14}
15
16//ADD A, #data                              /* 1: 0010 0100 */
17OPHANDLER( add_a_byte )
18{
19   UINT8 data = ROP_ARG(PC++);             //Grab data
20   UINT8 result = ACC + data;          //Add data to accumulator
21   DO_ADD_FLAGS(ACC,data,0);               //Set Flags
22   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
23}
24
25//ADD A, data addr                          /* 1: 0010 0101 */
26OPHANDLER( add_a_mem )
27{
28   UINT8 addr = ROP_ARG(PC++);             //Grab data address
29   UINT8 data = IRAM_R(addr);              //Grab data from data address
30   UINT8 result = ACC + data;          //Add data to accumulator
31   DO_ADD_FLAGS(ACC,data,0);               //Set Flags
32   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
33}
34
35//ADD A, @R0/@R1                            /* 1: 0010 011i */
36OPHANDLER( add_a_ir )
37{
38   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from memory pointed to by R0 or R1
39   UINT8 result = ACC + data;          //Add data to accumulator
40   DO_ADD_FLAGS(ACC,data,0);               //Set Flags
41   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
42}
43
44//ADD A, R0 to R7                           /* 1: 0010 1rrr */
45OPHANDLER( add_a_r )
46{
47   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
48   UINT8 result = ACC + data;          //Add data to accumulator
49   DO_ADD_FLAGS(ACC,data,0);               //Set Flags
50   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
51}
52
53//ADDC A, #data                             /* 1: 0011 0100 */
54OPHANDLER( addc_a_byte )
55{
56   UINT8 data = ROP_ARG(PC++);             //Grab data
57   UINT8 result = ACC + data + GET_CY; //Add data + carry flag to accumulator
58   DO_ADD_FLAGS(ACC,data,GET_CY);      //Set Flags
59   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
60}
61
62//ADDC A, data addr                         /* 1: 0011 0101 */
63OPHANDLER( addc_a_mem )
64{
65   UINT8 addr = ROP_ARG(PC++);             //Grab data address
66   UINT8 data = IRAM_R(addr);              //Grab data from data address
67   UINT8 result = ACC + data + GET_CY; //Add data + carry flag to accumulator
68   DO_ADD_FLAGS(ACC,data,GET_CY);      //Set Flags
69   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
70}
71
72//ADDC A, @R0/@R1                           /* 1: 0011 011i */
73OPHANDLER( addc_a_ir )
74{
75   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from memory pointed to by R0 or R1
76   UINT8 result = ACC + data + GET_CY; //Add data + carry flag to accumulator
77   DO_ADD_FLAGS(ACC,data,GET_CY);      //Set Flags
78   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
79}
80
81//ADDC A, R0 to R7                          /* 1: 0011 1rrr */
82OPHANDLER( addc_a_r )
83{
84   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
85   UINT8 result = ACC + data + GET_CY; //Add data + carry flag to accumulator
86   DO_ADD_FLAGS(ACC,data,GET_CY);      //Set Flags
87   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
88}
89
90//AJMP code addr                            /* 1: aaa0 0001 */
91OPHANDLER( ajmp )
92{
93   UINT8 addr = ROP_ARG(PC++);             //Grab code address byte
94   //Thanks Gerrit for help with this! :)
95   PC = (PC & 0xf800) | ((r & 0xe0) << 3) | addr;
96}
97
98//ANL data addr, A                          /* 1: 0101 0010 */
99OPHANDLER( anl_mem_a )
100{
101   UINT8 addr = ROP_ARG(PC++);             //Grab data address
102   UINT8 data = IRAM_R(addr);              //Grab data from data address
103   IRAM_W(addr,data & ACC);                //Set data address value to it's value Logical AND with ACC
104}
105
106//ANL data addr, #data                      /* 1: 0101 0011 */
107OPHANDLER( anl_mem_byte )
108{
109   UINT8 addr = ROP_ARG(PC++);             //Grab data address
110   UINT8 data = ROP_ARG(PC++);             //Grab data
111   UINT8 srcdata = IRAM_R(addr);           //Grab data from data address
112   IRAM_W(addr,srcdata & data);            //Set data address value to it's value Logical AND with Data
113}
114
115//ANL A, #data                              /* 1: 0101 0100 */
116OPHANDLER( anl_a_byte )
117{
118   UINT8 data = ROP_ARG(PC++);             //Grab data
119   SET_ACC(ACC & data);                //Set ACC to value of ACC Logical AND with Data
120}
121
122//ANL A, data addr                          /* 1: 0101 0101 */
123OPHANDLER( anl_a_mem )
124{
125   UINT8 addr = ROP_ARG(PC++);             //Grab data address
126   UINT8 data = IRAM_R(addr);              //Grab data from data address
127   SET_ACC(ACC & data);                //Set ACC to value of ACC Logical AND with Data
128}
129
130//ANL A, @RO/@R1                            /* 1: 0101 011i */
131OPHANDLER( anl_a_ir )
132{
133   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from address R0 or R1 points to
134   SET_ACC(ACC & data);                //Set ACC to value of ACC Logical AND with Data
135}
136
137//ANL A, RO to R7                           /* 1: 0101 1rrr */
138OPHANDLER( anl_a_r )
139{
140   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
141   SET_ACC(ACC & data);                //Set ACC to value of ACC Logical AND with Data
142}
143
144//ANL C, bit addr                           /* 1: 1000 0010 */
145OPHANDLER( anl_c_bitaddr )
146{
147   int cy = GET_CY;
148   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
149   UINT8 bit = BIT_R(addr);                //Grab bit data from bit address
150   SET_CY( (cy & bit) );                   //Set Carry flag to Carry Flag Value Logical AND with Bit
151}
152
153//ANL C,/bit addr                           /* 1: 1011 0000 */
154OPHANDLER( anl_c_nbitaddr )
155{
156   int cy = GET_CY;
157   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
158   UINT8 bit = BIT_R(addr);                //Grab bit data from bit address
159   bit = ((~bit)&1);                       //Complement bit
160   SET_CY( (cy & bit) );                   //Set Carry flag to Carry Flag Value Logical AND with Complemented Bit
161}
162
163//CJNE A, #data, code addr                  /* 1: 1011 0100 */
164OPHANDLER( cjne_a_byte )
165{
166   UINT8 data = ROP_ARG(PC++);             //Grab data
167   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
168
169   if(ACC != data)                     //Jump if values are not equal
170   {
171      PC = PC + rel_addr;
172   }
173
174   //Set carry flag to 1 if 1st compare value is < 2nd compare value
175   SET_CY( (ACC < data) );
176}
177
178//CJNE A, data addr, code addr              /* 1: 1011 0101 */
179OPHANDLER( cjne_a_mem )
180{
181   UINT8 addr = ROP_ARG(PC++);             //Grab data address
182   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
183   UINT8 data = IRAM_R(addr);              //Pull value from data address
184
185   if(ACC != data)                     //Jump if values are not equal
186   {
187      PC = PC + rel_addr;
188   }
189
190   //Set carry flag to 1 if 1st compare value is < 2nd compare value
191   SET_CY( (ACC < data) );
192}
193
194//CJNE @R0/@R1, #data, code addr            /* 1: 1011 011i */
195OPHANDLER( cjne_ir_byte )
196{
197   UINT8 data = ROP_ARG(PC++);             //Grab data
198   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
199   UINT8 srcdata = IRAM_IR(R_REG(r));      //Grab value pointed to by R0 or R1
200
201   if(srcdata != data)                     //Jump if values are not equal
202   {
203      PC = PC + rel_addr;
204   }
205
206   //Set carry flag to 1 if 1st compare value is < 2nd compare value
207   SET_CY( (srcdata < data) );
208}
209
210//CJNE R0 to R7, #data, code addr           /* 1: 1011 1rrr */
211OPHANDLER( cjne_r_byte )
212{
213   UINT8 data = ROP_ARG(PC++);             //Grab data
214   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
215   UINT8 srcdata = R_REG(r);                   //Grab value of R0 - R7
216
217   if(srcdata != data)                     //Jump if values are not equal
218   {
219      PC = PC + rel_addr;
220   }
221
222   //Set carry flag to 1 if 1st compare value is < 2nd compare value
223   SET_CY( (srcdata < data) );
224}
225
226//CLR bit addr                              /* 1: 1100 0010 */
227OPHANDLER( clr_bitaddr )
228{
229   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
230   BIT_W(addr,0);                          //Clear bit at specified bit address
231}
232
233//CLR C                                     /* 1: 1100 0011 */
234OPHANDLER( clr_c )
235{
236   SET_CY(0);                              //Clear Carry Flag
237}
238
239//CLR A                                     /* 1: 1110 0100 */
240OPHANDLER( clr_a )
241{
242   SET_ACC(0);                         //Clear Accumulator
243}
244
245//CPL bit addr                              /* 1: 1011 0010 */
246OPHANDLER( cpl_bitaddr )
247{
248   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
249   UINT8 data = (~BIT_R(addr))&1;
250   BIT_W(addr,data);                       //Complement bit at specified bit address
251}
252
253//CPL C                                     /* 1: 1011 0011 */
254OPHANDLER( cpl_c )
255{
256   UINT8 bit = (~GET_CY)&1;                //Complement Carry Flag
257   SET_CY(bit);
258}
259
260//CPL A                                     /* 1: 1111 0100 */
261OPHANDLER( cpl_a )
262{
263   UINT8 data = ((~ACC)&0xff);
264   SET_ACC(data);                      //Complement Accumulator
265}
266
267//DA A                                      /* 1: 1101 0100 */
268OPHANDLER( da_a )
269{
270/*From several sources, since none said the same thing:
271 The decimal adjust instruction is associated with the use of the ADD and ADDC instructions.
272 The eight-bit value in the accumulator is adjusted to form two BCD digits of four bits each.
273 If the accumulator contents bits 0-3 are greater than 9, OR the AC flag is set, then six is added to
274 produce a proper BCD digit.
275 If the carry is set, OR the four high bits 4-7 exceed nine, six is added to the value of these bits.
276 The carry flag will be set if the result is > 0x99, but not cleared otherwise */
277
278   UINT16 new_acc = ACC & 0xff;
279   if(GET_AC || (new_acc & 0x0f) > 0x09)
280      new_acc += 0x06;
281   if(GET_CY || ((new_acc & 0xf0) > 0x90) || (new_acc & ~0xff))
282      new_acc += 0x60;
283   SET_ACC(new_acc&0xff);
284   if(new_acc & ~0xff)
285   SET_CY(1);
286}
287
288//DEC A                                     /* 1: 0001 0100 */
289OPHANDLER( dec_a )
290{
291   SET_ACC(ACC-1);
292}
293
294//DEC data addr                             /* 1: 0001 0101 */
295OPHANDLER( dec_mem )
296{
297   UINT8 addr = ROP_ARG(PC++);             //Grab data address
298   UINT8 data = IRAM_R(addr);
299   IRAM_W(addr,data-1);
300}
301
302//DEC @R0/@R1                               /* 1: 0001 011i */
303OPHANDLER( dec_ir )
304{
305   UINT8 data = IRAM_IR(R_REG(r));
306   IRAM_W(R_REG(r),data-1);
307}
308
309//DEC R0 to R7                              /* 1: 0001 1rrr */
310OPHANDLER( dec_r )
311{
312   SET_REG(r, R_REG(r) - 1);
313}
314
315//DIV AB                                    /* 1: 1000 0100 */
316OPHANDLER( div_ab )
317{
318   if( B == 0 ) {
319      //Overflow flag is set!
320      SET_OV(1);
321      //Really the values are undefined according to the manual, but we'll just leave them as is..
322      //SET_ACC(0xff);
323      //SFR_W(B,0xff);
324   }
325   else {
326      int a = (int)ACC / B;
327      int b = (int)ACC % B;
328      //A gets quotient byte, B gets remainder byte
329      SET_ACC(a);
330      B = b;
331      //Overflow flag is cleared
332      SET_OV(0);
333   }
334   //Carry Flag is always cleared
335   SET_CY(0);
336}
337
338//DJNZ data addr, code addr                 /* 1: 1101 0101 */
339OPHANDLER( djnz_mem )
340{
341   UINT8 addr = ROP_ARG(PC++);             //Grab data address
342   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
343   IRAM_W(addr,IRAM_R(addr) - 1);          //Decrement value contained at data address
344   if(IRAM_R(addr) != 0)                   //Branch if contents of data address is not 0
345   {
346      PC = PC + rel_addr;
347   }
348}
349
350//DJNZ R0 to R7,code addr                   /* 1: 1101 1rrr */
351OPHANDLER( djnz_r )
352{
353   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
354   SET_REG(r ,R_REG(r) - 1);                   //Decrement value
355   if(R_REG(r) != 0)                           //Branch if contents of R0 - R7 is not 0
356   {
357      PC = PC + rel_addr;
358   }
359}
360
361//INC A                                     /* 1: 0000 0100 */
362OPHANDLER( inc_a )
363{
364   SET_ACC(ACC+1);
365}
366
367//INC data addr                             /* 1: 0000 0101 */
368OPHANDLER( inc_mem )
369{
370   UINT8 addr = ROP_ARG(PC++);             //Grab data address
371   UINT8 data = IRAM_R(addr);
372   IRAM_W(addr,data+1);
373}
374
375//INC @R0/@R1                               /* 1: 0000 011i */
376OPHANDLER( inc_ir )
377{
378   UINT8 data = IRAM_IR(R_REG(r));
379   IRAM_W(R_REG(r),data+1);
380}
381
382//INC R0 to R7                              /* 1: 0000 1rrr */
383OPHANDLER( inc_r )
384{
385   UINT8 data = R_REG(r);
386   SET_REG(r, data + 1);
387}
388
389//INC DPTR                                  /* 1: 1010 0011 */
390OPHANDLER( inc_dptr )
391{
392   UINT16 dptr = (DPTR)+1;
393   SET_DPTR(dptr);
394}
395
396//JB  bit addr, code addr                   /* 1: 0010 0000 */
397OPHANDLER( jb )
398{
399   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
400   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
401   if(BIT_R(addr))                         //If bit set at specified bit address, jump
402   {
403      PC = PC + rel_addr;
404   }
405}
406
407//JBC bit addr, code addr                   /* 1: 0001 0000 */
408OPHANDLER( jbc )
409{
410   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
411   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
412   if(BIT_R(addr)) {                       //If bit set at specified bit address, jump
413      PC = PC + rel_addr;
414      BIT_W(addr,0);                      //Clear Bit also
415   }
416}
417
418//JC code addr                              /* 1: 0100 0000 */
419OPHANDLER( jc )
420{
421   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
422   if(GET_CY)                              //Jump if Carry Flag Set
423   {
424      PC = PC + rel_addr;
425   }
426}
427
428//JMP @A+DPTR                               /* 1: 0111 0011 */
429OPHANDLER( jmp_iadptr )
430{
431   PC = ACC + DPTR;
432}
433
434//JNB bit addr, code addr                   /* 1: 0011 0000 */
435OPHANDLER( jnb )
436{
437   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
438   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
439   if(!BIT_R(addr))                        //If bit NOT set at specified bit address, jump
440   {
441      PC = PC + rel_addr;
442   }
443}
444
445//JNC code addr                             /* 1: 0101 0000 */
446OPHANDLER( jnc )
447{
448   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
449   if(!GET_CY)                             //Jump if Carry Flag not set
450   {
451      PC = PC + rel_addr;
452   }
453}
454
455//JNZ code addr                             /* 1: 0111 0000 */
456OPHANDLER( jnz )
457{
458   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
459   if(ACC != 0)                            //Branch if ACC is not 0
460   {
461      PC = PC+rel_addr;
462   }
463}
464
465//JZ code addr                              /* 1: 0110 0000 */
466OPHANDLER( jz )
467{
468   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
469   if(ACC == 0)                            //Branch if ACC is 0
470   {
471      PC = PC+rel_addr;
472   }
473}
474
475//LCALL code addr                           /* 1: 0001 0010 */
476OPHANDLER( lcall )
477{
478   UINT8 addr_hi, addr_lo;
479   addr_hi = ROP_ARG(PC++);
480   addr_lo = ROP_ARG(PC++);
481   PUSH_PC();
482   PC = (UINT16)((addr_hi<<8) | addr_lo);
483}
484
485//LJMP code addr                            /* 1: 0000 0010 */
486OPHANDLER( ljmp )
487{
488   UINT8 addr_hi, addr_lo;
489   addr_hi = ROP_ARG(PC++);
490   addr_lo = ROP_ARG(PC++);
491   PC = (UINT16)((addr_hi<<8) | addr_lo);
492}
493
494//MOV A, #data                              /* 1: 0111 0100 */
495OPHANDLER( mov_a_byte )
496{
497   UINT8 data = ROP_ARG(PC++);             //Grab data
498   SET_ACC(data);                      //Store data to ACC
499}
500
501//MOV A, data addr                          /* 1: 1110 0101 */
502OPHANDLER( mov_a_mem )
503{
504   UINT8 addr = ROP_ARG(PC++);             //Grab data address
505   SET_ACC(IRAM_R(addr));              //Store contents of data address to ACC
506}
507
508//MOV A,@RO/@R1                             /* 1: 1110 011i */
509OPHANDLER( mov_a_ir )
510{
511   SET_ACC(IRAM_IR(R_REG(r)));             //Store contents of address pointed by R0 or R1 to ACC
512}
513
514//MOV A,R0 to R7                            /* 1: 1110 1rrr */
515OPHANDLER( mov_a_r )
516{
517   SET_ACC(R_REG(r));                      //Store contents of R0 - R7 to ACC
518}
519
520//MOV data addr, #data                      /* 1: 0111 0101 */
521OPHANDLER( mov_mem_byte )
522{
523   UINT8 addr = ROP_ARG(PC++);             //Grab data address
524   UINT8 data = ROP_ARG(PC++);             //Grab data
525   IRAM_W(addr,data);                      //Store data to data address location
526}
527
528//MOV data addr, data addr                  /* 1: 1000 0101 */
529OPHANDLER( mov_mem_mem )
530{
531   //1st address is src, 2nd is dst, but the mov command works as mov dst,src)
532   UINT8 src,dst;
533   src = ROP_ARG(PC++);                    //Grab source data address
534   dst = ROP_ARG(PC++);                    //Grab destination data address
535   IRAM_W(dst,IRAM_R(src));                //Read source address contents and store to destination address
536}
537
538//MOV @R0/@R1, #data                        /* 1: 0111 011i */
539OPHANDLER( mov_ir_byte )
540{
541   UINT8 data = ROP_ARG(PC++);             //Grab data
542   IRAM_IW(R_REG(r),data);                 //Store data to address pointed by R0 or R1
543}
544
545//MOV R0 to R7, #data                       /* 1: 0111 1rrr */
546OPHANDLER( mov_r_byte )
547{
548   UINT8 data = ROP_ARG(PC++);             //Grab data
549   SET_REG(r, data);                           //Store to R0 - R7
550}
551
552//MOV data addr, @R0/@R1                    /* 1: 1000 011i */
553OPHANDLER( mov_mem_ir )
554{
555   UINT8 addr = ROP_ARG(PC++);             //Grab data address
556   IRAM_W(addr,IRAM_IR(R_REG(r)));         //Store contents pointed to by R0 or R1 to data address
557}
558
559//MOV data addr,R0 to R7                    /* 1: 1000 1rrr */
560OPHANDLER( mov_mem_r )
561{
562   UINT8 addr = ROP_ARG(PC++);             //Grab data address
563   IRAM_W(addr,R_REG(r));                  //Store contents of R0 - R7 to data address
564}
565
566//MOV DPTR, #data16                         /* 1: 1001 0000 */
567OPHANDLER( mov_dptr_byte )
568{
569   UINT8 data_hi, data_lo;
570   data_hi = ROP_ARG(PC++);                //Grab hi byte
571   data_lo = ROP_ARG(PC++);                //Grab lo byte
572   SET_DPTR((UINT16)((data_hi<<8)|data_lo));   //Store to DPTR
573}
574
575//MOV bit addr, C                           /* 1: 1001 0010 */
576OPHANDLER( mov_bitaddr_c )
577{
578   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
579   BIT_W(addr,GET_CY);                     //Store Carry Flag to Bit Address
580}
581
582//MOV @R0/@R1, data addr                    /* 1: 1010 011i */
583OPHANDLER( mov_ir_mem )
584{
585   UINT8 addr = ROP_ARG(PC++);             //Grab data address
586   IRAM_IW(R_REG(r),IRAM_R(addr));         //Store data from data address to address pointed to by R0 or R1
587}
588
589//MOV R0 to R7, data addr                   /* 1: 1010 1rrr */
590OPHANDLER( mov_r_mem )
591{
592   UINT8 addr = ROP_ARG(PC++);             //Grab data address
593   SET_REG(r, IRAM_R(addr));               //Store to R0 - R7
594}
595
596//MOV data addr, A                          /* 1: 1111 0101 */
597OPHANDLER( mov_mem_a )
598{
599   UINT8 addr = ROP_ARG(PC++);             //Grab data address
600   IRAM_W(addr,ACC);                       //Store A to data address
601}
602
603//MOV @R0/@R1, A                            /* 1: 1111 011i */
604OPHANDLER( mov_ir_a )
605{
606   IRAM_IW(R_REG(r),ACC);                  //Store A to location pointed to by R0 or R1
607}
608
609//MOV R0 to R7, A                           /* 1: 1111 1rrr */
610OPHANDLER( mov_r_a )
611{
612   SET_REG(r, ACC);                        //Store A to R0-R7
613}
614
615//MOVC A, @A + PC                           /* 1: 1000 0011 */
616OPHANDLER( movc_a_iapc )
617{
618   UINT8 data;
619   data = CODEMEM_R(ACC+PC);               //Move a byte from CODE(Program) Memory and store to ACC
620   SET_ACC(data);
621}
622
623//MOV C, bit addr                           /* 1: 1010 0010 */
624OPHANDLER( mov_c_bitaddr )
625{
626   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
627   SET_CY( (BIT_R(addr)) );                //Store Bit from Bit Address to Carry Flag
628}
629
630//MOVC A, @A + DPTR                         /* 1: 1001 0011 */
631OPHANDLER( movc_a_iadptr )
632{
633   UINT8 data;
634   data = CODEMEM_R(ACC + DPTR);           //Move a byte from CODE(Program) Memory and store to ACC
635   SET_ACC(data);
636}
637
638//MOVX A,@DPTR                              /* 1: 1110 0000 */
639//(Move External Ram 16 bit address to A)
640OPHANDLER( movx_a_idptr )
641{
642//  UINT8 byte = DATAMEM_R(R_DPTR);         //Grab 1 byte from External DATA memory pointed to by dptr
643   UINT32 addr = ERAM_ADDR(DPTR, 0xFFFF);
644   UINT8 byte = DATAMEM_R(addr);           //Grab 1 byte from External DATA memory pointed to by dptr
645   SET_ACC(byte);                      //Store to ACC
646}
647
648//MOVX A, @R0/@R1                           /* 1: 1110 001i */
649//(Move External Ram 8 bit address to A)
650OPHANDLER( movx_a_ir )
651{
652   UINT32 addr = ERAM_ADDR(R_REG(r),0xFF); //Grab address by reading location pointed to by R0 or R1
653   UINT8 byte = DATAMEM_R(addr);           //Grab 1 byte from External DATA memory pointed to by address
654   SET_ACC(byte);                      //Store to ACC
655}
656
657//MOVX @DPTR,A                              /* 1: 1111 0000 */
658//(Move A to External Ram 16 bit address)
659OPHANDLER( movx_idptr_a )
660{
661//  DATAMEM_W(R_DPTR, ACC);               //Store ACC to External DATA memory address pointed to by DPTR
662   UINT32 addr = ERAM_ADDR(DPTR, 0xFFFF);
663   DATAMEM_W(addr, ACC);               //Store ACC to External DATA memory address pointed to by DPTR
664}
665
666//MOVX @R0/@R1,A                            /* 1: 1111 001i */
667//(Move A to External Ram 8 bit address)
668OPHANDLER( movx_ir_a )
669{
670   UINT32 addr = ERAM_ADDR(R_REG(r),0xFF);   //Grab address by reading location pointed to by R0 or R1
671   DATAMEM_W(addr, ACC);                   //Store ACC to External DATA memory address
672}
673
674//MUL AB                                    /* 1: 1010 0100 */
675OPHANDLER( mul_ab )
676{
677   UINT16 result = ACC * B;
678   //A gets lo bits, B gets hi bits of result
679   B = (UINT8) ((result & 0xFF00) >> 8);
680   SET_ACC((UINT8)(result & 0x00FF));
681   //Set flags
682   SET_OV( ((result & 0x100) >> 8) );      //Set/Clear Overflow Flag if result > 255
683   SET_CY(0);                              //Carry Flag always cleared
684}
685
686//NOP                                       /* 1: 0000 0000 */
687OPHANDLER( nop )
688{
689}
690
691//ORL data addr, A                          /* 1: 0100 0010 */
692OPHANDLER( orl_mem_a )
693{
694   UINT8 addr = ROP_ARG(PC++);             //Grab data address
695   UINT8 data = IRAM_R(addr);              //Grab data from data address
696   IRAM_W(addr,data | ACC);                //Set data address value to it's value Logical OR with ACC
697}
698
699//ORL data addr, #data                      /* 1: 0100 0011 */
700OPHANDLER( orl_mem_byte )
701{
702   UINT8 addr = ROP_ARG(PC++);             //Grab data address
703   UINT8 data = ROP_ARG(PC++);             //Grab data
704   UINT8 srcdata = IRAM_R(addr);           //Grab data from data address
705   IRAM_W(addr,srcdata | data);            //Set data address value to it's value Logical OR with Data
706}
707
708//ORL A, #data                              /* 1: 0100 0100 */
709OPHANDLER( orl_a_byte )
710{
711   UINT8 data = ROP_ARG(PC++);             //Grab data
712   SET_ACC(ACC | data);                //Set ACC to value of ACC Logical OR with Data
713}
714
715//ORL A, data addr                          /* 1: 0100 0101 */
716OPHANDLER( orl_a_mem )
717{
718   UINT8 addr = ROP_ARG(PC++);             //Grab data address
719   UINT8 data = IRAM_R(addr);              //Grab data from data address
720   SET_ACC(ACC | data);                //Set ACC to value of ACC Logical OR with Data
721}
722
723//ORL A, @RO/@R1                            /* 1: 0100 011i */
724OPHANDLER( orl_a_ir )
725{
726   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from address R0 or R1 points to
727   SET_ACC(ACC | data);                //Set ACC to value of ACC Logical OR with Data
728}
729
730//ORL A, RO to R7                           /* 1: 0100 1rrr */
731OPHANDLER( orl_a_r )
732{
733   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
734   SET_ACC(ACC | data);                //Set ACC to value of ACC Logical OR with Data
735}
736
737//ORL C, bit addr                           /* 1: 0111 0010 */
738OPHANDLER( orl_c_bitaddr )
739{
740   int cy = GET_CY;
741   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
742   UINT8 bit = BIT_R(addr);                //Grab bit data from bit address
743   SET_CY( (cy | bit) );                   //Set Carry flag to Carry Flag Value Logical OR with Bit
744}
745
746//ORL C, /bit addr                          /* 1: 1010 0000 */
747OPHANDLER( orl_c_nbitaddr )
748{
749   int cy = GET_CY;
750   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
751   UINT8 bit = BIT_R(addr);                //Grab bit data from bit address
752   bit = ((~bit)&1);                       //Complement bit
753   SET_CY( (cy | bit) );                   //Set Carry flag to Carry Flag Value Logical OR with Complemented Bit
754}
755
756//POP data addr                             /* 1: 1101 0000 */
757OPHANDLER( pop )
758{
759   UINT8 addr = ROP_ARG(PC++);             //Grab data address
760   IRAM_W(addr, IRAM_IR(SP));              //Store to contents of data addr, data pointed to by Stack - IRAM_IR needed to access upper 128 bytes of stack
761   //IRAM_IW(addr, IRAM_IR(R_SP));         //Store to contents of data addr, data pointed to by Stack - doesn't work, sfr's are not restored this way and it's not an indirect access anyway
762   SP = SP-1;                              //Decrement SP
763}
764
765//PUSH data addr                            /* 1: 1100 0000 */
766OPHANDLER( push )
767{
768   UINT8 addr = ROP_ARG(PC++);             //Grab data address
769   UINT8 tmpSP = SP+1;                 //Grab and Increment Stack Pointer
770   SP = tmpSP;                         // ""
771   IRAM_IW(tmpSP, IRAM_R(addr));           //Store to stack contents of data address - IRAM_IW needed to store to upper 128 bytes of stack, however, can't use IRAM_IR because that won't store the sfrs and it's not an indirect access anyway
772}
773
774//RET                                       /* 1: 0010 0010 */
775OPHANDLER( ret )
776{
777   POP_PC();
778}
779
780//RETI                                      /* 1: 0011 0010 */
781OPHANDLER( reti )
782{
783   POP_PC();
784   CLEAR_CURRENT_IRQ();
785}
786
787//RL A                                      /* 1: 0010 0011 */
788OPHANDLER( rl_a )
789{
790   //Left Shift A, Bit 7 carries to Bit 0
791   int carry = ((ACC & 0x80) >> 7);
792   int data = (ACC<<1) & 0xfe;
793   SET_ACC( data | carry);
794}
795
796//RLC A                                     /* 1: 0011 0011 */
797OPHANDLER( rlc_a )
798{
799   //Left Shift A, Bit 7 goes to Carry Flag, Original Carry Flag goes to Bit 0 of ACC
800   int carry = ((ACC & 0x80) >> 7);
801   int data = ((ACC<<1) & 0xfe) | GET_CY;
802   SET_ACC( data);
803   SET_CY(carry);
804}
805
806//RR A                                      /* 1: 0000 0011 */
807OPHANDLER( rr_a )
808{
809   //Right Shift A, Bit 0 carries to Bit 7
810   int carry = ((ACC & 1) << 7);
811   int data = (ACC>>1) & 0x7f;
812   SET_ACC( data | carry);
813}
814
815//RRC A                                     /* 1: 0001 0011 */
816OPHANDLER( rrc_a )
817{
818   //Right Shift A, Bit 0 goes to Carry Flag, Bit 7 of ACC gets set to original Carry Flag
819   int carry = (ACC & 1);
820   int data = ((ACC>>1) & 0x7f) | (GET_CY<<7);
821   SET_ACC( data);
822   SET_CY(carry);
823}
824
825//SETB C                                    /* 1: 1101 0011 */
826OPHANDLER( setb_c )
827{
828   SET_CY(1);      //Set Carry Flag
829}
830
831//SETB bit addr                             /* 1: 1101 0010 */
832OPHANDLER( setb_bitaddr )
833{
834   UINT8 addr = ROP_ARG(PC++);             //Grab bit address
835   BIT_W(addr,1);                          //Set Bit at Bit Address
836}
837
838//SJMP code addr                            /* 1: 1000 0000 */
839OPHANDLER( sjmp )
840{
841   INT8 rel_addr = ROP_ARG(PC++);          //Grab relative code address
842   PC = PC + rel_addr;                     //Update PC
843}
844
845//SUBB A, #data                             /* 1: 1001 0100 */
846OPHANDLER( subb_a_byte )
847{
848   UINT8 data = ROP_ARG(PC++);             //Grab data
849   UINT8 result = ACC - data - GET_CY; //Subtract data & carry flag from accumulator
850   DO_SUB_FLAGS(ACC,data,GET_CY);      //Set Flags
851   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
852
853}
854
855//SUBB A, data addr                         /* 1: 1001 0101 */
856OPHANDLER( subb_a_mem )
857{
858   UINT8 addr = ROP_ARG(PC++);             //Grab data address
859   UINT8 data = IRAM_R(addr);              //Grab data from data address
860   UINT8 result = ACC - data - GET_CY; //Subtract data & carry flag from accumulator
861   DO_SUB_FLAGS(ACC,data,GET_CY);      //Set Flags
862   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
863}
864
865//SUBB A, @R0/@R1                           /* 1: 1001 011i */
866OPHANDLER( subb_a_ir )
867{
868   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from memory pointed to by R0 or R1
869   UINT8 result = ACC - data - GET_CY; //Subtract data & carry flag from accumulator
870   DO_SUB_FLAGS(ACC,data,GET_CY);      //Set Flags
871   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
872}
873
874//SUBB A, R0 to R7                          /* 1: 1001 1rrr */
875OPHANDLER( subb_a_r )
876{
877   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
878   UINT8 result = ACC - data - GET_CY; //Subtract data & carry flag from accumulator
879   DO_SUB_FLAGS(ACC,data,GET_CY);      //Set Flags
880   SET_ACC(result);                        //Store 8 bit result of addtion in ACC
881}
882
883//SWAP A                                    /* 1: 1100 0100 */
884OPHANDLER( swap_a )
885{
886   UINT8 a_nib_lo, a_nib_hi;
887   a_nib_hi = (ACC & 0x0f) << 4;           //Grab lo byte of ACC and move to hi
888   a_nib_lo = (ACC & 0xf0) >> 4;           //Grab hi byte of ACC and move to lo
889   SET_ACC( a_nib_hi | a_nib_lo);
890}
891
892//XCH A, data addr                          /* 1: 1100 0101 */
893OPHANDLER( xch_a_mem )
894{
895   UINT8 addr = ROP_ARG(PC++);             //Grab data address
896   UINT8 data = IRAM_R(addr);              //Grab data
897   UINT8 oldACC = ACC;                 //Hold value of ACC
898   SET_ACC(data);                      //Sets ACC to data
899   IRAM_W(addr,oldACC);                    //Sets data address to old value of ACC
900}
901
902//XCH A, @RO/@R1                            /* 1: 1100 011i */
903OPHANDLER( xch_a_ir )
904{
905   UINT8 data = IRAM_IR(R_REG(r));         //Grab data pointed to by R0 or R1
906   UINT8 oldACC = ACC;                 //Hold value of ACC
907   SET_ACC(data);                      //Sets ACC to data
908   IRAM_W(R_REG(r),oldACC);                    //Sets data address to old value of ACC
909}
910
911//XCH A, RO to R7                           /* 1: 1100 1rrr */
912OPHANDLER( xch_a_r )
913{
914   UINT8 data = R_REG(r);                  //Grab data from R0-R7
915   UINT8 oldACC = ACC;                 //Hold value of ACC
916   SET_ACC(data);                      //Sets ACC to data
917   SET_REG(r, oldACC);                     //Sets data address to old value of ACC
918}
919
920//XCHD A, @R0/@R1                           /* 1: 1101 011i */
921OPHANDLER( xchd_a_ir )
922{
923   UINT8 acc, ir_data;
924   ir_data = IRAM_IR(R_REG(r));                //Grab data pointed to by R0 or R1
925   acc = ACC;                          //Grab ACC value
926   SET_ACC( (acc & 0xf0) | (ir_data & 0x0f) );     //Set ACC to lower nibble of data pointed to by R0 or R1
927   IRAM_W(R_REG(r), (ir_data & 0xf0) | (acc & 0x0f) ); //Set data pointed to by R0 or R1 to lower nibble of ACC
928}
929
930//XRL data addr, A                          /* 1: 0110 0010 */
931OPHANDLER( xrl_mem_a )
932{
933   UINT8 addr = ROP_ARG(PC++);             //Grab data address
934   UINT8 data = IRAM_R(addr);              //Grab data from data address
935   IRAM_W(addr,data ^ ACC);                //Set data address value to it's value Logical XOR with ACC
936}
937
938//XRL data addr, #data                      /* 1: 0110 0011 */
939OPHANDLER( xrl_mem_byte )
940{
941   UINT8 addr = ROP_ARG(PC++);             //Grab data address
942   UINT8 data = ROP_ARG(PC++);             //Grab data
943   UINT8 srcdata = IRAM_R(addr);           //Grab data from data address
944   IRAM_W(addr,srcdata ^ data);            //Set data address value to it's value Logical XOR with Data
945}
946
947//XRL A, #data                              /* 1: 0110 0100 */
948OPHANDLER( xrl_a_byte )
949{
950   UINT8 data = ROP_ARG(PC++);             //Grab data
951   SET_ACC(ACC ^ data);                //Set ACC to value of ACC Logical XOR with Data
952}
953
954//XRL A, data addr                          /* 1: 0110 0101 */
955OPHANDLER( xrl_a_mem )
956{
957   UINT8 addr = ROP_ARG(PC++);             //Grab data address
958   UINT8 data = IRAM_R(addr);              //Grab data from data address
959   SET_ACC(ACC ^ data);                //Set ACC to value of ACC Logical XOR with Data
960}
961
962//XRL A, @R0/@R1                            /* 1: 0110 011i */
963OPHANDLER( xrl_a_ir )
964{
965   UINT8 data = IRAM_IR(R_REG(r));         //Grab data from address R0 or R1 points to
966   SET_ACC(ACC ^ data);                //Set ACC to value of ACC Logical XOR with Data
967}
968
969//XRL A, R0 to R7                           /* 1: 0110 1rrr */
970OPHANDLER( xrl_a_r )
971{
972   UINT8 data = R_REG(r);                  //Grab data from R0 - R7
973   SET_ACC(ACC ^ data);                //Set ACC to value of ACC Logical XOR with Data
974}
975
976//illegal opcodes
977OPHANDLER( illegal )
978{
979   LOG(("i8051 '%s': illegal opcode at 0x%03x: %02x\n", tag(), PC-1, r));
980}
Property changes on: trunk/src/emu/cpu/mcs51/mcs51ops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/mcs51/mcs51.c
r28738r28739
13451345
13461346#define OPHANDLER( _name ) void mcs51_cpu_device::_name (UINT8 r)
13471347
1348#include "mcs51ops.c"
1348#include "mcs51ops.inc"
13491349
13501350
13511351void mcs51_cpu_device::execute_op(UINT8 op)
trunk/src/emu/cpu/dsp32/dsp32ops.c
r28738r28739
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3/***************************************************************************
4
5    dsp32ops.c
6    Core implementation for the portable DSP32 emulator.
7
8****************************************************************************/
9
10
11
12//**************************************************************************
13//  COMPILE-TIME OPTIONS
14//**************************************************************************
15
16// these defined latencies are a pain to implement, but are necessary
17#define EMULATE_MEMORY_LATENCY      (1)
18#define EMULATE_MULTIPLIER_LATENCY  (1)
19#define EMULATE_AFLAGS_LATENCY      (1)
20
21// these optimizations should have some effect, but they don't really, so
22// leave them off
23#define IGNORE_DAU_UV_FLAGS         (0)
24#define ASSUME_WRITEABLE            (0)
25#define ASSUME_UNCONDITIONAL_CAU    (0)
26
27
28
29//**************************************************************************
30//  MACROS
31//**************************************************************************
32
33#define SET_V_16(a,b,r)         m_vflags = (((a) ^ (b) ^ (r) ^ ((r) >> 1)) << 8)
34#define SET_NZC_16(r)           m_nzcflags = ((r) << 8)
35#define SET_NZCV_16(a,b,r)      SET_NZC_16(r); SET_V_16(a,b,r)
36#define SET_NZ00_16(r)          m_nzcflags = (((r) << 8) & 0xffffff); m_vflags = 0
37
38#define SET_V_24(a,b,r)         m_vflags = ((a) ^ (b) ^ (r) ^ ((r) >> 1))
39#define SET_NZC_24(r)           m_nzcflags = (r)
40#define SET_NZCV_24(a,b,r)      SET_NZC_24(r); SET_V_24(a,b,r)
41#define SET_NZ00_24(r)          m_nzcflags = ((r) & 0xffffff); m_vflags = 0
42
43#define TRUNCATE24(a)           ((a) & 0xffffff)
44#define EXTEND16_TO_24(a)       TRUNCATE24((INT32)(INT16)(a))
45#define REG16(a)                ((UINT16)m_r[a])
46#define REG24(a)                (m_r[a])
47
48#define WRITEABLE_REGS          (0x6f3efffe)
49#if ASSUME_WRITEABLE
50#define IS_WRITEABLE(r)         (1)
51#else
52#define IS_WRITEABLE(r)         (WRITEABLE_REGS & (1 << (r)))
53#endif
54
55#if ASSUME_UNCONDITIONAL_CAU
56#define CONDITION_IS_TRUE()     (1)
57#else
58#define CONDITION_IS_TRUE()     (!(op & 0x400) || (condition((op >> 12) & 15)))
59#endif
60
61#if EMULATE_MEMORY_LATENCY
62#define WWORD_DEFERRED(a,v)     do { int bufidx = m_mbuf_index & 3; m_mbufaddr[bufidx] = -(a); m_mbufdata[bufidx] = (v); } while (0)
63#define WLONG_DEFERRED(a,v)     do { int bufidx = m_mbuf_index & 3; m_mbufaddr[bufidx] = (a); m_mbufdata[bufidx] = (v); } while (0)
64#define PROCESS_DEFERRED_MEMORY()                                   \
65   if (m_mbufaddr[++m_mbuf_index & 3] != 1)                    \
66   {                                                                   \
67      int bufidx = m_mbuf_index & 3;                              \
68      if (m_mbufaddr[bufidx] >= 0)                                \
69         WLONG(m_mbufaddr[bufidx], m_mbufdata[bufidx]);  \
70      else                                                            \
71         WWORD(-m_mbufaddr[bufidx], m_mbufdata[bufidx]); \
72      m_mbufaddr[bufidx] = 1;                                     \
73   }
74#else
75#define WWORD_DEFERRED(a,v) WWORD(a,v)
76#define WLONG_DEFERRED(a,v) WLONG(a,v)
77#define PROCESS_DEFERRED_MEMORY()
78#endif
79
80#if EMULATE_MULTIPLIER_LATENCY
81#define DEFERRED_MULTIPLIER(x)  dau_get_amult(x)
82#else
83#define DEFERRED_MULTIPLIER(x)  m_a[x]
84#endif
85
86#if EMULATE_AFLAGS_LATENCY
87#define DEFERRED_NZFLAGS()  dau_get_anzflags()
88#define DEFERRED_VUFLAGS()  dau_get_avuflags()
89#else
90#define DEFERRED_NZFLAGS()  m_NZflags
91#define DEFERRED_VUFLAGS()  m_VUflags
92#endif
93
94
95
96//**************************************************************************
97//  TYPEDEFS
98//**************************************************************************
99
100union int_double
101{
102   double d;
103   UINT32 i[2];
104};
105
106
107
108//**************************************************************************
109//  IMPLEMENTATION
110//**************************************************************************
111
112void dsp32c_device::illegal(UINT32 op)
113{
114}
115
116
117void dsp32c_device::unimplemented(UINT32 op)
118{
119   fatalerror("Unimplemented op @ %06X: %08X (dis=%02X, tbl=%03X)\n", PC - 4, op, op >> 25, op >> 21);
120}
121
122
123inline void dsp32c_device::execute_one()
124{
125   UINT32 op;
126
127   PROCESS_DEFERRED_MEMORY();
128   debugger_instruction_hook(this, PC);
129   op = ROPCODE(PC);
130   m_icount -= 4;  // 4 clocks per cycle
131   PC += 4;
132   if (op)
133      (this->*s_dsp32ops[op >> 21])(op);
134}
135
136
137
138//**************************************************************************
139//  CAU HELPERS
140//**************************************************************************
141
142UINT32 dsp32c_device::cau_read_pi_special(UINT8 i)
143{
144   switch (i)
145   {
146      case 4:     return m_ibuf;
147      case 5:     return m_obuf;
148      case 6:     update_pcr(m_pcr & ~PCR_PDFs); update_pins(); return m_pdr;
149      case 14:    return m_piop;
150      case 20:    return m_pdr2;
151      case 22:    update_pcr(m_pcr & ~PCR_PIFs); update_pins(); return m_pir;
152      case 30:    return m_pcw;
153      default:    fprintf(stderr, "Unimplemented CAU PI read = %X\n", i);
154   }
155   return 0;
156}
157
158
159void dsp32c_device::cau_write_pi_special(UINT8 i, UINT32 val)
160{
161   switch (i)
162   {
163      case 4:     m_ibuf = val;   break;
164      case 5:     m_obuf = val;   break;
165      case 6:     m_pdr = val; update_pcr(m_pcr | PCR_PDFs); update_pins(); break;
166      case 14:    m_piop = val;   break;
167      case 20:    m_pdr2 = val;   break;
168      case 22:    m_pir = val; update_pcr(m_pcr | PCR_PIFs); update_pins(); break;
169      case 30:    m_pcw = val;    break;
170      default:    fprintf(stderr, "Unimplemented CAU PI write = %X\n", i);
171   }
172}
173
174
175inline UINT8 dsp32c_device::cau_read_pi_1byte(int pi)
176{
177   int p = (pi >> 5) & 0x1f;
178   int i = (pi >> 0) & 0x1f;
179   if (p)
180   {
181      UINT32 result = RBYTE(m_r[p]);
182      m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
183      return result;
184   }
185   else
186      return cau_read_pi_special(i);
187}
188
189
190inline UINT16 dsp32c_device::cau_read_pi_2byte(int pi)
191{
192   int p = (pi >> 5) & 0x1f;
193   int i = (pi >> 0) & 0x1f;
194   if (p)
195   {
196      UINT32 result = RWORD(m_r[p]);
197      if (i < 22 || i > 23)
198         m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
199      else
200         m_r[p] = TRUNCATE24(m_r[p] + m_r[i] * 2);
201      return result;
202   }
203   else
204      return cau_read_pi_special(i);
205}
206
207
208inline UINT32 dsp32c_device::cau_read_pi_4byte(int pi)
209{
210   int p = (pi >> 5) & 0x1f;
211   int i = (pi >> 0) & 0x1f;
212   if (p)
213   {
214      UINT32 result = RLONG(m_r[p]);
215      if (i < 22 || i > 23)
216         m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
217      else
218         m_r[p] = TRUNCATE24(m_r[p] + m_r[i] * 4);
219      return result;
220   }
221   else
222      return cau_read_pi_special(i);
223}
224
225
226inline void dsp32c_device::cau_write_pi_1byte(int pi, UINT8 val)
227{
228   int p = (pi >> 5) & 0x1f;
229   int i = (pi >> 0) & 0x1f;
230   if (p)
231   {
232      WBYTE(m_r[p], val);
233      m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
234   }
235   else
236      cau_write_pi_special(i, val);
237}
238
239
240inline void dsp32c_device::cau_write_pi_2byte(int pi, UINT16 val)
241{
242   int p = (pi >> 5) & 0x1f;
243   int i = (pi >> 0) & 0x1f;
244   if (p)
245   {
246      WWORD(m_r[p], val);
247      if (i < 22 || i > 23)
248         m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
249      else
250         m_r[p] = TRUNCATE24(m_r[p] + m_r[i] * 2);
251   }
252   else
253      cau_write_pi_special(i, val);
254}
255
256
257inline void dsp32c_device::cau_write_pi_4byte(int pi, UINT32 val)
258{
259   int p = (pi >> 5) & 0x1f;
260   int i = (pi >> 0) & 0x1f;
261   if (p)
262   {
263      WLONG(m_r[p], (INT32)(val << 8) >> 8);
264      if (i < 22 || i > 23)
265         m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
266      else
267         m_r[p] = TRUNCATE24(m_r[p] + m_r[i] * 4);
268   }
269   else
270      cau_write_pi_special(i, val);
271}
272
273
274
275//**************************************************************************
276//  DAU HELPERS
277//**************************************************************************
278
279inline double dsp32c_device::dau_get_amult(int aidx)
280{
281   int bufidx = (m_abuf_index - 1) & 3;
282   double val = m_a[aidx];
283   while (m_icount >= m_abufcycle[bufidx] - 2 * 4)
284   {
285      if (m_abufreg[bufidx] == aidx)
286         val = m_abuf[bufidx];
287      bufidx = (bufidx - 1) & 3;
288   }
289   return val;
290}
291
292
293inline double dsp32c_device::dau_get_anzflags()
294{
295   int bufidx = (m_abuf_index - 1) & 3;
296   double nzflags = m_NZflags;
297   while (m_icount >= m_abufcycle[bufidx] - 3 * 4)
298   {
299      nzflags = m_abufNZflags[bufidx];
300      bufidx = (bufidx - 1) & 3;
301   }
302   return nzflags;
303}
304
305
306inline UINT8 dsp32c_device::dau_get_avuflags()
307{
308#if (!IGNORE_DAU_UV_FLAGS)
309   int bufidx = (m_abuf_index - 1) & 3;
310   UINT8 vuflags = m_VUflags;
311   while (m_icount >= m_abufcycle[bufidx] - 3 * 4)
312   {
313      vuflags = m_abufVUflags[bufidx];
314      bufidx = (bufidx - 1) & 3;
315   }
316   return vuflags;
317#else
318   return 0;
319#endif
320}
321
322
323inline void dsp32c_device::remember_last_dau(int aidx)
324{
325#if (EMULATE_MULTIPLIER_LATENCY || EMULATE_AFLAGS_LATENCY)
326   int bufidx = m_abuf_index++ & 3;
327   m_abuf[bufidx] = m_a[aidx];
328   m_abufreg[bufidx] = aidx;
329   m_abufNZflags[bufidx] = m_NZflags;
330#if (!IGNORE_DAU_UV_FLAGS)
331   m_abufVUflags[bufidx] = m_VUflags;
332#endif
333   m_abufcycle[bufidx] = m_icount;
334#endif
335}
336
337
338inline void dsp32c_device::dau_set_val_noflags(int aidx, double res)
339{
340   remember_last_dau(aidx);
341   m_a[aidx] = res;
342}
343
344
345inline void dsp32c_device::dau_set_val_flags(int aidx, double res)
346{
347   remember_last_dau(aidx);
348#if (!IGNORE_DAU_UV_FLAGS)
349{
350   double absres = (res < 0) ? -res : res;
351   m_VUflags = 0;
352   if (absres < 5.87747e-39)
353   {
354      if (absres != 0)
355         m_VUflags = UFLAGBIT;
356      res = 0.0;
357   }
358   else if (absres > 3.40282e38)
359   {
360      m_VUflags = VFLAGBIT;
361//      debugger_break(Machine);
362//      fprintf(stderr, "Result = %g\n", absres);
363      res = (res < 0) ? -3.40282e38 : 3.40282e38;
364   }
365}
366#endif
367   m_NZflags = res;
368   m_a[aidx] = res;
369}
370
371
372inline double dsp32c_device::dsp_to_double(UINT32 val)
373{
374   int_double id;
375
376   if (val == 0)
377      return 0;
378   else if ((INT32)val > 0)
379   {
380      int exponent = ((val & 0xff) - 128 + 1023) << 20;
381      id.i[BYTE_XOR_BE(0)] = exponent + (val >> 11);
382      id.i[BYTE_XOR_BE(1)] = (val << 21) & 0xe0000000;
383   }
384   else
385   {
386      int exponent = ((val & 0xff) - 128 + 1023) << 20;
387      val = -(val & 0xffffff00);
388      id.i[BYTE_XOR_BE(0)] = 0x80000000 + exponent + ((val >> 11) & 0x001fffff);
389      id.i[BYTE_XOR_BE(1)] = (val << 21) & 0xe0000000;
390   }
391   return id.d;
392}
393
394
395inline UINT32 dsp32c_device::double_to_dsp(double val)
396{
397   int mantissa, exponent;
398   int_double id;
399   id.d = val;
400   mantissa = ((id.i[BYTE_XOR_BE(0)] & 0x000fffff) << 11) | ((id.i[BYTE_XOR_BE(1)] & 0xe0000000) >> 21);
401   exponent = ((id.i[BYTE_XOR_BE(0)] & 0x7ff00000) >> 20) - 1023 + 128;
402   if (exponent < 0)
403      return 0x00000000;
404   else if (exponent > 255)
405   {
406//      debugger_break(Machine);
407//      fprintf(stderr, "Exponent = %d\n", exponent);
408      return ((INT32)id.i[BYTE_XOR_BE(0)] >= 0) ? 0x7fffffff : 0x800000ff;
409   }
410   else if ((INT32)id.i[BYTE_XOR_BE(0)] >= 0)
411      return exponent | mantissa;
412   else
413   {
414      mantissa = -mantissa;
415      if (mantissa == 0) { mantissa = 0x80000000; exponent--; }
416      return 0x80000000 | exponent | (mantissa & 0xffffff00);
417   }
418}
419
420
421double dsp32c_device::dau_read_pi_special(int i)
422{
423   fatalerror("Unimplemented dau_read_pi_special(%d)\n", i);
424   return 0;
425}
426
427
428void dsp32c_device::dau_write_pi_special(int i, double val)
429{
430   fatalerror("Unimplemented dau_write_pi_special(%d)\n", i);
431}
432
433
434inline double dsp32c_device::dau_read_pi_double_1st(int pi, int multiplier)
435{
436   int p = (pi >> 3) & 15;
437   int i = (pi >> 0) & 7;
438
439   m_lastp = p;
440   if (p)
441   {
442      UINT32 result = RLONG(m_r[p]);
443      if (i < 6)
444         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
445      else
446         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
447      return dsp_to_double(result);
448   }
449   else if (i < 4)
450      return multiplier ? DEFERRED_MULTIPLIER(i) : m_a[i];
451   else
452      return dau_read_pi_special(i);
453}
454
455
456inline double dsp32c_device::dau_read_pi_double_2nd(int pi, int multiplier, double xval)
457{
458   int p = (pi >> 3) & 15;
459   int i = (pi >> 0) & 7;
460
461   if (p == 15) p = m_lastp;       // P=15 means Z inherits from Y, Y inherits from X
462   m_lastp = p;
463   if (p)
464   {
465      UINT32 result;
466      result = RLONG(m_r[p]);
467      if (i < 6)
468         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
469      else
470         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
471      return dsp_to_double(result);
472   }
473   else if (i < 4)
474      return multiplier ? DEFERRED_MULTIPLIER(i) : m_a[i];
475   else
476      return dau_read_pi_special(i);
477}
478
479
480inline UINT32 dsp32c_device::dau_read_pi_4bytes(int pi)
481{
482   int p = (pi >> 3) & 15;
483   int i = (pi >> 0) & 7;
484
485   m_lastp = p;
486   if (p)
487   {
488      UINT32 result = RLONG(m_r[p]);
489      if (i < 6)
490         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
491      else
492         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
493      return result;
494   }
495   else if (i < 4)
496      return double_to_dsp(m_a[i]);
497   else
498      return dau_read_pi_special(i);
499}
500
501
502inline UINT16 dsp32c_device::dau_read_pi_2bytes(int pi)
503{
504   int p = (pi >> 3) & 15;
505   int i = (pi >> 0) & 7;
506
507   m_lastp = p;
508   if (p)
509   {
510      UINT32 result = RWORD(m_r[p]);
511      if (i < 6)
512         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
513      else
514         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 2);
515      return result;
516   }
517   else if (i < 4)
518      return double_to_dsp(m_a[i]);
519   else
520      return dau_read_pi_special(i);
521}
522
523
524inline void dsp32c_device::dau_write_pi_double(int pi, double val)
525{
526   int p = (pi >> 3) & 15;
527   int i = (pi >> 0) & 7;
528
529   if (p == 15) p = m_lastp;       // P=15 means Z inherits from Y, Y inherits from X
530   if (p)
531   {
532      WLONG_DEFERRED(m_r[p], double_to_dsp(val));
533      if (i < 6)
534         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
535      else
536         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
537   }
538   else if (i < 4)
539      dau_set_val_noflags(i, val);
540   else
541      dau_write_pi_special(i, val);
542}
543
544
545inline void dsp32c_device::dau_write_pi_4bytes(int pi, UINT32 val)
546{
547   int p = (pi >> 3) & 15;
548   int i = (pi >> 0) & 7;
549
550   if (p == 15) p = m_lastp;       // P=15 means Z inherits from Y, Y inherits from X
551   if (p)
552   {
553      m_lastp = p;
554      WLONG_DEFERRED(m_r[p], val);
555      if (i < 6)
556         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
557      else
558         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
559   }
560   else if (i < 4)
561      dau_set_val_noflags(i, dsp_to_double(val));
562   else
563      dau_write_pi_special(i, val);
564}
565
566
567inline void dsp32c_device::dau_write_pi_2bytes(int pi, UINT16 val)
568{
569   int p = (pi >> 3) & 15;
570   int i = (pi >> 0) & 7;
571
572   if (p == 15) p = m_lastp;       // P=15 means Z inherits from Y, Y inherits from X
573   if (p)
574   {
575      m_lastp = p;
576      WWORD_DEFERRED(m_r[p], val);
577      if (i < 6)
578         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
579      else
580         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 2);
581   }
582   else if (i < 4)
583      dau_set_val_noflags(i, dsp_to_double(val << 16));
584   else
585      dau_write_pi_special(i, val);
586}
587
588
589
590//**************************************************************************
591//  COMMON CONDITION ROUTINE
592//**************************************************************************
593
594#if (!ASSUME_UNCONDITIONAL_CAU)
595int dsp32c_device::condition(int cond)
596{
597   switch (cond)
598   {
599      case 0:
600         return 0;
601      case 1:
602         return 1;
603      case 2:
604         return !nFLAG;
605      case 3:
606         return nFLAG;
607      case 4:
608         return !zFLAG;
609      case 5:
610         return zFLAG;
611      case 6:
612         return !vFLAG;
613      case 7:
614         return vFLAG;
615      case 8:
616         return !cFLAG;
617      case 9:
618         return cFLAG;
619      case 10:
620         return !(nFLAG ^ cFLAG);
621      case 11:
622         return (nFLAG ^ cFLAG);
623      case 12:
624         return !(zFLAG | (nFLAG ^ vFLAG));
625      case 13:
626         return (zFLAG | (nFLAG ^ vFLAG));
627      case 14:
628         return !(cFLAG | zFLAG);
629      case 15:
630         return (cFLAG | zFLAG);
631
632      case 16:
633         return !(DEFERRED_VUFLAGS() & UFLAGBIT);
634      case 17:
635         return (DEFERRED_VUFLAGS() & UFLAGBIT);
636      case 18:
637         return !(DEFERRED_NZFLAGS() < 0);
638      case 19:
639         return (DEFERRED_NZFLAGS() < 0);
640      case 20:
641         return !(DEFERRED_NZFLAGS() == 0);
642      case 21:
643         return (DEFERRED_NZFLAGS() == 0);
644      case 22:
645         return !(DEFERRED_VUFLAGS() & VFLAGBIT);
646      case 23:
647         return (DEFERRED_VUFLAGS() & VFLAGBIT);
648      case 24:
649         return !(DEFERRED_NZFLAGS() <= 0);
650      case 25:
651         return (DEFERRED_NZFLAGS() <= 0);
652
653      case 32:    // !ibf
654      case 33:    // ibf
655      case 34:    // !obe
656      case 35:    // obe
657      case 36:    // !pdf
658      case 37:    // pdf
659      case 38:    // !pif
660      case 39:    // pif
661      case 40:    // !sy
662      case 41:    // sy
663      case 42:    // !fb
664      case 43:    // fb
665      case 44:    // !ireq1
666      case 45:    // ireq1
667      case 46:    // !ireq2
668      case 47:    // ireq2
669      default:
670         fatalerror("Unimplemented condition: %X\n", cond);
671   }
672}
673#endif
674
675
676
677//**************************************************************************
678//  CAU BRANCH INSTRUCTION IMPLEMENTATION
679//**************************************************************************
680
681void dsp32c_device::nop(UINT32 op)
682{
683   if (op == 0)
684      return;
685   execute_one();
686   PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
687}
688
689
690void dsp32c_device::goto_t(UINT32 op)
691{
692   execute_one();
693   PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
694}
695
696
697void dsp32c_device::goto_pl(UINT32 op)
698{
699   if (!nFLAG)
700   {
701      execute_one();
702      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
703   }
704}
705
706
707void dsp32c_device::goto_mi(UINT32 op)
708{
709   if (nFLAG)
710   {
711      execute_one();
712      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
713   }
714}
715
716
717void dsp32c_device::goto_ne(UINT32 op)
718{
719   if (!zFLAG)
720   {
721      execute_one();
722      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
723   }
724}
725
726
727void dsp32c_device::goto_eq(UINT32 op)
728{
729   if (zFLAG)
730   {
731      execute_one();
732      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
733   }
734}
735
736
737void dsp32c_device::goto_vc(UINT32 op)
738{
739   if (!vFLAG)
740   {
741      execute_one();
742      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
743   }
744}
745
746
747void dsp32c_device::goto_vs(UINT32 op)
748{
749   if (vFLAG)
750   {
751      execute_one();
752      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
753   }
754}
755
756
757void dsp32c_device::goto_cc(UINT32 op)
758{
759   if (!cFLAG)
760   {
761      execute_one();
762      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
763   }
764}
765
766
767void dsp32c_device::goto_cs(UINT32 op)
768{
769   if (cFLAG)
770   {
771      execute_one();
772      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
773   }
774}
775
776
777void dsp32c_device::goto_ge(UINT32 op)
778{
779   if (!(nFLAG ^ vFLAG))
780   {
781      execute_one();
782      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
783   }
784}
785
786
787void dsp32c_device::goto_lt(UINT32 op)
788{
789   if (nFLAG ^ vFLAG)
790   {
791      execute_one();
792      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
793   }
794}
795
796
797void dsp32c_device::goto_gt(UINT32 op)
798{
799   if (!(zFLAG | (nFLAG ^ vFLAG)))
800   {
801      execute_one();
802      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
803   }
804}
805
806
807void dsp32c_device::goto_le(UINT32 op)
808{
809   if (zFLAG | (nFLAG ^ vFLAG))
810   {
811      execute_one();
812      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
813   }
814}
815
816
817void dsp32c_device::goto_hi(UINT32 op)
818{
819   if (!cFLAG && !zFLAG)
820   {
821      execute_one();
822      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
823   }
824}
825
826
827void dsp32c_device::goto_ls(UINT32 op)
828{
829   if (cFLAG || zFLAG)
830   {
831      execute_one();
832      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
833   }
834}
835
836
837void dsp32c_device::goto_auc(UINT32 op)
838{
839   if (!(DEFERRED_VUFLAGS() & UFLAGBIT))
840   {
841      execute_one();
842      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
843   }
844}
845
846
847void dsp32c_device::goto_aus(UINT32 op)
848{
849   if (DEFERRED_VUFLAGS() & UFLAGBIT)
850   {
851      execute_one();
852      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
853   }
854}
855
856
857void dsp32c_device::goto_age(UINT32 op)
858{
859   if (DEFERRED_NZFLAGS() >= 0)
860   {
861      execute_one();
862      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
863   }
864}
865
866
867void dsp32c_device::goto_alt(UINT32 op)
868{
869   if (DEFERRED_NZFLAGS() < 0)
870   {
871      execute_one();
872      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
873   }
874}
875
876
877void dsp32c_device::goto_ane(UINT32 op)
878{
879   if (DEFERRED_NZFLAGS() != 0)
880   {
881      execute_one();
882      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
883   }
884}
885
886
887void dsp32c_device::goto_aeq(UINT32 op)
888{
889   if (DEFERRED_NZFLAGS() == 0)
890   {
891      execute_one();
892      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
893   }
894}
895
896
897void dsp32c_device::goto_avc(UINT32 op)
898{
899   if (!(DEFERRED_VUFLAGS() & VFLAGBIT))
900   {
901      execute_one();
902      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
903   }
904}
905
906
907void dsp32c_device::goto_avs(UINT32 op)
908{
909   if (DEFERRED_VUFLAGS() & VFLAGBIT)
910   {
911      execute_one();
912      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
913   }
914}
915
916
917void dsp32c_device::goto_agt(UINT32 op)
918{
919   if (DEFERRED_NZFLAGS() > 0)
920   {
921      execute_one();
922      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
923   }
924}
925
926
927void dsp32c_device::goto_ale(UINT32 op)
928{
929   if (DEFERRED_NZFLAGS() <= 0)
930   {
931      execute_one();
932      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
933   }
934}
935
936
937void dsp32c_device::goto_ibe(UINT32 op)
938{
939   unimplemented(op);
940}
941
942
943void dsp32c_device::goto_ibf(UINT32 op)
944{
945   unimplemented(op);
946}
947
948
949void dsp32c_device::goto_obf(UINT32 op)
950{
951   unimplemented(op);
952}
953
954
955void dsp32c_device::goto_obe(UINT32 op)
956{
957   unimplemented(op);
958}
959
960
961void dsp32c_device::goto_pde(UINT32 op)
962{
963   if (!(m_pcr & PCR_PDFs))
964   {
965      execute_one();
966      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
967   }
968}
969
970
971void dsp32c_device::goto_pdf(UINT32 op)
972{
973   if (m_pcr & PCR_PDFs)
974   {
975      execute_one();
976      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
977   }
978}
979
980
981void dsp32c_device::goto_pie(UINT32 op)
982{
983   if (!(m_pcr & PCR_PIFs))
984   {
985      execute_one();
986      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
987   }
988}
989
990
991void dsp32c_device::goto_pif(UINT32 op)
992{
993   if (m_pcr & PCR_PIFs)
994   {
995      execute_one();
996      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
997   }
998}
999
1000
1001void dsp32c_device::goto_syc(UINT32 op)
1002{
1003   unimplemented(op);
1004}
1005
1006
1007void dsp32c_device::goto_sys(UINT32 op)
1008{
1009   unimplemented(op);
1010}
1011
1012
1013void dsp32c_device::goto_fbc(UINT32 op)
1014{
1015   unimplemented(op);
1016}
1017
1018
1019void dsp32c_device::goto_fbs(UINT32 op)
1020{
1021   unimplemented(op);
1022}
1023
1024
1025void dsp32c_device::goto_irq1lo(UINT32 op)
1026{
1027   unimplemented(op);
1028}
1029
1030
1031void dsp32c_device::goto_irq1hi(UINT32 op)
1032{
1033   unimplemented(op);
1034}
1035
1036
1037void dsp32c_device::goto_irq2lo(UINT32 op)
1038{
1039   unimplemented(op);
1040}
1041
1042
1043void dsp32c_device::goto_irq2hi(UINT32 op)
1044{
1045   unimplemented(op);
1046}
1047
1048
1049void dsp32c_device::dec_goto(UINT32 op)
1050{
1051   int hr = (op >> 21) & 0x1f;
1052   int old = (INT16)m_r[hr];
1053   m_r[hr] = EXTEND16_TO_24(m_r[hr] - 1);
1054   if (old >= 0)
1055   {
1056      execute_one();
1057      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
1058   }
1059}
1060
1061
1062void dsp32c_device::call(UINT32 op)
1063{
1064   int mr = (op >> 21) & 0x1f;
1065   if (IS_WRITEABLE(mr))
1066      m_r[mr] = PC + 4;
1067   execute_one();
1068   PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
1069}
1070
1071
1072void dsp32c_device::goto24(UINT32 op)
1073{
1074   execute_one();
1075   PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (op & 0xffff) + ((op >> 5) & 0xff0000));
1076}
1077
1078
1079void dsp32c_device::call24(UINT32 op)
1080{
1081   int mr = (op >> 16) & 0x1f;
1082   if (IS_WRITEABLE(mr))
1083      m_r[mr] = PC + 4;
1084   execute_one();
1085   PC = (op & 0xffff) + ((op >> 5) & 0xff0000);
1086}
1087
1088
1089void dsp32c_device::do_i(UINT32 op)
1090{
1091   unimplemented(op);
1092}
1093
1094
1095void dsp32c_device::do_r(UINT32 op)
1096{
1097   unimplemented(op);
1098}
1099
1100
1101
1102//**************************************************************************
1103//  CAU 16-BIT ARITHMETIC IMPLEMENTATION
1104//**************************************************************************
1105
1106void dsp32c_device::add_si(UINT32 op)
1107{
1108   int dr = (op >> 21) & 0x1f;
1109   int hrval = REG16((op >> 16) & 0x1f);
1110   int res = hrval + (UINT16)op;
1111   if (IS_WRITEABLE(dr))
1112      m_r[dr] = EXTEND16_TO_24(res);
1113   SET_NZCV_16(hrval, op, res);
1114}
1115
1116
1117void dsp32c_device::add_ss(UINT32 op)
1118{
1119   if (CONDITION_IS_TRUE())
1120   {
1121      int dr = (op >> 16) & 0x1f;
1122      int s1rval = REG16((op >> 5) & 0x1f);
1123      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1124      int res = s2rval + s1rval;
1125      if (IS_WRITEABLE(dr))
1126         m_r[dr] = EXTEND16_TO_24(res);
1127      SET_NZCV_16(s1rval, s2rval, res);
1128   }
1129}
1130
1131
1132void dsp32c_device::mul2_s(UINT32 op)
1133{
1134   if (CONDITION_IS_TRUE())
1135   {
1136      int dr = (op >> 16) & 0x1f;
1137      int s1rval = REG16((op >> 5) & 0x1f);
1138      int res = s1rval * 2;
1139      if (IS_WRITEABLE(dr))
1140         m_r[dr] = EXTEND16_TO_24(res);
1141      SET_NZCV_16(s1rval, 0, res);
1142   }
1143}
1144
1145
1146void dsp32c_device::subr_ss(UINT32 op)
1147{
1148   if (CONDITION_IS_TRUE())
1149   {
1150      int dr = (op >> 16) & 0x1f;
1151      int s1rval = REG16((op >> 5) & 0x1f);
1152      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1153      int res = s1rval - s2rval;
1154      if (IS_WRITEABLE(dr))
1155         m_r[dr] = EXTEND16_TO_24(res);
1156      SET_NZCV_16(s1rval, s2rval, res);
1157   }
1158}
1159
1160
1161void dsp32c_device::addr_ss(UINT32 op)
1162{
1163   unimplemented(op);
1164}
1165
1166
1167void dsp32c_device::sub_ss(UINT32 op)
1168{
1169   if (CONDITION_IS_TRUE())
1170   {
1171      int dr = (op >> 16) & 0x1f;
1172      int s1rval = REG16((op >> 5) & 0x1f);
1173      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1174      int res = s2rval - s1rval;
1175      if (IS_WRITEABLE(dr))
1176         m_r[dr] = EXTEND16_TO_24(res);
1177      SET_NZCV_16(s1rval, s2rval, res);
1178   }
1179}
1180
1181
1182void dsp32c_device::neg_s(UINT32 op)
1183{
1184   if (CONDITION_IS_TRUE())
1185   {
1186      int dr = (op >> 16) & 0x1f;
1187      int s1rval = REG16((op >> 5) & 0x1f);
1188      int res = -s1rval;
1189      if (IS_WRITEABLE(dr))
1190         m_r[dr] = EXTEND16_TO_24(res);
1191      SET_NZCV_16(s1rval, 0, res);
1192   }
1193}
1194
1195
1196void dsp32c_device::andc_ss(UINT32 op)
1197{
1198   if (CONDITION_IS_TRUE())
1199   {
1200      int dr = (op >> 16) & 0x1f;
1201      int s1rval = REG16((op >> 5) & 0x1f);
1202      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1203      int res = s2rval & ~s1rval;
1204      if (IS_WRITEABLE(dr))
1205         m_r[dr] = EXTEND16_TO_24(res);
1206      SET_NZ00_16(res);
1207   }
1208}
1209
1210
1211void dsp32c_device::cmp_ss(UINT32 op)
1212{
1213   if (CONDITION_IS_TRUE())
1214   {
1215      int drval = REG16((op >> 16) & 0x1f);
1216      int s1rval = REG16((op >> 5) & 0x1f);
1217      int res = drval - s1rval;
1218      SET_NZCV_16(drval, s1rval, res);
1219   }
1220}
1221
1222
1223void dsp32c_device::xor_ss(UINT32 op)
1224{
1225   if (CONDITION_IS_TRUE())
1226   {
1227      int dr = (op >> 16) & 0x1f;
1228      int s1rval = REG16((op >> 5) & 0x1f);
1229      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1230      int res = s2rval ^ s1rval;
1231      if (IS_WRITEABLE(dr))
1232         m_r[dr] = EXTEND16_TO_24(res);
1233      SET_NZ00_16(res);
1234   }
1235}
1236
1237
1238void dsp32c_device::rcr_s(UINT32 op)
1239{
1240   if (CONDITION_IS_TRUE())
1241   {
1242      int dr = (op >> 16) & 0x1f;
1243      int s1rval = REG16((op >> 5) & 0x1f);
1244      int res = ((m_nzcflags >> 9) & 0x8000) | (s1rval >> 1);
1245      if (IS_WRITEABLE(dr))
1246         m_r[dr] = EXTEND16_TO_24(res);
1247      m_nzcflags = ((res & 0xffff) << 8) | ((s1rval & 1) << 24);
1248      m_vflags = 0;
1249   }
1250}
1251
1252
1253void dsp32c_device::or_ss(UINT32 op)
1254{
1255   if (CONDITION_IS_TRUE())
1256   {
1257      int dr = (op >> 16) & 0x1f;
1258      int s1rval = REG16((op >> 5) & 0x1f);
1259      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1260      int res = s2rval | s1rval;
1261      if (IS_WRITEABLE(dr))
1262         m_r[dr] = EXTEND16_TO_24(res);
1263      SET_NZ00_16(res);
1264   }
1265}
1266
1267
1268void dsp32c_device::rcl_s(UINT32 op)
1269{
1270   if (CONDITION_IS_TRUE())
1271   {
1272      int dr = (op >> 16) & 0x1f;
1273      int s1rval = REG16((op >> 5) & 0x1f);
1274      int res = ((m_nzcflags >> 24) & 0x0001) | (s1rval << 1);
1275      if (IS_WRITEABLE(dr))
1276         m_r[dr] = EXTEND16_TO_24(res);
1277      m_nzcflags = ((res & 0xffff) << 8) | ((s1rval & 0x8000) << 9);
1278      m_vflags = 0;
1279   }
1280}
1281
1282
1283void dsp32c_device::shr_s(UINT32 op)
1284{
1285   if (CONDITION_IS_TRUE())
1286   {
1287      int dr = (op >> 16) & 0x1f;
1288      int s1rval = REG16((op >> 5) & 0x1f);
1289      int res = s1rval >> 1;
1290      if (IS_WRITEABLE(dr))
1291         m_r[dr] = EXTEND16_TO_24(res);
1292      m_nzcflags = ((res & 0xffff) << 8) | ((s1rval & 1) << 24);
1293      m_vflags = 0;
1294   }
1295}
1296
1297
1298void dsp32c_device::div2_s(UINT32 op)
1299{
1300   if (CONDITION_IS_TRUE())
1301   {
1302      int dr = (op >> 16) & 0x1f;
1303      int s1rval = REG16((op >> 5) & 0x1f);
1304      int res = (s1rval & 0x8000) | (s1rval >> 1);
1305      if (IS_WRITEABLE(dr))
1306         m_r[dr] = EXTEND16_TO_24(res);
1307      m_nzcflags = ((res & 0xffff) << 8) | ((s1rval & 1) << 24);
1308      m_vflags = 0;
1309   }
1310}
1311
1312
1313void dsp32c_device::and_ss(UINT32 op)
1314{
1315   if (CONDITION_IS_TRUE())
1316   {
1317      int dr = (op >> 16) & 0x1f;
1318      int s1rval = REG16((op >> 5) & 0x1f);
1319      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1320      int res = s2rval & s1rval;
1321      if (IS_WRITEABLE(dr))
1322         m_r[dr] = EXTEND16_TO_24(res);
1323      SET_NZ00_16(res);
1324   }
1325}
1326
1327
1328void dsp32c_device::test_ss(UINT32 op)
1329{
1330   if (CONDITION_IS_TRUE())
1331   {
1332      int drval = REG16((op >> 16) & 0x1f);
1333      int s1rval = REG16((op >> 5) & 0x1f);
1334      int res = drval & s1rval;
1335      SET_NZ00_16(res);
1336   }
1337}
1338
1339
1340void dsp32c_device::add_di(UINT32 op)
1341{
1342   int dr = (op >> 16) & 0x1f;
1343   int drval = REG16(dr);
1344   int res = drval + (UINT16)op;
1345   if (IS_WRITEABLE(dr))
1346      m_r[dr] = EXTEND16_TO_24(res);
1347   SET_NZCV_16(drval, op, res);
1348}
1349
1350
1351void dsp32c_device::subr_di(UINT32 op)
1352{
1353   int dr = (op >> 16) & 0x1f;
1354   int drval = REG16(dr);
1355   int res = (UINT16)op - drval;
1356   if (IS_WRITEABLE(dr))
1357      m_r[dr] = EXTEND16_TO_24(res);
1358   SET_NZCV_16(drval, op, res);
1359}
1360
1361
1362void dsp32c_device::addr_di(UINT32 op)
1363{
1364   unimplemented(op);
1365}
1366
1367
1368void dsp32c_device::sub_di(UINT32 op)
1369{
1370   int dr = (op >> 16) & 0x1f;
1371   int drval = REG16(dr);
1372   int res = drval - (UINT16)op;
1373   if (IS_WRITEABLE(dr))
1374      m_r[dr] = EXTEND16_TO_24(res);
1375   SET_NZCV_16(drval, op, res);
1376}
1377
1378
1379void dsp32c_device::andc_di(UINT32 op)
1380{
1381   int dr = (op >> 16) & 0x1f;
1382   int drval = REG16(dr);
1383   int res = drval & ~(UINT16)op;
1384   if (IS_WRITEABLE(dr))
1385      m_r[dr] = EXTEND16_TO_24(res);
1386   SET_NZ00_16(res);
1387}
1388
1389
1390void dsp32c_device::cmp_di(UINT32 op)
1391{
1392   int drval = REG16((op >> 16) & 0x1f);
1393   int res = drval - (UINT16)op;
1394   SET_NZCV_16(drval, op, res);
1395}
1396
1397
1398void dsp32c_device::xor_di(UINT32 op)
1399{
1400   int dr = (op >> 16) & 0x1f;
1401   int drval = REG16(dr);
1402   int res = drval ^ (UINT16)op;
1403   if (IS_WRITEABLE(dr))
1404      m_r[dr] = EXTEND16_TO_24(res);
1405   SET_NZ00_16(res);
1406}
1407
1408
1409void dsp32c_device::or_di(UINT32 op)
1410{
1411   int dr = (op >> 16) & 0x1f;
1412   int drval = REG16(dr);
1413   int res = drval | (UINT16)op;
1414   if (IS_WRITEABLE(dr))
1415      m_r[dr] = EXTEND16_TO_24(res);
1416   SET_NZ00_16(res);
1417}
1418
1419
1420void dsp32c_device::and_di(UINT32 op)
1421{
1422   int dr = (op >> 16) & 0x1f;
1423   int drval = REG16(dr);
1424   int res = drval & (UINT16)op;
1425   if (IS_WRITEABLE(dr))
1426      m_r[dr] = EXTEND16_TO_24(res);
1427   SET_NZ00_16(res);
1428}
1429
1430
1431void dsp32c_device::test_di(UINT32 op)
1432{
1433   int drval = REG16((op >> 16) & 0x1f);
1434   int res = drval & (UINT16)op;
1435   SET_NZ00_16(res);
1436}
1437
1438
1439
1440//**************************************************************************
1441//  CAU 24-BIT ARITHMETIC IMPLEMENTATION
1442//**************************************************************************
1443
1444void dsp32c_device::adde_si(UINT32 op)
1445{
1446   int dr = (op >> 21) & 0x1f;
1447   int hrval = REG24((op >> 16) & 0x1f);
1448   int res = hrval + EXTEND16_TO_24(op);
1449   if (IS_WRITEABLE(dr))
1450      m_r[dr] = TRUNCATE24(res);
1451   SET_NZCV_24(hrval, op << 8, res);
1452}
1453
1454
1455void dsp32c_device::adde_ss(UINT32 op)
1456{
1457   if (CONDITION_IS_TRUE())
1458   {
1459      int dr = (op >> 16) & 0x1f;
1460      int s1rval = REG24((op >> 5) & 0x1f);
1461      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1462      int res = s2rval + s1rval;
1463      if (IS_WRITEABLE(dr))
1464         m_r[dr] = TRUNCATE24(res);
1465      SET_NZCV_24(s1rval, s2rval, res);
1466   }
1467}
1468
1469
1470void dsp32c_device::mul2e_s(UINT32 op)
1471{
1472   if (CONDITION_IS_TRUE())
1473   {
1474      int dr = (op >> 16) & 0x1f;
1475      int s1rval = REG24((op >> 5) & 0x1f);
1476      int res = s1rval * 2;
1477      if (IS_WRITEABLE(dr))
1478         m_r[dr] = TRUNCATE24(res);
1479      SET_NZCV_24(s1rval, 0, res);
1480   }
1481}
1482
1483
1484void dsp32c_device::subre_ss(UINT32 op)
1485{
1486   if (CONDITION_IS_TRUE())
1487   {
1488      int dr = (op >> 16) & 0x1f;
1489      int s1rval = REG24((op >> 5) & 0x1f);
1490      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1491      int res = s1rval - s2rval;
1492      if (IS_WRITEABLE(dr))
1493         m_r[dr] = TRUNCATE24(res);
1494      SET_NZCV_24(s1rval, s2rval, res);
1495   }
1496}
1497
1498
1499void dsp32c_device::addre_ss(UINT32 op)
1500{
1501   unimplemented(op);
1502}
1503
1504
1505void dsp32c_device::sube_ss(UINT32 op)
1506{
1507   if (CONDITION_IS_TRUE())
1508   {
1509      int dr = (op >> 16) & 0x1f;
1510      int s1rval = REG24((op >> 5) & 0x1f);
1511      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1512      int res = s2rval - s1rval;
1513      if (IS_WRITEABLE(dr))
1514         m_r[dr] = TRUNCATE24(res);
1515      SET_NZCV_24(s1rval, s2rval, res);
1516   }
1517}
1518
1519
1520void dsp32c_device::nege_s(UINT32 op)
1521{
1522   if (CONDITION_IS_TRUE())
1523   {
1524      int dr = (op >> 16) & 0x1f;
1525      int s1rval = REG24((op >> 5) & 0x1f);
1526      int res = -s1rval;
1527      if (IS_WRITEABLE(dr))
1528         m_r[dr] = TRUNCATE24(res);
1529      SET_NZCV_24(s1rval, 0, res);
1530   }
1531}
1532
1533
1534void dsp32c_device::andce_ss(UINT32 op)
1535{
1536   if (CONDITION_IS_TRUE())
1537   {
1538      int dr = (op >> 16) & 0x1f;
1539      int s1rval = REG24((op >> 5) & 0x1f);
1540      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1541      int res = s2rval & ~s1rval;
1542      if (IS_WRITEABLE(dr))
1543         m_r[dr] = res;
1544      SET_NZ00_24(res);
1545   }
1546}
1547
1548
1549void dsp32c_device::cmpe_ss(UINT32 op)
1550{
1551   if (CONDITION_IS_TRUE())
1552   {
1553      int drval = REG24((op >> 16) & 0x1f);
1554      int s1rval = REG24((op >> 5) & 0x1f);
1555      int res = drval - s1rval;
1556      SET_NZCV_24(drval, s1rval, res);
1557   }
1558}
1559
1560
1561void dsp32c_device::xore_ss(UINT32 op)
1562{
1563   if (CONDITION_IS_TRUE())
1564   {
1565      int dr = (op >> 16) & 0x1f;
1566      int s1rval = REG24((op >> 5) & 0x1f);
1567      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1568      int res = s2rval ^ s1rval;
1569      if (IS_WRITEABLE(dr))
1570         m_r[dr] = res;
1571      SET_NZ00_24(res);
1572   }
1573}
1574
1575
1576void dsp32c_device::rcre_s(UINT32 op)
1577{
1578   if (CONDITION_IS_TRUE())
1579   {
1580      int dr = (op >> 16) & 0x1f;
1581      int s1rval = REG24((op >> 5) & 0x1f);
1582      int res = ((m_nzcflags >> 1) & 0x800000) | (s1rval >> 1);
1583      if (IS_WRITEABLE(dr))
1584         m_r[dr] = TRUNCATE24(res);
1585      m_nzcflags = res | ((s1rval & 1) << 24);
1586      m_vflags = 0;
1587   }
1588}
1589
1590
1591void dsp32c_device::ore_ss(UINT32 op)
1592{
1593   if (CONDITION_IS_TRUE())
1594   {
1595      int dr = (op >> 16) & 0x1f;
1596      int s1rval = REG24((op >> 5) & 0x1f);
1597      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1598      int res = s2rval | s1rval;
1599      if (IS_WRITEABLE(dr))
1600         m_r[dr] = res;
1601      SET_NZ00_24(res);
1602   }
1603}
1604
1605
1606void dsp32c_device::rcle_s(UINT32 op)
1607{
1608   if (CONDITION_IS_TRUE())
1609   {
1610      int dr = (op >> 16) & 0x1f;
1611      int s1rval = REG24((op >> 5) & 0x1f);
1612      int res = ((m_nzcflags >> 24) & 0x000001) | (s1rval << 1);
1613      if (IS_WRITEABLE(dr))
1614         m_r[dr] = TRUNCATE24(res);
1615      m_nzcflags = res | ((s1rval & 0x800000) << 1);
1616      m_vflags = 0;
1617   }
1618}
1619
1620
1621void dsp32c_device::shre_s(UINT32 op)
1622{
1623   if (CONDITION_IS_TRUE())
1624   {
1625      int dr = (op >> 16) & 0x1f;
1626      int s1rval = REG24((op >> 5) & 0x1f);
1627      int res = s1rval >> 1;
1628      if (IS_WRITEABLE(dr))
1629         m_r[dr] = res;
1630      m_nzcflags = res | ((s1rval & 1) << 24);
1631      m_vflags = 0;
1632   }
1633}
1634
1635
1636void dsp32c_device::div2e_s(UINT32 op)
1637{
1638   if (CONDITION_IS_TRUE())
1639   {
1640      int dr = (op >> 16) & 0x1f;
1641      int s1rval = REG24((op >> 5) & 0x1f);
1642      int res = (s1rval & 0x800000) | (s1rval >> 1);
1643      if (IS_WRITEABLE(dr))
1644         m_r[dr] = TRUNCATE24(res);
1645      m_nzcflags = res | ((s1rval & 1) << 24);
1646      m_vflags = 0;
1647   }
1648}
1649
1650
1651void dsp32c_device::ande_ss(UINT32 op)
1652{
1653   if (CONDITION_IS_TRUE())
1654   {
1655      int dr = (op >> 16) & 0x1f;
1656      int s1rval = REG24((op >> 5) & 0x1f);
1657      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1658      int res = s2rval & s1rval;
1659      if (IS_WRITEABLE(dr))
1660         m_r[dr] = res;
1661      SET_NZ00_24(res);
1662   }
1663}
1664
1665
1666void dsp32c_device::teste_ss(UINT32 op)
1667{
1668   if (CONDITION_IS_TRUE())
1669   {
1670      int drval = REG24((op >> 16) & 0x1f);
1671      int s1rval = REG24((op >> 5) & 0x1f);
1672      int res = drval & s1rval;
1673      SET_NZ00_24(res);
1674   }
1675}
1676
1677
1678void dsp32c_device::adde_di(UINT32 op)
1679{
1680   int dr = (op >> 16) & 0x1f;
1681   int drval = REG24(dr);
1682   int res = drval + EXTEND16_TO_24(op);
1683   if (IS_WRITEABLE(dr))
1684      m_r[dr] = TRUNCATE24(res);
1685   SET_NZCV_24(drval, op << 8, res);
1686}
1687
1688
1689void dsp32c_device::subre_di(UINT32 op)
1690{
1691   int dr = (op >> 16) & 0x1f;
1692   int drval = REG24(dr);
1693   int res = EXTEND16_TO_24(op) - drval;
1694   if (IS_WRITEABLE(dr))
1695      m_r[dr] = TRUNCATE24(res);
1696   SET_NZCV_24(drval, op << 8, res);
1697}
1698
1699
1700void dsp32c_device::addre_di(UINT32 op)
1701{
1702   unimplemented(op);
1703}
1704
1705
1706void dsp32c_device::sube_di(UINT32 op)
1707{
1708   int dr = (op >> 16) & 0x1f;
1709   int drval = REG24(dr);
1710   int res = drval - EXTEND16_TO_24(op);
1711   if (IS_WRITEABLE(dr))
1712      m_r[dr] = TRUNCATE24(res);
1713   SET_NZCV_24(drval, op << 8, res);
1714}
1715
1716
1717void dsp32c_device::andce_di(UINT32 op)
1718{
1719   int dr = (op >> 16) & 0x1f;
1720   int drval = REG24(dr);
1721   int res = drval & ~EXTEND16_TO_24(op);
1722   if (IS_WRITEABLE(dr))
1723      m_r[dr] = res;
1724   SET_NZ00_24(res);
1725}
1726
1727
1728void dsp32c_device::cmpe_di(UINT32 op)
1729{
1730   int drval = REG24((op >> 16) & 0x1f);
1731   int res = drval - EXTEND16_TO_24(op);
1732   SET_NZCV_24(drval, op << 8, res);
1733}
1734
1735
1736void dsp32c_device::xore_di(UINT32 op)
1737{
1738   int dr = (op >> 16) & 0x1f;
1739   int drval = REG24(dr);
1740   int res = drval ^ EXTEND16_TO_24(op);
1741   if (IS_WRITEABLE(dr))
1742      m_r[dr] = res;
1743   SET_NZ00_24(res);
1744}
1745
1746
1747void dsp32c_device::ore_di(UINT32 op)
1748{
1749   int dr = (op >> 16) & 0x1f;
1750   int drval = REG24(dr);
1751   int res = drval | EXTEND16_TO_24(op);
1752   if (IS_WRITEABLE(dr))
1753      m_r[dr] = res;
1754   SET_NZ00_24(res);
1755}
1756
1757
1758void dsp32c_device::ande_di(UINT32 op)
1759{
1760   int dr = (op >> 16) & 0x1f;
1761   int drval = REG24(dr);
1762   int res = drval & EXTEND16_TO_24(op);
1763   if (IS_WRITEABLE(dr))
1764      m_r[dr] = res;
1765   SET_NZ00_24(res);
1766}
1767
1768
1769void dsp32c_device::teste_di(UINT32 op)
1770{
1771   int drval = REG24((op >> 16) & 0x1f);
1772   int res = drval & EXTEND16_TO_24(op);
1773   SET_NZ00_24(res);
1774}
1775
1776
1777
1778//**************************************************************************
1779//  CAU LOAD/STORE IMPLEMENTATION
1780//**************************************************************************
1781
1782void dsp32c_device::load_hi(UINT32 op)
1783{
1784   int dr = (op >> 16) & 0x1f;
1785   UINT32 res = RBYTE(EXTEND16_TO_24(op));
1786   if (IS_WRITEABLE(dr))
1787      m_r[dr] = EXTEND16_TO_24(res);
1788   m_nzcflags = res << 8;
1789   m_vflags = 0;
1790}
1791
1792
1793void dsp32c_device::load_li(UINT32 op)
1794{
1795   int dr = (op >> 16) & 0x1f;
1796   UINT32 res = RBYTE(EXTEND16_TO_24(op));
1797   if (IS_WRITEABLE(dr))
1798      m_r[dr] = res;
1799   m_nzcflags = res << 8;
1800   m_vflags = 0;
1801}
1802
1803
1804void dsp32c_device::load_i(UINT32 op)
1805{
1806   UINT32 res = RWORD(EXTEND16_TO_24(op));
1807   int dr = (op >> 16) & 0x1f;
1808   if (IS_WRITEABLE(dr))
1809      m_r[dr] = EXTEND16_TO_24(res);
1810   m_nzcflags = res << 8;
1811   m_vflags = 0;
1812}
1813
1814
1815void dsp32c_device::load_ei(UINT32 op)
1816{
1817   UINT32 res = TRUNCATE24(RLONG(EXTEND16_TO_24(op)));
1818   int dr = (op >> 16) & 0x1f;
1819   if (IS_WRITEABLE(dr))
1820      m_r[dr] = res;
1821   m_nzcflags = res;
1822   m_vflags = 0;
1823}
1824
1825
1826void dsp32c_device::store_hi(UINT32 op)
1827{
1828   WBYTE(EXTEND16_TO_24(op), m_r[(op >> 16) & 0x1f] >> 8);
1829}
1830
1831
1832void dsp32c_device::store_li(UINT32 op)
1833{
1834   WBYTE(EXTEND16_TO_24(op), m_r[(op >> 16) & 0x1f]);
1835}
1836
1837
1838void dsp32c_device::store_i(UINT32 op)
1839{
1840   WWORD(EXTEND16_TO_24(op), REG16((op >> 16) & 0x1f));
1841}
1842
1843
1844void dsp32c_device::store_ei(UINT32 op)
1845{
1846   WLONG(EXTEND16_TO_24(op), (INT32)(REG24((op >> 16) & 0x1f) << 8) >> 8);
1847}
1848
1849
1850void dsp32c_device::load_hr(UINT32 op)
1851{
1852   if (!(op & 0x400))
1853   {
1854      int dr = (op >> 16) & 0x1f;
1855      UINT32 res = cau_read_pi_1byte(op) << 8;
1856      if (IS_WRITEABLE(dr))
1857         m_r[dr] = EXTEND16_TO_24(res);
1858      m_nzcflags = res << 8;
1859      m_vflags = 0;
1860   }
1861   else
1862      unimplemented(op);
1863}
1864
1865
1866void dsp32c_device::load_lr(UINT32 op)
1867{
1868   if (!(op & 0x400))
1869   {
1870      int dr = (op >> 16) & 0x1f;
1871      UINT32 res = cau_read_pi_1byte(op);
1872      if (IS_WRITEABLE(dr))
1873         m_r[dr] = res;
1874      m_nzcflags = res << 8;
1875      m_vflags = 0;
1876   }
1877   else
1878      unimplemented(op);
1879}
1880
1881
1882void dsp32c_device::load_r(UINT32 op)
1883{
1884   if (!(op & 0x400))
1885   {
1886      UINT32 res = cau_read_pi_2byte(op);
1887      int dr = (op >> 16) & 0x1f;
1888      if (IS_WRITEABLE(dr))
1889         m_r[dr] = EXTEND16_TO_24(res);
1890      m_nzcflags = res << 8;
1891      m_vflags = 0;
1892   }
1893   else
1894      unimplemented(op);
1895}
1896
1897
1898void dsp32c_device::load_er(UINT32 op)
1899{
1900   if (!(op & 0x400))
1901   {
1902      UINT32 res = TRUNCATE24(cau_read_pi_4byte(op));
1903      int dr = (op >> 16) & 0x1f;
1904      if (IS_WRITEABLE(dr))
1905         m_r[dr] = res;
1906      m_nzcflags = res;
1907      m_vflags = 0;
1908   }
1909   else
1910      unimplemented(op);
1911}
1912
1913
1914void dsp32c_device::store_hr(UINT32 op)
1915{
1916   if (!(op & 0x400))
1917      cau_write_pi_1byte(op, m_r[(op >> 16) & 0x1f] >> 8);
1918   else
1919      unimplemented(op);
1920}
1921
1922
1923void dsp32c_device::store_lr(UINT32 op)
1924{
1925   if (!(op & 0x400))
1926      cau_write_pi_1byte(op, m_r[(op >> 16) & 0x1f]);
1927   else
1928      unimplemented(op);
1929}
1930
1931
1932void dsp32c_device::store_r(UINT32 op)
1933{
1934   if (!(op & 0x400))
1935      cau_write_pi_2byte(op, REG16((op >> 16) & 0x1f));
1936   else
1937      unimplemented(op);
1938}
1939
1940
1941void dsp32c_device::store_er(UINT32 op)
1942{
1943   if (!(op & 0x400))
1944      cau_write_pi_4byte(op, REG24((op >> 16) & 0x1f));
1945   else
1946      unimplemented(op);
1947}
1948
1949
1950void dsp32c_device::load24(UINT32 op)
1951{
1952   int dr = (op >> 16) & 0x1f;
1953   UINT32 res = (op & 0xffff) + ((op >> 5) & 0xff0000);
1954   if (IS_WRITEABLE(dr))
1955      m_r[dr] = res;
1956}
1957
1958
1959
1960//**************************************************************************
1961//  DAU FORM 1 IMPLEMENTATION
1962//**************************************************************************
1963
1964void dsp32c_device::d1_aMpp(UINT32 op)
1965{
1966   double xval = dau_read_pi_double_1st(op >> 14, 1);
1967   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
1968   double res = yval + DEFERRED_MULTIPLIER((op >> 26) & 7) * xval;
1969   int zpi = (op >> 0) & 0x7f;
1970   if (zpi != 7)
1971      dau_write_pi_double(zpi, res);
1972   dau_set_val_flags((op >> 21) & 3, res);
1973}
1974
1975
1976void dsp32c_device::d1_aMpm(UINT32 op)
1977{
1978   double xval = dau_read_pi_double_1st(op >> 14, 1);
1979   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
1980   double res = yval - DEFERRED_MULTIPLIER((op >> 26) & 7) * xval;
1981   int zpi = (op >> 0) & 0x7f;
1982   if (zpi != 7)
1983      dau_write_pi_double(zpi, res);
1984   dau_set_val_flags((op >> 21) & 3, res);
1985}
1986
1987
1988void dsp32c_device::d1_aMmp(UINT32 op)
1989{
1990   double xval = dau_read_pi_double_1st(op >> 14, 1);
1991   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
1992   double res = -yval + DEFERRED_MULTIPLIER((op >> 26) & 7) * xval;
1993   int zpi = (op >> 0) & 0x7f;
1994   if (zpi != 7)
1995      dau_write_pi_double(zpi, res);
1996   dau_set_val_flags((op >> 21) & 3, res);
1997}
1998
1999
2000void dsp32c_device::d1_aMmm(UINT32 op)
2001{
2002   double xval = dau_read_pi_double_1st(op >> 14, 1);
2003   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2004   double res = -yval - DEFERRED_MULTIPLIER((op >> 26) & 7) * xval;
2005   int zpi = (op >> 0) & 0x7f;
2006   if (zpi != 7)
2007      dau_write_pi_double(zpi, res);
2008   dau_set_val_flags((op >> 21) & 3, res);
2009}
2010
2011
2012void dsp32c_device::d1_0px(UINT32 op)
2013{
2014   double xval = dau_read_pi_double_1st(op >> 14, 1);
2015   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2016   double res = yval;
2017   int zpi = (op >> 0) & 0x7f;
2018   if (zpi != 7)
2019      dau_write_pi_double(zpi, res);
2020   dau_set_val_flags((op >> 21) & 3, res);
2021   (void)xval;
2022}
2023
2024
2025void dsp32c_device::d1_0mx(UINT32 op)
2026{
2027   double xval = dau_read_pi_double_1st(op >> 14, 1);
2028   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2029   double res = -yval;
2030   int zpi = (op >> 0) & 0x7f;
2031   if (zpi != 7)
2032      dau_write_pi_double(zpi, res);
2033   dau_set_val_flags((op >> 21) & 3, res);
2034   (void)xval;
2035}
2036
2037
2038void dsp32c_device::d1_1pp(UINT32 op)
2039{
2040   double xval = dau_read_pi_double_1st(op >> 14, 1);
2041   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2042   double res = yval + xval;
2043   int zpi = (op >> 0) & 0x7f;
2044   if (zpi != 7)
2045      dau_write_pi_double(zpi, res);
2046   dau_set_val_flags((op >> 21) & 3, res);
2047}
2048
2049
2050void dsp32c_device::d1_1pm(UINT32 op)
2051{
2052   double xval = dau_read_pi_double_1st(op >> 14, 1);
2053   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2054   double res = yval - xval;
2055   int zpi = (op >> 0) & 0x7f;
2056   if (zpi != 7)
2057      dau_write_pi_double(zpi, res);
2058   dau_set_val_flags((op >> 21) & 3, res);
2059}
2060
2061
2062void dsp32c_device::d1_1mp(UINT32 op)
2063{
2064   double xval = dau_read_pi_double_1st(op >> 14, 1);
2065   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2066   double res = -yval + xval;
2067   int zpi = (op >> 0) & 0x7f;
2068   if (zpi != 7)
2069      dau_write_pi_double(zpi, res);
2070   dau_set_val_flags((op >> 21) & 3, res);
2071}
2072
2073
2074void dsp32c_device::d1_1mm(UINT32 op)
2075{
2076   double xval = dau_read_pi_double_1st(op >> 14, 1);
2077   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2078   double res = -yval - xval;
2079   int zpi = (op >> 0) & 0x7f;
2080   if (zpi != 7)
2081      dau_write_pi_double(zpi, res);
2082   dau_set_val_flags((op >> 21) & 3, res);
2083}
2084
2085
2086void dsp32c_device::d1_aMppr(UINT32 op)
2087{
2088   unimplemented(op);
2089}
2090
2091
2092void dsp32c_device::d1_aMpmr(UINT32 op)
2093{
2094   unimplemented(op);
2095}
2096
2097
2098void dsp32c_device::d1_aMmpr(UINT32 op)
2099{
2100   unimplemented(op);
2101}
2102
2103
2104void dsp32c_device::d1_aMmmr(UINT32 op)
2105{
2106   unimplemented(op);
2107}
2108
2109
2110
2111//**************************************************************************
2112//  DAU FORM 2 IMPLEMENTATION
2113//**************************************************************************
2114
2115void dsp32c_device::d2_aMpp(UINT32 op)
2116{
2117   double xval = dau_read_pi_double_1st(op >> 14, 1);
2118   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2119   double res = m_a[(op >> 26) & 7] + yval * xval;
2120   int zpi = (op >> 0) & 0x7f;
2121   if (zpi != 7)
2122      dau_write_pi_double(zpi, yval);
2123   dau_set_val_flags((op >> 21) & 3, res);
2124}
2125
2126
2127void dsp32c_device::d2_aMpm(UINT32 op)
2128{
2129   double xval = dau_read_pi_double_1st(op >> 14, 1);
2130   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2131   double res = m_a[(op >> 26) & 7] - yval * xval;
2132   int zpi = (op >> 0) & 0x7f;
2133   if (zpi != 7)
2134      dau_write_pi_double(zpi, yval);
2135   dau_set_val_flags((op >> 21) & 3, res);
2136}
2137
2138
2139void dsp32c_device::d2_aMmp(UINT32 op)
2140{
2141   double xval = dau_read_pi_double_1st(op >> 14, 1);
2142   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2143   double res = -m_a[(op >> 26) & 7] + yval * xval;
2144   int zpi = (op >> 0) & 0x7f;
2145   if (zpi != 7)
2146      dau_write_pi_double(zpi, yval);
2147   dau_set_val_flags((op >> 21) & 3, res);
2148}
2149
2150
2151void dsp32c_device::d2_aMmm(UINT32 op)
2152{
2153   double xval = dau_read_pi_double_1st(op >> 14, 1);
2154   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2155   double res = -m_a[(op >> 26) & 7] - yval * xval;
2156   int zpi = (op >> 0) & 0x7f;
2157   if (zpi != 7)
2158      dau_write_pi_double(zpi, yval);
2159   dau_set_val_flags((op >> 21) & 3, res);
2160}
2161
2162
2163void dsp32c_device::d2_aMppr(UINT32 op)
2164{
2165   unimplemented(op);
2166}
2167
2168
2169void dsp32c_device::d2_aMpmr(UINT32 op)
2170{
2171   unimplemented(op);
2172}
2173
2174
2175void dsp32c_device::d2_aMmpr(UINT32 op)
2176{
2177   unimplemented(op);
2178}
2179
2180
2181void dsp32c_device::d2_aMmmr(UINT32 op)
2182{
2183   unimplemented(op);
2184}
2185
2186
2187
2188//**************************************************************************
2189//  DAU FORM 3 IMPLEMENTATION
2190//**************************************************************************
2191
2192void dsp32c_device::d3_aMpp(UINT32 op)
2193{
2194   double xval = dau_read_pi_double_1st(op >> 14, 1);
2195   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2196   double res = m_a[(op >> 26) & 7] + yval * xval;
2197   int zpi = (op >> 0) & 0x7f;
2198   if (zpi != 7)
2199      dau_write_pi_double(zpi, res);
2200   dau_set_val_flags((op >> 21) & 3, res);
2201}
2202
2203
2204void dsp32c_device::d3_aMpm(UINT32 op)
2205{
2206   double xval = dau_read_pi_double_1st(op >> 14, 1);
2207   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2208   double res = m_a[(op >> 26) & 7] - yval * xval;
2209   int zpi = (op >> 0) & 0x7f;
2210   if (zpi != 7)
2211      dau_write_pi_double(zpi, res);
2212   dau_set_val_flags((op >> 21) & 3, res);
2213}
2214
2215
2216void dsp32c_device::d3_aMmp(UINT32 op)
2217{
2218   double xval = dau_read_pi_double_1st(op >> 14, 1);
2219   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2220   double res = -m_a[(op >> 26) & 7] + yval * xval;
2221   int zpi = (op >> 0) & 0x7f;
2222   if (zpi != 7)
2223      dau_write_pi_double(zpi, res);
2224   dau_set_val_flags((op >> 21) & 3, res);
2225}
2226
2227
2228void dsp32c_device::d3_aMmm(UINT32 op)
2229{
2230   double xval = dau_read_pi_double_1st(op >> 14, 1);
2231   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2232   double res = -m_a[(op >> 26) & 7] - yval * xval;
2233   int zpi = (op >> 0) & 0x7f;
2234   if (zpi != 7)
2235      dau_write_pi_double(zpi, res);
2236   dau_set_val_flags((op >> 21) & 3, res);
2237}
2238
2239
2240void dsp32c_device::d3_aMppr(UINT32 op)
2241{
2242   unimplemented(op);
2243}
2244
2245
2246void dsp32c_device::d3_aMpmr(UINT32 op)
2247{
2248   unimplemented(op);
2249}
2250
2251
2252void dsp32c_device::d3_aMmpr(UINT32 op)
2253{
2254   unimplemented(op);
2255}
2256
2257
2258void dsp32c_device::d3_aMmmr(UINT32 op)
2259{
2260   unimplemented(op);
2261}
2262
2263
2264
2265//**************************************************************************
2266//  DAU FORM 4 IMPLEMENTATION
2267//**************************************************************************
2268
2269void dsp32c_device::d4_pp(UINT32 op)
2270{
2271   double xval = dau_read_pi_double_1st(op >> 14, 1);
2272   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2273   double res = yval + xval;
2274   int zpi = (op >> 0) & 0x7f;
2275   if (zpi != 7)
2276      dau_write_pi_double(zpi, yval);
2277   dau_set_val_flags((op >> 21) & 3, res);
2278}
2279
2280
2281void dsp32c_device::d4_pm(UINT32 op)
2282{
2283   double xval = dau_read_pi_double_1st(op >> 14, 1);
2284   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2285   double res = yval - xval;
2286   int zpi = (op >> 0) & 0x7f;
2287   if (zpi != 7)
2288      dau_write_pi_double(zpi, yval);
2289   dau_set_val_flags((op >> 21) & 3, res);
2290}
2291
2292
2293void dsp32c_device::d4_mp(UINT32 op)
2294{
2295   double xval = dau_read_pi_double_1st(op >> 14, 1);
2296   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2297   double res = -yval + xval;
2298   int zpi = (op >> 0) & 0x7f;
2299   if (zpi != 7)
2300      dau_write_pi_double(zpi, yval);
2301   dau_set_val_flags((op >> 21) & 3, res);
2302}
2303
2304
2305void dsp32c_device::d4_mm(UINT32 op)
2306{
2307   double xval = dau_read_pi_double_1st(op >> 14, 1);
2308   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2309   double res = -yval - xval;
2310   int zpi = (op >> 0) & 0x7f;
2311   if (zpi != 7)
2312      dau_write_pi_double(zpi, yval);
2313   dau_set_val_flags((op >> 21) & 3, res);
2314}
2315
2316
2317void dsp32c_device::d4_ppr(UINT32 op)
2318{
2319   unimplemented(op);
2320}
2321
2322
2323void dsp32c_device::d4_pmr(UINT32 op)
2324{
2325   unimplemented(op);
2326}
2327
2328
2329void dsp32c_device::d4_mpr(UINT32 op)
2330{
2331   unimplemented(op);
2332}
2333
2334
2335void dsp32c_device::d4_mmr(UINT32 op)
2336{
2337   unimplemented(op);
2338}
2339
2340
2341
2342//**************************************************************************
2343//  DAU FORM 5 IMPLEMENTATION
2344//**************************************************************************
2345
2346void dsp32c_device::d5_ic(UINT32 op)
2347{
2348   unimplemented(op);
2349}
2350
2351
2352void dsp32c_device::d5_oc(UINT32 op)
2353{
2354   unimplemented(op);
2355}
2356
2357
2358void dsp32c_device::d5_float(UINT32 op)
2359{
2360   double res = (double)(INT16)dau_read_pi_2bytes(op >> 7);
2361   int zpi = (op >> 0) & 0x7f;
2362   if (zpi != 7)
2363      dau_write_pi_double(zpi, res);
2364   dau_set_val_flags((op >> 21) & 3, res);
2365}
2366
2367
2368void dsp32c_device::d5_int(UINT32 op)
2369{
2370   double val = dau_read_pi_double_1st(op >> 7, 0);
2371   int zpi = (op >> 0) & 0x7f;
2372   INT16 res;
2373   if (!(DAUC & 0x10)) val = floor(val + 0.5);
2374   else val = ceil(val - 0.5);
2375   res = (INT16)val;
2376   if (zpi != 7)
2377      dau_write_pi_2bytes(zpi, res);
2378   dau_set_val_noflags((op >> 21) & 3, dsp_to_double(res << 16));
2379}
2380
2381
2382void dsp32c_device::d5_round(UINT32 op)
2383{
2384   double res = (double)(float)dau_read_pi_double_1st(op >> 7, 0);
2385   int zpi = (op >> 0) & 0x7f;
2386   if (zpi != 7)
2387      dau_write_pi_double(zpi, res);
2388   dau_set_val_flags((op >> 21) & 3, res);
2389}
2390
2391
2392void dsp32c_device::d5_ifalt(UINT32 op)
2393{
2394   int ar = (op >> 21) & 3;
2395   double res = m_a[ar];
2396   int zpi = (op >> 0) & 0x7f;
2397   if (NFLAG)
2398      res = dau_read_pi_double_1st(op >> 7, 0);
2399   if (zpi != 7)
2400      dau_write_pi_double(zpi, res);
2401   dau_set_val_noflags(ar, res);
2402}
2403
2404
2405void dsp32c_device::d5_ifaeq(UINT32 op)
2406{
2407   int ar = (op >> 21) & 3;
2408   double res = m_a[ar];
2409   int zpi = (op >> 0) & 0x7f;
2410   if (ZFLAG)
2411      res = dau_read_pi_double_1st(op >> 7, 0);
2412   if (zpi != 7)
2413      dau_write_pi_double(zpi, res);
2414   dau_set_val_noflags(ar, res);
2415}
2416
2417
2418void dsp32c_device::d5_ifagt(UINT32 op)
2419{
2420   int ar = (op >> 21) & 3;
2421   double res = m_a[ar];
2422   int zpi = (op >> 0) & 0x7f;
2423   if (!NFLAG && !ZFLAG)
2424      res = dau_read_pi_double_1st(op >> 7, 0);
2425   if (zpi != 7)
2426      dau_write_pi_double(zpi, res);
2427   dau_set_val_noflags(ar, res);
2428}
2429
2430
2431void dsp32c_device::d5_float24(UINT32 op)
2432{
2433   double res = (double)((INT32)(dau_read_pi_4bytes(op >> 7) << 8) >> 8);
2434   int zpi = (op >> 0) & 0x7f;
2435   if (zpi != 7)
2436      dau_write_pi_double(zpi, res);
2437   dau_set_val_flags((op >> 21) & 3, res);
2438}
2439
2440
2441void dsp32c_device::d5_int24(UINT32 op)
2442{
2443   double val = dau_read_pi_double_1st(op >> 7, 0);
2444   int zpi = (op >> 0) & 0x7f;
2445   INT32 res;
2446   if (!(DAUC & 0x10)) val = floor(val + 0.5);
2447   else val = ceil(val - 0.5);
2448   res = (INT32)val;
2449   if (res > 0x7fffff) res = 0x7fffff;
2450   else if (res < -0x800000) res = -0x800000;
2451   if (zpi != 7)
2452      dau_write_pi_4bytes(zpi, (INT32)(res << 8) >> 8);
2453   dau_set_val_noflags((op >> 21) & 3, dsp_to_double(res << 8));
2454}
2455
2456
2457void dsp32c_device::d5_ieee(UINT32 op)
2458{
2459   unimplemented(op);
2460}
2461
2462
2463void dsp32c_device::d5_dsp(UINT32 op)
2464{
2465   unimplemented(op);
2466}
2467
2468
2469void dsp32c_device::d5_seed(UINT32 op)
2470{
2471   UINT32 val = dau_read_pi_4bytes(op >> 7);
2472   INT32 res = val ^ 0x7fffffff;
2473   int zpi = (op >> 0) & 0x7f;
2474   if (zpi != 7)
2475      dau_write_pi_4bytes(zpi, res);
2476   dau_set_val_flags((op >> 21) & 3, dsp_to_double((INT32)res));
2477}
2478
2479
2480
2481//**************************************************************************
2482//  FUNCTION TABLE
2483//**************************************************************************
2484
2485void (dsp32c_device::*const dsp32c_device::s_dsp32ops[])(UINT32 op) =
2486{
2487   &dsp32c_device::nop,        &dsp32c_device::goto_t,     &dsp32c_device::goto_pl,    &dsp32c_device::goto_mi,    &dsp32c_device::goto_ne,    &dsp32c_device::goto_eq,    &dsp32c_device::goto_vc,    &dsp32c_device::goto_vs,    // 00
2488   &dsp32c_device::goto_cc,    &dsp32c_device::goto_cs,    &dsp32c_device::goto_ge,    &dsp32c_device::goto_lt,    &dsp32c_device::goto_gt,    &dsp32c_device::goto_le,    &dsp32c_device::goto_hi,    &dsp32c_device::goto_ls,
2489   &dsp32c_device::goto_auc,   &dsp32c_device::goto_aus,   &dsp32c_device::goto_age,   &dsp32c_device::goto_alt,   &dsp32c_device::goto_ane,   &dsp32c_device::goto_aeq,   &dsp32c_device::goto_avc,   &dsp32c_device::goto_avs,   // 01
2490   &dsp32c_device::goto_agt,   &dsp32c_device::goto_ale,   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2491   &dsp32c_device::goto_ibe,   &dsp32c_device::goto_ibf,   &dsp32c_device::goto_obf,   &dsp32c_device::goto_obe,   &dsp32c_device::goto_pde,   &dsp32c_device::goto_pdf,   &dsp32c_device::goto_pie,   &dsp32c_device::goto_pif,   // 02
2492   &dsp32c_device::goto_syc,   &dsp32c_device::goto_sys,   &dsp32c_device::goto_fbc,   &dsp32c_device::goto_fbs,   &dsp32c_device::goto_irq1lo,&dsp32c_device::goto_irq1hi,&dsp32c_device::goto_irq2lo,&dsp32c_device::goto_irq2hi,
2493   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 03
2494   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2495
2496   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 04
2497   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2498   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 05
2499   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2500   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   // 06
2501   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,
2502   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   // 07
2503   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,
2504
2505   &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       // 08
2506   &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,
2507   &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       // 09
2508   &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,
2509   &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     // 0a
2510   &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,
2511   &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     // 0b
2512   &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,
2513
2514   &dsp32c_device::add_ss,     &dsp32c_device::mul2_s,     &dsp32c_device::subr_ss,    &dsp32c_device::addr_ss,    &dsp32c_device::sub_ss,     &dsp32c_device::neg_s,      &dsp32c_device::andc_ss,    &dsp32c_device::cmp_ss,     // 0c
2515   &dsp32c_device::xor_ss,     &dsp32c_device::rcr_s,      &dsp32c_device::or_ss,      &dsp32c_device::rcl_s,      &dsp32c_device::shr_s,      &dsp32c_device::div2_s,     &dsp32c_device::and_ss,     &dsp32c_device::test_ss,
2516   &dsp32c_device::add_di,     &dsp32c_device::illegal,    &dsp32c_device::subr_di,    &dsp32c_device::addr_di,    &dsp32c_device::sub_di,     &dsp32c_device::illegal,    &dsp32c_device::andc_di,    &dsp32c_device::cmp_di,     // 0d
2517   &dsp32c_device::xor_di,     &dsp32c_device::illegal,    &dsp32c_device::or_di,      &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::and_di,     &dsp32c_device::test_di,
2518   &dsp32c_device::load_hi,    &dsp32c_device::load_hi,    &dsp32c_device::load_li,    &dsp32c_device::load_li,    &dsp32c_device::load_i,     &dsp32c_device::load_i,     &dsp32c_device::load_ei,    &dsp32c_device::load_ei,    // 0e
2519   &dsp32c_device::store_hi,   &dsp32c_device::store_hi,   &dsp32c_device::store_li,   &dsp32c_device::store_li,   &dsp32c_device::store_i,    &dsp32c_device::store_i,    &dsp32c_device::store_ei,   &dsp32c_device::store_ei,
2520   &dsp32c_device::load_hr,    &dsp32c_device::load_hr,    &dsp32c_device::load_lr,    &dsp32c_device::load_lr,    &dsp32c_device::load_r,     &dsp32c_device::load_r,     &dsp32c_device::load_er,    &dsp32c_device::load_er,    // 0f
2521   &dsp32c_device::store_hr,   &dsp32c_device::store_hr,   &dsp32c_device::store_lr,   &dsp32c_device::store_lr,   &dsp32c_device::store_r,    &dsp32c_device::store_r,    &dsp32c_device::store_er,   &dsp32c_device::store_er,
2522
2523   &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    // 10
2524   &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,
2525   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 11
2526   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2527   &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    // 12
2528   &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,
2529   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 13
2530   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2531
2532   &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    // 14
2533   &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,
2534   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 15
2535   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2536   &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    // 16
2537   &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,
2538   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 17
2539   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2540
2541   &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     // 18
2542   &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,
2543   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 19
2544   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2545   &dsp32c_device::d1_1pp,     &dsp32c_device::d1_1pp,     &dsp32c_device::d1_1pp,     &dsp32c_device::d1_1pp,     &dsp32c_device::d1_1pm,     &dsp32c_device::d1_1pm,     &dsp32c_device::d1_1pm,     &dsp32c_device::d1_1pm,     // 1a
2546   &dsp32c_device::d1_1mp,     &dsp32c_device::d1_1mp,     &dsp32c_device::d1_1mp,     &dsp32c_device::d1_1mp,     &dsp32c_device::d1_1mm,     &dsp32c_device::d1_1mm,     &dsp32c_device::d1_1mm,     &dsp32c_device::d1_1mm,
2547   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 1b
2548   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2549
2550   &dsp32c_device::d4_pp,      &dsp32c_device::d4_pp,      &dsp32c_device::d4_pp,      &dsp32c_device::d4_pp,      &dsp32c_device::d4_pm,      &dsp32c_device::d4_pm,      &dsp32c_device::d4_pm,      &dsp32c_device::d4_pm,      // 1c
2551   &dsp32c_device::d4_mp,      &dsp32c_device::d4_mp,      &dsp32c_device::d4_mp,      &dsp32c_device::d4_mp,      &dsp32c_device::d4_mm,      &dsp32c_device::d4_mm,      &dsp32c_device::d4_mm,      &dsp32c_device::d4_mm,
2552   &dsp32c_device::d4_ppr,     &dsp32c_device::d4_ppr,     &dsp32c_device::d4_ppr,     &dsp32c_device::d4_ppr,     &dsp32c_device::d4_pmr,     &dsp32c_device::d4_pmr,     &dsp32c_device::d4_pmr,     &dsp32c_device::d4_pmr,     // 1d
2553   &dsp32c_device::d4_mpr,     &dsp32c_device::d4_mpr,     &dsp32c_device::d4_mpr,     &dsp32c_device::d4_mpr,     &dsp32c_device::d4_mmr,     &dsp32c_device::d4_mmr,     &dsp32c_device::d4_mmr,     &dsp32c_device::d4_mmr,
2554   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 1e
2555   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2556   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 1f
2557   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2558
2559   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 20
2560   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2561   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 21
2562   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2563   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 22
2564   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2565   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 23
2566   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2567
2568   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 24
2569   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2570   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 25
2571   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2572   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 26
2573   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2574   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 27
2575   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2576
2577   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 28
2578   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2579   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 29
2580   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2581   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 2a
2582   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2583   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 2b
2584   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2585
2586   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 2c
2587   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2588   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 2d
2589   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2590   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 2e
2591   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2592   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 2f
2593   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2594
2595   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 30
2596   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2597   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 31
2598   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2599   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 32
2600   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2601   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 33
2602   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2603
2604   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 34
2605   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2606   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 35
2607   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2608   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 36
2609   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2610   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 37
2611   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2612
2613   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 38
2614   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2615   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 39
2616   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2617   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 3a
2618   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2619   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 3b
2620   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2621
2622   &dsp32c_device::d5_ic,      &dsp32c_device::d5_ic,      &dsp32c_device::d5_ic,      &dsp32c_device::d5_ic,      &dsp32c_device::d5_oc,      &dsp32c_device::d5_oc,      &dsp32c_device::d5_oc,      &dsp32c_device::d5_oc,      // 3c
2623   &dsp32c_device::d5_float,   &dsp32c_device::d5_float,   &dsp32c_device::d5_float,   &dsp32c_device::d5_float,   &dsp32c_device::d5_int,     &dsp32c_device::d5_int,     &dsp32c_device::d5_int,     &dsp32c_device::d5_int,
2624   &dsp32c_device::d5_round,   &dsp32c_device::d5_round,   &dsp32c_device::d5_round,   &dsp32c_device::d5_round,   &dsp32c_device::d5_ifalt,   &dsp32c_device::d5_ifalt,   &dsp32c_device::d5_ifalt,   &dsp32c_device::d5_ifalt,   // 3d
2625   &dsp32c_device::d5_ifaeq,   &dsp32c_device::d5_ifaeq,   &dsp32c_device::d5_ifaeq,   &dsp32c_device::d5_ifaeq,   &dsp32c_device::d5_ifagt,   &dsp32c_device::d5_ifagt,   &dsp32c_device::d5_ifagt,   &dsp32c_device::d5_ifagt,
2626   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 3e
2627   &dsp32c_device::d5_float24, &dsp32c_device::d5_float24, &dsp32c_device::d5_float24, &dsp32c_device::d5_float24, &dsp32c_device::d5_int24,   &dsp32c_device::d5_int24,   &dsp32c_device::d5_int24,   &dsp32c_device::d5_int24,
2628   &dsp32c_device::d5_ieee,    &dsp32c_device::d5_ieee,    &dsp32c_device::d5_ieee,    &dsp32c_device::d5_ieee,    &dsp32c_device::d5_dsp,     &dsp32c_device::d5_dsp,     &dsp32c_device::d5_dsp,     &dsp32c_device::d5_dsp,     // 3f
2629   &dsp32c_device::d5_seed,    &dsp32c_device::d5_seed,    &dsp32c_device::d5_seed,    &dsp32c_device::d5_seed,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2630
2631   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 40
2632   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2633   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 41
2634   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2635   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 42
2636   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2637   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 43
2638   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2639
2640   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 44
2641   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2642   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 45
2643   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2644   &dsp32c_device::do_i,       &dsp32c_device::do_r,       &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 46
2645   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2646   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 47
2647   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2648
2649   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 48
2650   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2651   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 49
2652   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2653   &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    // 4a
2654   &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,
2655   &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    // 4b
2656   &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,
2657
2658   &dsp32c_device::adde_ss,    &dsp32c_device::mul2e_s,    &dsp32c_device::subre_ss,   &dsp32c_device::addre_ss,   &dsp32c_device::sube_ss,    &dsp32c_device::nege_s,     &dsp32c_device::andce_ss,   &dsp32c_device::cmpe_ss,    // 4c
2659   &dsp32c_device::xore_ss,    &dsp32c_device::rcre_s,     &dsp32c_device::ore_ss,     &dsp32c_device::rcle_s,     &dsp32c_device::shre_s,     &dsp32c_device::div2e_s,    &dsp32c_device::ande_ss,    &dsp32c_device::teste_ss,
2660   &dsp32c_device::adde_di,    &dsp32c_device::illegal,    &dsp32c_device::subre_di,   &dsp32c_device::addre_di,   &dsp32c_device::sube_di,    &dsp32c_device::illegal,    &dsp32c_device::andce_di,   &dsp32c_device::cmpe_di,    // 4d
2661   &dsp32c_device::xore_di,    &dsp32c_device::illegal,    &dsp32c_device::ore_di,     &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::ande_di,    &dsp32c_device::teste_di,
2662   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 4e
2663   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2664   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 4f
2665   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2666
2667   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 50
2668   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2669   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 51
2670   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2671   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 52
2672   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2673   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 53
2674   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2675
2676   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 54
2677   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2678   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 55
2679   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2680   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 56
2681   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2682   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 57
2683   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2684
2685   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 58
2686   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2687   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 59
2688   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2689   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5a
2690   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2691   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5b
2692   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2693
2694   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5c
2695   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2696   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5d
2697   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2698   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5e
2699   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2700   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5f
2701   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2702
2703   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 60
2704   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2705   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 61
2706   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2707   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 62
2708   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2709   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 63
2710   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2711
2712   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 64
2713   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2714   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 65
2715   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2716   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 66
2717   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2718   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 67
2719   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2720
2721   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 68
2722   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2723   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 69
2724   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2725   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6a
2726   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2727   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6b
2728   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2729
2730   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6c
2731   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2732   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6d
2733   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2734   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6e
2735   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2736   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6f
2737   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2738
2739   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 70
2740   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2741   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 71
2742   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2743   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 72
2744   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2745   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 73
2746   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2747
2748   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 74
2749   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2750   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 75
2751   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2752   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 76
2753   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2754   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 77
2755   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2756
2757   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 78
2758   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2759   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 79
2760   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2761   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7a
2762   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2763   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7b
2764   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2765
2766   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7c
2767   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2768   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7d
2769   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2770   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7e
2771   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2772   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7f
2773   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24
2774};
2775
2776
2777/*
2778
2779    Most common OPs in Race Drivin':
2780
2781301681217 - op   0 - nop
2782164890391 - op 4A1 - adde_si
278399210113 - op 661 - load24
278486010010 - op  F7 - load_er
278561148739 - op 4D4 - sube_di
278652693763 - op 180 - d1_0px
278741525754 - op  FF - store_er
278835033321 - op 380 - d3_aMpp
278931621151 - op 4C0 - adde_ss
279028076244 - op 660 - load24
279119190505 - op 4C1 - mul2e_s
279213270852 - op  F5 - load_r
279312535169 - op 1A4 - d1_1pm
279412265141 - op 4C4 - sube_ss
279510748211 - op 4CD - div2e_s
279610493660 - op  FD - store_r
2797 9721263 - op 189
2798 9415685 - op 3C8
2799 9294148 - op 3D5
2800 8887846 - op 1A1
2801 8788648 - op 381
2802 8185239 - op 300
2803 7241256 - op 383
2804 6877349 - op 4A3
2805 6832295 - op 181
2806 6601270 - op 3E8
2807 6562483 - op 4A4
2808 6553514 - op 3C9
2809 6270430 - op 280
2810 6041485 - op 1A0
2811 5299529 - op 304
2812 5110926 - op 382
2813 4922253 - op 363
2814 4603670 - op 4D7
2815 4164327 - op 4AE
2816 3980085 - op 3EC
2817 3599198 - op 3CC
2818 3543878 - op 3D0
2819 3489158 - op   4
2820 3463235 - op 321
2821 3335995 - op 3F9
2822 3001546 - op 4CE
2823 2882940 - op 129
2824 2882940 - op 1A5
2825 2882940 - op 342
2826 2841981 - op 360
2827 2663417 - op  FB
2828 2059640 - op 3ED
2829 1867166 - op 1A8
2830 1830789 - op 305
2831 1753312 - op 301
2832 1726866 - op   5
2833 1594991 - op  12
2834 1571286 - op  19
2835 1507644 - op  A2
2836 1418846 - op 3CD
2837 1273134 - op  F3
2838 1177914 - op 4C7
2839 1175720 - op 188
2840 1091848 - op 3E9
2841 1088206 - op 6FF
2842 1088204 - op 4CA
2843 1012639 - op 101
2844  939617 - op 4C5
2845
2846*/
trunk/src/emu/cpu/dsp32/dsp32ops.inc
r0r28739
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3/***************************************************************************
4
5    dsp32ops.inc
6    Core implementation for the portable DSP32 emulator.
7
8****************************************************************************/
9
10
11
12//**************************************************************************
13//  COMPILE-TIME OPTIONS
14//**************************************************************************
15
16// these defined latencies are a pain to implement, but are necessary
17#define EMULATE_MEMORY_LATENCY      (1)
18#define EMULATE_MULTIPLIER_LATENCY  (1)
19#define EMULATE_AFLAGS_LATENCY      (1)
20
21// these optimizations should have some effect, but they don't really, so
22// leave them off
23#define IGNORE_DAU_UV_FLAGS         (0)
24#define ASSUME_WRITEABLE            (0)
25#define ASSUME_UNCONDITIONAL_CAU    (0)
26
27
28
29//**************************************************************************
30//  MACROS
31//**************************************************************************
32
33#define SET_V_16(a,b,r)         m_vflags = (((a) ^ (b) ^ (r) ^ ((r) >> 1)) << 8)
34#define SET_NZC_16(r)           m_nzcflags = ((r) << 8)
35#define SET_NZCV_16(a,b,r)      SET_NZC_16(r); SET_V_16(a,b,r)
36#define SET_NZ00_16(r)          m_nzcflags = (((r) << 8) & 0xffffff); m_vflags = 0
37
38#define SET_V_24(a,b,r)         m_vflags = ((a) ^ (b) ^ (r) ^ ((r) >> 1))
39#define SET_NZC_24(r)           m_nzcflags = (r)
40#define SET_NZCV_24(a,b,r)      SET_NZC_24(r); SET_V_24(a,b,r)
41#define SET_NZ00_24(r)          m_nzcflags = ((r) & 0xffffff); m_vflags = 0
42
43#define TRUNCATE24(a)           ((a) & 0xffffff)
44#define EXTEND16_TO_24(a)       TRUNCATE24((INT32)(INT16)(a))
45#define REG16(a)                ((UINT16)m_r[a])
46#define REG24(a)                (m_r[a])
47
48#define WRITEABLE_REGS          (0x6f3efffe)
49#if ASSUME_WRITEABLE
50#define IS_WRITEABLE(r)         (1)
51#else
52#define IS_WRITEABLE(r)         (WRITEABLE_REGS & (1 << (r)))
53#endif
54
55#if ASSUME_UNCONDITIONAL_CAU
56#define CONDITION_IS_TRUE()     (1)
57#else
58#define CONDITION_IS_TRUE()     (!(op & 0x400) || (condition((op >> 12) & 15)))
59#endif
60
61#if EMULATE_MEMORY_LATENCY
62#define WWORD_DEFERRED(a,v)     do { int bufidx = m_mbuf_index & 3; m_mbufaddr[bufidx] = -(a); m_mbufdata[bufidx] = (v); } while (0)
63#define WLONG_DEFERRED(a,v)     do { int bufidx = m_mbuf_index & 3; m_mbufaddr[bufidx] = (a); m_mbufdata[bufidx] = (v); } while (0)
64#define PROCESS_DEFERRED_MEMORY()                                   \
65   if (m_mbufaddr[++m_mbuf_index & 3] != 1)                    \
66   {                                                                   \
67      int bufidx = m_mbuf_index & 3;                              \
68      if (m_mbufaddr[bufidx] >= 0)                                \
69         WLONG(m_mbufaddr[bufidx], m_mbufdata[bufidx]);  \
70      else                                                            \
71         WWORD(-m_mbufaddr[bufidx], m_mbufdata[bufidx]); \
72      m_mbufaddr[bufidx] = 1;                                     \
73   }
74#else
75#define WWORD_DEFERRED(a,v) WWORD(a,v)
76#define WLONG_DEFERRED(a,v) WLONG(a,v)
77#define PROCESS_DEFERRED_MEMORY()
78#endif
79
80#if EMULATE_MULTIPLIER_LATENCY
81#define DEFERRED_MULTIPLIER(x)  dau_get_amult(x)
82#else
83#define DEFERRED_MULTIPLIER(x)  m_a[x]
84#endif
85
86#if EMULATE_AFLAGS_LATENCY
87#define DEFERRED_NZFLAGS()  dau_get_anzflags()
88#define DEFERRED_VUFLAGS()  dau_get_avuflags()
89#else
90#define DEFERRED_NZFLAGS()  m_NZflags
91#define DEFERRED_VUFLAGS()  m_VUflags
92#endif
93
94
95
96//**************************************************************************
97//  TYPEDEFS
98//**************************************************************************
99
100union int_double
101{
102   double d;
103   UINT32 i[2];
104};
105
106
107
108//**************************************************************************
109//  IMPLEMENTATION
110//**************************************************************************
111
112void dsp32c_device::illegal(UINT32 op)
113{
114}
115
116
117void dsp32c_device::unimplemented(UINT32 op)
118{
119   fatalerror("Unimplemented op @ %06X: %08X (dis=%02X, tbl=%03X)\n", PC - 4, op, op >> 25, op >> 21);
120}
121
122
123inline void dsp32c_device::execute_one()
124{
125   UINT32 op;
126
127   PROCESS_DEFERRED_MEMORY();
128   debugger_instruction_hook(this, PC);
129   op = ROPCODE(PC);
130   m_icount -= 4;  // 4 clocks per cycle
131   PC += 4;
132   if (op)
133      (this->*s_dsp32ops[op >> 21])(op);
134}
135
136
137
138//**************************************************************************
139//  CAU HELPERS
140//**************************************************************************
141
142UINT32 dsp32c_device::cau_read_pi_special(UINT8 i)
143{
144   switch (i)
145   {
146      case 4:     return m_ibuf;
147      case 5:     return m_obuf;
148      case 6:     update_pcr(m_pcr & ~PCR_PDFs); update_pins(); return m_pdr;
149      case 14:    return m_piop;
150      case 20:    return m_pdr2;
151      case 22:    update_pcr(m_pcr & ~PCR_PIFs); update_pins(); return m_pir;
152      case 30:    return m_pcw;
153      default:    fprintf(stderr, "Unimplemented CAU PI read = %X\n", i);
154   }
155   return 0;
156}
157
158
159void dsp32c_device::cau_write_pi_special(UINT8 i, UINT32 val)
160{
161   switch (i)
162   {
163      case 4:     m_ibuf = val;   break;
164      case 5:     m_obuf = val;   break;
165      case 6:     m_pdr = val; update_pcr(m_pcr | PCR_PDFs); update_pins(); break;
166      case 14:    m_piop = val;   break;
167      case 20:    m_pdr2 = val;   break;
168      case 22:    m_pir = val; update_pcr(m_pcr | PCR_PIFs); update_pins(); break;
169      case 30:    m_pcw = val;    break;
170      default:    fprintf(stderr, "Unimplemented CAU PI write = %X\n", i);
171   }
172}
173
174
175inline UINT8 dsp32c_device::cau_read_pi_1byte(int pi)
176{
177   int p = (pi >> 5) & 0x1f;
178   int i = (pi >> 0) & 0x1f;
179   if (p)
180   {
181      UINT32 result = RBYTE(m_r[p]);
182      m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
183      return result;
184   }
185   else
186      return cau_read_pi_special(i);
187}
188
189
190inline UINT16 dsp32c_device::cau_read_pi_2byte(int pi)
191{
192   int p = (pi >> 5) & 0x1f;
193   int i = (pi >> 0) & 0x1f;
194   if (p)
195   {
196      UINT32 result = RWORD(m_r[p]);
197      if (i < 22 || i > 23)
198         m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
199      else
200         m_r[p] = TRUNCATE24(m_r[p] + m_r[i] * 2);
201      return result;
202   }
203   else
204      return cau_read_pi_special(i);
205}
206
207
208inline UINT32 dsp32c_device::cau_read_pi_4byte(int pi)
209{
210   int p = (pi >> 5) & 0x1f;
211   int i = (pi >> 0) & 0x1f;
212   if (p)
213   {
214      UINT32 result = RLONG(m_r[p]);
215      if (i < 22 || i > 23)
216         m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
217      else
218         m_r[p] = TRUNCATE24(m_r[p] + m_r[i] * 4);
219      return result;
220   }
221   else
222      return cau_read_pi_special(i);
223}
224
225
226inline void dsp32c_device::cau_write_pi_1byte(int pi, UINT8 val)
227{
228   int p = (pi >> 5) & 0x1f;
229   int i = (pi >> 0) & 0x1f;
230   if (p)
231   {
232      WBYTE(m_r[p], val);
233      m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
234   }
235   else
236      cau_write_pi_special(i, val);
237}
238
239
240inline void dsp32c_device::cau_write_pi_2byte(int pi, UINT16 val)
241{
242   int p = (pi >> 5) & 0x1f;
243   int i = (pi >> 0) & 0x1f;
244   if (p)
245   {
246      WWORD(m_r[p], val);
247      if (i < 22 || i > 23)
248         m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
249      else
250         m_r[p] = TRUNCATE24(m_r[p] + m_r[i] * 2);
251   }
252   else
253      cau_write_pi_special(i, val);
254}
255
256
257inline void dsp32c_device::cau_write_pi_4byte(int pi, UINT32 val)
258{
259   int p = (pi >> 5) & 0x1f;
260   int i = (pi >> 0) & 0x1f;
261   if (p)
262   {
263      WLONG(m_r[p], (INT32)(val << 8) >> 8);
264      if (i < 22 || i > 23)
265         m_r[p] = TRUNCATE24(m_r[p] + m_r[i]);
266      else
267         m_r[p] = TRUNCATE24(m_r[p] + m_r[i] * 4);
268   }
269   else
270      cau_write_pi_special(i, val);
271}
272
273
274
275//**************************************************************************
276//  DAU HELPERS
277//**************************************************************************
278
279inline double dsp32c_device::dau_get_amult(int aidx)
280{
281   int bufidx = (m_abuf_index - 1) & 3;
282   double val = m_a[aidx];
283   while (m_icount >= m_abufcycle[bufidx] - 2 * 4)
284   {
285      if (m_abufreg[bufidx] == aidx)
286         val = m_abuf[bufidx];
287      bufidx = (bufidx - 1) & 3;
288   }
289   return val;
290}
291
292
293inline double dsp32c_device::dau_get_anzflags()
294{
295   int bufidx = (m_abuf_index - 1) & 3;
296   double nzflags = m_NZflags;
297   while (m_icount >= m_abufcycle[bufidx] - 3 * 4)
298   {
299      nzflags = m_abufNZflags[bufidx];
300      bufidx = (bufidx - 1) & 3;
301   }
302   return nzflags;
303}
304
305
306inline UINT8 dsp32c_device::dau_get_avuflags()
307{
308#if (!IGNORE_DAU_UV_FLAGS)
309   int bufidx = (m_abuf_index - 1) & 3;
310   UINT8 vuflags = m_VUflags;
311   while (m_icount >= m_abufcycle[bufidx] - 3 * 4)
312   {
313      vuflags = m_abufVUflags[bufidx];
314      bufidx = (bufidx - 1) & 3;
315   }
316   return vuflags;
317#else
318   return 0;
319#endif
320}
321
322
323inline void dsp32c_device::remember_last_dau(int aidx)
324{
325#if (EMULATE_MULTIPLIER_LATENCY || EMULATE_AFLAGS_LATENCY)
326   int bufidx = m_abuf_index++ & 3;
327   m_abuf[bufidx] = m_a[aidx];
328   m_abufreg[bufidx] = aidx;
329   m_abufNZflags[bufidx] = m_NZflags;
330#if (!IGNORE_DAU_UV_FLAGS)
331   m_abufVUflags[bufidx] = m_VUflags;
332#endif
333   m_abufcycle[bufidx] = m_icount;
334#endif
335}
336
337
338inline void dsp32c_device::dau_set_val_noflags(int aidx, double res)
339{
340   remember_last_dau(aidx);
341   m_a[aidx] = res;
342}
343
344
345inline void dsp32c_device::dau_set_val_flags(int aidx, double res)
346{
347   remember_last_dau(aidx);
348#if (!IGNORE_DAU_UV_FLAGS)
349{
350   double absres = (res < 0) ? -res : res;
351   m_VUflags = 0;
352   if (absres < 5.87747e-39)
353   {
354      if (absres != 0)
355         m_VUflags = UFLAGBIT;
356      res = 0.0;
357   }
358   else if (absres > 3.40282e38)
359   {
360      m_VUflags = VFLAGBIT;
361//      debugger_break(Machine);
362//      fprintf(stderr, "Result = %g\n", absres);
363      res = (res < 0) ? -3.40282e38 : 3.40282e38;
364   }
365}
366#endif
367   m_NZflags = res;
368   m_a[aidx] = res;
369}
370
371
372inline double dsp32c_device::dsp_to_double(UINT32 val)
373{
374   int_double id;
375
376   if (val == 0)
377      return 0;
378   else if ((INT32)val > 0)
379   {
380      int exponent = ((val & 0xff) - 128 + 1023) << 20;
381      id.i[BYTE_XOR_BE(0)] = exponent + (val >> 11);
382      id.i[BYTE_XOR_BE(1)] = (val << 21) & 0xe0000000;
383   }
384   else
385   {
386      int exponent = ((val & 0xff) - 128 + 1023) << 20;
387      val = -(val & 0xffffff00);
388      id.i[BYTE_XOR_BE(0)] = 0x80000000 + exponent + ((val >> 11) & 0x001fffff);
389      id.i[BYTE_XOR_BE(1)] = (val << 21) & 0xe0000000;
390   }
391   return id.d;
392}
393
394
395inline UINT32 dsp32c_device::double_to_dsp(double val)
396{
397   int mantissa, exponent;
398   int_double id;
399   id.d = val;
400   mantissa = ((id.i[BYTE_XOR_BE(0)] & 0x000fffff) << 11) | ((id.i[BYTE_XOR_BE(1)] & 0xe0000000) >> 21);
401   exponent = ((id.i[BYTE_XOR_BE(0)] & 0x7ff00000) >> 20) - 1023 + 128;
402   if (exponent < 0)
403      return 0x00000000;
404   else if (exponent > 255)
405   {
406//      debugger_break(Machine);
407//      fprintf(stderr, "Exponent = %d\n", exponent);
408      return ((INT32)id.i[BYTE_XOR_BE(0)] >= 0) ? 0x7fffffff : 0x800000ff;
409   }
410   else if ((INT32)id.i[BYTE_XOR_BE(0)] >= 0)
411      return exponent | mantissa;
412   else
413   {
414      mantissa = -mantissa;
415      if (mantissa == 0) { mantissa = 0x80000000; exponent--; }
416      return 0x80000000 | exponent | (mantissa & 0xffffff00);
417   }
418}
419
420
421double dsp32c_device::dau_read_pi_special(int i)
422{
423   fatalerror("Unimplemented dau_read_pi_special(%d)\n", i);
424   return 0;
425}
426
427
428void dsp32c_device::dau_write_pi_special(int i, double val)
429{
430   fatalerror("Unimplemented dau_write_pi_special(%d)\n", i);
431}
432
433
434inline double dsp32c_device::dau_read_pi_double_1st(int pi, int multiplier)
435{
436   int p = (pi >> 3) & 15;
437   int i = (pi >> 0) & 7;
438
439   m_lastp = p;
440   if (p)
441   {
442      UINT32 result = RLONG(m_r[p]);
443      if (i < 6)
444         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
445      else
446         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
447      return dsp_to_double(result);
448   }
449   else if (i < 4)
450      return multiplier ? DEFERRED_MULTIPLIER(i) : m_a[i];
451   else
452      return dau_read_pi_special(i);
453}
454
455
456inline double dsp32c_device::dau_read_pi_double_2nd(int pi, int multiplier, double xval)
457{
458   int p = (pi >> 3) & 15;
459   int i = (pi >> 0) & 7;
460
461   if (p == 15) p = m_lastp;       // P=15 means Z inherits from Y, Y inherits from X
462   m_lastp = p;
463   if (p)
464   {
465      UINT32 result;
466      result = RLONG(m_r[p]);
467      if (i < 6)
468         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
469      else
470         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
471      return dsp_to_double(result);
472   }
473   else if (i < 4)
474      return multiplier ? DEFERRED_MULTIPLIER(i) : m_a[i];
475   else
476      return dau_read_pi_special(i);
477}
478
479
480inline UINT32 dsp32c_device::dau_read_pi_4bytes(int pi)
481{
482   int p = (pi >> 3) & 15;
483   int i = (pi >> 0) & 7;
484
485   m_lastp = p;
486   if (p)
487   {
488      UINT32 result = RLONG(m_r[p]);
489      if (i < 6)
490         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
491      else
492         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
493      return result;
494   }
495   else if (i < 4)
496      return double_to_dsp(m_a[i]);
497   else
498      return dau_read_pi_special(i);
499}
500
501
502inline UINT16 dsp32c_device::dau_read_pi_2bytes(int pi)
503{
504   int p = (pi >> 3) & 15;
505   int i = (pi >> 0) & 7;
506
507   m_lastp = p;
508   if (p)
509   {
510      UINT32 result = RWORD(m_r[p]);
511      if (i < 6)
512         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
513      else
514         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 2);
515      return result;
516   }
517   else if (i < 4)
518      return double_to_dsp(m_a[i]);
519   else
520      return dau_read_pi_special(i);
521}
522
523
524inline void dsp32c_device::dau_write_pi_double(int pi, double val)
525{
526   int p = (pi >> 3) & 15;
527   int i = (pi >> 0) & 7;
528
529   if (p == 15) p = m_lastp;       // P=15 means Z inherits from Y, Y inherits from X
530   if (p)
531   {
532      WLONG_DEFERRED(m_r[p], double_to_dsp(val));
533      if (i < 6)
534         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
535      else
536         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
537   }
538   else if (i < 4)
539      dau_set_val_noflags(i, val);
540   else
541      dau_write_pi_special(i, val);
542}
543
544
545inline void dsp32c_device::dau_write_pi_4bytes(int pi, UINT32 val)
546{
547   int p = (pi >> 3) & 15;
548   int i = (pi >> 0) & 7;
549
550   if (p == 15) p = m_lastp;       // P=15 means Z inherits from Y, Y inherits from X
551   if (p)
552   {
553      m_lastp = p;
554      WLONG_DEFERRED(m_r[p], val);
555      if (i < 6)
556         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
557      else
558         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 4);
559   }
560   else if (i < 4)
561      dau_set_val_noflags(i, dsp_to_double(val));
562   else
563      dau_write_pi_special(i, val);
564}
565
566
567inline void dsp32c_device::dau_write_pi_2bytes(int pi, UINT16 val)
568{
569   int p = (pi >> 3) & 15;
570   int i = (pi >> 0) & 7;
571
572   if (p == 15) p = m_lastp;       // P=15 means Z inherits from Y, Y inherits from X
573   if (p)
574   {
575      m_lastp = p;
576      WWORD_DEFERRED(m_r[p], val);
577      if (i < 6)
578         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16]);
579      else
580         m_r[p] = TRUNCATE24(m_r[p] + m_r[i+16] * 2);
581   }
582   else if (i < 4)
583      dau_set_val_noflags(i, dsp_to_double(val << 16));
584   else
585      dau_write_pi_special(i, val);
586}
587
588
589
590//**************************************************************************
591//  COMMON CONDITION ROUTINE
592//**************************************************************************
593
594#if (!ASSUME_UNCONDITIONAL_CAU)
595int dsp32c_device::condition(int cond)
596{
597   switch (cond)
598   {
599      case 0:
600         return 0;
601      case 1:
602         return 1;
603      case 2:
604         return !nFLAG;
605      case 3:
606         return nFLAG;
607      case 4:
608         return !zFLAG;
609      case 5:
610         return zFLAG;
611      case 6:
612         return !vFLAG;
613      case 7:
614         return vFLAG;
615      case 8:
616         return !cFLAG;
617      case 9:
618         return cFLAG;
619      case 10:
620         return !(nFLAG ^ cFLAG);
621      case 11:
622         return (nFLAG ^ cFLAG);
623      case 12:
624         return !(zFLAG | (nFLAG ^ vFLAG));
625      case 13:
626         return (zFLAG | (nFLAG ^ vFLAG));
627      case 14:
628         return !(cFLAG | zFLAG);
629      case 15:
630         return (cFLAG | zFLAG);
631
632      case 16:
633         return !(DEFERRED_VUFLAGS() & UFLAGBIT);
634      case 17:
635         return (DEFERRED_VUFLAGS() & UFLAGBIT);
636      case 18:
637         return !(DEFERRED_NZFLAGS() < 0);
638      case 19:
639         return (DEFERRED_NZFLAGS() < 0);
640      case 20:
641         return !(DEFERRED_NZFLAGS() == 0);
642      case 21:
643         return (DEFERRED_NZFLAGS() == 0);
644      case 22:
645         return !(DEFERRED_VUFLAGS() & VFLAGBIT);
646      case 23:
647         return (DEFERRED_VUFLAGS() & VFLAGBIT);
648      case 24:
649         return !(DEFERRED_NZFLAGS() <= 0);
650      case 25:
651         return (DEFERRED_NZFLAGS() <= 0);
652
653      case 32:    // !ibf
654      case 33:    // ibf
655      case 34:    // !obe
656      case 35:    // obe
657      case 36:    // !pdf
658      case 37:    // pdf
659      case 38:    // !pif
660      case 39:    // pif
661      case 40:    // !sy
662      case 41:    // sy
663      case 42:    // !fb
664      case 43:    // fb
665      case 44:    // !ireq1
666      case 45:    // ireq1
667      case 46:    // !ireq2
668      case 47:    // ireq2
669      default:
670         fatalerror("Unimplemented condition: %X\n", cond);
671   }
672}
673#endif
674
675
676
677//**************************************************************************
678//  CAU BRANCH INSTRUCTION IMPLEMENTATION
679//**************************************************************************
680
681void dsp32c_device::nop(UINT32 op)
682{
683   if (op == 0)
684      return;
685   execute_one();
686   PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
687}
688
689
690void dsp32c_device::goto_t(UINT32 op)
691{
692   execute_one();
693   PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
694}
695
696
697void dsp32c_device::goto_pl(UINT32 op)
698{
699   if (!nFLAG)
700   {
701      execute_one();
702      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
703   }
704}
705
706
707void dsp32c_device::goto_mi(UINT32 op)
708{
709   if (nFLAG)
710   {
711      execute_one();
712      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
713   }
714}
715
716
717void dsp32c_device::goto_ne(UINT32 op)
718{
719   if (!zFLAG)
720   {
721      execute_one();
722      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
723   }
724}
725
726
727void dsp32c_device::goto_eq(UINT32 op)
728{
729   if (zFLAG)
730   {
731      execute_one();
732      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
733   }
734}
735
736
737void dsp32c_device::goto_vc(UINT32 op)
738{
739   if (!vFLAG)
740   {
741      execute_one();
742      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
743   }
744}
745
746
747void dsp32c_device::goto_vs(UINT32 op)
748{
749   if (vFLAG)
750   {
751      execute_one();
752      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
753   }
754}
755
756
757void dsp32c_device::goto_cc(UINT32 op)
758{
759   if (!cFLAG)
760   {
761      execute_one();
762      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
763   }
764}
765
766
767void dsp32c_device::goto_cs(UINT32 op)
768{
769   if (cFLAG)
770   {
771      execute_one();
772      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
773   }
774}
775
776
777void dsp32c_device::goto_ge(UINT32 op)
778{
779   if (!(nFLAG ^ vFLAG))
780   {
781      execute_one();
782      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
783   }
784}
785
786
787void dsp32c_device::goto_lt(UINT32 op)
788{
789   if (nFLAG ^ vFLAG)
790   {
791      execute_one();
792      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
793   }
794}
795
796
797void dsp32c_device::goto_gt(UINT32 op)
798{
799   if (!(zFLAG | (nFLAG ^ vFLAG)))
800   {
801      execute_one();
802      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
803   }
804}
805
806
807void dsp32c_device::goto_le(UINT32 op)
808{
809   if (zFLAG | (nFLAG ^ vFLAG))
810   {
811      execute_one();
812      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
813   }
814}
815
816
817void dsp32c_device::goto_hi(UINT32 op)
818{
819   if (!cFLAG && !zFLAG)
820   {
821      execute_one();
822      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
823   }
824}
825
826
827void dsp32c_device::goto_ls(UINT32 op)
828{
829   if (cFLAG || zFLAG)
830   {
831      execute_one();
832      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
833   }
834}
835
836
837void dsp32c_device::goto_auc(UINT32 op)
838{
839   if (!(DEFERRED_VUFLAGS() & UFLAGBIT))
840   {
841      execute_one();
842      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
843   }
844}
845
846
847void dsp32c_device::goto_aus(UINT32 op)
848{
849   if (DEFERRED_VUFLAGS() & UFLAGBIT)
850   {
851      execute_one();
852      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
853   }
854}
855
856
857void dsp32c_device::goto_age(UINT32 op)
858{
859   if (DEFERRED_NZFLAGS() >= 0)
860   {
861      execute_one();
862      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
863   }
864}
865
866
867void dsp32c_device::goto_alt(UINT32 op)
868{
869   if (DEFERRED_NZFLAGS() < 0)
870   {
871      execute_one();
872      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
873   }
874}
875
876
877void dsp32c_device::goto_ane(UINT32 op)
878{
879   if (DEFERRED_NZFLAGS() != 0)
880   {
881      execute_one();
882      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
883   }
884}
885
886
887void dsp32c_device::goto_aeq(UINT32 op)
888{
889   if (DEFERRED_NZFLAGS() == 0)
890   {
891      execute_one();
892      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
893   }
894}
895
896
897void dsp32c_device::goto_avc(UINT32 op)
898{
899   if (!(DEFERRED_VUFLAGS() & VFLAGBIT))
900   {
901      execute_one();
902      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
903   }
904}
905
906
907void dsp32c_device::goto_avs(UINT32 op)
908{
909   if (DEFERRED_VUFLAGS() & VFLAGBIT)
910   {
911      execute_one();
912      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
913   }
914}
915
916
917void dsp32c_device::goto_agt(UINT32 op)
918{
919   if (DEFERRED_NZFLAGS() > 0)
920   {
921      execute_one();
922      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
923   }
924}
925
926
927void dsp32c_device::goto_ale(UINT32 op)
928{
929   if (DEFERRED_NZFLAGS() <= 0)
930   {
931      execute_one();
932      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
933   }
934}
935
936
937void dsp32c_device::goto_ibe(UINT32 op)
938{
939   unimplemented(op);
940}
941
942
943void dsp32c_device::goto_ibf(UINT32 op)
944{
945   unimplemented(op);
946}
947
948
949void dsp32c_device::goto_obf(UINT32 op)
950{
951   unimplemented(op);
952}
953
954
955void dsp32c_device::goto_obe(UINT32 op)
956{
957   unimplemented(op);
958}
959
960
961void dsp32c_device::goto_pde(UINT32 op)
962{
963   if (!(m_pcr & PCR_PDFs))
964   {
965      execute_one();
966      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
967   }
968}
969
970
971void dsp32c_device::goto_pdf(UINT32 op)
972{
973   if (m_pcr & PCR_PDFs)
974   {
975      execute_one();
976      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
977   }
978}
979
980
981void dsp32c_device::goto_pie(UINT32 op)
982{
983   if (!(m_pcr & PCR_PIFs))
984   {
985      execute_one();
986      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
987   }
988}
989
990
991void dsp32c_device::goto_pif(UINT32 op)
992{
993   if (m_pcr & PCR_PIFs)
994   {
995      execute_one();
996      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
997   }
998}
999
1000
1001void dsp32c_device::goto_syc(UINT32 op)
1002{
1003   unimplemented(op);
1004}
1005
1006
1007void dsp32c_device::goto_sys(UINT32 op)
1008{
1009   unimplemented(op);
1010}
1011
1012
1013void dsp32c_device::goto_fbc(UINT32 op)
1014{
1015   unimplemented(op);
1016}
1017
1018
1019void dsp32c_device::goto_fbs(UINT32 op)
1020{
1021   unimplemented(op);
1022}
1023
1024
1025void dsp32c_device::goto_irq1lo(UINT32 op)
1026{
1027   unimplemented(op);
1028}
1029
1030
1031void dsp32c_device::goto_irq1hi(UINT32 op)
1032{
1033   unimplemented(op);
1034}
1035
1036
1037void dsp32c_device::goto_irq2lo(UINT32 op)
1038{
1039   unimplemented(op);
1040}
1041
1042
1043void dsp32c_device::goto_irq2hi(UINT32 op)
1044{
1045   unimplemented(op);
1046}
1047
1048
1049void dsp32c_device::dec_goto(UINT32 op)
1050{
1051   int hr = (op >> 21) & 0x1f;
1052   int old = (INT16)m_r[hr];
1053   m_r[hr] = EXTEND16_TO_24(m_r[hr] - 1);
1054   if (old >= 0)
1055   {
1056      execute_one();
1057      PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
1058   }
1059}
1060
1061
1062void dsp32c_device::call(UINT32 op)
1063{
1064   int mr = (op >> 21) & 0x1f;
1065   if (IS_WRITEABLE(mr))
1066      m_r[mr] = PC + 4;
1067   execute_one();
1068   PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (INT16)op);
1069}
1070
1071
1072void dsp32c_device::goto24(UINT32 op)
1073{
1074   execute_one();
1075   PC = TRUNCATE24(REG24((op >> 16) & 0x1f) + (op & 0xffff) + ((op >> 5) & 0xff0000));
1076}
1077
1078
1079void dsp32c_device::call24(UINT32 op)
1080{
1081   int mr = (op >> 16) & 0x1f;
1082   if (IS_WRITEABLE(mr))
1083      m_r[mr] = PC + 4;
1084   execute_one();
1085   PC = (op & 0xffff) + ((op >> 5) & 0xff0000);
1086}
1087
1088
1089void dsp32c_device::do_i(UINT32 op)
1090{
1091   unimplemented(op);
1092}
1093
1094
1095void dsp32c_device::do_r(UINT32 op)
1096{
1097   unimplemented(op);
1098}
1099
1100
1101
1102//**************************************************************************
1103//  CAU 16-BIT ARITHMETIC IMPLEMENTATION
1104//**************************************************************************
1105
1106void dsp32c_device::add_si(UINT32 op)
1107{
1108   int dr = (op >> 21) & 0x1f;
1109   int hrval = REG16((op >> 16) & 0x1f);
1110   int res = hrval + (UINT16)op;
1111   if (IS_WRITEABLE(dr))
1112      m_r[dr] = EXTEND16_TO_24(res);
1113   SET_NZCV_16(hrval, op, res);
1114}
1115
1116
1117void dsp32c_device::add_ss(UINT32 op)
1118{
1119   if (CONDITION_IS_TRUE())
1120   {
1121      int dr = (op >> 16) & 0x1f;
1122      int s1rval = REG16((op >> 5) & 0x1f);
1123      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1124      int res = s2rval + s1rval;
1125      if (IS_WRITEABLE(dr))
1126         m_r[dr] = EXTEND16_TO_24(res);
1127      SET_NZCV_16(s1rval, s2rval, res);
1128   }
1129}
1130
1131
1132void dsp32c_device::mul2_s(UINT32 op)
1133{
1134   if (CONDITION_IS_TRUE())
1135   {
1136      int dr = (op >> 16) & 0x1f;
1137      int s1rval = REG16((op >> 5) & 0x1f);
1138      int res = s1rval * 2;
1139      if (IS_WRITEABLE(dr))
1140         m_r[dr] = EXTEND16_TO_24(res);
1141      SET_NZCV_16(s1rval, 0, res);
1142   }
1143}
1144
1145
1146void dsp32c_device::subr_ss(UINT32 op)
1147{
1148   if (CONDITION_IS_TRUE())
1149   {
1150      int dr = (op >> 16) & 0x1f;
1151      int s1rval = REG16((op >> 5) & 0x1f);
1152      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1153      int res = s1rval - s2rval;
1154      if (IS_WRITEABLE(dr))
1155         m_r[dr] = EXTEND16_TO_24(res);
1156      SET_NZCV_16(s1rval, s2rval, res);
1157   }
1158}
1159
1160
1161void dsp32c_device::addr_ss(UINT32 op)
1162{
1163   unimplemented(op);
1164}
1165
1166
1167void dsp32c_device::sub_ss(UINT32 op)
1168{
1169   if (CONDITION_IS_TRUE())
1170   {
1171      int dr = (op >> 16) & 0x1f;
1172      int s1rval = REG16((op >> 5) & 0x1f);
1173      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1174      int res = s2rval - s1rval;
1175      if (IS_WRITEABLE(dr))
1176         m_r[dr] = EXTEND16_TO_24(res);
1177      SET_NZCV_16(s1rval, s2rval, res);
1178   }
1179}
1180
1181
1182void dsp32c_device::neg_s(UINT32 op)
1183{
1184   if (CONDITION_IS_TRUE())
1185   {
1186      int dr = (op >> 16) & 0x1f;
1187      int s1rval = REG16((op >> 5) & 0x1f);
1188      int res = -s1rval;
1189      if (IS_WRITEABLE(dr))
1190         m_r[dr] = EXTEND16_TO_24(res);
1191      SET_NZCV_16(s1rval, 0, res);
1192   }
1193}
1194
1195
1196void dsp32c_device::andc_ss(UINT32 op)
1197{
1198   if (CONDITION_IS_TRUE())
1199   {
1200      int dr = (op >> 16) & 0x1f;
1201      int s1rval = REG16((op >> 5) & 0x1f);
1202      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1203      int res = s2rval & ~s1rval;
1204      if (IS_WRITEABLE(dr))
1205         m_r[dr] = EXTEND16_TO_24(res);
1206      SET_NZ00_16(res);
1207   }
1208}
1209
1210
1211void dsp32c_device::cmp_ss(UINT32 op)
1212{
1213   if (CONDITION_IS_TRUE())
1214   {
1215      int drval = REG16((op >> 16) & 0x1f);
1216      int s1rval = REG16((op >> 5) & 0x1f);
1217      int res = drval - s1rval;
1218      SET_NZCV_16(drval, s1rval, res);
1219   }
1220}
1221
1222
1223void dsp32c_device::xor_ss(UINT32 op)
1224{
1225   if (CONDITION_IS_TRUE())
1226   {
1227      int dr = (op >> 16) & 0x1f;
1228      int s1rval = REG16((op >> 5) & 0x1f);
1229      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1230      int res = s2rval ^ s1rval;
1231      if (IS_WRITEABLE(dr))
1232         m_r[dr] = EXTEND16_TO_24(res);
1233      SET_NZ00_16(res);
1234   }
1235}
1236
1237
1238void dsp32c_device::rcr_s(UINT32 op)
1239{
1240   if (CONDITION_IS_TRUE())
1241   {
1242      int dr = (op >> 16) & 0x1f;
1243      int s1rval = REG16((op >> 5) & 0x1f);
1244      int res = ((m_nzcflags >> 9) & 0x8000) | (s1rval >> 1);
1245      if (IS_WRITEABLE(dr))
1246         m_r[dr] = EXTEND16_TO_24(res);
1247      m_nzcflags = ((res & 0xffff) << 8) | ((s1rval & 1) << 24);
1248      m_vflags = 0;
1249   }
1250}
1251
1252
1253void dsp32c_device::or_ss(UINT32 op)
1254{
1255   if (CONDITION_IS_TRUE())
1256   {
1257      int dr = (op >> 16) & 0x1f;
1258      int s1rval = REG16((op >> 5) & 0x1f);
1259      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1260      int res = s2rval | s1rval;
1261      if (IS_WRITEABLE(dr))
1262         m_r[dr] = EXTEND16_TO_24(res);
1263      SET_NZ00_16(res);
1264   }
1265}
1266
1267
1268void dsp32c_device::rcl_s(UINT32 op)
1269{
1270   if (CONDITION_IS_TRUE())
1271   {
1272      int dr = (op >> 16) & 0x1f;
1273      int s1rval = REG16((op >> 5) & 0x1f);
1274      int res = ((m_nzcflags >> 24) & 0x0001) | (s1rval << 1);
1275      if (IS_WRITEABLE(dr))
1276         m_r[dr] = EXTEND16_TO_24(res);
1277      m_nzcflags = ((res & 0xffff) << 8) | ((s1rval & 0x8000) << 9);
1278      m_vflags = 0;
1279   }
1280}
1281
1282
1283void dsp32c_device::shr_s(UINT32 op)
1284{
1285   if (CONDITION_IS_TRUE())
1286   {
1287      int dr = (op >> 16) & 0x1f;
1288      int s1rval = REG16((op >> 5) & 0x1f);
1289      int res = s1rval >> 1;
1290      if (IS_WRITEABLE(dr))
1291         m_r[dr] = EXTEND16_TO_24(res);
1292      m_nzcflags = ((res & 0xffff) << 8) | ((s1rval & 1) << 24);
1293      m_vflags = 0;
1294   }
1295}
1296
1297
1298void dsp32c_device::div2_s(UINT32 op)
1299{
1300   if (CONDITION_IS_TRUE())
1301   {
1302      int dr = (op >> 16) & 0x1f;
1303      int s1rval = REG16((op >> 5) & 0x1f);
1304      int res = (s1rval & 0x8000) | (s1rval >> 1);
1305      if (IS_WRITEABLE(dr))
1306         m_r[dr] = EXTEND16_TO_24(res);
1307      m_nzcflags = ((res & 0xffff) << 8) | ((s1rval & 1) << 24);
1308      m_vflags = 0;
1309   }
1310}
1311
1312
1313void dsp32c_device::and_ss(UINT32 op)
1314{
1315   if (CONDITION_IS_TRUE())
1316   {
1317      int dr = (op >> 16) & 0x1f;
1318      int s1rval = REG16((op >> 5) & 0x1f);
1319      int s2rval = (op & 0x800) ? REG16((op >> 0) & 0x1f) : REG16(dr);
1320      int res = s2rval & s1rval;
1321      if (IS_WRITEABLE(dr))
1322         m_r[dr] = EXTEND16_TO_24(res);
1323      SET_NZ00_16(res);
1324   }
1325}
1326
1327
1328void dsp32c_device::test_ss(UINT32 op)
1329{
1330   if (CONDITION_IS_TRUE())
1331   {
1332      int drval = REG16((op >> 16) & 0x1f);
1333      int s1rval = REG16((op >> 5) & 0x1f);
1334      int res = drval & s1rval;
1335      SET_NZ00_16(res);
1336   }
1337}
1338
1339
1340void dsp32c_device::add_di(UINT32 op)
1341{
1342   int dr = (op >> 16) & 0x1f;
1343   int drval = REG16(dr);
1344   int res = drval + (UINT16)op;
1345   if (IS_WRITEABLE(dr))
1346      m_r[dr] = EXTEND16_TO_24(res);
1347   SET_NZCV_16(drval, op, res);
1348}
1349
1350
1351void dsp32c_device::subr_di(UINT32 op)
1352{
1353   int dr = (op >> 16) & 0x1f;
1354   int drval = REG16(dr);
1355   int res = (UINT16)op - drval;
1356   if (IS_WRITEABLE(dr))
1357      m_r[dr] = EXTEND16_TO_24(res);
1358   SET_NZCV_16(drval, op, res);
1359}
1360
1361
1362void dsp32c_device::addr_di(UINT32 op)
1363{
1364   unimplemented(op);
1365}
1366
1367
1368void dsp32c_device::sub_di(UINT32 op)
1369{
1370   int dr = (op >> 16) & 0x1f;
1371   int drval = REG16(dr);
1372   int res = drval - (UINT16)op;
1373   if (IS_WRITEABLE(dr))
1374      m_r[dr] = EXTEND16_TO_24(res);
1375   SET_NZCV_16(drval, op, res);
1376}
1377
1378
1379void dsp32c_device::andc_di(UINT32 op)
1380{
1381   int dr = (op >> 16) & 0x1f;
1382   int drval = REG16(dr);
1383   int res = drval & ~(UINT16)op;
1384   if (IS_WRITEABLE(dr))
1385      m_r[dr] = EXTEND16_TO_24(res);
1386   SET_NZ00_16(res);
1387}
1388
1389
1390void dsp32c_device::cmp_di(UINT32 op)
1391{
1392   int drval = REG16((op >> 16) & 0x1f);
1393   int res = drval - (UINT16)op;
1394   SET_NZCV_16(drval, op, res);
1395}
1396
1397
1398void dsp32c_device::xor_di(UINT32 op)
1399{
1400   int dr = (op >> 16) & 0x1f;
1401   int drval = REG16(dr);
1402   int res = drval ^ (UINT16)op;
1403   if (IS_WRITEABLE(dr))
1404      m_r[dr] = EXTEND16_TO_24(res);
1405   SET_NZ00_16(res);
1406}
1407
1408
1409void dsp32c_device::or_di(UINT32 op)
1410{
1411   int dr = (op >> 16) & 0x1f;
1412   int drval = REG16(dr);
1413   int res = drval | (UINT16)op;
1414   if (IS_WRITEABLE(dr))
1415      m_r[dr] = EXTEND16_TO_24(res);
1416   SET_NZ00_16(res);
1417}
1418
1419
1420void dsp32c_device::and_di(UINT32 op)
1421{
1422   int dr = (op >> 16) & 0x1f;
1423   int drval = REG16(dr);
1424   int res = drval & (UINT16)op;
1425   if (IS_WRITEABLE(dr))
1426      m_r[dr] = EXTEND16_TO_24(res);
1427   SET_NZ00_16(res);
1428}
1429
1430
1431void dsp32c_device::test_di(UINT32 op)
1432{
1433   int drval = REG16((op >> 16) & 0x1f);
1434   int res = drval & (UINT16)op;
1435   SET_NZ00_16(res);
1436}
1437
1438
1439
1440//**************************************************************************
1441//  CAU 24-BIT ARITHMETIC IMPLEMENTATION
1442//**************************************************************************
1443
1444void dsp32c_device::adde_si(UINT32 op)
1445{
1446   int dr = (op >> 21) & 0x1f;
1447   int hrval = REG24((op >> 16) & 0x1f);
1448   int res = hrval + EXTEND16_TO_24(op);
1449   if (IS_WRITEABLE(dr))
1450      m_r[dr] = TRUNCATE24(res);
1451   SET_NZCV_24(hrval, op << 8, res);
1452}
1453
1454
1455void dsp32c_device::adde_ss(UINT32 op)
1456{
1457   if (CONDITION_IS_TRUE())
1458   {
1459      int dr = (op >> 16) & 0x1f;
1460      int s1rval = REG24((op >> 5) & 0x1f);
1461      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1462      int res = s2rval + s1rval;
1463      if (IS_WRITEABLE(dr))
1464         m_r[dr] = TRUNCATE24(res);
1465      SET_NZCV_24(s1rval, s2rval, res);
1466   }
1467}
1468
1469
1470void dsp32c_device::mul2e_s(UINT32 op)
1471{
1472   if (CONDITION_IS_TRUE())
1473   {
1474      int dr = (op >> 16) & 0x1f;
1475      int s1rval = REG24((op >> 5) & 0x1f);
1476      int res = s1rval * 2;
1477      if (IS_WRITEABLE(dr))
1478         m_r[dr] = TRUNCATE24(res);
1479      SET_NZCV_24(s1rval, 0, res);
1480   }
1481}
1482
1483
1484void dsp32c_device::subre_ss(UINT32 op)
1485{
1486   if (CONDITION_IS_TRUE())
1487   {
1488      int dr = (op >> 16) & 0x1f;
1489      int s1rval = REG24((op >> 5) & 0x1f);
1490      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1491      int res = s1rval - s2rval;
1492      if (IS_WRITEABLE(dr))
1493         m_r[dr] = TRUNCATE24(res);
1494      SET_NZCV_24(s1rval, s2rval, res);
1495   }
1496}
1497
1498
1499void dsp32c_device::addre_ss(UINT32 op)
1500{
1501   unimplemented(op);
1502}
1503
1504
1505void dsp32c_device::sube_ss(UINT32 op)
1506{
1507   if (CONDITION_IS_TRUE())
1508   {
1509      int dr = (op >> 16) & 0x1f;
1510      int s1rval = REG24((op >> 5) & 0x1f);
1511      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1512      int res = s2rval - s1rval;
1513      if (IS_WRITEABLE(dr))
1514         m_r[dr] = TRUNCATE24(res);
1515      SET_NZCV_24(s1rval, s2rval, res);
1516   }
1517}
1518
1519
1520void dsp32c_device::nege_s(UINT32 op)
1521{
1522   if (CONDITION_IS_TRUE())
1523   {
1524      int dr = (op >> 16) & 0x1f;
1525      int s1rval = REG24((op >> 5) & 0x1f);
1526      int res = -s1rval;
1527      if (IS_WRITEABLE(dr))
1528         m_r[dr] = TRUNCATE24(res);
1529      SET_NZCV_24(s1rval, 0, res);
1530   }
1531}
1532
1533
1534void dsp32c_device::andce_ss(UINT32 op)
1535{
1536   if (CONDITION_IS_TRUE())
1537   {
1538      int dr = (op >> 16) & 0x1f;
1539      int s1rval = REG24((op >> 5) & 0x1f);
1540      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1541      int res = s2rval & ~s1rval;
1542      if (IS_WRITEABLE(dr))
1543         m_r[dr] = res;
1544      SET_NZ00_24(res);
1545   }
1546}
1547
1548
1549void dsp32c_device::cmpe_ss(UINT32 op)
1550{
1551   if (CONDITION_IS_TRUE())
1552   {
1553      int drval = REG24((op >> 16) & 0x1f);
1554      int s1rval = REG24((op >> 5) & 0x1f);
1555      int res = drval - s1rval;
1556      SET_NZCV_24(drval, s1rval, res);
1557   }
1558}
1559
1560
1561void dsp32c_device::xore_ss(UINT32 op)
1562{
1563   if (CONDITION_IS_TRUE())
1564   {
1565      int dr = (op >> 16) & 0x1f;
1566      int s1rval = REG24((op >> 5) & 0x1f);
1567      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1568      int res = s2rval ^ s1rval;
1569      if (IS_WRITEABLE(dr))
1570         m_r[dr] = res;
1571      SET_NZ00_24(res);
1572   }
1573}
1574
1575
1576void dsp32c_device::rcre_s(UINT32 op)
1577{
1578   if (CONDITION_IS_TRUE())
1579   {
1580      int dr = (op >> 16) & 0x1f;
1581      int s1rval = REG24((op >> 5) & 0x1f);
1582      int res = ((m_nzcflags >> 1) & 0x800000) | (s1rval >> 1);
1583      if (IS_WRITEABLE(dr))
1584         m_r[dr] = TRUNCATE24(res);
1585      m_nzcflags = res | ((s1rval & 1) << 24);
1586      m_vflags = 0;
1587   }
1588}
1589
1590
1591void dsp32c_device::ore_ss(UINT32 op)
1592{
1593   if (CONDITION_IS_TRUE())
1594   {
1595      int dr = (op >> 16) & 0x1f;
1596      int s1rval = REG24((op >> 5) & 0x1f);
1597      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1598      int res = s2rval | s1rval;
1599      if (IS_WRITEABLE(dr))
1600         m_r[dr] = res;
1601      SET_NZ00_24(res);
1602   }
1603}
1604
1605
1606void dsp32c_device::rcle_s(UINT32 op)
1607{
1608   if (CONDITION_IS_TRUE())
1609   {
1610      int dr = (op >> 16) & 0x1f;
1611      int s1rval = REG24((op >> 5) & 0x1f);
1612      int res = ((m_nzcflags >> 24) & 0x000001) | (s1rval << 1);
1613      if (IS_WRITEABLE(dr))
1614         m_r[dr] = TRUNCATE24(res);
1615      m_nzcflags = res | ((s1rval & 0x800000) << 1);
1616      m_vflags = 0;
1617   }
1618}
1619
1620
1621void dsp32c_device::shre_s(UINT32 op)
1622{
1623   if (CONDITION_IS_TRUE())
1624   {
1625      int dr = (op >> 16) & 0x1f;
1626      int s1rval = REG24((op >> 5) & 0x1f);
1627      int res = s1rval >> 1;
1628      if (IS_WRITEABLE(dr))
1629         m_r[dr] = res;
1630      m_nzcflags = res | ((s1rval & 1) << 24);
1631      m_vflags = 0;
1632   }
1633}
1634
1635
1636void dsp32c_device::div2e_s(UINT32 op)
1637{
1638   if (CONDITION_IS_TRUE())
1639   {
1640      int dr = (op >> 16) & 0x1f;
1641      int s1rval = REG24((op >> 5) & 0x1f);
1642      int res = (s1rval & 0x800000) | (s1rval >> 1);
1643      if (IS_WRITEABLE(dr))
1644         m_r[dr] = TRUNCATE24(res);
1645      m_nzcflags = res | ((s1rval & 1) << 24);
1646      m_vflags = 0;
1647   }
1648}
1649
1650
1651void dsp32c_device::ande_ss(UINT32 op)
1652{
1653   if (CONDITION_IS_TRUE())
1654   {
1655      int dr = (op >> 16) & 0x1f;
1656      int s1rval = REG24((op >> 5) & 0x1f);
1657      int s2rval = (op & 0x800) ? REG24((op >> 0) & 0x1f) : REG24(dr);
1658      int res = s2rval & s1rval;
1659      if (IS_WRITEABLE(dr))
1660         m_r[dr] = res;
1661      SET_NZ00_24(res);
1662   }
1663}
1664
1665
1666void dsp32c_device::teste_ss(UINT32 op)
1667{
1668   if (CONDITION_IS_TRUE())
1669   {
1670      int drval = REG24((op >> 16) & 0x1f);
1671      int s1rval = REG24((op >> 5) & 0x1f);
1672      int res = drval & s1rval;
1673      SET_NZ00_24(res);
1674   }
1675}
1676
1677
1678void dsp32c_device::adde_di(UINT32 op)
1679{
1680   int dr = (op >> 16) & 0x1f;
1681   int drval = REG24(dr);
1682   int res = drval + EXTEND16_TO_24(op);
1683   if (IS_WRITEABLE(dr))
1684      m_r[dr] = TRUNCATE24(res);
1685   SET_NZCV_24(drval, op << 8, res);
1686}
1687
1688
1689void dsp32c_device::subre_di(UINT32 op)
1690{
1691   int dr = (op >> 16) & 0x1f;
1692   int drval = REG24(dr);
1693   int res = EXTEND16_TO_24(op) - drval;
1694   if (IS_WRITEABLE(dr))
1695      m_r[dr] = TRUNCATE24(res);
1696   SET_NZCV_24(drval, op << 8, res);
1697}
1698
1699
1700void dsp32c_device::addre_di(UINT32 op)
1701{
1702   unimplemented(op);
1703}
1704
1705
1706void dsp32c_device::sube_di(UINT32 op)
1707{
1708   int dr = (op >> 16) & 0x1f;
1709   int drval = REG24(dr);
1710   int res = drval - EXTEND16_TO_24(op);
1711   if (IS_WRITEABLE(dr))
1712      m_r[dr] = TRUNCATE24(res);
1713   SET_NZCV_24(drval, op << 8, res);
1714}
1715
1716
1717void dsp32c_device::andce_di(UINT32 op)
1718{
1719   int dr = (op >> 16) & 0x1f;
1720   int drval = REG24(dr);
1721   int res = drval & ~EXTEND16_TO_24(op);
1722   if (IS_WRITEABLE(dr))
1723      m_r[dr] = res;
1724   SET_NZ00_24(res);
1725}
1726
1727
1728void dsp32c_device::cmpe_di(UINT32 op)
1729{
1730   int drval = REG24((op >> 16) & 0x1f);
1731   int res = drval - EXTEND16_TO_24(op);
1732   SET_NZCV_24(drval, op << 8, res);
1733}
1734
1735
1736void dsp32c_device::xore_di(UINT32 op)
1737{
1738   int dr = (op >> 16) & 0x1f;
1739   int drval = REG24(dr);
1740   int res = drval ^ EXTEND16_TO_24(op);
1741   if (IS_WRITEABLE(dr))
1742      m_r[dr] = res;
1743   SET_NZ00_24(res);
1744}
1745
1746
1747void dsp32c_device::ore_di(UINT32 op)
1748{
1749   int dr = (op >> 16) & 0x1f;
1750   int drval = REG24(dr);
1751   int res = drval | EXTEND16_TO_24(op);
1752   if (IS_WRITEABLE(dr))
1753      m_r[dr] = res;
1754   SET_NZ00_24(res);
1755}
1756
1757
1758void dsp32c_device::ande_di(UINT32 op)
1759{
1760   int dr = (op >> 16) & 0x1f;
1761   int drval = REG24(dr);
1762   int res = drval & EXTEND16_TO_24(op);
1763   if (IS_WRITEABLE(dr))
1764      m_r[dr] = res;
1765   SET_NZ00_24(res);
1766}
1767
1768
1769void dsp32c_device::teste_di(UINT32 op)
1770{
1771   int drval = REG24((op >> 16) & 0x1f);
1772   int res = drval & EXTEND16_TO_24(op);
1773   SET_NZ00_24(res);
1774}
1775
1776
1777
1778//**************************************************************************
1779//  CAU LOAD/STORE IMPLEMENTATION
1780//**************************************************************************
1781
1782void dsp32c_device::load_hi(UINT32 op)
1783{
1784   int dr = (op >> 16) & 0x1f;
1785   UINT32 res = RBYTE(EXTEND16_TO_24(op));
1786   if (IS_WRITEABLE(dr))
1787      m_r[dr] = EXTEND16_TO_24(res);
1788   m_nzcflags = res << 8;
1789   m_vflags = 0;
1790}
1791
1792
1793void dsp32c_device::load_li(UINT32 op)
1794{
1795   int dr = (op >> 16) & 0x1f;
1796   UINT32 res = RBYTE(EXTEND16_TO_24(op));
1797   if (IS_WRITEABLE(dr))
1798      m_r[dr] = res;
1799   m_nzcflags = res << 8;
1800   m_vflags = 0;
1801}
1802
1803
1804void dsp32c_device::load_i(UINT32 op)
1805{
1806   UINT32 res = RWORD(EXTEND16_TO_24(op));
1807   int dr = (op >> 16) & 0x1f;
1808   if (IS_WRITEABLE(dr))
1809      m_r[dr] = EXTEND16_TO_24(res);
1810   m_nzcflags = res << 8;
1811   m_vflags = 0;
1812}
1813
1814
1815void dsp32c_device::load_ei(UINT32 op)
1816{
1817   UINT32 res = TRUNCATE24(RLONG(EXTEND16_TO_24(op)));
1818   int dr = (op >> 16) & 0x1f;
1819   if (IS_WRITEABLE(dr))
1820      m_r[dr] = res;
1821   m_nzcflags = res;
1822   m_vflags = 0;
1823}
1824
1825
1826void dsp32c_device::store_hi(UINT32 op)
1827{
1828   WBYTE(EXTEND16_TO_24(op), m_r[(op >> 16) & 0x1f] >> 8);
1829}
1830
1831
1832void dsp32c_device::store_li(UINT32 op)
1833{
1834   WBYTE(EXTEND16_TO_24(op), m_r[(op >> 16) & 0x1f]);
1835}
1836
1837
1838void dsp32c_device::store_i(UINT32 op)
1839{
1840   WWORD(EXTEND16_TO_24(op), REG16((op >> 16) & 0x1f));
1841}
1842
1843
1844void dsp32c_device::store_ei(UINT32 op)
1845{
1846   WLONG(EXTEND16_TO_24(op), (INT32)(REG24((op >> 16) & 0x1f) << 8) >> 8);
1847}
1848
1849
1850void dsp32c_device::load_hr(UINT32 op)
1851{
1852   if (!(op & 0x400))
1853   {
1854      int dr = (op >> 16) & 0x1f;
1855      UINT32 res = cau_read_pi_1byte(op) << 8;
1856      if (IS_WRITEABLE(dr))
1857         m_r[dr] = EXTEND16_TO_24(res);
1858      m_nzcflags = res << 8;
1859      m_vflags = 0;
1860   }
1861   else
1862      unimplemented(op);
1863}
1864
1865
1866void dsp32c_device::load_lr(UINT32 op)
1867{
1868   if (!(op & 0x400))
1869   {
1870      int dr = (op >> 16) & 0x1f;
1871      UINT32 res = cau_read_pi_1byte(op);
1872      if (IS_WRITEABLE(dr))
1873         m_r[dr] = res;
1874      m_nzcflags = res << 8;
1875      m_vflags = 0;
1876   }
1877   else
1878      unimplemented(op);
1879}
1880
1881
1882void dsp32c_device::load_r(UINT32 op)
1883{
1884   if (!(op & 0x400))
1885   {
1886      UINT32 res = cau_read_pi_2byte(op);
1887      int dr = (op >> 16) & 0x1f;
1888      if (IS_WRITEABLE(dr))
1889         m_r[dr] = EXTEND16_TO_24(res);
1890      m_nzcflags = res << 8;
1891      m_vflags = 0;
1892   }
1893   else
1894      unimplemented(op);
1895}
1896
1897
1898void dsp32c_device::load_er(UINT32 op)
1899{
1900   if (!(op & 0x400))
1901   {
1902      UINT32 res = TRUNCATE24(cau_read_pi_4byte(op));
1903      int dr = (op >> 16) & 0x1f;
1904      if (IS_WRITEABLE(dr))
1905         m_r[dr] = res;
1906      m_nzcflags = res;
1907      m_vflags = 0;
1908   }
1909   else
1910      unimplemented(op);
1911}
1912
1913
1914void dsp32c_device::store_hr(UINT32 op)
1915{
1916   if (!(op & 0x400))
1917      cau_write_pi_1byte(op, m_r[(op >> 16) & 0x1f] >> 8);
1918   else
1919      unimplemented(op);
1920}
1921
1922
1923void dsp32c_device::store_lr(UINT32 op)
1924{
1925   if (!(op & 0x400))
1926      cau_write_pi_1byte(op, m_r[(op >> 16) & 0x1f]);
1927   else
1928      unimplemented(op);
1929}
1930
1931
1932void dsp32c_device::store_r(UINT32 op)
1933{
1934   if (!(op & 0x400))
1935      cau_write_pi_2byte(op, REG16((op >> 16) & 0x1f));
1936   else
1937      unimplemented(op);
1938}
1939
1940
1941void dsp32c_device::store_er(UINT32 op)
1942{
1943   if (!(op & 0x400))
1944      cau_write_pi_4byte(op, REG24((op >> 16) & 0x1f));
1945   else
1946      unimplemented(op);
1947}
1948
1949
1950void dsp32c_device::load24(UINT32 op)
1951{
1952   int dr = (op >> 16) & 0x1f;
1953   UINT32 res = (op & 0xffff) + ((op >> 5) & 0xff0000);
1954   if (IS_WRITEABLE(dr))
1955      m_r[dr] = res;
1956}
1957
1958
1959
1960//**************************************************************************
1961//  DAU FORM 1 IMPLEMENTATION
1962//**************************************************************************
1963
1964void dsp32c_device::d1_aMpp(UINT32 op)
1965{
1966   double xval = dau_read_pi_double_1st(op >> 14, 1);
1967   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
1968   double res = yval + DEFERRED_MULTIPLIER((op >> 26) & 7) * xval;
1969   int zpi = (op >> 0) & 0x7f;
1970   if (zpi != 7)
1971      dau_write_pi_double(zpi, res);
1972   dau_set_val_flags((op >> 21) & 3, res);
1973}
1974
1975
1976void dsp32c_device::d1_aMpm(UINT32 op)
1977{
1978   double xval = dau_read_pi_double_1st(op >> 14, 1);
1979   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
1980   double res = yval - DEFERRED_MULTIPLIER((op >> 26) & 7) * xval;
1981   int zpi = (op >> 0) & 0x7f;
1982   if (zpi != 7)
1983      dau_write_pi_double(zpi, res);
1984   dau_set_val_flags((op >> 21) & 3, res);
1985}
1986
1987
1988void dsp32c_device::d1_aMmp(UINT32 op)
1989{
1990   double xval = dau_read_pi_double_1st(op >> 14, 1);
1991   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
1992   double res = -yval + DEFERRED_MULTIPLIER((op >> 26) & 7) * xval;
1993   int zpi = (op >> 0) & 0x7f;
1994   if (zpi != 7)
1995      dau_write_pi_double(zpi, res);
1996   dau_set_val_flags((op >> 21) & 3, res);
1997}
1998
1999
2000void dsp32c_device::d1_aMmm(UINT32 op)
2001{
2002   double xval = dau_read_pi_double_1st(op >> 14, 1);
2003   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2004   double res = -yval - DEFERRED_MULTIPLIER((op >> 26) & 7) * xval;
2005   int zpi = (op >> 0) & 0x7f;
2006   if (zpi != 7)
2007      dau_write_pi_double(zpi, res);
2008   dau_set_val_flags((op >> 21) & 3, res);
2009}
2010
2011
2012void dsp32c_device::d1_0px(UINT32 op)
2013{
2014   double xval = dau_read_pi_double_1st(op >> 14, 1);
2015   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2016   double res = yval;
2017   int zpi = (op >> 0) & 0x7f;
2018   if (zpi != 7)
2019      dau_write_pi_double(zpi, res);
2020   dau_set_val_flags((op >> 21) & 3, res);
2021   (void)xval;
2022}
2023
2024
2025void dsp32c_device::d1_0mx(UINT32 op)
2026{
2027   double xval = dau_read_pi_double_1st(op >> 14, 1);
2028   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2029   double res = -yval;
2030   int zpi = (op >> 0) & 0x7f;
2031   if (zpi != 7)
2032      dau_write_pi_double(zpi, res);
2033   dau_set_val_flags((op >> 21) & 3, res);
2034   (void)xval;
2035}
2036
2037
2038void dsp32c_device::d1_1pp(UINT32 op)
2039{
2040   double xval = dau_read_pi_double_1st(op >> 14, 1);
2041   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2042   double res = yval + xval;
2043   int zpi = (op >> 0) & 0x7f;
2044   if (zpi != 7)
2045      dau_write_pi_double(zpi, res);
2046   dau_set_val_flags((op >> 21) & 3, res);
2047}
2048
2049
2050void dsp32c_device::d1_1pm(UINT32 op)
2051{
2052   double xval = dau_read_pi_double_1st(op >> 14, 1);
2053   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2054   double res = yval - xval;
2055   int zpi = (op >> 0) & 0x7f;
2056   if (zpi != 7)
2057      dau_write_pi_double(zpi, res);
2058   dau_set_val_flags((op >> 21) & 3, res);
2059}
2060
2061
2062void dsp32c_device::d1_1mp(UINT32 op)
2063{
2064   double xval = dau_read_pi_double_1st(op >> 14, 1);
2065   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2066   double res = -yval + xval;
2067   int zpi = (op >> 0) & 0x7f;
2068   if (zpi != 7)
2069      dau_write_pi_double(zpi, res);
2070   dau_set_val_flags((op >> 21) & 3, res);
2071}
2072
2073
2074void dsp32c_device::d1_1mm(UINT32 op)
2075{
2076   double xval = dau_read_pi_double_1st(op >> 14, 1);
2077   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2078   double res = -yval - xval;
2079   int zpi = (op >> 0) & 0x7f;
2080   if (zpi != 7)
2081      dau_write_pi_double(zpi, res);
2082   dau_set_val_flags((op >> 21) & 3, res);
2083}
2084
2085
2086void dsp32c_device::d1_aMppr(UINT32 op)
2087{
2088   unimplemented(op);
2089}
2090
2091
2092void dsp32c_device::d1_aMpmr(UINT32 op)
2093{
2094   unimplemented(op);
2095}
2096
2097
2098void dsp32c_device::d1_aMmpr(UINT32 op)
2099{
2100   unimplemented(op);
2101}
2102
2103
2104void dsp32c_device::d1_aMmmr(UINT32 op)
2105{
2106   unimplemented(op);
2107}
2108
2109
2110
2111//**************************************************************************
2112//  DAU FORM 2 IMPLEMENTATION
2113//**************************************************************************
2114
2115void dsp32c_device::d2_aMpp(UINT32 op)
2116{
2117   double xval = dau_read_pi_double_1st(op >> 14, 1);
2118   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2119   double res = m_a[(op >> 26) & 7] + yval * xval;
2120   int zpi = (op >> 0) & 0x7f;
2121   if (zpi != 7)
2122      dau_write_pi_double(zpi, yval);
2123   dau_set_val_flags((op >> 21) & 3, res);
2124}
2125
2126
2127void dsp32c_device::d2_aMpm(UINT32 op)
2128{
2129   double xval = dau_read_pi_double_1st(op >> 14, 1);
2130   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2131   double res = m_a[(op >> 26) & 7] - yval * xval;
2132   int zpi = (op >> 0) & 0x7f;
2133   if (zpi != 7)
2134      dau_write_pi_double(zpi, yval);
2135   dau_set_val_flags((op >> 21) & 3, res);
2136}
2137
2138
2139void dsp32c_device::d2_aMmp(UINT32 op)
2140{
2141   double xval = dau_read_pi_double_1st(op >> 14, 1);
2142   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2143   double res = -m_a[(op >> 26) & 7] + yval * xval;
2144   int zpi = (op >> 0) & 0x7f;
2145   if (zpi != 7)
2146      dau_write_pi_double(zpi, yval);
2147   dau_set_val_flags((op >> 21) & 3, res);
2148}
2149
2150
2151void dsp32c_device::d2_aMmm(UINT32 op)
2152{
2153   double xval = dau_read_pi_double_1st(op >> 14, 1);
2154   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2155   double res = -m_a[(op >> 26) & 7] - yval * xval;
2156   int zpi = (op >> 0) & 0x7f;
2157   if (zpi != 7)
2158      dau_write_pi_double(zpi, yval);
2159   dau_set_val_flags((op >> 21) & 3, res);
2160}
2161
2162
2163void dsp32c_device::d2_aMppr(UINT32 op)
2164{
2165   unimplemented(op);
2166}
2167
2168
2169void dsp32c_device::d2_aMpmr(UINT32 op)
2170{
2171   unimplemented(op);
2172}
2173
2174
2175void dsp32c_device::d2_aMmpr(UINT32 op)
2176{
2177   unimplemented(op);
2178}
2179
2180
2181void dsp32c_device::d2_aMmmr(UINT32 op)
2182{
2183   unimplemented(op);
2184}
2185
2186
2187
2188//**************************************************************************
2189//  DAU FORM 3 IMPLEMENTATION
2190//**************************************************************************
2191
2192void dsp32c_device::d3_aMpp(UINT32 op)
2193{
2194   double xval = dau_read_pi_double_1st(op >> 14, 1);
2195   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2196   double res = m_a[(op >> 26) & 7] + yval * xval;
2197   int zpi = (op >> 0) & 0x7f;
2198   if (zpi != 7)
2199      dau_write_pi_double(zpi, res);
2200   dau_set_val_flags((op >> 21) & 3, res);
2201}
2202
2203
2204void dsp32c_device::d3_aMpm(UINT32 op)
2205{
2206   double xval = dau_read_pi_double_1st(op >> 14, 1);
2207   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2208   double res = m_a[(op >> 26) & 7] - yval * xval;
2209   int zpi = (op >> 0) & 0x7f;
2210   if (zpi != 7)
2211      dau_write_pi_double(zpi, res);
2212   dau_set_val_flags((op >> 21) & 3, res);
2213}
2214
2215
2216void dsp32c_device::d3_aMmp(UINT32 op)
2217{
2218   double xval = dau_read_pi_double_1st(op >> 14, 1);
2219   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2220   double res = -m_a[(op >> 26) & 7] + yval * xval;
2221   int zpi = (op >> 0) & 0x7f;
2222   if (zpi != 7)
2223      dau_write_pi_double(zpi, res);
2224   dau_set_val_flags((op >> 21) & 3, res);
2225}
2226
2227
2228void dsp32c_device::d3_aMmm(UINT32 op)
2229{
2230   double xval = dau_read_pi_double_1st(op >> 14, 1);
2231   double yval = dau_read_pi_double_2nd(op >> 7, 1, xval);
2232   double res = -m_a[(op >> 26) & 7] - yval * xval;
2233   int zpi = (op >> 0) & 0x7f;
2234   if (zpi != 7)
2235      dau_write_pi_double(zpi, res);
2236   dau_set_val_flags((op >> 21) & 3, res);
2237}
2238
2239
2240void dsp32c_device::d3_aMppr(UINT32 op)
2241{
2242   unimplemented(op);
2243}
2244
2245
2246void dsp32c_device::d3_aMpmr(UINT32 op)
2247{
2248   unimplemented(op);
2249}
2250
2251
2252void dsp32c_device::d3_aMmpr(UINT32 op)
2253{
2254   unimplemented(op);
2255}
2256
2257
2258void dsp32c_device::d3_aMmmr(UINT32 op)
2259{
2260   unimplemented(op);
2261}
2262
2263
2264
2265//**************************************************************************
2266//  DAU FORM 4 IMPLEMENTATION
2267//**************************************************************************
2268
2269void dsp32c_device::d4_pp(UINT32 op)
2270{
2271   double xval = dau_read_pi_double_1st(op >> 14, 1);
2272   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2273   double res = yval + xval;
2274   int zpi = (op >> 0) & 0x7f;
2275   if (zpi != 7)
2276      dau_write_pi_double(zpi, yval);
2277   dau_set_val_flags((op >> 21) & 3, res);
2278}
2279
2280
2281void dsp32c_device::d4_pm(UINT32 op)
2282{
2283   double xval = dau_read_pi_double_1st(op >> 14, 1);
2284   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2285   double res = yval - xval;
2286   int zpi = (op >> 0) & 0x7f;
2287   if (zpi != 7)
2288      dau_write_pi_double(zpi, yval);
2289   dau_set_val_flags((op >> 21) & 3, res);
2290}
2291
2292
2293void dsp32c_device::d4_mp(UINT32 op)
2294{
2295   double xval = dau_read_pi_double_1st(op >> 14, 1);
2296   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2297   double res = -yval + xval;
2298   int zpi = (op >> 0) & 0x7f;
2299   if (zpi != 7)
2300      dau_write_pi_double(zpi, yval);
2301   dau_set_val_flags((op >> 21) & 3, res);
2302}
2303
2304
2305void dsp32c_device::d4_mm(UINT32 op)
2306{
2307   double xval = dau_read_pi_double_1st(op >> 14, 1);
2308   double yval = dau_read_pi_double_2nd(op >> 7, 0, xval);
2309   double res = -yval - xval;
2310   int zpi = (op >> 0) & 0x7f;
2311   if (zpi != 7)
2312      dau_write_pi_double(zpi, yval);
2313   dau_set_val_flags((op >> 21) & 3, res);
2314}
2315
2316
2317void dsp32c_device::d4_ppr(UINT32 op)
2318{
2319   unimplemented(op);
2320}
2321
2322
2323void dsp32c_device::d4_pmr(UINT32 op)
2324{
2325   unimplemented(op);
2326}
2327
2328
2329void dsp32c_device::d4_mpr(UINT32 op)
2330{
2331   unimplemented(op);
2332}
2333
2334
2335void dsp32c_device::d4_mmr(UINT32 op)
2336{
2337   unimplemented(op);
2338}
2339
2340
2341
2342//**************************************************************************
2343//  DAU FORM 5 IMPLEMENTATION
2344//**************************************************************************
2345
2346void dsp32c_device::d5_ic(UINT32 op)
2347{
2348   unimplemented(op);
2349}
2350
2351
2352void dsp32c_device::d5_oc(UINT32 op)
2353{
2354   unimplemented(op);
2355}
2356
2357
2358void dsp32c_device::d5_float(UINT32 op)
2359{
2360   double res = (double)(INT16)dau_read_pi_2bytes(op >> 7);
2361   int zpi = (op >> 0) & 0x7f;
2362   if (zpi != 7)
2363      dau_write_pi_double(zpi, res);
2364   dau_set_val_flags((op >> 21) & 3, res);
2365}
2366
2367
2368void dsp32c_device::d5_int(UINT32 op)
2369{
2370   double val = dau_read_pi_double_1st(op >> 7, 0);
2371   int zpi = (op >> 0) & 0x7f;
2372   INT16 res;
2373   if (!(DAUC & 0x10)) val = floor(val + 0.5);
2374   else val = ceil(val - 0.5);
2375   res = (INT16)val;
2376   if (zpi != 7)
2377      dau_write_pi_2bytes(zpi, res);
2378   dau_set_val_noflags((op >> 21) & 3, dsp_to_double(res << 16));
2379}
2380
2381
2382void dsp32c_device::d5_round(UINT32 op)
2383{
2384   double res = (double)(float)dau_read_pi_double_1st(op >> 7, 0);
2385   int zpi = (op >> 0) & 0x7f;
2386   if (zpi != 7)
2387      dau_write_pi_double(zpi, res);
2388   dau_set_val_flags((op >> 21) & 3, res);
2389}
2390
2391
2392void dsp32c_device::d5_ifalt(UINT32 op)
2393{
2394   int ar = (op >> 21) & 3;
2395   double res = m_a[ar];
2396   int zpi = (op >> 0) & 0x7f;
2397   if (NFLAG)
2398      res = dau_read_pi_double_1st(op >> 7, 0);
2399   if (zpi != 7)
2400      dau_write_pi_double(zpi, res);
2401   dau_set_val_noflags(ar, res);
2402}
2403
2404
2405void dsp32c_device::d5_ifaeq(UINT32 op)
2406{
2407   int ar = (op >> 21) & 3;
2408   double res = m_a[ar];
2409   int zpi = (op >> 0) & 0x7f;
2410   if (ZFLAG)
2411      res = dau_read_pi_double_1st(op >> 7, 0);
2412   if (zpi != 7)
2413      dau_write_pi_double(zpi, res);
2414   dau_set_val_noflags(ar, res);
2415}
2416
2417
2418void dsp32c_device::d5_ifagt(UINT32 op)
2419{
2420   int ar = (op >> 21) & 3;
2421   double res = m_a[ar];
2422   int zpi = (op >> 0) & 0x7f;
2423   if (!NFLAG && !ZFLAG)
2424      res = dau_read_pi_double_1st(op >> 7, 0);
2425   if (zpi != 7)
2426      dau_write_pi_double(zpi, res);
2427   dau_set_val_noflags(ar, res);
2428}
2429
2430
2431void dsp32c_device::d5_float24(UINT32 op)
2432{
2433   double res = (double)((INT32)(dau_read_pi_4bytes(op >> 7) << 8) >> 8);
2434   int zpi = (op >> 0) & 0x7f;
2435   if (zpi != 7)
2436      dau_write_pi_double(zpi, res);
2437   dau_set_val_flags((op >> 21) & 3, res);
2438}
2439
2440
2441void dsp32c_device::d5_int24(UINT32 op)
2442{
2443   double val = dau_read_pi_double_1st(op >> 7, 0);
2444   int zpi = (op >> 0) & 0x7f;
2445   INT32 res;
2446   if (!(DAUC & 0x10)) val = floor(val + 0.5);
2447   else val = ceil(val - 0.5);
2448   res = (INT32)val;
2449   if (res > 0x7fffff) res = 0x7fffff;
2450   else if (res < -0x800000) res = -0x800000;
2451   if (zpi != 7)
2452      dau_write_pi_4bytes(zpi, (INT32)(res << 8) >> 8);
2453   dau_set_val_noflags((op >> 21) & 3, dsp_to_double(res << 8));
2454}
2455
2456
2457void dsp32c_device::d5_ieee(UINT32 op)
2458{
2459   unimplemented(op);
2460}
2461
2462
2463void dsp32c_device::d5_dsp(UINT32 op)
2464{
2465   unimplemented(op);
2466}
2467
2468
2469void dsp32c_device::d5_seed(UINT32 op)
2470{
2471   UINT32 val = dau_read_pi_4bytes(op >> 7);
2472   INT32 res = val ^ 0x7fffffff;
2473   int zpi = (op >> 0) & 0x7f;
2474   if (zpi != 7)
2475      dau_write_pi_4bytes(zpi, res);
2476   dau_set_val_flags((op >> 21) & 3, dsp_to_double((INT32)res));
2477}
2478
2479
2480
2481//**************************************************************************
2482//  FUNCTION TABLE
2483//**************************************************************************
2484
2485void (dsp32c_device::*const dsp32c_device::s_dsp32ops[])(UINT32 op) =
2486{
2487   &dsp32c_device::nop,        &dsp32c_device::goto_t,     &dsp32c_device::goto_pl,    &dsp32c_device::goto_mi,    &dsp32c_device::goto_ne,    &dsp32c_device::goto_eq,    &dsp32c_device::goto_vc,    &dsp32c_device::goto_vs,    // 00
2488   &dsp32c_device::goto_cc,    &dsp32c_device::goto_cs,    &dsp32c_device::goto_ge,    &dsp32c_device::goto_lt,    &dsp32c_device::goto_gt,    &dsp32c_device::goto_le,    &dsp32c_device::goto_hi,    &dsp32c_device::goto_ls,
2489   &dsp32c_device::goto_auc,   &dsp32c_device::goto_aus,   &dsp32c_device::goto_age,   &dsp32c_device::goto_alt,   &dsp32c_device::goto_ane,   &dsp32c_device::goto_aeq,   &dsp32c_device::goto_avc,   &dsp32c_device::goto_avs,   // 01
2490   &dsp32c_device::goto_agt,   &dsp32c_device::goto_ale,   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2491   &dsp32c_device::goto_ibe,   &dsp32c_device::goto_ibf,   &dsp32c_device::goto_obf,   &dsp32c_device::goto_obe,   &dsp32c_device::goto_pde,   &dsp32c_device::goto_pdf,   &dsp32c_device::goto_pie,   &dsp32c_device::goto_pif,   // 02
2492   &dsp32c_device::goto_syc,   &dsp32c_device::goto_sys,   &dsp32c_device::goto_fbc,   &dsp32c_device::goto_fbs,   &dsp32c_device::goto_irq1lo,&dsp32c_device::goto_irq1hi,&dsp32c_device::goto_irq2lo,&dsp32c_device::goto_irq2hi,
2493   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 03
2494   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2495
2496   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 04
2497   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2498   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 05
2499   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2500   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   // 06
2501   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,
2502   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   // 07
2503   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,   &dsp32c_device::dec_goto,
2504
2505   &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       // 08
2506   &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,
2507   &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       // 09
2508   &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,       &dsp32c_device::call,
2509   &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     // 0a
2510   &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,
2511   &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     // 0b
2512   &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,     &dsp32c_device::add_si,
2513
2514   &dsp32c_device::add_ss,     &dsp32c_device::mul2_s,     &dsp32c_device::subr_ss,    &dsp32c_device::addr_ss,    &dsp32c_device::sub_ss,     &dsp32c_device::neg_s,      &dsp32c_device::andc_ss,    &dsp32c_device::cmp_ss,     // 0c
2515   &dsp32c_device::xor_ss,     &dsp32c_device::rcr_s,      &dsp32c_device::or_ss,      &dsp32c_device::rcl_s,      &dsp32c_device::shr_s,      &dsp32c_device::div2_s,     &dsp32c_device::and_ss,     &dsp32c_device::test_ss,
2516   &dsp32c_device::add_di,     &dsp32c_device::illegal,    &dsp32c_device::subr_di,    &dsp32c_device::addr_di,    &dsp32c_device::sub_di,     &dsp32c_device::illegal,    &dsp32c_device::andc_di,    &dsp32c_device::cmp_di,     // 0d
2517   &dsp32c_device::xor_di,     &dsp32c_device::illegal,    &dsp32c_device::or_di,      &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::and_di,     &dsp32c_device::test_di,
2518   &dsp32c_device::load_hi,    &dsp32c_device::load_hi,    &dsp32c_device::load_li,    &dsp32c_device::load_li,    &dsp32c_device::load_i,     &dsp32c_device::load_i,     &dsp32c_device::load_ei,    &dsp32c_device::load_ei,    // 0e
2519   &dsp32c_device::store_hi,   &dsp32c_device::store_hi,   &dsp32c_device::store_li,   &dsp32c_device::store_li,   &dsp32c_device::store_i,    &dsp32c_device::store_i,    &dsp32c_device::store_ei,   &dsp32c_device::store_ei,
2520   &dsp32c_device::load_hr,    &dsp32c_device::load_hr,    &dsp32c_device::load_lr,    &dsp32c_device::load_lr,    &dsp32c_device::load_r,     &dsp32c_device::load_r,     &dsp32c_device::load_er,    &dsp32c_device::load_er,    // 0f
2521   &dsp32c_device::store_hr,   &dsp32c_device::store_hr,   &dsp32c_device::store_lr,   &dsp32c_device::store_lr,   &dsp32c_device::store_r,    &dsp32c_device::store_r,    &dsp32c_device::store_er,   &dsp32c_device::store_er,
2522
2523   &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    // 10
2524   &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,
2525   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 11
2526   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2527   &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    // 12
2528   &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,
2529   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 13
2530   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2531
2532   &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    // 14
2533   &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,
2534   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 15
2535   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2536   &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpp,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    &dsp32c_device::d1_aMpm,    // 16
2537   &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmp,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,    &dsp32c_device::d1_aMmm,
2538   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 17
2539   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2540
2541   &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     &dsp32c_device::d1_0px,     // 18
2542   &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,     &dsp32c_device::d1_0mx,
2543   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 19
2544   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2545   &dsp32c_device::d1_1pp,     &dsp32c_device::d1_1pp,     &dsp32c_device::d1_1pp,     &dsp32c_device::d1_1pp,     &dsp32c_device::d1_1pm,     &dsp32c_device::d1_1pm,     &dsp32c_device::d1_1pm,     &dsp32c_device::d1_1pm,     // 1a
2546   &dsp32c_device::d1_1mp,     &dsp32c_device::d1_1mp,     &dsp32c_device::d1_1mp,     &dsp32c_device::d1_1mp,     &dsp32c_device::d1_1mm,     &dsp32c_device::d1_1mm,     &dsp32c_device::d1_1mm,     &dsp32c_device::d1_1mm,
2547   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMppr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   &dsp32c_device::d1_aMpmr,   // 1b
2548   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmpr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,   &dsp32c_device::d1_aMmmr,
2549
2550   &dsp32c_device::d4_pp,      &dsp32c_device::d4_pp,      &dsp32c_device::d4_pp,      &dsp32c_device::d4_pp,      &dsp32c_device::d4_pm,      &dsp32c_device::d4_pm,      &dsp32c_device::d4_pm,      &dsp32c_device::d4_pm,      // 1c
2551   &dsp32c_device::d4_mp,      &dsp32c_device::d4_mp,      &dsp32c_device::d4_mp,      &dsp32c_device::d4_mp,      &dsp32c_device::d4_mm,      &dsp32c_device::d4_mm,      &dsp32c_device::d4_mm,      &dsp32c_device::d4_mm,
2552   &dsp32c_device::d4_ppr,     &dsp32c_device::d4_ppr,     &dsp32c_device::d4_ppr,     &dsp32c_device::d4_ppr,     &dsp32c_device::d4_pmr,     &dsp32c_device::d4_pmr,     &dsp32c_device::d4_pmr,     &dsp32c_device::d4_pmr,     // 1d
2553   &dsp32c_device::d4_mpr,     &dsp32c_device::d4_mpr,     &dsp32c_device::d4_mpr,     &dsp32c_device::d4_mpr,     &dsp32c_device::d4_mmr,     &dsp32c_device::d4_mmr,     &dsp32c_device::d4_mmr,     &dsp32c_device::d4_mmr,
2554   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 1e
2555   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2556   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 1f
2557   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2558
2559   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 20
2560   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2561   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 21
2562   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2563   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 22
2564   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2565   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 23
2566   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2567
2568   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 24
2569   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2570   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 25
2571   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2572   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 26
2573   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2574   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 27
2575   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2576
2577   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 28
2578   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2579   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 29
2580   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2581   &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpp,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    &dsp32c_device::d2_aMpm,    // 2a
2582   &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmp,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,    &dsp32c_device::d2_aMmm,
2583   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMppr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   &dsp32c_device::d2_aMpmr,   // 2b
2584   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmpr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,   &dsp32c_device::d2_aMmmr,
2585
2586   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 2c
2587   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2588   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 2d
2589   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2590   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 2e
2591   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2592   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 2f
2593   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2594
2595   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 30
2596   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2597   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 31
2598   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2599   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 32
2600   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2601   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 33
2602   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2603
2604   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 34
2605   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2606   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 35
2607   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2608   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 36
2609   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2610   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 37
2611   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2612
2613   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 38
2614   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2615   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 39
2616   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2617   &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpp,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    &dsp32c_device::d3_aMpm,    // 3a
2618   &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmp,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,    &dsp32c_device::d3_aMmm,
2619   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMppr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   &dsp32c_device::d3_aMpmr,   // 3b
2620   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmpr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,   &dsp32c_device::d3_aMmmr,
2621
2622   &dsp32c_device::d5_ic,      &dsp32c_device::d5_ic,      &dsp32c_device::d5_ic,      &dsp32c_device::d5_ic,      &dsp32c_device::d5_oc,      &dsp32c_device::d5_oc,      &dsp32c_device::d5_oc,      &dsp32c_device::d5_oc,      // 3c
2623   &dsp32c_device::d5_float,   &dsp32c_device::d5_float,   &dsp32c_device::d5_float,   &dsp32c_device::d5_float,   &dsp32c_device::d5_int,     &dsp32c_device::d5_int,     &dsp32c_device::d5_int,     &dsp32c_device::d5_int,
2624   &dsp32c_device::d5_round,   &dsp32c_device::d5_round,   &dsp32c_device::d5_round,   &dsp32c_device::d5_round,   &dsp32c_device::d5_ifalt,   &dsp32c_device::d5_ifalt,   &dsp32c_device::d5_ifalt,   &dsp32c_device::d5_ifalt,   // 3d
2625   &dsp32c_device::d5_ifaeq,   &dsp32c_device::d5_ifaeq,   &dsp32c_device::d5_ifaeq,   &dsp32c_device::d5_ifaeq,   &dsp32c_device::d5_ifagt,   &dsp32c_device::d5_ifagt,   &dsp32c_device::d5_ifagt,   &dsp32c_device::d5_ifagt,
2626   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 3e
2627   &dsp32c_device::d5_float24, &dsp32c_device::d5_float24, &dsp32c_device::d5_float24, &dsp32c_device::d5_float24, &dsp32c_device::d5_int24,   &dsp32c_device::d5_int24,   &dsp32c_device::d5_int24,   &dsp32c_device::d5_int24,
2628   &dsp32c_device::d5_ieee,    &dsp32c_device::d5_ieee,    &dsp32c_device::d5_ieee,    &dsp32c_device::d5_ieee,    &dsp32c_device::d5_dsp,     &dsp32c_device::d5_dsp,     &dsp32c_device::d5_dsp,     &dsp32c_device::d5_dsp,     // 3f
2629   &dsp32c_device::d5_seed,    &dsp32c_device::d5_seed,    &dsp32c_device::d5_seed,    &dsp32c_device::d5_seed,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2630
2631   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 40
2632   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2633   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 41
2634   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2635   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 42
2636   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2637   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 43
2638   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2639
2640   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 44
2641   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2642   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 45
2643   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2644   &dsp32c_device::do_i,       &dsp32c_device::do_r,       &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 46
2645   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2646   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 47
2647   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2648
2649   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 48
2650   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2651   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 49
2652   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2653   &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    // 4a
2654   &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,
2655   &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    // 4b
2656   &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,    &dsp32c_device::adde_si,
2657
2658   &dsp32c_device::adde_ss,    &dsp32c_device::mul2e_s,    &dsp32c_device::subre_ss,   &dsp32c_device::addre_ss,   &dsp32c_device::sube_ss,    &dsp32c_device::nege_s,     &dsp32c_device::andce_ss,   &dsp32c_device::cmpe_ss,    // 4c
2659   &dsp32c_device::xore_ss,    &dsp32c_device::rcre_s,     &dsp32c_device::ore_ss,     &dsp32c_device::rcle_s,     &dsp32c_device::shre_s,     &dsp32c_device::div2e_s,    &dsp32c_device::ande_ss,    &dsp32c_device::teste_ss,
2660   &dsp32c_device::adde_di,    &dsp32c_device::illegal,    &dsp32c_device::subre_di,   &dsp32c_device::addre_di,   &dsp32c_device::sube_di,    &dsp32c_device::illegal,    &dsp32c_device::andce_di,   &dsp32c_device::cmpe_di,    // 4d
2661   &dsp32c_device::xore_di,    &dsp32c_device::illegal,    &dsp32c_device::ore_di,     &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::ande_di,    &dsp32c_device::teste_di,
2662   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 4e
2663   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2664   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    // 4f
2665   &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,    &dsp32c_device::illegal,
2666
2667   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 50
2668   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2669   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 51
2670   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2671   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 52
2672   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2673   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 53
2674   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2675
2676   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 54
2677   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2678   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 55
2679   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2680   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 56
2681   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2682   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 57
2683   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2684
2685   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 58
2686   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2687   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 59
2688   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2689   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5a
2690   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2691   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5b
2692   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2693
2694   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5c
2695   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2696   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5d
2697   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2698   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5e
2699   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2700   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     // 5f
2701   &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,     &dsp32c_device::goto24,
2702
2703   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 60
2704   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2705   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 61
2706   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2707   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 62
2708   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2709   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 63
2710   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2711
2712   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 64
2713   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2714   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 65
2715   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2716   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 66
2717   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2718   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 67
2719   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2720
2721   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 68
2722   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2723   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 69
2724   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2725   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6a
2726   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2727   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6b
2728   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2729
2730   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6c
2731   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2732   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6d
2733   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2734   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6e
2735   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2736   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     // 6f
2737   &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,     &dsp32c_device::load24,
2738
2739   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 70
2740   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2741   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 71
2742   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2743   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 72
2744   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2745   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 73
2746   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2747
2748   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 74
2749   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2750   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 75
2751   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2752   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 76
2753   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2754   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 77
2755   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2756
2757   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 78
2758   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2759   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 79
2760   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2761   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7a
2762   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2763   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7b
2764   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2765
2766   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7c
2767   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2768   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7d
2769   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2770   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7e
2771   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,
2772   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     // 7f
2773   &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24,     &dsp32c_device::call24
2774};
2775
2776
2777/*
2778
2779    Most common OPs in Race Drivin':
2780
2781301681217 - op   0 - nop
2782164890391 - op 4A1 - adde_si
278399210113 - op 661 - load24
278486010010 - op  F7 - load_er
278561148739 - op 4D4 - sube_di
278652693763 - op 180 - d1_0px
278741525754 - op  FF - store_er
278835033321 - op 380 - d3_aMpp
278931621151 - op 4C0 - adde_ss
279028076244 - op 660 - load24
279119190505 - op 4C1 - mul2e_s
279213270852 - op  F5 - load_r
279312535169 - op 1A4 - d1_1pm
279412265141 - op 4C4 - sube_ss
279510748211 - op 4CD - div2e_s
279610493660 - op  FD - store_r
2797 9721263 - op 189
2798 9415685 - op 3C8
2799 9294148 - op 3D5
2800 8887846 - op 1A1
2801 8788648 - op 381
2802 8185239 - op 300
2803 7241256 - op 383
2804 6877349 - op 4A3
2805 6832295 - op 181
2806 6601270 - op 3E8
2807 6562483 - op 4A4
2808 6553514 - op 3C9
2809 6270430 - op 280
2810 6041485 - op 1A0
2811 5299529 - op 304
2812 5110926 - op 382
2813 4922253 - op 363
2814 4603670 - op 4D7
2815 4164327 - op 4AE
2816 3980085 - op 3EC
2817 3599198 - op 3CC
2818 3543878 - op 3D0
2819 3489158 - op   4
2820 3463235 - op 321
2821 3335995 - op 3F9
2822 3001546 - op 4CE
2823 2882940 - op 129
2824 2882940 - op 1A5
2825 2882940 - op 342
2826 2841981 - op 360
2827 2663417 - op  FB
2828 2059640 - op 3ED
2829 1867166 - op 1A8
2830 1830789 - op 305
2831 1753312 - op 301
2832 1726866 - op   5
2833 1594991 - op  12
2834 1571286 - op  19
2835 1507644 - op  A2
2836 1418846 - op 3CD
2837 1273134 - op  F3
2838 1177914 - op 4C7
2839 1175720 - op 188
2840 1091848 - op 3E9
2841 1088206 - op 6FF
2842 1088204 - op 4CA
2843 1012639 - op 101
2844  939617 - op 4C5
2845
2846*/
Property changes on: trunk/src/emu/cpu/dsp32/dsp32ops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/dsp32/dsp32.c
r28738r28739
2424
2525    In addition, there are several optimizations enabled which make
2626    assumptions about the code which may not be valid for other
27    applications. Check dsp32ops.c for details.
27    applications. Check dsp32ops.inc for details.
2828
2929***************************************************************************/
3030
r28738r28739
565565//  CORE INCLUDE
566566//**************************************************************************
567567
568#include "dsp32ops.c"
568#include "dsp32ops.inc"
569569
570570
571571
trunk/src/emu/cpu/i860/i860dec.c
r28738r28739
1/***************************************************************************
2
3    i860dec.c
4
5    Execution engine for the Intel i860 emulator.
6
7    Copyright (C) 1995-present Jason Eckhardt (jle@rice.edu)
8    Released for general non-commercial use under the MAME license
9    with the additional requirement that you are free to use and
10    redistribute this code in modified or unmodified form, provided
11    you list me in the credits.
12    Visit http://mamedev.org for licensing and usage restrictions.
13
14***************************************************************************/
15
16/*
17 * References:
18 *  `i860 Microprocessor Programmer's Reference Manual', Intel, 1990.
19 *
20 * This code was originally written by Jason Eckhardt as part of an
21 * emulator for some i860-based Unix workstations (early 1990's) such
22 * as the Stardent Vistra 800 series and the OkiStation/i860 7300 series.
23 * The code you are reading now is the i860 CPU portion only, which has
24 * been adapted to (and simplified for) MAME.
25 * MAME-specific notes:
26 * - i860XR emulation only (i860XP unnecessary for MAME).
27 * - No emulation of data and instruction caches (unnecessary for MAME version).
28 * - No emulation of DIM mode or CS8 mode (unnecessary for MAME version).
29 * - No BL/IL/locked sequences (unnecessary for MAME).
30 * - Emulate only the i860's LSB-first mode (BE = 0).
31 * Generic notes:
32 * - There is some amount of code duplication (e.g., see the
33 *   various insn_* routines for the branches and FP routines) that
34 *   could be eliminated.
35 * - The host's floating point types are used to emulate the i860's
36 *   floating point.  Should probably be made machine independent by
37 *   using an IEEE FP emulation library.  On the other hand, most machines
38 *   today also use IEEE FP.
39 *
40 */
41#include "i860.h"
42#include <math.h>
43
44
45#undef HOST_MSB
46
47#undef  TRACE_RDWR_MEM
48#undef  TRACE_ADDR_TRANSLATION
49#undef  TRACE_PAGE_FAULT
50#define TRACE_UNDEFINED_I860
51#undef  TRACE_EXT_INT
52#define TRACE_UNALIGNED_MEM
53
54
55/* Defines for pending_trap.  */
56enum {
57   TRAP_NORMAL        = 0x01,
58   TRAP_IN_DELAY_SLOT = 0x02,
59   TRAP_WAS_EXTERNAL  = 0x04
60};
61
62
63/*  TODO: THESE WILL BE REPLACED BY MAME FUNCTIONS
64#define BYTE_REV32(t)   \
65  do { \
66    (t) = ((UINT32)(t) >> 16) | ((UINT32)(t) << 16); \
67    (t) = (((UINT32)(t) >> 8) & 0x00ff00ff) | (((UINT32)(t) << 8) & 0xff00ff00); \
68  } while (0);
69
70#define BYTE_REV16(t)   \
71  do { \
72    (t) = (((UINT16)(t) >> 8) & 0x00ff) | (((UINT16)(t) << 8) & 0xff00); \
73  } while (0);
74#endif
75*/
76
77
78/* Get/set general register value -- watch for r0 on writes.  */
79#define get_iregval(gr)       (m_iregs[(gr)])
80#define set_iregval(gr, val)  (m_iregs[(gr)] = ((gr) == 0 ? 0 : (val)))
81
82float i860_cpu_device::get_fregval_s (int fr)
83{
84   float f;
85   UINT32 x;
86   UINT8 *tp;
87   fr = 31 - fr;
88   tp = (UINT8 *)(&m_frg[fr * 4]);
89   x = ((UINT32)tp[0] << 24) | ((UINT32)tp[1] << 16) |
90      ((UINT32)tp[2] << 8) | ((UINT32)tp[3]);
91   f = *(float *)(&x);
92   return f;
93}
94
95double i860_cpu_device::get_fregval_d (int fr)
96{
97   double d;
98   UINT64 x;
99   UINT8 *tp;
100   fr = 31 - (fr + 1);
101   tp = (UINT8 *)(&m_frg[fr * 4]);
102   x = ((UINT64)tp[0] << 56) | ((UINT64)tp[1] << 48) |
103      ((UINT64)tp[2] << 40) | ((UINT64)tp[3] << 32) |
104      ((UINT64)tp[4] << 24) | ((UINT64)tp[5] << 16) |
105      ((UINT64)tp[6] << 8) | ((UINT64)tp[7]);
106   d = *(double *)(&x);
107   return d;
108}
109
110void i860_cpu_device::set_fregval_s (int fr, float s)
111{
112   UINT8 *f = (UINT8 *)&s;
113   UINT8 *tp;
114   int newfr = 31 - fr;
115   float jj = s;
116   tp = (UINT8 *)(&m_frg[newfr * 4]);
117
118   f = (UINT8 *)(&jj);
119   if (fr == 0 || fr == 1)
120   {
121      tp[0] = 0; tp[1] = 0; tp[2] = 0; tp[3] = 0;
122   }
123   else
124   {
125#ifndef HOST_MSB
126      tp[0] = f[3]; tp[1] = f[2]; tp[2] = f[1]; tp[3] = f[0];
127#else
128      tp[0] = f[0]; tp[1] = f[1]; tp[2] = f[2]; tp[3] = f[3];
129#endif
130   }
131}
132
133void i860_cpu_device::set_fregval_d (int fr, double d)
134{
135   UINT8 *f = (UINT8 *)&d;
136   UINT8 *tp;
137   int newfr = 31 - (fr + 1);
138   double jj = d;
139   tp = (UINT8 *)(&m_frg[newfr * 4]);
140
141   f = (UINT8 *)(&jj);
142
143   if (fr == 0)
144   {
145      tp[0] = 0; tp[1] = 0; tp[2] = 0; tp[3] = 0;
146      tp[4] = 0; tp[5] = 0; tp[6] = 0; tp[7] = 0;
147   }
148   else
149   {
150#ifndef HOST_MSB
151      tp[0] = f[7]; tp[1] = f[6]; tp[2] = f[5]; tp[3] = f[4];
152      tp[4] = f[3]; tp[5] = f[2]; tp[6] = f[1]; tp[7] = f[0];
153#else
154      tp[0] = f[0]; tp[1] = f[1]; tp[2] = f[2]; tp[3] = f[3];
155      tp[4] = f[4]; tp[5] = f[5]; tp[6] = f[6]; tp[7] = f[7];
156#endif
157   }
158}
159
160
161/* Macros for accessing register fields in instruction word.  */
162#define get_isrc1(bits) (((bits) >> 11) & 0x1f)
163#define get_isrc2(bits) (((bits) >> 21) & 0x1f)
164#define get_idest(bits) (((bits) >> 16) & 0x1f)
165#define get_fsrc1(bits) (((bits) >> 11) & 0x1f)
166#define get_fsrc2(bits) (((bits) >> 21) & 0x1f)
167#define get_fdest(bits) (((bits) >> 16) & 0x1f)
168#define get_creg(bits) (((bits) >> 21) & 0x7)
169
170/* Macros for accessing immediate fields.  */
171/* 16-bit immediate.  */
172#define get_imm16(insn) ((insn) & 0xffff)
173
174/* A mask for all the trap bits of the PSR (FT, DAT, IAT, IN, IT, or
175   bits [12..8]).  */
176#define PSR_ALL_TRAP_BITS_MASK 0x00001f00
177
178/* A mask for PSR bits which can only be changed from supervisor level.  */
179#define PSR_SUPERVISOR_ONLY_MASK 0x0000fff3
180
181
182/* PSR: BR flag (PSR[0]):  set/get.  */
183#define GET_PSR_BR()  ((m_cregs[CR_PSR] >> 0) & 1)
184#define SET_PSR_BR(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 0)) | (((val) & 1) << 0))
185
186/* PSR: BW flag (PSR[1]):  set/get.  */
187#define GET_PSR_BW()  ((m_cregs[CR_PSR] >> 1) & 1)
188#define SET_PSR_BW(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 1)) | (((val) & 1) << 1))
189
190/* PSR: Shift count (PSR[21..17]):  set/get.  */
191#define GET_PSR_SC()  ((m_cregs[CR_PSR] >> 17) & 0x1f)
192#define SET_PSR_SC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x003e0000) | (((val) & 0x1f) << 17))
193
194/* PSR: CC flag (PSR[2]):  set/get.  */
195#define GET_PSR_CC()  ((m_cregs[CR_PSR] >> 2) & 1)
196#define SET_PSR_CC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 2)) | (((val) & 1) << 2))
197
198/* PSR: IT flag (PSR[8]):  set/get.  */
199#define GET_PSR_IT()  ((m_cregs[CR_PSR] >> 8) & 1)
200#define SET_PSR_IT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 8)) | (((val) & 1) << 8))
201
202/* PSR: IN flag (PSR[9]):  set/get.  */
203#define GET_PSR_IN()  ((m_cregs[CR_PSR] >> 9) & 1)
204#define SET_PSR_IN(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 9)) | (((val) & 1) << 9))
205
206/* PSR: IAT flag (PSR[10]):  set/get.  */
207#define GET_PSR_IAT()  ((m_cregs[CR_PSR] >> 10) & 1)
208#define SET_PSR_IAT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 10)) | (((val) & 1) << 10))
209
210/* PSR: DAT flag (PSR[11]):  set/get.  */
211#define GET_PSR_DAT()  ((m_cregs[CR_PSR] >> 11) & 1)
212#define SET_PSR_DAT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 11)) | (((val) & 1) << 11))
213
214/* PSR: FT flag (PSR[12]):  set/get.  */
215#define GET_PSR_FT()  ((m_cregs[CR_PSR] >> 12) & 1)
216#define SET_PSR_FT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 12)) | (((val) & 1) << 12))
217
218/* PSR: DS flag (PSR[13]):  set/get.  */
219#define GET_PSR_DS()  ((m_cregs[CR_PSR] >> 13) & 1)
220#define SET_PSR_DS(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 13)) | (((val) & 1) << 13))
221
222/* PSR: DIM flag (PSR[14]):  set/get.  */
223#define GET_PSR_DIM()  ((m_cregs[CR_PSR] >> 14) & 1)
224#define SET_PSR_DIM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 14)) | (((val) & 1) << 14))
225
226/* PSR: LCC (PSR[3]):  set/get.  */
227#define GET_PSR_LCC()  ((m_cregs[CR_PSR] >> 3) & 1)
228#define SET_PSR_LCC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 3)) | (((val) & 1) << 3))
229
230/* PSR: IM (PSR[4]):  set/get.  */
231#define GET_PSR_IM()  ((m_cregs[CR_PSR] >> 4) & 1)
232#define SET_PSR_IM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 4)) | (((val) & 1) << 4))
233
234/* PSR: PIM (PSR[5]):  set/get.  */
235#define GET_PSR_PIM()  ((m_cregs[CR_PSR] >> 5) & 1)
236#define SET_PSR_PIM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 5)) | (((val) & 1) << 5))
237
238/* PSR: U (PSR[6]):  set/get.  */
239#define GET_PSR_U()  ((m_cregs[CR_PSR] >> 6) & 1)
240#define SET_PSR_U(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 6)) | (((val) & 1) << 6))
241
242/* PSR: PU (PSR[7]):  set/get.  */
243#define GET_PSR_PU()  ((m_cregs[CR_PSR] >> 7) & 1)
244#define SET_PSR_PU(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 7)) | (((val) & 1) << 7))
245
246/* PSR: Pixel size (PSR[23..22]):  set/get.  */
247#define GET_PSR_PS()  ((m_cregs[CR_PSR] >> 22) & 0x3)
248#define SET_PSR_PS(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x00c00000) | (((val) & 0x3) << 22))
249
250/* PSR: Pixel mask (PSR[31..24]):  set/get.  */
251#define GET_PSR_PM()  ((m_cregs[CR_PSR] >> 24) & 0xff)
252#define SET_PSR_PM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0xff000000) | (((val) & 0xff) << 24))
253
254/* EPSR: WP bit (EPSR[14]):  set/get.  */
255#define GET_EPSR_WP()  ((m_cregs[CR_EPSR] >> 14) & 1)
256#define SET_EPSR_WP(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 14)) | (((val) & 1) << 14))
257
258/* EPSR: INT bit (EPSR[17]):  set/get.  */
259#define GET_EPSR_INT()  ((m_cregs[CR_EPSR] >> 17) & 1)
260#define SET_EPSR_INT(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 17)) | (((val) & 1) << 17))
261
262
263/* EPSR: OF flag (EPSR[24]):  set/get.  */
264#define GET_EPSR_OF()  ((m_cregs[CR_EPSR] >> 24) & 1)
265#define SET_EPSR_OF(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 24)) | (((val) & 1) << 24))
266
267/* EPSR: BE flag (EPSR[23]):  set/get.  */
268#define GET_EPSR_BE()  ((m_cregs[CR_EPSR] >> 23) & 1)
269#define SET_EPSR_BE(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 23)) | (((val) & 1) << 23))
270
271/* DIRBASE: ATE bit (DIRBASE[0]):  get.  */
272#define GET_DIRBASE_ATE()  (m_cregs[CR_DIRBASE] & 1)
273
274/* DIRBASE: CS8 bit (DIRBASE[7]):  get.  */
275#define GET_DIRBASE_CS8()  ((m_cregs[CR_DIRBASE] >> 7) & 1)
276
277/* FSR: FTE bit (FSR[5]):  set/get.  */
278#define GET_FSR_FTE()  ((m_cregs[CR_FSR] >> 5) & 1)
279#define SET_FSR_FTE(val)  (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 5)) | (((val) & 1) << 5))
280
281/* FSR: SE bit (FSR[8]):  set/get.  */
282#define GET_FSR_SE()  ((m_cregs[CR_FSR] >> 8) & 1)
283#define SET_FSR_SE(val)  (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 8)) | (((val) & 1) << 8))
284
285
286int i860_cpu_device::has_delay_slot(UINT32 insn)
287{
288   int opc = (insn >> 26) & 0x3f;
289   if (opc == 0x10 || opc == 0x1a || opc == 0x1b || opc == 0x1d ||
290      opc == 0x1f || opc == 0x2d || (opc == 0x13 && (insn & 3) == 2))
291   return 1;
292   return 0;
293}
294
295/* This is the external interface for asserting/deasserting pins on
296   the i860.  */
297void i860_cpu_device::i860_set_pin (int pin, int val)
298{
299   if (pin == DEC_PIN_BUS_HOLD)
300      m_pin_bus_hold = val;
301   else if (pin == DEC_PIN_RESET)
302      m_pin_reset = val;
303   else
304      assert (0);
305}
306
307
308/* This is the external interface for indicating an external interrupt
309   to the i860.  */
310void i860_cpu_device::i860_gen_interrupt()
311{
312   /* If interrupts are enabled, then set PSR.IN and prepare for trap.
313      Otherwise, the external interrupt is ignored.  We also set
314      bit EPSR.INT (which tracks the INT pin).  */
315   if (GET_PSR_IM ())
316   {
317      SET_PSR_IN (1);
318      SET_EPSR_INT (1);
319      m_pending_trap = TRAP_WAS_EXTERNAL;
320   }
321
322#ifdef TRACE_EXT_INT
323   fprintf (stderr, "i860_gen_interrupt: External interrupt received ");
324   if (GET_PSR_IM ())
325      fprintf (stderr, "[PSR.IN set, preparing to trap]\n");
326   else
327      fprintf (stderr, "[ignored (interrupts disabled)]\n");
328#endif
329}
330
331
332/* Fetch instructions from instruction cache.
333   Note: The instruction cache is not implemented for MAME version,
334   this just fetches and returns 1 instruction from memory.  */
335UINT32 i860_cpu_device::ifetch (UINT32 pc)
336{
337   UINT32 phys_pc = 0;
338   UINT32 w1 = 0;
339
340   /* If virtual mode, get translation.  */
341   if (GET_DIRBASE_ATE ())
342   {
343      phys_pc = get_address_translation (pc, 0  /* is_dataref */, 0 /* is_write */);
344      m_exiting_ifetch = 0;
345      if (m_pending_trap && (GET_PSR_DAT () || GET_PSR_IAT ()))
346      {
347         m_exiting_ifetch = 1;
348         return 0xffeeffee;
349      }
350   }
351   else
352      phys_pc = pc;
353
354   /* Since i860 instructions are always stored LSB first (regardless of
355      the BE bit), we need to adjust the instruction below on MSB hosts.  */
356   w1 = m_program->read_dword(phys_pc);
357#ifdef HOST_MSB
358   BYTE_REV32 (w1);
359#endif /* HOST_MSB.  */
360   return w1;
361}
362
363
364/* Given a virtual address, perform the i860 address translation and
365   return the corresponding physical address.
366     vaddr:      virtual address
367     is_dataref: 1 = load/store, 0 = instruction fetch.
368     is_write:   1 = writing to vaddr, 0 = reading from vaddr
369   The last two arguments are only used to determine what types
370   of traps should be taken.
371
372   Page tables must always be in memory (not cached).  So the routine
373   here only accesses memory.  */
374UINT32 i860_cpu_device::get_address_translation (UINT32 vaddr, int is_dataref, int is_write)
375{
376   UINT32 vdir = (vaddr >> 22) & 0x3ff;
377   UINT32 vpage = (vaddr >> 12) & 0x3ff;
378   UINT32 voffset = vaddr & 0xfff;
379   UINT32 dtb = (m_cregs[CR_DIRBASE]) & 0xfffff000;
380   UINT32 pg_dir_entry_a = 0;
381   UINT32 pg_dir_entry = 0;
382   UINT32 pg_tbl_entry_a = 0;
383   UINT32 pg_tbl_entry = 0;
384   UINT32 pfa1 = 0;
385   UINT32 pfa2 = 0;
386   UINT32 ret = 0;
387   UINT32 ttpde = 0;
388   UINT32 ttpte = 0;
389
390   assert (GET_DIRBASE_ATE ());
391
392   /* Get page directory entry at DTB:DIR:00.  */
393   pg_dir_entry_a = dtb | (vdir << 2);
394   pg_dir_entry = m_program->read_dword(pg_dir_entry_a);
395#ifdef HOST_MSB
396   BYTE_REV32 (pg_dir_entry);
397#endif
398
399   /* Check for non-present PDE.  */
400   if (!(pg_dir_entry & 1))
401   {
402      /* PDE is not present, generate DAT or IAT.  */
403      if (is_dataref)
404         SET_PSR_DAT (1);
405      else
406         SET_PSR_IAT (1);
407      m_pending_trap = 1;
408
409      /* Dummy return.  */
410      return 0;
411   }
412
413   /* PDE Check for write protection violations.  */
414   if (is_write && is_dataref
415      && !(pg_dir_entry & 2)                  /* W = 0.  */
416      && (GET_PSR_U () || GET_EPSR_WP ()))   /* PSR_U = 1 or EPSR_WP = 1.  */
417   {
418      SET_PSR_DAT (1);
419      m_pending_trap = 1;
420      /* Dummy return.  */
421      return 0;
422   }
423
424   /* PDE Check for user-mode access to supervisor pages.  */
425   if (GET_PSR_U ()
426      && !(pg_dir_entry & 4))                 /* U = 0.  */
427   {
428      if (is_dataref)
429         SET_PSR_DAT (1);
430      else
431         SET_PSR_IAT (1);
432      m_pending_trap = 1;
433      /* Dummy return.  */
434      return 0;
435   }
436
437   /* FIXME: How exactly to handle A check/update?.  */
438
439   /* Get page table entry at PFA1:PAGE:00.  */
440   pfa1 = pg_dir_entry & 0xfffff000;
441   pg_tbl_entry_a = pfa1 | (vpage << 2);
442   pg_tbl_entry = m_program->read_dword(pg_tbl_entry_a);
443#ifdef HOST_MSB
444   BYTE_REV32 (pg_tbl_entry);
445#endif
446
447   /* Check for non-present PTE.  */
448   if (!(pg_tbl_entry & 1))
449   {
450      /* PTE is not present, generate DAT or IAT.  */
451      if (is_dataref)
452         SET_PSR_DAT (1);
453      else
454         SET_PSR_IAT (1);
455      m_pending_trap = 1;
456
457      /* Dummy return.  */
458      return 0;
459   }
460
461   /* PTE Check for write protection violations.  */
462   if (is_write && is_dataref
463      && !(pg_tbl_entry & 2)                  /* W = 0.  */
464      && (GET_PSR_U () || GET_EPSR_WP ()))   /* PSR_U = 1 or EPSR_WP = 1.  */
465   {
466      SET_PSR_DAT (1);
467      m_pending_trap = 1;
468      /* Dummy return.  */
469      return 0;
470   }
471
472   /* PTE Check for user-mode access to supervisor pages.  */
473   if (GET_PSR_U ()
474      && !(pg_tbl_entry & 4))                 /* U = 0.  */
475   {
476      if (is_dataref)
477         SET_PSR_DAT (1);
478      else
479         SET_PSR_IAT (1);
480      m_pending_trap = 1;
481      /* Dummy return.  */
482      return 0;
483   }
484
485   /* Update A bit and check D bit.  */
486   ttpde = pg_dir_entry | 0x20;
487   ttpte = pg_tbl_entry | 0x20;
488#ifdef HOST_MSB
489   BYTE_REV32 (ttpde);
490   BYTE_REV32 (ttpte);
491#endif
492   m_program->write_dword(pg_dir_entry_a, ttpde);
493   m_program->write_dword(pg_tbl_entry_a, ttpte);
494
495   if (is_write && is_dataref && (pg_tbl_entry & 0x40) == 0)
496   {
497      /* fprintf(stderr, "DAT trap on write without dirty bit v0x%08x/p0x%08x\n",
498         vaddr, (pg_tbl_entry & ~0xfff)|voffset); */
499      SET_PSR_DAT (1);
500      m_pending_trap = 1;
501      /* Dummy return.  */
502      return 0;
503   }
504
505   pfa2 = (pg_tbl_entry & 0xfffff000);
506   ret = pfa2 | voffset;
507
508#ifdef TRACE_ADDR_TRANSLATION
509   fprintf (stderr, "get_address_translation: virt(0x%08x) -> phys(0x%08x)\n",
510            vaddr, ret);
511#endif
512
513   return ret;
514}
515
516
517/* Read memory emulation.
518     addr = address to read.
519     size = size of read in bytes.  */
520UINT32 i860_cpu_device::readmemi_emu (UINT32 addr, int size)
521{
522#ifdef TRACE_RDWR_MEM
523   fprintf (stderr, "readmemi_emu: (ATE=%d) addr = 0x%08x, size = %d\n",
524            GET_DIRBASE_ATE (), addr, size);
525#endif
526
527   /* If virtual mode, do translation.  */
528   if (GET_DIRBASE_ATE ())
529   {
530      UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 0 /* is_write */);
531      if (m_pending_trap && (GET_PSR_IAT () || GET_PSR_DAT ()))
532      {
533#ifdef TRACE_PAGE_FAULT
534         fprintf (stderr, "0x%08x: ## Page fault (readmemi_emu).\n",
535                  m_pc);
536#endif
537         m_exiting_readmem = 1;
538         return 0;
539      }
540      addr = phys;
541   }
542
543   /* First check for match to db register (before read).  */
544   if (((addr & ~(size - 1)) == m_cregs[CR_DB]) && GET_PSR_BR ())
545   {
546      SET_PSR_DAT (1);
547      m_pending_trap = 1;
548      return 0;
549   }
550
551   /* Now do the actual read.  */
552   if (size == 1)
553   {
554      UINT32 ret = m_program->read_byte(addr);
555      return ret & 0xff;
556   }
557   else if (size == 2)
558   {
559      UINT32 ret = m_program->read_word(addr);
560#ifdef HOST_MSB
561      BYTE_REV16 (ret);
562#endif
563      return ret & 0xffff;
564   }
565   else if (size == 4)
566   {
567      UINT32 ret = m_program->read_dword(addr);
568#ifdef HOST_MSB
569      BYTE_REV32 (ret);
570#endif
571      return ret;
572   }
573   else
574      assert (0);
575
576   return 0;
577}
578
579
580/* Write memory emulation.
581     addr = address to write.
582     size = size of write in bytes.
583     data = data to write.  */
584void i860_cpu_device::writememi_emu (UINT32 addr, int size, UINT32 data)
585{
586#ifdef TRACE_RDWR_MEM
587   fprintf (stderr, "writememi_emu: (ATE=%d) addr = 0x%08x, size = %d, data = 0x%08x\n",
588            GET_DIRBASE_ATE (), addr, size, data);
589#endif
590
591   /* If virtual mode, do translation.  */
592   if (GET_DIRBASE_ATE ())
593   {
594      UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 1 /* is_write */);
595      if (m_pending_trap && (GET_PSR_IAT () || GET_PSR_DAT ()))
596      {
597#ifdef TRACE_PAGE_FAULT
598         fprintf (stderr, "0x%08x: ## Page fault (writememi_emu).\n",
599                  m_pc);
600#endif
601         m_exiting_readmem = 2;
602         return;
603      }
604      addr = phys;
605   }
606
607   /* First check for match to db register (before write).  */
608   if (((addr & ~(size - 1)) == m_cregs[CR_DB]) && GET_PSR_BW ())
609   {
610      SET_PSR_DAT (1);
611      m_pending_trap = 1;
612      return;
613   }
614
615   /* Now do the actual write.  */
616   if (size == 1)
617      m_program->write_byte(addr, data);
618   else if (size == 2)
619   {
620#ifdef HOST_MSB
621      BYTE_REV16 (data);
622#endif
623      m_program->write_word(addr, data);
624   }
625   else if (size == 4)
626   {
627#ifdef HOST_MSB
628      BYTE_REV32 (data);
629#endif
630      m_program->write_dword(addr, data);
631   }
632   else
633      assert (0);
634}
635
636
637/* Floating-point read mem routine.
638     addr = address to read.
639     size = size of read in bytes.
640     dest = memory to put read data.  */
641void i860_cpu_device::fp_readmem_emu (UINT32 addr, int size, UINT8 *dest)
642{
643#ifdef TRACE_RDWR_MEM
644   fprintf (stderr, "fp_readmem_emu: (ATE=%d) addr = 0x%08x, size = %d\n",
645            GET_DIRBASE_ATE (), addr, size);
646#endif
647
648   assert (size == 4 || size == 8 || size == 16);
649
650   /* If virtual mode, do translation.  */
651   if (GET_DIRBASE_ATE ())
652   {
653      UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 0 /* is_write */);
654      if (m_pending_trap && (GET_PSR_IAT () || GET_PSR_DAT ()))
655      {
656#ifdef TRACE_PAGE_FAULT
657         fprintf (stderr, "0x%08x: ## Page fault (fp_readmem_emu).\n",
658                  m_pc);
659#endif
660         m_exiting_readmem = 3;
661         return;
662      }
663      addr = phys;
664   }
665
666   /* First check for match to db register (before read).  */
667   if (((addr & ~(size - 1)) == m_cregs[CR_DB]) && GET_PSR_BR ())
668   {
669      SET_PSR_DAT (1);
670      m_pending_trap = 1;
671      return;
672   }
673
674   if (size == 4)
675   {
676      dest[0] = m_program->read_byte(addr+3);
677      dest[1] = m_program->read_byte(addr+2);
678      dest[2] = m_program->read_byte(addr+1);
679      dest[3] = m_program->read_byte(addr+0);
680   }
681   else if (size == 8)
682   {
683      dest[0] = m_program->read_byte(addr+7);
684      dest[1] = m_program->read_byte(addr+6);
685      dest[2] = m_program->read_byte(addr+5);
686      dest[3] = m_program->read_byte(addr+4);
687      dest[4] = m_program->read_byte(addr+3);
688      dest[5] = m_program->read_byte(addr+2);
689      dest[6] = m_program->read_byte(addr+1);
690      dest[7] = m_program->read_byte(addr+0);
691   }
692   else if (size == 16)
693   {
694      int i;
695      for (i = 0; i < 16; i++)
696      {
697         dest[i] = m_program->read_byte(addr+15-i);
698      }
699   }
700}
701
702
703/* Floating-point write mem routine.
704     addr = address to read.
705     size = size of read in bytes.
706     data = pointer to the data.
707     wmask = bit mask of bytes to write (only for pst.d).  */
708void i860_cpu_device::fp_writemem_emu (UINT32 addr, int size, UINT8 *data, UINT32 wmask)
709{
710#ifdef TRACE_RDWR_MEM
711   fprintf (stderr, "fp_writemem_emu: (ATE=%d) addr = 0x%08x, size = %d\n",
712            GET_DIRBASE_ATE (), addr, size);
713#endif
714
715   assert (size == 4 || size == 8 || size == 16);
716
717   /* If virtual mode, do translation.  */
718   if (GET_DIRBASE_ATE ())
719   {
720      UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 1 /* is_write */);
721      if (m_pending_trap && GET_PSR_DAT ())
722      {
723#ifdef TRACE_PAGE_FAULT
724         fprintf (stderr, "0x%08x: ## Page fault (fp_writememi_emu).\n",
725                  m_pc);
726#endif
727         m_exiting_readmem = 4;
728         return;
729      }
730      addr = phys;
731   }
732
733   /* First check for match to db register (before read).  */
734   if (((addr & ~(size - 1)) == m_cregs[CR_DB]) && GET_PSR_BW ())
735   {
736      SET_PSR_DAT (1);
737      m_pending_trap = 1;
738      return;
739   }
740
741   if (size == 4)
742   {
743#if 1
744      m_program->write_byte(addr+3, data[0]);
745      m_program->write_byte(addr+2, data[1]);
746      m_program->write_byte(addr+1, data[2]);
747      m_program->write_byte(addr+0, data[3]);
748#else
749      UINT32 ddd = (data[3]) | (data[2] << 8) | (data[1] << 16) |(data[0] << 24);
750      m_program->write_dword(addr+0, ddd);
751#endif
752   }
753   else if (size == 8)
754   {
755      /* Special: watch for wmask != 0xff, which means we're doing pst.d.  */
756      if (wmask == 0xff)
757      {
758         m_program->write_byte(addr+7, data[0]);
759         m_program->write_byte(addr+6, data[1]);
760         m_program->write_byte(addr+5, data[2]);
761         m_program->write_byte(addr+4, data[3]);
762         m_program->write_byte(addr+3, data[4]);
763         m_program->write_byte(addr+2, data[5]);
764         m_program->write_byte(addr+1, data[6]);
765         m_program->write_byte(addr+0, data[7]);
766      }
767      else
768      {
769         if (wmask & 0x80) m_program->write_byte(addr+7, data[0]);
770         if (wmask & 0x40) m_program->write_byte(addr+6, data[1]);
771         if (wmask & 0x20) m_program->write_byte(addr+5, data[2]);
772         if (wmask & 0x10) m_program->write_byte(addr+4, data[3]);
773         if (wmask & 0x08) m_program->write_byte(addr+3, data[4]);
774         if (wmask & 0x04) m_program->write_byte(addr+2, data[5]);
775         if (wmask & 0x02) m_program->write_byte(addr+1, data[6]);
776         if (wmask & 0x01) m_program->write_byte(addr+0, data[7]);
777      }
778   }
779   else if (size == 16)
780   {
781      int i;
782      for (i = 0; i < 16; i++)
783      {
784         m_program->write_byte(addr+15-i, data[i]);
785      }
786   }
787
788}
789
790
791#if 0
792/* Do a pipeline dump.
793    type: 0 (all), 1 (add), 2 (mul), 3 (load), 4 (graphics).  */
794void i860_cpu_device::dump_pipe (int type)
795{
796   int i = 0;
797
798   fprintf (stderr, "pipeline state:\n");
799   /* Dump the adder pipeline, if requested.  */
800   if (type == 0 || type == 1)
801   {
802      fprintf (stderr, "  A: ");
803      for (i = 0; i < 3; i++)
804      {
805         if (m_A[i].stat.arp)
806            fprintf (stderr, "[%dd] 0x%016llx ", i + 1,
807                     *(UINT64 *)(&m_A[i].val.d));
808         else
809            fprintf (stderr, "[%ds] 0x%08x ", i + 1,
810                     *(UINT32 *)(&m_A[i].val.s));
811      }
812      fprintf (stderr, "\n");
813   }
814
815
816   /* Dump the multiplier pipeline, if requested.  */
817   if (type == 0 || type == 2)
818   {
819      fprintf (stderr, "  M: ");
820      for (i = 0; i < 3; i++)
821      {
822         if (m_M[i].stat.mrp)
823            fprintf (stderr, "[%dd] 0x%016llx ", i + 1,
824                     *(UINT64 *)(&m_M[i].val.d));
825         else
826            fprintf (stderr, "[%ds] 0x%08x ", i + 1,
827                     *(UINT32 *)(&m_M[i].val.s));
828      }
829      fprintf (stderr, "\n");
830   }
831
832   /* Dump the load pipeline, if requested.  */
833   if (type == 0 || type == 3)
834   {
835      fprintf (stderr, "  L: ");
836      for (i = 0; i < 3; i++)
837      {
838         if (m_L[i].stat.lrp)
839            fprintf (stderr, "[%dd] 0x%016llx ", i + 1,
840                     *(UINT64 *)(&m_L[i].val.d));
841         else
842            fprintf (stderr, "[%ds] 0x%08x ", i + 1,
843                     *(UINT32 *)(&m_L[i].val.s));
844      }
845      fprintf (stderr, "\n");
846   }
847
848   /* Dump the graphics pipeline, if requested.  */
849   if (type == 0 || type == 4)
850   {
851      fprintf (stderr, "  I: ");
852      if (m_G.stat.irp)
853         fprintf (stderr, "[1d] 0x%016llx\n",
854                  *(UINT64 *)(&m_G.val.d));
855      else
856         fprintf (stderr, "[1s] 0x%08x\n",
857                  *(UINT32 *)(&m_G.val.s));
858   }
859}
860
861
862/* Do a register/state dump.  */
863void i860_cpu_device::dump_state (i860s *cpustate)
864{
865   int rn;
866
867   /* GR's first, 4 per line.  */
868   for (rn = 0; rn < 32; rn++)
869   {
870      if ((rn % 4) == 0)
871         fprintf (stderr, "\n");
872      fprintf (stderr, "%%r%-3d: 0x%08x  ", rn, get_iregval (rn));
873   }
874   fprintf (stderr, "\n");
875
876   /* FR's (as 32-bits), 4 per line.  */
877   for (rn = 0; rn < 32; rn++)
878   {
879      float ff = get_fregval_s (rn);
880      if ((rn % 4) == 0)
881         fprintf (stderr, "\n");
882      fprintf (stderr, "%%f%-3d: 0x%08x  ", rn, *(UINT32 *)&ff);
883   }
884   fprintf (stderr, "\n");
885
886   fprintf (stderr, " psr: CC = %d, LCC = %d, SC = %d, IM = %d, U = %d\n",
887            GET_PSR_CC (), GET_PSR_LCC (), GET_PSR_SC (), GET_PSR_IM (),
888            GET_PSR_U ());
889   fprintf (stderr, "      IT/FT/IAT/DAT/IN = %d/%d/%d/%d/%d\n",
890            GET_PSR_IT (), GET_PSR_FT (), GET_PSR_IAT (),
891            GET_PSR_DAT (), GET_PSR_IN ());
892   fprintf (stderr, "epsr: INT = %d, OF = %d, BE = %d\n",
893            GET_EPSR_INT (), GET_EPSR_OF (), GET_EPSR_BE ());
894   fprintf (stderr, " fir: 0x%08x  dirbase: 0x%08x  fsr: 0x%08x\n",
895            m_cregs[CR_FIR], m_cregs[CR_DIRBASE],
896            m_cregs[CR_FSR]);
897   fprintf (stderr, "  pc: 0x%08x\n", m_pc);
898}
899#endif
900
901/* Sign extend N-bit number.  */
902INLINE INT32 sign_ext (UINT32 x, int n)
903{
904   INT32 t;
905   t = x >> (n - 1);
906   t = ((-t) << n) | x;
907   return t;
908}
909
910
911void i860_cpu_device::unrecog_opcode (UINT32 pc, UINT32 insn)
912{
913   fprintf (stderr, "0x%08x: 0x%08x   (unrecognized opcode)\n", pc, insn);
914}
915
916
917/* Execute "ld.c csrc2,idest" instruction.  */
918void i860_cpu_device::insn_ld_ctrl (UINT32 insn)
919{
920   UINT32 csrc2 = get_creg (insn);
921   UINT32 idest = get_idest (insn);
922
923#ifdef TRACE_UNDEFINED_I860
924   if (csrc2 > 5)
925   {
926      /* Control register not between 0..5.  Undefined i860XR behavior.  */
927      fprintf (stderr, "WARNING: insn_ld_from_ctrl (pc=0x%08x): bad creg in ld.c (ignored)\n", m_pc);
928      return;
929   }
930#endif
931
932   /* If this is a load of the fir, then there are two cases:
933      1. First load of fir after a trap = usual value.
934      2. Not first load of fir after a trap = address of the ld.c insn.  */
935   if (csrc2 == CR_FIR)
936   {
937      if (m_fir_gets_trap_addr)
938         set_iregval (idest, m_cregs[csrc2]);
939      else
940      {
941         m_cregs[csrc2] = m_pc;
942         set_iregval (idest, m_cregs[csrc2]);
943      }
944      m_fir_gets_trap_addr = 0;
945   }
946   else
947      set_iregval (idest, m_cregs[csrc2]);
948}
949
950
951/* Execute "st.c isrc1,csrc2" instruction.  */
952void i860_cpu_device::insn_st_ctrl (UINT32 insn)
953{
954   UINT32 csrc2 = get_creg (insn);
955   UINT32 isrc1 = get_isrc1 (insn);
956
957#ifdef TRACE_UNDEFINED_I860
958   if (csrc2 > 5)
959   {
960      /* Control register not between 0..5.  Undefined i860XR behavior.  */
961      fprintf (stderr, "WARNING: insn_st_to_ctrl (pc=0x%08x): bad creg in st.c (ignored)\n", m_pc);
962      return;
963   }
964#endif
965
966   /* Look for ITI bit turned on (but it never actually is written --
967      it always appears to be 0).  */
968   if (csrc2 == CR_DIRBASE && (get_iregval (isrc1) & 0x20))
969   {
970      /* NOTE: The actual icache and TLB flush are unimplemented for
971         the MAME version.  */
972
973      /* Make sure ITI isn't actually written.  */
974      set_iregval (isrc1, (get_iregval (isrc1) & ~0x20));
975   }
976
977   if (csrc2 == CR_DIRBASE && (get_iregval (isrc1) & 1)
978      && GET_DIRBASE_ATE () == 0)
979   {
980      fprintf (stderr, "0x%08x: ** ATE going high!\n", m_pc);
981   }
982
983   /* Update the register -- unless it is fir which cannot be updated.  */
984   if (csrc2 == CR_EPSR)
985   {
986      UINT32 enew = 0, tmp = 0;
987      /* Make sure unchangeable EPSR bits stay unchanged (DCS, stepping,
988         and type).  Also, some bits are only writeable in supervisor
989         mode.  */
990      if (GET_PSR_U ())
991      {
992         enew = get_iregval (isrc1) & ~(0x003e1fff | 0x00c06000);
993         tmp = m_cregs[CR_EPSR] & (0x003e1fff | 0x00c06000);
994      }
995      else
996      {
997         enew = get_iregval (isrc1) & ~0x003e1fff;
998         tmp = m_cregs[CR_EPSR] & 0x003e1fff;
999      }
1000      m_cregs[CR_EPSR] = enew | tmp;
1001   }
1002   else if (csrc2 == CR_PSR)
1003   {
1004      /* Some PSR bits are only writeable in supervisor mode.  */
1005      if (GET_PSR_U ())
1006      {
1007         UINT32 enew = get_iregval (isrc1) & ~PSR_SUPERVISOR_ONLY_MASK;
1008         UINT32 tmp = m_cregs[CR_PSR] & PSR_SUPERVISOR_ONLY_MASK;
1009         m_cregs[CR_PSR] = enew | tmp;
1010      }
1011      else
1012         m_cregs[CR_PSR] = get_iregval (isrc1);
1013   }
1014   else if (csrc2 == CR_FSR)
1015   {
1016      /* I believe that only 21..17, 8..5, and 3..0 should be updated.  */
1017      UINT32 enew = get_iregval (isrc1) & 0x003e01ef;
1018      UINT32 tmp = m_cregs[CR_FSR] & ~0x003e01ef;
1019      m_cregs[CR_FSR] = enew | tmp;
1020   }
1021   else if (csrc2 != CR_FIR)
1022      m_cregs[csrc2] = get_iregval (isrc1);
1023}
1024
1025
1026/* Execute "ld.{s,b,l} isrc1(isrc2),idest" or
1027   "ld.{s,b,l} #const(isrc2),idest".  */
1028void i860_cpu_device::insn_ldx (UINT32 insn)
1029{
1030   UINT32 isrc1 = get_isrc1 (insn);
1031   INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
1032   UINT32 isrc2 = get_isrc2 (insn);
1033   UINT32 idest = get_idest (insn);
1034   UINT32 eff = 0;
1035   /* Operand size, in bytes.  */
1036   int sizes[4] = { 1, 1, 2, 4};
1037   int size = 0;
1038   int form_disp_reg = 0;
1039
1040   /* Bits 28 and 0 determine the operand size.  */
1041   size = sizes[((insn >> 27) & 2) | (insn & 1)];
1042
1043   /* Bit 26 determines the addressing mode (reg+reg or disp+reg).  */
1044   form_disp_reg = (insn & 0x04000000);
1045
1046   /* Get effective address depending on disp+reg or reg+reg form.  */
1047   if (form_disp_reg)
1048   {
1049      /* Chop off lower bits of displacement.  */
1050      immsrc1 &= ~(size - 1);
1051      eff = (UINT32)(immsrc1 + (INT32)(get_iregval (isrc2)));
1052   }
1053   else
1054      eff = get_iregval (isrc1) + get_iregval (isrc2);
1055
1056#ifdef TRACE_UNALIGNED_MEM
1057   if (eff & (size - 1))
1058   {
1059      fprintf (stderr, "0x%08x: Unaligned access detected (0x%08x).\n",
1060               m_pc, eff);
1061      SET_PSR_DAT (1);
1062      m_pending_trap = 1;
1063      return;
1064   }
1065#endif
1066
1067   /* The i860 sign-extends 8- or 16-bit integer loads.
1068
1069      Below, the readmemi_emu() needs to happen outside of the
1070      set_iregval macro (otherwise the readmem won't occur if r0
1071      is the target register).  */
1072   if (size < 4)
1073   {
1074      UINT32 readval = sign_ext (readmemi_emu (eff, size), size * 8);
1075      /* Do not update register on page fault.  */
1076      if (m_exiting_readmem)
1077      {
1078         return;
1079      }
1080      set_iregval (idest, readval);
1081   }
1082   else
1083   {
1084      UINT32 readval = readmemi_emu (eff, size);
1085      /* Do not update register on page fault.  */
1086      if (m_exiting_readmem)
1087      {
1088         return;
1089      }
1090      set_iregval (idest, readval);
1091   }
1092}
1093
1094
1095/* Execute "st.x isrc1ni,#const(isrc2)" instruction (there is no
1096   (reg + reg form).  Store uses the split immediate, not the normal
1097   16-bit immediate as in ld.x.  */
1098void i860_cpu_device::insn_stx (UINT32 insn)
1099{
1100   INT32 immsrc = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
1101   UINT32 isrc1 = get_isrc1 (insn);
1102   UINT32 isrc2 = get_isrc2 (insn);
1103   UINT32 eff = 0;
1104   /* Operand size, in bytes.  */
1105   int sizes[4] = { 1, 1, 2, 4};
1106   int size = 0;
1107
1108   /* Bits 28 and 0 determine the operand size.  */
1109   size = sizes[((insn >> 27) & 2) | (insn & 1)];
1110
1111   /* FIXME: Do any necessary traps.  */
1112
1113   /* Get effective address.  Chop off lower bits of displacement.  */
1114   immsrc &= ~(size - 1);
1115   eff = (UINT32)(immsrc + (INT32)get_iregval (isrc2));
1116
1117   /* Write data (value of reg isrc1) to memory at eff.  */
1118   writememi_emu (eff, size, get_iregval (isrc1));
1119   if (m_exiting_readmem)
1120      return;
1121}
1122
1123
1124/* Execute "fst.y fdest,isrc1(isrc2)", "fst.y fdest,isrc1(isrc2)++",
1125           "fst.y fdest,#const(isrc2)" or "fst.y fdest,#const(isrc2)++"
1126   instruction.  */
1127void i860_cpu_device::insn_fsty (UINT32 insn)
1128{
1129   UINT32 isrc1 = get_isrc1 (insn);
1130   INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
1131   UINT32 isrc2 = get_isrc2 (insn);
1132   UINT32 fdest = get_fdest (insn);
1133   UINT32 eff = 0;
1134   /* Operand size, in bytes.  */
1135   int sizes[4] = { 8, 4, 16, 4};
1136   int size = 0;
1137   int form_disp_reg = 0;
1138   int auto_inc = (insn & 1);
1139
1140   /* Bits 2 and 1 determine the operand size.  */
1141   size = sizes[((insn >> 1) & 3)];
1142
1143   /* Bit 26 determines the addressing mode (reg+reg or disp+reg).  */
1144   form_disp_reg = (insn & 0x04000000);
1145
1146   /* FIXME: Check for undefined behavior, non-even or non-quad
1147      register operands for fst.d and fst.q respectively.  */
1148
1149   /* Get effective address depending on disp+reg or reg+reg form.  */
1150   if (form_disp_reg)
1151   {
1152      /* Chop off lower bits of displacement.  */
1153      immsrc1 &= ~(size - 1);
1154      eff = (UINT32)(immsrc1 + (INT32)(get_iregval (isrc2)));
1155   }
1156   else
1157      eff = get_iregval (isrc1) + get_iregval (isrc2);
1158
1159#ifdef TRACE_UNALIGNED_MEM
1160   if (eff & (size - 1))
1161   {
1162      fprintf (stderr, "0x%08x: Unaligned access detected (0x%08x).\n",
1163               m_pc, eff);
1164      SET_PSR_DAT (1);
1165      m_pending_trap = 1;
1166      return;
1167   }
1168#endif
1169
1170   /* Do (post) auto-increment.  */
1171   if (auto_inc)
1172   {
1173      set_iregval (isrc2, eff);
1174#ifdef TRACE_UNDEFINED_I860
1175      /* When auto-inc, isrc1 and isrc2 regs can't be the same.  */
1176      if (isrc1 == isrc2)
1177      {
1178         /* Undefined i860XR behavior.  */
1179         fprintf (stderr, "WARNING: insn_fsty (pc=0x%08x): isrc1 = isrc2 in fst with auto-inc (ignored)\n", m_pc);
1180         return;
1181      }
1182#endif
1183   }
1184
1185   /* Write data (value of freg fdest) to memory at eff.  */
1186   if (size == 4)
1187      fp_writemem_emu (eff, size, (UINT8 *)(&m_frg[4 * (31 - fdest)]), 0xff);
1188   else if (size == 8)
1189      fp_writemem_emu (eff, size, (UINT8 *)(&m_frg[4 * (31 - (fdest + 1))]), 0xff);
1190   else
1191      fp_writemem_emu (eff, size, (UINT8 *)(&m_frg[4 * (31 - (fdest + 3))]), 0xff);
1192
1193}
1194
1195
1196/* Execute "fld.y isrc1(isrc2),fdest", "fld.y isrc1(isrc2)++,idest",
1197           "fld.y #const(isrc2),fdest" or "fld.y #const(isrc2)++,idest".
1198   Where y = {l,d,q}.  Note, there is no pfld.q, though.  */
1199void i860_cpu_device::insn_fldy (UINT32 insn)
1200{
1201   UINT32 isrc1 = get_isrc1 (insn);
1202   INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
1203   UINT32 isrc2 = get_isrc2 (insn);
1204   UINT32 fdest = get_fdest (insn);
1205   UINT32 eff = 0;
1206   /* Operand size, in bytes.  */
1207   int sizes[4] = { 8, 4, 16, 4};
1208   int size = 0;
1209   int form_disp_reg = 0;
1210   int auto_inc = (insn & 1);
1211   int piped = (insn & 0x40000000);
1212
1213   /* Bits 2 and 1 determine the operand size.  */
1214   size = sizes[((insn >> 1) & 3)];
1215
1216   /* Bit 26 determines the addressing mode (reg+reg or disp+reg).  */
1217   form_disp_reg = (insn & 0x04000000);
1218
1219   /* There is no pipelined load quad.  */
1220   if (piped && size == 16)
1221   {
1222      unrecog_opcode (m_pc, insn);
1223      return;
1224   }
1225
1226   /* FIXME: Check for undefined behavior, non-even or non-quad
1227      register operands for fld.d and fld.q respectively.  */
1228
1229   /* Get effective address depending on disp+reg or reg+reg form.  */
1230   if (form_disp_reg)
1231   {
1232      /* Chop off lower bits of displacement.  */
1233      immsrc1 &= ~(size - 1);
1234      eff = (UINT32)(immsrc1 + (INT32)(get_iregval (isrc2)));
1235   }
1236   else
1237      eff = get_iregval (isrc1) + get_iregval (isrc2);
1238
1239   /* Do (post) auto-increment.  */
1240   if (auto_inc)
1241   {
1242      set_iregval (isrc2, eff);
1243#ifdef TRACE_UNDEFINED_I860
1244      /* When auto-inc, isrc1 and isrc2 regs can't be the same.  */
1245      if (isrc1 == isrc2)
1246      {
1247         /* Undefined i860XR behavior.  */
1248         fprintf (stderr, "WARNING: insn_fldy (pc=0x%08x): isrc1 = isrc2 in fst with auto-inc (ignored)\n", m_pc);
1249         return;
1250      }
1251#endif
1252   }
1253
1254#ifdef TRACE_UNALIGNED_MEM
1255   if (eff & (size - 1))
1256   {
1257      fprintf (stderr, "0x%08x: Unaligned access detected (0x%08x).\n",
1258               m_pc, eff);
1259      SET_PSR_DAT (1);
1260      m_pending_trap = 1;
1261      return;
1262   }
1263#endif
1264
1265   /* Update the load pipe if necessary.  */
1266   /* FIXME: Copy result-status bits to fsr from last stage.  */
1267   if (!piped)
1268   {
1269      /* Scalar version writes the current result to fdest.  */
1270      /* Read data at 'eff' into freg 'fdest' (reads to f0 or f1 are
1271         thrown away).  */
1272      if (fdest > 1)
1273      {
1274         if (size == 4)
1275            fp_readmem_emu (eff, size, (UINT8 *)&(m_frg[4 * (31 - fdest)]));
1276         else if (size == 8)
1277            fp_readmem_emu (eff, size, (UINT8 *)&(m_frg[4 * (31 - (fdest + 1))]));
1278         else if (size == 16)
1279            fp_readmem_emu (eff, size, (UINT8 *)&(m_frg[4 * (31 - (fdest + 3))]));
1280      }
1281   }
1282   else
1283   {
1284      /* Read the data into a temp space first.  This way we can test
1285         for any traps before updating the pipeline.  The pipeline must
1286         stay unaffected after a trap so that the instruction can be
1287         properly restarted.  */
1288      UINT8 bebuf[8];
1289      fp_readmem_emu (eff, size, bebuf);
1290      if (m_pending_trap && m_exiting_readmem)
1291         goto ab_op;
1292
1293      /* Pipelined version writes fdest with the result from the last
1294         stage of the pipeline, with precision specified by the LRP
1295         bit of the stage's result-status bits.  */
1296#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
1297      /* Copy 3rd stage LRP to FSR.  */
1298      if (m_L[1 /* 2 */].stat.lrp)
1299         m_cregs[CR_FSR] |= 0x04000000;
1300      else
1301         m_cregs[CR_FSR] &= ~0x04000000;
1302#endif
1303      if (m_L[2].stat.lrp)  /* 3rd (last) stage.  */
1304         set_fregval_d (fdest, m_L[2].val.d);
1305      else
1306         set_fregval_s (fdest, m_L[2].val.s);
1307
1308      /* Now advance pipeline and write loaded data to first stage.  */
1309      m_L[2] = m_L[1];
1310      m_L[1] = m_L[0];
1311      if (size == 8)
1312      {
1313         UINT8 *t = (UINT8 *)&(m_L[0].val.d);
1314#ifndef HOST_MSB
1315         t[7] = bebuf[0]; t[6] = bebuf[1]; t[5] = bebuf[2]; t[4] = bebuf[3];
1316         t[3] = bebuf[4]; t[2] = bebuf[5]; t[1] = bebuf[6]; t[0] = bebuf[7];
1317#else
1318         t[0] = bebuf[0]; t[1] = bebuf[1]; t[2] = bebuf[2]; t[3] = bebuf[3];
1319         t[4] = bebuf[4]; t[5] = bebuf[5]; t[6] = bebuf[6]; t[7] = bebuf[7];
1320#endif
1321         m_L[0].stat.lrp = 1;
1322      }
1323      else
1324      {
1325         UINT8 *t = (UINT8 *)&(m_L[0].val.s);
1326#ifndef HOST_MSB
1327         t[3] = bebuf[0]; t[2] = bebuf[1]; t[1] = bebuf[2]; t[0] = bebuf[3];
1328#else
1329         t[0] = bebuf[0]; t[1] = bebuf[1]; t[2] = bebuf[2]; t[3] = bebuf[3];
1330#endif
1331         m_L[0].stat.lrp = 0;
1332      }
1333   }
1334
1335   ab_op:;
1336}
1337
1338
1339/* Execute "pst.d fdest,#const(isrc2)" or "fst.d fdest,#const(isrc2)++"
1340   instruction.  */
1341void i860_cpu_device::insn_pstd (UINT32 insn)
1342{
1343   INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
1344   UINT32 isrc2 = get_isrc2 (insn);
1345   UINT32 fdest = get_fdest (insn);
1346   UINT32 eff = 0;
1347   int auto_inc = (insn & 1);
1348   UINT8 *bebuf = 0;
1349   int pm = GET_PSR_PM ();
1350   int i;
1351   UINT32 wmask;
1352   int orig_pm = pm;
1353
1354   /* Get the pixel size, where:
1355      PS: 0 = 8 bits, 1 = 16 bits, 2 = 32-bits.  */
1356   int ps = GET_PSR_PS ();
1357
1358#ifdef TRACE_UNDEFINED_I860
1359   if (!(ps == 0 || ps == 1 || ps == 2))
1360      fprintf (stderr, "insn_pstd: Undefined i860XR behavior, invalid value %d for pixel size.\n", ps);
1361#endif
1362
1363#ifdef TRACE_UNDEFINED_I860
1364   /* Bits 2 and 1 determine the operand size, which must always be
1365      zero (indicating a 64-bit operand).  */
1366   if (insn & 0x6)
1367   {
1368      /* Undefined i860XR behavior.  */
1369      fprintf (stderr, "WARNING: insn_pstd (pc=0x%08x): bad operand size specifier\n", m_pc);
1370   }
1371#endif
1372
1373   /* FIXME: Check for undefined behavior, non-even register operands.  */
1374
1375   /* Get effective address.  Chop off lower bits of displacement.  */
1376   immsrc1 &= ~(8 - 1);
1377   eff = (UINT32)(immsrc1 + (INT32)(get_iregval (isrc2)));
1378
1379#ifdef TRACE_UNALIGNED_MEM
1380   if (eff & (8 - 1))
1381   {
1382      fprintf (stderr, "0x%08x: Unaligned access detected (0x%08x).\n",
1383               m_pc, eff);
1384      SET_PSR_DAT (1);
1385      m_pending_trap = 1;
1386      return;
1387   }
1388#endif
1389
1390   /* Do (post) auto-increment.  */
1391   if (auto_inc)
1392      set_iregval (isrc2, eff);
1393
1394   /* Update the the pixel mask depending on the pixel size.  Shift PM
1395      right by 8/2^ps bits.  */
1396   if (ps == 0)
1397      pm = (pm >> 8) & 0x00;
1398   else if (ps == 1)
1399      pm = (pm >> 4) & 0x0f;
1400   else if (ps == 2)
1401      pm = (pm >> 2) & 0x3f;
1402   SET_PSR_PM (pm);
1403
1404   /* Write data (value of freg fdest) to memory at eff-- but only those
1405      bytes that are enabled by the bits in PSR.PM.  Bit 0 of PM selects
1406      the pixel at the lowest address.  */
1407   wmask = 0;
1408   for (i = 0; i < 8; )
1409   {
1410      if (ps == 0)
1411      {
1412         if (orig_pm & 0x80)
1413            wmask |= 1 << (7-i);
1414         i += 1;
1415      }
1416      else if (ps == 1)
1417      {
1418         if (orig_pm & 0x08)
1419            wmask |= 0x3 << (6-i);
1420         i += 2;
1421      }
1422      else if (ps == 2)
1423      {
1424         if (orig_pm & 0x02)
1425            wmask |= 0xf << (4-i);
1426         i += 4;
1427      }
1428      else
1429      {
1430         wmask = 0xff;
1431         break;
1432      }
1433      orig_pm <<= 1;
1434   }
1435   bebuf = (UINT8 *)(&m_frg[4 * (31 - (fdest + 1))]);
1436   fp_writemem_emu (eff, 8, bebuf, wmask);
1437}
1438
1439
1440/* Execute "ixfr isrc1ni,fdest" instruction.  */
1441void i860_cpu_device::insn_ixfr (UINT32 insn)
1442{
1443   UINT32 isrc1 = get_isrc1 (insn);
1444   UINT32 fdest = get_fdest (insn);
1445   UINT32 iv = 0;
1446
1447   /* This is a bit-pattern transfer, not a conversion.  */
1448   iv = get_iregval (isrc1);
1449   set_fregval_s (fdest, *(float *)&iv);
1450}
1451
1452
1453/* Execute "addu isrc1,isrc2,idest".  */
1454void i860_cpu_device::insn_addu (UINT32 insn)
1455{
1456   UINT32 src1val;
1457   UINT32 isrc2 = get_isrc2 (insn);
1458   UINT32 idest = get_idest (insn);
1459   UINT32 tmp_dest_val = 0;
1460   UINT64 tmp = 0;
1461
1462   src1val = get_iregval (get_isrc1 (insn));
1463
1464   /* We don't update the actual idest register now because below we
1465      need to test the original src1 and src2 if either happens to
1466      be the destination register.  */
1467   tmp_dest_val = src1val + get_iregval (isrc2);
1468
1469   /* Set OF and CC flags.
1470      For unsigned:
1471        OF = bit 31 carry
1472        CC = bit 31 carry.
1473    */
1474   tmp = (UINT64)src1val + (UINT64)(get_iregval (isrc2));
1475   if ((tmp >> 32) & 1)
1476   {
1477      SET_PSR_CC (1);
1478      SET_EPSR_OF (1);
1479   }
1480   else
1481   {
1482      SET_PSR_CC (0);
1483      SET_EPSR_OF (0);
1484   }
1485
1486   /* Now update the destination register.  */
1487   set_iregval (idest, tmp_dest_val);
1488}
1489
1490
1491/* Execute "addu #const,isrc2,idest".  */
1492void i860_cpu_device::insn_addu_imm (UINT32 insn)
1493{
1494   UINT32 src1val;
1495   UINT32 isrc2 = get_isrc2 (insn);
1496   UINT32 idest = get_idest (insn);
1497   UINT32 tmp_dest_val = 0;
1498   UINT64 tmp = 0;
1499
1500   src1val = sign_ext (get_imm16 (insn), 16);
1501
1502   /* We don't update the actual idest register now because below we
1503      need to test the original src1 and src2 if either happens to
1504      be the destination register.  */
1505   tmp_dest_val = src1val + get_iregval (isrc2);
1506
1507   /* Set OF and CC flags.
1508      For unsigned:
1509        OF = bit 31 carry
1510        CC = bit 31 carry.
1511    */
1512   tmp = (UINT64)src1val + (UINT64)(get_iregval (isrc2));
1513   if ((tmp >> 32) & 1)
1514   {
1515      SET_PSR_CC (1);
1516      SET_EPSR_OF (1);
1517   }
1518   else
1519   {
1520      SET_PSR_CC (0);
1521      SET_EPSR_OF (0);
1522   }
1523
1524   /* Now update the destination register.  */
1525   set_iregval (idest, tmp_dest_val);
1526}
1527
1528
1529/* Execute "adds isrc1,isrc2,idest".  */
1530void i860_cpu_device::insn_adds (UINT32 insn)
1531{
1532   UINT32 src1val;
1533   UINT32 isrc2 = get_isrc2 (insn);
1534   UINT32 idest = get_idest (insn);
1535   UINT32 tmp_dest_val = 0;
1536   int sa, sb, sres;
1537
1538   src1val = get_iregval (get_isrc1 (insn));
1539
1540   /* We don't update the actual idest register now because below we
1541      need to test the original src1 and src2 if either happens to
1542      be the destination register.  */
1543   tmp_dest_val = src1val + get_iregval (isrc2);
1544
1545   /* Set OF and CC flags.
1546      For signed:
1547        OF = standard signed overflow.
1548        CC set   if isrc2 < -isrc1
1549        CC clear if isrc2 >= -isrc1
1550    */
1551   sa = src1val & 0x80000000;
1552   sb = get_iregval (isrc2) & 0x80000000;
1553   sres = tmp_dest_val & 0x80000000;
1554   if (sa != sb && sa != sres)
1555      SET_EPSR_OF (1);
1556   else
1557      SET_EPSR_OF (0);
1558
1559   if ((INT32)get_iregval (isrc2) < -(INT32)(src1val))
1560      SET_PSR_CC (1);
1561   else
1562      SET_PSR_CC (0);
1563
1564   /* Now update the destination register.  */
1565   set_iregval (idest, tmp_dest_val);
1566}
1567
1568
1569/* Execute "adds #const,isrc2,idest".  */
1570void i860_cpu_device::insn_adds_imm (UINT32 insn)
1571{
1572   UINT32 src1val;
1573   UINT32 isrc2 = get_isrc2 (insn);
1574   UINT32 idest = get_idest (insn);
1575   UINT32 tmp_dest_val = 0;
1576   int sa, sb, sres;
1577
1578   src1val = sign_ext (get_imm16 (insn), 16);
1579
1580   /* We don't update the actual idest register now because below we
1581      need to test the original src1 and src2 if either happens to
1582      be the destination register.  */
1583   tmp_dest_val = src1val + get_iregval (isrc2);
1584
1585   /* Set OF and CC flags.
1586      For signed:
1587        OF = standard signed overflow.
1588        CC set   if isrc2 < -isrc1
1589        CC clear if isrc2 >= -isrc1
1590    */
1591   sa = src1val & 0x80000000;
1592   sb = get_iregval (isrc2) & 0x80000000;
1593   sres = tmp_dest_val & 0x80000000;
1594   if (sa != sb && sa != sres)
1595      SET_EPSR_OF (1);
1596   else
1597      SET_EPSR_OF (0);
1598
1599   if ((INT32)get_iregval (isrc2) < -(INT32)(src1val))
1600      SET_PSR_CC (1);
1601   else
1602      SET_PSR_CC (0);
1603
1604   /* Now update the destination register.  */
1605   set_iregval (idest, tmp_dest_val);
1606}
1607
1608
1609/* Execute "subu isrc1,isrc2,idest".  */
1610void i860_cpu_device::insn_subu (UINT32 insn)
1611{
1612   UINT32 src1val;
1613   UINT32 isrc2 = get_isrc2 (insn);
1614   UINT32 idest = get_idest (insn);
1615   UINT32 tmp_dest_val = 0;
1616
1617   src1val = get_iregval (get_isrc1 (insn));
1618
1619   /* We don't update the actual idest register now because below we
1620      need to test the original src1 and src2 if either happens to
1621      be the destination register.  */
1622   tmp_dest_val = src1val - get_iregval (isrc2);
1623
1624   /* Set OF and CC flags.
1625      For unsigned:
1626        OF = NOT(bit 31 carry)
1627        CC = bit 31 carry.
1628        (i.e. CC set   if isrc2 <= isrc1
1629              CC clear if isrc2 > isrc1
1630    */
1631   if ((UINT32)get_iregval (isrc2) <= (UINT32)src1val)
1632   {
1633      SET_PSR_CC (1);
1634      SET_EPSR_OF (0);
1635   }
1636   else
1637   {
1638      SET_PSR_CC (0);
1639      SET_EPSR_OF (1);
1640   }
1641
1642   /* Now update the destination register.  */
1643   set_iregval (idest, tmp_dest_val);
1644}
1645
1646
1647/* Execute "subu #const,isrc2,idest".  */
1648void i860_cpu_device::insn_subu_imm (UINT32 insn)
1649{
1650   UINT32 src1val;
1651   UINT32 isrc2 = get_isrc2 (insn);
1652   UINT32 idest = get_idest (insn);
1653   UINT32 tmp_dest_val = 0;
1654
1655   src1val = sign_ext (get_imm16 (insn), 16);
1656
1657   /* We don't update the actual idest register now because below we
1658      need to test the original src1 and src2 if either happens to
1659      be the destination register.  */
1660   tmp_dest_val = src1val - get_iregval (isrc2);
1661
1662   /* Set OF and CC flags.
1663      For unsigned:
1664        OF = NOT(bit 31 carry)
1665        CC = bit 31 carry.
1666        (i.e. CC set   if isrc2 <= isrc1
1667              CC clear if isrc2 > isrc1
1668    */
1669   if ((UINT32)get_iregval (isrc2) <= (UINT32)src1val)
1670   {
1671      SET_PSR_CC (1);
1672      SET_EPSR_OF (0);
1673   }
1674   else
1675   {
1676      SET_PSR_CC (0);
1677      SET_EPSR_OF (1);
1678   }
1679
1680   /* Now update the destination register.  */
1681   set_iregval (idest, tmp_dest_val);
1682}
1683
1684
1685/* Execute "subs isrc1,isrc2,idest".  */
1686void i860_cpu_device::insn_subs (UINT32 insn)
1687{
1688   UINT32 src1val;
1689   UINT32 isrc2 = get_isrc2 (insn);
1690   UINT32 idest = get_idest (insn);
1691   UINT32 tmp_dest_val = 0;
1692   int sa, sb, sres;
1693
1694   src1val = get_iregval (get_isrc1 (insn));
1695
1696   /* We don't update the actual idest register now because below we
1697      need to test the original src1 and src2 if either happens to
1698      be the destination register.  */
1699   tmp_dest_val = src1val - get_iregval (isrc2);
1700
1701   /* Set OF and CC flags.
1702      For signed:
1703        OF = standard signed overflow.
1704        CC set   if isrc2 > isrc1
1705        CC clear if isrc2 <= isrc1
1706    */
1707   sa = src1val & 0x80000000;
1708   sb = get_iregval (isrc2) & 0x80000000;
1709   sres = tmp_dest_val & 0x80000000;
1710   if (sa != sb && sa != sres)
1711      SET_EPSR_OF (1);
1712   else
1713      SET_EPSR_OF (0);
1714
1715   if ((INT32)get_iregval (isrc2) > (INT32)(src1val))
1716      SET_PSR_CC (1);
1717   else
1718      SET_PSR_CC (0);
1719
1720   /* Now update the destination register.  */
1721   set_iregval (idest, tmp_dest_val);
1722}
1723
1724
1725/* Execute "subs #const,isrc2,idest".  */
1726void i860_cpu_device::insn_subs_imm (UINT32 insn)
1727{
1728   UINT32 src1val;
1729   UINT32 isrc2 = get_isrc2 (insn);
1730   UINT32 idest = get_idest (insn);
1731   UINT32 tmp_dest_val = 0;
1732   int sa, sb, sres;
1733
1734   src1val = sign_ext (get_imm16 (insn), 16);
1735
1736   /* We don't update the actual idest register now because below we
1737      need to test the original src1 and src2 if either happens to
1738      be the destination register.  */
1739   tmp_dest_val = src1val - get_iregval (isrc2);
1740
1741   /* Set OF and CC flags.
1742      For signed:
1743        OF = standard signed overflow.
1744        CC set   if isrc2 > isrc1
1745        CC clear if isrc2 <= isrc1
1746    */
1747   sa = src1val & 0x80000000;
1748   sb = get_iregval (isrc2) & 0x80000000;
1749   sres = tmp_dest_val & 0x80000000;
1750   if (sa != sb && sa != sres)
1751      SET_EPSR_OF (1);
1752   else
1753      SET_EPSR_OF (0);
1754
1755   if ((INT32)get_iregval (isrc2) > (INT32)(src1val))
1756      SET_PSR_CC (1);
1757   else
1758      SET_PSR_CC (0);
1759
1760   /* Now update the destination register.  */
1761   set_iregval (idest, tmp_dest_val);
1762}
1763
1764
1765/* Execute "shl isrc1,isrc2,idest".  */
1766void i860_cpu_device::insn_shl (UINT32 insn)
1767{
1768   UINT32 src1val = 0;
1769   UINT32 isrc2 = get_isrc2 (insn);
1770   UINT32 idest = get_idest (insn);
1771
1772   src1val = get_iregval (get_isrc1 (insn));
1773   set_iregval (idest, get_iregval (isrc2) << src1val);
1774}
1775
1776
1777/* Execute "shl #const,isrc2,idest".  */
1778void i860_cpu_device::insn_shl_imm (UINT32 insn)
1779{
1780   UINT32 src1val = 0;
1781   UINT32 isrc2 = get_isrc2 (insn);
1782   UINT32 idest = get_idest (insn);
1783
1784   src1val = sign_ext (get_imm16 (insn), 16);
1785   set_iregval (idest, get_iregval (isrc2) << src1val);
1786}
1787
1788
1789/* Execute "shr isrc1,isrc2,idest".  */
1790void i860_cpu_device::insn_shr (UINT32 insn)
1791{
1792   UINT32 src1val = 0;
1793   UINT32 isrc2 = get_isrc2 (insn);
1794   UINT32 idest = get_idest (insn);
1795
1796   src1val = get_iregval (get_isrc1 (insn));
1797
1798   /* The iregs array is UINT32, so this is a logical shift.  */
1799   set_iregval (idest, get_iregval (isrc2) >> src1val);
1800
1801   /* shr also sets the SC in psr (shift count).  */
1802   SET_PSR_SC (src1val);
1803}
1804
1805
1806/* Execute "shr #const,isrc2,idest".  */
1807void i860_cpu_device::insn_shr_imm (UINT32 insn)
1808{
1809   UINT32 src1val = 0;
1810   UINT32 isrc2 = get_isrc2 (insn);
1811   UINT32 idest = get_idest (insn);
1812
1813   src1val = sign_ext (get_imm16 (insn), 16);
1814
1815   /* The iregs array is UINT32, so this is a logical shift.  */
1816   set_iregval (idest, get_iregval (isrc2) >> src1val);
1817
1818   /* shr also sets the SC in psr (shift count).  */
1819   SET_PSR_SC (src1val);
1820}
1821
1822
1823/* Execute "shra isrc1,isrc2,idest".  */
1824void i860_cpu_device::insn_shra (UINT32 insn)
1825{
1826   UINT32 src1val = 0;
1827   UINT32 isrc2 = get_isrc2 (insn);
1828   UINT32 idest = get_idest (insn);
1829
1830   src1val = get_iregval (get_isrc1 (insn));
1831
1832   /* The iregs array is UINT32, so cast isrc2 to get arithmetic shift.  */
1833   set_iregval (idest, (INT32)get_iregval (isrc2) >> src1val);
1834}
1835
1836
1837/* Execute "shra #const,isrc2,idest".  */
1838void i860_cpu_device::insn_shra_imm (UINT32 insn)
1839{
1840   UINT32 src1val = 0;
1841   UINT32 isrc2 = get_isrc2 (insn);
1842   UINT32 idest = get_idest (insn);
1843
1844   src1val = sign_ext (get_imm16 (insn), 16);
1845
1846   /* The iregs array is UINT32, so cast isrc2 to get arithmetic shift.  */
1847   set_iregval (idest, (INT32)get_iregval (isrc2) >> src1val);
1848}
1849
1850
1851/* Execute "shrd isrc1ni,isrc2,idest" instruction.  */
1852void i860_cpu_device::insn_shrd (UINT32 insn)
1853{
1854   UINT32 isrc1 = get_isrc1 (insn);
1855   UINT32 isrc2 = get_isrc2 (insn);
1856   UINT32 idest = get_idest (insn);
1857   UINT32 sc = GET_PSR_SC ();
1858   UINT32 tmp;
1859
1860   /* Do the operation:
1861      idest = low_32(isrc1ni:isrc2 >> sc).  */
1862   if (sc == 0)
1863      tmp = get_iregval (isrc2);
1864   else
1865   {
1866      tmp = get_iregval (isrc1) << (32 - sc);
1867      tmp |= (get_iregval (isrc2) >> sc);
1868   }
1869   set_iregval (idest, tmp);
1870}
1871
1872
1873/* Execute "and isrc1,isrc2,idest".  */
1874void i860_cpu_device::insn_and (UINT32 insn)
1875{
1876   UINT32 isrc1 = get_isrc1 (insn);
1877   UINT32 isrc2 = get_isrc2 (insn);
1878   UINT32 idest = get_idest (insn);
1879   UINT32 res = 0;
1880
1881   /* Do the operation.  */
1882   res = get_iregval (isrc1) & get_iregval (isrc2);
1883
1884   /* Set flags.  */
1885   if (res == 0)
1886      SET_PSR_CC (1);
1887   else
1888      SET_PSR_CC (0);
1889
1890   set_iregval (idest, res);
1891}
1892
1893
1894/* Execute "and #const,isrc2,idest".  */
1895void i860_cpu_device::insn_and_imm (UINT32 insn)
1896{
1897   UINT32 src1val = 0;
1898   UINT32 isrc2 = get_isrc2 (insn);
1899   UINT32 idest = get_idest (insn);
1900   UINT32 res = 0;
1901
1902   /* Do the operation.  */
1903   src1val = get_imm16 (insn);
1904   res = src1val & get_iregval (isrc2);
1905
1906   /* Set flags.  */
1907   if (res == 0)
1908      SET_PSR_CC (1);
1909   else
1910      SET_PSR_CC (0);
1911
1912   set_iregval (idest, res);
1913}
1914
1915
1916/* Execute "andh #const,isrc2,idest".  */
1917void i860_cpu_device::insn_andh_imm (UINT32 insn)
1918{
1919   UINT32 src1val = 0;
1920   UINT32 isrc2 = get_isrc2 (insn);
1921   UINT32 idest = get_idest (insn);
1922   UINT32 res = 0;
1923
1924   /* Do the operation.  */
1925   src1val = get_imm16 (insn);
1926   res = (src1val << 16) & get_iregval (isrc2);
1927
1928   /* Set flags.  */
1929   if (res == 0)
1930      SET_PSR_CC (1);
1931   else
1932      SET_PSR_CC (0);
1933
1934   set_iregval (idest, res);
1935}
1936
1937
1938/* Execute "andnot isrc1,isrc2,idest".  */
1939void i860_cpu_device::insn_andnot (UINT32 insn)
1940{
1941   UINT32 isrc1 = get_isrc1 (insn);
1942   UINT32 isrc2 = get_isrc2 (insn);
1943   UINT32 idest = get_idest (insn);
1944   UINT32 res = 0;
1945
1946   /* Do the operation.  */
1947   res = (~get_iregval (isrc1)) & get_iregval (isrc2);
1948
1949   /* Set flags.  */
1950   if (res == 0)
1951      SET_PSR_CC (1);
1952   else
1953      SET_PSR_CC (0);
1954
1955   set_iregval (idest, res);
1956}
1957
1958
1959/* Execute "andnot #const,isrc2,idest".  */
1960void i860_cpu_device::insn_andnot_imm (UINT32 insn)
1961{
1962   UINT32 src1val = 0;
1963   UINT32 isrc2 = get_isrc2 (insn);
1964   UINT32 idest = get_idest (insn);
1965   UINT32 res = 0;
1966
1967   /* Do the operation.  */
1968   src1val = get_imm16 (insn);
1969   res = (~src1val) & get_iregval (isrc2);
1970
1971   /* Set flags.  */
1972   if (res == 0)
1973      SET_PSR_CC (1);
1974   else
1975      SET_PSR_CC (0);
1976
1977   set_iregval (idest, res);
1978}
1979
1980
1981/* Execute "andnoth #const,isrc2,idest".  */
1982void i860_cpu_device::insn_andnoth_imm (UINT32 insn)
1983{
1984   UINT32 src1val = 0;
1985   UINT32 isrc2 = get_isrc2 (insn);
1986   UINT32 idest = get_idest (insn);
1987   UINT32 res = 0;
1988
1989   /* Do the operation.  */
1990   src1val = get_imm16 (insn);
1991   res = (~(src1val << 16)) & get_iregval (isrc2);
1992
1993   /* Set flags.  */
1994   if (res == 0)
1995      SET_PSR_CC (1);
1996   else
1997      SET_PSR_CC (0);
1998
1999   set_iregval (idest, res);
2000}
2001
2002
2003/* Execute "or isrc1,isrc2,idest".  */
2004void i860_cpu_device::insn_or (UINT32 insn)
2005{
2006   UINT32 isrc1 = get_isrc1 (insn);
2007   UINT32 isrc2 = get_isrc2 (insn);
2008   UINT32 idest = get_idest (insn);
2009   UINT32 res = 0;
2010
2011   /* Do the operation.  */
2012   res = get_iregval (isrc1) | get_iregval (isrc2);
2013
2014   /* Set flags.  */
2015   if (res == 0)
2016      SET_PSR_CC (1);
2017   else
2018      SET_PSR_CC (0);
2019
2020   set_iregval (idest, res);
2021}
2022
2023
2024/* Execute "or #const,isrc2,idest".  */
2025void i860_cpu_device::insn_or_imm (UINT32 insn)
2026{
2027   UINT32 src1val = 0;
2028   UINT32 isrc2 = get_isrc2 (insn);
2029   UINT32 idest = get_idest (insn);
2030   UINT32 res = 0;
2031
2032   /* Do the operation.  */
2033   src1val = get_imm16 (insn);
2034   res = src1val | get_iregval (isrc2);
2035
2036   /* Set flags.  */
2037   if (res == 0)
2038      SET_PSR_CC (1);
2039   else
2040      SET_PSR_CC (0);
2041
2042   set_iregval (idest, res);
2043}
2044
2045
2046/* Execute "orh #const,isrc2,idest".  */
2047void i860_cpu_device::insn_orh_imm (UINT32 insn)
2048{
2049   UINT32 src1val = 0;
2050   UINT32 isrc2 = get_isrc2 (insn);
2051   UINT32 idest = get_idest (insn);
2052   UINT32 res = 0;
2053
2054   /* Do the operation.  */
2055   src1val = get_imm16 (insn);
2056   res = (src1val << 16) | get_iregval (isrc2);
2057
2058   /* Set flags.  */
2059   if (res == 0)
2060      SET_PSR_CC (1);
2061   else
2062      SET_PSR_CC (0);
2063
2064   set_iregval (idest, res);
2065}
2066
2067
2068/* Execute "xor isrc1,isrc2,idest".  */
2069void i860_cpu_device::insn_xor (UINT32 insn)
2070{
2071   UINT32 isrc1 = get_isrc1 (insn);
2072   UINT32 isrc2 = get_isrc2 (insn);
2073   UINT32 idest = get_idest (insn);
2074   UINT32 res = 0;
2075
2076   /* Do the operation.  */
2077   res = get_iregval (isrc1) ^ get_iregval (isrc2);
2078
2079   /* Set flags.  */
2080   if (res == 0)
2081      SET_PSR_CC (1);
2082   else
2083      SET_PSR_CC (0);
2084
2085   set_iregval (idest, res);
2086}
2087
2088
2089/* Execute "xor #const,isrc2,idest".  */
2090void i860_cpu_device::insn_xor_imm (UINT32 insn)
2091{
2092   UINT32 src1val = 0;
2093   UINT32 isrc2 = get_isrc2 (insn);
2094   UINT32 idest = get_idest (insn);
2095   UINT32 res = 0;
2096
2097   /* Do the operation.  */
2098   src1val = get_imm16 (insn);
2099   res = src1val ^ get_iregval (isrc2);
2100
2101   /* Set flags.  */
2102   if (res == 0)
2103      SET_PSR_CC (1);
2104   else
2105      SET_PSR_CC (0);
2106
2107   set_iregval (idest, res);
2108}
2109
2110
2111/* Execute "xorh #const,isrc2,idest".  */
2112void i860_cpu_device::insn_xorh_imm (UINT32 insn)
2113{
2114   UINT32 src1val = 0;
2115   UINT32 isrc2 = get_isrc2 (insn);
2116   UINT32 idest = get_idest (insn);
2117   UINT32 res = 0;
2118
2119   /* Do the operation.  */
2120   src1val = get_imm16 (insn);
2121   res = (src1val << 16) ^ get_iregval (isrc2);
2122
2123   /* Set flags.  */
2124   if (res == 0)
2125      SET_PSR_CC (1);
2126   else
2127      SET_PSR_CC (0);
2128
2129   set_iregval (idest, res);
2130}
2131
2132
2133/* Execute "trap isrc1ni,isrc2,idest" instruction.  */
2134void i860_cpu_device::insn_trap (UINT32 insn)
2135{
2136   SET_PSR_IT (1);
2137   m_pending_trap = 1;
2138}
2139
2140
2141/* Execute "intovr" instruction.  */
2142void i860_cpu_device::insn_intovr (UINT32 insn)
2143{
2144   if (GET_EPSR_OF ())
2145   {
2146      SET_PSR_IT (1);
2147      m_pending_trap = 1;
2148   }
2149}
2150
2151
2152/* Execute "bte isrc1,isrc2,sbroff".  */
2153void i860_cpu_device::insn_bte (UINT32 insn)
2154{
2155   UINT32 src1val = 0;
2156   UINT32 isrc2 = get_isrc2 (insn);
2157   UINT32 target_addr = 0;
2158   INT32 sbroff = 0;
2159   int res = 0;
2160
2161   src1val = get_iregval (get_isrc1 (insn));
2162
2163   /* Compute the target address from the sbroff field.  */
2164   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2165   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2166
2167   /* Determine comparison result.  */
2168   res = (src1val == get_iregval (isrc2));
2169
2170   /* Branch routines always update the PC.  */
2171   if (res)
2172      m_pc = target_addr;
2173   else
2174      m_pc += 4;
2175
2176   m_pc_updated = 1;
2177}
2178
2179
2180/* Execute "bte #const5,isrc2,sbroff".  */
2181void i860_cpu_device::insn_bte_imm (UINT32 insn)
2182{
2183   UINT32 src1val = 0;
2184   UINT32 isrc2 = get_isrc2 (insn);
2185   UINT32 target_addr = 0;
2186   INT32 sbroff = 0;
2187   int res = 0;
2188
2189   src1val = (insn >> 11) & 0x1f;  /* 5-bit field, zero-extended.  */
2190
2191   /* Compute the target address from the sbroff field.  */
2192   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2193   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2194
2195   /* Determine comparison result.  */
2196   res = (src1val == get_iregval (isrc2));
2197
2198   /* Branch routines always update the PC.  */
2199   if (res)
2200      m_pc = target_addr;
2201   else
2202      m_pc += 4;
2203
2204   m_pc_updated = 1;
2205}
2206
2207
2208/* Execute "btne isrc1,isrc2,sbroff".  */
2209void i860_cpu_device::insn_btne (UINT32 insn)
2210{
2211   UINT32 src1val = 0;
2212   UINT32 isrc2 = get_isrc2 (insn);
2213   UINT32 target_addr = 0;
2214   INT32 sbroff = 0;
2215   int res = 0;
2216
2217   src1val = get_iregval (get_isrc1 (insn));
2218
2219   /* Compute the target address from the sbroff field.  */
2220   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2221   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2222
2223   /* Determine comparison result.  */
2224   res = (src1val != get_iregval (isrc2));
2225
2226   /* Branch routines always update the PC.  */
2227   if (res)
2228      m_pc = target_addr;
2229   else
2230      m_pc += 4;
2231
2232   m_pc_updated = 1;
2233}
2234
2235
2236/* Execute "btne #const5,isrc2,sbroff".  */
2237void i860_cpu_device::insn_btne_imm (UINT32 insn)
2238{
2239   UINT32 src1val = 0;
2240   UINT32 isrc2 = get_isrc2 (insn);
2241   UINT32 target_addr = 0;
2242   INT32 sbroff = 0;
2243   int res = 0;
2244
2245   src1val = (insn >> 11) & 0x1f;  /* 5-bit field, zero-extended.  */
2246
2247   /* Compute the target address from the sbroff field.  */
2248   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2249   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2250
2251   /* Determine comparison result.  */
2252   res = (src1val != get_iregval (isrc2));
2253
2254   /* Branch routines always update the PC.  */
2255   if (res)
2256      m_pc = target_addr;
2257   else
2258      m_pc += 4;
2259
2260   m_pc_updated = 1;
2261}
2262
2263
2264/* Execute "bc lbroff" instruction.  */
2265void i860_cpu_device::insn_bc (UINT32 insn)
2266{
2267   UINT32 target_addr = 0;
2268   INT32 lbroff = 0;
2269   int res = 0;
2270
2271   /* Compute the target address from the lbroff field.  */
2272   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2273   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2274
2275   /* Determine comparison result.  */
2276   res = (GET_PSR_CC () == 1);
2277
2278   /* Branch routines always update the PC.  */
2279   if (res)
2280      m_pc = target_addr;
2281   else
2282      m_pc += 4;
2283
2284   m_pc_updated = 1;
2285}
2286
2287
2288/* Execute "bnc lbroff" instruction.  */
2289void i860_cpu_device::insn_bnc (UINT32 insn)
2290{
2291   UINT32 target_addr = 0;
2292   INT32 lbroff = 0;
2293   int res = 0;
2294
2295   /* Compute the target address from the lbroff field.  */
2296   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2297   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2298
2299   /* Determine comparison result.  */
2300   res = (GET_PSR_CC () == 0);
2301
2302   /* Branch routines always update the PC, since pc_updated is set
2303      in the decode routine.  */
2304   if (res)
2305      m_pc = target_addr;
2306   else
2307      m_pc += 4;
2308
2309   m_pc_updated = 1;
2310}
2311
2312
2313/* Execute "bc.t lbroff" instruction.  */
2314void i860_cpu_device::insn_bct (UINT32 insn)
2315{
2316   UINT32 target_addr = 0;
2317   INT32 lbroff = 0;
2318   int res = 0;
2319   UINT32 orig_pc = m_pc;
2320
2321   /* Compute the target address from the lbroff field.  */
2322   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2323   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2324
2325   /* Determine comparison result.  */
2326   res = (GET_PSR_CC () == 1);
2327
2328   /* Careful. Unlike bla, the delay slot instruction is only executed
2329      if the branch is taken.  */
2330   if (res)
2331   {
2332      /* Execute delay slot instruction.  */
2333      m_pc += 4;
2334      decode_exec (ifetch (orig_pc + 4), 0);
2335      m_pc = orig_pc;
2336      if (m_pending_trap)
2337      {
2338         m_pending_trap |= TRAP_IN_DELAY_SLOT;
2339         goto ab_op;
2340      }
2341   }
2342
2343   /* Since this branch is delayed, we must jump 2 instructions if
2344      if isn't taken.  */
2345   if (res)
2346      m_pc = target_addr;
2347   else
2348      m_pc += 8;
2349
2350   m_pc_updated = 1;
2351
2352   ab_op:
2353   ;
2354}
2355
2356
2357/* Execute "bnc.t lbroff" instruction.  */
2358void i860_cpu_device::insn_bnct (UINT32 insn)
2359{
2360   UINT32 target_addr = 0;
2361   INT32 lbroff = 0;
2362   int res = 0;
2363   UINT32 orig_pc = m_pc;
2364
2365   /* Compute the target address from the lbroff field.  */
2366   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2367   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2368
2369   /* Determine comparison result.  */
2370   res = (GET_PSR_CC () == 0);
2371
2372   /* Careful. Unlike bla, the delay slot instruction is only executed
2373      if the branch is taken.  */
2374   if (res)
2375   {
2376      /* Execute delay slot instruction.  */
2377      m_pc += 4;
2378      decode_exec (ifetch (orig_pc + 4), 0);
2379      m_pc = orig_pc;
2380      if (m_pending_trap)
2381      {
2382         m_pending_trap |= TRAP_IN_DELAY_SLOT;
2383         goto ab_op;
2384      }
2385   }
2386
2387   /* Since this branch is delayed, we must jump 2 instructions if
2388      if isn't taken.  */
2389   if (res)
2390      m_pc = target_addr;
2391   else
2392      m_pc += 8;
2393
2394   m_pc_updated = 1;
2395
2396   ab_op:
2397   ;
2398}
2399
2400
2401/* Execute "call lbroff" instruction.  */
2402void i860_cpu_device::insn_call (UINT32 insn)
2403{
2404   UINT32 target_addr = 0;
2405   INT32 lbroff = 0;
2406   UINT32 orig_pc = m_pc;
2407
2408   /* Compute the target address from the lbroff field.  */
2409   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2410   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2411
2412   /* Execute the delay slot instruction.  */
2413   m_pc += 4;
2414   decode_exec (ifetch (orig_pc + 4), 0);
2415   m_pc = orig_pc;
2416   if (m_pending_trap)
2417   {
2418      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2419      goto ab_op;
2420   }
2421
2422   /* Sets the return pointer (r1).  */
2423   set_iregval (1, orig_pc + 8);
2424
2425   /* New target.  */
2426   m_pc = target_addr;
2427   m_pc_updated = 1;
2428
2429   ab_op:;
2430}
2431
2432
2433/* Execute "br lbroff".  */
2434void i860_cpu_device::insn_br (UINT32 insn)
2435{
2436   UINT32 target_addr = 0;
2437   INT32 lbroff = 0;
2438   UINT32 orig_pc = m_pc;
2439
2440   /* Compute the target address from the lbroff field.  */
2441   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2442   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2443
2444   /* Execute the delay slot instruction.  */
2445   m_pc += 4;
2446   decode_exec (ifetch (orig_pc + 4), 0);
2447   m_pc = orig_pc;
2448   if (m_pending_trap)
2449   {
2450      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2451      goto ab_op;
2452   }
2453
2454   /* New target.  */
2455   m_pc = target_addr;
2456   m_pc_updated = 1;
2457
2458   ab_op:;
2459}
2460
2461
2462/* Execute "bri isrc1ni" instruction.
2463   Note: I didn't merge this code with calli because bri must do
2464   a lot of flag manipulation if any trap bits are set.  */
2465void i860_cpu_device::insn_bri (UINT32 insn)
2466{
2467   UINT32 isrc1 = get_isrc1 (insn);
2468   UINT32 orig_pc = m_pc;
2469   UINT32 orig_psr = m_cregs[CR_PSR];
2470   UINT32 orig_src1_val = get_iregval (isrc1);
2471
2472#if 1 /* TURBO.  */
2473   m_cregs[CR_PSR] &= ~PSR_ALL_TRAP_BITS_MASK;
2474#endif
2475
2476   /* Execute the delay slot instruction.  */
2477   m_pc += 4;
2478   decode_exec (ifetch (orig_pc + 4), 0);
2479   m_pc = orig_pc;
2480
2481   /* Delay slot insn caused a trap, abort operation.  */
2482   if (m_pending_trap)
2483   {
2484      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2485      goto ab_op;
2486   }
2487
2488   /* If any trap bits are set, we need to do the return from
2489      trap work.  Note, we must use the PSR value that existed
2490      before the delay slot instruction was executed since the
2491      delay slot instruction might itself cause a trap bit to
2492      be set.  */
2493   if (orig_psr & PSR_ALL_TRAP_BITS_MASK)
2494   {
2495      /* Restore U and IM from their previous copies.  */
2496      SET_PSR_U (GET_PSR_PU ());
2497      SET_PSR_IM (GET_PSR_PIM ());
2498
2499      m_fir_gets_trap_addr = 0;
2500   }
2501
2502   /* Update PC.  */
2503   m_pc = orig_src1_val;
2504
2505   m_pc_updated = 1;
2506   ab_op:;
2507}
2508
2509/* Execute "calli isrc1ni" instruction.  */
2510void i860_cpu_device::insn_calli (UINT32 insn)
2511{
2512   UINT32 isrc1 = get_isrc1 (insn);
2513   UINT32 orig_pc = m_pc;
2514   UINT32 orig_src1_val = get_iregval (isrc1);
2515
2516#ifdef TRACE_UNDEFINED_I860
2517   /* Check for undefined behavior.  */
2518   if (isrc1 == 1)
2519   {
2520      /* Src1 must not be r1.  */
2521      fprintf (stderr, "WARNING: insn_calli (pc=0x%08x): isrc1 = r1 on a calli\n", m_pc);
2522   }
2523#endif
2524
2525   /* Set return pointer before executing delay slot instruction.  */
2526   set_iregval (1, m_pc + 8);
2527
2528   /* Execute the delay slot instruction.  */
2529   m_pc += 4;
2530   decode_exec (ifetch (orig_pc + 4), 0);
2531   m_pc = orig_pc;
2532   if (m_pending_trap)
2533   {
2534      set_iregval (1, orig_src1_val);
2535      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2536      goto ab_op;
2537   }
2538
2539   /* Set new PC.  */
2540   m_pc = orig_src1_val;
2541   m_pc_updated = 1;
2542
2543   ab_op:;
2544}
2545
2546
2547/* Execute "bla isrc1ni,isrc2,sbroff" instruction.  */
2548void i860_cpu_device::insn_bla (UINT32 insn)
2549{
2550   UINT32 isrc1 = get_isrc1 (insn);
2551   UINT32 isrc2 = get_isrc2 (insn);
2552   UINT32 target_addr = 0;
2553   INT32 sbroff = 0;
2554   int lcc_tmp = 0;
2555   UINT32 orig_pc = m_pc;
2556   UINT32 orig_isrc2val = get_iregval (isrc2);
2557
2558#ifdef TRACE_UNDEFINED_I860
2559   /* Check for undefined behavior.  */
2560   if (isrc1 == isrc2)
2561   {
2562      /* Src1 and src2 the same is undefined i860XR behavior.  */
2563      fprintf (stderr, "WARNING: insn_bla (pc=0x%08x): isrc1 and isrc2 are the same (ignored)\n", m_pc);
2564      return;
2565   }
2566#endif
2567
2568   /* Compute the target address from the sbroff field.  */
2569   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2570   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2571
2572   /* Determine comparison result based on opcode.  */
2573   lcc_tmp = ((INT32)get_iregval (isrc2) >= -(INT32)get_iregval (isrc1));
2574
2575   set_iregval (isrc2, get_iregval (isrc1) + orig_isrc2val);
2576
2577   /* Execute the delay slot instruction.  */
2578   m_pc += 4;
2579   decode_exec (ifetch (orig_pc + 4), 0);
2580   m_pc = orig_pc;
2581   if (m_pending_trap)
2582   {
2583      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2584      goto ab_op;
2585   }
2586
2587   if (GET_PSR_LCC ())
2588      m_pc = target_addr;
2589   else
2590   {
2591      /* Since this branch is delayed, we must jump 2 instructions if
2592         if isn't taken.  */
2593      m_pc += 8;
2594   }
2595   SET_PSR_LCC (lcc_tmp);
2596
2597   m_pc_updated = 1;
2598   ab_op:;
2599}
2600
2601
2602/* Execute "flush #const(isrc2)" or "flush #const(isrc2)++" instruction.  */
2603void i860_cpu_device::insn_flush (UINT32 insn)
2604{
2605   UINT32 src1val = sign_ext (get_imm16 (insn), 16);
2606   UINT32 isrc2 = get_isrc2 (insn);
2607   int auto_inc = (insn & 1);
2608   UINT32 eff = 0;
2609
2610   /* Technically, idest should be encoded as r0 because idest
2611      is undefined after the instruction.  We don't currently
2612      check for this.
2613
2614      Flush D$ block at address #const+isrc2.  Block is undefined
2615      after.  The effective address must be 16-byte aligned.
2616
2617      FIXME: Need to examine RB and RC and do this right.
2618     */
2619
2620   /* Chop off lower bits of displacement to 16-byte alignment.  */
2621   src1val &= ~(16-1);
2622   eff = src1val + get_iregval (isrc2);
2623   if (auto_inc)
2624      set_iregval (isrc2, eff);
2625
2626   /* In user mode, the flush is ignored.  */
2627   if (GET_PSR_U () == 0)
2628   {
2629      /* If line is dirty, write it to memory and invalidate.
2630         NOTE: The actual dirty write is unimplemented in the MAME version
2631         as we don't emulate the dcache.  */
2632   }
2633}
2634
2635
2636/* Execute "[p]fmul.{ss,sd,dd} fsrc1,fsrc2,fdest" instruction or
2637   pfmul3.dd fsrc1,fsrc2,fdest.
2638
2639   The pfmul3.dd differs from pfmul.dd in that it treats the pipeline
2640   as 3 stages, even though it is a double precision multiply.  */
2641void i860_cpu_device::insn_fmul (UINT32 insn)
2642{
2643   UINT32 fsrc1 = get_fsrc1 (insn);
2644   UINT32 fsrc2 = get_fsrc2 (insn);
2645   UINT32 fdest = get_fdest (insn);
2646   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
2647   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
2648   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
2649   double dbl_tmp_dest = 0.0;
2650   float sgl_tmp_dest = 0.0;
2651   double dbl_last_stage_contents = 0.0;
2652   float sgl_last_stage_contents = 0.0;
2653   int is_pfmul3 = insn & 0x4;
2654   int num_stages = (src_prec && !is_pfmul3) ? 2 : 3;
2655
2656   /* Only .dd is valid for pfmul.  */
2657   if (is_pfmul3 && (insn & 0x180) != 0x180)
2658   {
2659      unrecog_opcode (m_pc, insn);
2660      return;
2661   }
2662
2663   /* Check for invalid .ds combination.  */
2664   if ((insn & 0x180) == 0x100)
2665   {
2666      unrecog_opcode (m_pc, insn);
2667      return;
2668   }
2669
2670   /* For pipelined version, retrieve the contents of the last stage
2671      of the pipeline, whose precision is specified by the MRP bit
2672      of the stage's result-status bits.  Note for pfmul, the number
2673      of stages is determined by the source precision of the current
2674      operation.  */
2675   if (piped)
2676   {
2677      if (m_M[num_stages - 1].stat.mrp)
2678         dbl_last_stage_contents = m_M[num_stages - 1].val.d;
2679      else
2680         sgl_last_stage_contents = m_M[num_stages - 1].val.s;
2681   }
2682
2683   /* Do the operation, being careful about source and result
2684      precision.  */
2685   if (src_prec)
2686   {
2687      double v1 = get_fregval_d (fsrc1);
2688      double v2 = get_fregval_d (fsrc2);
2689
2690      /* For pipelined mul, if fsrc2 is the same as fdest, then the last
2691         stage is bypassed to fsrc2 (rather than using the value in fsrc2).
2692         This bypass is not available for fsrc1, and is undefined behavior.  */
2693      if (0 && piped && fdest != 0 && fsrc1 == fdest)
2694         v1 = dbl_last_stage_contents;
2695      if (piped && fdest != 0 && fsrc2 == fdest)
2696         v2 = dbl_last_stage_contents;
2697
2698      if (res_prec)
2699         dbl_tmp_dest = v1 * v2;
2700      else
2701         sgl_tmp_dest = (float)(v1 * v2);
2702   }
2703   else
2704   {
2705      float v1 = get_fregval_s (fsrc1);
2706      float v2 = get_fregval_s (fsrc2);
2707
2708      /* For pipelined mul, if fsrc2 is the same as fdest, then the last
2709         stage is bypassed to fsrc2 (rather than using the value in fsrc2).
2710         This bypass is not available for fsrc1, and is undefined behavior.  */
2711      if (0 && piped && fdest != 0 && fsrc1 == fdest)
2712         v1 = sgl_last_stage_contents;
2713      if (piped && fdest != 0 && fsrc2 == fdest)
2714         v2 = sgl_last_stage_contents;
2715
2716      if (res_prec)
2717         dbl_tmp_dest = (double)(v1 * v2);
2718      else
2719         sgl_tmp_dest = v1 * v2;
2720   }
2721
2722   /* FIXME: Set result-status bits besides MRP. And copy to fsr from
2723             last stage.  */
2724   /* FIXME: Scalar version flows through all stages.  */
2725   /* FIXME: Mixed precision (only weird for pfmul).  */
2726   if (!piped)
2727   {
2728      /* Scalar version writes the current calculation to the fdest
2729         register, with precision specified by the R bit.  */
2730      if (res_prec)
2731         set_fregval_d (fdest, dbl_tmp_dest);
2732      else
2733         set_fregval_s (fdest, sgl_tmp_dest);
2734   }
2735   else
2736   {
2737      /* Pipelined version writes fdest with the result from the last
2738         stage of the pipeline.  */
2739#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
2740      /* Copy 3rd stage MRP to FSR.  */
2741      if (m_M[num_stages - 2  /* 1 */].stat.mrp)
2742         m_cregs[CR_FSR] |= 0x10000000;
2743      else
2744         m_cregs[CR_FSR] &= ~0x10000000;
2745#endif
2746
2747      if (m_M[num_stages - 1].stat.mrp)
2748         set_fregval_d (fdest, dbl_last_stage_contents);
2749      else
2750         set_fregval_s (fdest, sgl_last_stage_contents);
2751
2752      /* Now advance pipeline and write current calculation to
2753         first stage.  */
2754      if (num_stages == 3)
2755      {
2756         m_M[2] = m_M[1];
2757         m_M[1] = m_M[0];
2758      }
2759      else
2760         m_M[1]  = m_M[0];
2761
2762      if (res_prec)
2763      {
2764         m_M[0].val.d = dbl_tmp_dest;
2765         m_M[0].stat.mrp = 1;
2766      }
2767      else
2768      {
2769         m_M[0].val.s = sgl_tmp_dest;
2770         m_M[0].stat.mrp = 0;
2771      }
2772   }
2773}
2774
2775
2776/* Execute "fmlow.dd fsrc1,fsrc2,fdest" instruction.  */
2777void i860_cpu_device::insn_fmlow (UINT32 insn)
2778{
2779   UINT32 fsrc1 = get_fsrc1 (insn);
2780   UINT32 fsrc2 = get_fsrc2 (insn);
2781   UINT32 fdest = get_fdest (insn);
2782
2783   double v1 = get_fregval_d (fsrc1);
2784   double v2 = get_fregval_d (fsrc2);
2785   INT64 i1 = *(UINT64 *)&v1;
2786   INT64 i2 = *(UINT64 *)&v2;
2787   INT64 tmp = 0;
2788
2789   /* Only .dd is valid for fmlow.  */
2790   if ((insn & 0x180) != 0x180)
2791   {
2792      unrecog_opcode (m_pc, insn);
2793      return;
2794   }
2795
2796   /* The lower 32-bits are obvious.  What exactly goes in the upper
2797      bits?
2798      Technically, the upper-most 10 bits are undefined, but i'd like
2799      to be undefined in the same way as the real i860 if possible.  */
2800
2801   /* Keep lower 53 bits of multiply.  */
2802   tmp = i1 * i2;
2803   tmp &= 0x001fffffffffffffULL;
2804   tmp |= (i1 & 0x8000000000000000LL) ^ (i2 & 0x8000000000000000LL);
2805   set_fregval_d (fdest, *(double *)&tmp);
2806}
2807
2808
2809/* Execute [p]fadd.{ss,sd,dd} fsrc1,fsrc2,fdest (.ds disallowed above).  */
2810void i860_cpu_device::insn_fadd_sub (UINT32 insn)
2811{
2812   UINT32 fsrc1 = get_fsrc1 (insn);
2813   UINT32 fsrc2 = get_fsrc2 (insn);
2814   UINT32 fdest = get_fdest (insn);
2815   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
2816   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
2817   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
2818   int is_sub = insn & 1;           /* 1 = sub, 0 = add.  */
2819   double dbl_tmp_dest = 0.0;
2820   float sgl_tmp_dest = 0.0;
2821   double dbl_last_stage_contents = 0.0;
2822   float sgl_last_stage_contents = 0.0;
2823
2824   /* Check for invalid .ds combination.  */
2825   if ((insn & 0x180) == 0x100)
2826   {
2827      unrecog_opcode (m_pc, insn);
2828      return;
2829   }
2830
2831   /* For pipelined version, retrieve the contents of the last stage
2832      of the pipeline, whose precision is specified by the ARP bit
2833      of the stage's result-status bits.  There are always three stages
2834      for pfadd/pfsub.  */
2835   if (piped)
2836   {
2837      if (m_A[2].stat.arp)
2838         dbl_last_stage_contents = m_A[2].val.d;
2839      else
2840         sgl_last_stage_contents = m_A[2].val.s;
2841   }
2842
2843   /* Do the operation, being careful about source and result
2844      precision.  */
2845   if (src_prec)
2846   {
2847      double v1 = get_fregval_d (fsrc1);
2848      double v2 = get_fregval_d (fsrc2);
2849
2850      /* For pipelined add/sub, if fsrc1 is the same as fdest, then the last
2851         stage is bypassed to fsrc1 (rather than using the value in fsrc1).
2852         Likewise for fsrc2.  */
2853      if (piped && fdest != 0 && fsrc1 == fdest)
2854         v1 = dbl_last_stage_contents;
2855      if (piped && fdest != 0 && fsrc2 == fdest)
2856         v2 = dbl_last_stage_contents;
2857
2858      if (res_prec)
2859         dbl_tmp_dest = is_sub ? v1 - v2 : v1 + v2;
2860      else
2861         sgl_tmp_dest = is_sub ? (float)(v1 - v2) : (float)(v1 + v2);
2862   }
2863   else
2864   {
2865      float v1 = get_fregval_s (fsrc1);
2866      float v2 = get_fregval_s (fsrc2);
2867
2868      /* For pipelined add/sub, if fsrc1 is the same as fdest, then the last
2869         stage is bypassed to fsrc1 (rather than using the value in fsrc1).
2870         Likewise for fsrc2.  */
2871      if (piped && fdest != 0 && fsrc1 == fdest)
2872         v1 = sgl_last_stage_contents;
2873      if (piped && fdest != 0 && fsrc2 == fdest)
2874         v2 = sgl_last_stage_contents;
2875
2876      if (res_prec)
2877         dbl_tmp_dest = is_sub ? (double)(v1 - v2) : (double)(v1 + v2);
2878      else
2879         sgl_tmp_dest = is_sub ? v1 - v2 : v1 + v2;
2880   }
2881
2882   /* FIXME: Set result-status bits besides ARP. And copy to fsr from
2883             last stage.  */
2884   /* FIXME: Scalar version flows through all stages.  */
2885   if (!piped)
2886   {
2887      /* Scalar version writes the current calculation to the fdest
2888         register, with precision specified by the R bit.  */
2889      if (res_prec)
2890         set_fregval_d (fdest, dbl_tmp_dest);
2891      else
2892         set_fregval_s (fdest, sgl_tmp_dest);
2893   }
2894   else
2895   {
2896      /* Pipelined version writes fdest with the result from the last
2897         stage of the pipeline, with precision specified by the ARP
2898         bit of the stage's result-status bits.  */
2899#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
2900      /* Copy 3rd stage ARP to FSR.  */
2901      if (m_A[1 /* 2 */].stat.arp)
2902         m_cregs[CR_FSR] |= 0x20000000;
2903      else
2904         m_cregs[CR_FSR] &= ~0x20000000;
2905#endif
2906      if (m_A[2].stat.arp)  /* 3rd (last) stage.  */
2907         set_fregval_d (fdest, dbl_last_stage_contents);
2908      else
2909         set_fregval_s (fdest, sgl_last_stage_contents);
2910
2911      /* Now advance pipeline and write current calculation to
2912         first stage.  */
2913      m_A[2] = m_A[1];
2914      m_A[1] = m_A[0];
2915      if (res_prec)
2916      {
2917         m_A[0].val.d = dbl_tmp_dest;
2918         m_A[0].stat.arp = 1;
2919      }
2920      else
2921      {
2922         m_A[0].val.s = sgl_tmp_dest;
2923         m_A[0].stat.arp = 0;
2924      }
2925   }
2926}
2927
2928
2929/* Operand types for PFAM/PFMAM routine below.  */
2930enum {
2931   OP_SRC1     = 0,
2932   OP_SRC2     = 1,
2933   OP_KI       = 2,
2934   OP_KR       = 4,
2935   OP_T        = 8,
2936   OP_MPIPE    = 16,
2937   OP_APIPE    = 32,
2938   FLAGM       = 64   /* Indicates PFMAM uses M rather than A pipe result.  */
2939};
2940
2941/* A table to map DPC value to source operands.
2942
2943   The PFAM and PFMAM tables are nearly identical, and the only differences
2944   are that every time PFAM uses the A pipe, PFMAM uses the M pipe instead.
2945   So we only represent the PFAM table and use a special flag on any entry
2946   where the PFMAM table would use the M pipe rather than the A pipe.
2947   Also, entry 16 is not valid for PFMAM.  */
2948static const struct
2949{
2950   int M_unit_op1;
2951   int M_unit_op2;
2952   int A_unit_op1;
2953   int A_unit_op2;
2954   int T_loaded;
2955   int K_loaded;
2956} src_opers[] = {
2957   /* 0000 */ { OP_KR,   OP_SRC2,        OP_SRC1,        OP_MPIPE,       0, 0},
2958   /* 0001 */ { OP_KR,   OP_SRC2,        OP_T,           OP_MPIPE,       0, 1},
2959   /* 0010 */ { OP_KR,   OP_SRC2,        OP_SRC1,        OP_APIPE|FLAGM, 1, 0},
2960   /* 0011 */ { OP_KR,   OP_SRC2,        OP_T,           OP_APIPE|FLAGM, 1, 1},
2961   /* 0100 */ { OP_KI,   OP_SRC2,        OP_SRC1,        OP_MPIPE,       0, 0},
2962   /* 0101 */ { OP_KI,   OP_SRC2,        OP_T,           OP_MPIPE,       0, 1},
2963   /* 0110 */ { OP_KI,   OP_SRC2,        OP_SRC1,        OP_APIPE|FLAGM, 1, 0},
2964   /* 0111 */ { OP_KI,   OP_SRC2,        OP_T,           OP_APIPE|FLAGM, 1, 1},
2965   /* 1000 */ { OP_KR,   OP_APIPE|FLAGM, OP_SRC1,        OP_SRC2,        1, 0},
2966   /* 1001 */ { OP_SRC1, OP_SRC2,        OP_APIPE|FLAGM, OP_MPIPE,       0, 0},
2967   /* 1010 */ { OP_KR,   OP_APIPE|FLAGM, OP_SRC1,        OP_SRC2,        0, 0},
2968   /* 1011 */ { OP_SRC1, OP_SRC2,        OP_T,           OP_APIPE|FLAGM, 1, 0},
2969   /* 1100 */ { OP_KI,   OP_APIPE|FLAGM, OP_SRC1,        OP_SRC2,        1, 0},
2970   /* 1101 */ { OP_SRC1, OP_SRC2,        OP_T,           OP_MPIPE,       0, 0},
2971   /* 1110 */ { OP_KI,   OP_APIPE|FLAGM, OP_SRC1,        OP_SRC2,        0, 0},
2972   /* 1111 */ { OP_SRC1, OP_SRC2,        OP_T,           OP_APIPE|FLAGM, 0, 0}
2973};
2974
2975float i860_cpu_device::get_fval_from_optype_s (UINT32 insn, int optype)
2976{
2977   float retval = 0.0;
2978   UINT32 fsrc1 = get_fsrc1 (insn);
2979   UINT32 fsrc2 = get_fsrc2 (insn);
2980
2981   optype &= ~FLAGM;
2982   switch (optype)
2983   {
2984   case OP_SRC1:
2985      retval = get_fregval_s (fsrc1);
2986      break;
2987   case OP_SRC2:
2988      retval = get_fregval_s (fsrc2);
2989      break;
2990   case OP_KI:
2991      retval = m_KI.s;
2992      break;
2993   case OP_KR:
2994      retval = m_KR.s;
2995      break;
2996   case OP_T:
2997      retval = m_T.s;
2998      break;
2999   case OP_MPIPE:
3000      /* Last stage is 3rd stage for single precision input.  */
3001      retval = m_M[2].val.s;
3002      break;
3003   case OP_APIPE:
3004      retval = m_A[2].val.s;
3005      break;
3006   default:
3007      assert (0);
3008   }
3009
3010   return retval;
3011}
3012
3013
3014double i860_cpu_device::get_fval_from_optype_d (UINT32 insn, int optype)
3015{
3016   double retval = 0.0;
3017   UINT32 fsrc1 = get_fsrc1 (insn);
3018   UINT32 fsrc2 = get_fsrc2 (insn);
3019
3020   optype &= ~FLAGM;
3021   switch (optype)
3022   {
3023   case OP_SRC1:
3024      retval = get_fregval_d (fsrc1);
3025      break;
3026   case OP_SRC2:
3027      retval = get_fregval_d (fsrc2);
3028      break;
3029   case OP_KI:
3030      retval = m_KI.d;
3031      break;
3032   case OP_KR:
3033      retval = m_KR.d;
3034      break;
3035   case OP_T:
3036      retval = m_T.d;
3037      break;
3038   case OP_MPIPE:
3039      /* Last stage is 2nd stage for double precision input.  */
3040      retval = m_M[1].val.d;
3041      break;
3042   case OP_APIPE:
3043      retval = m_A[2].val.d;
3044      break;
3045   default:
3046      assert (0);
3047   }
3048
3049   return retval;
3050}
3051
3052
3053/* Execute pf[m]{a,s}m.{ss,sd,dd} fsrc1,fsrc2,fdest (FP dual ops).
3054
3055   Since these are always pipelined, the P bit is used to distinguish
3056   family pfam (P=1) from family pfmam (P=0), and the lower 4 bits
3057   of the extended opcode is the DPC.
3058
3059   Note also that the S and R bits are slightly different than normal
3060   floating point operations.  The S bit denotes the precision of the
3061   multiplication source, while the R bit denotes the precision of
3062   the addition source as well as precision of all results.  */
3063void i860_cpu_device::insn_dualop (UINT32 insn)
3064{
3065   UINT32 fsrc1 = get_fsrc1 (insn);
3066   UINT32 fsrc2 = get_fsrc2 (insn);
3067   UINT32 fdest = get_fdest (insn);
3068   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3069   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3070   int is_pfam = insn & 0x400;      /* 1 = pfam, 0 = pfmam.  */
3071   int is_sub = insn & 0x10;        /* 1 = pf[m]sm, 0 = pf[m]am.  */
3072   double dbl_tmp_dest_mul = 0.0;
3073   float sgl_tmp_dest_mul = 0.0;
3074   double dbl_tmp_dest_add = 0.0;
3075   float sgl_tmp_dest_add = 0.0;
3076   double dbl_last_Mstage_contents = 0.0;
3077   float sgl_last_Mstage_contents = 0.0;
3078   double dbl_last_Astage_contents = 0.0;
3079   float sgl_last_Astage_contents = 0.0;
3080   int num_mul_stages = src_prec ? 2 : 3;
3081
3082   int dpc = insn & 0xf;
3083   int M_unit_op1 = src_opers[dpc].M_unit_op1;
3084   int M_unit_op2 = src_opers[dpc].M_unit_op2;
3085   int A_unit_op1 = src_opers[dpc].A_unit_op1;
3086   int A_unit_op2 = src_opers[dpc].A_unit_op2;
3087   int T_loaded = src_opers[dpc].T_loaded;
3088   int K_loaded = src_opers[dpc].K_loaded;
3089
3090   /* Check for invalid .ds combination.  */
3091   if ((insn & 0x180) == 0x100)
3092   {
3093      unrecog_opcode (m_pc, insn);
3094      return;
3095   }
3096
3097   if (is_pfam == 0)
3098   {
3099      /* Check for invalid DPC combination 16 for PFMAM.  */
3100      if (dpc == 16)
3101      {
3102         unrecog_opcode (m_pc, insn);
3103         return;
3104      }
3105
3106      /* PFMAM table adjustments (M_unit_op1 is never a pipe stage,
3107         so no adjustment made for it).   */
3108      M_unit_op2 = (M_unit_op2 & FLAGM) ? OP_MPIPE : M_unit_op2;
3109      A_unit_op1 = (A_unit_op1 & FLAGM) ? OP_MPIPE : A_unit_op1;
3110      A_unit_op2 = (A_unit_op2 & FLAGM) ? OP_MPIPE : A_unit_op2;
3111   }
3112
3113   /* FIXME: Check for fsrc1/fdest overlap for some mul DPC combinations.  */
3114
3115   /* Retrieve the contents of the last stage of the multiplier pipeline,
3116      whose precision is specified by the MRP bit of the stage's result-
3117      status bits.  Note for multiply, the number of stages is determined
3118      by the source precision of the current operation.  */
3119   if (m_M[num_mul_stages - 1].stat.mrp)
3120      dbl_last_Mstage_contents = m_M[num_mul_stages - 1].val.d;
3121   else
3122      sgl_last_Mstage_contents = m_M[num_mul_stages - 1].val.s;
3123
3124   /* Similarly, retrieve the last stage of the adder pipe.  */
3125   if (m_A[2].stat.arp)
3126      dbl_last_Astage_contents = m_A[2].val.d;
3127   else
3128      sgl_last_Astage_contents = m_A[2].val.s;
3129
3130   /* Do the mul operation, being careful about source and result
3131      precision.  */
3132   if (src_prec)
3133   {
3134      double v1 = get_fval_from_optype_d (insn, M_unit_op1);
3135      double v2 = get_fval_from_optype_d (insn, M_unit_op2);
3136
3137      /* For mul, if fsrc2 is the same as fdest, then the last stage
3138         is bypassed to fsrc2 (rather than using the value in fsrc2).
3139         This bypass is not available for fsrc1, and is undefined behavior.  */
3140      if (0 && M_unit_op1 == OP_SRC1 && fdest != 0 && fsrc1 == fdest)
3141         v1 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents;
3142      if (M_unit_op2 == OP_SRC2 && fdest != 0 && fsrc2 == fdest)
3143         v2 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents;
3144
3145      if (res_prec)
3146         dbl_tmp_dest_mul = v1 * v2;
3147      else
3148         sgl_tmp_dest_mul = (float)(v1 * v2);
3149   }
3150   else
3151   {
3152      float v1 = get_fval_from_optype_s (insn, M_unit_op1);
3153      float v2 = get_fval_from_optype_s (insn, M_unit_op2);
3154
3155      /* For mul, if fsrc2 is the same as fdest, then the last stage
3156         is bypassed to fsrc2 (rather than using the value in fsrc2).
3157         This bypass is not available for fsrc1, and is undefined behavior.  */
3158      if (0 && M_unit_op1 == OP_SRC1 && fdest != 0 && fsrc1 == fdest)
3159         v1 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents;
3160      if (M_unit_op2 == OP_SRC2 && fdest != 0 && fsrc2 == fdest)
3161         v2 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents;
3162
3163      if (res_prec)
3164         dbl_tmp_dest_mul = (double)(v1 * v2);
3165      else
3166         sgl_tmp_dest_mul = v1 * v2;
3167   }
3168
3169   /* Do the add operation, being careful about source and result
3170      precision.  Remember, the R bit indicates source and result precision
3171      here.  */
3172   if (res_prec)
3173   {
3174      double v1 = get_fval_from_optype_d (insn, A_unit_op1);
3175      double v2 = get_fval_from_optype_d (insn, A_unit_op2);
3176
3177      /* For add/sub, if fsrc1 is the same as fdest, then the last stage
3178         is bypassed to fsrc1 (rather than using the value in fsrc1).
3179         Likewise for fsrc2.  */
3180      if (A_unit_op1 == OP_SRC1 && fdest != 0 && fsrc1 == fdest)
3181         v1 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents;
3182      if (A_unit_op2 == OP_SRC2 && fdest != 0 && fsrc2 == fdest)
3183         v2 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents;
3184
3185      if (res_prec)
3186         dbl_tmp_dest_add = is_sub ? v1 - v2 : v1 + v2;
3187      else
3188         sgl_tmp_dest_add = is_sub ? (float)(v1 - v2) : (float)(v1 + v2);
3189   }
3190   else
3191   {
3192      float v1 = get_fval_from_optype_s (insn, A_unit_op1);
3193      float v2 = get_fval_from_optype_s (insn, A_unit_op2);
3194
3195      /* For add/sub, if fsrc1 is the same as fdest, then the last stage
3196         is bypassed to fsrc1 (rather than using the value in fsrc1).
3197         Likewise for fsrc2.  */
3198      if (A_unit_op1 == OP_SRC1 && fdest != 0 && fsrc1 == fdest)
3199         v1 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents;
3200      if (A_unit_op2 == OP_SRC2 && fdest != 0 && fsrc2 == fdest)
3201         v2 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents;
3202
3203      if (res_prec)
3204         dbl_tmp_dest_add = is_sub ? (double)(v1 - v2) : (double)(v1 + v2);
3205      else
3206         sgl_tmp_dest_add = is_sub ? v1 - v2 : v1 + v2;
3207   }
3208
3209   /* If necessary, load T.  */
3210   if (T_loaded)
3211   {
3212      /* T is loaded from the result of the last stage of the multiplier.  */
3213      if (m_M[num_mul_stages - 1].stat.mrp)
3214         m_T.d = dbl_last_Mstage_contents;
3215      else
3216         m_T.s = sgl_last_Mstage_contents;
3217   }
3218
3219   /* If necessary, load KR or KI.  */
3220   if (K_loaded)
3221   {
3222      /* KI or KR is loaded from the first register input.  */
3223      if (M_unit_op1 == OP_KI)
3224      {
3225         if (src_prec)
3226            m_KI.d = get_fregval_d (fsrc1);
3227         else
3228            m_KI.s  = get_fregval_s (fsrc1);
3229      }
3230      else if (M_unit_op1 == OP_KR)
3231      {
3232         if (src_prec)
3233            m_KR.d = get_fregval_d (fsrc1);
3234         else
3235            m_KR.s  = get_fregval_s (fsrc1);
3236      }
3237      else
3238         assert (0);
3239   }
3240
3241   /* Now update fdest (either from adder pipe or multiplier pipe,
3242      depending on whether the instruction is pfam or pfmam).  */
3243   if (is_pfam)
3244   {
3245      /* Update fdest with the result from the last stage of the
3246         adder pipeline, with precision specified by the ARP
3247         bit of the stage's result-status bits.  */
3248      if (m_A[2].stat.arp)
3249         set_fregval_d (fdest, dbl_last_Astage_contents);
3250      else
3251         set_fregval_s (fdest, sgl_last_Astage_contents);
3252   }
3253   else
3254   {
3255      /* Update fdest with the result from the last stage of the
3256         multiplier pipeline, with precision specified by the MRP
3257         bit of the stage's result-status bits.  */
3258      if (m_M[num_mul_stages - 1].stat.mrp)
3259         set_fregval_d (fdest, dbl_last_Mstage_contents);
3260      else
3261         set_fregval_s (fdest, sgl_last_Mstage_contents);
3262   }
3263
3264   /* FIXME: Set result-status bits besides MRP. And copy to fsr from
3265             last stage.  */
3266   /* FIXME: Mixed precision (only weird for pfmul).  */
3267#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3268   /* Copy 3rd stage MRP to FSR.  */
3269   if (m_M[num_mul_stages - 2  /* 1 */].stat.mrp)
3270      m_cregs[CR_FSR] |= 0x10000000;
3271   else
3272      m_cregs[CR_FSR] &= ~0x10000000;
3273#endif
3274
3275   /* Now advance multiplier pipeline and write current calculation to
3276      first stage.  */
3277   if (num_mul_stages == 3)
3278   {
3279      m_M[2] = m_M[1];
3280      m_M[1] = m_M[0];
3281   }
3282   else
3283      m_M[1]  = m_M[0];
3284
3285   if (res_prec)
3286   {
3287      m_M[0].val.d = dbl_tmp_dest_mul;
3288      m_M[0].stat.mrp = 1;
3289   }
3290   else
3291   {
3292      m_M[0].val.s = sgl_tmp_dest_mul;
3293      m_M[0].stat.mrp = 0;
3294   }
3295
3296   /* FIXME: Set result-status bits besides ARP. And copy to fsr from
3297             last stage.  */
3298#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3299   /* Copy 3rd stage ARP to FSR.  */
3300   if (m_A[1 /* 2 */].stat.arp)
3301      m_cregs[CR_FSR] |= 0x20000000;
3302   else
3303      m_cregs[CR_FSR] &= ~0x20000000;
3304#endif
3305
3306   /* Now advance adder pipeline and write current calculation to
3307      first stage.  */
3308   m_A[2] = m_A[1];
3309   m_A[1] = m_A[0];
3310   if (res_prec)
3311   {
3312      m_A[0].val.d = dbl_tmp_dest_add;
3313      m_A[0].stat.arp = 1;
3314   }
3315   else
3316   {
3317      m_A[0].val.s = sgl_tmp_dest_add;
3318      m_A[0].stat.arp = 0;
3319   }
3320}
3321
3322
3323/* Execute frcp.{ss,sd,dd} fsrc2,fdest (.ds disallowed above).  */
3324void i860_cpu_device::insn_frcp (UINT32 insn)
3325{
3326   UINT32 fsrc2 = get_fsrc2 (insn);
3327   UINT32 fdest = get_fdest (insn);
3328   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3329   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3330
3331   /* Do the operation, being careful about source and result
3332      precision.  */
3333   if (src_prec)
3334   {
3335      double v = get_fregval_d (fsrc2);
3336      double res;
3337      if (v == (double)0.0)
3338      {
3339         /* Generate source-exception trap if fsrc2 is 0.  */
3340         if (0 /* && GET_FSR_FTE () */)
3341         {
3342            SET_PSR_FT (1);
3343            SET_FSR_SE (1);
3344            m_pending_trap = GET_FSR_FTE ();
3345         }
3346         /* Set fdest to INF or some other exceptional value here?  */
3347      }
3348      else
3349      {
3350         /* Real i860 isn't a precise as a real divide, but this should
3351            be okay.  */
3352         SET_FSR_SE (0);
3353         *((UINT64 *)&v) &= 0xfffff00000000000ULL;
3354         res = (double)1.0/v;
3355         *((UINT64 *)&res) &= 0xfffff00000000000ULL;
3356         if (res_prec)
3357            set_fregval_d (fdest, res);
3358         else
3359            set_fregval_s (fdest, (float)res);
3360      }
3361   }
3362   else
3363   {
3364      float v = get_fregval_s (fsrc2);
3365      float res;
3366      if (v == 0.0)
3367      {
3368         /* Generate source-exception trap if fsrc2 is 0.  */
3369         if (0 /* GET_FSR_FTE () */)
3370         {
3371            SET_PSR_FT (1);
3372            SET_FSR_SE (1);
3373            m_pending_trap = GET_FSR_FTE ();
3374         }
3375         /* Set fdest to INF or some other exceptional value here?  */
3376      }
3377      else
3378      {
3379         /* Real i860 isn't a precise as a real divide, but this should
3380            be okay.  */
3381         SET_FSR_SE (0);
3382         *((UINT32 *)&v) &= 0xffff8000;
3383         res = (float)1.0/v;
3384         *((UINT32 *)&res) &= 0xffff8000;
3385         if (res_prec)
3386            set_fregval_d (fdest, (double)res);
3387         else
3388            set_fregval_s (fdest, res);
3389      }
3390   }
3391}
3392
3393
3394/* Execute frsqr.{ss,sd,dd} fsrc2,fdest (.ds disallowed above).  */
3395void i860_cpu_device::insn_frsqr (UINT32 insn)
3396{
3397   UINT32 fsrc2 = get_fsrc2 (insn);
3398   UINT32 fdest = get_fdest (insn);
3399   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3400   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3401
3402   /* Check for invalid .ds combination.  */
3403   if ((insn & 0x180) == 0x100)
3404   {
3405      unrecog_opcode (m_pc, insn);
3406      return;
3407   }
3408
3409   /* Check for invalid .ds combination.  */
3410   if ((insn & 0x180) == 0x100)
3411   {
3412      unrecog_opcode (m_pc, insn);
3413      return;
3414   }
3415
3416   /* Do the operation, being careful about source and result
3417      precision.  */
3418   if (src_prec)
3419   {
3420      double v = get_fregval_d (fsrc2);
3421      double res;
3422      if (v == 0.0 || v < 0.0)
3423      {
3424         /* Generate source-exception trap if fsrc2 is 0 or negative.  */
3425         if (0 /* GET_FSR_FTE () */)
3426         {
3427            SET_PSR_FT (1);
3428            SET_FSR_SE (1);
3429            m_pending_trap = GET_FSR_FTE ();
3430         }
3431         /* Set fdest to INF or some other exceptional value here?  */
3432      }
3433      else
3434      {
3435         SET_FSR_SE (0);
3436         *((UINT64 *)&v) &= 0xfffff00000000000ULL;
3437         res = (double)1.0/sqrt (v);
3438         *((UINT64 *)&res) &= 0xfffff00000000000ULL;
3439         if (res_prec)
3440            set_fregval_d (fdest, res);
3441         else
3442            set_fregval_s (fdest, (float)res);
3443      }
3444   }
3445   else
3446   {
3447      float v = get_fregval_s (fsrc2);
3448      float res;
3449      if (v == 0.0 || v < 0.0)
3450      {
3451         /* Generate source-exception trap if fsrc2 is 0 or negative.  */
3452         if (0 /* GET_FSR_FTE () */)
3453         {
3454            SET_PSR_FT (1);
3455            SET_FSR_SE (1);
3456            m_pending_trap = GET_FSR_FTE ();
3457         }
3458         /* Set fdest to INF or some other exceptional value here?  */
3459      }
3460      else
3461      {
3462         SET_FSR_SE (0);
3463         *((UINT32 *)&v) &= 0xffff8000;
3464         res = (float)1.0/sqrt (v);
3465         *((UINT32 *)&res) &= 0xffff8000;
3466         if (res_prec)
3467            set_fregval_d (fdest, (double)res);
3468         else
3469            set_fregval_s (fdest, res);
3470      }
3471   }
3472}
3473
3474
3475/* Execute fxfr fsrc1,idest.  */
3476void i860_cpu_device::insn_fxfr (UINT32 insn)
3477{
3478   UINT32 fsrc1 = get_fsrc1 (insn);
3479   UINT32 idest = get_idest (insn);
3480   float fv = 0;
3481
3482   /* This is a bit-pattern transfer, not a conversion.  */
3483   fv = get_fregval_s (fsrc1);
3484   set_iregval (idest, *(UINT32 *)&fv);
3485}
3486
3487
3488/* Execute [p]ftrunc.{ss,sd,dd} fsrc1,idest.  */
3489/* FIXME: Is .ss really a valid combination?  On the one hand,
3490   the programmer's reference (1990) lists ftrunc.p where .p
3491   is any of {ss,sd,dd}.  On the other hand, a paragraph on the
3492   same page states that [p]ftrunc must specify double-precision
3493   results.  Inconsistent.
3494   Update: The vendor SVR4 assembler does not accept .ss combination,
3495   so the latter sentence above appears to be the correct way.  */
3496void i860_cpu_device::insn_ftrunc (UINT32 insn)
3497{
3498   UINT32 fsrc1 = get_fsrc1 (insn);
3499   UINT32 fdest = get_fdest (insn);
3500   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3501   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3502   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3503
3504   /* Check for invalid .ds or .ss combinations.  */
3505   if ((insn & 0x080) == 0)
3506   {
3507      unrecog_opcode (m_pc, insn);
3508      return;
3509   }
3510
3511   /* Do the operation, being careful about source and result
3512      precision.  Operation: fdest = integer part of fsrc1 in
3513      lower 32-bits.  */
3514   if (src_prec)
3515   {
3516      double v1 = get_fregval_d (fsrc1);
3517      INT32 iv = (INT32)v1;
3518      /* We always write a single, since the lower 32-bits of fdest
3519         get the result (and the even numbered reg is the lower).  */
3520      set_fregval_s (fdest, *(float *)&iv);
3521   }
3522   else
3523   {
3524      float v1 = get_fregval_s (fsrc1);
3525      INT32 iv = (INT32)v1;
3526      /* We always write a single, since the lower 32-bits of fdest
3527         get the result (and the even numbered reg is the lower).  */
3528      set_fregval_s (fdest, *(float *)&iv);
3529   }
3530
3531   /* FIXME: Handle updating of pipestages for pftrunc.  */
3532   /* Includes looking at ARP (add result precision.) */
3533   if (piped)
3534   {
3535      fprintf (stderr, "insn_ftrunc: FIXME: pipelined not functional yet.\n");
3536      if (res_prec)
3537         set_fregval_d (fdest, 0.0);
3538      else
3539         set_fregval_s (fdest, 0.0);
3540   }
3541}
3542
3543
3544/* Execute [p]famov.{ss,sd,ds,dd} fsrc1,fdest.  */
3545void i860_cpu_device::insn_famov (UINT32 insn)
3546{
3547   UINT32 fsrc1 = get_fsrc1 (insn);
3548   UINT32 fdest = get_fdest (insn);
3549   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3550   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3551   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3552   double dbl_tmp_dest = 0.0;
3553   double sgl_tmp_dest = 0.0;
3554
3555   /* Do the operation, being careful about source and result
3556      precision.  */
3557   if (src_prec)
3558   {
3559      double v1 = get_fregval_d (fsrc1);
3560      if (res_prec)
3561         dbl_tmp_dest = v1;
3562      else
3563         sgl_tmp_dest = (float)v1;
3564   }
3565   else
3566   {
3567      float v1 = get_fregval_s (fsrc1);
3568      if (res_prec)
3569         dbl_tmp_dest = (double)v1;
3570      else
3571         sgl_tmp_dest = v1;
3572   }
3573
3574   /* FIXME: Set result-status bits besides ARP. And copy to fsr from
3575             last stage.  */
3576   /* FIXME: Scalar version flows through all stages.  */
3577   if (!piped)
3578   {
3579      /* Scalar version writes the current calculation to the fdest
3580         register, with precision specified by the R bit.  */
3581      if (res_prec)
3582         set_fregval_d (fdest, dbl_tmp_dest);
3583      else
3584         set_fregval_s (fdest, sgl_tmp_dest);
3585   }
3586   else
3587   {
3588      /* Pipelined version writes fdest with the result from the last
3589         stage of the pipeline, with precision specified by the ARP
3590         bit of the stage's result-status bits.  */
3591#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3592      /* Copy 3rd stage ARP to FSR.  */
3593      if (m_A[1 /* 2 */].stat.arp)
3594         m_cregs[CR_FSR] |= 0x20000000;
3595      else
3596         m_cregs[CR_FSR] &= ~0x20000000;
3597#endif
3598      if (m_A[2].stat.arp)  /* 3rd (last) stage.  */
3599         set_fregval_d (fdest, m_A[2].val.d);
3600      else
3601         set_fregval_s (fdest, m_A[2].val.s);
3602
3603      /* Now advance pipeline and write current calculation to
3604         first stage.  */
3605      m_A[2] = m_A[1];
3606      m_A[1] = m_A[0];
3607      if (res_prec)
3608      {
3609         m_A[0].val.d = dbl_tmp_dest;
3610         m_A[0].stat.arp = 1;
3611      }
3612      else
3613      {
3614         m_A[0].val.s = sgl_tmp_dest;
3615         m_A[0].stat.arp = 0;
3616      }
3617   }
3618}
3619
3620
3621/* Execute [p]fiadd/sub.{ss,dd} fsrc1,fsrc2,fdest.  */
3622void i860_cpu_device::insn_fiadd_sub (UINT32 insn)
3623{
3624   UINT32 fsrc1 = get_fsrc1 (insn);
3625   UINT32 fsrc2 = get_fsrc2 (insn);
3626   UINT32 fdest = get_fdest (insn);
3627   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3628   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3629   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3630   int is_sub = insn & 0x4;         /* 1 = sub, 0 = add.  */
3631   double dbl_tmp_dest = 0.0;
3632   float sgl_tmp_dest = 0.0;
3633
3634   /* Check for invalid .ds and .sd combinations.  */
3635   if ((insn & 0x180) == 0x100
3636      || (insn & 0x180) == 0x080)
3637   {
3638      unrecog_opcode (m_pc, insn);
3639      return;
3640   }
3641
3642   /* Do the operation, being careful about source and result
3643      precision.  */
3644   if (src_prec)
3645   {
3646      double v1 = get_fregval_d (fsrc1);
3647      double v2 = get_fregval_d (fsrc2);
3648      UINT64 iv1 = *(UINT64 *)&v1;
3649      UINT64 iv2 = *(UINT64 *)&v2;
3650      UINT64 r;
3651      if (is_sub)
3652         r = iv1 - iv2;
3653      else
3654         r = iv1 + iv2;
3655      if (res_prec)
3656         dbl_tmp_dest = *(double *)&r;
3657      else
3658         assert (0);    /* .ds not allowed.  */
3659   }
3660   else
3661   {
3662      float v1 = get_fregval_s (fsrc1);
3663      float v2 = get_fregval_s (fsrc2);
3664      UINT64 iv1 = (UINT64)(*(UINT32 *)&v1);
3665      UINT64 iv2 = (UINT64)(*(UINT32 *)&v2);
3666      UINT32 r;
3667      if (is_sub)
3668         r = (UINT32)(iv1 - iv2);
3669      else
3670         r = (UINT32)(iv1 + iv2);
3671      if (res_prec)
3672         assert (0);    /* .sd not allowed.  */
3673      else
3674         sgl_tmp_dest = *(float *)&r;
3675   }
3676
3677   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
3678   /* FIXME: Scalar version flows through all stages.  */
3679   if (!piped)
3680   {
3681      /* Scalar version writes the current calculation to the fdest
3682         register, with precision specified by the R bit.  */
3683      if (res_prec)
3684         set_fregval_d (fdest, dbl_tmp_dest);
3685      else
3686         set_fregval_s (fdest, sgl_tmp_dest);
3687   }
3688   else
3689   {
3690      /* Pipelined version writes fdest with the result from the last
3691         stage of the pipeline, with precision specified by the IRP
3692         bit of the stage's result-status bits.  */
3693#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3694      /* Copy stage IRP to FSR.  */
3695      if (res_prec)
3696         m_cregs[CR_FSR] |= 0x08000000;
3697      else
3698         m_cregs[CR_FSR] &= ~0x08000000;
3699#endif
3700      if (m_G.stat.irp)   /* 1st (and last) stage.  */
3701         set_fregval_d (fdest, m_G.val.d);
3702      else
3703         set_fregval_s (fdest, m_G.val.s);
3704
3705      /* Now write current calculation to first and only stage.  */
3706      if (res_prec)
3707      {
3708         m_G.val.d = dbl_tmp_dest;
3709         m_G.stat.irp = 1;
3710      }
3711      else
3712      {
3713         m_G.val.s = sgl_tmp_dest;
3714         m_G.stat.irp = 0;
3715      }
3716   }
3717}
3718
3719
3720/* Execute pf{gt,le,eq}.{ss,dd} fsrc1,fsrc2,fdest.
3721   Opcode pfgt has R bit cleared; pfle has R bit set.  */
3722void i860_cpu_device::insn_fcmp (UINT32 insn)
3723{
3724   UINT32 fsrc1 = get_fsrc1 (insn);
3725   UINT32 fsrc2 = get_fsrc2 (insn);
3726   UINT32 fdest = get_fdest (insn);
3727   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3728   double dbl_tmp_dest = 0.0;
3729   double sgl_tmp_dest = 0.0;
3730   /* int is_eq = insn & 1; */
3731   int is_gt = ((insn & 0x81) == 0x00);
3732   int is_le = ((insn & 0x81) == 0x80);
3733
3734   /* Do the operation.  Source and result precision must be the same.
3735        pfgt: CC set     if fsrc1 > fsrc2, else cleared.
3736        pfle: CC cleared if fsrc1 <= fsrc2, else set.
3737        pfeq: CC set     if fsrc1 = fsrc2, else cleared.
3738
3739      Note that the compares write an undefined (but non-exceptional)
3740      result into the first stage of the adder pipeline.  We'll model
3741      this by just pushing in dbl_ or sgl_tmp_dest which equal 0.0.  */
3742   if (src_prec)
3743   {
3744      double v1 = get_fregval_d (fsrc1);
3745      double v2 = get_fregval_d (fsrc2);
3746      if (is_gt)                /* gt.  */
3747         SET_PSR_CC (v1 > v2 ? 1 : 0);
3748      else if (is_le)           /* le.  */
3749         SET_PSR_CC (v1 <= v2 ? 0 : 1);
3750      else                      /* eq.  */
3751         SET_PSR_CC (v1 == v2 ? 1 : 0);
3752   }
3753   else
3754   {
3755      float v1 = get_fregval_s (fsrc1);
3756      float v2 = get_fregval_s (fsrc2);
3757      if (is_gt)                /* gt.  */
3758         SET_PSR_CC (v1 > v2 ? 1 : 0);
3759      else if (is_le)           /* le.  */
3760         SET_PSR_CC (v1 <= v2 ? 0 : 1);
3761      else                      /* eq.  */
3762         SET_PSR_CC (v1 == v2 ? 1 : 0);
3763   }
3764
3765   /* FIXME: Set result-status bits besides ARP. And copy to fsr from
3766             last stage.  */
3767   /* These write fdest with the result from the last
3768      stage of the pipeline, with precision specified by the ARP
3769      bit of the stage's result-status bits.  */
3770#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3771   /* Copy 3rd stage ARP to FSR.  */
3772   if (m_A[1 /* 2 */].stat.arp)
3773      m_cregs[CR_FSR] |= 0x20000000;
3774   else
3775      m_cregs[CR_FSR] &= ~0x20000000;
3776#endif
3777   if (m_A[2].stat.arp)  /* 3rd (last) stage.  */
3778      set_fregval_d (fdest, m_A[2].val.d);
3779   else
3780      set_fregval_s (fdest, m_A[2].val.s);
3781
3782   /* Now advance pipeline and write current calculation to
3783      first stage.  */
3784   m_A[2] = m_A[1];
3785   m_A[1] = m_A[0];
3786   if (src_prec)
3787   {
3788      m_A[0].val.d = dbl_tmp_dest;
3789      m_A[0].stat.arp = 1;
3790   }
3791   else
3792   {
3793      m_A[0].val.s = sgl_tmp_dest;
3794      m_A[0].stat.arp = 0;
3795   }
3796}
3797
3798
3799/* Execute [p]fzchk{l,s} fsrc1,fsrc2,fdest.
3800   The fzchk instructions have S and R bits set.  */
3801void i860_cpu_device::insn_fzchk (UINT32 insn)
3802{
3803   UINT32 fsrc1 = get_fsrc1 (insn);
3804   UINT32 fsrc2 = get_fsrc2 (insn);
3805   UINT32 fdest = get_fdest (insn);
3806   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3807   int is_fzchks = insn & 8;        /* 1 = fzchks, 0 = fzchkl.  */
3808   double dbl_tmp_dest = 0.0;
3809   int i;
3810   double v1 = get_fregval_d (fsrc1);
3811   double v2 = get_fregval_d (fsrc2);
3812   UINT64 iv1 = *(UINT64 *)&v1;
3813   UINT64 iv2 = *(UINT64 *)&v2;
3814   UINT64 r = 0;
3815   char pm = GET_PSR_PM ();
3816
3817   /* Check for S and R bits set.  */
3818   if ((insn & 0x180) != 0x180)
3819   {
3820      unrecog_opcode (m_pc, insn);
3821      return;
3822   }
3823
3824   /* Do the operation.  The fzchks version operates in parallel on
3825      four 16-bit pixels, while the fzchkl operates on two 32-bit
3826      pixels (pixels are unsigned ordinals in this context).  */
3827   if (is_fzchks)
3828   {
3829      pm = (pm >> 4) & 0x0f;
3830      for (i = 3; i >= 0; i--)
3831      {
3832         UINT16 ps1 = (iv1 >> (i * 16)) & 0xffff;
3833         UINT16 ps2 = (iv2 >> (i * 16)) & 0xffff;
3834         if (ps2 <= ps1)
3835         {
3836            r |= ((UINT64)ps2 << (i * 16));
3837            pm |= (1 << (7 - (3 - i)));
3838         }
3839         else
3840         {
3841            r |= ((UINT64)ps1 << (i * 16));
3842            pm &= ~(1 << (7 - (3 - i)));
3843         }
3844      }
3845   }
3846   else
3847   {
3848      pm = (pm >> 2) & 0x3f;
3849      for (i = 1; i >= 0; i--)
3850      {
3851         UINT32 ps1 = (iv1 >> (i * 32)) & 0xffffffff;
3852         UINT32 ps2 = (iv2 >> (i * 32)) & 0xffffffff;
3853         if (ps2 <= ps1)
3854         {
3855            r |= ((UINT64)ps2 << (i * 32));
3856            pm |= (1 << (7 - (1 - i)));
3857         }
3858         else
3859         {
3860            r |= ((UINT64)ps1 << (i * 32));
3861            pm &= ~(1 << (7 - (1 - i)));
3862         }
3863      }
3864   }
3865
3866   dbl_tmp_dest = *(double *)&r;
3867   SET_PSR_PM (pm);
3868   m_merge = 0;
3869
3870   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
3871   /* FIXME: Scalar version flows through all stages.  */
3872   if (!piped)
3873   {
3874      /* Scalar version writes the current calculation to the fdest
3875         register, always with double precision.  */
3876      set_fregval_d (fdest, dbl_tmp_dest);
3877   }
3878   else
3879   {
3880      /* Pipelined version writes fdest with the result from the last
3881         stage of the pipeline, with precision specified by the IRP
3882         bit of the stage's result-status bits.  */
3883      if (m_G.stat.irp)   /* 1st (and last) stage.  */
3884         set_fregval_d (fdest, m_G.val.d);
3885      else
3886         set_fregval_s (fdest, m_G.val.s);
3887
3888      /* Now write current calculation to first and only stage.  */
3889      m_G.val.d = dbl_tmp_dest;
3890      m_G.stat.irp = 1;
3891   }
3892}
3893
3894
3895/* Execute [p]form.dd fsrc1,fdest.
3896   The form.dd instructions have S and R bits set.  */
3897void i860_cpu_device::insn_form (UINT32 insn)
3898{
3899   UINT32 fsrc1 = get_fsrc1 (insn);
3900   UINT32 fdest = get_fdest (insn);
3901   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3902   double dbl_tmp_dest = 0.0;
3903   double v1 = get_fregval_d (fsrc1);
3904   UINT64 iv1 = *(UINT64 *)&v1;
3905
3906   /* Check for S and R bits set.  */
3907   if ((insn & 0x180) != 0x180)
3908   {
3909      unrecog_opcode (m_pc, insn);
3910      return;
3911   }
3912
3913   iv1 |= m_merge;
3914   dbl_tmp_dest = *(double *)&iv1;
3915   m_merge = 0;
3916
3917   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
3918   /* FIXME: Scalar version flows through all stages.  */
3919   if (!piped)
3920   {
3921      /* Scalar version writes the current calculation to the fdest
3922         register, always with double precision.  */
3923      set_fregval_d (fdest, dbl_tmp_dest);
3924   }
3925   else
3926   {
3927      /* Pipelined version writes fdest with the result from the last
3928         stage of the pipeline, with precision specified by the IRP
3929         bit of the stage's result-status bits.  */
3930      if (m_G.stat.irp)   /* 1st (and last) stage.  */
3931         set_fregval_d (fdest, m_G.val.d);
3932      else
3933         set_fregval_s (fdest, m_G.val.s);
3934
3935      /* Now write current calculation to first and only stage.  */
3936      m_G.val.d = dbl_tmp_dest;
3937      m_G.stat.irp = 1;
3938   }
3939}
3940
3941
3942/* Execute [p]faddp fsrc1,fsrc2,fdest.  */
3943void i860_cpu_device::insn_faddp (UINT32 insn)
3944{
3945   UINT32 fsrc1 = get_fsrc1 (insn);
3946   UINT32 fsrc2 = get_fsrc2 (insn);
3947   UINT32 fdest = get_fdest (insn);
3948   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3949   double dbl_tmp_dest = 0.0;
3950   double v1 = get_fregval_d (fsrc1);
3951   double v2 = get_fregval_d (fsrc2);
3952   UINT64 iv1 = *(UINT64 *)&v1;
3953   UINT64 iv2 = *(UINT64 *)&v2;
3954   UINT64 r = 0;
3955   int ps = GET_PSR_PS ();
3956
3957   r = iv1 + iv2;
3958   dbl_tmp_dest = *(double *)&r;
3959
3960   /* Update the merge register depending on the pixel size.
3961      PS: 0 = 8 bits, 1 = 16 bits, 2 = 32-bits.  */
3962   if (ps == 0)
3963   {
3964      m_merge = ((m_merge >> 8) & ~0xff00ff00ff00ff00ULL);
3965      m_merge |= (r & 0xff00ff00ff00ff00ULL);
3966   }
3967   else if (ps == 1)
3968   {
3969      m_merge = ((m_merge >> 6) & ~0xfc00fc00fc00fc00ULL);
3970      m_merge |= (r & 0xfc00fc00fc00fc00ULL);
3971   }
3972   else if (ps == 2)
3973   {
3974      m_merge = ((m_merge >> 8) & ~0xff000000ff000000ULL);
3975      m_merge |= (r & 0xff000000ff000000ULL);
3976   }
3977#ifdef TRACE_UNDEFINED_I860
3978   else
3979      fprintf (stderr, "insn_faddp: Undefined i860XR behavior, invalid value %d for pixel size.\n", ps);
3980#endif
3981
3982   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
3983   /* FIXME: Scalar version flows through all stages.  */
3984   if (!piped)
3985   {
3986      /* Scalar version writes the current calculation to the fdest
3987         register, always with double precision.  */
3988      set_fregval_d (fdest, dbl_tmp_dest);
3989   }
3990   else
3991   {
3992      /* Pipelined version writes fdest with the result from the last
3993         stage of the pipeline, with precision specified by the IRP
3994         bit of the stage's result-status bits.  */
3995      if (m_G.stat.irp)   /* 1st (and last) stage.  */
3996         set_fregval_d (fdest, m_G.val.d);
3997      else
3998         set_fregval_s (fdest, m_G.val.s);
3999
4000      /* Now write current calculation to first and only stage.  */
4001      m_G.val.d = dbl_tmp_dest;
4002      m_G.stat.irp = 1;
4003   }
4004}
4005
4006
4007/* Execute [p]faddz fsrc1,fsrc2,fdest.  */
4008void i860_cpu_device::insn_faddz (UINT32 insn)
4009{
4010   UINT32 fsrc1 = get_fsrc1 (insn);
4011   UINT32 fsrc2 = get_fsrc2 (insn);
4012   UINT32 fdest = get_fdest (insn);
4013   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
4014   double dbl_tmp_dest = 0.0;
4015   double v1 = get_fregval_d (fsrc1);
4016   double v2 = get_fregval_d (fsrc2);
4017   UINT64 iv1 = *(UINT64 *)&v1;
4018   UINT64 iv2 = *(UINT64 *)&v2;
4019   UINT64 r = 0;
4020
4021   r = iv1 + iv2;
4022   dbl_tmp_dest = *(double *)&r;
4023
4024   /* Update the merge register depending on the pixel size.  */
4025   m_merge = ((m_merge >> 16) & ~0xffff0000ffff0000ULL);
4026   m_merge |= (r & 0xffff0000ffff0000ULL);
4027
4028   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
4029   /* FIXME: Scalar version flows through all stages.  */
4030   if (!piped)
4031   {
4032      /* Scalar version writes the current calculation to the fdest
4033         register, always with double precision.  */
4034      set_fregval_d (fdest, dbl_tmp_dest);
4035   }
4036   else
4037   {
4038      /* Pipelined version writes fdest with the result from the last
4039         stage of the pipeline, with precision specified by the IRP
4040         bit of the stage's result-status bits.  */
4041      if (m_G.stat.irp)   /* 1st (and last) stage.  */
4042         set_fregval_d (fdest, m_G.val.d);
4043      else
4044         set_fregval_s (fdest, m_G.val.s);
4045
4046      /* Now write current calculation to first and only stage.  */
4047      m_G.val.d = dbl_tmp_dest;
4048      m_G.stat.irp = 1;
4049   }
4050}
4051
4052
4053/* Flags for the decode table.  */
4054enum {
4055   DEC_MORE    = 1,    /* More decoding necessary.  */
4056   DEC_DECODED = 2     /* Fully decoded, go.  */
4057};
4058
4059
4060/* First-level decode table (i.e., for the 6 primary opcode bits).  */
4061const i860_cpu_device::decode_tbl_t i860_cpu_device::decode_tbl[64] = {
4062   /* A slight bit of decoding for loads and stores is done in the
4063      execution routines (operand size and addressing mode), which
4064      is why their respective entries are identical.  */
4065   { &i860_cpu_device::insn_ldx,         DEC_DECODED}, /* ld.b isrc1(isrc2),idest.  */
4066   { &i860_cpu_device::insn_ldx,         DEC_DECODED}, /* ld.b #const(isrc2),idest.  */
4067   { &i860_cpu_device::insn_ixfr,        DEC_DECODED}, /* ixfr isrc1ni,fdest.  */
4068   { &i860_cpu_device::insn_stx,         DEC_DECODED}, /* st.b isrc1ni,#const(isrc2).  */
4069   { &i860_cpu_device::insn_ldx,         DEC_DECODED}, /* ld.{s,l} isrc1(isrc2),idest.  */
4070   { &i860_cpu_device::insn_ldx,         DEC_DECODED}, /* ld.{s,l} #const(isrc2),idest.  */
4071   { 0,                0},
4072   { &i860_cpu_device::insn_stx,         DEC_DECODED}, /* st.{s,l} isrc1ni,#const(isrc2),idest.*/
4073   { &i860_cpu_device::insn_fldy,        DEC_DECODED}, /* fld.{l,d,q} isrc1(isrc2)[++],fdest. */
4074   { &i860_cpu_device::insn_fldy,        DEC_DECODED}, /* fld.{l,d,q} #const(isrc2)[++],fdest. */
4075   { &i860_cpu_device::insn_fsty,        DEC_DECODED}, /* fst.{l,d,q} fdest,isrc1(isrc2)[++] */
4076   { &i860_cpu_device::insn_fsty,        DEC_DECODED}, /* fst.{l,d,q} fdest,#const(isrc2)[++] */
4077   { &i860_cpu_device::insn_ld_ctrl,     DEC_DECODED}, /* ld.c csrc2,idest.  */
4078   { &i860_cpu_device::insn_flush,       DEC_DECODED}, /* flush #const(isrc2) (or autoinc).  */
4079   { &i860_cpu_device::insn_st_ctrl,     DEC_DECODED}, /* st.c isrc1,csrc2.  */
4080   { &i860_cpu_device::insn_pstd,        DEC_DECODED}, /* pst.d fdest,#const(isrc2)[++].  */
4081   { &i860_cpu_device::insn_bri,         DEC_DECODED}, /* bri isrc1ni.  */
4082   { &i860_cpu_device::insn_trap,        DEC_DECODED}, /* trap isrc1ni,isrc2,idest.   */
4083   { 0,                DEC_MORE}, /* FP ESCAPE FORMAT, more decode.  */
4084   { 0,                DEC_MORE}, /* CORE ESCAPE FORMAT, more decode.  */
4085   { &i860_cpu_device::insn_btne,        DEC_DECODED}, /* btne isrc1,isrc2,sbroff.  */
4086   { &i860_cpu_device::insn_btne_imm,    DEC_DECODED}, /* btne #const,isrc2,sbroff.  */
4087   { &i860_cpu_device::insn_bte,         DEC_DECODED}, /* bte isrc1,isrc2,sbroff.  */
4088   { &i860_cpu_device::insn_bte_imm,     DEC_DECODED}, /* bte #const5,isrc2,idest.  */
4089   { &i860_cpu_device::insn_fldy,        DEC_DECODED}, /* pfld.{l,d,q} isrc1(isrc2)[++],fdest.*/
4090   { &i860_cpu_device::insn_fldy,        DEC_DECODED}, /* pfld.{l,d,q} #const(isrc2)[++],fdest.*/
4091   { &i860_cpu_device::insn_br,          DEC_DECODED}, /* br lbroff.  */
4092   { &i860_cpu_device::insn_call,        DEC_DECODED}, /* call lbroff .  */
4093   { &i860_cpu_device::insn_bc,          DEC_DECODED}, /* bc lbroff.  */
4094   { &i860_cpu_device::insn_bct,         DEC_DECODED}, /* bc.t lbroff.  */
4095   { &i860_cpu_device::insn_bnc,         DEC_DECODED}, /* bnc lbroff.  */
4096   { &i860_cpu_device::insn_bnct,        DEC_DECODED}, /* bnc.t lbroff.  */
4097   { &i860_cpu_device::insn_addu,        DEC_DECODED}, /* addu isrc1,isrc2,idest.  */
4098   { &i860_cpu_device::insn_addu_imm,    DEC_DECODED}, /* addu #const,isrc2,idest.  */
4099   { &i860_cpu_device::insn_subu,        DEC_DECODED}, /* subu isrc1,isrc2,idest.  */
4100   { &i860_cpu_device::insn_subu_imm,    DEC_DECODED}, /* subu #const,isrc2,idest.  */
4101   { &i860_cpu_device::insn_adds,        DEC_DECODED}, /* adds isrc1,isrc2,idest.  */
4102   { &i860_cpu_device::insn_adds_imm,    DEC_DECODED}, /* adds #const,isrc2,idest.  */
4103   { &i860_cpu_device::insn_subs,        DEC_DECODED}, /* subs isrc1,isrc2,idest.  */
4104   { &i860_cpu_device::insn_subs_imm,    DEC_DECODED}, /* subs #const,isrc2,idest.  */
4105   { &i860_cpu_device::insn_shl,         DEC_DECODED}, /* shl isrc1,isrc2,idest.  */
4106   { &i860_cpu_device::insn_shl_imm,     DEC_DECODED}, /* shl #const,isrc2,idest.  */
4107   { &i860_cpu_device::insn_shr,         DEC_DECODED}, /* shr isrc1,isrc2,idest.  */
4108   { &i860_cpu_device::insn_shr_imm,     DEC_DECODED}, /* shr #const,isrc2,idest.  */
4109   { &i860_cpu_device::insn_shrd,        DEC_DECODED}, /* shrd isrc1ni,isrc2,idest.  */
4110   { &i860_cpu_device::insn_bla,         DEC_DECODED}, /* bla isrc1ni,isrc2,sbroff.  */
4111   { &i860_cpu_device::insn_shra,        DEC_DECODED}, /* shra isrc1,isrc2,idest.  */
4112   { &i860_cpu_device::insn_shra_imm,    DEC_DECODED}, /* shra #const,isrc2,idest.  */
4113   { &i860_cpu_device::insn_and,         DEC_DECODED}, /* and isrc1,isrc2,idest.  */
4114   { &i860_cpu_device::insn_and_imm,     DEC_DECODED}, /* and #const,isrc2,idest.  */
4115   { 0,                0},
4116   { &i860_cpu_device::insn_andh_imm,    DEC_DECODED}, /* andh #const,isrc2,idest.  */
4117   { &i860_cpu_device::insn_andnot,      DEC_DECODED}, /* andnot isrc1,isrc2,idest.  */
4118   { &i860_cpu_device::insn_andnot_imm,  DEC_DECODED}, /* andnot #const,isrc2,idest.  */
4119   { 0,                0},
4120   { &i860_cpu_device::insn_andnoth_imm, DEC_DECODED}, /* andnoth #const,isrc2,idest.  */
4121   { &i860_cpu_device::insn_or,          DEC_DECODED}, /* or isrc1,isrc2,idest.  */
4122   { &i860_cpu_device::insn_or_imm,      DEC_DECODED}, /* or #const,isrc2,idest.  */
4123   { 0,                0},
4124   { &i860_cpu_device::insn_orh_imm,     DEC_DECODED}, /* orh #const,isrc2,idest.  */
4125   { &i860_cpu_device::insn_xor,         DEC_DECODED}, /* xor isrc1,isrc2,idest.  */
4126   { &i860_cpu_device::insn_xor_imm,     DEC_DECODED}, /* xor #const,isrc2,idest.  */
4127   { 0,                0},
4128   { &i860_cpu_device::insn_xorh_imm,    DEC_DECODED}, /* xorh #const,isrc2,idest.  */
4129};
4130
4131
4132/* Second-level decode table (i.e., for the 3 core escape opcode bits).  */
4133const i860_cpu_device::decode_tbl_t i860_cpu_device::core_esc_decode_tbl[8] = {
4134   { 0,                0},
4135   { 0,                0}, /* lock  (FIXME: unimplemented).  */
4136   { &i860_cpu_device::insn_calli,       DEC_DECODED}, /* calli isrc1ni.                 */
4137   { 0,                0},
4138   { &i860_cpu_device::insn_intovr,      DEC_DECODED}, /* intovr.                        */
4139   { 0,                0},
4140   { 0,                0},
4141   { 0,                0}, /* unlock (FIXME: unimplemented). */
4142};
4143
4144
4145/* Second-level decode table (i.e., for the 7 FP extended opcode bits).  */
4146const i860_cpu_device::decode_tbl_t i860_cpu_device::fp_decode_tbl[128] = {
4147   /* Floating point instructions.  The least significant 7 bits are
4148      the (extended) opcode and bits 10:7 are P,D,S,R respectively
4149      ([p]ipelined, [d]ual, [s]ource prec., [r]esult prec.).
4150      For some operations, I defer decoding the P,S,R bits to the
4151      emulation routine for them.  */
4152   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x00 pf[m]am */
4153   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x01 pf[m]am */
4154   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x02 pf[m]am */
4155   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x03 pf[m]am */
4156   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x04 pf[m]am */
4157   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x05 pf[m]am */
4158   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x06 pf[m]am */
4159   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x07 pf[m]am */
4160   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x08 pf[m]am */
4161   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x09 pf[m]am */
4162   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0A pf[m]am */
4163   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0B pf[m]am */
4164   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0C pf[m]am */
4165   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0D pf[m]am */
4166   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0E pf[m]am */
4167   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0F pf[m]am */
4168   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x10 pf[m]sm */
4169   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x11 pf[m]sm */
4170   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x12 pf[m]sm */
4171   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x13 pf[m]sm */
4172   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x14 pf[m]sm */
4173   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x15 pf[m]sm */
4174   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x16 pf[m]sm */
4175   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x17 pf[m]sm */
4176   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x18 pf[m]sm */
4177   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x19 pf[m]sm */
4178   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1A pf[m]sm */
4179   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1B pf[m]sm */
4180   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1C pf[m]sm */
4181   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1D pf[m]sm */
4182   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1E pf[m]sm */
4183   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1F pf[m]sm */
4184   { &i860_cpu_device::insn_fmul,        DEC_DECODED}, /* 0x20 [p]fmul */
4185   { &i860_cpu_device::insn_fmlow,       DEC_DECODED}, /* 0x21 fmlow.dd */
4186   { &i860_cpu_device::insn_frcp,        DEC_DECODED}, /* 0x22 frcp.{ss,sd,dd} */
4187   { &i860_cpu_device::insn_frsqr,       DEC_DECODED}, /* 0x23 frsqr.{ss,sd,dd} */
4188   { &i860_cpu_device::insn_fmul,        DEC_DECODED}, /* 0x24 pfmul3.dd */
4189   { 0,                0}, /* 0x25 */
4190   { 0,                0}, /* 0x26 */
4191   { 0,                0}, /* 0x27 */
4192   { 0,                0}, /* 0x28 */
4193   { 0,                0}, /* 0x29 */
4194   { 0,                0}, /* 0x2A */
4195   { 0,                0}, /* 0x2B */
4196   { 0,                0}, /* 0x2C */
4197   { 0,                0}, /* 0x2D */
4198   { 0,                0}, /* 0x2E */
4199   { 0,                0}, /* 0x2F */
4200   { &i860_cpu_device::insn_fadd_sub,    DEC_DECODED}, /* 0x30, [p]fadd.{ss,sd,dd} */
4201   { &i860_cpu_device::insn_fadd_sub,    DEC_DECODED}, /* 0x31, [p]fsub.{ss,sd,dd} */
4202   { 0,                0}, /* 0x32, [p]fix.{ss,sd,dd}  FIXME: nyi. */
4203   { &i860_cpu_device::insn_famov,       DEC_DECODED}, /* 0x33, [p]famov.{ss,sd,ds,dd} */
4204   { &i860_cpu_device::insn_fcmp,        DEC_DECODED}, /* 0x34, pf{gt,le}.{ss,dd} */
4205   { &i860_cpu_device::insn_fcmp,        DEC_DECODED}, /* 0x35, pfeq.{ss,dd} */
4206   { 0,                0}, /* 0x36 */
4207   { 0,                0}, /* 0x37 */
4208   { 0,                0}, /* 0x38 */
4209   { 0,                0}, /* 0x39 */
4210   { &i860_cpu_device::insn_ftrunc,      DEC_DECODED}, /* 0x3A, [p]ftrunc.{ss,sd,dd} */
4211   { 0,                0}, /* 0x3B */
4212   { 0,                0}, /* 0x3C */
4213   { 0,                0}, /* 0x3D */
4214   { 0,                0}, /* 0x3E */
4215   { 0,                0}, /* 0x3F */
4216   { &i860_cpu_device::insn_fxfr,        DEC_DECODED}, /* 0x40, fxfr */
4217   { 0,                0}, /* 0x41 */
4218   { 0,                0}, /* 0x42 */
4219   { 0,                0}, /* 0x43 */
4220   { 0,                0}, /* 0x44 */
4221   { 0,                0}, /* 0x45 */
4222   { 0,                0}, /* 0x46 */
4223   { 0,                0}, /* 0x47 */
4224   { 0,                0}, /* 0x48 */
4225   { &i860_cpu_device::insn_fiadd_sub,   DEC_DECODED}, /* 0x49, [p]fiadd.{ss,dd} */
4226   { 0,                0}, /* 0x4A */
4227   { 0,                0}, /* 0x4B */
4228   { 0,                0}, /* 0x4C */
4229   { &i860_cpu_device::insn_fiadd_sub,   DEC_DECODED}, /* 0x4D, [p]fisub.{ss,dd} */
4230   { 0,                0}, /* 0x4E */
4231   { 0,                0}, /* 0x4F */
4232   { &i860_cpu_device::insn_faddp,       DEC_DECODED}, /* 0x50, [p]faddp */
4233   { &i860_cpu_device::insn_faddz,       DEC_DECODED}, /* 0x51, [p]faddz */
4234   { 0,                0}, /* 0x52 */
4235   { 0,                0}, /* 0x53 */
4236   { 0,                0}, /* 0x54 */
4237   { 0,                0}, /* 0x55 */
4238   { 0,                0}, /* 0x56 */
4239   { &i860_cpu_device::insn_fzchk,       DEC_DECODED}, /* 0x57, [p]fzchkl */
4240   { 0,                0}, /* 0x58 */
4241   { 0,                0}, /* 0x59 */
4242   { &i860_cpu_device::insn_form,        DEC_DECODED}, /* 0x5A, [p]form.dd */
4243   { 0,                0}, /* 0x5B */
4244   { 0,                0}, /* 0x5C */
4245   { 0,                0}, /* 0x5D */
4246   { 0,                0}, /* 0x5E */
4247   { &i860_cpu_device::insn_fzchk,       DEC_DECODED}, /* 0x5F, [p]fzchks */
4248   { 0,                0}, /* 0x60 */
4249   { 0,                0}, /* 0x61 */
4250   { 0,                0}, /* 0x62 */
4251   { 0,                0}, /* 0x63 */
4252   { 0,                0}, /* 0x64 */
4253   { 0,                0}, /* 0x65 */
4254   { 0,                0}, /* 0x66 */
4255   { 0,                0}, /* 0x67 */
4256   { 0,                0}, /* 0x68 */
4257   { 0,                0}, /* 0x69 */
4258   { 0,                0}, /* 0x6A */
4259   { 0,                0}, /* 0x6B */
4260   { 0,                0}, /* 0x6C */
4261   { 0,                0}, /* 0x6D */
4262   { 0,                0}, /* 0x6E */
4263   { 0,                0}, /* 0x6F */
4264   { 0,                0}, /* 0x70 */
4265   { 0,                0}, /* 0x71 */
4266   { 0,                0}, /* 0x72 */
4267   { 0,                0}, /* 0x73 */
4268   { 0,                0}, /* 0x74 */
4269   { 0,                0}, /* 0x75 */
4270   { 0,                0}, /* 0x76 */
4271   { 0,                0}, /* 0x77 */
4272   { 0,                0}, /* 0x78 */
4273   { 0,                0}, /* 0x79 */
4274   { 0,                0}, /* 0x7A */
4275   { 0,                0}, /* 0x7B */
4276   { 0,                0}, /* 0x7C */
4277   { 0,                0}, /* 0x7D */
4278   { 0,                0}, /* 0x7E */
4279   { 0,                0}, /* 0x7F */
4280};
4281
4282
4283/*
4284 * Main decoder driver.
4285 *  insn = instruction at the current PC to execute.
4286 *  non_shadow = This insn is not in the shadow of a delayed branch).
4287 */
4288void i860_cpu_device::decode_exec (UINT32 insn, UINT32 non_shadow)
4289{
4290   int upper_6bits = (insn >> 26) & 0x3f;
4291   char flags = 0;
4292   int unrecognized = 1;
4293
4294   if (m_exiting_ifetch)
4295      return;
4296
4297   if ((upper_6bits == 0x12 || upper_6bits == 0x2c) && insn & 0x0200)
4298      logerror("D-bit seen.\n");
4299   if (GET_EPSR_BE ())
4300      logerror("BE-bit high.\n");
4301   if (GET_DIRBASE_CS8 ())
4302      logerror("CS8-bit high.\n");
4303
4304   flags = decode_tbl[upper_6bits].flags;
4305   if (flags & DEC_DECODED)
4306   {
4307      (this->*decode_tbl[upper_6bits].insn_exec)(insn);
4308      unrecognized = 0;
4309   }
4310   else if (flags & DEC_MORE)
4311   {
4312      if (upper_6bits == 0x12)
4313      {
4314         /* FP instruction format handled here.  */
4315         char fp_flags = fp_decode_tbl[insn & 0x7f].flags;
4316         if (fp_flags & DEC_DECODED)
4317         {
4318            (this->*fp_decode_tbl[insn & 0x7f].insn_exec)(insn);
4319            unrecognized = 0;
4320         }
4321      }
4322      else if (upper_6bits == 0x13)
4323      {
4324         /* Core escape instruction format handled here.  */
4325         char esc_flags = core_esc_decode_tbl[insn & 0x3].flags;
4326         if (esc_flags & DEC_DECODED)
4327         {
4328            (this->*core_esc_decode_tbl[insn & 0x3].insn_exec)(insn);
4329            unrecognized = 0;
4330         }
4331      }
4332   }
4333
4334   if (unrecognized)
4335      unrecog_opcode (m_pc, insn);
4336
4337   /* For now, just treat every instruction as taking the same number of
4338      clocks-- a major oversimplification.  */
4339   m_icount -= 9;
4340}
4341
4342
4343/* Set-up all the default power-on/reset values.  */
4344void i860_cpu_device::reset_i860 ()
4345{
4346   int i;
4347   /* On power-up/reset, i860 has values:
4348        PC = 0xffffff00.
4349        Integer registers: r0 = 0, others = undefined.
4350        FP registers:      f0:f1 = 0, others undefined.
4351        psr: U = IM = BR = BW = 0; others = undefined.
4352        epsr: IL = WP = PBM = BE = 0; processor type, stepping, and
4353              DCS are proper and read-only; others = undefined.
4354        db: undefined.
4355        dirbase: DPS, BL, ATE = 0
4356        fir, fsr, KR, KI, MERGE: undefined. (what about T?)
4357
4358        I$: flushed.
4359        D$: undefined (all modified bits = 0).
4360        TLB: flushed.
4361
4362      Note that any undefined values are set to 0x55aa55aa patterns to
4363      try to detect defective i860 software.  */
4364
4365   /* PC is at trap address after reset.  */
4366   m_pc = 0xffffff00;
4367
4368   /* Set grs and frs to undefined/nonsense values, except r0.  */
4369   for (i = 0; i < 32; i++)
4370   {
4371      set_iregval (i, 0x55aa55aa);
4372      set_fregval_s (i, 0.0);
4373   }
4374   set_iregval (0, 0);
4375   set_fregval_s (0, 0.0);
4376   set_fregval_s (1, 0.0);
4377
4378   /* Set whole psr to 0.  This sets the proper bits to 0 as specified
4379      above, and zeroes the undefined bits.  */
4380   m_cregs[CR_PSR] = 0;
4381
4382   /* Set most of the epsr bits to 0 (as specified above), leaving
4383      undefined as zero as well.  Then properly set processor type,
4384      step, and DCS. Type = EPSR[7..0], step = EPSR[12..8],
4385      DCS = EPSR[21..18] (2^[12+dcs] = cache size).
4386      We'll pretend to be stepping D0, since it has the fewest bugs
4387      (and I don't want to emulate the many defects in the earlier
4388      steppings).
4389      Proc type: 1 = XR, 2 = XP   (XR has 8KB data cache -> DCS = 1).
4390      Steppings (XR): 3,4,5,6,7 = (B2, C0, B3, C1, D0 respectively).
4391      Steppings (XP): 0, 2, 3, 4 = (A0, B0, B1, B2) (any others?).  */
4392   m_cregs[CR_EPSR] = 0x00040701;
4393
4394   /* Set DPS, BL, ATE = 0 and the undefined parts also to 0.  */
4395   m_cregs[CR_DIRBASE] = 0x00000000;
4396
4397   /* Set fir, fsr, KR, KI, MERGE, T to undefined.  */
4398   m_cregs[CR_FIR] = 0xaa55aa55;
4399   m_cregs[CR_FSR] = /* 0xaa55aa55; */ 0;
4400   m_KR.d = 0.0;
4401   m_KI.d = 0.0;
4402   m_T.d = 0.0;
4403   m_merge = 0xaa55aa55;
4404
4405   m_fir_gets_trap_addr = 0;
4406}
4407
4408
4409
4410
4411/*=================================================================*/
4412/* MAME execution hook for i860 emulator. */
4413/*=================================================================*/
4414
4415void i860_cpu_device::execute_run()
4416{
4417   /* Check if the data bus is held by another device, and bail if so.
4418      Also check for reset.  */
4419   if (m_pin_reset)
4420      reset_i860 ();
4421   if (m_pin_bus_hold)
4422   {
4423      m_icount = 0;
4424      return;
4425   }
4426
4427   m_exiting_readmem = 0;
4428   m_exiting_ifetch = 0;
4429
4430   /* Decode and execute loop.  */
4431   while (m_icount > 0)
4432   {
4433      UINT32 savepc = m_pc;
4434      m_pc_updated = 0;
4435      m_pending_trap = 0;
4436
4437#if 1 /* Delete me soon, for debugging VC inter-processor synch.  */
4438      if (m_pc == 0xfffc0370 ||
4439         m_pc == 0xfffc03a4)
4440      {
4441         fprintf(stderr, "(%s) 0x%08x: snag 0x20000000\n", tag(), m_pc);
4442         m_single_stepping = 0;
4443      }
4444      else if (m_pc == 0xfffc0384 ||
4445               m_pc == 0xfffc03b8)
4446      {
4447         fprintf(stderr, "(%s) 0x%08x: passed 0x20000000\n", tag(), m_pc);
4448         m_single_stepping = 0;
4449      }
4450#endif
4451
4452      savepc = m_pc;
4453      debugger_instruction_hook(this, m_pc);
4454      decode_exec (ifetch (m_pc), 1);
4455
4456      m_exiting_ifetch = 0;
4457      m_exiting_readmem = 0;
4458
4459      if (m_pending_trap)
4460      {
4461         /* If we need to trap, change PC to trap address.
4462            Also set supervisor mode, copy U and IM to their
4463            previous versions, clear IM.  */
4464         if ((m_pending_trap & TRAP_WAS_EXTERNAL) || (GET_EPSR_INT () && GET_PSR_IN ()))
4465         {
4466            if (!m_pc_updated)
4467               m_cregs[CR_FIR] = savepc + 4;
4468            else
4469               m_cregs[CR_FIR] = m_pc;
4470         }
4471         else if (m_pending_trap & TRAP_IN_DELAY_SLOT)
4472         {
4473            m_cregs[CR_FIR] = savepc + 4;
4474         }
4475         else
4476            m_cregs[CR_FIR] = savepc;
4477
4478         m_fir_gets_trap_addr = 1;
4479         SET_PSR_PU (GET_PSR_U ());
4480         SET_PSR_PIM (GET_PSR_IM ());
4481         SET_PSR_U (0);
4482         SET_PSR_IM (0);
4483         SET_PSR_DIM (0);
4484         SET_PSR_DS (0);
4485         m_pc = 0xffffff00;
4486         m_pending_trap = 0;
4487      }
4488      else if (!m_pc_updated)
4489      {
4490         /* If the PC wasn't updated by a control flow instruction, just
4491            bump to next sequential instruction.  */
4492         m_pc += 4;
4493      }
4494
4495      /*if (m_single_stepping)
4496          debugger (cpustate); */
4497   }
4498}
4499/*=================================================================*/
4500
4501
4502
4503
4504#if 0
4505/*=================================================================*/
4506/* Internal debugger-related stuff.  */
4507
4508extern unsigned disasm_i860 (char *buf, unsigned int pc, unsigned int insn);
4509
4510
4511/* Disassemble `len' instructions starting at `addr'.  */
4512void i860_cpu_device::disasm (UINT32 addr, int len)
4513{
4514   UINT32 insn;
4515   int j;
4516   for (j = 0; j < len; j++)
4517   {
4518      char buf[256];
4519      UINT32 phys_addr = addr;
4520      if (GET_DIRBASE_ATE ())
4521         phys_addr = get_address_translation (addr, 1  /* is_dataref */, 0 /* is_write */);
4522
4523      /* Note that we print the incoming (possibly virtual) address as the
4524         PC rather than the translated address.  */
4525      fprintf (stderr, "  (%s) 0x%08x: ", m_device->tag(), addr);
4526      insn = m_program->read_dword(phys_addr);
4527#ifdef HOST_MSB
4528      BYTE_REV32 (insn);
4529#endif /* HOST_MSB.  */
4530      disasm_i860 (buf, addr, insn); fprintf (stderr, "%s", buf);
4531      fprintf (stderr, "\n");
4532      addr += 4;
4533#if 1
4534      if (m_single_stepping == 1 && has_delay_slot (insn))
4535         len += 1;
4536#endif
4537   }
4538}
4539
4540
4541/* Dump `len' bytes starting at `addr'.  */
4542void i860_cpu_device::dbg_db (UINT32 addr, int len)
4543{
4544   UINT8 b[16];
4545   int i;
4546   /* This will always dump a multiple of 16 bytes, even if 'len' isn't.  */
4547   while (len > 0)
4548   {
4549      /* Note that we print the incoming (possibly virtual) address
4550         rather than the translated address.  */
4551      fprintf (stderr, "0x%08x: ", addr);
4552      for (i = 0; i < 16; i++)
4553      {
4554         UINT32 phys_addr = addr;
4555         if (GET_DIRBASE_ATE ())
4556            phys_addr = get_address_translation (addr, 1  /* is_dataref */, 0 /* is_write */);
4557
4558         b[i] = m_program->read_byte(phys_addr);
4559         fprintf (stderr, "%02x ", b[i]);
4560         addr++;
4561      }
4562      fprintf (stderr, "| ");
4563      for (i = 0; i < 16; i++)
4564      {
4565         if (isprint (b[i]))
4566            fprintf (stderr, "%c", b[i]);
4567         else
4568            fprintf (stderr, ".");
4569      }
4570      fprintf (stderr, "\n");
4571      len -= 16;
4572   }
4573}
4574
4575
4576/* A simple internal debugger.  */
4577void debugger (i860s *cpustate)
4578{
4579   char buf[256];
4580   UINT32 curr_disasm = m_pc;
4581   UINT32 curr_dumpdb = 0;
4582   int c = 0;
4583
4584   if (m_single_stepping > 1 && m_single_stepping != m_pc)
4585      return;
4586
4587   buf[0] = 0;
4588
4589   /* Always disassemble the upcoming instruction when single-stepping.  */
4590   if (m_single_stepping)
4591   {
4592      disasm (m_pc, 1);
4593      if (has_delay_slot (2))
4594         disasm (m_pc + 4, 1);
4595   }
4596   else
4597      fprintf (stderr, "\nEmulator: internal debugger started (? for help).\n");
4598
4599   fflush (stdin);
4600
4601   m_single_stepping = 0;
4602   while (!m_single_stepping)
4603   {
4604      fprintf (stderr, "- ");
4605#if 0  /* Doesn't work on MacOSX BSD flavor.  */
4606      fscanf (stdin, "%s", buf);
4607#else
4608      while (1)
4609      {
4610         char it = 0;
4611         if (read(STDIN_FILENO, &it, 1) == 1)
4612         {
4613            if (it == '\n')
4614            {
4615               buf[c] = 0;
4616               c = 0;
4617               break;
4618            }
4619            buf[c++] = it;
4620         }
4621      }
4622#endif
4623      if (buf[0] == 'g')
4624      {
4625         if (buf[1] == '0')
4626            sscanf (buf + 1, "%x", &m_single_stepping);
4627         else
4628            break;
4629         buf[1] = 0;
4630         fprintf (stderr, "go until pc = 0x%08x.\n",
4631                  m_single_stepping);
4632         m_single_stepping = 0;    /* HACK */
4633      }
4634      else if (buf[0] == 'r')
4635         dump_state (cpustate);
4636      else if (buf[0] == 'u')
4637      {
4638         if (buf[1] == '0')
4639            sscanf (buf + 1, "%x", &curr_disasm);
4640         disasm (curr_disasm, 10);
4641         curr_disasm += 10 * 4;
4642         buf[1] = 0;
4643      }
4644      else if (buf[0] == 'p')
4645      {
4646         if (buf[1] >= '0' && buf[1] <= '4')
4647            dump_pipe (buf[1] - 0x30);
4648         buf[1] = 0;
4649      }
4650      else if (buf[0] == 's')
4651         m_single_stepping = 1;
4652      else if (buf[0] == 'l')
4653         ; //m_pc = elf_load(buf + 1);
4654      else if (buf[0] == 'd' && buf[1] == 'b')
4655      {
4656         if (buf[2] == '0')
4657            sscanf (buf + 2, "%x", &curr_dumpdb);
4658         dbg_db (curr_dumpdb, 32);
4659         curr_dumpdb += 32;
4660      }
4661      else if (buf[0] == 'x' && buf[1] == '0')
4662      {
4663         UINT32 v;
4664         sscanf (buf + 1, "%x", &v);
4665         if (GET_DIRBASE_ATE ())
4666            fprintf (stderr, "vma 0x%08x ==> phys 0x%08x\n", v,
4667                     get_address_translation (v, 1, 0));
4668         else
4669            fprintf (stderr, "not in virtual address mode.\n");
4670      }
4671      else if (buf[0] == 'B')
4672      {
4673         ;//m_pc = elf_load("bins/bsd");
4674         break;
4675      }
4676      else if (buf[0] == '?')
4677      {
4678         fprintf (stderr, "  db: dump bytes (db[0xaddress])\n   r: dump registers\n   s: single-step\n   g: go back to emulator (g[0xaddress])\n   u: disassemble (u[0xaddress])\n   p: dump pipelines (p{0-4} for all, add, mul, load, graphics)\n   l: load an ELF binary (lpath)\n   x: give virt->phys translation (x{0xaddress})\n");
4679      }
4680      else
4681         fprintf (stderr, "Bad command '%s'.\n", buf);
4682   }
4683
4684   /* Less noise when single-stepping.  */
4685   if (m_single_stepping != 1)
4686      fprintf (stderr, "Debugger done, continuing emulation.\n");
4687}
4688
4689#endif
trunk/src/emu/cpu/i860/i860dec.inc
r0r28739
1/***************************************************************************
2
3    i860dec.inc
4
5    Execution engine for the Intel i860 emulator.
6
7    Copyright (C) 1995-present Jason Eckhardt (jle@rice.edu)
8    Released for general non-commercial use under the MAME license
9    with the additional requirement that you are free to use and
10    redistribute this code in modified or unmodified form, provided
11    you list me in the credits.
12    Visit http://mamedev.org for licensing and usage restrictions.
13
14***************************************************************************/
15
16/*
17 * References:
18 *  `i860 Microprocessor Programmer's Reference Manual', Intel, 1990.
19 *
20 * This code was originally written by Jason Eckhardt as part of an
21 * emulator for some i860-based Unix workstations (early 1990's) such
22 * as the Stardent Vistra 800 series and the OkiStation/i860 7300 series.
23 * The code you are reading now is the i860 CPU portion only, which has
24 * been adapted to (and simplified for) MAME.
25 * MAME-specific notes:
26 * - i860XR emulation only (i860XP unnecessary for MAME).
27 * - No emulation of data and instruction caches (unnecessary for MAME version).
28 * - No emulation of DIM mode or CS8 mode (unnecessary for MAME version).
29 * - No BL/IL/locked sequences (unnecessary for MAME).
30 * - Emulate only the i860's LSB-first mode (BE = 0).
31 * Generic notes:
32 * - There is some amount of code duplication (e.g., see the
33 *   various insn_* routines for the branches and FP routines) that
34 *   could be eliminated.
35 * - The host's floating point types are used to emulate the i860's
36 *   floating point.  Should probably be made machine independent by
37 *   using an IEEE FP emulation library.  On the other hand, most machines
38 *   today also use IEEE FP.
39 *
40 */
41#include "i860.h"
42#include <math.h>
43
44
45#undef HOST_MSB
46
47#undef  TRACE_RDWR_MEM
48#undef  TRACE_ADDR_TRANSLATION
49#undef  TRACE_PAGE_FAULT
50#define TRACE_UNDEFINED_I860
51#undef  TRACE_EXT_INT
52#define TRACE_UNALIGNED_MEM
53
54
55/* Defines for pending_trap.  */
56enum {
57   TRAP_NORMAL        = 0x01,
58   TRAP_IN_DELAY_SLOT = 0x02,
59   TRAP_WAS_EXTERNAL  = 0x04
60};
61
62
63/*  TODO: THESE WILL BE REPLACED BY MAME FUNCTIONS
64#define BYTE_REV32(t)   \
65  do { \
66    (t) = ((UINT32)(t) >> 16) | ((UINT32)(t) << 16); \
67    (t) = (((UINT32)(t) >> 8) & 0x00ff00ff) | (((UINT32)(t) << 8) & 0xff00ff00); \
68  } while (0);
69
70#define BYTE_REV16(t)   \
71  do { \
72    (t) = (((UINT16)(t) >> 8) & 0x00ff) | (((UINT16)(t) << 8) & 0xff00); \
73  } while (0);
74#endif
75*/
76
77
78/* Get/set general register value -- watch for r0 on writes.  */
79#define get_iregval(gr)       (m_iregs[(gr)])
80#define set_iregval(gr, val)  (m_iregs[(gr)] = ((gr) == 0 ? 0 : (val)))
81
82float i860_cpu_device::get_fregval_s (int fr)
83{
84   float f;
85   UINT32 x;
86   UINT8 *tp;
87   fr = 31 - fr;
88   tp = (UINT8 *)(&m_frg[fr * 4]);
89   x = ((UINT32)tp[0] << 24) | ((UINT32)tp[1] << 16) |
90      ((UINT32)tp[2] << 8) | ((UINT32)tp[3]);
91   f = *(float *)(&x);
92   return f;
93}
94
95double i860_cpu_device::get_fregval_d (int fr)
96{
97   double d;
98   UINT64 x;
99   UINT8 *tp;
100   fr = 31 - (fr + 1);
101   tp = (UINT8 *)(&m_frg[fr * 4]);
102   x = ((UINT64)tp[0] << 56) | ((UINT64)tp[1] << 48) |
103      ((UINT64)tp[2] << 40) | ((UINT64)tp[3] << 32) |
104      ((UINT64)tp[4] << 24) | ((UINT64)tp[5] << 16) |
105      ((UINT64)tp[6] << 8) | ((UINT64)tp[7]);
106   d = *(double *)(&x);
107   return d;
108}
109
110void i860_cpu_device::set_fregval_s (int fr, float s)
111{
112   UINT8 *f = (UINT8 *)&s;
113   UINT8 *tp;
114   int newfr = 31 - fr;
115   float jj = s;
116   tp = (UINT8 *)(&m_frg[newfr * 4]);
117
118   f = (UINT8 *)(&jj);
119   if (fr == 0 || fr == 1)
120   {
121      tp[0] = 0; tp[1] = 0; tp[2] = 0; tp[3] = 0;
122   }
123   else
124   {
125#ifndef HOST_MSB
126      tp[0] = f[3]; tp[1] = f[2]; tp[2] = f[1]; tp[3] = f[0];
127#else
128      tp[0] = f[0]; tp[1] = f[1]; tp[2] = f[2]; tp[3] = f[3];
129#endif
130   }
131}
132
133void i860_cpu_device::set_fregval_d (int fr, double d)
134{
135   UINT8 *f = (UINT8 *)&d;
136   UINT8 *tp;
137   int newfr = 31 - (fr + 1);
138   double jj = d;
139   tp = (UINT8 *)(&m_frg[newfr * 4]);
140
141   f = (UINT8 *)(&jj);
142
143   if (fr == 0)
144   {
145      tp[0] = 0; tp[1] = 0; tp[2] = 0; tp[3] = 0;
146      tp[4] = 0; tp[5] = 0; tp[6] = 0; tp[7] = 0;
147   }
148   else
149   {
150#ifndef HOST_MSB
151      tp[0] = f[7]; tp[1] = f[6]; tp[2] = f[5]; tp[3] = f[4];
152      tp[4] = f[3]; tp[5] = f[2]; tp[6] = f[1]; tp[7] = f[0];
153#else
154      tp[0] = f[0]; tp[1] = f[1]; tp[2] = f[2]; tp[3] = f[3];
155      tp[4] = f[4]; tp[5] = f[5]; tp[6] = f[6]; tp[7] = f[7];
156#endif
157   }
158}
159
160
161/* Macros for accessing register fields in instruction word.  */
162#define get_isrc1(bits) (((bits) >> 11) & 0x1f)
163#define get_isrc2(bits) (((bits) >> 21) & 0x1f)
164#define get_idest(bits) (((bits) >> 16) & 0x1f)
165#define get_fsrc1(bits) (((bits) >> 11) & 0x1f)
166#define get_fsrc2(bits) (((bits) >> 21) & 0x1f)
167#define get_fdest(bits) (((bits) >> 16) & 0x1f)
168#define get_creg(bits) (((bits) >> 21) & 0x7)
169
170/* Macros for accessing immediate fields.  */
171/* 16-bit immediate.  */
172#define get_imm16(insn) ((insn) & 0xffff)
173
174/* A mask for all the trap bits of the PSR (FT, DAT, IAT, IN, IT, or
175   bits [12..8]).  */
176#define PSR_ALL_TRAP_BITS_MASK 0x00001f00
177
178/* A mask for PSR bits which can only be changed from supervisor level.  */
179#define PSR_SUPERVISOR_ONLY_MASK 0x0000fff3
180
181
182/* PSR: BR flag (PSR[0]):  set/get.  */
183#define GET_PSR_BR()  ((m_cregs[CR_PSR] >> 0) & 1)
184#define SET_PSR_BR(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 0)) | (((val) & 1) << 0))
185
186/* PSR: BW flag (PSR[1]):  set/get.  */
187#define GET_PSR_BW()  ((m_cregs[CR_PSR] >> 1) & 1)
188#define SET_PSR_BW(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 1)) | (((val) & 1) << 1))
189
190/* PSR: Shift count (PSR[21..17]):  set/get.  */
191#define GET_PSR_SC()  ((m_cregs[CR_PSR] >> 17) & 0x1f)
192#define SET_PSR_SC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x003e0000) | (((val) & 0x1f) << 17))
193
194/* PSR: CC flag (PSR[2]):  set/get.  */
195#define GET_PSR_CC()  ((m_cregs[CR_PSR] >> 2) & 1)
196#define SET_PSR_CC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 2)) | (((val) & 1) << 2))
197
198/* PSR: IT flag (PSR[8]):  set/get.  */
199#define GET_PSR_IT()  ((m_cregs[CR_PSR] >> 8) & 1)
200#define SET_PSR_IT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 8)) | (((val) & 1) << 8))
201
202/* PSR: IN flag (PSR[9]):  set/get.  */
203#define GET_PSR_IN()  ((m_cregs[CR_PSR] >> 9) & 1)
204#define SET_PSR_IN(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 9)) | (((val) & 1) << 9))
205
206/* PSR: IAT flag (PSR[10]):  set/get.  */
207#define GET_PSR_IAT()  ((m_cregs[CR_PSR] >> 10) & 1)
208#define SET_PSR_IAT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 10)) | (((val) & 1) << 10))
209
210/* PSR: DAT flag (PSR[11]):  set/get.  */
211#define GET_PSR_DAT()  ((m_cregs[CR_PSR] >> 11) & 1)
212#define SET_PSR_DAT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 11)) | (((val) & 1) << 11))
213
214/* PSR: FT flag (PSR[12]):  set/get.  */
215#define GET_PSR_FT()  ((m_cregs[CR_PSR] >> 12) & 1)
216#define SET_PSR_FT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 12)) | (((val) & 1) << 12))
217
218/* PSR: DS flag (PSR[13]):  set/get.  */
219#define GET_PSR_DS()  ((m_cregs[CR_PSR] >> 13) & 1)
220#define SET_PSR_DS(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 13)) | (((val) & 1) << 13))
221
222/* PSR: DIM flag (PSR[14]):  set/get.  */
223#define GET_PSR_DIM()  ((m_cregs[CR_PSR] >> 14) & 1)
224#define SET_PSR_DIM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 14)) | (((val) & 1) << 14))
225
226/* PSR: LCC (PSR[3]):  set/get.  */
227#define GET_PSR_LCC()  ((m_cregs[CR_PSR] >> 3) & 1)
228#define SET_PSR_LCC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 3)) | (((val) & 1) << 3))
229
230/* PSR: IM (PSR[4]):  set/get.  */
231#define GET_PSR_IM()  ((m_cregs[CR_PSR] >> 4) & 1)
232#define SET_PSR_IM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 4)) | (((val) & 1) << 4))
233
234/* PSR: PIM (PSR[5]):  set/get.  */
235#define GET_PSR_PIM()  ((m_cregs[CR_PSR] >> 5) & 1)
236#define SET_PSR_PIM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 5)) | (((val) & 1) << 5))
237
238/* PSR: U (PSR[6]):  set/get.  */
239#define GET_PSR_U()  ((m_cregs[CR_PSR] >> 6) & 1)
240#define SET_PSR_U(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 6)) | (((val) & 1) << 6))
241
242/* PSR: PU (PSR[7]):  set/get.  */
243#define GET_PSR_PU()  ((m_cregs[CR_PSR] >> 7) & 1)
244#define SET_PSR_PU(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 7)) | (((val) & 1) << 7))
245
246/* PSR: Pixel size (PSR[23..22]):  set/get.  */
247#define GET_PSR_PS()  ((m_cregs[CR_PSR] >> 22) & 0x3)
248#define SET_PSR_PS(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x00c00000) | (((val) & 0x3) << 22))
249
250/* PSR: Pixel mask (PSR[31..24]):  set/get.  */
251#define GET_PSR_PM()  ((m_cregs[CR_PSR] >> 24) & 0xff)
252#define SET_PSR_PM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0xff000000) | (((val) & 0xff) << 24))
253
254/* EPSR: WP bit (EPSR[14]):  set/get.  */
255#define GET_EPSR_WP()  ((m_cregs[CR_EPSR] >> 14) & 1)
256#define SET_EPSR_WP(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 14)) | (((val) & 1) << 14))
257
258/* EPSR: INT bit (EPSR[17]):  set/get.  */
259#define GET_EPSR_INT()  ((m_cregs[CR_EPSR] >> 17) & 1)
260#define SET_EPSR_INT(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 17)) | (((val) & 1) << 17))
261
262
263/* EPSR: OF flag (EPSR[24]):  set/get.  */
264#define GET_EPSR_OF()  ((m_cregs[CR_EPSR] >> 24) & 1)
265#define SET_EPSR_OF(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 24)) | (((val) & 1) << 24))
266
267/* EPSR: BE flag (EPSR[23]):  set/get.  */
268#define GET_EPSR_BE()  ((m_cregs[CR_EPSR] >> 23) & 1)
269#define SET_EPSR_BE(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 23)) | (((val) & 1) << 23))
270
271/* DIRBASE: ATE bit (DIRBASE[0]):  get.  */
272#define GET_DIRBASE_ATE()  (m_cregs[CR_DIRBASE] & 1)
273
274/* DIRBASE: CS8 bit (DIRBASE[7]):  get.  */
275#define GET_DIRBASE_CS8()  ((m_cregs[CR_DIRBASE] >> 7) & 1)
276
277/* FSR: FTE bit (FSR[5]):  set/get.  */
278#define GET_FSR_FTE()  ((m_cregs[CR_FSR] >> 5) & 1)
279#define SET_FSR_FTE(val)  (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 5)) | (((val) & 1) << 5))
280
281/* FSR: SE bit (FSR[8]):  set/get.  */
282#define GET_FSR_SE()  ((m_cregs[CR_FSR] >> 8) & 1)
283#define SET_FSR_SE(val)  (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 8)) | (((val) & 1) << 8))
284
285
286int i860_cpu_device::has_delay_slot(UINT32 insn)
287{
288   int opc = (insn >> 26) & 0x3f;
289   if (opc == 0x10 || opc == 0x1a || opc == 0x1b || opc == 0x1d ||
290      opc == 0x1f || opc == 0x2d || (opc == 0x13 && (insn & 3) == 2))
291   return 1;
292   return 0;
293}
294
295/* This is the external interface for asserting/deasserting pins on
296   the i860.  */
297void i860_cpu_device::i860_set_pin (int pin, int val)
298{
299   if (pin == DEC_PIN_BUS_HOLD)
300      m_pin_bus_hold = val;
301   else if (pin == DEC_PIN_RESET)
302      m_pin_reset = val;
303   else
304      assert (0);
305}
306
307
308/* This is the external interface for indicating an external interrupt
309   to the i860.  */
310void i860_cpu_device::i860_gen_interrupt()
311{
312   /* If interrupts are enabled, then set PSR.IN and prepare for trap.
313      Otherwise, the external interrupt is ignored.  We also set
314      bit EPSR.INT (which tracks the INT pin).  */
315   if (GET_PSR_IM ())
316   {
317      SET_PSR_IN (1);
318      SET_EPSR_INT (1);
319      m_pending_trap = TRAP_WAS_EXTERNAL;
320   }
321
322#ifdef TRACE_EXT_INT
323   fprintf (stderr, "i860_gen_interrupt: External interrupt received ");
324   if (GET_PSR_IM ())
325      fprintf (stderr, "[PSR.IN set, preparing to trap]\n");
326   else
327      fprintf (stderr, "[ignored (interrupts disabled)]\n");
328#endif
329}
330
331
332/* Fetch instructions from instruction cache.
333   Note: The instruction cache is not implemented for MAME version,
334   this just fetches and returns 1 instruction from memory.  */
335UINT32 i860_cpu_device::ifetch (UINT32 pc)
336{
337   UINT32 phys_pc = 0;
338   UINT32 w1 = 0;
339
340   /* If virtual mode, get translation.  */
341   if (GET_DIRBASE_ATE ())
342   {
343      phys_pc = get_address_translation (pc, 0  /* is_dataref */, 0 /* is_write */);
344      m_exiting_ifetch = 0;
345      if (m_pending_trap && (GET_PSR_DAT () || GET_PSR_IAT ()))
346      {
347         m_exiting_ifetch = 1;
348         return 0xffeeffee;
349      }
350   }
351   else
352      phys_pc = pc;
353
354   /* Since i860 instructions are always stored LSB first (regardless of
355      the BE bit), we need to adjust the instruction below on MSB hosts.  */
356   w1 = m_program->read_dword(phys_pc);
357#ifdef HOST_MSB
358   BYTE_REV32 (w1);
359#endif /* HOST_MSB.  */
360   return w1;
361}
362
363
364/* Given a virtual address, perform the i860 address translation and
365   return the corresponding physical address.
366     vaddr:      virtual address
367     is_dataref: 1 = load/store, 0 = instruction fetch.
368     is_write:   1 = writing to vaddr, 0 = reading from vaddr
369   The last two arguments are only used to determine what types
370   of traps should be taken.
371
372   Page tables must always be in memory (not cached).  So the routine
373   here only accesses memory.  */
374UINT32 i860_cpu_device::get_address_translation (UINT32 vaddr, int is_dataref, int is_write)
375{
376   UINT32 vdir = (vaddr >> 22) & 0x3ff;
377   UINT32 vpage = (vaddr >> 12) & 0x3ff;
378   UINT32 voffset = vaddr & 0xfff;
379   UINT32 dtb = (m_cregs[CR_DIRBASE]) & 0xfffff000;
380   UINT32 pg_dir_entry_a = 0;
381   UINT32 pg_dir_entry = 0;
382   UINT32 pg_tbl_entry_a = 0;
383   UINT32 pg_tbl_entry = 0;
384   UINT32 pfa1 = 0;
385   UINT32 pfa2 = 0;
386   UINT32 ret = 0;
387   UINT32 ttpde = 0;
388   UINT32 ttpte = 0;
389
390   assert (GET_DIRBASE_ATE ());
391
392   /* Get page directory entry at DTB:DIR:00.  */
393   pg_dir_entry_a = dtb | (vdir << 2);
394   pg_dir_entry = m_program->read_dword(pg_dir_entry_a);
395#ifdef HOST_MSB
396   BYTE_REV32 (pg_dir_entry);
397#endif
398
399   /* Check for non-present PDE.  */
400   if (!(pg_dir_entry & 1))
401   {
402      /* PDE is not present, generate DAT or IAT.  */
403      if (is_dataref)
404         SET_PSR_DAT (1);
405      else
406         SET_PSR_IAT (1);
407      m_pending_trap = 1;
408
409      /* Dummy return.  */
410      return 0;
411   }
412
413   /* PDE Check for write protection violations.  */
414   if (is_write && is_dataref
415      && !(pg_dir_entry & 2)                  /* W = 0.  */
416      && (GET_PSR_U () || GET_EPSR_WP ()))   /* PSR_U = 1 or EPSR_WP = 1.  */
417   {
418      SET_PSR_DAT (1);
419      m_pending_trap = 1;
420      /* Dummy return.  */
421      return 0;
422   }
423
424   /* PDE Check for user-mode access to supervisor pages.  */
425   if (GET_PSR_U ()
426      && !(pg_dir_entry & 4))                 /* U = 0.  */
427   {
428      if (is_dataref)
429         SET_PSR_DAT (1);
430      else
431         SET_PSR_IAT (1);
432      m_pending_trap = 1;
433      /* Dummy return.  */
434      return 0;
435   }
436
437   /* FIXME: How exactly to handle A check/update?.  */
438
439   /* Get page table entry at PFA1:PAGE:00.  */
440   pfa1 = pg_dir_entry & 0xfffff000;
441   pg_tbl_entry_a = pfa1 | (vpage << 2);
442   pg_tbl_entry = m_program->read_dword(pg_tbl_entry_a);
443#ifdef HOST_MSB
444   BYTE_REV32 (pg_tbl_entry);
445#endif
446
447   /* Check for non-present PTE.  */
448   if (!(pg_tbl_entry & 1))
449   {
450      /* PTE is not present, generate DAT or IAT.  */
451      if (is_dataref)
452         SET_PSR_DAT (1);
453      else
454         SET_PSR_IAT (1);
455      m_pending_trap = 1;
456
457      /* Dummy return.  */
458      return 0;
459   }
460
461   /* PTE Check for write protection violations.  */
462   if (is_write && is_dataref
463      && !(pg_tbl_entry & 2)                  /* W = 0.  */
464      && (GET_PSR_U () || GET_EPSR_WP ()))   /* PSR_U = 1 or EPSR_WP = 1.  */
465   {
466      SET_PSR_DAT (1);
467      m_pending_trap = 1;
468      /* Dummy return.  */
469      return 0;
470   }
471
472   /* PTE Check for user-mode access to supervisor pages.  */
473   if (GET_PSR_U ()
474      && !(pg_tbl_entry & 4))                 /* U = 0.  */
475   {
476      if (is_dataref)
477         SET_PSR_DAT (1);
478      else
479         SET_PSR_IAT (1);
480      m_pending_trap = 1;
481      /* Dummy return.  */
482      return 0;
483   }
484
485   /* Update A bit and check D bit.  */
486   ttpde = pg_dir_entry | 0x20;
487   ttpte = pg_tbl_entry | 0x20;
488#ifdef HOST_MSB
489   BYTE_REV32 (ttpde);
490   BYTE_REV32 (ttpte);
491#endif
492   m_program->write_dword(pg_dir_entry_a, ttpde);
493   m_program->write_dword(pg_tbl_entry_a, ttpte);
494
495   if (is_write && is_dataref && (pg_tbl_entry & 0x40) == 0)
496   {
497      /* fprintf(stderr, "DAT trap on write without dirty bit v0x%08x/p0x%08x\n",
498         vaddr, (pg_tbl_entry & ~0xfff)|voffset); */
499      SET_PSR_DAT (1);
500      m_pending_trap = 1;
501      /* Dummy return.  */
502      return 0;
503   }
504
505   pfa2 = (pg_tbl_entry & 0xfffff000);
506   ret = pfa2 | voffset;
507
508#ifdef TRACE_ADDR_TRANSLATION
509   fprintf (stderr, "get_address_translation: virt(0x%08x) -> phys(0x%08x)\n",
510            vaddr, ret);
511#endif
512
513   return ret;
514}
515
516
517/* Read memory emulation.
518     addr = address to read.
519     size = size of read in bytes.  */
520UINT32 i860_cpu_device::readmemi_emu (UINT32 addr, int size)
521{
522#ifdef TRACE_RDWR_MEM
523   fprintf (stderr, "readmemi_emu: (ATE=%d) addr = 0x%08x, size = %d\n",
524            GET_DIRBASE_ATE (), addr, size);
525#endif
526
527   /* If virtual mode, do translation.  */
528   if (GET_DIRBASE_ATE ())
529   {
530      UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 0 /* is_write */);
531      if (m_pending_trap && (GET_PSR_IAT () || GET_PSR_DAT ()))
532      {
533#ifdef TRACE_PAGE_FAULT
534         fprintf (stderr, "0x%08x: ## Page fault (readmemi_emu).\n",
535                  m_pc);
536#endif
537         m_exiting_readmem = 1;
538         return 0;
539      }
540      addr = phys;
541   }
542
543   /* First check for match to db register (before read).  */
544   if (((addr & ~(size - 1)) == m_cregs[CR_DB]) && GET_PSR_BR ())
545   {
546      SET_PSR_DAT (1);
547      m_pending_trap = 1;
548      return 0;
549   }
550
551   /* Now do the actual read.  */
552   if (size == 1)
553   {
554      UINT32 ret = m_program->read_byte(addr);
555      return ret & 0xff;
556   }
557   else if (size == 2)
558   {
559      UINT32 ret = m_program->read_word(addr);
560#ifdef HOST_MSB
561      BYTE_REV16 (ret);
562#endif
563      return ret & 0xffff;
564   }
565   else if (size == 4)
566   {
567      UINT32 ret = m_program->read_dword(addr);
568#ifdef HOST_MSB
569      BYTE_REV32 (ret);
570#endif
571      return ret;
572   }
573   else
574      assert (0);
575
576   return 0;
577}
578
579
580/* Write memory emulation.
581     addr = address to write.
582     size = size of write in bytes.
583     data = data to write.  */
584void i860_cpu_device::writememi_emu (UINT32 addr, int size, UINT32 data)
585{
586#ifdef TRACE_RDWR_MEM
587   fprintf (stderr, "writememi_emu: (ATE=%d) addr = 0x%08x, size = %d, data = 0x%08x\n",
588            GET_DIRBASE_ATE (), addr, size, data);
589#endif
590
591   /* If virtual mode, do translation.  */
592   if (GET_DIRBASE_ATE ())
593   {
594      UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 1 /* is_write */);
595      if (m_pending_trap && (GET_PSR_IAT () || GET_PSR_DAT ()))
596      {
597#ifdef TRACE_PAGE_FAULT
598         fprintf (stderr, "0x%08x: ## Page fault (writememi_emu).\n",
599                  m_pc);
600#endif
601         m_exiting_readmem = 2;
602         return;
603      }
604      addr = phys;
605   }
606
607   /* First check for match to db register (before write).  */
608   if (((addr & ~(size - 1)) == m_cregs[CR_DB]) && GET_PSR_BW ())
609   {
610      SET_PSR_DAT (1);
611      m_pending_trap = 1;
612      return;
613   }
614
615   /* Now do the actual write.  */
616   if (size == 1)
617      m_program->write_byte(addr, data);
618   else if (size == 2)
619   {
620#ifdef HOST_MSB
621      BYTE_REV16 (data);
622#endif
623      m_program->write_word(addr, data);
624   }
625   else if (size == 4)
626   {
627#ifdef HOST_MSB
628      BYTE_REV32 (data);
629#endif
630      m_program->write_dword(addr, data);
631   }
632   else
633      assert (0);
634}
635
636
637/* Floating-point read mem routine.
638     addr = address to read.
639     size = size of read in bytes.
640     dest = memory to put read data.  */
641void i860_cpu_device::fp_readmem_emu (UINT32 addr, int size, UINT8 *dest)
642{
643#ifdef TRACE_RDWR_MEM
644   fprintf (stderr, "fp_readmem_emu: (ATE=%d) addr = 0x%08x, size = %d\n",
645            GET_DIRBASE_ATE (), addr, size);
646#endif
647
648   assert (size == 4 || size == 8 || size == 16);
649
650   /* If virtual mode, do translation.  */
651   if (GET_DIRBASE_ATE ())
652   {
653      UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 0 /* is_write */);
654      if (m_pending_trap && (GET_PSR_IAT () || GET_PSR_DAT ()))
655      {
656#ifdef TRACE_PAGE_FAULT
657         fprintf (stderr, "0x%08x: ## Page fault (fp_readmem_emu).\n",
658                  m_pc);
659#endif
660         m_exiting_readmem = 3;
661         return;
662      }
663      addr = phys;
664   }
665
666   /* First check for match to db register (before read).  */
667   if (((addr & ~(size - 1)) == m_cregs[CR_DB]) && GET_PSR_BR ())
668   {
669      SET_PSR_DAT (1);
670      m_pending_trap = 1;
671      return;
672   }
673
674   if (size == 4)
675   {
676      dest[0] = m_program->read_byte(addr+3);
677      dest[1] = m_program->read_byte(addr+2);
678      dest[2] = m_program->read_byte(addr+1);
679      dest[3] = m_program->read_byte(addr+0);
680   }
681   else if (size == 8)
682   {
683      dest[0] = m_program->read_byte(addr+7);
684      dest[1] = m_program->read_byte(addr+6);
685      dest[2] = m_program->read_byte(addr+5);
686      dest[3] = m_program->read_byte(addr+4);
687      dest[4] = m_program->read_byte(addr+3);
688      dest[5] = m_program->read_byte(addr+2);
689      dest[6] = m_program->read_byte(addr+1);
690      dest[7] = m_program->read_byte(addr+0);
691   }
692   else if (size == 16)
693   {
694      int i;
695      for (i = 0; i < 16; i++)
696      {
697         dest[i] = m_program->read_byte(addr+15-i);
698      }
699   }
700}
701
702
703/* Floating-point write mem routine.
704     addr = address to read.
705     size = size of read in bytes.
706     data = pointer to the data.
707     wmask = bit mask of bytes to write (only for pst.d).  */
708void i860_cpu_device::fp_writemem_emu (UINT32 addr, int size, UINT8 *data, UINT32 wmask)
709{
710#ifdef TRACE_RDWR_MEM
711   fprintf (stderr, "fp_writemem_emu: (ATE=%d) addr = 0x%08x, size = %d\n",
712            GET_DIRBASE_ATE (), addr, size);
713#endif
714
715   assert (size == 4 || size == 8 || size == 16);
716
717   /* If virtual mode, do translation.  */
718   if (GET_DIRBASE_ATE ())
719   {
720      UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 1 /* is_write */);
721      if (m_pending_trap && GET_PSR_DAT ())
722      {
723#ifdef TRACE_PAGE_FAULT
724         fprintf (stderr, "0x%08x: ## Page fault (fp_writememi_emu).\n",
725                  m_pc);
726#endif
727         m_exiting_readmem = 4;
728         return;
729      }
730      addr = phys;
731   }
732
733   /* First check for match to db register (before read).  */
734   if (((addr & ~(size - 1)) == m_cregs[CR_DB]) && GET_PSR_BW ())
735   {
736      SET_PSR_DAT (1);
737      m_pending_trap = 1;
738      return;
739   }
740
741   if (size == 4)
742   {
743#if 1
744      m_program->write_byte(addr+3, data[0]);
745      m_program->write_byte(addr+2, data[1]);
746      m_program->write_byte(addr+1, data[2]);
747      m_program->write_byte(addr+0, data[3]);
748#else
749      UINT32 ddd = (data[3]) | (data[2] << 8) | (data[1] << 16) |(data[0] << 24);
750      m_program->write_dword(addr+0, ddd);
751#endif
752   }
753   else if (size == 8)
754   {
755      /* Special: watch for wmask != 0xff, which means we're doing pst.d.  */
756      if (wmask == 0xff)
757      {
758         m_program->write_byte(addr+7, data[0]);
759         m_program->write_byte(addr+6, data[1]);
760         m_program->write_byte(addr+5, data[2]);
761         m_program->write_byte(addr+4, data[3]);
762         m_program->write_byte(addr+3, data[4]);
763         m_program->write_byte(addr+2, data[5]);
764         m_program->write_byte(addr+1, data[6]);
765         m_program->write_byte(addr+0, data[7]);
766      }
767      else
768      {
769         if (wmask & 0x80) m_program->write_byte(addr+7, data[0]);
770         if (wmask & 0x40) m_program->write_byte(addr+6, data[1]);
771         if (wmask & 0x20) m_program->write_byte(addr+5, data[2]);
772         if (wmask & 0x10) m_program->write_byte(addr+4, data[3]);
773         if (wmask & 0x08) m_program->write_byte(addr+3, data[4]);
774         if (wmask & 0x04) m_program->write_byte(addr+2, data[5]);
775         if (wmask & 0x02) m_program->write_byte(addr+1, data[6]);
776         if (wmask & 0x01) m_program->write_byte(addr+0, data[7]);
777      }
778   }
779   else if (size == 16)
780   {
781      int i;
782      for (i = 0; i < 16; i++)
783      {
784         m_program->write_byte(addr+15-i, data[i]);
785      }
786   }
787
788}
789
790
791#if 0
792/* Do a pipeline dump.
793    type: 0 (all), 1 (add), 2 (mul), 3 (load), 4 (graphics).  */
794void i860_cpu_device::dump_pipe (int type)
795{
796   int i = 0;
797
798   fprintf (stderr, "pipeline state:\n");
799   /* Dump the adder pipeline, if requested.  */
800   if (type == 0 || type == 1)
801   {
802      fprintf (stderr, "  A: ");
803      for (i = 0; i < 3; i++)
804      {
805         if (m_A[i].stat.arp)
806            fprintf (stderr, "[%dd] 0x%016llx ", i + 1,
807                     *(UINT64 *)(&m_A[i].val.d));
808         else
809            fprintf (stderr, "[%ds] 0x%08x ", i + 1,
810                     *(UINT32 *)(&m_A[i].val.s));
811      }
812      fprintf (stderr, "\n");
813   }
814
815
816   /* Dump the multiplier pipeline, if requested.  */
817   if (type == 0 || type == 2)
818   {
819      fprintf (stderr, "  M: ");
820      for (i = 0; i < 3; i++)
821      {
822         if (m_M[i].stat.mrp)
823            fprintf (stderr, "[%dd] 0x%016llx ", i + 1,
824                     *(UINT64 *)(&m_M[i].val.d));
825         else
826            fprintf (stderr, "[%ds] 0x%08x ", i + 1,
827                     *(UINT32 *)(&m_M[i].val.s));
828      }
829      fprintf (stderr, "\n");
830   }
831
832   /* Dump the load pipeline, if requested.  */
833   if (type == 0 || type == 3)
834   {
835      fprintf (stderr, "  L: ");
836      for (i = 0; i < 3; i++)
837      {
838         if (m_L[i].stat.lrp)
839            fprintf (stderr, "[%dd] 0x%016llx ", i + 1,
840                     *(UINT64 *)(&m_L[i].val.d));
841         else
842            fprintf (stderr, "[%ds] 0x%08x ", i + 1,
843                     *(UINT32 *)(&m_L[i].val.s));
844      }
845      fprintf (stderr, "\n");
846   }
847
848   /* Dump the graphics pipeline, if requested.  */
849   if (type == 0 || type == 4)
850   {
851      fprintf (stderr, "  I: ");
852      if (m_G.stat.irp)
853         fprintf (stderr, "[1d] 0x%016llx\n",
854                  *(UINT64 *)(&m_G.val.d));
855      else
856         fprintf (stderr, "[1s] 0x%08x\n",
857                  *(UINT32 *)(&m_G.val.s));
858   }
859}
860
861
862/* Do a register/state dump.  */
863void i860_cpu_device::dump_state (i860s *cpustate)
864{
865   int rn;
866
867   /* GR's first, 4 per line.  */
868   for (rn = 0; rn < 32; rn++)
869   {
870      if ((rn % 4) == 0)
871         fprintf (stderr, "\n");
872      fprintf (stderr, "%%r%-3d: 0x%08x  ", rn, get_iregval (rn));
873   }
874   fprintf (stderr, "\n");
875
876   /* FR's (as 32-bits), 4 per line.  */
877   for (rn = 0; rn < 32; rn++)
878   {
879      float ff = get_fregval_s (rn);
880      if ((rn % 4) == 0)
881         fprintf (stderr, "\n");
882      fprintf (stderr, "%%f%-3d: 0x%08x  ", rn, *(UINT32 *)&ff);
883   }
884   fprintf (stderr, "\n");
885
886   fprintf (stderr, " psr: CC = %d, LCC = %d, SC = %d, IM = %d, U = %d\n",
887            GET_PSR_CC (), GET_PSR_LCC (), GET_PSR_SC (), GET_PSR_IM (),
888            GET_PSR_U ());
889   fprintf (stderr, "      IT/FT/IAT/DAT/IN = %d/%d/%d/%d/%d\n",
890            GET_PSR_IT (), GET_PSR_FT (), GET_PSR_IAT (),
891            GET_PSR_DAT (), GET_PSR_IN ());
892   fprintf (stderr, "epsr: INT = %d, OF = %d, BE = %d\n",
893            GET_EPSR_INT (), GET_EPSR_OF (), GET_EPSR_BE ());
894   fprintf (stderr, " fir: 0x%08x  dirbase: 0x%08x  fsr: 0x%08x\n",
895            m_cregs[CR_FIR], m_cregs[CR_DIRBASE],
896            m_cregs[CR_FSR]);
897   fprintf (stderr, "  pc: 0x%08x\n", m_pc);
898}
899#endif
900
901/* Sign extend N-bit number.  */
902INLINE INT32 sign_ext (UINT32 x, int n)
903{
904   INT32 t;
905   t = x >> (n - 1);
906   t = ((-t) << n) | x;
907   return t;
908}
909
910
911void i860_cpu_device::unrecog_opcode (UINT32 pc, UINT32 insn)
912{
913   fprintf (stderr, "0x%08x: 0x%08x   (unrecognized opcode)\n", pc, insn);
914}
915
916
917/* Execute "ld.c csrc2,idest" instruction.  */
918void i860_cpu_device::insn_ld_ctrl (UINT32 insn)
919{
920   UINT32 csrc2 = get_creg (insn);
921   UINT32 idest = get_idest (insn);
922
923#ifdef TRACE_UNDEFINED_I860
924   if (csrc2 > 5)
925   {
926      /* Control register not between 0..5.  Undefined i860XR behavior.  */
927      fprintf (stderr, "WARNING: insn_ld_from_ctrl (pc=0x%08x): bad creg in ld.c (ignored)\n", m_pc);
928      return;
929   }
930#endif
931
932   /* If this is a load of the fir, then there are two cases:
933      1. First load of fir after a trap = usual value.
934      2. Not first load of fir after a trap = address of the ld.c insn.  */
935   if (csrc2 == CR_FIR)
936   {
937      if (m_fir_gets_trap_addr)
938         set_iregval (idest, m_cregs[csrc2]);
939      else
940      {
941         m_cregs[csrc2] = m_pc;
942         set_iregval (idest, m_cregs[csrc2]);
943      }
944      m_fir_gets_trap_addr = 0;
945   }
946   else
947      set_iregval (idest, m_cregs[csrc2]);
948}
949
950
951/* Execute "st.c isrc1,csrc2" instruction.  */
952void i860_cpu_device::insn_st_ctrl (UINT32 insn)
953{
954   UINT32 csrc2 = get_creg (insn);
955   UINT32 isrc1 = get_isrc1 (insn);
956
957#ifdef TRACE_UNDEFINED_I860
958   if (csrc2 > 5)
959   {
960      /* Control register not between 0..5.  Undefined i860XR behavior.  */
961      fprintf (stderr, "WARNING: insn_st_to_ctrl (pc=0x%08x): bad creg in st.c (ignored)\n", m_pc);
962      return;
963   }
964#endif
965
966   /* Look for ITI bit turned on (but it never actually is written --
967      it always appears to be 0).  */
968   if (csrc2 == CR_DIRBASE && (get_iregval (isrc1) & 0x20))
969   {
970      /* NOTE: The actual icache and TLB flush are unimplemented for
971         the MAME version.  */
972
973      /* Make sure ITI isn't actually written.  */
974      set_iregval (isrc1, (get_iregval (isrc1) & ~0x20));
975   }
976
977   if (csrc2 == CR_DIRBASE && (get_iregval (isrc1) & 1)
978      && GET_DIRBASE_ATE () == 0)
979   {
980      fprintf (stderr, "0x%08x: ** ATE going high!\n", m_pc);
981   }
982
983   /* Update the register -- unless it is fir which cannot be updated.  */
984   if (csrc2 == CR_EPSR)
985   {
986      UINT32 enew = 0, tmp = 0;
987      /* Make sure unchangeable EPSR bits stay unchanged (DCS, stepping,
988         and type).  Also, some bits are only writeable in supervisor
989         mode.  */
990      if (GET_PSR_U ())
991      {
992         enew = get_iregval (isrc1) & ~(0x003e1fff | 0x00c06000);
993         tmp = m_cregs[CR_EPSR] & (0x003e1fff | 0x00c06000);
994      }
995      else
996      {
997         enew = get_iregval (isrc1) & ~0x003e1fff;
998         tmp = m_cregs[CR_EPSR] & 0x003e1fff;
999      }
1000      m_cregs[CR_EPSR] = enew | tmp;
1001   }
1002   else if (csrc2 == CR_PSR)
1003   {
1004      /* Some PSR bits are only writeable in supervisor mode.  */
1005      if (GET_PSR_U ())
1006      {
1007         UINT32 enew = get_iregval (isrc1) & ~PSR_SUPERVISOR_ONLY_MASK;
1008         UINT32 tmp = m_cregs[CR_PSR] & PSR_SUPERVISOR_ONLY_MASK;
1009         m_cregs[CR_PSR] = enew | tmp;
1010      }
1011      else
1012         m_cregs[CR_PSR] = get_iregval (isrc1);
1013   }
1014   else if (csrc2 == CR_FSR)
1015   {
1016      /* I believe that only 21..17, 8..5, and 3..0 should be updated.  */
1017      UINT32 enew = get_iregval (isrc1) & 0x003e01ef;
1018      UINT32 tmp = m_cregs[CR_FSR] & ~0x003e01ef;
1019      m_cregs[CR_FSR] = enew | tmp;
1020   }
1021   else if (csrc2 != CR_FIR)
1022      m_cregs[csrc2] = get_iregval (isrc1);
1023}
1024
1025
1026/* Execute "ld.{s,b,l} isrc1(isrc2),idest" or
1027   "ld.{s,b,l} #const(isrc2),idest".  */
1028void i860_cpu_device::insn_ldx (UINT32 insn)
1029{
1030   UINT32 isrc1 = get_isrc1 (insn);
1031   INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
1032   UINT32 isrc2 = get_isrc2 (insn);
1033   UINT32 idest = get_idest (insn);
1034   UINT32 eff = 0;
1035   /* Operand size, in bytes.  */
1036   int sizes[4] = { 1, 1, 2, 4};
1037   int size = 0;
1038   int form_disp_reg = 0;
1039
1040   /* Bits 28 and 0 determine the operand size.  */
1041   size = sizes[((insn >> 27) & 2) | (insn & 1)];
1042
1043   /* Bit 26 determines the addressing mode (reg+reg or disp+reg).  */
1044   form_disp_reg = (insn & 0x04000000);
1045
1046   /* Get effective address depending on disp+reg or reg+reg form.  */
1047   if (form_disp_reg)
1048   {
1049      /* Chop off lower bits of displacement.  */
1050      immsrc1 &= ~(size - 1);
1051      eff = (UINT32)(immsrc1 + (INT32)(get_iregval (isrc2)));
1052   }
1053   else
1054      eff = get_iregval (isrc1) + get_iregval (isrc2);
1055
1056#ifdef TRACE_UNALIGNED_MEM
1057   if (eff & (size - 1))
1058   {
1059      fprintf (stderr, "0x%08x: Unaligned access detected (0x%08x).\n",
1060               m_pc, eff);
1061      SET_PSR_DAT (1);
1062      m_pending_trap = 1;
1063      return;
1064   }
1065#endif
1066
1067   /* The i860 sign-extends 8- or 16-bit integer loads.
1068
1069      Below, the readmemi_emu() needs to happen outside of the
1070      set_iregval macro (otherwise the readmem won't occur if r0
1071      is the target register).  */
1072   if (size < 4)
1073   {
1074      UINT32 readval = sign_ext (readmemi_emu (eff, size), size * 8);
1075      /* Do not update register on page fault.  */
1076      if (m_exiting_readmem)
1077      {
1078         return;
1079      }
1080      set_iregval (idest, readval);
1081   }
1082   else
1083   {
1084      UINT32 readval = readmemi_emu (eff, size);
1085      /* Do not update register on page fault.  */
1086      if (m_exiting_readmem)
1087      {
1088         return;
1089      }
1090      set_iregval (idest, readval);
1091   }
1092}
1093
1094
1095/* Execute "st.x isrc1ni,#const(isrc2)" instruction (there is no
1096   (reg + reg form).  Store uses the split immediate, not the normal
1097   16-bit immediate as in ld.x.  */
1098void i860_cpu_device::insn_stx (UINT32 insn)
1099{
1100   INT32 immsrc = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
1101   UINT32 isrc1 = get_isrc1 (insn);
1102   UINT32 isrc2 = get_isrc2 (insn);
1103   UINT32 eff = 0;
1104   /* Operand size, in bytes.  */
1105   int sizes[4] = { 1, 1, 2, 4};
1106   int size = 0;
1107
1108   /* Bits 28 and 0 determine the operand size.  */
1109   size = sizes[((insn >> 27) & 2) | (insn & 1)];
1110
1111   /* FIXME: Do any necessary traps.  */
1112
1113   /* Get effective address.  Chop off lower bits of displacement.  */
1114   immsrc &= ~(size - 1);
1115   eff = (UINT32)(immsrc + (INT32)get_iregval (isrc2));
1116
1117   /* Write data (value of reg isrc1) to memory at eff.  */
1118   writememi_emu (eff, size, get_iregval (isrc1));
1119   if (m_exiting_readmem)
1120      return;
1121}
1122
1123
1124/* Execute "fst.y fdest,isrc1(isrc2)", "fst.y fdest,isrc1(isrc2)++",
1125           "fst.y fdest,#const(isrc2)" or "fst.y fdest,#const(isrc2)++"
1126   instruction.  */
1127void i860_cpu_device::insn_fsty (UINT32 insn)
1128{
1129   UINT32 isrc1 = get_isrc1 (insn);
1130   INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
1131   UINT32 isrc2 = get_isrc2 (insn);
1132   UINT32 fdest = get_fdest (insn);
1133   UINT32 eff = 0;
1134   /* Operand size, in bytes.  */
1135   int sizes[4] = { 8, 4, 16, 4};
1136   int size = 0;
1137   int form_disp_reg = 0;
1138   int auto_inc = (insn & 1);
1139
1140   /* Bits 2 and 1 determine the operand size.  */
1141   size = sizes[((insn >> 1) & 3)];
1142
1143   /* Bit 26 determines the addressing mode (reg+reg or disp+reg).  */
1144   form_disp_reg = (insn & 0x04000000);
1145
1146   /* FIXME: Check for undefined behavior, non-even or non-quad
1147      register operands for fst.d and fst.q respectively.  */
1148
1149   /* Get effective address depending on disp+reg or reg+reg form.  */
1150   if (form_disp_reg)
1151   {
1152      /* Chop off lower bits of displacement.  */
1153      immsrc1 &= ~(size - 1);
1154      eff = (UINT32)(immsrc1 + (INT32)(get_iregval (isrc2)));
1155   }
1156   else
1157      eff = get_iregval (isrc1) + get_iregval (isrc2);
1158
1159#ifdef TRACE_UNALIGNED_MEM
1160   if (eff & (size - 1))
1161   {
1162      fprintf (stderr, "0x%08x: Unaligned access detected (0x%08x).\n",
1163               m_pc, eff);
1164      SET_PSR_DAT (1);
1165      m_pending_trap = 1;
1166      return;
1167   }
1168#endif
1169
1170   /* Do (post) auto-increment.  */
1171   if (auto_inc)
1172   {
1173      set_iregval (isrc2, eff);
1174#ifdef TRACE_UNDEFINED_I860
1175      /* When auto-inc, isrc1 and isrc2 regs can't be the same.  */
1176      if (isrc1 == isrc2)
1177      {
1178         /* Undefined i860XR behavior.  */
1179         fprintf (stderr, "WARNING: insn_fsty (pc=0x%08x): isrc1 = isrc2 in fst with auto-inc (ignored)\n", m_pc);
1180         return;
1181      }
1182#endif
1183   }
1184
1185   /* Write data (value of freg fdest) to memory at eff.  */
1186   if (size == 4)
1187      fp_writemem_emu (eff, size, (UINT8 *)(&m_frg[4 * (31 - fdest)]), 0xff);
1188   else if (size == 8)
1189      fp_writemem_emu (eff, size, (UINT8 *)(&m_frg[4 * (31 - (fdest + 1))]), 0xff);
1190   else
1191      fp_writemem_emu (eff, size, (UINT8 *)(&m_frg[4 * (31 - (fdest + 3))]), 0xff);
1192
1193}
1194
1195
1196/* Execute "fld.y isrc1(isrc2),fdest", "fld.y isrc1(isrc2)++,idest",
1197           "fld.y #const(isrc2),fdest" or "fld.y #const(isrc2)++,idest".
1198   Where y = {l,d,q}.  Note, there is no pfld.q, though.  */
1199void i860_cpu_device::insn_fldy (UINT32 insn)
1200{
1201   UINT32 isrc1 = get_isrc1 (insn);
1202   INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
1203   UINT32 isrc2 = get_isrc2 (insn);
1204   UINT32 fdest = get_fdest (insn);
1205   UINT32 eff = 0;
1206   /* Operand size, in bytes.  */
1207   int sizes[4] = { 8, 4, 16, 4};
1208   int size = 0;
1209   int form_disp_reg = 0;
1210   int auto_inc = (insn & 1);
1211   int piped = (insn & 0x40000000);
1212
1213   /* Bits 2 and 1 determine the operand size.  */
1214   size = sizes[((insn >> 1) & 3)];
1215
1216   /* Bit 26 determines the addressing mode (reg+reg or disp+reg).  */
1217   form_disp_reg = (insn & 0x04000000);
1218
1219   /* There is no pipelined load quad.  */
1220   if (piped && size == 16)
1221   {
1222      unrecog_opcode (m_pc, insn);
1223      return;
1224   }
1225
1226   /* FIXME: Check for undefined behavior, non-even or non-quad
1227      register operands for fld.d and fld.q respectively.  */
1228
1229   /* Get effective address depending on disp+reg or reg+reg form.  */
1230   if (form_disp_reg)
1231   {
1232      /* Chop off lower bits of displacement.  */
1233      immsrc1 &= ~(size - 1);
1234      eff = (UINT32)(immsrc1 + (INT32)(get_iregval (isrc2)));
1235   }
1236   else
1237      eff = get_iregval (isrc1) + get_iregval (isrc2);
1238
1239   /* Do (post) auto-increment.  */
1240   if (auto_inc)
1241   {
1242      set_iregval (isrc2, eff);
1243#ifdef TRACE_UNDEFINED_I860
1244      /* When auto-inc, isrc1 and isrc2 regs can't be the same.  */
1245      if (isrc1 == isrc2)
1246      {
1247         /* Undefined i860XR behavior.  */
1248         fprintf (stderr, "WARNING: insn_fldy (pc=0x%08x): isrc1 = isrc2 in fst with auto-inc (ignored)\n", m_pc);
1249         return;
1250      }
1251#endif
1252   }
1253
1254#ifdef TRACE_UNALIGNED_MEM
1255   if (eff & (size - 1))
1256   {
1257      fprintf (stderr, "0x%08x: Unaligned access detected (0x%08x).\n",
1258               m_pc, eff);
1259      SET_PSR_DAT (1);
1260      m_pending_trap = 1;
1261      return;
1262   }
1263#endif
1264
1265   /* Update the load pipe if necessary.  */
1266   /* FIXME: Copy result-status bits to fsr from last stage.  */
1267   if (!piped)
1268   {
1269      /* Scalar version writes the current result to fdest.  */
1270      /* Read data at 'eff' into freg 'fdest' (reads to f0 or f1 are
1271         thrown away).  */
1272      if (fdest > 1)
1273      {
1274         if (size == 4)
1275            fp_readmem_emu (eff, size, (UINT8 *)&(m_frg[4 * (31 - fdest)]));
1276         else if (size == 8)
1277            fp_readmem_emu (eff, size, (UINT8 *)&(m_frg[4 * (31 - (fdest + 1))]));
1278         else if (size == 16)
1279            fp_readmem_emu (eff, size, (UINT8 *)&(m_frg[4 * (31 - (fdest + 3))]));
1280      }
1281   }
1282   else
1283   {
1284      /* Read the data into a temp space first.  This way we can test
1285         for any traps before updating the pipeline.  The pipeline must
1286         stay unaffected after a trap so that the instruction can be
1287         properly restarted.  */
1288      UINT8 bebuf[8];
1289      fp_readmem_emu (eff, size, bebuf);
1290      if (m_pending_trap && m_exiting_readmem)
1291         goto ab_op;
1292
1293      /* Pipelined version writes fdest with the result from the last
1294         stage of the pipeline, with precision specified by the LRP
1295         bit of the stage's result-status bits.  */
1296#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
1297      /* Copy 3rd stage LRP to FSR.  */
1298      if (m_L[1 /* 2 */].stat.lrp)
1299         m_cregs[CR_FSR] |= 0x04000000;
1300      else
1301         m_cregs[CR_FSR] &= ~0x04000000;
1302#endif
1303      if (m_L[2].stat.lrp)  /* 3rd (last) stage.  */
1304         set_fregval_d (fdest, m_L[2].val.d);
1305      else
1306         set_fregval_s (fdest, m_L[2].val.s);
1307
1308      /* Now advance pipeline and write loaded data to first stage.  */
1309      m_L[2] = m_L[1];
1310      m_L[1] = m_L[0];
1311      if (size == 8)
1312      {
1313         UINT8 *t = (UINT8 *)&(m_L[0].val.d);
1314#ifndef HOST_MSB
1315         t[7] = bebuf[0]; t[6] = bebuf[1]; t[5] = bebuf[2]; t[4] = bebuf[3];
1316         t[3] = bebuf[4]; t[2] = bebuf[5]; t[1] = bebuf[6]; t[0] = bebuf[7];
1317#else
1318         t[0] = bebuf[0]; t[1] = bebuf[1]; t[2] = bebuf[2]; t[3] = bebuf[3];
1319         t[4] = bebuf[4]; t[5] = bebuf[5]; t[6] = bebuf[6]; t[7] = bebuf[7];
1320#endif
1321         m_L[0].stat.lrp = 1;
1322      }
1323      else
1324      {
1325         UINT8 *t = (UINT8 *)&(m_L[0].val.s);
1326#ifndef HOST_MSB
1327         t[3] = bebuf[0]; t[2] = bebuf[1]; t[1] = bebuf[2]; t[0] = bebuf[3];
1328#else
1329         t[0] = bebuf[0]; t[1] = bebuf[1]; t[2] = bebuf[2]; t[3] = bebuf[3];
1330#endif
1331         m_L[0].stat.lrp = 0;
1332      }
1333   }
1334
1335   ab_op:;
1336}
1337
1338
1339/* Execute "pst.d fdest,#const(isrc2)" or "fst.d fdest,#const(isrc2)++"
1340   instruction.  */
1341void i860_cpu_device::insn_pstd (UINT32 insn)
1342{
1343   INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
1344   UINT32 isrc2 = get_isrc2 (insn);
1345   UINT32 fdest = get_fdest (insn);
1346   UINT32 eff = 0;
1347   int auto_inc = (insn & 1);
1348   UINT8 *bebuf = 0;
1349   int pm = GET_PSR_PM ();
1350   int i;
1351   UINT32 wmask;
1352   int orig_pm = pm;
1353
1354   /* Get the pixel size, where:
1355      PS: 0 = 8 bits, 1 = 16 bits, 2 = 32-bits.  */
1356   int ps = GET_PSR_PS ();
1357
1358#ifdef TRACE_UNDEFINED_I860
1359   if (!(ps == 0 || ps == 1 || ps == 2))
1360      fprintf (stderr, "insn_pstd: Undefined i860XR behavior, invalid value %d for pixel size.\n", ps);
1361#endif
1362
1363#ifdef TRACE_UNDEFINED_I860
1364   /* Bits 2 and 1 determine the operand size, which must always be
1365      zero (indicating a 64-bit operand).  */
1366   if (insn & 0x6)
1367   {
1368      /* Undefined i860XR behavior.  */
1369      fprintf (stderr, "WARNING: insn_pstd (pc=0x%08x): bad operand size specifier\n", m_pc);
1370   }
1371#endif
1372
1373   /* FIXME: Check for undefined behavior, non-even register operands.  */
1374
1375   /* Get effective address.  Chop off lower bits of displacement.  */
1376   immsrc1 &= ~(8 - 1);
1377   eff = (UINT32)(immsrc1 + (INT32)(get_iregval (isrc2)));
1378
1379#ifdef TRACE_UNALIGNED_MEM
1380   if (eff & (8 - 1))
1381   {
1382      fprintf (stderr, "0x%08x: Unaligned access detected (0x%08x).\n",
1383               m_pc, eff);
1384      SET_PSR_DAT (1);
1385      m_pending_trap = 1;
1386      return;
1387   }
1388#endif
1389
1390   /* Do (post) auto-increment.  */
1391   if (auto_inc)
1392      set_iregval (isrc2, eff);
1393
1394   /* Update the the pixel mask depending on the pixel size.  Shift PM
1395      right by 8/2^ps bits.  */
1396   if (ps == 0)
1397      pm = (pm >> 8) & 0x00;
1398   else if (ps == 1)
1399      pm = (pm >> 4) & 0x0f;
1400   else if (ps == 2)
1401      pm = (pm >> 2) & 0x3f;
1402   SET_PSR_PM (pm);
1403
1404   /* Write data (value of freg fdest) to memory at eff-- but only those
1405      bytes that are enabled by the bits in PSR.PM.  Bit 0 of PM selects
1406      the pixel at the lowest address.  */
1407   wmask = 0;
1408   for (i = 0; i < 8; )
1409   {
1410      if (ps == 0)
1411      {
1412         if (orig_pm & 0x80)
1413            wmask |= 1 << (7-i);
1414         i += 1;
1415      }
1416      else if (ps == 1)
1417      {
1418         if (orig_pm & 0x08)
1419            wmask |= 0x3 << (6-i);
1420         i += 2;
1421      }
1422      else if (ps == 2)
1423      {
1424         if (orig_pm & 0x02)
1425            wmask |= 0xf << (4-i);
1426         i += 4;
1427      }
1428      else
1429      {
1430         wmask = 0xff;
1431         break;
1432      }
1433      orig_pm <<= 1;
1434   }
1435   bebuf = (UINT8 *)(&m_frg[4 * (31 - (fdest + 1))]);
1436   fp_writemem_emu (eff, 8, bebuf, wmask);
1437}
1438
1439
1440/* Execute "ixfr isrc1ni,fdest" instruction.  */
1441void i860_cpu_device::insn_ixfr (UINT32 insn)
1442{
1443   UINT32 isrc1 = get_isrc1 (insn);
1444   UINT32 fdest = get_fdest (insn);
1445   UINT32 iv = 0;
1446
1447   /* This is a bit-pattern transfer, not a conversion.  */
1448   iv = get_iregval (isrc1);
1449   set_fregval_s (fdest, *(float *)&iv);
1450}
1451
1452
1453/* Execute "addu isrc1,isrc2,idest".  */
1454void i860_cpu_device::insn_addu (UINT32 insn)
1455{
1456   UINT32 src1val;
1457   UINT32 isrc2 = get_isrc2 (insn);
1458   UINT32 idest = get_idest (insn);
1459   UINT32 tmp_dest_val = 0;
1460   UINT64 tmp = 0;
1461
1462   src1val = get_iregval (get_isrc1 (insn));
1463
1464   /* We don't update the actual idest register now because below we
1465      need to test the original src1 and src2 if either happens to
1466      be the destination register.  */
1467   tmp_dest_val = src1val + get_iregval (isrc2);
1468
1469   /* Set OF and CC flags.
1470      For unsigned:
1471        OF = bit 31 carry
1472        CC = bit 31 carry.
1473    */
1474   tmp = (UINT64)src1val + (UINT64)(get_iregval (isrc2));
1475   if ((tmp >> 32) & 1)
1476   {
1477      SET_PSR_CC (1);
1478      SET_EPSR_OF (1);
1479   }
1480   else
1481   {
1482      SET_PSR_CC (0);
1483      SET_EPSR_OF (0);
1484   }
1485
1486   /* Now update the destination register.  */
1487   set_iregval (idest, tmp_dest_val);
1488}
1489
1490
1491/* Execute "addu #const,isrc2,idest".  */
1492void i860_cpu_device::insn_addu_imm (UINT32 insn)
1493{
1494   UINT32 src1val;
1495   UINT32 isrc2 = get_isrc2 (insn);
1496   UINT32 idest = get_idest (insn);
1497   UINT32 tmp_dest_val = 0;
1498   UINT64 tmp = 0;
1499
1500   src1val = sign_ext (get_imm16 (insn), 16);
1501
1502   /* We don't update the actual idest register now because below we
1503      need to test the original src1 and src2 if either happens to
1504      be the destination register.  */
1505   tmp_dest_val = src1val + get_iregval (isrc2);
1506
1507   /* Set OF and CC flags.
1508      For unsigned:
1509        OF = bit 31 carry
1510        CC = bit 31 carry.
1511    */
1512   tmp = (UINT64)src1val + (UINT64)(get_iregval (isrc2));
1513   if ((tmp >> 32) & 1)
1514   {
1515      SET_PSR_CC (1);
1516      SET_EPSR_OF (1);
1517   }
1518   else
1519   {
1520      SET_PSR_CC (0);
1521      SET_EPSR_OF (0);
1522   }
1523
1524   /* Now update the destination register.  */
1525   set_iregval (idest, tmp_dest_val);
1526}
1527
1528
1529/* Execute "adds isrc1,isrc2,idest".  */
1530void i860_cpu_device::insn_adds (UINT32 insn)
1531{
1532   UINT32 src1val;
1533   UINT32 isrc2 = get_isrc2 (insn);
1534   UINT32 idest = get_idest (insn);
1535   UINT32 tmp_dest_val = 0;
1536   int sa, sb, sres;
1537
1538   src1val = get_iregval (get_isrc1 (insn));
1539
1540   /* We don't update the actual idest register now because below we
1541      need to test the original src1 and src2 if either happens to
1542      be the destination register.  */
1543   tmp_dest_val = src1val + get_iregval (isrc2);
1544
1545   /* Set OF and CC flags.
1546      For signed:
1547        OF = standard signed overflow.
1548        CC set   if isrc2 < -isrc1
1549        CC clear if isrc2 >= -isrc1
1550    */
1551   sa = src1val & 0x80000000;
1552   sb = get_iregval (isrc2) & 0x80000000;
1553   sres = tmp_dest_val & 0x80000000;
1554   if (sa != sb && sa != sres)
1555      SET_EPSR_OF (1);
1556   else
1557      SET_EPSR_OF (0);
1558
1559   if ((INT32)get_iregval (isrc2) < -(INT32)(src1val))
1560      SET_PSR_CC (1);
1561   else
1562      SET_PSR_CC (0);
1563
1564   /* Now update the destination register.  */
1565   set_iregval (idest, tmp_dest_val);
1566}
1567
1568
1569/* Execute "adds #const,isrc2,idest".  */
1570void i860_cpu_device::insn_adds_imm (UINT32 insn)
1571{
1572   UINT32 src1val;
1573   UINT32 isrc2 = get_isrc2 (insn);
1574   UINT32 idest = get_idest (insn);
1575   UINT32 tmp_dest_val = 0;
1576   int sa, sb, sres;
1577
1578   src1val = sign_ext (get_imm16 (insn), 16);
1579
1580   /* We don't update the actual idest register now because below we
1581      need to test the original src1 and src2 if either happens to
1582      be the destination register.  */
1583   tmp_dest_val = src1val + get_iregval (isrc2);
1584
1585   /* Set OF and CC flags.
1586      For signed:
1587        OF = standard signed overflow.
1588        CC set   if isrc2 < -isrc1
1589        CC clear if isrc2 >= -isrc1
1590    */
1591   sa = src1val & 0x80000000;
1592   sb = get_iregval (isrc2) & 0x80000000;
1593   sres = tmp_dest_val & 0x80000000;
1594   if (sa != sb && sa != sres)
1595      SET_EPSR_OF (1);
1596   else
1597      SET_EPSR_OF (0);
1598
1599   if ((INT32)get_iregval (isrc2) < -(INT32)(src1val))
1600      SET_PSR_CC (1);
1601   else
1602      SET_PSR_CC (0);
1603
1604   /* Now update the destination register.  */
1605   set_iregval (idest, tmp_dest_val);
1606}
1607
1608
1609/* Execute "subu isrc1,isrc2,idest".  */
1610void i860_cpu_device::insn_subu (UINT32 insn)
1611{
1612   UINT32 src1val;
1613   UINT32 isrc2 = get_isrc2 (insn);
1614   UINT32 idest = get_idest (insn);
1615   UINT32 tmp_dest_val = 0;
1616
1617   src1val = get_iregval (get_isrc1 (insn));
1618
1619   /* We don't update the actual idest register now because below we
1620      need to test the original src1 and src2 if either happens to
1621      be the destination register.  */
1622   tmp_dest_val = src1val - get_iregval (isrc2);
1623
1624   /* Set OF and CC flags.
1625      For unsigned:
1626        OF = NOT(bit 31 carry)
1627        CC = bit 31 carry.
1628        (i.e. CC set   if isrc2 <= isrc1
1629              CC clear if isrc2 > isrc1
1630    */
1631   if ((UINT32)get_iregval (isrc2) <= (UINT32)src1val)
1632   {
1633      SET_PSR_CC (1);
1634      SET_EPSR_OF (0);
1635   }
1636   else
1637   {
1638      SET_PSR_CC (0);
1639      SET_EPSR_OF (1);
1640   }
1641
1642   /* Now update the destination register.  */
1643   set_iregval (idest, tmp_dest_val);
1644}
1645
1646
1647/* Execute "subu #const,isrc2,idest".  */
1648void i860_cpu_device::insn_subu_imm (UINT32 insn)
1649{
1650   UINT32 src1val;
1651   UINT32 isrc2 = get_isrc2 (insn);
1652   UINT32 idest = get_idest (insn);
1653   UINT32 tmp_dest_val = 0;
1654
1655   src1val = sign_ext (get_imm16 (insn), 16);
1656
1657   /* We don't update the actual idest register now because below we
1658      need to test the original src1 and src2 if either happens to
1659      be the destination register.  */
1660   tmp_dest_val = src1val - get_iregval (isrc2);
1661
1662   /* Set OF and CC flags.
1663      For unsigned:
1664        OF = NOT(bit 31 carry)
1665        CC = bit 31 carry.
1666        (i.e. CC set   if isrc2 <= isrc1
1667              CC clear if isrc2 > isrc1
1668    */
1669   if ((UINT32)get_iregval (isrc2) <= (UINT32)src1val)
1670   {
1671      SET_PSR_CC (1);
1672      SET_EPSR_OF (0);
1673   }
1674   else
1675   {
1676      SET_PSR_CC (0);
1677      SET_EPSR_OF (1);
1678   }
1679
1680   /* Now update the destination register.  */
1681   set_iregval (idest, tmp_dest_val);
1682}
1683
1684
1685/* Execute "subs isrc1,isrc2,idest".  */
1686void i860_cpu_device::insn_subs (UINT32 insn)
1687{
1688   UINT32 src1val;
1689   UINT32 isrc2 = get_isrc2 (insn);
1690   UINT32 idest = get_idest (insn);
1691   UINT32 tmp_dest_val = 0;
1692   int sa, sb, sres;
1693
1694   src1val = get_iregval (get_isrc1 (insn));
1695
1696   /* We don't update the actual idest register now because below we
1697      need to test the original src1 and src2 if either happens to
1698      be the destination register.  */
1699   tmp_dest_val = src1val - get_iregval (isrc2);
1700
1701   /* Set OF and CC flags.
1702      For signed:
1703        OF = standard signed overflow.
1704        CC set   if isrc2 > isrc1
1705        CC clear if isrc2 <= isrc1
1706    */
1707   sa = src1val & 0x80000000;
1708   sb = get_iregval (isrc2) & 0x80000000;
1709   sres = tmp_dest_val & 0x80000000;
1710   if (sa != sb && sa != sres)
1711      SET_EPSR_OF (1);
1712   else
1713      SET_EPSR_OF (0);
1714
1715   if ((INT32)get_iregval (isrc2) > (INT32)(src1val))
1716      SET_PSR_CC (1);
1717   else
1718      SET_PSR_CC (0);
1719
1720   /* Now update the destination register.  */
1721   set_iregval (idest, tmp_dest_val);
1722}
1723
1724
1725/* Execute "subs #const,isrc2,idest".  */
1726void i860_cpu_device::insn_subs_imm (UINT32 insn)
1727{
1728   UINT32 src1val;
1729   UINT32 isrc2 = get_isrc2 (insn);
1730   UINT32 idest = get_idest (insn);
1731   UINT32 tmp_dest_val = 0;
1732   int sa, sb, sres;
1733
1734   src1val = sign_ext (get_imm16 (insn), 16);
1735
1736   /* We don't update the actual idest register now because below we
1737      need to test the original src1 and src2 if either happens to
1738      be the destination register.  */
1739   tmp_dest_val = src1val - get_iregval (isrc2);
1740
1741   /* Set OF and CC flags.
1742      For signed:
1743        OF = standard signed overflow.
1744        CC set   if isrc2 > isrc1
1745        CC clear if isrc2 <= isrc1
1746    */
1747   sa = src1val & 0x80000000;
1748   sb = get_iregval (isrc2) & 0x80000000;
1749   sres = tmp_dest_val & 0x80000000;
1750   if (sa != sb && sa != sres)
1751      SET_EPSR_OF (1);
1752   else
1753      SET_EPSR_OF (0);
1754
1755   if ((INT32)get_iregval (isrc2) > (INT32)(src1val))
1756      SET_PSR_CC (1);
1757   else
1758      SET_PSR_CC (0);
1759
1760   /* Now update the destination register.  */
1761   set_iregval (idest, tmp_dest_val);
1762}
1763
1764
1765/* Execute "shl isrc1,isrc2,idest".  */
1766void i860_cpu_device::insn_shl (UINT32 insn)
1767{
1768   UINT32 src1val = 0;
1769   UINT32 isrc2 = get_isrc2 (insn);
1770   UINT32 idest = get_idest (insn);
1771
1772   src1val = get_iregval (get_isrc1 (insn));
1773   set_iregval (idest, get_iregval (isrc2) << src1val);
1774}
1775
1776
1777/* Execute "shl #const,isrc2,idest".  */
1778void i860_cpu_device::insn_shl_imm (UINT32 insn)
1779{
1780   UINT32 src1val = 0;
1781   UINT32 isrc2 = get_isrc2 (insn);
1782   UINT32 idest = get_idest (insn);
1783
1784   src1val = sign_ext (get_imm16 (insn), 16);
1785   set_iregval (idest, get_iregval (isrc2) << src1val);
1786}
1787
1788
1789/* Execute "shr isrc1,isrc2,idest".  */
1790void i860_cpu_device::insn_shr (UINT32 insn)
1791{
1792   UINT32 src1val = 0;
1793   UINT32 isrc2 = get_isrc2 (insn);
1794   UINT32 idest = get_idest (insn);
1795
1796   src1val = get_iregval (get_isrc1 (insn));
1797
1798   /* The iregs array is UINT32, so this is a logical shift.  */
1799   set_iregval (idest, get_iregval (isrc2) >> src1val);
1800
1801   /* shr also sets the SC in psr (shift count).  */
1802   SET_PSR_SC (src1val);
1803}
1804
1805
1806/* Execute "shr #const,isrc2,idest".  */
1807void i860_cpu_device::insn_shr_imm (UINT32 insn)
1808{
1809   UINT32 src1val = 0;
1810   UINT32 isrc2 = get_isrc2 (insn);
1811   UINT32 idest = get_idest (insn);
1812
1813   src1val = sign_ext (get_imm16 (insn), 16);
1814
1815   /* The iregs array is UINT32, so this is a logical shift.  */
1816   set_iregval (idest, get_iregval (isrc2) >> src1val);
1817
1818   /* shr also sets the SC in psr (shift count).  */
1819   SET_PSR_SC (src1val);
1820}
1821
1822
1823/* Execute "shra isrc1,isrc2,idest".  */
1824void i860_cpu_device::insn_shra (UINT32 insn)
1825{
1826   UINT32 src1val = 0;
1827   UINT32 isrc2 = get_isrc2 (insn);
1828   UINT32 idest = get_idest (insn);
1829
1830   src1val = get_iregval (get_isrc1 (insn));
1831
1832   /* The iregs array is UINT32, so cast isrc2 to get arithmetic shift.  */
1833   set_iregval (idest, (INT32)get_iregval (isrc2) >> src1val);
1834}
1835
1836
1837/* Execute "shra #const,isrc2,idest".  */
1838void i860_cpu_device::insn_shra_imm (UINT32 insn)
1839{
1840   UINT32 src1val = 0;
1841   UINT32 isrc2 = get_isrc2 (insn);
1842   UINT32 idest = get_idest (insn);
1843
1844   src1val = sign_ext (get_imm16 (insn), 16);
1845
1846   /* The iregs array is UINT32, so cast isrc2 to get arithmetic shift.  */
1847   set_iregval (idest, (INT32)get_iregval (isrc2) >> src1val);
1848}
1849
1850
1851/* Execute "shrd isrc1ni,isrc2,idest" instruction.  */
1852void i860_cpu_device::insn_shrd (UINT32 insn)
1853{
1854   UINT32 isrc1 = get_isrc1 (insn);
1855   UINT32 isrc2 = get_isrc2 (insn);
1856   UINT32 idest = get_idest (insn);
1857   UINT32 sc = GET_PSR_SC ();
1858   UINT32 tmp;
1859
1860   /* Do the operation:
1861      idest = low_32(isrc1ni:isrc2 >> sc).  */
1862   if (sc == 0)
1863      tmp = get_iregval (isrc2);
1864   else
1865   {
1866      tmp = get_iregval (isrc1) << (32 - sc);
1867      tmp |= (get_iregval (isrc2) >> sc);
1868   }
1869   set_iregval (idest, tmp);
1870}
1871
1872
1873/* Execute "and isrc1,isrc2,idest".  */
1874void i860_cpu_device::insn_and (UINT32 insn)
1875{
1876   UINT32 isrc1 = get_isrc1 (insn);
1877   UINT32 isrc2 = get_isrc2 (insn);
1878   UINT32 idest = get_idest (insn);
1879   UINT32 res = 0;
1880
1881   /* Do the operation.  */
1882   res = get_iregval (isrc1) & get_iregval (isrc2);
1883
1884   /* Set flags.  */
1885   if (res == 0)
1886      SET_PSR_CC (1);
1887   else
1888      SET_PSR_CC (0);
1889
1890   set_iregval (idest, res);
1891}
1892
1893
1894/* Execute "and #const,isrc2,idest".  */
1895void i860_cpu_device::insn_and_imm (UINT32 insn)
1896{
1897   UINT32 src1val = 0;
1898   UINT32 isrc2 = get_isrc2 (insn);
1899   UINT32 idest = get_idest (insn);
1900   UINT32 res = 0;
1901
1902   /* Do the operation.  */
1903   src1val = get_imm16 (insn);
1904   res = src1val & get_iregval (isrc2);
1905
1906   /* Set flags.  */
1907   if (res == 0)
1908      SET_PSR_CC (1);
1909   else
1910      SET_PSR_CC (0);
1911
1912   set_iregval (idest, res);
1913}
1914
1915
1916/* Execute "andh #const,isrc2,idest".  */
1917void i860_cpu_device::insn_andh_imm (UINT32 insn)
1918{
1919   UINT32 src1val = 0;
1920   UINT32 isrc2 = get_isrc2 (insn);
1921   UINT32 idest = get_idest (insn);
1922   UINT32 res = 0;
1923
1924   /* Do the operation.  */
1925   src1val = get_imm16 (insn);
1926   res = (src1val << 16) & get_iregval (isrc2);
1927
1928   /* Set flags.  */
1929   if (res == 0)
1930      SET_PSR_CC (1);
1931   else
1932      SET_PSR_CC (0);
1933
1934   set_iregval (idest, res);
1935}
1936
1937
1938/* Execute "andnot isrc1,isrc2,idest".  */
1939void i860_cpu_device::insn_andnot (UINT32 insn)
1940{
1941   UINT32 isrc1 = get_isrc1 (insn);
1942   UINT32 isrc2 = get_isrc2 (insn);
1943   UINT32 idest = get_idest (insn);
1944   UINT32 res = 0;
1945
1946   /* Do the operation.  */
1947   res = (~get_iregval (isrc1)) & get_iregval (isrc2);
1948
1949   /* Set flags.  */
1950   if (res == 0)
1951      SET_PSR_CC (1);
1952   else
1953      SET_PSR_CC (0);
1954
1955   set_iregval (idest, res);
1956}
1957
1958
1959/* Execute "andnot #const,isrc2,idest".  */
1960void i860_cpu_device::insn_andnot_imm (UINT32 insn)
1961{
1962   UINT32 src1val = 0;
1963   UINT32 isrc2 = get_isrc2 (insn);
1964   UINT32 idest = get_idest (insn);
1965   UINT32 res = 0;
1966
1967   /* Do the operation.  */
1968   src1val = get_imm16 (insn);
1969   res = (~src1val) & get_iregval (isrc2);
1970
1971   /* Set flags.  */
1972   if (res == 0)
1973      SET_PSR_CC (1);
1974   else
1975      SET_PSR_CC (0);
1976
1977   set_iregval (idest, res);
1978}
1979
1980
1981/* Execute "andnoth #const,isrc2,idest".  */
1982void i860_cpu_device::insn_andnoth_imm (UINT32 insn)
1983{
1984   UINT32 src1val = 0;
1985   UINT32 isrc2 = get_isrc2 (insn);
1986   UINT32 idest = get_idest (insn);
1987   UINT32 res = 0;
1988
1989   /* Do the operation.  */
1990   src1val = get_imm16 (insn);
1991   res = (~(src1val << 16)) & get_iregval (isrc2);
1992
1993   /* Set flags.  */
1994   if (res == 0)
1995      SET_PSR_CC (1);
1996   else
1997      SET_PSR_CC (0);
1998
1999   set_iregval (idest, res);
2000}
2001
2002
2003/* Execute "or isrc1,isrc2,idest".  */
2004void i860_cpu_device::insn_or (UINT32 insn)
2005{
2006   UINT32 isrc1 = get_isrc1 (insn);
2007   UINT32 isrc2 = get_isrc2 (insn);
2008   UINT32 idest = get_idest (insn);
2009   UINT32 res = 0;
2010
2011   /* Do the operation.  */
2012   res = get_iregval (isrc1) | get_iregval (isrc2);
2013
2014   /* Set flags.  */
2015   if (res == 0)
2016      SET_PSR_CC (1);
2017   else
2018      SET_PSR_CC (0);
2019
2020   set_iregval (idest, res);
2021}
2022
2023
2024/* Execute "or #const,isrc2,idest".  */
2025void i860_cpu_device::insn_or_imm (UINT32 insn)
2026{
2027   UINT32 src1val = 0;
2028   UINT32 isrc2 = get_isrc2 (insn);
2029   UINT32 idest = get_idest (insn);
2030   UINT32 res = 0;
2031
2032   /* Do the operation.  */
2033   src1val = get_imm16 (insn);
2034   res = src1val | get_iregval (isrc2);
2035
2036   /* Set flags.  */
2037   if (res == 0)
2038      SET_PSR_CC (1);
2039   else
2040      SET_PSR_CC (0);
2041
2042   set_iregval (idest, res);
2043}
2044
2045
2046/* Execute "orh #const,isrc2,idest".  */
2047void i860_cpu_device::insn_orh_imm (UINT32 insn)
2048{
2049   UINT32 src1val = 0;
2050   UINT32 isrc2 = get_isrc2 (insn);
2051   UINT32 idest = get_idest (insn);
2052   UINT32 res = 0;
2053
2054   /* Do the operation.  */
2055   src1val = get_imm16 (insn);
2056   res = (src1val << 16) | get_iregval (isrc2);
2057
2058   /* Set flags.  */
2059   if (res == 0)
2060      SET_PSR_CC (1);
2061   else
2062      SET_PSR_CC (0);
2063
2064   set_iregval (idest, res);
2065}
2066
2067
2068/* Execute "xor isrc1,isrc2,idest".  */
2069void i860_cpu_device::insn_xor (UINT32 insn)
2070{
2071   UINT32 isrc1 = get_isrc1 (insn);
2072   UINT32 isrc2 = get_isrc2 (insn);
2073   UINT32 idest = get_idest (insn);
2074   UINT32 res = 0;
2075
2076   /* Do the operation.  */
2077   res = get_iregval (isrc1) ^ get_iregval (isrc2);
2078
2079   /* Set flags.  */
2080   if (res == 0)
2081      SET_PSR_CC (1);
2082   else
2083      SET_PSR_CC (0);
2084
2085   set_iregval (idest, res);
2086}
2087
2088
2089/* Execute "xor #const,isrc2,idest".  */
2090void i860_cpu_device::insn_xor_imm (UINT32 insn)
2091{
2092   UINT32 src1val = 0;
2093   UINT32 isrc2 = get_isrc2 (insn);
2094   UINT32 idest = get_idest (insn);
2095   UINT32 res = 0;
2096
2097   /* Do the operation.  */
2098   src1val = get_imm16 (insn);
2099   res = src1val ^ get_iregval (isrc2);
2100
2101   /* Set flags.  */
2102   if (res == 0)
2103      SET_PSR_CC (1);
2104   else
2105      SET_PSR_CC (0);
2106
2107   set_iregval (idest, res);
2108}
2109
2110
2111/* Execute "xorh #const,isrc2,idest".  */
2112void i860_cpu_device::insn_xorh_imm (UINT32 insn)
2113{
2114   UINT32 src1val = 0;
2115   UINT32 isrc2 = get_isrc2 (insn);
2116   UINT32 idest = get_idest (insn);
2117   UINT32 res = 0;
2118
2119   /* Do the operation.  */
2120   src1val = get_imm16 (insn);
2121   res = (src1val << 16) ^ get_iregval (isrc2);
2122
2123   /* Set flags.  */
2124   if (res == 0)
2125      SET_PSR_CC (1);
2126   else
2127      SET_PSR_CC (0);
2128
2129   set_iregval (idest, res);
2130}
2131
2132
2133/* Execute "trap isrc1ni,isrc2,idest" instruction.  */
2134void i860_cpu_device::insn_trap (UINT32 insn)
2135{
2136   SET_PSR_IT (1);
2137   m_pending_trap = 1;
2138}
2139
2140
2141/* Execute "intovr" instruction.  */
2142void i860_cpu_device::insn_intovr (UINT32 insn)
2143{
2144   if (GET_EPSR_OF ())
2145   {
2146      SET_PSR_IT (1);
2147      m_pending_trap = 1;
2148   }
2149}
2150
2151
2152/* Execute "bte isrc1,isrc2,sbroff".  */
2153void i860_cpu_device::insn_bte (UINT32 insn)
2154{
2155   UINT32 src1val = 0;
2156   UINT32 isrc2 = get_isrc2 (insn);
2157   UINT32 target_addr = 0;
2158   INT32 sbroff = 0;
2159   int res = 0;
2160
2161   src1val = get_iregval (get_isrc1 (insn));
2162
2163   /* Compute the target address from the sbroff field.  */
2164   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2165   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2166
2167   /* Determine comparison result.  */
2168   res = (src1val == get_iregval (isrc2));
2169
2170   /* Branch routines always update the PC.  */
2171   if (res)
2172      m_pc = target_addr;
2173   else
2174      m_pc += 4;
2175
2176   m_pc_updated = 1;
2177}
2178
2179
2180/* Execute "bte #const5,isrc2,sbroff".  */
2181void i860_cpu_device::insn_bte_imm (UINT32 insn)
2182{
2183   UINT32 src1val = 0;
2184   UINT32 isrc2 = get_isrc2 (insn);
2185   UINT32 target_addr = 0;
2186   INT32 sbroff = 0;
2187   int res = 0;
2188
2189   src1val = (insn >> 11) & 0x1f;  /* 5-bit field, zero-extended.  */
2190
2191   /* Compute the target address from the sbroff field.  */
2192   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2193   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2194
2195   /* Determine comparison result.  */
2196   res = (src1val == get_iregval (isrc2));
2197
2198   /* Branch routines always update the PC.  */
2199   if (res)
2200      m_pc = target_addr;
2201   else
2202      m_pc += 4;
2203
2204   m_pc_updated = 1;
2205}
2206
2207
2208/* Execute "btne isrc1,isrc2,sbroff".  */
2209void i860_cpu_device::insn_btne (UINT32 insn)
2210{
2211   UINT32 src1val = 0;
2212   UINT32 isrc2 = get_isrc2 (insn);
2213   UINT32 target_addr = 0;
2214   INT32 sbroff = 0;
2215   int res = 0;
2216
2217   src1val = get_iregval (get_isrc1 (insn));
2218
2219   /* Compute the target address from the sbroff field.  */
2220   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2221   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2222
2223   /* Determine comparison result.  */
2224   res = (src1val != get_iregval (isrc2));
2225
2226   /* Branch routines always update the PC.  */
2227   if (res)
2228      m_pc = target_addr;
2229   else
2230      m_pc += 4;
2231
2232   m_pc_updated = 1;
2233}
2234
2235
2236/* Execute "btne #const5,isrc2,sbroff".  */
2237void i860_cpu_device::insn_btne_imm (UINT32 insn)
2238{
2239   UINT32 src1val = 0;
2240   UINT32 isrc2 = get_isrc2 (insn);
2241   UINT32 target_addr = 0;
2242   INT32 sbroff = 0;
2243   int res = 0;
2244
2245   src1val = (insn >> 11) & 0x1f;  /* 5-bit field, zero-extended.  */
2246
2247   /* Compute the target address from the sbroff field.  */
2248   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2249   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2250
2251   /* Determine comparison result.  */
2252   res = (src1val != get_iregval (isrc2));
2253
2254   /* Branch routines always update the PC.  */
2255   if (res)
2256      m_pc = target_addr;
2257   else
2258      m_pc += 4;
2259
2260   m_pc_updated = 1;
2261}
2262
2263
2264/* Execute "bc lbroff" instruction.  */
2265void i860_cpu_device::insn_bc (UINT32 insn)
2266{
2267   UINT32 target_addr = 0;
2268   INT32 lbroff = 0;
2269   int res = 0;
2270
2271   /* Compute the target address from the lbroff field.  */
2272   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2273   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2274
2275   /* Determine comparison result.  */
2276   res = (GET_PSR_CC () == 1);
2277
2278   /* Branch routines always update the PC.  */
2279   if (res)
2280      m_pc = target_addr;
2281   else
2282      m_pc += 4;
2283
2284   m_pc_updated = 1;
2285}
2286
2287
2288/* Execute "bnc lbroff" instruction.  */
2289void i860_cpu_device::insn_bnc (UINT32 insn)
2290{
2291   UINT32 target_addr = 0;
2292   INT32 lbroff = 0;
2293   int res = 0;
2294
2295   /* Compute the target address from the lbroff field.  */
2296   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2297   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2298
2299   /* Determine comparison result.  */
2300   res = (GET_PSR_CC () == 0);
2301
2302   /* Branch routines always update the PC, since pc_updated is set
2303      in the decode routine.  */
2304   if (res)
2305      m_pc = target_addr;
2306   else
2307      m_pc += 4;
2308
2309   m_pc_updated = 1;
2310}
2311
2312
2313/* Execute "bc.t lbroff" instruction.  */
2314void i860_cpu_device::insn_bct (UINT32 insn)
2315{
2316   UINT32 target_addr = 0;
2317   INT32 lbroff = 0;
2318   int res = 0;
2319   UINT32 orig_pc = m_pc;
2320
2321   /* Compute the target address from the lbroff field.  */
2322   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2323   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2324
2325   /* Determine comparison result.  */
2326   res = (GET_PSR_CC () == 1);
2327
2328   /* Careful. Unlike bla, the delay slot instruction is only executed
2329      if the branch is taken.  */
2330   if (res)
2331   {
2332      /* Execute delay slot instruction.  */
2333      m_pc += 4;
2334      decode_exec (ifetch (orig_pc + 4), 0);
2335      m_pc = orig_pc;
2336      if (m_pending_trap)
2337      {
2338         m_pending_trap |= TRAP_IN_DELAY_SLOT;
2339         goto ab_op;
2340      }
2341   }
2342
2343   /* Since this branch is delayed, we must jump 2 instructions if
2344      if isn't taken.  */
2345   if (res)
2346      m_pc = target_addr;
2347   else
2348      m_pc += 8;
2349
2350   m_pc_updated = 1;
2351
2352   ab_op:
2353   ;
2354}
2355
2356
2357/* Execute "bnc.t lbroff" instruction.  */
2358void i860_cpu_device::insn_bnct (UINT32 insn)
2359{
2360   UINT32 target_addr = 0;
2361   INT32 lbroff = 0;
2362   int res = 0;
2363   UINT32 orig_pc = m_pc;
2364
2365   /* Compute the target address from the lbroff field.  */
2366   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2367   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2368
2369   /* Determine comparison result.  */
2370   res = (GET_PSR_CC () == 0);
2371
2372   /* Careful. Unlike bla, the delay slot instruction is only executed
2373      if the branch is taken.  */
2374   if (res)
2375   {
2376      /* Execute delay slot instruction.  */
2377      m_pc += 4;
2378      decode_exec (ifetch (orig_pc + 4), 0);
2379      m_pc = orig_pc;
2380      if (m_pending_trap)
2381      {
2382         m_pending_trap |= TRAP_IN_DELAY_SLOT;
2383         goto ab_op;
2384      }
2385   }
2386
2387   /* Since this branch is delayed, we must jump 2 instructions if
2388      if isn't taken.  */
2389   if (res)
2390      m_pc = target_addr;
2391   else
2392      m_pc += 8;
2393
2394   m_pc_updated = 1;
2395
2396   ab_op:
2397   ;
2398}
2399
2400
2401/* Execute "call lbroff" instruction.  */
2402void i860_cpu_device::insn_call (UINT32 insn)
2403{
2404   UINT32 target_addr = 0;
2405   INT32 lbroff = 0;
2406   UINT32 orig_pc = m_pc;
2407
2408   /* Compute the target address from the lbroff field.  */
2409   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2410   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2411
2412   /* Execute the delay slot instruction.  */
2413   m_pc += 4;
2414   decode_exec (ifetch (orig_pc + 4), 0);
2415   m_pc = orig_pc;
2416   if (m_pending_trap)
2417   {
2418      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2419      goto ab_op;
2420   }
2421
2422   /* Sets the return pointer (r1).  */
2423   set_iregval (1, orig_pc + 8);
2424
2425   /* New target.  */
2426   m_pc = target_addr;
2427   m_pc_updated = 1;
2428
2429   ab_op:;
2430}
2431
2432
2433/* Execute "br lbroff".  */
2434void i860_cpu_device::insn_br (UINT32 insn)
2435{
2436   UINT32 target_addr = 0;
2437   INT32 lbroff = 0;
2438   UINT32 orig_pc = m_pc;
2439
2440   /* Compute the target address from the lbroff field.  */
2441   lbroff = sign_ext ((insn & 0x03ffffff), 26);
2442   target_addr = (INT32)m_pc + 4 + (lbroff << 2);
2443
2444   /* Execute the delay slot instruction.  */
2445   m_pc += 4;
2446   decode_exec (ifetch (orig_pc + 4), 0);
2447   m_pc = orig_pc;
2448   if (m_pending_trap)
2449   {
2450      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2451      goto ab_op;
2452   }
2453
2454   /* New target.  */
2455   m_pc = target_addr;
2456   m_pc_updated = 1;
2457
2458   ab_op:;
2459}
2460
2461
2462/* Execute "bri isrc1ni" instruction.
2463   Note: I didn't merge this code with calli because bri must do
2464   a lot of flag manipulation if any trap bits are set.  */
2465void i860_cpu_device::insn_bri (UINT32 insn)
2466{
2467   UINT32 isrc1 = get_isrc1 (insn);
2468   UINT32 orig_pc = m_pc;
2469   UINT32 orig_psr = m_cregs[CR_PSR];
2470   UINT32 orig_src1_val = get_iregval (isrc1);
2471
2472#if 1 /* TURBO.  */
2473   m_cregs[CR_PSR] &= ~PSR_ALL_TRAP_BITS_MASK;
2474#endif
2475
2476   /* Execute the delay slot instruction.  */
2477   m_pc += 4;
2478   decode_exec (ifetch (orig_pc + 4), 0);
2479   m_pc = orig_pc;
2480
2481   /* Delay slot insn caused a trap, abort operation.  */
2482   if (m_pending_trap)
2483   {
2484      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2485      goto ab_op;
2486   }
2487
2488   /* If any trap bits are set, we need to do the return from
2489      trap work.  Note, we must use the PSR value that existed
2490      before the delay slot instruction was executed since the
2491      delay slot instruction might itself cause a trap bit to
2492      be set.  */
2493   if (orig_psr & PSR_ALL_TRAP_BITS_MASK)
2494   {
2495      /* Restore U and IM from their previous copies.  */
2496      SET_PSR_U (GET_PSR_PU ());
2497      SET_PSR_IM (GET_PSR_PIM ());
2498
2499      m_fir_gets_trap_addr = 0;
2500   }
2501
2502   /* Update PC.  */
2503   m_pc = orig_src1_val;
2504
2505   m_pc_updated = 1;
2506   ab_op:;
2507}
2508
2509/* Execute "calli isrc1ni" instruction.  */
2510void i860_cpu_device::insn_calli (UINT32 insn)
2511{
2512   UINT32 isrc1 = get_isrc1 (insn);
2513   UINT32 orig_pc = m_pc;
2514   UINT32 orig_src1_val = get_iregval (isrc1);
2515
2516#ifdef TRACE_UNDEFINED_I860
2517   /* Check for undefined behavior.  */
2518   if (isrc1 == 1)
2519   {
2520      /* Src1 must not be r1.  */
2521      fprintf (stderr, "WARNING: insn_calli (pc=0x%08x): isrc1 = r1 on a calli\n", m_pc);
2522   }
2523#endif
2524
2525   /* Set return pointer before executing delay slot instruction.  */
2526   set_iregval (1, m_pc + 8);
2527
2528   /* Execute the delay slot instruction.  */
2529   m_pc += 4;
2530   decode_exec (ifetch (orig_pc + 4), 0);
2531   m_pc = orig_pc;
2532   if (m_pending_trap)
2533   {
2534      set_iregval (1, orig_src1_val);
2535      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2536      goto ab_op;
2537   }
2538
2539   /* Set new PC.  */
2540   m_pc = orig_src1_val;
2541   m_pc_updated = 1;
2542
2543   ab_op:;
2544}
2545
2546
2547/* Execute "bla isrc1ni,isrc2,sbroff" instruction.  */
2548void i860_cpu_device::insn_bla (UINT32 insn)
2549{
2550   UINT32 isrc1 = get_isrc1 (insn);
2551   UINT32 isrc2 = get_isrc2 (insn);
2552   UINT32 target_addr = 0;
2553   INT32 sbroff = 0;
2554   int lcc_tmp = 0;
2555   UINT32 orig_pc = m_pc;
2556   UINT32 orig_isrc2val = get_iregval (isrc2);
2557
2558#ifdef TRACE_UNDEFINED_I860
2559   /* Check for undefined behavior.  */
2560   if (isrc1 == isrc2)
2561   {
2562      /* Src1 and src2 the same is undefined i860XR behavior.  */
2563      fprintf (stderr, "WARNING: insn_bla (pc=0x%08x): isrc1 and isrc2 are the same (ignored)\n", m_pc);
2564      return;
2565   }
2566#endif
2567
2568   /* Compute the target address from the sbroff field.  */
2569   sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
2570   target_addr = (INT32)m_pc + 4 + (sbroff << 2);
2571
2572   /* Determine comparison result based on opcode.  */
2573   lcc_tmp = ((INT32)get_iregval (isrc2) >= -(INT32)get_iregval (isrc1));
2574
2575   set_iregval (isrc2, get_iregval (isrc1) + orig_isrc2val);
2576
2577   /* Execute the delay slot instruction.  */
2578   m_pc += 4;
2579   decode_exec (ifetch (orig_pc + 4), 0);
2580   m_pc = orig_pc;
2581   if (m_pending_trap)
2582   {
2583      m_pending_trap |= TRAP_IN_DELAY_SLOT;
2584      goto ab_op;
2585   }
2586
2587   if (GET_PSR_LCC ())
2588      m_pc = target_addr;
2589   else
2590   {
2591      /* Since this branch is delayed, we must jump 2 instructions if
2592         if isn't taken.  */
2593      m_pc += 8;
2594   }
2595   SET_PSR_LCC (lcc_tmp);
2596
2597   m_pc_updated = 1;
2598   ab_op:;
2599}
2600
2601
2602/* Execute "flush #const(isrc2)" or "flush #const(isrc2)++" instruction.  */
2603void i860_cpu_device::insn_flush (UINT32 insn)
2604{
2605   UINT32 src1val = sign_ext (get_imm16 (insn), 16);
2606   UINT32 isrc2 = get_isrc2 (insn);
2607   int auto_inc = (insn & 1);
2608   UINT32 eff = 0;
2609
2610   /* Technically, idest should be encoded as r0 because idest
2611      is undefined after the instruction.  We don't currently
2612      check for this.
2613
2614      Flush D$ block at address #const+isrc2.  Block is undefined
2615      after.  The effective address must be 16-byte aligned.
2616
2617      FIXME: Need to examine RB and RC and do this right.
2618     */
2619
2620   /* Chop off lower bits of displacement to 16-byte alignment.  */
2621   src1val &= ~(16-1);
2622   eff = src1val + get_iregval (isrc2);
2623   if (auto_inc)
2624      set_iregval (isrc2, eff);
2625
2626   /* In user mode, the flush is ignored.  */
2627   if (GET_PSR_U () == 0)
2628   {
2629      /* If line is dirty, write it to memory and invalidate.
2630         NOTE: The actual dirty write is unimplemented in the MAME version
2631         as we don't emulate the dcache.  */
2632   }
2633}
2634
2635
2636/* Execute "[p]fmul.{ss,sd,dd} fsrc1,fsrc2,fdest" instruction or
2637   pfmul3.dd fsrc1,fsrc2,fdest.
2638
2639   The pfmul3.dd differs from pfmul.dd in that it treats the pipeline
2640   as 3 stages, even though it is a double precision multiply.  */
2641void i860_cpu_device::insn_fmul (UINT32 insn)
2642{
2643   UINT32 fsrc1 = get_fsrc1 (insn);
2644   UINT32 fsrc2 = get_fsrc2 (insn);
2645   UINT32 fdest = get_fdest (insn);
2646   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
2647   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
2648   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
2649   double dbl_tmp_dest = 0.0;
2650   float sgl_tmp_dest = 0.0;
2651   double dbl_last_stage_contents = 0.0;
2652   float sgl_last_stage_contents = 0.0;
2653   int is_pfmul3 = insn & 0x4;
2654   int num_stages = (src_prec && !is_pfmul3) ? 2 : 3;
2655
2656   /* Only .dd is valid for pfmul.  */
2657   if (is_pfmul3 && (insn & 0x180) != 0x180)
2658   {
2659      unrecog_opcode (m_pc, insn);
2660      return;
2661   }
2662
2663   /* Check for invalid .ds combination.  */
2664   if ((insn & 0x180) == 0x100)
2665   {
2666      unrecog_opcode (m_pc, insn);
2667      return;
2668   }
2669
2670   /* For pipelined version, retrieve the contents of the last stage
2671      of the pipeline, whose precision is specified by the MRP bit
2672      of the stage's result-status bits.  Note for pfmul, the number
2673      of stages is determined by the source precision of the current
2674      operation.  */
2675   if (piped)
2676   {
2677      if (m_M[num_stages - 1].stat.mrp)
2678         dbl_last_stage_contents = m_M[num_stages - 1].val.d;
2679      else
2680         sgl_last_stage_contents = m_M[num_stages - 1].val.s;
2681   }
2682
2683   /* Do the operation, being careful about source and result
2684      precision.  */
2685   if (src_prec)
2686   {
2687      double v1 = get_fregval_d (fsrc1);
2688      double v2 = get_fregval_d (fsrc2);
2689
2690      /* For pipelined mul, if fsrc2 is the same as fdest, then the last
2691         stage is bypassed to fsrc2 (rather than using the value in fsrc2).
2692         This bypass is not available for fsrc1, and is undefined behavior.  */
2693      if (0 && piped && fdest != 0 && fsrc1 == fdest)
2694         v1 = dbl_last_stage_contents;
2695      if (piped && fdest != 0 && fsrc2 == fdest)
2696         v2 = dbl_last_stage_contents;
2697
2698      if (res_prec)
2699         dbl_tmp_dest = v1 * v2;
2700      else
2701         sgl_tmp_dest = (float)(v1 * v2);
2702   }
2703   else
2704   {
2705      float v1 = get_fregval_s (fsrc1);
2706      float v2 = get_fregval_s (fsrc2);
2707
2708      /* For pipelined mul, if fsrc2 is the same as fdest, then the last
2709         stage is bypassed to fsrc2 (rather than using the value in fsrc2).
2710         This bypass is not available for fsrc1, and is undefined behavior.  */
2711      if (0 && piped && fdest != 0 && fsrc1 == fdest)
2712         v1 = sgl_last_stage_contents;
2713      if (piped && fdest != 0 && fsrc2 == fdest)
2714         v2 = sgl_last_stage_contents;
2715
2716      if (res_prec)
2717         dbl_tmp_dest = (double)(v1 * v2);
2718      else
2719         sgl_tmp_dest = v1 * v2;
2720   }
2721
2722   /* FIXME: Set result-status bits besides MRP. And copy to fsr from
2723             last stage.  */
2724   /* FIXME: Scalar version flows through all stages.  */
2725   /* FIXME: Mixed precision (only weird for pfmul).  */
2726   if (!piped)
2727   {
2728      /* Scalar version writes the current calculation to the fdest
2729         register, with precision specified by the R bit.  */
2730      if (res_prec)
2731         set_fregval_d (fdest, dbl_tmp_dest);
2732      else
2733         set_fregval_s (fdest, sgl_tmp_dest);
2734   }
2735   else
2736   {
2737      /* Pipelined version writes fdest with the result from the last
2738         stage of the pipeline.  */
2739#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
2740      /* Copy 3rd stage MRP to FSR.  */
2741      if (m_M[num_stages - 2  /* 1 */].stat.mrp)
2742         m_cregs[CR_FSR] |= 0x10000000;
2743      else
2744         m_cregs[CR_FSR] &= ~0x10000000;
2745#endif
2746
2747      if (m_M[num_stages - 1].stat.mrp)
2748         set_fregval_d (fdest, dbl_last_stage_contents);
2749      else
2750         set_fregval_s (fdest, sgl_last_stage_contents);
2751
2752      /* Now advance pipeline and write current calculation to
2753         first stage.  */
2754      if (num_stages == 3)
2755      {
2756         m_M[2] = m_M[1];
2757         m_M[1] = m_M[0];
2758      }
2759      else
2760         m_M[1]  = m_M[0];
2761
2762      if (res_prec)
2763      {
2764         m_M[0].val.d = dbl_tmp_dest;
2765         m_M[0].stat.mrp = 1;
2766      }
2767      else
2768      {
2769         m_M[0].val.s = sgl_tmp_dest;
2770         m_M[0].stat.mrp = 0;
2771      }
2772   }
2773}
2774
2775
2776/* Execute "fmlow.dd fsrc1,fsrc2,fdest" instruction.  */
2777void i860_cpu_device::insn_fmlow (UINT32 insn)
2778{
2779   UINT32 fsrc1 = get_fsrc1 (insn);
2780   UINT32 fsrc2 = get_fsrc2 (insn);
2781   UINT32 fdest = get_fdest (insn);
2782
2783   double v1 = get_fregval_d (fsrc1);
2784   double v2 = get_fregval_d (fsrc2);
2785   INT64 i1 = *(UINT64 *)&v1;
2786   INT64 i2 = *(UINT64 *)&v2;
2787   INT64 tmp = 0;
2788
2789   /* Only .dd is valid for fmlow.  */
2790   if ((insn & 0x180) != 0x180)
2791   {
2792      unrecog_opcode (m_pc, insn);
2793      return;
2794   }
2795
2796   /* The lower 32-bits are obvious.  What exactly goes in the upper
2797      bits?
2798      Technically, the upper-most 10 bits are undefined, but i'd like
2799      to be undefined in the same way as the real i860 if possible.  */
2800
2801   /* Keep lower 53 bits of multiply.  */
2802   tmp = i1 * i2;
2803   tmp &= 0x001fffffffffffffULL;
2804   tmp |= (i1 & 0x8000000000000000LL) ^ (i2 & 0x8000000000000000LL);
2805   set_fregval_d (fdest, *(double *)&tmp);
2806}
2807
2808
2809/* Execute [p]fadd.{ss,sd,dd} fsrc1,fsrc2,fdest (.ds disallowed above).  */
2810void i860_cpu_device::insn_fadd_sub (UINT32 insn)
2811{
2812   UINT32 fsrc1 = get_fsrc1 (insn);
2813   UINT32 fsrc2 = get_fsrc2 (insn);
2814   UINT32 fdest = get_fdest (insn);
2815   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
2816   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
2817   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
2818   int is_sub = insn & 1;           /* 1 = sub, 0 = add.  */
2819   double dbl_tmp_dest = 0.0;
2820   float sgl_tmp_dest = 0.0;
2821   double dbl_last_stage_contents = 0.0;
2822   float sgl_last_stage_contents = 0.0;
2823
2824   /* Check for invalid .ds combination.  */
2825   if ((insn & 0x180) == 0x100)
2826   {
2827      unrecog_opcode (m_pc, insn);
2828      return;
2829   }
2830
2831   /* For pipelined version, retrieve the contents of the last stage
2832      of the pipeline, whose precision is specified by the ARP bit
2833      of the stage's result-status bits.  There are always three stages
2834      for pfadd/pfsub.  */
2835   if (piped)
2836   {
2837      if (m_A[2].stat.arp)
2838         dbl_last_stage_contents = m_A[2].val.d;
2839      else
2840         sgl_last_stage_contents = m_A[2].val.s;
2841   }
2842
2843   /* Do the operation, being careful about source and result
2844      precision.  */
2845   if (src_prec)
2846   {
2847      double v1 = get_fregval_d (fsrc1);
2848      double v2 = get_fregval_d (fsrc2);
2849
2850      /* For pipelined add/sub, if fsrc1 is the same as fdest, then the last
2851         stage is bypassed to fsrc1 (rather than using the value in fsrc1).
2852         Likewise for fsrc2.  */
2853      if (piped && fdest != 0 && fsrc1 == fdest)
2854         v1 = dbl_last_stage_contents;
2855      if (piped && fdest != 0 && fsrc2 == fdest)
2856         v2 = dbl_last_stage_contents;
2857
2858      if (res_prec)
2859         dbl_tmp_dest = is_sub ? v1 - v2 : v1 + v2;
2860      else
2861         sgl_tmp_dest = is_sub ? (float)(v1 - v2) : (float)(v1 + v2);
2862   }
2863   else
2864   {
2865      float v1 = get_fregval_s (fsrc1);
2866      float v2 = get_fregval_s (fsrc2);
2867
2868      /* For pipelined add/sub, if fsrc1 is the same as fdest, then the last
2869         stage is bypassed to fsrc1 (rather than using the value in fsrc1).
2870         Likewise for fsrc2.  */
2871      if (piped && fdest != 0 && fsrc1 == fdest)
2872         v1 = sgl_last_stage_contents;
2873      if (piped && fdest != 0 && fsrc2 == fdest)
2874         v2 = sgl_last_stage_contents;
2875
2876      if (res_prec)
2877         dbl_tmp_dest = is_sub ? (double)(v1 - v2) : (double)(v1 + v2);
2878      else
2879         sgl_tmp_dest = is_sub ? v1 - v2 : v1 + v2;
2880   }
2881
2882   /* FIXME: Set result-status bits besides ARP. And copy to fsr from
2883             last stage.  */
2884   /* FIXME: Scalar version flows through all stages.  */
2885   if (!piped)
2886   {
2887      /* Scalar version writes the current calculation to the fdest
2888         register, with precision specified by the R bit.  */
2889      if (res_prec)
2890         set_fregval_d (fdest, dbl_tmp_dest);
2891      else
2892         set_fregval_s (fdest, sgl_tmp_dest);
2893   }
2894   else
2895   {
2896      /* Pipelined version writes fdest with the result from the last
2897         stage of the pipeline, with precision specified by the ARP
2898         bit of the stage's result-status bits.  */
2899#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
2900      /* Copy 3rd stage ARP to FSR.  */
2901      if (m_A[1 /* 2 */].stat.arp)
2902         m_cregs[CR_FSR] |= 0x20000000;
2903      else
2904         m_cregs[CR_FSR] &= ~0x20000000;
2905#endif
2906      if (m_A[2].stat.arp)  /* 3rd (last) stage.  */
2907         set_fregval_d (fdest, dbl_last_stage_contents);
2908      else
2909         set_fregval_s (fdest, sgl_last_stage_contents);
2910
2911      /* Now advance pipeline and write current calculation to
2912         first stage.  */
2913      m_A[2] = m_A[1];
2914      m_A[1] = m_A[0];
2915      if (res_prec)
2916      {
2917         m_A[0].val.d = dbl_tmp_dest;
2918         m_A[0].stat.arp = 1;
2919      }
2920      else
2921      {
2922         m_A[0].val.s = sgl_tmp_dest;
2923         m_A[0].stat.arp = 0;
2924      }
2925   }
2926}
2927
2928
2929/* Operand types for PFAM/PFMAM routine below.  */
2930enum {
2931   OP_SRC1     = 0,
2932   OP_SRC2     = 1,
2933   OP_KI       = 2,
2934   OP_KR       = 4,
2935   OP_T        = 8,
2936   OP_MPIPE    = 16,
2937   OP_APIPE    = 32,
2938   FLAGM       = 64   /* Indicates PFMAM uses M rather than A pipe result.  */
2939};
2940
2941/* A table to map DPC value to source operands.
2942
2943   The PFAM and PFMAM tables are nearly identical, and the only differences
2944   are that every time PFAM uses the A pipe, PFMAM uses the M pipe instead.
2945   So we only represent the PFAM table and use a special flag on any entry
2946   where the PFMAM table would use the M pipe rather than the A pipe.
2947   Also, entry 16 is not valid for PFMAM.  */
2948static const struct
2949{
2950   int M_unit_op1;
2951   int M_unit_op2;
2952   int A_unit_op1;
2953   int A_unit_op2;
2954   int T_loaded;
2955   int K_loaded;
2956} src_opers[] = {
2957   /* 0000 */ { OP_KR,   OP_SRC2,        OP_SRC1,        OP_MPIPE,       0, 0},
2958   /* 0001 */ { OP_KR,   OP_SRC2,        OP_T,           OP_MPIPE,       0, 1},
2959   /* 0010 */ { OP_KR,   OP_SRC2,        OP_SRC1,        OP_APIPE|FLAGM, 1, 0},
2960   /* 0011 */ { OP_KR,   OP_SRC2,        OP_T,           OP_APIPE|FLAGM, 1, 1},
2961   /* 0100 */ { OP_KI,   OP_SRC2,        OP_SRC1,        OP_MPIPE,       0, 0},
2962   /* 0101 */ { OP_KI,   OP_SRC2,        OP_T,           OP_MPIPE,       0, 1},
2963   /* 0110 */ { OP_KI,   OP_SRC2,        OP_SRC1,        OP_APIPE|FLAGM, 1, 0},
2964   /* 0111 */ { OP_KI,   OP_SRC2,        OP_T,           OP_APIPE|FLAGM, 1, 1},
2965   /* 1000 */ { OP_KR,   OP_APIPE|FLAGM, OP_SRC1,        OP_SRC2,        1, 0},
2966   /* 1001 */ { OP_SRC1, OP_SRC2,        OP_APIPE|FLAGM, OP_MPIPE,       0, 0},
2967   /* 1010 */ { OP_KR,   OP_APIPE|FLAGM, OP_SRC1,        OP_SRC2,        0, 0},
2968   /* 1011 */ { OP_SRC1, OP_SRC2,        OP_T,           OP_APIPE|FLAGM, 1, 0},
2969   /* 1100 */ { OP_KI,   OP_APIPE|FLAGM, OP_SRC1,        OP_SRC2,        1, 0},
2970   /* 1101 */ { OP_SRC1, OP_SRC2,        OP_T,           OP_MPIPE,       0, 0},
2971   /* 1110 */ { OP_KI,   OP_APIPE|FLAGM, OP_SRC1,        OP_SRC2,        0, 0},
2972   /* 1111 */ { OP_SRC1, OP_SRC2,        OP_T,           OP_APIPE|FLAGM, 0, 0}
2973};
2974
2975float i860_cpu_device::get_fval_from_optype_s (UINT32 insn, int optype)
2976{
2977   float retval = 0.0;
2978   UINT32 fsrc1 = get_fsrc1 (insn);
2979   UINT32 fsrc2 = get_fsrc2 (insn);
2980
2981   optype &= ~FLAGM;
2982   switch (optype)
2983   {
2984   case OP_SRC1:
2985      retval = get_fregval_s (fsrc1);
2986      break;
2987   case OP_SRC2:
2988      retval = get_fregval_s (fsrc2);
2989      break;
2990   case OP_KI:
2991      retval = m_KI.s;
2992      break;
2993   case OP_KR:
2994      retval = m_KR.s;
2995      break;
2996   case OP_T:
2997      retval = m_T.s;
2998      break;
2999   case OP_MPIPE:
3000      /* Last stage is 3rd stage for single precision input.  */
3001      retval = m_M[2].val.s;
3002      break;
3003   case OP_APIPE:
3004      retval = m_A[2].val.s;
3005      break;
3006   default:
3007      assert (0);
3008   }
3009
3010   return retval;
3011}
3012
3013
3014double i860_cpu_device::get_fval_from_optype_d (UINT32 insn, int optype)
3015{
3016   double retval = 0.0;
3017   UINT32 fsrc1 = get_fsrc1 (insn);
3018   UINT32 fsrc2 = get_fsrc2 (insn);
3019
3020   optype &= ~FLAGM;
3021   switch (optype)
3022   {
3023   case OP_SRC1:
3024      retval = get_fregval_d (fsrc1);
3025      break;
3026   case OP_SRC2:
3027      retval = get_fregval_d (fsrc2);
3028      break;
3029   case OP_KI:
3030      retval = m_KI.d;
3031      break;
3032   case OP_KR:
3033      retval = m_KR.d;
3034      break;
3035   case OP_T:
3036      retval = m_T.d;
3037      break;
3038   case OP_MPIPE:
3039      /* Last stage is 2nd stage for double precision input.  */
3040      retval = m_M[1].val.d;
3041      break;
3042   case OP_APIPE:
3043      retval = m_A[2].val.d;
3044      break;
3045   default:
3046      assert (0);
3047   }
3048
3049   return retval;
3050}
3051
3052
3053/* Execute pf[m]{a,s}m.{ss,sd,dd} fsrc1,fsrc2,fdest (FP dual ops).
3054
3055   Since these are always pipelined, the P bit is used to distinguish
3056   family pfam (P=1) from family pfmam (P=0), and the lower 4 bits
3057   of the extended opcode is the DPC.
3058
3059   Note also that the S and R bits are slightly different than normal
3060   floating point operations.  The S bit denotes the precision of the
3061   multiplication source, while the R bit denotes the precision of
3062   the addition source as well as precision of all results.  */
3063void i860_cpu_device::insn_dualop (UINT32 insn)
3064{
3065   UINT32 fsrc1 = get_fsrc1 (insn);
3066   UINT32 fsrc2 = get_fsrc2 (insn);
3067   UINT32 fdest = get_fdest (insn);
3068   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3069   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3070   int is_pfam = insn & 0x400;      /* 1 = pfam, 0 = pfmam.  */
3071   int is_sub = insn & 0x10;        /* 1 = pf[m]sm, 0 = pf[m]am.  */
3072   double dbl_tmp_dest_mul = 0.0;
3073   float sgl_tmp_dest_mul = 0.0;
3074   double dbl_tmp_dest_add = 0.0;
3075   float sgl_tmp_dest_add = 0.0;
3076   double dbl_last_Mstage_contents = 0.0;
3077   float sgl_last_Mstage_contents = 0.0;
3078   double dbl_last_Astage_contents = 0.0;
3079   float sgl_last_Astage_contents = 0.0;
3080   int num_mul_stages = src_prec ? 2 : 3;
3081
3082   int dpc = insn & 0xf;
3083   int M_unit_op1 = src_opers[dpc].M_unit_op1;
3084   int M_unit_op2 = src_opers[dpc].M_unit_op2;
3085   int A_unit_op1 = src_opers[dpc].A_unit_op1;
3086   int A_unit_op2 = src_opers[dpc].A_unit_op2;
3087   int T_loaded = src_opers[dpc].T_loaded;
3088   int K_loaded = src_opers[dpc].K_loaded;
3089
3090   /* Check for invalid .ds combination.  */
3091   if ((insn & 0x180) == 0x100)
3092   {
3093      unrecog_opcode (m_pc, insn);
3094      return;
3095   }
3096
3097   if (is_pfam == 0)
3098   {
3099      /* Check for invalid DPC combination 16 for PFMAM.  */
3100      if (dpc == 16)
3101      {
3102         unrecog_opcode (m_pc, insn);
3103         return;
3104      }
3105
3106      /* PFMAM table adjustments (M_unit_op1 is never a pipe stage,
3107         so no adjustment made for it).   */
3108      M_unit_op2 = (M_unit_op2 & FLAGM) ? OP_MPIPE : M_unit_op2;
3109      A_unit_op1 = (A_unit_op1 & FLAGM) ? OP_MPIPE : A_unit_op1;
3110      A_unit_op2 = (A_unit_op2 & FLAGM) ? OP_MPIPE : A_unit_op2;
3111   }
3112
3113   /* FIXME: Check for fsrc1/fdest overlap for some mul DPC combinations.  */
3114
3115   /* Retrieve the contents of the last stage of the multiplier pipeline,
3116      whose precision is specified by the MRP bit of the stage's result-
3117      status bits.  Note for multiply, the number of stages is determined
3118      by the source precision of the current operation.  */
3119   if (m_M[num_mul_stages - 1].stat.mrp)
3120      dbl_last_Mstage_contents = m_M[num_mul_stages - 1].val.d;
3121   else
3122      sgl_last_Mstage_contents = m_M[num_mul_stages - 1].val.s;
3123
3124   /* Similarly, retrieve the last stage of the adder pipe.  */
3125   if (m_A[2].stat.arp)
3126      dbl_last_Astage_contents = m_A[2].val.d;
3127   else
3128      sgl_last_Astage_contents = m_A[2].val.s;
3129
3130   /* Do the mul operation, being careful about source and result
3131      precision.  */
3132   if (src_prec)
3133   {
3134      double v1 = get_fval_from_optype_d (insn, M_unit_op1);
3135      double v2 = get_fval_from_optype_d (insn, M_unit_op2);
3136
3137      /* For mul, if fsrc2 is the same as fdest, then the last stage
3138         is bypassed to fsrc2 (rather than using the value in fsrc2).
3139         This bypass is not available for fsrc1, and is undefined behavior.  */
3140      if (0 && M_unit_op1 == OP_SRC1 && fdest != 0 && fsrc1 == fdest)
3141         v1 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents;
3142      if (M_unit_op2 == OP_SRC2 && fdest != 0 && fsrc2 == fdest)
3143         v2 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents;
3144
3145      if (res_prec)
3146         dbl_tmp_dest_mul = v1 * v2;
3147      else
3148         sgl_tmp_dest_mul = (float)(v1 * v2);
3149   }
3150   else
3151   {
3152      float v1 = get_fval_from_optype_s (insn, M_unit_op1);
3153      float v2 = get_fval_from_optype_s (insn, M_unit_op2);
3154
3155      /* For mul, if fsrc2 is the same as fdest, then the last stage
3156         is bypassed to fsrc2 (rather than using the value in fsrc2).
3157         This bypass is not available for fsrc1, and is undefined behavior.  */
3158      if (0 && M_unit_op1 == OP_SRC1 && fdest != 0 && fsrc1 == fdest)
3159         v1 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents;
3160      if (M_unit_op2 == OP_SRC2 && fdest != 0 && fsrc2 == fdest)
3161         v2 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents;
3162
3163      if (res_prec)
3164         dbl_tmp_dest_mul = (double)(v1 * v2);
3165      else
3166         sgl_tmp_dest_mul = v1 * v2;
3167   }
3168
3169   /* Do the add operation, being careful about source and result
3170      precision.  Remember, the R bit indicates source and result precision
3171      here.  */
3172   if (res_prec)
3173   {
3174      double v1 = get_fval_from_optype_d (insn, A_unit_op1);
3175      double v2 = get_fval_from_optype_d (insn, A_unit_op2);
3176
3177      /* For add/sub, if fsrc1 is the same as fdest, then the last stage
3178         is bypassed to fsrc1 (rather than using the value in fsrc1).
3179         Likewise for fsrc2.  */
3180      if (A_unit_op1 == OP_SRC1 && fdest != 0 && fsrc1 == fdest)
3181         v1 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents;
3182      if (A_unit_op2 == OP_SRC2 && fdest != 0 && fsrc2 == fdest)
3183         v2 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents;
3184
3185      if (res_prec)
3186         dbl_tmp_dest_add = is_sub ? v1 - v2 : v1 + v2;
3187      else
3188         sgl_tmp_dest_add = is_sub ? (float)(v1 - v2) : (float)(v1 + v2);
3189   }
3190   else
3191   {
3192      float v1 = get_fval_from_optype_s (insn, A_unit_op1);
3193      float v2 = get_fval_from_optype_s (insn, A_unit_op2);
3194
3195      /* For add/sub, if fsrc1 is the same as fdest, then the last stage
3196         is bypassed to fsrc1 (rather than using the value in fsrc1).
3197         Likewise for fsrc2.  */
3198      if (A_unit_op1 == OP_SRC1 && fdest != 0 && fsrc1 == fdest)
3199         v1 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents;
3200      if (A_unit_op2 == OP_SRC2 && fdest != 0 && fsrc2 == fdest)
3201         v2 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents;
3202
3203      if (res_prec)
3204         dbl_tmp_dest_add = is_sub ? (double)(v1 - v2) : (double)(v1 + v2);
3205      else
3206         sgl_tmp_dest_add = is_sub ? v1 - v2 : v1 + v2;
3207   }
3208
3209   /* If necessary, load T.  */
3210   if (T_loaded)
3211   {
3212      /* T is loaded from the result of the last stage of the multiplier.  */
3213      if (m_M[num_mul_stages - 1].stat.mrp)
3214         m_T.d = dbl_last_Mstage_contents;
3215      else
3216         m_T.s = sgl_last_Mstage_contents;
3217   }
3218
3219   /* If necessary, load KR or KI.  */
3220   if (K_loaded)
3221   {
3222      /* KI or KR is loaded from the first register input.  */
3223      if (M_unit_op1 == OP_KI)
3224      {
3225         if (src_prec)
3226            m_KI.d = get_fregval_d (fsrc1);
3227         else
3228            m_KI.s  = get_fregval_s (fsrc1);
3229      }
3230      else if (M_unit_op1 == OP_KR)
3231      {
3232         if (src_prec)
3233            m_KR.d = get_fregval_d (fsrc1);
3234         else
3235            m_KR.s  = get_fregval_s (fsrc1);
3236      }
3237      else
3238         assert (0);
3239   }
3240
3241   /* Now update fdest (either from adder pipe or multiplier pipe,
3242      depending on whether the instruction is pfam or pfmam).  */
3243   if (is_pfam)
3244   {
3245      /* Update fdest with the result from the last stage of the
3246         adder pipeline, with precision specified by the ARP
3247         bit of the stage's result-status bits.  */
3248      if (m_A[2].stat.arp)
3249         set_fregval_d (fdest, dbl_last_Astage_contents);
3250      else
3251         set_fregval_s (fdest, sgl_last_Astage_contents);
3252   }
3253   else
3254   {
3255      /* Update fdest with the result from the last stage of the
3256         multiplier pipeline, with precision specified by the MRP
3257         bit of the stage's result-status bits.  */
3258      if (m_M[num_mul_stages - 1].stat.mrp)
3259         set_fregval_d (fdest, dbl_last_Mstage_contents);
3260      else
3261         set_fregval_s (fdest, sgl_last_Mstage_contents);
3262   }
3263
3264   /* FIXME: Set result-status bits besides MRP. And copy to fsr from
3265             last stage.  */
3266   /* FIXME: Mixed precision (only weird for pfmul).  */
3267#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3268   /* Copy 3rd stage MRP to FSR.  */
3269   if (m_M[num_mul_stages - 2  /* 1 */].stat.mrp)
3270      m_cregs[CR_FSR] |= 0x10000000;
3271   else
3272      m_cregs[CR_FSR] &= ~0x10000000;
3273#endif
3274
3275   /* Now advance multiplier pipeline and write current calculation to
3276      first stage.  */
3277   if (num_mul_stages == 3)
3278   {
3279      m_M[2] = m_M[1];
3280      m_M[1] = m_M[0];
3281   }
3282   else
3283      m_M[1]  = m_M[0];
3284
3285   if (res_prec)
3286   {
3287      m_M[0].val.d = dbl_tmp_dest_mul;
3288      m_M[0].stat.mrp = 1;
3289   }
3290   else
3291   {
3292      m_M[0].val.s = sgl_tmp_dest_mul;
3293      m_M[0].stat.mrp = 0;
3294   }
3295
3296   /* FIXME: Set result-status bits besides ARP. And copy to fsr from
3297             last stage.  */
3298#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3299   /* Copy 3rd stage ARP to FSR.  */
3300   if (m_A[1 /* 2 */].stat.arp)
3301      m_cregs[CR_FSR] |= 0x20000000;
3302   else
3303      m_cregs[CR_FSR] &= ~0x20000000;
3304#endif
3305
3306   /* Now advance adder pipeline and write current calculation to
3307      first stage.  */
3308   m_A[2] = m_A[1];
3309   m_A[1] = m_A[0];
3310   if (res_prec)
3311   {
3312      m_A[0].val.d = dbl_tmp_dest_add;
3313      m_A[0].stat.arp = 1;
3314   }
3315   else
3316   {
3317      m_A[0].val.s = sgl_tmp_dest_add;
3318      m_A[0].stat.arp = 0;
3319   }
3320}
3321
3322
3323/* Execute frcp.{ss,sd,dd} fsrc2,fdest (.ds disallowed above).  */
3324void i860_cpu_device::insn_frcp (UINT32 insn)
3325{
3326   UINT32 fsrc2 = get_fsrc2 (insn);
3327   UINT32 fdest = get_fdest (insn);
3328   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3329   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3330
3331   /* Do the operation, being careful about source and result
3332      precision.  */
3333   if (src_prec)
3334   {
3335      double v = get_fregval_d (fsrc2);
3336      double res;
3337      if (v == (double)0.0)
3338      {
3339         /* Generate source-exception trap if fsrc2 is 0.  */
3340         if (0 /* && GET_FSR_FTE () */)
3341         {
3342            SET_PSR_FT (1);
3343            SET_FSR_SE (1);
3344            m_pending_trap = GET_FSR_FTE ();
3345         }
3346         /* Set fdest to INF or some other exceptional value here?  */
3347      }
3348      else
3349      {
3350         /* Real i860 isn't a precise as a real divide, but this should
3351            be okay.  */
3352         SET_FSR_SE (0);
3353         *((UINT64 *)&v) &= 0xfffff00000000000ULL;
3354         res = (double)1.0/v;
3355         *((UINT64 *)&res) &= 0xfffff00000000000ULL;
3356         if (res_prec)
3357            set_fregval_d (fdest, res);
3358         else
3359            set_fregval_s (fdest, (float)res);
3360      }
3361   }
3362   else
3363   {
3364      float v = get_fregval_s (fsrc2);
3365      float res;
3366      if (v == 0.0)
3367      {
3368         /* Generate source-exception trap if fsrc2 is 0.  */
3369         if (0 /* GET_FSR_FTE () */)
3370         {
3371            SET_PSR_FT (1);
3372            SET_FSR_SE (1);
3373            m_pending_trap = GET_FSR_FTE ();
3374         }
3375         /* Set fdest to INF or some other exceptional value here?  */
3376      }
3377      else
3378      {
3379         /* Real i860 isn't a precise as a real divide, but this should
3380            be okay.  */
3381         SET_FSR_SE (0);
3382         *((UINT32 *)&v) &= 0xffff8000;
3383         res = (float)1.0/v;
3384         *((UINT32 *)&res) &= 0xffff8000;
3385         if (res_prec)
3386            set_fregval_d (fdest, (double)res);
3387         else
3388            set_fregval_s (fdest, res);
3389      }
3390   }
3391}
3392
3393
3394/* Execute frsqr.{ss,sd,dd} fsrc2,fdest (.ds disallowed above).  */
3395void i860_cpu_device::insn_frsqr (UINT32 insn)
3396{
3397   UINT32 fsrc2 = get_fsrc2 (insn);
3398   UINT32 fdest = get_fdest (insn);
3399   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3400   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3401
3402   /* Check for invalid .ds combination.  */
3403   if ((insn & 0x180) == 0x100)
3404   {
3405      unrecog_opcode (m_pc, insn);
3406      return;
3407   }
3408
3409   /* Check for invalid .ds combination.  */
3410   if ((insn & 0x180) == 0x100)
3411   {
3412      unrecog_opcode (m_pc, insn);
3413      return;
3414   }
3415
3416   /* Do the operation, being careful about source and result
3417      precision.  */
3418   if (src_prec)
3419   {
3420      double v = get_fregval_d (fsrc2);
3421      double res;
3422      if (v == 0.0 || v < 0.0)
3423      {
3424         /* Generate source-exception trap if fsrc2 is 0 or negative.  */
3425         if (0 /* GET_FSR_FTE () */)
3426         {
3427            SET_PSR_FT (1);
3428            SET_FSR_SE (1);
3429            m_pending_trap = GET_FSR_FTE ();
3430         }
3431         /* Set fdest to INF or some other exceptional value here?  */
3432      }
3433      else
3434      {
3435         SET_FSR_SE (0);
3436         *((UINT64 *)&v) &= 0xfffff00000000000ULL;
3437         res = (double)1.0/sqrt (v);
3438         *((UINT64 *)&res) &= 0xfffff00000000000ULL;
3439         if (res_prec)
3440            set_fregval_d (fdest, res);
3441         else
3442            set_fregval_s (fdest, (float)res);
3443      }
3444   }
3445   else
3446   {
3447      float v = get_fregval_s (fsrc2);
3448      float res;
3449      if (v == 0.0 || v < 0.0)
3450      {
3451         /* Generate source-exception trap if fsrc2 is 0 or negative.  */
3452         if (0 /* GET_FSR_FTE () */)
3453         {
3454            SET_PSR_FT (1);
3455            SET_FSR_SE (1);
3456            m_pending_trap = GET_FSR_FTE ();
3457         }
3458         /* Set fdest to INF or some other exceptional value here?  */
3459      }
3460      else
3461      {
3462         SET_FSR_SE (0);
3463         *((UINT32 *)&v) &= 0xffff8000;
3464         res = (float)1.0/sqrt (v);
3465         *((UINT32 *)&res) &= 0xffff8000;
3466         if (res_prec)
3467            set_fregval_d (fdest, (double)res);
3468         else
3469            set_fregval_s (fdest, res);
3470      }
3471   }
3472}
3473
3474
3475/* Execute fxfr fsrc1,idest.  */
3476void i860_cpu_device::insn_fxfr (UINT32 insn)
3477{
3478   UINT32 fsrc1 = get_fsrc1 (insn);
3479   UINT32 idest = get_idest (insn);
3480   float fv = 0;
3481
3482   /* This is a bit-pattern transfer, not a conversion.  */
3483   fv = get_fregval_s (fsrc1);
3484   set_iregval (idest, *(UINT32 *)&fv);
3485}
3486
3487
3488/* Execute [p]ftrunc.{ss,sd,dd} fsrc1,idest.  */
3489/* FIXME: Is .ss really a valid combination?  On the one hand,
3490   the programmer's reference (1990) lists ftrunc.p where .p
3491   is any of {ss,sd,dd}.  On the other hand, a paragraph on the
3492   same page states that [p]ftrunc must specify double-precision
3493   results.  Inconsistent.
3494   Update: The vendor SVR4 assembler does not accept .ss combination,
3495   so the latter sentence above appears to be the correct way.  */
3496void i860_cpu_device::insn_ftrunc (UINT32 insn)
3497{
3498   UINT32 fsrc1 = get_fsrc1 (insn);
3499   UINT32 fdest = get_fdest (insn);
3500   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3501   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3502   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3503
3504   /* Check for invalid .ds or .ss combinations.  */
3505   if ((insn & 0x080) == 0)
3506   {
3507      unrecog_opcode (m_pc, insn);
3508      return;
3509   }
3510
3511   /* Do the operation, being careful about source and result
3512      precision.  Operation: fdest = integer part of fsrc1 in
3513      lower 32-bits.  */
3514   if (src_prec)
3515   {
3516      double v1 = get_fregval_d (fsrc1);
3517      INT32 iv = (INT32)v1;
3518      /* We always write a single, since the lower 32-bits of fdest
3519         get the result (and the even numbered reg is the lower).  */
3520      set_fregval_s (fdest, *(float *)&iv);
3521   }
3522   else
3523   {
3524      float v1 = get_fregval_s (fsrc1);
3525      INT32 iv = (INT32)v1;
3526      /* We always write a single, since the lower 32-bits of fdest
3527         get the result (and the even numbered reg is the lower).  */
3528      set_fregval_s (fdest, *(float *)&iv);
3529   }
3530
3531   /* FIXME: Handle updating of pipestages for pftrunc.  */
3532   /* Includes looking at ARP (add result precision.) */
3533   if (piped)
3534   {
3535      fprintf (stderr, "insn_ftrunc: FIXME: pipelined not functional yet.\n");
3536      if (res_prec)
3537         set_fregval_d (fdest, 0.0);
3538      else
3539         set_fregval_s (fdest, 0.0);
3540   }
3541}
3542
3543
3544/* Execute [p]famov.{ss,sd,ds,dd} fsrc1,fdest.  */
3545void i860_cpu_device::insn_famov (UINT32 insn)
3546{
3547   UINT32 fsrc1 = get_fsrc1 (insn);
3548   UINT32 fdest = get_fdest (insn);
3549   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3550   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3551   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3552   double dbl_tmp_dest = 0.0;
3553   double sgl_tmp_dest = 0.0;
3554
3555   /* Do the operation, being careful about source and result
3556      precision.  */
3557   if (src_prec)
3558   {
3559      double v1 = get_fregval_d (fsrc1);
3560      if (res_prec)
3561         dbl_tmp_dest = v1;
3562      else
3563         sgl_tmp_dest = (float)v1;
3564   }
3565   else
3566   {
3567      float v1 = get_fregval_s (fsrc1);
3568      if (res_prec)
3569         dbl_tmp_dest = (double)v1;
3570      else
3571         sgl_tmp_dest = v1;
3572   }
3573
3574   /* FIXME: Set result-status bits besides ARP. And copy to fsr from
3575             last stage.  */
3576   /* FIXME: Scalar version flows through all stages.  */
3577   if (!piped)
3578   {
3579      /* Scalar version writes the current calculation to the fdest
3580         register, with precision specified by the R bit.  */
3581      if (res_prec)
3582         set_fregval_d (fdest, dbl_tmp_dest);
3583      else
3584         set_fregval_s (fdest, sgl_tmp_dest);
3585   }
3586   else
3587   {
3588      /* Pipelined version writes fdest with the result from the last
3589         stage of the pipeline, with precision specified by the ARP
3590         bit of the stage's result-status bits.  */
3591#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3592      /* Copy 3rd stage ARP to FSR.  */
3593      if (m_A[1 /* 2 */].stat.arp)
3594         m_cregs[CR_FSR] |= 0x20000000;
3595      else
3596         m_cregs[CR_FSR] &= ~0x20000000;
3597#endif
3598      if (m_A[2].stat.arp)  /* 3rd (last) stage.  */
3599         set_fregval_d (fdest, m_A[2].val.d);
3600      else
3601         set_fregval_s (fdest, m_A[2].val.s);
3602
3603      /* Now advance pipeline and write current calculation to
3604         first stage.  */
3605      m_A[2] = m_A[1];
3606      m_A[1] = m_A[0];
3607      if (res_prec)
3608      {
3609         m_A[0].val.d = dbl_tmp_dest;
3610         m_A[0].stat.arp = 1;
3611      }
3612      else
3613      {
3614         m_A[0].val.s = sgl_tmp_dest;
3615         m_A[0].stat.arp = 0;
3616      }
3617   }
3618}
3619
3620
3621/* Execute [p]fiadd/sub.{ss,dd} fsrc1,fsrc2,fdest.  */
3622void i860_cpu_device::insn_fiadd_sub (UINT32 insn)
3623{
3624   UINT32 fsrc1 = get_fsrc1 (insn);
3625   UINT32 fsrc2 = get_fsrc2 (insn);
3626   UINT32 fdest = get_fdest (insn);
3627   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3628   int res_prec = insn & 0x080;     /* 1 = double, 0 = single.  */
3629   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3630   int is_sub = insn & 0x4;         /* 1 = sub, 0 = add.  */
3631   double dbl_tmp_dest = 0.0;
3632   float sgl_tmp_dest = 0.0;
3633
3634   /* Check for invalid .ds and .sd combinations.  */
3635   if ((insn & 0x180) == 0x100
3636      || (insn & 0x180) == 0x080)
3637   {
3638      unrecog_opcode (m_pc, insn);
3639      return;
3640   }
3641
3642   /* Do the operation, being careful about source and result
3643      precision.  */
3644   if (src_prec)
3645   {
3646      double v1 = get_fregval_d (fsrc1);
3647      double v2 = get_fregval_d (fsrc2);
3648      UINT64 iv1 = *(UINT64 *)&v1;
3649      UINT64 iv2 = *(UINT64 *)&v2;
3650      UINT64 r;
3651      if (is_sub)
3652         r = iv1 - iv2;
3653      else
3654         r = iv1 + iv2;
3655      if (res_prec)
3656         dbl_tmp_dest = *(double *)&r;
3657      else
3658         assert (0);    /* .ds not allowed.  */
3659   }
3660   else
3661   {
3662      float v1 = get_fregval_s (fsrc1);
3663      float v2 = get_fregval_s (fsrc2);
3664      UINT64 iv1 = (UINT64)(*(UINT32 *)&v1);
3665      UINT64 iv2 = (UINT64)(*(UINT32 *)&v2);
3666      UINT32 r;
3667      if (is_sub)
3668         r = (UINT32)(iv1 - iv2);
3669      else
3670         r = (UINT32)(iv1 + iv2);
3671      if (res_prec)
3672         assert (0);    /* .sd not allowed.  */
3673      else
3674         sgl_tmp_dest = *(float *)&r;
3675   }
3676
3677   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
3678   /* FIXME: Scalar version flows through all stages.  */
3679   if (!piped)
3680   {
3681      /* Scalar version writes the current calculation to the fdest
3682         register, with precision specified by the R bit.  */
3683      if (res_prec)
3684         set_fregval_d (fdest, dbl_tmp_dest);
3685      else
3686         set_fregval_s (fdest, sgl_tmp_dest);
3687   }
3688   else
3689   {
3690      /* Pipelined version writes fdest with the result from the last
3691         stage of the pipeline, with precision specified by the IRP
3692         bit of the stage's result-status bits.  */
3693#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3694      /* Copy stage IRP to FSR.  */
3695      if (res_prec)
3696         m_cregs[CR_FSR] |= 0x08000000;
3697      else
3698         m_cregs[CR_FSR] &= ~0x08000000;
3699#endif
3700      if (m_G.stat.irp)   /* 1st (and last) stage.  */
3701         set_fregval_d (fdest, m_G.val.d);
3702      else
3703         set_fregval_s (fdest, m_G.val.s);
3704
3705      /* Now write current calculation to first and only stage.  */
3706      if (res_prec)
3707      {
3708         m_G.val.d = dbl_tmp_dest;
3709         m_G.stat.irp = 1;
3710      }
3711      else
3712      {
3713         m_G.val.s = sgl_tmp_dest;
3714         m_G.stat.irp = 0;
3715      }
3716   }
3717}
3718
3719
3720/* Execute pf{gt,le,eq}.{ss,dd} fsrc1,fsrc2,fdest.
3721   Opcode pfgt has R bit cleared; pfle has R bit set.  */
3722void i860_cpu_device::insn_fcmp (UINT32 insn)
3723{
3724   UINT32 fsrc1 = get_fsrc1 (insn);
3725   UINT32 fsrc2 = get_fsrc2 (insn);
3726   UINT32 fdest = get_fdest (insn);
3727   int src_prec = insn & 0x100;     /* 1 = double, 0 = single.  */
3728   double dbl_tmp_dest = 0.0;
3729   double sgl_tmp_dest = 0.0;
3730   /* int is_eq = insn & 1; */
3731   int is_gt = ((insn & 0x81) == 0x00);
3732   int is_le = ((insn & 0x81) == 0x80);
3733
3734   /* Do the operation.  Source and result precision must be the same.
3735        pfgt: CC set     if fsrc1 > fsrc2, else cleared.
3736        pfle: CC cleared if fsrc1 <= fsrc2, else set.
3737        pfeq: CC set     if fsrc1 = fsrc2, else cleared.
3738
3739      Note that the compares write an undefined (but non-exceptional)
3740      result into the first stage of the adder pipeline.  We'll model
3741      this by just pushing in dbl_ or sgl_tmp_dest which equal 0.0.  */
3742   if (src_prec)
3743   {
3744      double v1 = get_fregval_d (fsrc1);
3745      double v2 = get_fregval_d (fsrc2);
3746      if (is_gt)                /* gt.  */
3747         SET_PSR_CC (v1 > v2 ? 1 : 0);
3748      else if (is_le)           /* le.  */
3749         SET_PSR_CC (v1 <= v2 ? 0 : 1);
3750      else                      /* eq.  */
3751         SET_PSR_CC (v1 == v2 ? 1 : 0);
3752   }
3753   else
3754   {
3755      float v1 = get_fregval_s (fsrc1);
3756      float v2 = get_fregval_s (fsrc2);
3757      if (is_gt)                /* gt.  */
3758         SET_PSR_CC (v1 > v2 ? 1 : 0);
3759      else if (is_le)           /* le.  */
3760         SET_PSR_CC (v1 <= v2 ? 0 : 1);
3761      else                      /* eq.  */
3762         SET_PSR_CC (v1 == v2 ? 1 : 0);
3763   }
3764
3765   /* FIXME: Set result-status bits besides ARP. And copy to fsr from
3766             last stage.  */
3767   /* These write fdest with the result from the last
3768      stage of the pipeline, with precision specified by the ARP
3769      bit of the stage's result-status bits.  */
3770#if 1 /* FIXME: WIP on FSR update.  This may not be correct.  */
3771   /* Copy 3rd stage ARP to FSR.  */
3772   if (m_A[1 /* 2 */].stat.arp)
3773      m_cregs[CR_FSR] |= 0x20000000;
3774   else
3775      m_cregs[CR_FSR] &= ~0x20000000;
3776#endif
3777   if (m_A[2].stat.arp)  /* 3rd (last) stage.  */
3778      set_fregval_d (fdest, m_A[2].val.d);
3779   else
3780      set_fregval_s (fdest, m_A[2].val.s);
3781
3782   /* Now advance pipeline and write current calculation to
3783      first stage.  */
3784   m_A[2] = m_A[1];
3785   m_A[1] = m_A[0];
3786   if (src_prec)
3787   {
3788      m_A[0].val.d = dbl_tmp_dest;
3789      m_A[0].stat.arp = 1;
3790   }
3791   else
3792   {
3793      m_A[0].val.s = sgl_tmp_dest;
3794      m_A[0].stat.arp = 0;
3795   }
3796}
3797
3798
3799/* Execute [p]fzchk{l,s} fsrc1,fsrc2,fdest.
3800   The fzchk instructions have S and R bits set.  */
3801void i860_cpu_device::insn_fzchk (UINT32 insn)
3802{
3803   UINT32 fsrc1 = get_fsrc1 (insn);
3804   UINT32 fsrc2 = get_fsrc2 (insn);
3805   UINT32 fdest = get_fdest (insn);
3806   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3807   int is_fzchks = insn & 8;        /* 1 = fzchks, 0 = fzchkl.  */
3808   double dbl_tmp_dest = 0.0;
3809   int i;
3810   double v1 = get_fregval_d (fsrc1);
3811   double v2 = get_fregval_d (fsrc2);
3812   UINT64 iv1 = *(UINT64 *)&v1;
3813   UINT64 iv2 = *(UINT64 *)&v2;
3814   UINT64 r = 0;
3815   char pm = GET_PSR_PM ();
3816
3817   /* Check for S and R bits set.  */
3818   if ((insn & 0x180) != 0x180)
3819   {
3820      unrecog_opcode (m_pc, insn);
3821      return;
3822   }
3823
3824   /* Do the operation.  The fzchks version operates in parallel on
3825      four 16-bit pixels, while the fzchkl operates on two 32-bit
3826      pixels (pixels are unsigned ordinals in this context).  */
3827   if (is_fzchks)
3828   {
3829      pm = (pm >> 4) & 0x0f;
3830      for (i = 3; i >= 0; i--)
3831      {
3832         UINT16 ps1 = (iv1 >> (i * 16)) & 0xffff;
3833         UINT16 ps2 = (iv2 >> (i * 16)) & 0xffff;
3834         if (ps2 <= ps1)
3835         {
3836            r |= ((UINT64)ps2 << (i * 16));
3837            pm |= (1 << (7 - (3 - i)));
3838         }
3839         else
3840         {
3841            r |= ((UINT64)ps1 << (i * 16));
3842            pm &= ~(1 << (7 - (3 - i)));
3843         }
3844      }
3845   }
3846   else
3847   {
3848      pm = (pm >> 2) & 0x3f;
3849      for (i = 1; i >= 0; i--)
3850      {
3851         UINT32 ps1 = (iv1 >> (i * 32)) & 0xffffffff;
3852         UINT32 ps2 = (iv2 >> (i * 32)) & 0xffffffff;
3853         if (ps2 <= ps1)
3854         {
3855            r |= ((UINT64)ps2 << (i * 32));
3856            pm |= (1 << (7 - (1 - i)));
3857         }
3858         else
3859         {
3860            r |= ((UINT64)ps1 << (i * 32));
3861            pm &= ~(1 << (7 - (1 - i)));
3862         }
3863      }
3864   }
3865
3866   dbl_tmp_dest = *(double *)&r;
3867   SET_PSR_PM (pm);
3868   m_merge = 0;
3869
3870   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
3871   /* FIXME: Scalar version flows through all stages.  */
3872   if (!piped)
3873   {
3874      /* Scalar version writes the current calculation to the fdest
3875         register, always with double precision.  */
3876      set_fregval_d (fdest, dbl_tmp_dest);
3877   }
3878   else
3879   {
3880      /* Pipelined version writes fdest with the result from the last
3881         stage of the pipeline, with precision specified by the IRP
3882         bit of the stage's result-status bits.  */
3883      if (m_G.stat.irp)   /* 1st (and last) stage.  */
3884         set_fregval_d (fdest, m_G.val.d);
3885      else
3886         set_fregval_s (fdest, m_G.val.s);
3887
3888      /* Now write current calculation to first and only stage.  */
3889      m_G.val.d = dbl_tmp_dest;
3890      m_G.stat.irp = 1;
3891   }
3892}
3893
3894
3895/* Execute [p]form.dd fsrc1,fdest.
3896   The form.dd instructions have S and R bits set.  */
3897void i860_cpu_device::insn_form (UINT32 insn)
3898{
3899   UINT32 fsrc1 = get_fsrc1 (insn);
3900   UINT32 fdest = get_fdest (insn);
3901   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3902   double dbl_tmp_dest = 0.0;
3903   double v1 = get_fregval_d (fsrc1);
3904   UINT64 iv1 = *(UINT64 *)&v1;
3905
3906   /* Check for S and R bits set.  */
3907   if ((insn & 0x180) != 0x180)
3908   {
3909      unrecog_opcode (m_pc, insn);
3910      return;
3911   }
3912
3913   iv1 |= m_merge;
3914   dbl_tmp_dest = *(double *)&iv1;
3915   m_merge = 0;
3916
3917   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
3918   /* FIXME: Scalar version flows through all stages.  */
3919   if (!piped)
3920   {
3921      /* Scalar version writes the current calculation to the fdest
3922         register, always with double precision.  */
3923      set_fregval_d (fdest, dbl_tmp_dest);
3924   }
3925   else
3926   {
3927      /* Pipelined version writes fdest with the result from the last
3928         stage of the pipeline, with precision specified by the IRP
3929         bit of the stage's result-status bits.  */
3930      if (m_G.stat.irp)   /* 1st (and last) stage.  */
3931         set_fregval_d (fdest, m_G.val.d);
3932      else
3933         set_fregval_s (fdest, m_G.val.s);
3934
3935      /* Now write current calculation to first and only stage.  */
3936      m_G.val.d = dbl_tmp_dest;
3937      m_G.stat.irp = 1;
3938   }
3939}
3940
3941
3942/* Execute [p]faddp fsrc1,fsrc2,fdest.  */
3943void i860_cpu_device::insn_faddp (UINT32 insn)
3944{
3945   UINT32 fsrc1 = get_fsrc1 (insn);
3946   UINT32 fsrc2 = get_fsrc2 (insn);
3947   UINT32 fdest = get_fdest (insn);
3948   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
3949   double dbl_tmp_dest = 0.0;
3950   double v1 = get_fregval_d (fsrc1);
3951   double v2 = get_fregval_d (fsrc2);
3952   UINT64 iv1 = *(UINT64 *)&v1;
3953   UINT64 iv2 = *(UINT64 *)&v2;
3954   UINT64 r = 0;
3955   int ps = GET_PSR_PS ();
3956
3957   r = iv1 + iv2;
3958   dbl_tmp_dest = *(double *)&r;
3959
3960   /* Update the merge register depending on the pixel size.
3961      PS: 0 = 8 bits, 1 = 16 bits, 2 = 32-bits.  */
3962   if (ps == 0)
3963   {
3964      m_merge = ((m_merge >> 8) & ~0xff00ff00ff00ff00ULL);
3965      m_merge |= (r & 0xff00ff00ff00ff00ULL);
3966   }
3967   else if (ps == 1)
3968   {
3969      m_merge = ((m_merge >> 6) & ~0xfc00fc00fc00fc00ULL);
3970      m_merge |= (r & 0xfc00fc00fc00fc00ULL);
3971   }
3972   else if (ps == 2)
3973   {
3974      m_merge = ((m_merge >> 8) & ~0xff000000ff000000ULL);
3975      m_merge |= (r & 0xff000000ff000000ULL);
3976   }
3977#ifdef TRACE_UNDEFINED_I860
3978   else
3979      fprintf (stderr, "insn_faddp: Undefined i860XR behavior, invalid value %d for pixel size.\n", ps);
3980#endif
3981
3982   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
3983   /* FIXME: Scalar version flows through all stages.  */
3984   if (!piped)
3985   {
3986      /* Scalar version writes the current calculation to the fdest
3987         register, always with double precision.  */
3988      set_fregval_d (fdest, dbl_tmp_dest);
3989   }
3990   else
3991   {
3992      /* Pipelined version writes fdest with the result from the last
3993         stage of the pipeline, with precision specified by the IRP
3994         bit of the stage's result-status bits.  */
3995      if (m_G.stat.irp)   /* 1st (and last) stage.  */
3996         set_fregval_d (fdest, m_G.val.d);
3997      else
3998         set_fregval_s (fdest, m_G.val.s);
3999
4000      /* Now write current calculation to first and only stage.  */
4001      m_G.val.d = dbl_tmp_dest;
4002      m_G.stat.irp = 1;
4003   }
4004}
4005
4006
4007/* Execute [p]faddz fsrc1,fsrc2,fdest.  */
4008void i860_cpu_device::insn_faddz (UINT32 insn)
4009{
4010   UINT32 fsrc1 = get_fsrc1 (insn);
4011   UINT32 fsrc2 = get_fsrc2 (insn);
4012   UINT32 fdest = get_fdest (insn);
4013   int piped = insn & 0x400;        /* 1 = pipelined, 0 = scalar.  */
4014   double dbl_tmp_dest = 0.0;
4015   double v1 = get_fregval_d (fsrc1);
4016   double v2 = get_fregval_d (fsrc2);
4017   UINT64 iv1 = *(UINT64 *)&v1;
4018   UINT64 iv2 = *(UINT64 *)&v2;
4019   UINT64 r = 0;
4020
4021   r = iv1 + iv2;
4022   dbl_tmp_dest = *(double *)&r;
4023
4024   /* Update the merge register depending on the pixel size.  */
4025   m_merge = ((m_merge >> 16) & ~0xffff0000ffff0000ULL);
4026   m_merge |= (r & 0xffff0000ffff0000ULL);
4027
4028   /* FIXME: Copy result-status bit IRP to fsr from last stage.  */
4029   /* FIXME: Scalar version flows through all stages.  */
4030   if (!piped)
4031   {
4032      /* Scalar version writes the current calculation to the fdest
4033         register, always with double precision.  */
4034      set_fregval_d (fdest, dbl_tmp_dest);
4035   }
4036   else
4037   {
4038      /* Pipelined version writes fdest with the result from the last
4039         stage of the pipeline, with precision specified by the IRP
4040         bit of the stage's result-status bits.  */
4041      if (m_G.stat.irp)   /* 1st (and last) stage.  */
4042         set_fregval_d (fdest, m_G.val.d);
4043      else
4044         set_fregval_s (fdest, m_G.val.s);
4045
4046      /* Now write current calculation to first and only stage.  */
4047      m_G.val.d = dbl_tmp_dest;
4048      m_G.stat.irp = 1;
4049   }
4050}
4051
4052
4053/* Flags for the decode table.  */
4054enum {
4055   DEC_MORE    = 1,    /* More decoding necessary.  */
4056   DEC_DECODED = 2     /* Fully decoded, go.  */
4057};
4058
4059
4060/* First-level decode table (i.e., for the 6 primary opcode bits).  */
4061const i860_cpu_device::decode_tbl_t i860_cpu_device::decode_tbl[64] = {
4062   /* A slight bit of decoding for loads and stores is done in the
4063      execution routines (operand size and addressing mode), which
4064      is why their respective entries are identical.  */
4065   { &i860_cpu_device::insn_ldx,         DEC_DECODED}, /* ld.b isrc1(isrc2),idest.  */
4066   { &i860_cpu_device::insn_ldx,         DEC_DECODED}, /* ld.b #const(isrc2),idest.  */
4067   { &i860_cpu_device::insn_ixfr,        DEC_DECODED}, /* ixfr isrc1ni,fdest.  */
4068   { &i860_cpu_device::insn_stx,         DEC_DECODED}, /* st.b isrc1ni,#const(isrc2).  */
4069   { &i860_cpu_device::insn_ldx,         DEC_DECODED}, /* ld.{s,l} isrc1(isrc2),idest.  */
4070   { &i860_cpu_device::insn_ldx,         DEC_DECODED}, /* ld.{s,l} #const(isrc2),idest.  */
4071   { 0,                0},
4072   { &i860_cpu_device::insn_stx,         DEC_DECODED}, /* st.{s,l} isrc1ni,#const(isrc2),idest.*/
4073   { &i860_cpu_device::insn_fldy,        DEC_DECODED}, /* fld.{l,d,q} isrc1(isrc2)[++],fdest. */
4074   { &i860_cpu_device::insn_fldy,        DEC_DECODED}, /* fld.{l,d,q} #const(isrc2)[++],fdest. */
4075   { &i860_cpu_device::insn_fsty,        DEC_DECODED}, /* fst.{l,d,q} fdest,isrc1(isrc2)[++] */
4076   { &i860_cpu_device::insn_fsty,        DEC_DECODED}, /* fst.{l,d,q} fdest,#const(isrc2)[++] */
4077   { &i860_cpu_device::insn_ld_ctrl,     DEC_DECODED}, /* ld.c csrc2,idest.  */
4078   { &i860_cpu_device::insn_flush,       DEC_DECODED}, /* flush #const(isrc2) (or autoinc).  */
4079   { &i860_cpu_device::insn_st_ctrl,     DEC_DECODED}, /* st.c isrc1,csrc2.  */
4080   { &i860_cpu_device::insn_pstd,        DEC_DECODED}, /* pst.d fdest,#const(isrc2)[++].  */
4081   { &i860_cpu_device::insn_bri,         DEC_DECODED}, /* bri isrc1ni.  */
4082   { &i860_cpu_device::insn_trap,        DEC_DECODED}, /* trap isrc1ni,isrc2,idest.   */
4083   { 0,                DEC_MORE}, /* FP ESCAPE FORMAT, more decode.  */
4084   { 0,                DEC_MORE}, /* CORE ESCAPE FORMAT, more decode.  */
4085   { &i860_cpu_device::insn_btne,        DEC_DECODED}, /* btne isrc1,isrc2,sbroff.  */
4086   { &i860_cpu_device::insn_btne_imm,    DEC_DECODED}, /* btne #const,isrc2,sbroff.  */
4087   { &i860_cpu_device::insn_bte,         DEC_DECODED}, /* bte isrc1,isrc2,sbroff.  */
4088   { &i860_cpu_device::insn_bte_imm,     DEC_DECODED}, /* bte #const5,isrc2,idest.  */
4089   { &i860_cpu_device::insn_fldy,        DEC_DECODED}, /* pfld.{l,d,q} isrc1(isrc2)[++],fdest.*/
4090   { &i860_cpu_device::insn_fldy,        DEC_DECODED}, /* pfld.{l,d,q} #const(isrc2)[++],fdest.*/
4091   { &i860_cpu_device::insn_br,          DEC_DECODED}, /* br lbroff.  */
4092   { &i860_cpu_device::insn_call,        DEC_DECODED}, /* call lbroff .  */
4093   { &i860_cpu_device::insn_bc,          DEC_DECODED}, /* bc lbroff.  */
4094   { &i860_cpu_device::insn_bct,         DEC_DECODED}, /* bc.t lbroff.  */
4095   { &i860_cpu_device::insn_bnc,         DEC_DECODED}, /* bnc lbroff.  */
4096   { &i860_cpu_device::insn_bnct,        DEC_DECODED}, /* bnc.t lbroff.  */
4097   { &i860_cpu_device::insn_addu,        DEC_DECODED}, /* addu isrc1,isrc2,idest.  */
4098   { &i860_cpu_device::insn_addu_imm,    DEC_DECODED}, /* addu #const,isrc2,idest.  */
4099   { &i860_cpu_device::insn_subu,        DEC_DECODED}, /* subu isrc1,isrc2,idest.  */
4100   { &i860_cpu_device::insn_subu_imm,    DEC_DECODED}, /* subu #const,isrc2,idest.  */
4101   { &i860_cpu_device::insn_adds,        DEC_DECODED}, /* adds isrc1,isrc2,idest.  */
4102   { &i860_cpu_device::insn_adds_imm,    DEC_DECODED}, /* adds #const,isrc2,idest.  */
4103   { &i860_cpu_device::insn_subs,        DEC_DECODED}, /* subs isrc1,isrc2,idest.  */
4104   { &i860_cpu_device::insn_subs_imm,    DEC_DECODED}, /* subs #const,isrc2,idest.  */
4105   { &i860_cpu_device::insn_shl,         DEC_DECODED}, /* shl isrc1,isrc2,idest.  */
4106   { &i860_cpu_device::insn_shl_imm,     DEC_DECODED}, /* shl #const,isrc2,idest.  */
4107   { &i860_cpu_device::insn_shr,         DEC_DECODED}, /* shr isrc1,isrc2,idest.  */
4108   { &i860_cpu_device::insn_shr_imm,     DEC_DECODED}, /* shr #const,isrc2,idest.  */
4109   { &i860_cpu_device::insn_shrd,        DEC_DECODED}, /* shrd isrc1ni,isrc2,idest.  */
4110   { &i860_cpu_device::insn_bla,         DEC_DECODED}, /* bla isrc1ni,isrc2,sbroff.  */
4111   { &i860_cpu_device::insn_shra,        DEC_DECODED}, /* shra isrc1,isrc2,idest.  */
4112   { &i860_cpu_device::insn_shra_imm,    DEC_DECODED}, /* shra #const,isrc2,idest.  */
4113   { &i860_cpu_device::insn_and,         DEC_DECODED}, /* and isrc1,isrc2,idest.  */
4114   { &i860_cpu_device::insn_and_imm,     DEC_DECODED}, /* and #const,isrc2,idest.  */
4115   { 0,                0},
4116   { &i860_cpu_device::insn_andh_imm,    DEC_DECODED}, /* andh #const,isrc2,idest.  */
4117   { &i860_cpu_device::insn_andnot,      DEC_DECODED}, /* andnot isrc1,isrc2,idest.  */
4118   { &i860_cpu_device::insn_andnot_imm,  DEC_DECODED}, /* andnot #const,isrc2,idest.  */
4119   { 0,                0},
4120   { &i860_cpu_device::insn_andnoth_imm, DEC_DECODED}, /* andnoth #const,isrc2,idest.  */
4121   { &i860_cpu_device::insn_or,          DEC_DECODED}, /* or isrc1,isrc2,idest.  */
4122   { &i860_cpu_device::insn_or_imm,      DEC_DECODED}, /* or #const,isrc2,idest.  */
4123   { 0,                0},
4124   { &i860_cpu_device::insn_orh_imm,     DEC_DECODED}, /* orh #const,isrc2,idest.  */
4125   { &i860_cpu_device::insn_xor,         DEC_DECODED}, /* xor isrc1,isrc2,idest.  */
4126   { &i860_cpu_device::insn_xor_imm,     DEC_DECODED}, /* xor #const,isrc2,idest.  */
4127   { 0,                0},
4128   { &i860_cpu_device::insn_xorh_imm,    DEC_DECODED}, /* xorh #const,isrc2,idest.  */
4129};
4130
4131
4132/* Second-level decode table (i.e., for the 3 core escape opcode bits).  */
4133const i860_cpu_device::decode_tbl_t i860_cpu_device::core_esc_decode_tbl[8] = {
4134   { 0,                0},
4135   { 0,                0}, /* lock  (FIXME: unimplemented).  */
4136   { &i860_cpu_device::insn_calli,       DEC_DECODED}, /* calli isrc1ni.                 */
4137   { 0,                0},
4138   { &i860_cpu_device::insn_intovr,      DEC_DECODED}, /* intovr.                        */
4139   { 0,                0},
4140   { 0,                0},
4141   { 0,                0}, /* unlock (FIXME: unimplemented). */
4142};
4143
4144
4145/* Second-level decode table (i.e., for the 7 FP extended opcode bits).  */
4146const i860_cpu_device::decode_tbl_t i860_cpu_device::fp_decode_tbl[128] = {
4147   /* Floating point instructions.  The least significant 7 bits are
4148      the (extended) opcode and bits 10:7 are P,D,S,R respectively
4149      ([p]ipelined, [d]ual, [s]ource prec., [r]esult prec.).
4150      For some operations, I defer decoding the P,S,R bits to the
4151      emulation routine for them.  */
4152   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x00 pf[m]am */
4153   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x01 pf[m]am */
4154   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x02 pf[m]am */
4155   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x03 pf[m]am */
4156   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x04 pf[m]am */
4157   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x05 pf[m]am */
4158   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x06 pf[m]am */
4159   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x07 pf[m]am */
4160   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x08 pf[m]am */
4161   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x09 pf[m]am */
4162   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0A pf[m]am */
4163   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0B pf[m]am */
4164   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0C pf[m]am */
4165   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0D pf[m]am */
4166   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0E pf[m]am */
4167   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x0F pf[m]am */
4168   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x10 pf[m]sm */
4169   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x11 pf[m]sm */
4170   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x12 pf[m]sm */
4171   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x13 pf[m]sm */
4172   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x14 pf[m]sm */
4173   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x15 pf[m]sm */
4174   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x16 pf[m]sm */
4175   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x17 pf[m]sm */
4176   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x18 pf[m]sm */
4177   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x19 pf[m]sm */
4178   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1A pf[m]sm */
4179   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1B pf[m]sm */
4180   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1C pf[m]sm */
4181   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1D pf[m]sm */
4182   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1E pf[m]sm */
4183   { &i860_cpu_device::insn_dualop,      DEC_DECODED}, /* 0x1F pf[m]sm */
4184   { &i860_cpu_device::insn_fmul,        DEC_DECODED}, /* 0x20 [p]fmul */
4185   { &i860_cpu_device::insn_fmlow,       DEC_DECODED}, /* 0x21 fmlow.dd */
4186   { &i860_cpu_device::insn_frcp,        DEC_DECODED}, /* 0x22 frcp.{ss,sd,dd} */
4187   { &i860_cpu_device::insn_frsqr,       DEC_DECODED}, /* 0x23 frsqr.{ss,sd,dd} */
4188   { &i860_cpu_device::insn_fmul,        DEC_DECODED}, /* 0x24 pfmul3.dd */
4189   { 0,                0}, /* 0x25 */
4190   { 0,                0}, /* 0x26 */
4191   { 0,                0}, /* 0x27 */
4192   { 0,                0}, /* 0x28 */
4193   { 0,                0}, /* 0x29 */
4194   { 0,                0}, /* 0x2A */
4195   { 0,                0}, /* 0x2B */
4196   { 0,                0}, /* 0x2C */
4197   { 0,                0}, /* 0x2D */
4198   { 0,                0}, /* 0x2E */
4199   { 0,                0}, /* 0x2F */
4200   { &i860_cpu_device::insn_fadd_sub,    DEC_DECODED}, /* 0x30, [p]fadd.{ss,sd,dd} */
4201   { &i860_cpu_device::insn_fadd_sub,    DEC_DECODED}, /* 0x31, [p]fsub.{ss,sd,dd} */
4202   { 0,                0}, /* 0x32, [p]fix.{ss,sd,dd}  FIXME: nyi. */
4203   { &i860_cpu_device::insn_famov,       DEC_DECODED}, /* 0x33, [p]famov.{ss,sd,ds,dd} */
4204   { &i860_cpu_device::insn_fcmp,        DEC_DECODED}, /* 0x34, pf{gt,le}.{ss,dd} */
4205   { &i860_cpu_device::insn_fcmp,        DEC_DECODED}, /* 0x35, pfeq.{ss,dd} */
4206   { 0,                0}, /* 0x36 */
4207   { 0,                0}, /* 0x37 */
4208   { 0,                0}, /* 0x38 */
4209   { 0,                0}, /* 0x39 */
4210   { &i860_cpu_device::insn_ftrunc,      DEC_DECODED}, /* 0x3A, [p]ftrunc.{ss,sd,dd} */
4211   { 0,                0}, /* 0x3B */
4212   { 0,                0}, /* 0x3C */
4213   { 0,                0}, /* 0x3D */
4214   { 0,                0}, /* 0x3E */
4215   { 0,                0}, /* 0x3F */
4216   { &i860_cpu_device::insn_fxfr,        DEC_DECODED}, /* 0x40, fxfr */
4217   { 0,                0}, /* 0x41 */
4218   { 0,                0}, /* 0x42 */
4219   { 0,                0}, /* 0x43 */
4220   { 0,                0}, /* 0x44 */
4221   { 0,                0}, /* 0x45 */
4222   { 0,                0}, /* 0x46 */
4223   { 0,                0}, /* 0x47 */
4224   { 0,                0}, /* 0x48 */
4225   { &i860_cpu_device::insn_fiadd_sub,   DEC_DECODED}, /* 0x49, [p]fiadd.{ss,dd} */
4226   { 0,                0}, /* 0x4A */
4227   { 0,                0}, /* 0x4B */
4228   { 0,                0}, /* 0x4C */
4229   { &i860_cpu_device::insn_fiadd_sub,   DEC_DECODED}, /* 0x4D, [p]fisub.{ss,dd} */
4230   { 0,                0}, /* 0x4E */
4231   { 0,                0}, /* 0x4F */
4232   { &i860_cpu_device::insn_faddp,       DEC_DECODED}, /* 0x50, [p]faddp */
4233   { &i860_cpu_device::insn_faddz,       DEC_DECODED}, /* 0x51, [p]faddz */
4234   { 0,                0}, /* 0x52 */
4235   { 0,                0}, /* 0x53 */
4236   { 0,                0}, /* 0x54 */
4237   { 0,                0}, /* 0x55 */
4238   { 0,                0}, /* 0x56 */
4239   { &i860_cpu_device::insn_fzchk,       DEC_DECODED}, /* 0x57, [p]fzchkl */
4240   { 0,                0}, /* 0x58 */
4241   { 0,                0}, /* 0x59 */
4242   { &i860_cpu_device::insn_form,        DEC_DECODED}, /* 0x5A, [p]form.dd */
4243   { 0,                0}, /* 0x5B */
4244   { 0,                0}, /* 0x5C */
4245   { 0,                0}, /* 0x5D */
4246   { 0,                0}, /* 0x5E */
4247   { &i860_cpu_device::insn_fzchk,       DEC_DECODED}, /* 0x5F, [p]fzchks */
4248   { 0,                0}, /* 0x60 */
4249   { 0,                0}, /* 0x61 */
4250   { 0,                0}, /* 0x62 */
4251   { 0,                0}, /* 0x63 */
4252   { 0,                0}, /* 0x64 */
4253   { 0,                0}, /* 0x65 */
4254   { 0,                0}, /* 0x66 */
4255   { 0,                0}, /* 0x67 */
4256   { 0,                0}, /* 0x68 */
4257   { 0,                0}, /* 0x69 */
4258   { 0,                0}, /* 0x6A */
4259   { 0,                0}, /* 0x6B */
4260   { 0,                0}, /* 0x6C */
4261   { 0,                0}, /* 0x6D */
4262   { 0,                0}, /* 0x6E */
4263   { 0,                0}, /* 0x6F */
4264   { 0,                0}, /* 0x70 */
4265   { 0,                0}, /* 0x71 */
4266   { 0,                0}, /* 0x72 */
4267   { 0,                0}, /* 0x73 */
4268   { 0,                0}, /* 0x74 */
4269   { 0,                0}, /* 0x75 */
4270   { 0,                0}, /* 0x76 */
4271   { 0,                0}, /* 0x77 */
4272   { 0,                0}, /* 0x78 */
4273   { 0,                0}, /* 0x79 */
4274   { 0,                0}, /* 0x7A */
4275   { 0,                0}, /* 0x7B */
4276   { 0,                0}, /* 0x7C */
4277   { 0,                0}, /* 0x7D */
4278   { 0,                0}, /* 0x7E */
4279   { 0,                0}, /* 0x7F */
4280};
4281
4282
4283/*
4284 * Main decoder driver.
4285 *  insn = instruction at the current PC to execute.
4286 *  non_shadow = This insn is not in the shadow of a delayed branch).
4287 */
4288void i860_cpu_device::decode_exec (UINT32 insn, UINT32 non_shadow)
4289{
4290   int upper_6bits = (insn >> 26) & 0x3f;
4291   char flags = 0;
4292   int unrecognized = 1;
4293
4294   if (m_exiting_ifetch)
4295      return;
4296
4297   if ((upper_6bits == 0x12 || upper_6bits == 0x2c) && insn & 0x0200)
4298      logerror("D-bit seen.\n");
4299   if (GET_EPSR_BE ())
4300      logerror("BE-bit high.\n");
4301   if (GET_DIRBASE_CS8 ())
4302      logerror("CS8-bit high.\n");
4303
4304   flags = decode_tbl[upper_6bits].flags;
4305   if (flags & DEC_DECODED)
4306   {
4307      (this->*decode_tbl[upper_6bits].insn_exec)(insn);
4308      unrecognized = 0;
4309   }
4310   else if (flags & DEC_MORE)
4311   {
4312      if (upper_6bits == 0x12)
4313      {
4314         /* FP instruction format handled here.  */
4315         char fp_flags = fp_decode_tbl[insn & 0x7f].flags;
4316         if (fp_flags & DEC_DECODED)
4317         {
4318            (this->*fp_decode_tbl[insn & 0x7f].insn_exec)(insn);
4319            unrecognized = 0;
4320         }
4321      }
4322      else if (upper_6bits == 0x13)
4323      {
4324         /* Core escape instruction format handled here.  */
4325         char esc_flags = core_esc_decode_tbl[insn & 0x3].flags;
4326         if (esc_flags & DEC_DECODED)
4327         {
4328            (this->*core_esc_decode_tbl[insn & 0x3].insn_exec)(insn);
4329            unrecognized = 0;
4330         }
4331      }
4332   }
4333
4334   if (unrecognized)
4335      unrecog_opcode (m_pc, insn);
4336
4337   /* For now, just treat every instruction as taking the same number of
4338      clocks-- a major oversimplification.  */
4339   m_icount -= 9;
4340}
4341
4342
4343/* Set-up all the default power-on/reset values.  */
4344void i860_cpu_device::reset_i860 ()
4345{
4346   int i;
4347   /* On power-up/reset, i860 has values:
4348        PC = 0xffffff00.
4349        Integer registers: r0 = 0, others = undefined.
4350        FP registers:      f0:f1 = 0, others undefined.
4351        psr: U = IM = BR = BW = 0; others = undefined.
4352        epsr: IL = WP = PBM = BE = 0; processor type, stepping, and
4353              DCS are proper and read-only; others = undefined.
4354        db: undefined.
4355        dirbase: DPS, BL, ATE = 0
4356        fir, fsr, KR, KI, MERGE: undefined. (what about T?)
4357
4358        I$: flushed.
4359        D$: undefined (all modified bits = 0).
4360        TLB: flushed.
4361
4362      Note that any undefined values are set to 0x55aa55aa patterns to
4363      try to detect defective i860 software.  */
4364
4365   /* PC is at trap address after reset.  */
4366   m_pc = 0xffffff00;
4367
4368   /* Set grs and frs to undefined/nonsense values, except r0.  */
4369   for (i = 0; i < 32; i++)
4370   {
4371      set_iregval (i, 0x55aa55aa);
4372      set_fregval_s (i, 0.0);
4373   }
4374   set_iregval (0, 0);
4375   set_fregval_s (0, 0.0);
4376   set_fregval_s (1, 0.0);
4377
4378   /* Set whole psr to 0.  This sets the proper bits to 0 as specified
4379      above, and zeroes the undefined bits.  */
4380   m_cregs[CR_PSR] = 0;
4381
4382   /* Set most of the epsr bits to 0 (as specified above), leaving
4383      undefined as zero as well.  Then properly set processor type,
4384      step, and DCS. Type = EPSR[7..0], step = EPSR[12..8],
4385      DCS = EPSR[21..18] (2^[12+dcs] = cache size).
4386      We'll pretend to be stepping D0, since it has the fewest bugs
4387      (and I don't want to emulate the many defects in the earlier
4388      steppings).
4389      Proc type: 1 = XR, 2 = XP   (XR has 8KB data cache -> DCS = 1).
4390      Steppings (XR): 3,4,5,6,7 = (B2, C0, B3, C1, D0 respectively).
4391      Steppings (XP): 0, 2, 3, 4 = (A0, B0, B1, B2) (any others?).  */
4392   m_cregs[CR_EPSR] = 0x00040701;
4393
4394   /* Set DPS, BL, ATE = 0 and the undefined parts also to 0.  */
4395   m_cregs[CR_DIRBASE] = 0x00000000;
4396
4397   /* Set fir, fsr, KR, KI, MERGE, T to undefined.  */
4398   m_cregs[CR_FIR] = 0xaa55aa55;
4399   m_cregs[CR_FSR] = /* 0xaa55aa55; */ 0;
4400   m_KR.d = 0.0;
4401   m_KI.d = 0.0;
4402   m_T.d = 0.0;
4403   m_merge = 0xaa55aa55;
4404
4405   m_fir_gets_trap_addr = 0;
4406}
4407
4408
4409
4410
4411/*=================================================================*/
4412/* MAME execution hook for i860 emulator. */
4413/*=================================================================*/
4414
4415void i860_cpu_device::execute_run()
4416{
4417   /* Check if the data bus is held by another device, and bail if so.
4418      Also check for reset.  */
4419   if (m_pin_reset)
4420      reset_i860 ();
4421   if (m_pin_bus_hold)
4422   {
4423      m_icount = 0;
4424      return;
4425   }
4426
4427   m_exiting_readmem = 0;
4428   m_exiting_ifetch = 0;
4429
4430   /* Decode and execute loop.  */
4431   while (m_icount > 0)
4432   {
4433      UINT32 savepc = m_pc;
4434      m_pc_updated = 0;
4435      m_pending_trap = 0;
4436
4437#if 1 /* Delete me soon, for debugging VC inter-processor synch.  */
4438      if (m_pc == 0xfffc0370 ||
4439         m_pc == 0xfffc03a4)
4440      {
4441         fprintf(stderr, "(%s) 0x%08x: snag 0x20000000\n", tag(), m_pc);
4442         m_single_stepping = 0;
4443      }
4444      else if (m_pc == 0xfffc0384 ||
4445               m_pc == 0xfffc03b8)
4446      {
4447         fprintf(stderr, "(%s) 0x%08x: passed 0x20000000\n", tag(), m_pc);
4448         m_single_stepping = 0;
4449      }
4450#endif
4451
4452      savepc = m_pc;
4453      debugger_instruction_hook(this, m_pc);
4454      decode_exec (ifetch (m_pc), 1);
4455
4456      m_exiting_ifetch = 0;
4457      m_exiting_readmem = 0;
4458
4459      if (m_pending_trap)
4460      {
4461         /* If we need to trap, change PC to trap address.
4462            Also set supervisor mode, copy U and IM to their
4463            previous versions, clear IM.  */
4464         if ((m_pending_trap & TRAP_WAS_EXTERNAL) || (GET_EPSR_INT () && GET_PSR_IN ()))
4465         {
4466            if (!m_pc_updated)
4467               m_cregs[CR_FIR] = savepc + 4;
4468            else
4469               m_cregs[CR_FIR] = m_pc;
4470         }
4471         else if (m_pending_trap & TRAP_IN_DELAY_SLOT)
4472         {
4473            m_cregs[CR_FIR] = savepc + 4;
4474         }
4475         else
4476            m_cregs[CR_FIR] = savepc;
4477
4478         m_fir_gets_trap_addr = 1;
4479         SET_PSR_PU (GET_PSR_U ());
4480         SET_PSR_PIM (GET_PSR_IM ());
4481         SET_PSR_U (0);
4482         SET_PSR_IM (0);
4483         SET_PSR_DIM (0);
4484         SET_PSR_DS (0);
4485         m_pc = 0xffffff00;
4486         m_pending_trap = 0;
4487      }
4488      else if (!m_pc_updated)
4489      {
4490         /* If the PC wasn't updated by a control flow instruction, just
4491            bump to next sequential instruction.  */
4492         m_pc += 4;
4493      }
4494
4495      /*if (m_single_stepping)
4496          debugger (cpustate); */
4497   }
4498}
4499/*=================================================================*/
4500
4501
4502
4503
4504#if 0
4505/*=================================================================*/
4506/* Internal debugger-related stuff.  */
4507
4508extern unsigned disasm_i860 (char *buf, unsigned int pc, unsigned int insn);
4509
4510
4511/* Disassemble `len' instructions starting at `addr'.  */
4512void i860_cpu_device::disasm (UINT32 addr, int len)
4513{
4514   UINT32 insn;
4515   int j;
4516   for (j = 0; j < len; j++)
4517   {
4518      char buf[256];
4519      UINT32 phys_addr = addr;
4520      if (GET_DIRBASE_ATE ())
4521         phys_addr = get_address_translation (addr, 1  /* is_dataref */, 0 /* is_write */);
4522
4523      /* Note that we print the incoming (possibly virtual) address as the
4524         PC rather than the translated address.  */
4525      fprintf (stderr, "  (%s) 0x%08x: ", m_device->tag(), addr);
4526      insn = m_program->read_dword(phys_addr);
4527#ifdef HOST_MSB
4528      BYTE_REV32 (insn);
4529#endif /* HOST_MSB.  */
4530      disasm_i860 (buf, addr, insn); fprintf (stderr, "%s", buf);
4531      fprintf (stderr, "\n");
4532      addr += 4;
4533#if 1
4534      if (m_single_stepping == 1 && has_delay_slot (insn))
4535         len += 1;
4536#endif
4537   }
4538}
4539
4540
4541/* Dump `len' bytes starting at `addr'.  */
4542void i860_cpu_device::dbg_db (UINT32 addr, int len)
4543{
4544   UINT8 b[16];
4545   int i;
4546   /* This will always dump a multiple of 16 bytes, even if 'len' isn't.  */
4547   while (len > 0)
4548   {
4549      /* Note that we print the incoming (possibly virtual) address
4550         rather than the translated address.  */
4551      fprintf (stderr, "0x%08x: ", addr);
4552      for (i = 0; i < 16; i++)
4553      {
4554         UINT32 phys_addr = addr;
4555         if (GET_DIRBASE_ATE ())
4556            phys_addr = get_address_translation (addr, 1  /* is_dataref */, 0 /* is_write */);
4557
4558         b[i] = m_program->read_byte(phys_addr);
4559         fprintf (stderr, "%02x ", b[i]);
4560         addr++;
4561      }
4562      fprintf (stderr, "| ");
4563      for (i = 0; i < 16; i++)
4564      {
4565         if (isprint (b[i]))
4566            fprintf (stderr, "%c", b[i]);
4567         else
4568            fprintf (stderr, ".");
4569      }
4570      fprintf (stderr, "\n");
4571      len -= 16;
4572   }
4573}
4574
4575
4576/* A simple internal debugger.  */
4577void debugger (i860s *cpustate)
4578{
4579   char buf[256];
4580   UINT32 curr_disasm = m_pc;
4581   UINT32 curr_dumpdb = 0;
4582   int c = 0;
4583
4584   if (m_single_stepping > 1 && m_single_stepping != m_pc)
4585      return;
4586
4587   buf[0] = 0;
4588
4589   /* Always disassemble the upcoming instruction when single-stepping.  */
4590   if (m_single_stepping)
4591   {
4592      disasm (m_pc, 1);
4593      if (has_delay_slot (2))
4594         disasm (m_pc + 4, 1);
4595   }
4596   else
4597      fprintf (stderr, "\nEmulator: internal debugger started (? for help).\n");
4598
4599   fflush (stdin);
4600
4601   m_single_stepping = 0;
4602   while (!m_single_stepping)
4603   {
4604      fprintf (stderr, "- ");
4605#if 0  /* Doesn't work on MacOSX BSD flavor.  */
4606      fscanf (stdin, "%s", buf);
4607#else
4608      while (1)
4609      {
4610         char it = 0;
4611         if (read(STDIN_FILENO, &it, 1) == 1)
4612         {
4613            if (it == '\n')
4614            {
4615               buf[c] = 0;
4616               c = 0;
4617               break;
4618            }
4619            buf[c++] = it;
4620         }
4621      }
4622#endif
4623      if (buf[0] == 'g')
4624      {
4625         if (buf[1] == '0')
4626            sscanf (buf + 1, "%x", &m_single_stepping);
4627         else
4628            break;
4629         buf[1] = 0;
4630         fprintf (stderr, "go until pc = 0x%08x.\n",
4631                  m_single_stepping);
4632         m_single_stepping = 0;    /* HACK */
4633      }
4634      else if (buf[0] == 'r')
4635         dump_state (cpustate);
4636      else if (buf[0] == 'u')
4637      {
4638         if (buf[1] == '0')
4639            sscanf (buf + 1, "%x", &curr_disasm);
4640         disasm (curr_disasm, 10);
4641         curr_disasm += 10 * 4;
4642         buf[1] = 0;
4643      }
4644      else if (buf[0] == 'p')
4645      {
4646         if (buf[1] >= '0' && buf[1] <= '4')
4647            dump_pipe (buf[1] - 0x30);
4648         buf[1] = 0;
4649      }
4650      else if (buf[0] == 's')
4651         m_single_stepping = 1;
4652      else if (buf[0] == 'l')
4653         ; //m_pc = elf_load(buf + 1);
4654      else if (buf[0] == 'd' && buf[1] == 'b')
4655      {
4656         if (buf[2] == '0')
4657            sscanf (buf + 2, "%x", &curr_dumpdb);
4658         dbg_db (curr_dumpdb, 32);
4659         curr_dumpdb += 32;
4660      }
4661      else if (buf[0] == 'x' && buf[1] == '0')
4662      {
4663         UINT32 v;
4664         sscanf (buf + 1, "%x", &v);
4665         if (GET_DIRBASE_ATE ())
4666            fprintf (stderr, "vma 0x%08x ==> phys 0x%08x\n", v,
4667                     get_address_translation (v, 1, 0));
4668         else
4669            fprintf (stderr, "not in virtual address mode.\n");
4670      }
4671      else if (buf[0] == 'B')
4672      {
4673         ;//m_pc = elf_load("bins/bsd");
4674         break;
4675      }
4676      else if (buf[0] == '?')
4677      {
4678         fprintf (stderr, "  db: dump bytes (db[0xaddress])\n   r: dump registers\n   s: single-step\n   g: go back to emulator (g[0xaddress])\n   u: disassemble (u[0xaddress])\n   p: dump pipelines (p{0-4} for all, add, mul, load, graphics)\n   l: load an ELF binary (lpath)\n   x: give virt->phys translation (x{0xaddress})\n");
4679      }
4680      else
4681         fprintf (stderr, "Bad command '%s'.\n", buf);
4682   }
4683
4684   /* Less noise when single-stepping.  */
4685   if (m_single_stepping != 1)
4686      fprintf (stderr, "Debugger done, continuing emulation.\n");
4687}
4688
4689#endif
Property changes on: trunk/src/emu/cpu/i860/i860dec.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/i860/i860.c
r28738r28739
237237/**************************************************************************
238238 * The actual decode and execute code.
239239 **************************************************************************/
240#include "i860dec.c"
240#include "i860dec.inc"
trunk/src/emu/cpu/i386/i386ops.c
r28738r28739
1UINT8 i386_device::i386_shift_rotate8(UINT8 modrm, UINT32 value, UINT8 shift)
2{
3   UINT32 src = value & 0xff;
4   UINT8 dst = value;
5
6   if( shift == 0 ) {
7      CYCLES_RM(modrm, 3, 7);
8   } else if( shift == 1 ) {
9      switch( (modrm >> 3) & 0x7 )
10      {
11         case 0:         /* ROL rm8, 1 */
12            m_CF = (src & 0x80) ? 1 : 0;
13            dst = (src << 1) + m_CF;
14            m_OF = ((src ^ dst) & 0x80) ? 1 : 0;
15            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
16            break;
17         case 1:         /* ROR rm8, 1 */
18            m_CF = (src & 0x1) ? 1 : 0;
19            dst = (m_CF << 7) | (src >> 1);
20            m_OF = ((src ^ dst) & 0x80) ? 1 : 0;
21            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
22            break;
23         case 2:         /* RCL rm8, 1 */
24            dst = (src << 1) + m_CF;
25            m_CF = (src & 0x80) ? 1 : 0;
26            m_OF = ((src ^ dst) & 0x80) ? 1 : 0;
27            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
28            break;
29         case 3:         /* RCR rm8, 1 */
30            dst = (m_CF << 7) | (src >> 1);
31            m_CF = src & 0x1;
32            m_OF = ((src ^ dst) & 0x80) ? 1 : 0;
33            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
34            break;
35         case 4:         /* SHL/SAL rm8, 1 */
36         case 6:
37            dst = src << 1;
38            m_CF = (src & 0x80) ? 1 : 0;
39            m_OF = (((m_CF << 7) ^ dst) & 0x80) ? 1 : 0;
40            SetSZPF8(dst);
41            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
42            break;
43         case 5:         /* SHR rm8, 1 */
44            dst = src >> 1;
45            m_CF = src & 0x1;
46            m_OF = (dst & 0x80) ? 1 : 0;
47            SetSZPF8(dst);
48            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
49            break;
50         case 7:         /* SAR rm8, 1 */
51            dst = (INT8)(src) >> 1;
52            m_CF = src & 0x1;
53            m_OF = 0;
54            SetSZPF8(dst);
55            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
56            break;
57      }
58
59   } else {
60      switch( (modrm >> 3) & 0x7 )
61      {
62         case 0:         /* ROL rm8, i8 */
63            if(!(shift & 7))
64            {
65               if(shift & 0x18)
66               {
67                  m_CF = src & 1;
68                  m_OF = (src & 1) ^ ((src >> 7) & 1);
69               }
70               break;
71            }
72            shift &= 7;
73            dst = ((src & ((UINT8)0xff >> shift)) << shift) |
74                  ((src & ((UINT8)0xff << (8-shift))) >> (8-shift));
75            m_CF = dst & 0x1;
76            m_OF = (dst & 1) ^ (dst >> 7);
77            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
78            break;
79         case 1:         /* ROR rm8, i8 */
80            if(!(shift & 7))
81            {
82               if(shift & 0x18)
83               {
84                  m_CF = (src >> 7) & 1;
85                  m_OF = ((src >> 7) & 1) ^ ((src >> 6) & 1);
86               }
87               break;
88            }
89            shift &= 7;
90            dst = ((src & ((UINT8)0xff << shift)) >> shift) |
91                  ((src & ((UINT8)0xff >> (8-shift))) << (8-shift));
92            m_CF = (dst >> 7) & 1;
93            m_OF = ((dst >> 7) ^ (dst >> 6)) & 1;
94            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
95            break;
96         case 2:         /* RCL rm8, i8 */
97            shift %= 9;
98            dst = ((src & ((UINT8)0xff >> shift)) << shift) |
99                  ((src & ((UINT8)0xff << (9-shift))) >> (9-shift)) |
100                  (m_CF << (shift-1));
101            if(shift) m_CF = (src >> (8-shift)) & 0x1;
102            m_OF = m_CF ^ ((dst >> 7) & 1);
103            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
104            break;
105         case 3:         /* RCR rm8, i8 */
106            shift %= 9;
107            dst = ((src & ((UINT8)0xff << shift)) >> shift) |
108                  ((src & ((UINT8)0xff >> (8-shift))) << (9-shift)) |
109                  (m_CF << (8-shift));
110            if(shift) m_CF = (src >> (shift-1)) & 0x1;
111            m_OF = ((dst >> 7) ^ (dst >> 6)) & 1;
112            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
113            break;
114         case 4:         /* SHL/SAL rm8, i8 */
115         case 6:
116            shift &= 31;
117            dst = src << shift;
118            m_CF = (shift <= 8) && ((src >> (8 - shift)) & 1);
119            SetSZPF8(dst);
120            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
121            break;
122         case 5:         /* SHR rm8, i8 */
123            shift &= 31;
124            dst = src >> shift;
125            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
126            SetSZPF8(dst);
127            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
128            break;
129         case 7:         /* SAR rm8, i8 */
130            shift &= 31;
131            dst = (INT8)src >> shift;
132            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
133            SetSZPF8(dst);
134            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
135            break;
136      }
137   }
138
139   return dst;
140}
141
142
143
144void i386_device::i386_adc_rm8_r8()        // Opcode 0x10
145{
146   UINT8 src, dst;
147   UINT8 modrm = FETCH();
148   if( modrm >= 0xc0 ) {
149      src = LOAD_REG8(modrm);
150      dst = LOAD_RM8(modrm);
151      dst = ADC8(dst, src, m_CF);
152      STORE_RM8(modrm, dst);
153      CYCLES(CYCLES_ALU_REG_REG);
154   } else {
155      UINT32 ea = GetEA(modrm,1);
156      src = LOAD_REG8(modrm);
157      dst = READ8(ea);
158      dst = ADC8(dst, src, m_CF);
159      WRITE8(ea, dst);
160      CYCLES(CYCLES_ALU_REG_MEM);
161   }
162}
163
164void i386_device::i386_adc_r8_rm8()        // Opcode 0x12
165{
166   UINT8 src, dst;
167   UINT8 modrm = FETCH();
168   if( modrm >= 0xc0 ) {
169      src = LOAD_RM8(modrm);
170      dst = LOAD_REG8(modrm);
171      dst = ADC8(dst, src, m_CF);
172      STORE_REG8(modrm, dst);
173      CYCLES(CYCLES_ALU_REG_REG);
174   } else {
175      UINT32 ea = GetEA(modrm,0);
176      src = READ8(ea);
177      dst = LOAD_REG8(modrm);
178      dst = ADC8(dst, src, m_CF);
179      STORE_REG8(modrm, dst);
180      CYCLES(CYCLES_ALU_MEM_REG);
181   }
182}
183
184void i386_device::i386_adc_al_i8()     // Opcode 0x14
185{
186   UINT8 src, dst;
187   src = FETCH();
188   dst = REG8(AL);
189   dst = ADC8(dst, src, m_CF);
190   REG8(AL) = dst;
191   CYCLES(CYCLES_ALU_IMM_ACC);
192}
193
194void i386_device::i386_add_rm8_r8()        // Opcode 0x00
195{
196   UINT8 src, dst;
197   UINT8 modrm = FETCH();
198   if( modrm >= 0xc0 ) {
199      src = LOAD_REG8(modrm);
200      dst = LOAD_RM8(modrm);
201      dst = ADD8(dst, src);
202      STORE_RM8(modrm, dst);
203      CYCLES(CYCLES_ALU_REG_REG);
204   } else {
205      UINT32 ea = GetEA(modrm,1);
206      src = LOAD_REG8(modrm);
207      dst = READ8(ea);
208      dst = ADD8(dst, src);
209      WRITE8(ea, dst);
210      CYCLES(CYCLES_ALU_REG_MEM);
211   }
212}
213
214void i386_device::i386_add_r8_rm8()        // Opcode 0x02
215{
216   UINT8 src, dst;
217   UINT8 modrm = FETCH();
218   if( modrm >= 0xc0 ) {
219      src = LOAD_RM8(modrm);
220      dst = LOAD_REG8(modrm);
221      dst = ADD8(dst, src);
222      STORE_REG8(modrm, dst);
223      CYCLES(CYCLES_ALU_REG_REG);
224   } else {
225      UINT32 ea = GetEA(modrm,0);
226      src = READ8(ea);
227      dst = LOAD_REG8(modrm);
228      dst = ADD8(dst, src);
229      STORE_REG8(modrm, dst);
230      CYCLES(CYCLES_ALU_MEM_REG);
231   }
232}
233
234void i386_device::i386_add_al_i8()     // Opcode 0x04
235{
236   UINT8 src, dst;
237   src = FETCH();
238   dst = REG8(AL);
239   dst = ADD8(dst, src);
240   REG8(AL) = dst;
241   CYCLES(CYCLES_ALU_IMM_ACC);
242}
243
244void i386_device::i386_and_rm8_r8()        // Opcode 0x20
245{
246   UINT8 src, dst;
247   UINT8 modrm = FETCH();
248   if( modrm >= 0xc0 ) {
249      src = LOAD_REG8(modrm);
250      dst = LOAD_RM8(modrm);
251      dst = AND8(dst, src);
252      STORE_RM8(modrm, dst);
253      CYCLES(CYCLES_ALU_REG_REG);
254   } else {
255      UINT32 ea = GetEA(modrm,1);
256      src = LOAD_REG8(modrm);
257      dst = READ8(ea);
258      dst = AND8(dst, src);
259      WRITE8(ea, dst);
260      CYCLES(CYCLES_ALU_REG_MEM);
261   }
262}
263
264void i386_device::i386_and_r8_rm8()        // Opcode 0x22
265{
266   UINT8 src, dst;
267   UINT8 modrm = FETCH();
268   if( modrm >= 0xc0 ) {
269      src = LOAD_RM8(modrm);
270      dst = LOAD_REG8(modrm);
271      dst = AND8(dst, src);
272      STORE_REG8(modrm, dst);
273      CYCLES(CYCLES_ALU_REG_REG);
274   } else {
275      UINT32 ea = GetEA(modrm,0);
276      src = READ8(ea);
277      dst = LOAD_REG8(modrm);
278      dst = AND8(dst, src);
279      STORE_REG8(modrm, dst);
280      CYCLES(CYCLES_ALU_MEM_REG);
281   }
282}
283
284void i386_device::i386_and_al_i8()         // Opcode 0x24
285{
286   UINT8 src, dst;
287   src = FETCH();
288   dst = REG8(AL);
289   dst = AND8(dst, src);
290   REG8(AL) = dst;
291   CYCLES(CYCLES_ALU_IMM_ACC);
292}
293
294void i386_device::i386_clc()               // Opcode 0xf8
295{
296   m_CF = 0;
297   CYCLES(CYCLES_CLC);
298}
299
300void i386_device::i386_cld()               // Opcode 0xfc
301{
302   m_DF = 0;
303   CYCLES(CYCLES_CLD);
304}
305
306void i386_device::i386_cli()               // Opcode 0xfa
307{
308   if(PROTECTED_MODE)
309   {
310      UINT8 IOPL = m_IOP1 | (m_IOP2 << 1);
311      if(m_CPL > IOPL)
312         FAULT(FAULT_GP,0);
313   }
314   m_IF = 0;
315   CYCLES(CYCLES_CLI);
316}
317
318void i386_device::i386_cmc()               // Opcode 0xf5
319{
320   m_CF ^= 1;
321   CYCLES(CYCLES_CMC);
322}
323
324void i386_device::i386_cmp_rm8_r8()        // Opcode 0x38
325{
326   UINT8 src, dst;
327   UINT8 modrm = FETCH();
328   if( modrm >= 0xc0 ) {
329      src = LOAD_REG8(modrm);
330      dst = LOAD_RM8(modrm);
331      SUB8(dst, src);
332      CYCLES(CYCLES_CMP_REG_REG);
333   } else {
334      UINT32 ea = GetEA(modrm,0);
335      src = LOAD_REG8(modrm);
336      dst = READ8(ea);
337      SUB8(dst, src);
338      CYCLES(CYCLES_CMP_REG_MEM);
339   }
340}
341
342void i386_device::i386_cmp_r8_rm8()        // Opcode 0x3a
343{
344   UINT8 src, dst;
345   UINT8 modrm = FETCH();
346   if( modrm >= 0xc0 ) {
347      src = LOAD_RM8(modrm);
348      dst = LOAD_REG8(modrm);
349      SUB8(dst, src);
350      CYCLES(CYCLES_CMP_REG_REG);
351   } else {
352      UINT32 ea = GetEA(modrm,0);
353      src = READ8(ea);
354      dst = LOAD_REG8(modrm);
355      SUB8(dst, src);
356      CYCLES(CYCLES_CMP_MEM_REG);
357   }
358}
359
360void i386_device::i386_cmp_al_i8()         // Opcode 0x3c
361{
362   UINT8 src, dst;
363   src = FETCH();
364   dst = REG8(AL);
365   SUB8(dst, src);
366   CYCLES(CYCLES_CMP_IMM_ACC);
367}
368
369void i386_device::i386_cmpsb()             // Opcode 0xa6
370{
371   UINT32 eas, ead;
372   UINT8 src, dst;
373   if( m_segment_prefix ) {
374      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
375   } else {
376      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
377   }
378   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
379   src = READ8(eas);
380   dst = READ8(ead);
381   SUB8(src, dst);
382   BUMP_SI(1);
383   BUMP_DI(1);
384   CYCLES(CYCLES_CMPS);
385}
386
387void i386_device::i386_in_al_i8()          // Opcode 0xe4
388{
389   UINT16 port = FETCH();
390   UINT8 data = READPORT8(port);
391   REG8(AL) = data;
392   CYCLES(CYCLES_IN_VAR);
393}
394
395void i386_device::i386_in_al_dx()          // Opcode 0xec
396{
397   UINT16 port = REG16(DX);
398   UINT8 data = READPORT8(port);
399   REG8(AL) = data;
400   CYCLES(CYCLES_IN);
401}
402
403void i386_device::i386_ja_rel8()           // Opcode 0x77
404{
405   INT8 disp = FETCH();
406   if( m_CF == 0 && m_ZF == 0 ) {
407      NEAR_BRANCH(disp);
408      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
409   } else {
410      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
411   }
412}
413
414void i386_device::i386_jbe_rel8()          // Opcode 0x76
415{
416   INT8 disp = FETCH();
417   if( m_CF != 0 || m_ZF != 0 ) {
418      NEAR_BRANCH(disp);
419      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
420   } else {
421      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
422   }
423}
424
425void i386_device::i386_jc_rel8()           // Opcode 0x72
426{
427   INT8 disp = FETCH();
428   if( m_CF != 0 ) {
429      NEAR_BRANCH(disp);
430      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
431   } else {
432      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
433   }
434}
435
436void i386_device::i386_jg_rel8()           // Opcode 0x7f
437{
438   INT8 disp = FETCH();
439   if( m_ZF == 0 && (m_SF == m_OF) ) {
440      NEAR_BRANCH(disp);
441      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
442   } else {
443      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
444   }
445}
446
447void i386_device::i386_jge_rel8()          // Opcode 0x7d
448{
449   INT8 disp = FETCH();
450   if(m_SF == m_OF) {
451      NEAR_BRANCH(disp);
452      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
453   } else {
454      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
455   }
456}
457
458void i386_device::i386_jl_rel8()           // Opcode 0x7c
459{
460   INT8 disp = FETCH();
461   if( (m_SF != m_OF) ) {
462      NEAR_BRANCH(disp);
463      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
464   } else {
465      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
466   }
467}
468
469void i386_device::i386_jle_rel8()      // Opcode 0x7e
470{
471   INT8 disp = FETCH();
472   if( m_ZF != 0 || (m_SF != m_OF) ) {
473      NEAR_BRANCH(disp);
474      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
475   } else {
476      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
477   }
478}
479
480void i386_device::i386_jnc_rel8()          // Opcode 0x73
481{
482   INT8 disp = FETCH();
483   if( m_CF == 0 ) {
484      NEAR_BRANCH(disp);
485      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
486   } else {
487      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
488   }
489}
490
491void i386_device::i386_jno_rel8()          // Opcode 0x71
492{
493   INT8 disp = FETCH();
494   if( m_OF == 0 ) {
495      NEAR_BRANCH(disp);
496      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
497   } else {
498      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
499   }
500}
501
502void i386_device::i386_jnp_rel8()          // Opcode 0x7b
503{
504   INT8 disp = FETCH();
505   if( m_PF == 0 ) {
506      NEAR_BRANCH(disp);
507      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
508   } else {
509      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
510   }
511}
512
513void i386_device::i386_jns_rel8()          // Opcode 0x79
514{
515   INT8 disp = FETCH();
516   if( m_SF == 0 ) {
517      NEAR_BRANCH(disp);
518      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
519   } else {
520      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
521   }
522}
523
524void i386_device::i386_jnz_rel8()          // Opcode 0x75
525{
526   INT8 disp = FETCH();
527   if( m_ZF == 0 ) {
528      NEAR_BRANCH(disp);
529      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
530   } else {
531      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
532   }
533}
534
535void i386_device::i386_jo_rel8()           // Opcode 0x70
536{
537   INT8 disp = FETCH();
538   if( m_OF != 0 ) {
539      NEAR_BRANCH(disp);
540      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
541   } else {
542      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
543   }
544}
545
546void i386_device::i386_jp_rel8()           // Opcode 0x7a
547{
548   INT8 disp = FETCH();
549   if( m_PF != 0 ) {
550      NEAR_BRANCH(disp);
551      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
552   } else {
553      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
554   }
555}
556
557void i386_device::i386_js_rel8()           // Opcode 0x78
558{
559   INT8 disp = FETCH();
560   if( m_SF != 0 ) {
561      NEAR_BRANCH(disp);
562      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
563   } else {
564      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
565   }
566}
567
568void i386_device::i386_jz_rel8()           // Opcode 0x74
569{
570   INT8 disp = FETCH();
571   if( m_ZF != 0 ) {
572      NEAR_BRANCH(disp);
573      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
574   } else {
575      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
576   }
577}
578
579void i386_device::i386_jmp_rel8()          // Opcode 0xeb
580{
581   INT8 disp = FETCH();
582   NEAR_BRANCH(disp);
583   CYCLES(CYCLES_JMP_SHORT);      /* TODO: Timing = 7 + m */
584}
585
586void i386_device::i386_lahf()              // Opcode 0x9f
587{
588   REG8(AH) = get_flags() & 0xd7;
589   CYCLES(CYCLES_LAHF);
590}
591
592void i386_device::i386_lodsb()             // Opcode 0xac
593{
594   UINT32 eas;
595   if( m_segment_prefix ) {
596      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
597   } else {
598      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
599   }
600   REG8(AL) = READ8(eas);
601   BUMP_SI(1);
602   CYCLES(CYCLES_LODS);
603}
604
605void i386_device::i386_mov_rm8_r8()        // Opcode 0x88
606{
607   UINT8 src;
608   UINT8 modrm = FETCH();
609   if( modrm >= 0xc0 ) {
610      src = LOAD_REG8(modrm);
611      STORE_RM8(modrm, src);
612      CYCLES(CYCLES_MOV_REG_REG);
613   } else {
614      UINT32 ea = GetEA(modrm,1);
615      src = LOAD_REG8(modrm);
616      WRITE8(ea, src);
617      CYCLES(CYCLES_MOV_REG_MEM);
618   }
619}
620
621void i386_device::i386_mov_r8_rm8()        // Opcode 0x8a
622{
623   UINT8 src;
624   UINT8 modrm = FETCH();
625   if( modrm >= 0xc0 ) {
626      src = LOAD_RM8(modrm);
627      STORE_REG8(modrm, src);
628      CYCLES(CYCLES_MOV_REG_REG);
629   } else {
630      UINT32 ea = GetEA(modrm,0);
631      src = READ8(ea);
632      STORE_REG8(modrm, src);
633      CYCLES(CYCLES_MOV_MEM_REG);
634   }
635}
636
637void i386_device::i386_mov_rm8_i8()        // Opcode 0xc6
638{
639   UINT8 modrm = FETCH();
640   if( modrm >= 0xc0 ) {
641      UINT8 value = FETCH();
642      STORE_RM8(modrm, value);
643      CYCLES(CYCLES_MOV_IMM_REG);
644   } else {
645      UINT32 ea = GetEA(modrm,1);
646      UINT8 value = FETCH();
647      WRITE8(ea, value);
648      CYCLES(CYCLES_MOV_IMM_MEM);
649   }
650}
651
652void i386_device::i386_mov_r32_cr()        // Opcode 0x0f 20
653{
654   if(PROTECTED_MODE && m_CPL)
655      FAULT(FAULT_GP, 0);
656   UINT8 modrm = FETCH();
657   UINT8 cr = (modrm >> 3) & 0x7;
658
659   STORE_RM32(modrm, m_cr[cr]);
660   CYCLES(CYCLES_MOV_CR_REG);
661}
662
663void i386_device::i386_mov_r32_dr()        // Opcode 0x0f 21
664{
665   if(PROTECTED_MODE && m_CPL)
666      FAULT(FAULT_GP, 0);
667   UINT8 modrm = FETCH();
668   UINT8 dr = (modrm >> 3) & 0x7;
669
670   STORE_RM32(modrm, m_dr[dr]);
671   switch(dr)
672   {
673      case 0:
674      case 1:
675      case 2:
676      case 3:
677         CYCLES(CYCLES_MOV_REG_DR0_3);
678         break;
679      case 6:
680      case 7:
681         CYCLES(CYCLES_MOV_REG_DR6_7);
682         break;
683   }
684}
685
686void i386_device::i386_mov_cr_r32()        // Opcode 0x0f 22
687{
688   if(PROTECTED_MODE && m_CPL)
689      FAULT(FAULT_GP, 0);
690   UINT8 modrm = FETCH();
691   UINT8 cr = (modrm >> 3) & 0x7;
692   UINT32 data = LOAD_RM32(modrm);
693   switch(cr)
694   {
695      case 0:
696         data &= 0xfffeffff; // wp not supported on 386
697         CYCLES(CYCLES_MOV_REG_CR0);
698         break;
699      case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
700      case 3:
701         CYCLES(CYCLES_MOV_REG_CR3);
702         vtlb_flush_dynamic(m_vtlb);
703         break;
704      case 4: CYCLES(1); break; // TODO
705      default:
706         logerror("i386: mov_cr_r32 CR%d!\n", cr);
707         return;
708   }
709   m_cr[cr] = data;
710}
711
712void i386_device::i386_mov_dr_r32()        // Opcode 0x0f 23
713{
714   if(PROTECTED_MODE && m_CPL)
715      FAULT(FAULT_GP, 0);
716   UINT8 modrm = FETCH();
717   UINT8 dr = (modrm >> 3) & 0x7;
718
719   m_dr[dr] = LOAD_RM32(modrm);
720   switch(dr)
721   {
722      case 0:
723      case 1:
724      case 2:
725      case 3:
726         CYCLES(CYCLES_MOV_DR0_3_REG);
727         break;
728      case 6:
729      case 7:
730         CYCLES(CYCLES_MOV_DR6_7_REG);
731         break;
732      default:
733         logerror("i386: mov_dr_r32 DR%d!\n", dr);
734         return;
735   }
736}
737
738void i386_device::i386_mov_al_m8()         // Opcode 0xa0
739{
740   UINT32 offset, ea;
741   if( m_address_size ) {
742      offset = FETCH32();
743   } else {
744      offset = FETCH16();
745   }
746   /* TODO: Not sure if this is correct... */
747   if( m_segment_prefix ) {
748      ea = i386_translate(m_segment_override, offset, 0 );
749   } else {
750      ea = i386_translate(DS, offset, 0 );
751   }
752   REG8(AL) = READ8(ea);
753   CYCLES(CYCLES_MOV_IMM_MEM);
754}
755
756void i386_device::i386_mov_m8_al()         // Opcode 0xa2
757{
758   UINT32 offset, ea;
759   if( m_address_size ) {
760      offset = FETCH32();
761   } else {
762      offset = FETCH16();
763   }
764   /* TODO: Not sure if this is correct... */
765   if( m_segment_prefix ) {
766      ea = i386_translate(m_segment_override, offset, 1 );
767   } else {
768      ea = i386_translate(DS, offset, 1 );
769   }
770   WRITE8(ea, REG8(AL) );
771   CYCLES(CYCLES_MOV_MEM_ACC);
772}
773
774void i386_device::i386_mov_rm16_sreg()     // Opcode 0x8c
775{
776   UINT8 modrm = FETCH();
777   int s = (modrm >> 3) & 0x7;
778
779   if( modrm >= 0xc0 ) {
780      if(m_operand_size)
781         STORE_RM32(modrm, m_sreg[s].selector);
782      else
783         STORE_RM16(modrm, m_sreg[s].selector);
784      CYCLES(CYCLES_MOV_SREG_REG);
785   } else {
786      UINT32 ea = GetEA(modrm,1);
787      WRITE16(ea, m_sreg[s].selector);
788      CYCLES(CYCLES_MOV_SREG_MEM);
789   }
790}
791
792void i386_device::i386_mov_sreg_rm16()     // Opcode 0x8e
793{
794   UINT16 selector;
795   UINT8 modrm = FETCH();
796   bool fault;
797   int s = (modrm >> 3) & 0x7;
798
799   if( modrm >= 0xc0 ) {
800      selector = LOAD_RM16(modrm);
801      CYCLES(CYCLES_MOV_REG_SREG);
802   } else {
803      UINT32 ea = GetEA(modrm,0);
804      selector = READ16(ea);
805      CYCLES(CYCLES_MOV_MEM_SREG);
806   }
807
808   i386_sreg_load(selector,s,&fault);
809   if((s == SS) && !fault)
810   {
811      if(m_IF != 0) // if external interrupts are enabled
812      {
813         m_IF = 0;  // reset IF for the next instruction
814         m_delayed_interrupt_enable = 1;
815      }
816   }
817}
818
819void i386_device::i386_mov_al_i8()         // Opcode 0xb0
820{
821   REG8(AL) = FETCH();
822   CYCLES(CYCLES_MOV_IMM_REG);
823}
824
825void i386_device::i386_mov_cl_i8()         // Opcode 0xb1
826{
827   REG8(CL) = FETCH();
828   CYCLES(CYCLES_MOV_IMM_REG);
829}
830
831void i386_device::i386_mov_dl_i8()         // Opcode 0xb2
832{
833   REG8(DL) = FETCH();
834   CYCLES(CYCLES_MOV_IMM_REG);
835}
836
837void i386_device::i386_mov_bl_i8()         // Opcode 0xb3
838{
839   REG8(BL) = FETCH();
840   CYCLES(CYCLES_MOV_IMM_REG);
841}
842
843void i386_device::i386_mov_ah_i8()         // Opcode 0xb4
844{
845   REG8(AH) = FETCH();
846   CYCLES(CYCLES_MOV_IMM_REG);
847}
848
849void i386_device::i386_mov_ch_i8()         // Opcode 0xb5
850{
851   REG8(CH) = FETCH();
852   CYCLES(CYCLES_MOV_IMM_REG);
853}
854
855void i386_device::i386_mov_dh_i8()         // Opcode 0xb6
856{
857   REG8(DH) = FETCH();
858   CYCLES(CYCLES_MOV_IMM_REG);
859}
860
861void i386_device::i386_mov_bh_i8()         // Opcode 0xb7
862{
863   REG8(BH) = FETCH();
864   CYCLES(CYCLES_MOV_IMM_REG);
865}
866
867void i386_device::i386_movsb()             // Opcode 0xa4
868{
869   UINT32 eas, ead;
870   UINT8 v;
871   if( m_segment_prefix ) {
872      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
873   } else {
874      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
875   }
876   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
877   v = READ8(eas);
878   WRITE8(ead, v);
879   BUMP_SI(1);
880   BUMP_DI(1);
881   CYCLES(CYCLES_MOVS);
882}
883
884void i386_device::i386_or_rm8_r8()         // Opcode 0x08
885{
886   UINT8 src, dst;
887   UINT8 modrm = FETCH();
888   if( modrm >= 0xc0 ) {
889      src = LOAD_REG8(modrm);
890      dst = LOAD_RM8(modrm);
891      dst = OR8(dst, src);
892      STORE_RM8(modrm, dst);
893      CYCLES(CYCLES_ALU_REG_REG);
894   } else {
895      UINT32 ea = GetEA(modrm,1);
896      src = LOAD_REG8(modrm);
897      dst = READ8(ea);
898      dst = OR8(dst, src);
899      WRITE8(ea, dst);
900      CYCLES(CYCLES_ALU_REG_MEM);
901   }
902}
903
904void i386_device::i386_or_r8_rm8()         // Opcode 0x0a
905{
906   UINT8 src, dst;
907   UINT8 modrm = FETCH();
908   if( modrm >= 0xc0 ) {
909      src = LOAD_RM8(modrm);
910      dst = LOAD_REG8(modrm);
911      dst = OR8(dst, src);
912      STORE_REG8(modrm, dst);
913      CYCLES(CYCLES_ALU_REG_REG);
914   } else {
915      UINT32 ea = GetEA(modrm,0);
916      src = READ8(ea);
917      dst = LOAD_REG8(modrm);
918      dst = OR8(dst, src);
919      STORE_REG8(modrm, dst);
920      CYCLES(CYCLES_ALU_MEM_REG);
921   }
922}
923
924void i386_device::i386_or_al_i8()          // Opcode 0x0c
925{
926   UINT8 src, dst;
927   src = FETCH();
928   dst = REG8(AL);
929   dst = OR8(dst, src);
930   REG8(EAX) = dst;
931   CYCLES(CYCLES_ALU_IMM_ACC);
932}
933
934void i386_device::i386_out_al_i8()         // Opcode 0xe6
935{
936   UINT16 port = FETCH();
937   UINT8 data = REG8(AL);
938   WRITEPORT8(port, data);
939   CYCLES(CYCLES_OUT_VAR);
940}
941
942void i386_device::i386_out_al_dx()         // Opcode 0xee
943{
944   UINT16 port = REG16(DX);
945   UINT8 data = REG8(AL);
946   WRITEPORT8(port, data);
947   CYCLES(CYCLES_OUT);
948}
949
950
951void i386_device::i386_arpl()           // Opcode 0x63
952{
953   UINT16 src, dst;
954   UINT8 modrm = FETCH();
955   UINT8 flag = 0;
956
957   if(PROTECTED_MODE && !V8086_MODE)
958   {
959         if( modrm >= 0xc0 ) {
960         src = LOAD_REG16(modrm);
961         dst = LOAD_RM16(modrm);
962         if( (dst&0x3) < (src&0x3) ) {
963            dst = (dst&0xfffc) | (src&0x3);
964            flag = 1;
965            STORE_RM16(modrm, dst);
966         }
967      } else {
968         UINT32 ea = GetEA(modrm,1);
969         src = LOAD_REG16(modrm);
970         dst = READ16(ea);
971         if( (dst&0x3) < (src&0x3) ) {
972            dst = (dst&0xfffc) | (src&0x3);
973            flag = 1;
974            WRITE16(ea, dst);
975         }
976      }
977      SetZF(flag);
978   }
979   else
980      i386_trap(6, 0, 0);  // invalid opcode in real mode or v8086 mode
981}
982
983void i386_device::i386_push_i8()           // Opcode 0x6a
984{
985   UINT8 value = FETCH();
986   PUSH8(value);
987   CYCLES(CYCLES_PUSH_IMM);
988}
989
990void i386_device::i386_ins_generic(int size)
991{
992   UINT32 ead;
993   UINT8 vb;
994   UINT16 vw;
995   UINT32 vd;
996
997   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
998
999   switch(size) {
1000   case 1:
1001      vb = READPORT8(REG16(DX));
1002      WRITE8(ead, vb);
1003      break;
1004   case 2:
1005      vw = READPORT16(REG16(DX));
1006      WRITE16(ead, vw);
1007      break;
1008   case 4:
1009      vd = READPORT32(REG16(DX));
1010      WRITE32(ead, vd);
1011      break;
1012   }
1013
1014   if(m_address_size)
1015      REG32(EDI) += ((m_DF) ? -1 : 1) * size;
1016   else
1017      REG16(DI) += ((m_DF) ? -1 : 1) * size;
1018   CYCLES(CYCLES_INS);    // TODO: Confirm this value
1019}
1020
1021void i386_device::i386_insb()              // Opcode 0x6c
1022{
1023   i386_ins_generic(1);
1024}
1025
1026void i386_device::i386_insw()              // Opcode 0x6d
1027{
1028   i386_ins_generic(2);
1029}
1030
1031void i386_device::i386_insd()              // Opcode 0x6d
1032{
1033   i386_ins_generic(4);
1034}
1035
1036void i386_device::i386_outs_generic(int size)
1037{
1038   UINT32 eas;
1039   UINT8 vb;
1040   UINT16 vw;
1041   UINT32 vd;
1042
1043   if( m_segment_prefix ) {
1044      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1045   } else {
1046      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1047   }
1048
1049   switch(size) {
1050   case 1:
1051      vb = READ8(eas);
1052      WRITEPORT8(REG16(DX), vb);
1053      break;
1054   case 2:
1055      vw = READ16(eas);
1056      WRITEPORT16(REG16(DX), vw);
1057      break;
1058   case 4:
1059      vd = READ32(eas);
1060      WRITEPORT32(REG16(DX), vd);
1061      break;
1062   }
1063
1064   if(m_address_size)
1065      REG32(ESI) += ((m_DF) ? -1 : 1) * size;
1066   else
1067      REG16(SI) += ((m_DF) ? -1 : 1) * size;
1068   CYCLES(CYCLES_OUTS);   // TODO: Confirm this value
1069}
1070
1071void i386_device::i386_outsb()             // Opcode 0x6e
1072{
1073   i386_outs_generic(1);
1074}
1075
1076void i386_device::i386_outsw()             // Opcode 0x6f
1077{
1078   i386_outs_generic(2);
1079}
1080
1081void i386_device::i386_outsd()             // Opcode 0x6f
1082{
1083   i386_outs_generic(4);
1084}
1085
1086void i386_device::i386_repeat(int invert_flag)
1087{
1088   UINT32 repeated_eip = m_eip;
1089   UINT32 repeated_pc = m_pc;
1090   UINT8 opcode; // = FETCH();
1091//  UINT32 eas, ead;
1092   UINT32 count;
1093   INT32 cycle_base = 0, cycle_adjustment = 0;
1094   UINT8 prefix_flag=1;
1095   UINT8 *flag = NULL;
1096
1097
1098   do {
1099   repeated_eip = m_eip;
1100   repeated_pc = m_pc;
1101   opcode = FETCH();
1102   switch(opcode) {
1103      case 0x0f:
1104      if (invert_flag == 0)
1105         i386_decode_three_bytef3(); // sse f3 0f
1106      else
1107         i386_decode_three_bytef2(); // sse f2 0f
1108      return;
1109      case 0x26:
1110      m_segment_override=ES;
1111      m_segment_prefix=1;
1112      break;
1113      case 0x2e:
1114      m_segment_override=CS;
1115      m_segment_prefix=1;
1116      break;
1117      case 0x36:
1118      m_segment_override=SS;
1119      m_segment_prefix=1;
1120      break;
1121      case 0x3e:
1122      m_segment_override=DS;
1123      m_segment_prefix=1;
1124      break;
1125      case 0x64:
1126      m_segment_override=FS;
1127      m_segment_prefix=1;
1128      break;
1129      case 0x65:
1130      m_segment_override=GS;
1131      m_segment_prefix=1;
1132      break;
1133      case 0x66:
1134      m_operand_size ^= 1;
1135      break;
1136      case 0x67:
1137      m_address_size ^= 1;
1138      break;
1139      default:
1140      prefix_flag=0;
1141   }
1142   } while (prefix_flag);
1143
1144
1145   if( m_segment_prefix ) {
1146      // FIXME: the following does not work if both address override and segment override are used
1147      i386_translate(m_segment_override, m_sreg[m_segment_prefix].d ? REG32(ESI) : REG16(SI), -1 );
1148   } else {
1149      //eas =
1150      i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), -1 );
1151   }
1152   i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), -1 );
1153
1154   switch(opcode)
1155   {
1156      case 0x6c:
1157      case 0x6d:
1158         /* INSB, INSW, INSD */
1159         // TODO: cycle count
1160         cycle_base = 8;
1161         cycle_adjustment = -4;
1162         flag = NULL;
1163         break;
1164
1165      case 0x6e:
1166      case 0x6f:
1167         /* OUTSB, OUTSW, OUTSD */
1168         // TODO: cycle count
1169         cycle_base = 8;
1170         cycle_adjustment = -4;
1171         flag = NULL;
1172         break;
1173
1174      case 0xa4:
1175      case 0xa5:
1176         /* MOVSB, MOVSW, MOVSD */
1177         cycle_base = 8;
1178         cycle_adjustment = -4;
1179         flag = NULL;
1180         break;
1181
1182      case 0xa6:
1183      case 0xa7:
1184         /* CMPSB, CMPSW, CMPSD */
1185         cycle_base = 5;
1186         cycle_adjustment = -1;
1187         flag = &m_ZF;
1188         break;
1189
1190      case 0xac:
1191      case 0xad:
1192         /* LODSB, LODSW, LODSD */
1193         cycle_base = 5;
1194         cycle_adjustment = 1;
1195         flag = NULL;
1196         break;
1197
1198      case 0xaa:
1199      case 0xab:
1200         /* STOSB, STOSW, STOSD */
1201         cycle_base = 5;
1202         cycle_adjustment = 0;
1203         flag = NULL;
1204         break;
1205
1206      case 0xae:
1207      case 0xaf:
1208         /* SCASB, SCASW, SCASD */
1209         cycle_base = 5;
1210         cycle_adjustment = 0;
1211         flag = &m_ZF;
1212         break;
1213
1214      case 0x90:
1215         CYCLES(CYCLES_NOP);
1216         return;
1217
1218      case 0xc2: // sigh
1219      case 0xc3:
1220         m_pc--;
1221         return;
1222
1223      default:
1224         fatalerror("i386: Invalid REP/opcode %02X combination\n",opcode);
1225         break;
1226   }
1227
1228   if( m_address_size ) {
1229      if( REG32(ECX) == 0 )
1230         return;
1231   } else {
1232      if( REG16(CX) == 0 )
1233         return;
1234   }
1235
1236   /* now actually perform the repeat */
1237   CYCLES_NUM(cycle_base);
1238   do
1239   {
1240      m_eip = repeated_eip;
1241      m_pc = repeated_pc;
1242      try
1243      {
1244         i386_decode_opcode();
1245      }
1246      catch (UINT64 e)
1247      {
1248         m_eip = m_prev_eip;
1249         throw e;
1250      }
1251
1252      CYCLES_NUM(cycle_adjustment);
1253
1254      if (m_address_size)
1255         count = --REG32(ECX);
1256      else
1257         count = --REG16(CX);
1258      if (m_cycles <= 0)
1259         goto outofcycles;
1260   }
1261   while( count && (!flag || (invert_flag ? !*flag : *flag)) );
1262   return;
1263
1264outofcycles:
1265   /* if we run out of cycles to execute, and we are still in the repeat, we need
1266    * to exit this instruction in such a way to go right back into it when we have
1267    * time to execute cycles */
1268   if(flag && (invert_flag ? *flag : !*flag))
1269      return;
1270   m_eip = m_prev_eip;
1271   CHANGE_PC(m_eip);
1272   CYCLES_NUM(-cycle_base);
1273}
1274
1275void i386_device::i386_rep()               // Opcode 0xf3
1276{
1277   i386_repeat(0);
1278}
1279
1280void i386_device::i386_repne()             // Opcode 0xf2
1281{
1282   i386_repeat(1);
1283}
1284
1285void i386_device::i386_sahf()              // Opcode 0x9e
1286{
1287   set_flags((get_flags() & 0xffffff00) | (REG8(AH) & 0xd7) );
1288   CYCLES(CYCLES_SAHF);
1289}
1290
1291void i386_device::i386_sbb_rm8_r8()        // Opcode 0x18
1292{
1293   UINT8 src, dst;
1294   UINT8 modrm = FETCH();
1295   if( modrm >= 0xc0 ) {
1296      src = LOAD_REG8(modrm);
1297      dst = LOAD_RM8(modrm);
1298      dst = SBB8(dst, src, m_CF);
1299      STORE_RM8(modrm, dst);
1300      CYCLES(CYCLES_ALU_REG_REG);
1301   } else {
1302      UINT32 ea = GetEA(modrm,1);
1303      src = LOAD_REG8(modrm);
1304      dst = READ8(ea);
1305      dst = SBB8(dst, src, m_CF);
1306      WRITE8(ea, dst);
1307      CYCLES(CYCLES_ALU_REG_MEM);
1308   }
1309}
1310
1311void i386_device::i386_sbb_r8_rm8()        // Opcode 0x1a
1312{
1313   UINT8 src, dst;
1314   UINT8 modrm = FETCH();
1315   if( modrm >= 0xc0 ) {
1316      src = LOAD_RM8(modrm);
1317      dst = LOAD_REG8(modrm);
1318      dst = SBB8(dst, src, m_CF);
1319      STORE_REG8(modrm, dst);
1320      CYCLES(CYCLES_ALU_REG_REG);
1321   } else {
1322      UINT32 ea = GetEA(modrm,0);
1323      src = READ8(ea);
1324      dst = LOAD_REG8(modrm);
1325      dst = SBB8(dst, src, m_CF);
1326      STORE_REG8(modrm, dst);
1327      CYCLES(CYCLES_ALU_MEM_REG);
1328   }
1329}
1330
1331void i386_device::i386_sbb_al_i8()         // Opcode 0x1c
1332{
1333   UINT8 src, dst;
1334   src = FETCH();
1335   dst = REG8(AL);
1336   dst = SBB8(dst, src, m_CF);
1337   REG8(EAX) = dst;
1338   CYCLES(CYCLES_ALU_IMM_ACC);
1339}
1340
1341void i386_device::i386_scasb()             // Opcode 0xae
1342{
1343   UINT32 eas;
1344   UINT8 src, dst;
1345   eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
1346   src = READ8(eas);
1347   dst = REG8(AL);
1348   SUB8(dst, src);
1349   BUMP_DI(1);
1350   CYCLES(CYCLES_SCAS);
1351}
1352
1353void i386_device::i386_setalc()            // Opcode 0xd6 (undocumented)
1354{
1355   if( m_CF ) {
1356      REG8(AL) = 0xff;
1357   } else {
1358      REG8(AL) = 0;
1359   }
1360   CYCLES(3);
1361}
1362
1363void i386_device::i386_seta_rm8()          // Opcode 0x0f 97
1364{
1365   UINT8 modrm = FETCH();
1366   UINT8 value = 0;
1367   if( m_CF == 0 && m_ZF == 0 ) {
1368      value = 1;
1369   }
1370   if( modrm >= 0xc0 ) {
1371      STORE_RM8(modrm, value);
1372      CYCLES(CYCLES_SETCC_REG);
1373   } else {
1374      UINT32 ea = GetEA(modrm,1);
1375      WRITE8(ea, value);
1376      CYCLES(CYCLES_SETCC_MEM);
1377   }
1378}
1379
1380void i386_device::i386_setbe_rm8()         // Opcode 0x0f 96
1381{
1382   UINT8 modrm = FETCH();
1383   UINT8 value = 0;
1384   if( m_CF != 0 || m_ZF != 0 ) {
1385      value = 1;
1386   }
1387   if( modrm >= 0xc0 ) {
1388      STORE_RM8(modrm, value);
1389      CYCLES(CYCLES_SETCC_REG);
1390   } else {
1391      UINT32 ea = GetEA(modrm,1);
1392      WRITE8(ea, value);
1393      CYCLES(CYCLES_SETCC_MEM);
1394   }
1395}
1396
1397void i386_device::i386_setc_rm8()          // Opcode 0x0f 92
1398{
1399   UINT8 modrm = FETCH();
1400   UINT8 value = 0;
1401   if( m_CF != 0 ) {
1402      value = 1;
1403   }
1404   if( modrm >= 0xc0 ) {
1405      STORE_RM8(modrm, value);
1406      CYCLES(CYCLES_SETCC_REG);
1407   } else {
1408      UINT32 ea = GetEA(modrm,1);
1409      WRITE8(ea, value);
1410      CYCLES(CYCLES_SETCC_MEM);
1411   }
1412}
1413
1414void i386_device::i386_setg_rm8()          // Opcode 0x0f 9f
1415{
1416   UINT8 modrm = FETCH();
1417   UINT8 value = 0;
1418   if( m_ZF == 0 && (m_SF == m_OF) ) {
1419      value = 1;
1420   }
1421   if( modrm >= 0xc0 ) {
1422      STORE_RM8(modrm, value);
1423      CYCLES(CYCLES_SETCC_REG);
1424   } else {
1425      UINT32 ea = GetEA(modrm,1);
1426      WRITE8(ea, value);
1427      CYCLES(CYCLES_SETCC_MEM);
1428   }
1429}
1430
1431void i386_device::i386_setge_rm8()         // Opcode 0x0f 9d
1432{
1433   UINT8 modrm = FETCH();
1434   UINT8 value = 0;
1435   if(m_SF == m_OF) {
1436      value = 1;
1437   }
1438   if( modrm >= 0xc0 ) {
1439      STORE_RM8(modrm, value);
1440      CYCLES(CYCLES_SETCC_REG);
1441   } else {
1442      UINT32 ea = GetEA(modrm,1);
1443      WRITE8(ea, value);
1444      CYCLES(CYCLES_SETCC_MEM);
1445   }
1446}
1447
1448void i386_device::i386_setl_rm8()          // Opcode 0x0f 9c
1449{
1450   UINT8 modrm = FETCH();
1451   UINT8 value = 0;
1452   if( m_SF != m_OF ) {
1453      value = 1;
1454   }
1455   if( modrm >= 0xc0 ) {
1456      STORE_RM8(modrm, value);
1457      CYCLES(CYCLES_SETCC_REG);
1458   } else {
1459      UINT32 ea = GetEA(modrm,1);
1460      WRITE8(ea, value);
1461      CYCLES(CYCLES_SETCC_MEM);
1462   }
1463}
1464
1465void i386_device::i386_setle_rm8()         // Opcode 0x0f 9e
1466{
1467   UINT8 modrm = FETCH();
1468   UINT8 value = 0;
1469   if( m_ZF != 0 || (m_SF != m_OF) ) {
1470      value = 1;
1471   }
1472   if( modrm >= 0xc0 ) {
1473      STORE_RM8(modrm, value);
1474      CYCLES(CYCLES_SETCC_REG);
1475   } else {
1476      UINT32 ea = GetEA(modrm,1);
1477      WRITE8(ea, value);
1478      CYCLES(CYCLES_SETCC_MEM);
1479   }
1480}
1481
1482void i386_device::i386_setnc_rm8()         // Opcode 0x0f 93
1483{
1484   UINT8 modrm = FETCH();
1485   UINT8 value = 0;
1486   if( m_CF == 0 ) {
1487      value = 1;
1488   }
1489   if( modrm >= 0xc0 ) {
1490      STORE_RM8(modrm, value);
1491      CYCLES(CYCLES_SETCC_REG);
1492   } else {
1493      UINT32 ea = GetEA(modrm,1);
1494      WRITE8(ea, value);
1495      CYCLES(CYCLES_SETCC_MEM);
1496   }
1497}
1498
1499void i386_device::i386_setno_rm8()         // Opcode 0x0f 91
1500{
1501   UINT8 modrm = FETCH();
1502   UINT8 value = 0;
1503   if( m_OF == 0 ) {
1504      value = 1;
1505   }
1506   if( modrm >= 0xc0 ) {
1507      STORE_RM8(modrm, value);
1508      CYCLES(CYCLES_SETCC_REG);
1509   } else {
1510      UINT32 ea = GetEA(modrm,1);
1511      WRITE8(ea, value);
1512      CYCLES(CYCLES_SETCC_MEM);
1513   }
1514}
1515
1516void i386_device::i386_setnp_rm8()         // Opcode 0x0f 9b
1517{
1518   UINT8 modrm = FETCH();
1519   UINT8 value = 0;
1520   if( m_PF == 0 ) {
1521      value = 1;
1522   }
1523   if( modrm >= 0xc0 ) {
1524      STORE_RM8(modrm, value);
1525      CYCLES(CYCLES_SETCC_REG);
1526   } else {
1527      UINT32 ea = GetEA(modrm,1);
1528      WRITE8(ea, value);
1529      CYCLES(CYCLES_SETCC_MEM);
1530   }
1531}
1532
1533void i386_device::i386_setns_rm8()         // Opcode 0x0f 99
1534{
1535   UINT8 modrm = FETCH();
1536   UINT8 value = 0;
1537   if( m_SF == 0 ) {
1538      value = 1;
1539   }
1540   if( modrm >= 0xc0 ) {
1541      STORE_RM8(modrm, value);
1542      CYCLES(CYCLES_SETCC_REG);
1543   } else {
1544      UINT32 ea = GetEA(modrm,1);
1545      WRITE8(ea, value);
1546      CYCLES(CYCLES_SETCC_MEM);
1547   }
1548}
1549
1550void i386_device::i386_setnz_rm8()         // Opcode 0x0f 95
1551{
1552   UINT8 modrm = FETCH();
1553   UINT8 value = 0;
1554   if( m_ZF == 0 ) {
1555      value = 1;
1556   }
1557   if( modrm >= 0xc0 ) {
1558      STORE_RM8(modrm, value);
1559      CYCLES(CYCLES_SETCC_REG);
1560   } else {
1561      UINT32 ea = GetEA(modrm,1);
1562      WRITE8(ea, value);
1563      CYCLES(CYCLES_SETCC_MEM);
1564   }
1565}
1566
1567void i386_device::i386_seto_rm8()          // Opcode 0x0f 90
1568{
1569   UINT8 modrm = FETCH();
1570   UINT8 value = 0;
1571   if( m_OF != 0 ) {
1572      value = 1;
1573   }
1574   if( modrm >= 0xc0 ) {
1575      STORE_RM8(modrm, value);
1576      CYCLES(CYCLES_SETCC_REG);
1577   } else {
1578      UINT32 ea = GetEA(modrm,1);
1579      WRITE8(ea, value);
1580      CYCLES(CYCLES_SETCC_MEM);
1581   }
1582}
1583
1584void i386_device::i386_setp_rm8()          // Opcode 0x0f 9a
1585{
1586   UINT8 modrm = FETCH();
1587   UINT8 value = 0;
1588   if( m_PF != 0 ) {
1589      value = 1;
1590   }
1591   if( modrm >= 0xc0 ) {
1592      STORE_RM8(modrm, value);
1593      CYCLES(CYCLES_SETCC_REG);
1594   } else {
1595      UINT32 ea = GetEA(modrm,1);
1596      WRITE8(ea, value);
1597      CYCLES(CYCLES_SETCC_MEM);
1598   }
1599}
1600
1601void i386_device::i386_sets_rm8()          // Opcode 0x0f 98
1602{
1603   UINT8 modrm = FETCH();
1604   UINT8 value = 0;
1605   if( m_SF != 0 ) {
1606      value = 1;
1607   }
1608   if( modrm >= 0xc0 ) {
1609      STORE_RM8(modrm, value);
1610      CYCLES(CYCLES_SETCC_REG);
1611   } else {
1612      UINT32 ea = GetEA(modrm,1);
1613      WRITE8(ea, value);
1614      CYCLES(CYCLES_SETCC_MEM);
1615   }
1616}
1617
1618void i386_device::i386_setz_rm8()          // Opcode 0x0f 94
1619{
1620   UINT8 modrm = FETCH();
1621   UINT8 value = 0;
1622   if( m_ZF != 0 ) {
1623      value = 1;
1624   }
1625   if( modrm >= 0xc0 ) {
1626      STORE_RM8(modrm, value);
1627      CYCLES(CYCLES_SETCC_REG);
1628   } else {
1629      UINT32 ea = GetEA(modrm,1);
1630      WRITE8(ea, value);
1631      CYCLES(CYCLES_SETCC_MEM);
1632   }
1633}
1634
1635void i386_device::i386_stc()               // Opcode 0xf9
1636{
1637   m_CF = 1;
1638   CYCLES(CYCLES_STC);
1639}
1640
1641void i386_device::i386_std()               // Opcode 0xfd
1642{
1643   m_DF = 1;
1644   CYCLES(CYCLES_STD);
1645}
1646
1647void i386_device::i386_sti()               // Opcode 0xfb
1648{
1649   if(PROTECTED_MODE)
1650   {
1651      UINT8 IOPL = m_IOP1 | (m_IOP2 << 1);
1652      if(m_CPL > IOPL)
1653         FAULT(FAULT_GP,0);
1654   }
1655   m_delayed_interrupt_enable = 1;  // IF is set after the next instruction.
1656   CYCLES(CYCLES_STI);
1657}
1658
1659void i386_device::i386_stosb()             // Opcode 0xaa
1660{
1661   UINT32 ead;
1662   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
1663   WRITE8(ead, REG8(AL));
1664   BUMP_DI(1);
1665   CYCLES(CYCLES_STOS);
1666}
1667
1668void i386_device::i386_sub_rm8_r8()        // Opcode 0x28
1669{
1670   UINT8 src, dst;
1671   UINT8 modrm = FETCH();
1672   if( modrm >= 0xc0 ) {
1673      src = LOAD_REG8(modrm);
1674      dst = LOAD_RM8(modrm);
1675      dst = SUB8(dst, src);
1676      STORE_RM8(modrm, dst);
1677      CYCLES(CYCLES_ALU_REG_REG);
1678   } else {
1679      UINT32 ea = GetEA(modrm,1);
1680      src = LOAD_REG8(modrm);
1681      dst = READ8(ea);
1682      dst = SUB8(dst, src);
1683      WRITE8(ea, dst);
1684      CYCLES(CYCLES_ALU_REG_MEM);
1685   }
1686}
1687
1688void i386_device::i386_sub_r8_rm8()        // Opcode 0x2a
1689{
1690   UINT8 src, dst;
1691   UINT8 modrm = FETCH();
1692   if( modrm >= 0xc0 ) {
1693      src = LOAD_RM8(modrm);
1694      dst = LOAD_REG8(modrm);
1695      dst = SUB8(dst, src);
1696      STORE_REG8(modrm, dst);
1697      CYCLES(CYCLES_ALU_REG_REG);
1698   } else {
1699      UINT32 ea = GetEA(modrm,0);
1700      src = READ8(ea);
1701      dst = LOAD_REG8(modrm);
1702      dst = SUB8(dst, src);
1703      STORE_REG8(modrm, dst);
1704      CYCLES(CYCLES_ALU_MEM_REG);
1705   }
1706}
1707
1708void i386_device::i386_sub_al_i8()         // Opcode 0x2c
1709{
1710   UINT8 src, dst;
1711   src = FETCH();
1712   dst = REG8(EAX);
1713   dst = SUB8(dst, src);
1714   REG8(EAX) = dst;
1715   CYCLES(CYCLES_ALU_IMM_ACC);
1716}
1717
1718void i386_device::i386_test_al_i8()        // Opcode 0xa8
1719{
1720   UINT8 src = FETCH();
1721   UINT8 dst = REG8(AL);
1722   dst = src & dst;
1723   SetSZPF8(dst);
1724   m_CF = 0;
1725   m_OF = 0;
1726   CYCLES(CYCLES_ALU_IMM_ACC);
1727}
1728
1729void i386_device::i386_test_rm8_r8()       // Opcode 0x84
1730{
1731   UINT8 src, dst;
1732   UINT8 modrm = FETCH();
1733   if( modrm >= 0xc0 ) {
1734      src = LOAD_REG8(modrm);
1735      dst = LOAD_RM8(modrm);
1736      dst = src & dst;
1737      SetSZPF8(dst);
1738      m_CF = 0;
1739      m_OF = 0;
1740      CYCLES(CYCLES_TEST_REG_REG);
1741   } else {
1742      UINT32 ea = GetEA(modrm,0);
1743      src = LOAD_REG8(modrm);
1744      dst = READ8(ea);
1745      dst = src & dst;
1746      SetSZPF8(dst);
1747      m_CF = 0;
1748      m_OF = 0;
1749      CYCLES(CYCLES_TEST_REG_MEM);
1750   }
1751}
1752
1753void i386_device::i386_xchg_r8_rm8()       // Opcode 0x86
1754{
1755   UINT8 modrm = FETCH();
1756   if( modrm >= 0xc0 ) {
1757      UINT8 src = LOAD_RM8(modrm);
1758      UINT8 dst = LOAD_REG8(modrm);
1759      STORE_REG8(modrm, src);
1760      STORE_RM8(modrm, dst);
1761      CYCLES(CYCLES_XCHG_REG_REG);
1762   } else {
1763      UINT32 ea = GetEA(modrm,1);
1764      UINT8 src = READ8(ea);
1765      UINT8 dst = LOAD_REG8(modrm);
1766      WRITE8(ea, dst);
1767      STORE_REG8(modrm, src);
1768      CYCLES(CYCLES_XCHG_REG_MEM);
1769   }
1770}
1771
1772void i386_device::i386_xor_rm8_r8()        // Opcode 0x30
1773{
1774   UINT8 src, dst;
1775   UINT8 modrm = FETCH();
1776   if( modrm >= 0xc0 ) {
1777      src = LOAD_REG8(modrm);
1778      dst = LOAD_RM8(modrm);
1779      dst = XOR8(dst, src);
1780      STORE_RM8(modrm, dst);
1781      CYCLES(CYCLES_ALU_REG_REG);
1782   } else {
1783      UINT32 ea = GetEA(modrm,1);
1784      src = LOAD_REG8(modrm);
1785      dst = READ8(ea);
1786      dst = XOR8(dst, src);
1787      WRITE8(ea, dst);
1788      CYCLES(CYCLES_ALU_REG_MEM);
1789   }
1790}
1791
1792void i386_device::i386_xor_r8_rm8()        // Opcode 0x32
1793{
1794   UINT32 src, dst;
1795   UINT8 modrm = FETCH();
1796   if( modrm >= 0xc0 ) {
1797      src = LOAD_RM8(modrm);
1798      dst = LOAD_REG8(modrm);
1799      dst = XOR8(dst, src);
1800      STORE_REG8(modrm, dst);
1801      CYCLES(CYCLES_ALU_REG_REG);
1802   } else {
1803      UINT32 ea = GetEA(modrm,0);
1804      src = READ8(ea);
1805      dst = LOAD_REG8(modrm);
1806      dst = XOR8(dst, src);
1807      STORE_REG8(modrm, dst);
1808      CYCLES(CYCLES_ALU_MEM_REG);
1809   }
1810}
1811
1812void i386_device::i386_xor_al_i8()         // Opcode 0x34
1813{
1814   UINT8 src, dst;
1815   src = FETCH();
1816   dst = REG8(AL);
1817   dst = XOR8(dst, src);
1818   REG8(AL) = dst;
1819   CYCLES(CYCLES_ALU_IMM_ACC);
1820}
1821
1822
1823
1824void i386_device::i386_group80_8()         // Opcode 0x80
1825{
1826   UINT32 ea;
1827   UINT8 src, dst;
1828   UINT8 modrm = FETCH();
1829
1830   switch( (modrm >> 3) & 0x7 )
1831   {
1832      case 0:     // ADD Rm8, i8
1833         if( modrm >= 0xc0 ) {
1834            dst = LOAD_RM8(modrm);
1835            src = FETCH();
1836            dst = ADD8(dst, src);
1837            STORE_RM8(modrm, dst);
1838            CYCLES(CYCLES_ALU_REG_REG);
1839         } else {
1840            ea = GetEA(modrm,0);
1841            dst = READ8(ea);
1842            src = FETCH();
1843            dst = ADD8(dst, src);
1844            WRITE8(ea, dst);
1845            CYCLES(CYCLES_ALU_REG_MEM);
1846         }
1847         break;
1848      case 1:     // OR Rm8, i8
1849         if( modrm >= 0xc0 ) {
1850            dst = LOAD_RM8(modrm);
1851            src = FETCH();
1852            dst = OR8(dst, src);
1853            STORE_RM8(modrm, dst);
1854            CYCLES(CYCLES_ALU_REG_REG);
1855         } else {
1856            ea = GetEA(modrm,1);
1857            dst = READ8(ea);
1858            src = FETCH();
1859            dst = OR8(dst, src);
1860            WRITE8(ea, dst);
1861            CYCLES(CYCLES_ALU_REG_MEM);
1862         }
1863         break;
1864      case 2:     // ADC Rm8, i8
1865         if( modrm >= 0xc0 ) {
1866            dst = LOAD_RM8(modrm);
1867            src = FETCH();
1868            dst = ADC8(dst, src, m_CF);
1869            STORE_RM8(modrm, dst);
1870            CYCLES(CYCLES_ALU_REG_REG);
1871         } else {
1872            ea = GetEA(modrm,1);
1873            dst = READ8(ea);
1874            src = FETCH();
1875            dst = ADC8(dst, src, m_CF);
1876            WRITE8(ea, dst);
1877            CYCLES(CYCLES_ALU_REG_MEM);
1878         }
1879         break;
1880      case 3:     // SBB Rm8, i8
1881         if( modrm >= 0xc0 ) {
1882            dst = LOAD_RM8(modrm);
1883            src = FETCH();
1884            dst = SBB8(dst, src, m_CF);
1885            STORE_RM8(modrm, dst);
1886            CYCLES(CYCLES_ALU_REG_REG);
1887         } else {
1888            ea = GetEA(modrm,1);
1889            dst = READ8(ea);
1890            src = FETCH();
1891            dst = SBB8(dst, src, m_CF);
1892            WRITE8(ea, dst);
1893            CYCLES(CYCLES_ALU_REG_MEM);
1894         }
1895         break;
1896      case 4:     // AND Rm8, i8
1897         if( modrm >= 0xc0 ) {
1898            dst = LOAD_RM8(modrm);
1899            src = FETCH();
1900            dst = AND8(dst, src);
1901            STORE_RM8(modrm, dst);
1902            CYCLES(CYCLES_ALU_REG_REG);
1903         } else {
1904            ea = GetEA(modrm,1);
1905            dst = READ8(ea);
1906            src = FETCH();
1907            dst = AND8(dst, src);
1908            WRITE8(ea, dst);
1909            CYCLES(CYCLES_ALU_REG_MEM);
1910         }
1911         break;
1912      case 5:     // SUB Rm8, i8
1913         if( modrm >= 0xc0 ) {
1914            dst = LOAD_RM8(modrm);
1915            src = FETCH();
1916            dst = SUB8(dst, src);
1917            STORE_RM8(modrm, dst);
1918            CYCLES(CYCLES_ALU_REG_REG);
1919         } else {
1920            ea = GetEA(modrm,1);
1921            dst = READ8(ea);
1922            src = FETCH();
1923            dst = SUB8(dst, src);
1924            WRITE8(ea, dst);
1925            CYCLES(CYCLES_ALU_REG_MEM);
1926         }
1927         break;
1928      case 6:     // XOR Rm8, i8
1929         if( modrm >= 0xc0 ) {
1930            dst = LOAD_RM8(modrm);
1931            src = FETCH();
1932            dst = XOR8(dst, src);
1933            STORE_RM8(modrm, dst);
1934            CYCLES(CYCLES_ALU_REG_REG);
1935         } else {
1936            ea = GetEA(modrm,1);
1937            dst = READ8(ea);
1938            src = FETCH();
1939            dst = XOR8(dst, src);
1940            WRITE8(ea, dst);
1941            CYCLES(CYCLES_ALU_REG_MEM);
1942         }
1943         break;
1944      case 7:     // CMP Rm8, i8
1945         if( modrm >= 0xc0 ) {
1946            dst = LOAD_RM8(modrm);
1947            src = FETCH();
1948            SUB8(dst, src);
1949            CYCLES(CYCLES_CMP_REG_REG);
1950         } else {
1951            ea = GetEA(modrm,0);
1952            dst = READ8(ea);
1953            src = FETCH();
1954            SUB8(dst, src);
1955            CYCLES(CYCLES_CMP_REG_MEM);
1956         }
1957         break;
1958   }
1959}
1960
1961void i386_device::i386_groupC0_8()         // Opcode 0xc0
1962{
1963   UINT8 dst;
1964   UINT8 modrm = FETCH();
1965   UINT8 shift;
1966
1967   if( modrm >= 0xc0 ) {
1968      dst = LOAD_RM8(modrm);
1969      shift = FETCH() & 0x1f;
1970      dst = i386_shift_rotate8(modrm, dst, shift);
1971      STORE_RM8(modrm, dst);
1972   } else {
1973      UINT32 ea = GetEA(modrm,1);
1974      dst = READ8(ea);
1975      shift = FETCH() & 0x1f;
1976      dst = i386_shift_rotate8(modrm, dst, shift);
1977      WRITE8(ea, dst);
1978   }
1979}
1980
1981void i386_device::i386_groupD0_8()         // Opcode 0xd0
1982{
1983   UINT8 dst;
1984   UINT8 modrm = FETCH();
1985
1986   if( modrm >= 0xc0 ) {
1987      dst = LOAD_RM8(modrm);
1988      dst = i386_shift_rotate8(modrm, dst, 1);
1989      STORE_RM8(modrm, dst);
1990   } else {
1991      UINT32 ea = GetEA(modrm,1);
1992      dst = READ8(ea);
1993      dst = i386_shift_rotate8(modrm, dst, 1);
1994      WRITE8(ea, dst);
1995   }
1996}
1997
1998void i386_device::i386_groupD2_8()         // Opcode 0xd2
1999{
2000   UINT8 dst;
2001   UINT8 modrm = FETCH();
2002
2003   if( modrm >= 0xc0 ) {
2004      dst = LOAD_RM8(modrm);
2005      dst = i386_shift_rotate8(modrm, dst, REG8(CL));
2006      STORE_RM8(modrm, dst);
2007   } else {
2008      UINT32 ea = GetEA(modrm,1);
2009      dst = READ8(ea);
2010      dst = i386_shift_rotate8(modrm, dst, REG8(CL));
2011      WRITE8(ea, dst);
2012   }
2013}
2014
2015void i386_device::i386_groupF6_8()         // Opcode 0xf6
2016{
2017   UINT8 modrm = FETCH();
2018
2019   switch( (modrm >> 3) & 0x7 )
2020   {
2021      case 0:         /* TEST Rm8, i8 */
2022         if( modrm >= 0xc0 ) {
2023            UINT8 dst = LOAD_RM8(modrm);
2024            UINT8 src = FETCH();
2025            dst &= src;
2026            m_CF = m_OF = m_AF = 0;
2027            SetSZPF8(dst);
2028            CYCLES(CYCLES_TEST_IMM_REG);
2029         } else {
2030            UINT32 ea = GetEA(modrm,0);
2031            UINT8 dst = READ8(ea);
2032            UINT8 src = FETCH();
2033            dst &= src;
2034            m_CF = m_OF = m_AF = 0;
2035            SetSZPF8(dst);
2036            CYCLES(CYCLES_TEST_IMM_MEM);
2037         }
2038         break;
2039      case 2:         /* NOT Rm8 */
2040         if( modrm >= 0xc0 ) {
2041            UINT8 dst = LOAD_RM8(modrm);
2042            dst = ~dst;
2043            STORE_RM8(modrm, dst);
2044            CYCLES(CYCLES_NOT_REG);
2045         } else {
2046            UINT32 ea = GetEA(modrm,1);
2047            UINT8 dst = READ8(ea);
2048            dst = ~dst;
2049            WRITE8(ea, dst);
2050            CYCLES(CYCLES_NOT_MEM);
2051         }
2052         break;
2053      case 3:         /* NEG Rm8 */
2054         if( modrm >= 0xc0 ) {
2055            UINT8 dst = LOAD_RM8(modrm);
2056            dst = SUB8(0, dst );
2057            STORE_RM8(modrm, dst);
2058            CYCLES(CYCLES_NEG_REG);
2059         } else {
2060            UINT32 ea = GetEA(modrm,1);
2061            UINT8 dst = READ8(ea);
2062            dst = SUB8(0, dst );
2063            WRITE8(ea, dst);
2064            CYCLES(CYCLES_NEG_MEM);
2065         }
2066         break;
2067      case 4:         /* MUL AL, Rm8 */
2068         {
2069            UINT16 result;
2070            UINT8 src, dst;
2071            if( modrm >= 0xc0 ) {
2072               src = LOAD_RM8(modrm);
2073               CYCLES(CYCLES_MUL8_ACC_REG);       /* TODO: Correct multiply timing */
2074            } else {
2075               UINT32 ea = GetEA(modrm,0);
2076               src = READ8(ea);
2077               CYCLES(CYCLES_MUL8_ACC_MEM);       /* TODO: Correct multiply timing */
2078            }
2079
2080            dst = REG8(AL);
2081            result = (UINT16)src * (UINT16)dst;
2082            REG16(AX) = (UINT16)result;
2083
2084            m_CF = m_OF = (REG16(AX) > 0xff);
2085         }
2086         break;
2087      case 5:         /* IMUL AL, Rm8 */
2088         {
2089            INT16 result;
2090            INT16 src, dst;
2091            if( modrm >= 0xc0 ) {
2092               src = (INT16)(INT8)LOAD_RM8(modrm);
2093               CYCLES(CYCLES_IMUL8_ACC_REG);      /* TODO: Correct multiply timing */
2094            } else {
2095               UINT32 ea = GetEA(modrm,0);
2096               src = (INT16)(INT8)READ8(ea);
2097               CYCLES(CYCLES_IMUL8_ACC_MEM);      /* TODO: Correct multiply timing */
2098            }
2099
2100            dst = (INT16)(INT8)REG8(AL);
2101            result = src * dst;
2102
2103            REG16(AX) = (UINT16)result;
2104
2105            m_CF = m_OF = !(result == (INT16)(INT8)result);
2106         }
2107         break;
2108      case 6:         /* DIV AL, Rm8 */
2109         {
2110            UINT16 quotient, remainder, result;
2111            UINT8 src;
2112            if( modrm >= 0xc0 ) {
2113               src = LOAD_RM8(modrm);
2114               CYCLES(CYCLES_DIV8_ACC_REG);
2115            } else {
2116               UINT32 ea = GetEA(modrm,0);
2117               src = READ8(ea);
2118               CYCLES(CYCLES_DIV8_ACC_MEM);
2119            }
2120
2121            quotient = (UINT16)REG16(AX);
2122            if( src ) {
2123               remainder = quotient % (UINT16)src;
2124               result = quotient / (UINT16)src;
2125               if( result > 0xff ) {
2126                  /* TODO: Divide error */
2127               } else {
2128                  REG8(AH) = (UINT8)remainder & 0xff;
2129                  REG8(AL) = (UINT8)result & 0xff;
2130
2131                  // this flag is actually undefined, enable on non-cyrix
2132                  if (m_cpuid_id0 != 0x69727943)
2133                     m_CF = 1;
2134               }
2135            } else {
2136               i386_trap(0, 0, 0);
2137            }
2138         }
2139         break;
2140      case 7:         /* IDIV AL, Rm8 */
2141         {
2142            INT16 quotient, remainder, result;
2143            UINT8 src;
2144            if( modrm >= 0xc0 ) {
2145               src = LOAD_RM8(modrm);
2146               CYCLES(CYCLES_IDIV8_ACC_REG);
2147            } else {
2148               UINT32 ea = GetEA(modrm,0);
2149               src = READ8(ea);
2150               CYCLES(CYCLES_IDIV8_ACC_MEM);
2151            }
2152
2153            quotient = (INT16)REG16(AX);
2154            if( src ) {
2155               remainder = quotient % (INT16)(INT8)src;
2156               result = quotient / (INT16)(INT8)src;
2157               if( result > 0xff ) {
2158                  /* TODO: Divide error */
2159               } else {
2160                  REG8(AH) = (UINT8)remainder & 0xff;
2161                  REG8(AL) = (UINT8)result & 0xff;
2162
2163                  // this flag is actually undefined, enable on non-cyrix
2164                  if (m_cpuid_id0 != 0x69727943)
2165                     m_CF = 1;
2166               }
2167            } else {
2168               i386_trap(0, 0, 0);
2169            }
2170         }
2171         break;
2172   }
2173}
2174
2175void i386_device::i386_groupFE_8()         // Opcode 0xfe
2176{
2177   UINT8 modrm = FETCH();
2178
2179   switch( (modrm >> 3) & 0x7 )
2180   {
2181      case 0:         /* INC Rm8 */
2182         if( modrm >= 0xc0 ) {
2183            UINT8 dst = LOAD_RM8(modrm);
2184            dst = INC8(dst);
2185            STORE_RM8(modrm, dst);
2186            CYCLES(CYCLES_INC_REG);
2187         } else {
2188            UINT32 ea = GetEA(modrm,1);
2189            UINT8 dst = READ8(ea);
2190            dst = INC8(dst);
2191            WRITE8(ea, dst);
2192            CYCLES(CYCLES_INC_MEM);
2193         }
2194         break;
2195      case 1:         /* DEC Rm8 */
2196         if( modrm >= 0xc0 ) {
2197            UINT8 dst = LOAD_RM8(modrm);
2198            dst = DEC8(dst);
2199            STORE_RM8(modrm, dst);
2200            CYCLES(CYCLES_DEC_REG);
2201         } else {
2202            UINT32 ea = GetEA(modrm,1);
2203            UINT8 dst = READ8(ea);
2204            dst = DEC8(dst);
2205            WRITE8(ea, dst);
2206            CYCLES(CYCLES_DEC_MEM);
2207         }
2208         break;
2209      case 6:         /* PUSH Rm8*/
2210         {
2211            UINT8 value;
2212            if( modrm >= 0xc0 ) {
2213               value = LOAD_RM8(modrm);
2214            } else {
2215               UINT32 ea = GetEA(modrm,0);
2216               value = READ8(ea);
2217            }
2218            if( m_operand_size ) {
2219               PUSH32(value);
2220            } else {
2221               PUSH16(value);
2222            }
2223            CYCLES(CYCLES_PUSH_RM);
2224         }
2225         break;
2226      default:
2227         report_invalid_modrm("groupFE_8", modrm);
2228         break;
2229   }
2230}
2231
2232
2233
2234void i386_device::i386_segment_CS()        // Opcode 0x2e
2235{
2236   m_segment_prefix = 1;
2237   m_segment_override = CS;
2238
2239   i386_decode_opcode();
2240}
2241
2242void i386_device::i386_segment_DS()        // Opcode 0x3e
2243{
2244   m_segment_prefix = 1;
2245   m_segment_override = DS;
2246   CYCLES(0); // TODO: Specify cycle count
2247   i386_decode_opcode();
2248}
2249
2250void i386_device::i386_segment_ES()        // Opcode 0x26
2251{
2252   m_segment_prefix = 1;
2253   m_segment_override = ES;
2254   CYCLES(0); // TODO: Specify cycle count
2255   i386_decode_opcode();
2256}
2257
2258void i386_device::i386_segment_FS()        // Opcode 0x64
2259{
2260   m_segment_prefix = 1;
2261   m_segment_override = FS;
2262   CYCLES(1); // TODO: Specify cycle count
2263   i386_decode_opcode();
2264}
2265
2266void i386_device::i386_segment_GS()        // Opcode 0x65
2267{
2268   m_segment_prefix = 1;
2269   m_segment_override = GS;
2270   CYCLES(1); // TODO: Specify cycle count
2271   i386_decode_opcode();
2272}
2273
2274void i386_device::i386_segment_SS()        // Opcode 0x36
2275{
2276   m_segment_prefix = 1;
2277   m_segment_override = SS;
2278   CYCLES(0); // TODO: Specify cycle count
2279   i386_decode_opcode();
2280}
2281
2282void i386_device::i386_operand_size()      // Opcode prefix 0x66
2283{
2284   if(m_operand_prefix == 0)
2285   {
2286      m_operand_size ^= 1;
2287      m_operand_prefix = 1;
2288   }
2289   m_opcode = FETCH();
2290   if (m_opcode == 0x0f)
2291      i386_decode_three_byte66();
2292   else
2293   {
2294      if( m_operand_size )
2295         (this->*m_opcode_table1_32[m_opcode])();
2296      else
2297         (this->*m_opcode_table1_16[m_opcode])();
2298   }
2299}
2300
2301void i386_device::i386_address_size()      // Opcode 0x67
2302{
2303   if(m_address_prefix == 0)
2304   {
2305      m_address_size ^= 1;
2306      m_address_prefix = 1;
2307   }
2308   i386_decode_opcode();
2309}
2310
2311void i386_device::i386_nop()               // Opcode 0x90
2312{
2313   CYCLES(CYCLES_NOP);
2314}
2315
2316void i386_device::i386_int3()              // Opcode 0xcc
2317{
2318   CYCLES(CYCLES_INT3);
2319   m_ext = 0; // not an external interrupt
2320   i386_trap(3, 1, 0);
2321   m_ext = 1;
2322}
2323
2324void i386_device::i386_int()               // Opcode 0xcd
2325{
2326   int interrupt = FETCH();
2327   CYCLES(CYCLES_INT);
2328   m_ext = 0; // not an external interrupt
2329   i386_trap(interrupt, 1, 0);
2330   m_ext = 1;
2331}
2332
2333void i386_device::i386_into()              // Opcode 0xce
2334{
2335   if( m_OF ) {
2336      m_ext = 0;
2337      i386_trap(4, 1, 0);
2338      m_ext = 1;
2339      CYCLES(CYCLES_INTO_OF1);
2340   }
2341   else
2342   {
2343      CYCLES(CYCLES_INTO_OF0);
2344   }
2345}
2346
2347static UINT32 i386_escape_ea;   // hack around GCC 4.6 error because we need the side effects of GetEA()
2348void i386_device::i386_escape()            // Opcodes 0xd8 - 0xdf
2349{
2350   UINT8 modrm = FETCH();
2351   if(modrm < 0xc0)
2352   {
2353      i386_escape_ea = GetEA(modrm,0);
2354   }
2355   CYCLES(3); // TODO: confirm this
2356   (void) LOAD_RM8(modrm);
2357}
2358
2359void i386_device::i386_hlt()               // Opcode 0xf4
2360{
2361   if(PROTECTED_MODE && m_CPL != 0)
2362      FAULT(FAULT_GP,0);
2363   m_halted = 1;
2364   CYCLES(CYCLES_HLT);
2365   if (m_cycles > 0)
2366      m_cycles = 0;
2367}
2368
2369void i386_device::i386_decimal_adjust(int direction)
2370{
2371   UINT8 tmpAL = REG8(AL);
2372   UINT8 tmpCF = m_CF;
2373
2374   if (m_AF || ((REG8(AL) & 0xf) > 9))
2375   {
2376      UINT16 t= (UINT16)REG8(AL) + (direction * 0x06);
2377      REG8(AL) = (UINT8)t&0xff;
2378      m_AF = 1;
2379      if (t & 0x100)
2380         m_CF = 1;
2381      if (direction > 0)
2382         tmpAL = REG8(AL);
2383   }
2384
2385   if (tmpCF || (tmpAL > 0x99))
2386   {
2387      REG8(AL) += (direction * 0x60);
2388      m_CF = 1;
2389   }
2390
2391   SetSZPF8(REG8(AL));
2392}
2393
2394void i386_device::i386_daa()               // Opcode 0x27
2395{
2396   i386_decimal_adjust(+1);
2397   CYCLES(CYCLES_DAA);
2398}
2399
2400void i386_device::i386_das()               // Opcode 0x2f
2401{
2402   i386_decimal_adjust(-1);
2403   CYCLES(CYCLES_DAS);
2404}
2405
2406void i386_device::i386_aaa()               // Opcode 0x37
2407{
2408   if( ( (REG8(AL) & 0x0f) > 9) || (m_AF != 0) ) {
2409      REG16(AX) = REG16(AX) + 6;
2410      REG8(AH) = REG8(AH) + 1;
2411      m_AF = 1;
2412      m_CF = 1;
2413   } else {
2414      m_AF = 0;
2415      m_CF = 0;
2416   }
2417   REG8(AL) = REG8(AL) & 0x0f;
2418   CYCLES(CYCLES_AAA);
2419}
2420
2421void i386_device::i386_aas()               // Opcode 0x3f
2422{
2423   if (m_AF || ((REG8(AL) & 0xf) > 9))
2424   {
2425      REG16(AX) -= 6;
2426      REG8(AH) -= 1;
2427      m_AF = 1;
2428      m_CF = 1;
2429   }
2430   else
2431   {
2432      m_AF = 0;
2433      m_CF = 0;
2434   }
2435   REG8(AL) &= 0x0f;
2436   CYCLES(CYCLES_AAS);
2437}
2438
2439void i386_device::i386_aad()               // Opcode 0xd5
2440{
2441   UINT8 tempAL = REG8(AL);
2442   UINT8 tempAH = REG8(AH);
2443   UINT8 i = FETCH();
2444
2445   REG8(AL) = (tempAL + (tempAH * i)) & 0xff;
2446   REG8(AH) = 0;
2447   SetSZPF8( REG8(AL) );
2448   CYCLES(CYCLES_AAD);
2449}
2450
2451void i386_device::i386_aam()               // Opcode 0xd4
2452{
2453   UINT8 tempAL = REG8(AL);
2454   UINT8 i = FETCH();
2455
2456   if(!i)
2457   {
2458      i386_trap(0, 0, 0);
2459      return;
2460   }
2461   REG8(AH) = tempAL / i;
2462   REG8(AL) = tempAL % i;
2463   SetSZPF8( REG8(AL) );
2464   CYCLES(CYCLES_AAM);
2465}
2466
2467void i386_device::i386_clts()              // Opcode 0x0f 0x06
2468{
2469   // Privileged instruction, CPL must be zero.  Can be used in real or v86 mode.
2470   if(PROTECTED_MODE && m_CPL != 0)
2471      FAULT(FAULT_GP,0)
2472   m_cr[0] &= ~0x08;   /* clear TS bit */
2473   CYCLES(CYCLES_CLTS);
2474}
2475
2476void i386_device::i386_wait()              // Opcode 0x9B
2477{
2478   // TODO
2479}
2480
2481void i386_device::i386_lock()              // Opcode 0xf0
2482{
2483   // lock doesn't depend on iopl on 386
2484   // TODO: lock causes UD on unlockable opcodes
2485   CYCLES(CYCLES_LOCK);       // TODO: Determine correct cycle count
2486   i386_decode_opcode();
2487}
2488
2489void i386_device::i386_mov_r32_tr()        // Opcode 0x0f 24
2490{
2491   FETCH();
2492   CYCLES(1);     // TODO: correct cycle count
2493}
2494
2495void i386_device::i386_mov_tr_r32()        // Opcode 0x0f 26
2496{
2497   FETCH();
2498   CYCLES(1);     // TODO: correct cycle count
2499}
2500
2501void i386_device::i386_loadall()       // Opcode 0x0f 0x07 (0x0f 0x05 on 80286), undocumented
2502{
2503   fatalerror("i386: LOADALL unimplemented at %08X\n", m_pc - 1);
2504}
2505
2506void i386_device::i386_invalid()
2507{
2508   report_invalid_opcode();
2509   i386_trap(6, 0, 0);
2510}
2511
2512void i386_device::i386_xlat()          // Opcode 0xd7
2513{
2514   UINT32 ea;
2515   if( m_segment_prefix ) {
2516      if(!m_address_size)
2517      {
2518         ea = i386_translate(m_segment_override, REG16(BX) + REG8(AL), 0 );
2519      }
2520      else
2521      {
2522         ea = i386_translate(m_segment_override, REG32(EBX) + REG8(AL), 0 );
2523      }
2524   } else {
2525      if(!m_address_size)
2526      {
2527         ea = i386_translate(DS, REG16(BX) + REG8(AL), 0 );
2528      }
2529      else
2530      {
2531         ea = i386_translate(DS, REG32(EBX) + REG8(AL), 0 );
2532      }
2533   }
2534   REG8(AL) = READ8(ea);
2535   CYCLES(CYCLES_XLAT);
2536}
trunk/src/emu/cpu/i386/i486ops.c
r28738r28739
1// Intel 486+ specific opcodes
2
3void i386_device::i486_cpuid()             // Opcode 0x0F A2
4{
5   if (m_cpuid_id0 == 0)
6   {
7      // this 486 doesn't support the CPUID instruction
8      logerror("CPUID not supported at %08x!\n", m_eip);
9      i386_trap(6, 0, 0);
10   }
11   else
12   {
13      switch (REG32(EAX))
14      {
15         case 0:
16         {
17            REG32(EAX) = m_cpuid_max_input_value_eax;
18            REG32(EBX) = m_cpuid_id0;
19            REG32(ECX) = m_cpuid_id2;
20            REG32(EDX) = m_cpuid_id1;
21            CYCLES(CYCLES_CPUID);
22            break;
23         }
24
25         case 1:
26         {
27            REG32(EAX) = m_cpu_version;
28            REG32(EDX) = m_feature_flags;
29            CYCLES(CYCLES_CPUID_EAX1);
30            break;
31         }
32      }
33   }
34}
35
36void i386_device::i486_invd()              // Opcode 0x0f 08
37{
38   // Nothing to do ?
39   CYCLES(CYCLES_INVD);
40}
41
42void i386_device::i486_wbinvd()            // Opcode 0x0f 09
43{
44   // Nothing to do ?
45}
46
47void i386_device::i486_cmpxchg_rm8_r8()    // Opcode 0x0f b0
48{
49   UINT8 modrm = FETCH();
50   if( modrm >= 0xc0 ) {
51      UINT8 dst = LOAD_RM8(modrm);
52      UINT8 src = LOAD_REG8(modrm);
53
54      if( REG8(AL) == dst ) {
55         STORE_RM8(modrm, src);
56         m_ZF = 1;
57         CYCLES(CYCLES_CMPXCHG_REG_REG_T);
58      } else {
59         REG8(AL) = dst;
60         m_ZF = 0;
61         CYCLES(CYCLES_CMPXCHG_REG_REG_F);
62      }
63   } else {
64      // TODO: Check write if needed
65      UINT32 ea = GetEA(modrm,0);
66      UINT8 dst = READ8(ea);
67      UINT8 src = LOAD_REG8(modrm);
68
69      if( REG8(AL) == dst ) {
70         WRITE8(ea, src);
71         m_ZF = 1;
72         CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
73      } else {
74         REG8(AL) = dst;
75         m_ZF = 0;
76         CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
77      }
78   }
79}
80
81void i386_device::i486_cmpxchg_rm16_r16()  // Opcode 0x0f b1
82{
83   UINT8 modrm = FETCH();
84   if( modrm >= 0xc0 ) {
85      UINT16 dst = LOAD_RM16(modrm);
86      UINT16 src = LOAD_REG16(modrm);
87
88      if( REG16(AX) == dst ) {
89         STORE_RM16(modrm, src);
90         m_ZF = 1;
91         CYCLES(CYCLES_CMPXCHG_REG_REG_T);
92      } else {
93         REG16(AX) = dst;
94         m_ZF = 0;
95         CYCLES(CYCLES_CMPXCHG_REG_REG_F);
96      }
97   } else {
98      UINT32 ea = GetEA(modrm,0);
99      UINT16 dst = READ16(ea);
100      UINT16 src = LOAD_REG16(modrm);
101
102      if( REG16(AX) == dst ) {
103         WRITE16(ea, src);
104         m_ZF = 1;
105         CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
106      } else {
107         REG16(AX) = dst;
108         m_ZF = 0;
109         CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
110      }
111   }
112}
113
114void i386_device::i486_cmpxchg_rm32_r32()  // Opcode 0x0f b1
115{
116   UINT8 modrm = FETCH();
117   if( modrm >= 0xc0 ) {
118      UINT32 dst = LOAD_RM32(modrm);
119      UINT32 src = LOAD_REG32(modrm);
120
121      if( REG32(EAX) == dst ) {
122         STORE_RM32(modrm, src);
123         m_ZF = 1;
124         CYCLES(CYCLES_CMPXCHG_REG_REG_T);
125      } else {
126         REG32(EAX) = dst;
127         m_ZF = 0;
128         CYCLES(CYCLES_CMPXCHG_REG_REG_F);
129      }
130   } else {
131      UINT32 ea = GetEA(modrm,0);
132      UINT32 dst = READ32(ea);
133      UINT32 src = LOAD_REG32(modrm);
134
135      if( REG32(EAX) == dst ) {
136         WRITE32(ea, src);
137         m_ZF = 1;
138         CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
139      } else {
140         REG32(EAX) = dst;
141         m_ZF = 0;
142         CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
143      }
144   }
145}
146
147void i386_device::i486_xadd_rm8_r8()   // Opcode 0x0f c0
148{
149   UINT8 modrm = FETCH();
150   if( modrm >= 0xc0 ) {
151      UINT8 dst = LOAD_RM8(modrm);
152      UINT8 src = LOAD_REG8(modrm);
153      STORE_REG8(modrm, dst);
154      STORE_RM8(modrm, dst + src);
155      CYCLES(CYCLES_XADD_REG_REG);
156   } else {
157      UINT32 ea = GetEA(modrm,1);
158      UINT8 dst = READ8(ea);
159      UINT8 src = LOAD_REG8(modrm);
160      WRITE8(ea, dst + src);
161      STORE_REG8(modrm, dst);
162      CYCLES(CYCLES_XADD_REG_MEM);
163   }
164}
165
166void i386_device::i486_xadd_rm16_r16() // Opcode 0x0f c1
167{
168   UINT8 modrm = FETCH();
169   if( modrm >= 0xc0 ) {
170      UINT16 dst = LOAD_RM16(modrm);
171      UINT16 src = LOAD_REG16(modrm);
172      STORE_REG16(modrm, dst);
173      STORE_RM16(modrm, dst + src);
174      CYCLES(CYCLES_XADD_REG_REG);
175   } else {
176      UINT32 ea = GetEA(modrm,1);
177      UINT16 dst = READ16(ea);
178      UINT16 src = LOAD_REG16(modrm);
179      WRITE16(ea, dst + src);
180      STORE_REG16(modrm, dst);
181      CYCLES(CYCLES_XADD_REG_MEM);
182   }
183}
184
185void i386_device::i486_xadd_rm32_r32() // Opcode 0x0f c1
186{
187   UINT8 modrm = FETCH();
188   if( modrm >= 0xc0 ) {
189      UINT32 dst = LOAD_RM32(modrm);
190      UINT32 src = LOAD_REG32(modrm);
191      STORE_REG32(modrm, dst);
192      STORE_RM32(modrm, dst + src);
193      CYCLES(CYCLES_XADD_REG_REG);
194   } else {
195      UINT32 ea = GetEA(modrm,1);
196      UINT32 dst = READ32(ea);
197      UINT32 src = LOAD_REG32(modrm);
198      WRITE32(ea, dst + src);
199      STORE_REG32(modrm, dst);
200      CYCLES(CYCLES_XADD_REG_MEM);
201   }
202}
203
204void i386_device::i486_group0F01_16()      // Opcode 0x0f 01
205{
206   UINT8 modrm = FETCH();
207   UINT16 address;
208   UINT32 ea;
209
210   switch( (modrm >> 3) & 0x7 )
211   {
212      case 0:         /* SGDT */
213         {
214            if( modrm >= 0xc0 ) {
215               address = LOAD_RM16(modrm);
216               ea = i386_translate( CS, address, 1 );
217            } else {
218               ea = GetEA(modrm,1);
219            }
220            WRITE16(ea, m_gdtr.limit);
221            WRITE32(ea + 2, m_gdtr.base & 0xffffff);
222            CYCLES(CYCLES_SGDT);
223            break;
224         }
225      case 1:         /* SIDT */
226         {
227            if (modrm >= 0xc0)
228            {
229               address = LOAD_RM16(modrm);
230               ea = i386_translate( CS, address, 1 );
231            }
232            else
233            {
234               ea = GetEA(modrm,1);
235            }
236            WRITE16(ea, m_idtr.limit);
237            WRITE32(ea + 2, m_idtr.base & 0xffffff);
238            CYCLES(CYCLES_SIDT);
239            break;
240         }
241      case 2:         /* LGDT */
242         {
243            if(PROTECTED_MODE && m_CPL)
244               FAULT(FAULT_GP,0)
245            if( modrm >= 0xc0 ) {
246               address = LOAD_RM16(modrm);
247               ea = i386_translate( CS, address, 0 );
248            } else {
249               ea = GetEA(modrm,0);
250            }
251            m_gdtr.limit = READ16(ea);
252            m_gdtr.base = READ32(ea + 2) & 0xffffff;
253            CYCLES(CYCLES_LGDT);
254            break;
255         }
256      case 3:         /* LIDT */
257         {
258            if(PROTECTED_MODE && m_CPL)
259               FAULT(FAULT_GP,0)
260            if( modrm >= 0xc0 ) {
261               address = LOAD_RM16(modrm);
262               ea = i386_translate( CS, address, 0 );
263            } else {
264               ea = GetEA(modrm,0);
265            }
266            m_idtr.limit = READ16(ea);
267            m_idtr.base = READ32(ea + 2) & 0xffffff;
268            CYCLES(CYCLES_LIDT);
269            break;
270         }
271      case 4:         /* SMSW */
272         {
273            if( modrm >= 0xc0 ) {
274               STORE_RM16(modrm, m_cr[0]);
275               CYCLES(CYCLES_SMSW_REG);
276            } else {
277               ea = GetEA(modrm,1);
278               WRITE16(ea, m_cr[0]);
279               CYCLES(CYCLES_SMSW_MEM);
280            }
281            break;
282         }
283      case 6:         /* LMSW */
284         {
285            UINT16 b;
286            if(PROTECTED_MODE && m_CPL)
287               FAULT(FAULT_GP,0)
288            if( modrm >= 0xc0 ) {
289               b = LOAD_RM16(modrm);
290               CYCLES(CYCLES_LMSW_REG);
291            } else {
292               ea = GetEA(modrm,0);
293               CYCLES(CYCLES_LMSW_MEM);
294               b = READ16(ea);
295            }
296            if(PROTECTED_MODE)
297               b |= 0x0001;  // cannot return to real mode using this instruction.
298            m_cr[0] &= ~0x0000000f;
299            m_cr[0] |= b & 0x0000000f;
300            break;
301         }
302      case 7:         /* INVLPG */
303         {
304            if(PROTECTED_MODE && m_CPL)
305               FAULT(FAULT_GP,0)
306            if(modrm >= 0xc0)
307            {
308               logerror("i486: invlpg with modrm %02X\n", modrm);
309               FAULT(FAULT_UD,0)
310            }
311            ea = GetEA(modrm,-1);
312            CYCLES(25); // TODO: add to cycles.h
313            vtlb_flush_address(m_vtlb, ea);
314            break;
315         }
316      default:
317         report_invalid_modrm("group0F01_16", modrm);
318         break;
319   }
320}
321
322void i386_device::i486_group0F01_32()      // Opcode 0x0f 01
323{
324   UINT8 modrm = FETCH();
325   UINT32 address, ea;
326
327   switch( (modrm >> 3) & 0x7 )
328   {
329      case 0:         /* SGDT */
330         {
331            if( modrm >= 0xc0 ) {
332               address = LOAD_RM32(modrm);
333               ea = i386_translate( CS, address, 1 );
334            } else {
335               ea = GetEA(modrm,1);
336            }
337            WRITE16(ea, m_gdtr.limit);
338            WRITE32(ea + 2, m_gdtr.base);
339            CYCLES(CYCLES_SGDT);
340            break;
341         }
342      case 1:         /* SIDT */
343         {
344            if (modrm >= 0xc0)
345            {
346               address = LOAD_RM32(modrm);
347               ea = i386_translate( CS, address, 1 );
348            }
349            else
350            {
351               ea = GetEA(modrm,1);
352            }
353            WRITE16(ea, m_idtr.limit);
354            WRITE32(ea + 2, m_idtr.base);
355            CYCLES(CYCLES_SIDT);
356            break;
357         }
358      case 2:         /* LGDT */
359         {
360            if(PROTECTED_MODE && m_CPL)
361               FAULT(FAULT_GP,0)
362            if( modrm >= 0xc0 ) {
363               address = LOAD_RM32(modrm);
364               ea = i386_translate( CS, address, 0 );
365            } else {
366               ea = GetEA(modrm,0);
367            }
368            m_gdtr.limit = READ16(ea);
369            m_gdtr.base = READ32(ea + 2);
370            CYCLES(CYCLES_LGDT);
371            break;
372         }
373      case 3:         /* LIDT */
374         {
375            if(PROTECTED_MODE && m_CPL)
376               FAULT(FAULT_GP,0)
377            if( modrm >= 0xc0 ) {
378               address = LOAD_RM32(modrm);
379               ea = i386_translate( CS, address, 0 );
380            } else {
381               ea = GetEA(modrm,0);
382            }
383            m_idtr.limit = READ16(ea);
384            m_idtr.base = READ32(ea + 2);
385            CYCLES(CYCLES_LIDT);
386            break;
387         }
388      case 4:         /* SMSW */
389         {
390            if( modrm >= 0xc0 ) {
391               STORE_RM32(modrm, m_cr[0] & 0xffff);
392               CYCLES(CYCLES_SMSW_REG);
393            } else {
394               /* always 16-bit memory operand */
395               ea = GetEA(modrm,1);
396               WRITE16(ea, m_cr[0]);
397               CYCLES(CYCLES_SMSW_MEM);
398            }
399            break;
400         }
401      case 6:         /* LMSW */
402         {
403            if(PROTECTED_MODE && m_CPL)
404               FAULT(FAULT_GP,0)
405            UINT16 b;
406            if( modrm >= 0xc0 ) {
407               b = LOAD_RM16(modrm);
408               CYCLES(CYCLES_LMSW_REG);
409            } else {
410               ea = GetEA(modrm,0);
411               CYCLES(CYCLES_LMSW_MEM);
412            b = READ16(ea);
413            }
414            if(PROTECTED_MODE)
415               b |= 0x0001;  // cannot return to real mode using this instruction.
416            m_cr[0] &= ~0x0000000f;
417            m_cr[0] |= b & 0x0000000f;
418            break;
419         }
420      case 7:         /* INVLPG */
421         {
422            if(PROTECTED_MODE && m_CPL)
423               FAULT(FAULT_GP,0)
424            if(modrm >= 0xc0)
425            {
426               logerror("i486: invlpg with modrm %02X\n", modrm);
427               FAULT(FAULT_UD,0)
428            }
429            ea = GetEA(modrm,-1);
430            CYCLES(25); // TODO: add to cycles.h
431            vtlb_flush_address(m_vtlb, ea);
432            break;
433         }
434      default:
435         report_invalid_modrm("group0F01_32", modrm);
436         break;
437   }
438}
439
440void i386_device::i486_bswap_eax()     // Opcode 0x0f 38
441{
442   REG32(EAX) = SWITCH_ENDIAN_32(REG32(EAX));
443   CYCLES(1);     // TODO
444}
445
446void i386_device::i486_bswap_ecx()     // Opcode 0x0f 39
447{
448   REG32(ECX) = SWITCH_ENDIAN_32(REG32(ECX));
449   CYCLES(1);     // TODO
450}
451
452void i386_device::i486_bswap_edx()     // Opcode 0x0f 3A
453{
454   REG32(EDX) = SWITCH_ENDIAN_32(REG32(EDX));
455   CYCLES(1);     // TODO
456}
457
458void i386_device::i486_bswap_ebx()     // Opcode 0x0f 3B
459{
460   REG32(EBX) = SWITCH_ENDIAN_32(REG32(EBX));
461   CYCLES(1);     // TODO
462}
463
464void i386_device::i486_bswap_esp()     // Opcode 0x0f 3C
465{
466   REG32(ESP) = SWITCH_ENDIAN_32(REG32(ESP));
467   CYCLES(1);     // TODO
468}
469
470void i386_device::i486_bswap_ebp()     // Opcode 0x0f 3D
471{
472   REG32(EBP) = SWITCH_ENDIAN_32(REG32(EBP));
473   CYCLES(1);     // TODO
474}
475
476void i386_device::i486_bswap_esi()     // Opcode 0x0f 3E
477{
478   REG32(ESI) = SWITCH_ENDIAN_32(REG32(ESI));
479   CYCLES(1);     // TODO
480}
481
482void i386_device::i486_bswap_edi()     // Opcode 0x0f 3F
483{
484   REG32(EDI) = SWITCH_ENDIAN_32(REG32(EDI));
485   CYCLES(1);     // TODO
486}
487
488void i386_device::i486_mov_cr_r32()        // Opcode 0x0f 22
489{
490   if(PROTECTED_MODE && m_CPL)
491      FAULT(FAULT_GP, 0);
492   UINT8 modrm = FETCH();
493   UINT8 cr = (modrm >> 3) & 0x7;
494   UINT32 oldcr = m_cr[cr];
495   UINT32 data = LOAD_RM32(modrm);
496   switch(cr)
497   {
498      case 0:
499         CYCLES(CYCLES_MOV_REG_CR0);
500         if((oldcr ^ m_cr[cr]) & 0x80010000)
501            vtlb_flush_dynamic(m_vtlb);
502         break;
503      case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
504      case 3:
505         CYCLES(CYCLES_MOV_REG_CR3);
506         vtlb_flush_dynamic(m_vtlb);
507         break;
508      case 4: CYCLES(1); break; // TODO
509      default:
510         logerror("i386: mov_cr_r32 CR%d!\n", cr);
511         return;
512   }
513   m_cr[cr] = data;
514}
trunk/src/emu/cpu/i386/i386op32.c
r28738r28739
1UINT32 i386_device::i386_shift_rotate32(UINT8 modrm, UINT32 value, UINT8 shift)
2{
3   UINT32 dst, src;
4   dst = value;
5   src = value;
6
7   if( shift == 0 ) {
8      CYCLES_RM(modrm, 3, 7);
9   } else if( shift == 1 ) {
10      switch( (modrm >> 3) & 0x7 )
11      {
12         case 0:         /* ROL rm32, 1 */
13            m_CF = (src & 0x80000000) ? 1 : 0;
14            dst = (src << 1) + m_CF;
15            m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
16            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
17            break;
18         case 1:         /* ROR rm32, 1 */
19            m_CF = (src & 0x1) ? 1 : 0;
20            dst = (m_CF << 31) | (src >> 1);
21            m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
22            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
23            break;
24         case 2:         /* RCL rm32, 1 */
25            dst = (src << 1) + m_CF;
26            m_CF = (src & 0x80000000) ? 1 : 0;
27            m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
28            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
29            break;
30         case 3:         /* RCR rm32, 1 */
31            dst = (m_CF << 31) | (src >> 1);
32            m_CF = src & 0x1;
33            m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
34            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
35            break;
36         case 4:         /* SHL/SAL rm32, 1 */
37         case 6:
38            dst = src << 1;
39            m_CF = (src & 0x80000000) ? 1 : 0;
40            m_OF = (((m_CF << 31) ^ dst) & 0x80000000) ? 1 : 0;
41            SetSZPF32(dst);
42            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
43            break;
44         case 5:         /* SHR rm32, 1 */
45            dst = src >> 1;
46            m_CF = src & 0x1;
47            m_OF = (src & 0x80000000) ? 1 : 0;
48            SetSZPF32(dst);
49            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
50            break;
51         case 7:         /* SAR rm32, 1 */
52            dst = (INT32)(src) >> 1;
53            m_CF = src & 0x1;
54            m_OF = 0;
55            SetSZPF32(dst);
56            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
57            break;
58      }
59
60   } else {
61      shift &= 31;
62      switch( (modrm >> 3) & 0x7 )
63      {
64         case 0:         /* ROL rm32, i8 */
65            dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
66                  ((src & ((UINT32)0xffffffff << (32-shift))) >> (32-shift));
67            m_CF = dst & 0x1;
68            m_OF = (dst & 1) ^ (dst >> 31);
69            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
70            break;
71         case 1:         /* ROR rm32, i8 */
72            dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
73                  ((src & ((UINT32)0xffffffff >> (32-shift))) << (32-shift));
74            m_CF = (dst >> 31) & 0x1;
75            m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
76            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
77            break;
78         case 2:         /* RCL rm32, i8 */
79            dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
80                  ((src & ((UINT32)0xffffffff << (33-shift))) >> (33-shift)) |
81                  (m_CF << (shift-1));
82            m_CF = (src >> (32-shift)) & 0x1;
83            m_OF = m_CF ^ ((dst >> 31) & 1);
84            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
85            break;
86         case 3:         /* RCR rm32, i8 */
87            dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
88                  ((src & ((UINT32)0xffffffff >> (32-shift))) << (33-shift)) |
89                  (m_CF << (32-shift));
90            m_CF = (src >> (shift-1)) & 0x1;
91            m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
92            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
93            break;
94         case 4:         /* SHL/SAL rm32, i8 */
95         case 6:
96            dst = src << shift;
97            m_CF = (src & (1 << (32-shift))) ? 1 : 0;
98            SetSZPF32(dst);
99            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
100            break;
101         case 5:         /* SHR rm32, i8 */
102            dst = src >> shift;
103            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
104            SetSZPF32(dst);
105            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
106            break;
107         case 7:         /* SAR rm32, i8 */
108            dst = (INT32)src >> shift;
109            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
110            SetSZPF32(dst);
111            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
112            break;
113      }
114
115   }
116   return dst;
117}
118
119
120
121void i386_device::i386_adc_rm32_r32()      // Opcode 0x11
122{
123   UINT32 src, dst;
124   UINT8 modrm = FETCH();
125   if( modrm >= 0xc0 ) {
126      src = LOAD_REG32(modrm);
127      dst = LOAD_RM32(modrm);
128      dst = ADC32(dst, src, m_CF);
129      STORE_RM32(modrm, dst);
130      CYCLES(CYCLES_ALU_REG_REG);
131   } else {
132      UINT32 ea = GetEA(modrm,1);
133      src = LOAD_REG32(modrm);
134      dst = READ32(ea);
135      dst = ADC32(dst, src, m_CF);
136      WRITE32(ea, dst);
137      CYCLES(CYCLES_ALU_REG_MEM);
138   }
139}
140
141void i386_device::i386_adc_r32_rm32()      // Opcode 0x13
142{
143   UINT32 src, dst;
144   UINT8 modrm = FETCH();
145   if( modrm >= 0xc0 ) {
146      src = LOAD_RM32(modrm);
147      dst = LOAD_REG32(modrm);
148      dst = ADC32(dst, src, m_CF);
149      STORE_REG32(modrm, dst);
150      CYCLES(CYCLES_ALU_REG_REG);
151   } else {
152      UINT32 ea = GetEA(modrm,0);
153      src = READ32(ea);
154      dst = LOAD_REG32(modrm);
155      dst = ADC32(dst, src, m_CF);
156      STORE_REG32(modrm, dst);
157      CYCLES(CYCLES_ALU_MEM_REG);
158   }
159}
160
161void i386_device::i386_adc_eax_i32()       // Opcode 0x15
162{
163   UINT32 src, dst;
164   src = FETCH32();
165   dst = REG32(EAX);
166   dst = ADC32(dst, src, m_CF);
167   REG32(EAX) = dst;
168   CYCLES(CYCLES_ALU_IMM_ACC);
169}
170
171void i386_device::i386_add_rm32_r32()      // Opcode 0x01
172{
173   UINT32 src, dst;
174   UINT8 modrm = FETCH();
175   if( modrm >= 0xc0 ) {
176      src = LOAD_REG32(modrm);
177      dst = LOAD_RM32(modrm);
178      dst = ADD32(dst, src);
179      STORE_RM32(modrm, dst);
180      CYCLES(CYCLES_ALU_REG_REG);
181   } else {
182      UINT32 ea = GetEA(modrm,1);
183      src = LOAD_REG32(modrm);
184      dst = READ32(ea);
185      dst = ADD32(dst, src);
186      WRITE32(ea, dst);
187      CYCLES(CYCLES_ALU_REG_MEM);
188   }
189}
190
191void i386_device::i386_add_r32_rm32()      // Opcode 0x03
192{
193   UINT32 src, dst;
194   UINT8 modrm = FETCH();
195   if( modrm >= 0xc0 ) {
196      src = LOAD_RM32(modrm);
197      dst = LOAD_REG32(modrm);
198      dst = ADD32(dst, src);
199      STORE_REG32(modrm, dst);
200      CYCLES(CYCLES_ALU_REG_REG);
201   } else {
202      UINT32 ea = GetEA(modrm,0);
203      src = READ32(ea);
204      dst = LOAD_REG32(modrm);
205      dst = ADD32(dst, src);
206      STORE_REG32(modrm, dst);
207      CYCLES(CYCLES_ALU_MEM_REG);
208   }
209}
210
211void i386_device::i386_add_eax_i32()       // Opcode 0x05
212{
213   UINT32 src, dst;
214   src = FETCH32();
215   dst = REG32(EAX);
216   dst = ADD32(dst, src);
217   REG32(EAX) = dst;
218   CYCLES(CYCLES_ALU_IMM_ACC);
219}
220
221void i386_device::i386_and_rm32_r32()      // Opcode 0x21
222{
223   UINT32 src, dst;
224   UINT8 modrm = FETCH();
225   if( modrm >= 0xc0 ) {
226      src = LOAD_REG32(modrm);
227      dst = LOAD_RM32(modrm);
228      dst = AND32(dst, src);
229      STORE_RM32(modrm, dst);
230      CYCLES(CYCLES_ALU_REG_REG);
231   } else {
232      UINT32 ea = GetEA(modrm,1);
233      src = LOAD_REG32(modrm);
234      dst = READ32(ea);
235      dst = AND32(dst, src);
236      WRITE32(ea, dst);
237      CYCLES(CYCLES_ALU_REG_MEM);
238   }
239}
240
241void i386_device::i386_and_r32_rm32()      // Opcode 0x23
242{
243   UINT32 src, dst;
244   UINT8 modrm = FETCH();
245   if( modrm >= 0xc0 ) {
246      src = LOAD_RM32(modrm);
247      dst = LOAD_REG32(modrm);
248      dst = AND32(dst, src);
249      STORE_REG32(modrm, dst);
250      CYCLES(CYCLES_ALU_REG_REG);
251   } else {
252      UINT32 ea = GetEA(modrm,0);
253      src = READ32(ea);
254      dst = LOAD_REG32(modrm);
255      dst = AND32(dst, src);
256      STORE_REG32(modrm, dst);
257      CYCLES(CYCLES_ALU_MEM_REG);
258   }
259}
260
261void i386_device::i386_and_eax_i32()       // Opcode 0x25
262{
263   UINT32 src, dst;
264   src = FETCH32();
265   dst = REG32(EAX);
266   dst = AND32(dst, src);
267   REG32(EAX) = dst;
268   CYCLES(CYCLES_ALU_IMM_ACC);
269}
270
271void i386_device::i386_bsf_r32_rm32()      // Opcode 0x0f bc
272{
273   UINT32 src, dst, temp;
274   UINT8 modrm = FETCH();
275
276   if( modrm >= 0xc0 ) {
277      src = LOAD_RM32(modrm);
278   } else {
279      UINT32 ea = GetEA(modrm,0);
280      src = READ32(ea);
281   }
282
283   dst = 0;
284
285   if( src == 0 ) {
286      m_ZF = 1;
287   } else {
288      m_ZF = 0;
289      temp = 0;
290      while( (src & (1 << temp)) == 0 ) {
291         temp++;
292         dst = temp;
293         CYCLES(CYCLES_BSF);
294      }
295      STORE_REG32(modrm, dst);
296   }
297   CYCLES(CYCLES_BSF_BASE);
298}
299
300void i386_device::i386_bsr_r32_rm32()      // Opcode 0x0f bd
301{
302   UINT32 src, dst, temp;
303   UINT8 modrm = FETCH();
304
305   if( modrm >= 0xc0 ) {
306      src = LOAD_RM32(modrm);
307   } else {
308      UINT32 ea = GetEA(modrm,0);
309      src = READ32(ea);
310   }
311
312   dst = 0;
313
314   if( src == 0 ) {
315      m_ZF = 1;
316   } else {
317      m_ZF = 0;
318      dst = temp = 31;
319      while( (src & (1 << temp)) == 0 ) {
320         temp--;
321         dst = temp;
322         CYCLES(CYCLES_BSR);
323      }
324      STORE_REG32(modrm, dst);
325   }
326   CYCLES(CYCLES_BSR_BASE);
327}
328
329void i386_device::i386_bt_rm32_r32()       // Opcode 0x0f a3
330{
331   UINT8 modrm = FETCH();
332   if( modrm >= 0xc0 ) {
333      UINT32 dst = LOAD_RM32(modrm);
334      UINT32 bit = LOAD_REG32(modrm);
335
336      if( dst & (1 << bit) )
337         m_CF = 1;
338      else
339         m_CF = 0;
340
341      CYCLES(CYCLES_BT_REG_REG);
342   } else {
343      UINT8 segment;
344      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
345      UINT32 bit = LOAD_REG32(modrm);
346      ea += 4*(bit/32);
347      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),0);
348      bit %= 32;
349      UINT32 dst = READ32(ea);
350
351      if( dst & (1 << bit) )
352         m_CF = 1;
353      else
354         m_CF = 0;
355
356      CYCLES(CYCLES_BT_REG_MEM);
357   }
358}
359
360void i386_device::i386_btc_rm32_r32()      // Opcode 0x0f bb
361{
362   UINT8 modrm = FETCH();
363   if( modrm >= 0xc0 ) {
364      UINT32 dst = LOAD_RM32(modrm);
365      UINT32 bit = LOAD_REG32(modrm);
366
367      if( dst & (1 << bit) )
368         m_CF = 1;
369      else
370         m_CF = 0;
371      dst ^= (1 << bit);
372
373      STORE_RM32(modrm, dst);
374      CYCLES(CYCLES_BTC_REG_REG);
375   } else {
376      UINT8 segment;
377      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
378      UINT32 bit = LOAD_REG32(modrm);
379      ea += 4*(bit/32);
380      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
381      bit %= 32;
382      UINT32 dst = READ32(ea);
383
384      if( dst & (1 << bit) )
385         m_CF = 1;
386      else
387         m_CF = 0;
388      dst ^= (1 << bit);
389
390      WRITE32(ea, dst);
391      CYCLES(CYCLES_BTC_REG_MEM);
392   }
393}
394
395void i386_device::i386_btr_rm32_r32()      // Opcode 0x0f b3
396{
397   UINT8 modrm = FETCH();
398   if( modrm >= 0xc0 ) {
399      UINT32 dst = LOAD_RM32(modrm);
400      UINT32 bit = LOAD_REG32(modrm);
401
402      if( dst & (1 << bit) )
403         m_CF = 1;
404      else
405         m_CF = 0;
406      dst &= ~(1 << bit);
407
408      STORE_RM32(modrm, dst);
409      CYCLES(CYCLES_BTR_REG_REG);
410   } else {
411      UINT8 segment;
412      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
413      UINT32 bit = LOAD_REG32(modrm);
414      ea += 4*(bit/32);
415      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
416      bit %= 32;
417      UINT32 dst = READ32(ea);
418
419      if( dst & (1 << bit) )
420         m_CF = 1;
421      else
422         m_CF = 0;
423      dst &= ~(1 << bit);
424
425      WRITE32(ea, dst);
426      CYCLES(CYCLES_BTR_REG_MEM);
427   }
428}
429
430void i386_device::i386_bts_rm32_r32()      // Opcode 0x0f ab
431{
432   UINT8 modrm = FETCH();
433   if( modrm >= 0xc0 ) {
434      UINT32 dst = LOAD_RM32(modrm);
435      UINT32 bit = LOAD_REG32(modrm);
436
437      if( dst & (1 << bit) )
438         m_CF = 1;
439      else
440         m_CF = 0;
441      dst |= (1 << bit);
442
443      STORE_RM32(modrm, dst);
444      CYCLES(CYCLES_BTS_REG_REG);
445   } else {
446      UINT8 segment;
447      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
448      UINT32 bit = LOAD_REG32(modrm);
449      ea += 4*(bit/32);
450      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
451      bit %= 32;
452      UINT32 dst = READ32(ea);
453
454      if( dst & (1 << bit) )
455         m_CF = 1;
456      else
457         m_CF = 0;
458      dst |= (1 << bit);
459
460      WRITE32(ea, dst);
461      CYCLES(CYCLES_BTS_REG_MEM);
462   }
463}
464
465void i386_device::i386_call_abs32()        // Opcode 0x9a
466{
467   UINT32 offset = FETCH32();
468   UINT16 ptr = FETCH16();
469
470   if(PROTECTED_MODE && !V8086_MODE)
471   {
472      i386_protected_mode_call(ptr,offset,0,1);
473   }
474   else
475   {
476      PUSH32(m_sreg[CS].selector );
477      PUSH32(m_eip );
478      m_sreg[CS].selector = ptr;
479      m_performed_intersegment_jump = 1;
480      m_eip = offset;
481      i386_load_segment_descriptor(CS);
482   }
483   CYCLES(CYCLES_CALL_INTERSEG);
484   CHANGE_PC(m_eip);
485}
486
487void i386_device::i386_call_rel32()        // Opcode 0xe8
488{
489   INT32 disp = FETCH32();
490   PUSH32(m_eip );
491   m_eip += disp;
492   CHANGE_PC(m_eip);
493   CYCLES(CYCLES_CALL);       /* TODO: Timing = 7 + m */
494}
495
496void i386_device::i386_cdq()               // Opcode 0x99
497{
498   if( REG32(EAX) & 0x80000000 ) {
499      REG32(EDX) = 0xffffffff;
500   } else {
501      REG32(EDX) = 0x00000000;
502   }
503   CYCLES(CYCLES_CWD);
504}
505
506void i386_device::i386_cmp_rm32_r32()      // Opcode 0x39
507{
508   UINT32 src, dst;
509   UINT8 modrm = FETCH();
510   if( modrm >= 0xc0 ) {
511      src = LOAD_REG32(modrm);
512      dst = LOAD_RM32(modrm);
513      SUB32(dst, src);
514      CYCLES(CYCLES_CMP_REG_REG);
515   } else {
516      UINT32 ea = GetEA(modrm,0);
517      src = LOAD_REG32(modrm);
518      dst = READ32(ea);
519      SUB32(dst, src);
520      CYCLES(CYCLES_CMP_REG_MEM);
521   }
522}
523
524void i386_device::i386_cmp_r32_rm32()      // Opcode 0x3b
525{
526   UINT32 src, dst;
527   UINT8 modrm = FETCH();
528   if( modrm >= 0xc0 ) {
529      src = LOAD_RM32(modrm);
530      dst = LOAD_REG32(modrm);
531      SUB32(dst, src);
532      CYCLES(CYCLES_CMP_REG_REG);
533   } else {
534      UINT32 ea = GetEA(modrm,0);
535      src = READ32(ea);
536      dst = LOAD_REG32(modrm);
537      SUB32(dst, src);
538      CYCLES(CYCLES_CMP_MEM_REG);
539   }
540}
541
542void i386_device::i386_cmp_eax_i32()       // Opcode 0x3d
543{
544   UINT32 src, dst;
545   src = FETCH32();
546   dst = REG32(EAX);
547   SUB32(dst, src);
548   CYCLES(CYCLES_CMP_IMM_ACC);
549}
550
551void i386_device::i386_cmpsd()             // Opcode 0xa7
552{
553   UINT32 eas, ead, src, dst;
554   if( m_segment_prefix ) {
555      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
556   } else {
557      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
558   }
559   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
560   src = READ32(eas);
561   dst = READ32(ead);
562   SUB32(src,dst);
563   BUMP_SI(4);
564   BUMP_DI(4);
565   CYCLES(CYCLES_CMPS);
566}
567
568void i386_device::i386_cwde()              // Opcode 0x98
569{
570   REG32(EAX) = (INT32)((INT16)REG16(AX));
571   CYCLES(CYCLES_CBW);
572}
573
574void i386_device::i386_dec_eax()           // Opcode 0x48
575{
576   REG32(EAX) = DEC32(REG32(EAX) );
577   CYCLES(CYCLES_DEC_REG);
578}
579
580void i386_device::i386_dec_ecx()           // Opcode 0x49
581{
582   REG32(ECX) = DEC32(REG32(ECX) );
583   CYCLES(CYCLES_DEC_REG);
584}
585
586void i386_device::i386_dec_edx()           // Opcode 0x4a
587{
588   REG32(EDX) = DEC32(REG32(EDX) );
589   CYCLES(CYCLES_DEC_REG);
590}
591
592void i386_device::i386_dec_ebx()           // Opcode 0x4b
593{
594   REG32(EBX) = DEC32(REG32(EBX) );
595   CYCLES(CYCLES_DEC_REG);
596}
597
598void i386_device::i386_dec_esp()           // Opcode 0x4c
599{
600   REG32(ESP) = DEC32(REG32(ESP) );
601   CYCLES(CYCLES_DEC_REG);
602}
603
604void i386_device::i386_dec_ebp()           // Opcode 0x4d
605{
606   REG32(EBP) = DEC32(REG32(EBP) );
607   CYCLES(CYCLES_DEC_REG);
608}
609
610void i386_device::i386_dec_esi()           // Opcode 0x4e
611{
612   REG32(ESI) = DEC32(REG32(ESI) );
613   CYCLES(CYCLES_DEC_REG);
614}
615
616void i386_device::i386_dec_edi()           // Opcode 0x4f
617{
618   REG32(EDI) = DEC32(REG32(EDI) );
619   CYCLES(CYCLES_DEC_REG);
620}
621
622void i386_device::i386_imul_r32_rm32()     // Opcode 0x0f af
623{
624   UINT8 modrm = FETCH();
625   INT64 result;
626   INT64 src, dst;
627   if( modrm >= 0xc0 ) {
628      src = (INT64)(INT32)LOAD_RM32(modrm);
629      CYCLES(CYCLES_IMUL32_REG_REG);     /* TODO: Correct multiply timing */
630   } else {
631      UINT32 ea = GetEA(modrm,0);
632      src = (INT64)(INT32)READ32(ea);
633      CYCLES(CYCLES_IMUL32_REG_REG);     /* TODO: Correct multiply timing */
634   }
635
636   dst = (INT64)(INT32)LOAD_REG32(modrm);
637   result = src * dst;
638
639   STORE_REG32(modrm, (UINT32)result);
640
641   m_CF = m_OF = !(result == (INT64)(INT32)result);
642}
643
644void i386_device::i386_imul_r32_rm32_i32() // Opcode 0x69
645{
646   UINT8 modrm = FETCH();
647   INT64 result;
648   INT64 src, dst;
649   if( modrm >= 0xc0 ) {
650      dst = (INT64)(INT32)LOAD_RM32(modrm);
651      CYCLES(CYCLES_IMUL32_REG_IMM_REG);     /* TODO: Correct multiply timing */
652   } else {
653      UINT32 ea = GetEA(modrm,0);
654      dst = (INT64)(INT32)READ32(ea);
655      CYCLES(CYCLES_IMUL32_MEM_IMM_REG);     /* TODO: Correct multiply timing */
656   }
657
658   src = (INT64)(INT32)FETCH32();
659   result = src * dst;
660
661   STORE_REG32(modrm, (UINT32)result);
662
663   m_CF = m_OF = !(result == (INT64)(INT32)result);
664}
665
666void i386_device::i386_imul_r32_rm32_i8()  // Opcode 0x6b
667{
668   UINT8 modrm = FETCH();
669   INT64 result;
670   INT64 src, dst;
671   if( modrm >= 0xc0 ) {
672      dst = (INT64)(INT32)LOAD_RM32(modrm);
673      CYCLES(CYCLES_IMUL32_REG_IMM_REG);     /* TODO: Correct multiply timing */
674   } else {
675      UINT32 ea = GetEA(modrm,0);
676      dst = (INT64)(INT32)READ32(ea);
677      CYCLES(CYCLES_IMUL32_MEM_IMM_REG);     /* TODO: Correct multiply timing */
678   }
679
680   src = (INT64)(INT8)FETCH();
681   result = src * dst;
682
683   STORE_REG32(modrm, (UINT32)result);
684
685   m_CF = m_OF = !(result == (INT64)(INT32)result);
686}
687
688void i386_device::i386_in_eax_i8()         // Opcode 0xe5
689{
690   UINT16 port = FETCH();
691   UINT32 data = READPORT32(port);
692   REG32(EAX) = data;
693   CYCLES(CYCLES_IN_VAR);
694}
695
696void i386_device::i386_in_eax_dx()         // Opcode 0xed
697{
698   UINT16 port = REG16(DX);
699   UINT32 data = READPORT32(port);
700   REG32(EAX) = data;
701   CYCLES(CYCLES_IN);
702}
703
704void i386_device::i386_inc_eax()           // Opcode 0x40
705{
706   REG32(EAX) = INC32(REG32(EAX) );
707   CYCLES(CYCLES_INC_REG);
708}
709
710void i386_device::i386_inc_ecx()           // Opcode 0x41
711{
712   REG32(ECX) = INC32(REG32(ECX) );
713   CYCLES(CYCLES_INC_REG);
714}
715
716void i386_device::i386_inc_edx()           // Opcode 0x42
717{
718   REG32(EDX) = INC32(REG32(EDX) );
719   CYCLES(CYCLES_INC_REG);
720}
721
722void i386_device::i386_inc_ebx()           // Opcode 0x43
723{
724   REG32(EBX) = INC32(REG32(EBX) );
725   CYCLES(CYCLES_INC_REG);
726}
727
728void i386_device::i386_inc_esp()           // Opcode 0x44
729{
730   REG32(ESP) = INC32(REG32(ESP) );
731   CYCLES(CYCLES_INC_REG);
732}
733
734void i386_device::i386_inc_ebp()           // Opcode 0x45
735{
736   REG32(EBP) = INC32(REG32(EBP) );
737   CYCLES(CYCLES_INC_REG);
738}
739
740void i386_device::i386_inc_esi()           // Opcode 0x46
741{
742   REG32(ESI) = INC32(REG32(ESI) );
743   CYCLES(CYCLES_INC_REG);
744}
745
746void i386_device::i386_inc_edi()           // Opcode 0x47
747{
748   REG32(EDI) = INC32(REG32(EDI) );
749   CYCLES(CYCLES_INC_REG);
750}
751
752void i386_device::i386_iret32()            // Opcode 0xcf
753{
754   if( PROTECTED_MODE )
755   {
756      i386_protected_mode_iret(1);
757   }
758   else
759   {
760      /* TODO: #SS(0) exception */
761      /* TODO: #GP(0) exception */
762      m_eip = POP32();
763      m_sreg[CS].selector = POP32() & 0xffff;
764      set_flags(POP32() );
765      i386_load_segment_descriptor(CS);
766      CHANGE_PC(m_eip);
767   }
768   CYCLES(CYCLES_IRET);
769}
770
771void i386_device::i386_ja_rel32()          // Opcode 0x0f 87
772{
773   INT32 disp = FETCH32();
774   if( m_CF == 0 && m_ZF == 0 ) {
775      m_eip += disp;
776      CHANGE_PC(m_eip);
777      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
778   } else {
779      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
780   }
781}
782
783void i386_device::i386_jbe_rel32()         // Opcode 0x0f 86
784{
785   INT32 disp = FETCH32();
786   if( m_CF != 0 || m_ZF != 0 ) {
787      m_eip += disp;
788      CHANGE_PC(m_eip);
789      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
790   } else {
791      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
792   }
793}
794
795void i386_device::i386_jc_rel32()          // Opcode 0x0f 82
796{
797   INT32 disp = FETCH32();
798   if( m_CF != 0 ) {
799      m_eip += disp;
800      CHANGE_PC(m_eip);
801      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
802   } else {
803      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
804   }
805}
806
807void i386_device::i386_jg_rel32()          // Opcode 0x0f 8f
808{
809   INT32 disp = FETCH32();
810   if( m_ZF == 0 && (m_SF == m_OF) ) {
811      m_eip += disp;
812      CHANGE_PC(m_eip);
813      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
814   } else {
815      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
816   }
817}
818
819void i386_device::i386_jge_rel32()         // Opcode 0x0f 8d
820{
821   INT32 disp = FETCH32();
822   if(m_SF == m_OF) {
823      m_eip += disp;
824      CHANGE_PC(m_eip);
825      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
826   } else {
827      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
828   }
829}
830
831void i386_device::i386_jl_rel32()          // Opcode 0x0f 8c
832{
833   INT32 disp = FETCH32();
834   if( (m_SF != m_OF) ) {
835      m_eip += disp;
836      CHANGE_PC(m_eip);
837      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
838   } else {
839      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
840   }
841}
842
843void i386_device::i386_jle_rel32()         // Opcode 0x0f 8e
844{
845   INT32 disp = FETCH32();
846   if( m_ZF != 0 || (m_SF != m_OF) ) {
847      m_eip += disp;
848      CHANGE_PC(m_eip);
849      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
850   } else {
851      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
852   }
853}
854
855void i386_device::i386_jnc_rel32()         // Opcode 0x0f 83
856{
857   INT32 disp = FETCH32();
858   if( m_CF == 0 ) {
859      m_eip += disp;
860      CHANGE_PC(m_eip);
861      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
862   } else {
863      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
864   }
865}
866
867void i386_device::i386_jno_rel32()         // Opcode 0x0f 81
868{
869   INT32 disp = FETCH32();
870   if( m_OF == 0 ) {
871      m_eip += disp;
872      CHANGE_PC(m_eip);
873      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
874   } else {
875      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
876   }
877}
878
879void i386_device::i386_jnp_rel32()         // Opcode 0x0f 8b
880{
881   INT32 disp = FETCH32();
882   if( m_PF == 0 ) {
883      m_eip += disp;
884      CHANGE_PC(m_eip);
885      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
886   } else {
887      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
888   }
889}
890
891void i386_device::i386_jns_rel32()         // Opcode 0x0f 89
892{
893   INT32 disp = FETCH32();
894   if( m_SF == 0 ) {
895      m_eip += disp;
896      CHANGE_PC(m_eip);
897      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
898   } else {
899      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
900   }
901}
902
903void i386_device::i386_jnz_rel32()         // Opcode 0x0f 85
904{
905   INT32 disp = FETCH32();
906   if( m_ZF == 0 ) {
907      m_eip += disp;
908      CHANGE_PC(m_eip);
909      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
910   } else {
911      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
912   }
913}
914
915void i386_device::i386_jo_rel32()          // Opcode 0x0f 80
916{
917   INT32 disp = FETCH32();
918   if( m_OF != 0 ) {
919      m_eip += disp;
920      CHANGE_PC(m_eip);
921      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
922   } else {
923      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
924   }
925}
926
927void i386_device::i386_jp_rel32()          // Opcode 0x0f 8a
928{
929   INT32 disp = FETCH32();
930   if( m_PF != 0 ) {
931      m_eip += disp;
932      CHANGE_PC(m_eip);
933      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
934   } else {
935      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
936   }
937}
938
939void i386_device::i386_js_rel32()          // Opcode 0x0f 88
940{
941   INT32 disp = FETCH32();
942   if( m_SF != 0 ) {
943      m_eip += disp;
944      CHANGE_PC(m_eip);
945      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
946   } else {
947      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
948   }
949}
950
951void i386_device::i386_jz_rel32()          // Opcode 0x0f 84
952{
953   INT32 disp = FETCH32();
954   if( m_ZF != 0 ) {
955      m_eip += disp;
956      CHANGE_PC(m_eip);
957      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
958   } else {
959      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
960   }
961}
962
963void i386_device::i386_jcxz32()            // Opcode 0xe3
964{
965   INT8 disp = FETCH();
966   int val = (m_address_size)?(REG32(ECX) == 0):(REG16(CX) == 0);
967   if( val ) {
968      m_eip += disp;
969      CHANGE_PC(m_eip);
970      CYCLES(CYCLES_JCXZ);       /* TODO: Timing = 9 + m */
971   } else {
972      CYCLES(CYCLES_JCXZ_NOBRANCH);
973   }
974}
975
976void i386_device::i386_jmp_rel32()         // Opcode 0xe9
977{
978   UINT32 disp = FETCH32();
979   /* TODO: Segment limit */
980   m_eip += disp;
981   CHANGE_PC(m_eip);
982   CYCLES(CYCLES_JMP);        /* TODO: Timing = 7 + m */
983}
984
985void i386_device::i386_jmp_abs32()         // Opcode 0xea
986{
987   UINT32 address = FETCH32();
988   UINT16 segment = FETCH16();
989
990   if( PROTECTED_MODE && !V8086_MODE)
991   {
992      i386_protected_mode_jump(segment,address,0,1);
993   }
994   else
995   {
996      m_eip = address;
997      m_sreg[CS].selector = segment;
998      m_performed_intersegment_jump = 1;
999      i386_load_segment_descriptor(CS);
1000      CHANGE_PC(m_eip);
1001   }
1002   CYCLES(CYCLES_JMP_INTERSEG);
1003}
1004
1005void i386_device::i386_lea32()             // Opcode 0x8d
1006{
1007   UINT8 modrm = FETCH();
1008   UINT32 ea = GetNonTranslatedEA(modrm,NULL);
1009   if (!m_address_size)
1010   {
1011      ea &= 0xffff;
1012   }
1013   STORE_REG32(modrm, ea);
1014   CYCLES(CYCLES_LEA);
1015}
1016
1017void i386_device::i386_enter32()           // Opcode 0xc8
1018{
1019   UINT16 framesize = FETCH16();
1020   UINT8 level = FETCH() % 32;
1021   UINT8 x;
1022   UINT32 frameptr;
1023   PUSH32(REG32(EBP));
1024   if(!STACK_32BIT)
1025      frameptr = REG16(SP);
1026   else
1027      frameptr = REG32(ESP);
1028
1029   if(level > 0)
1030   {
1031      for(x=1;x<level-1;x++)
1032      {
1033         REG32(EBP) -= 4;
1034         PUSH32(READ32(REG32(EBP)));
1035      }
1036      PUSH32(frameptr);
1037   }
1038   REG32(EBP) = frameptr;
1039   if(!STACK_32BIT)
1040      REG16(SP) -= framesize;
1041   else
1042      REG32(ESP) -= framesize;
1043   CYCLES(CYCLES_ENTER);
1044}
1045
1046void i386_device::i386_leave32()           // Opcode 0xc9
1047{
1048   if(!STACK_32BIT)
1049      REG16(SP) = REG16(BP);
1050   else
1051      REG32(ESP) = REG32(EBP);
1052   REG32(EBP) = POP32();
1053   CYCLES(CYCLES_LEAVE);
1054}
1055
1056void i386_device::i386_lodsd()             // Opcode 0xad
1057{
1058   UINT32 eas;
1059   if( m_segment_prefix ) {
1060      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1061   } else {
1062      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1063   }
1064   REG32(EAX) = READ32(eas);
1065   BUMP_SI(4);
1066   CYCLES(CYCLES_LODS);
1067}
1068
1069void i386_device::i386_loop32()            // Opcode 0xe2
1070{
1071   INT8 disp = FETCH();
1072   INT32 reg = (m_address_size)?--REG32(ECX):--REG16(CX);
1073   if( reg != 0 ) {
1074      m_eip += disp;
1075      CHANGE_PC(m_eip);
1076   }
1077   CYCLES(CYCLES_LOOP);       /* TODO: Timing = 11 + m */
1078}
1079
1080void i386_device::i386_loopne32()          // Opcode 0xe0
1081{
1082   INT8 disp = FETCH();
1083   INT32 reg = (m_address_size)?--REG32(ECX):--REG16(CX);
1084   if( reg != 0 && m_ZF == 0 ) {
1085      m_eip += disp;
1086      CHANGE_PC(m_eip);
1087   }
1088   CYCLES(CYCLES_LOOPNZ);     /* TODO: Timing = 11 + m */
1089}
1090
1091void i386_device::i386_loopz32()           // Opcode 0xe1
1092{
1093   INT8 disp = FETCH();
1094   INT32 reg = (m_address_size)?--REG32(ECX):--REG16(CX);
1095   if( reg != 0 && m_ZF != 0 ) {
1096      m_eip += disp;
1097      CHANGE_PC(m_eip);
1098   }
1099   CYCLES(CYCLES_LOOPZ);      /* TODO: Timing = 11 + m */
1100}
1101
1102void i386_device::i386_mov_rm32_r32()      // Opcode 0x89
1103{
1104   UINT32 src;
1105   UINT8 modrm = FETCH();
1106   if( modrm >= 0xc0 ) {
1107      src = LOAD_REG32(modrm);
1108      STORE_RM32(modrm, src);
1109      CYCLES(CYCLES_MOV_REG_REG);
1110   } else {
1111      UINT32 ea = GetEA(modrm,1);
1112      src = LOAD_REG32(modrm);
1113      WRITE32(ea, src);
1114      CYCLES(CYCLES_MOV_REG_MEM);
1115   }
1116}
1117
1118void i386_device::i386_mov_r32_rm32()      // Opcode 0x8b
1119{
1120   UINT32 src;
1121   UINT8 modrm = FETCH();
1122   if( modrm >= 0xc0 ) {
1123      src = LOAD_RM32(modrm);
1124      STORE_REG32(modrm, src);
1125      CYCLES(CYCLES_MOV_REG_REG);
1126   } else {
1127      UINT32 ea = GetEA(modrm,0);
1128      src = READ32(ea);
1129      STORE_REG32(modrm, src);
1130      CYCLES(CYCLES_MOV_MEM_REG);
1131   }
1132}
1133
1134void i386_device::i386_mov_rm32_i32()      // Opcode 0xc7
1135{
1136   UINT8 modrm = FETCH();
1137   if( modrm >= 0xc0 ) {
1138      UINT32 value = FETCH32();
1139      STORE_RM32(modrm, value);
1140      CYCLES(CYCLES_MOV_IMM_REG);
1141   } else {
1142      UINT32 ea = GetEA(modrm,1);
1143      UINT32 value = FETCH32();
1144      WRITE32(ea, value);
1145      CYCLES(CYCLES_MOV_IMM_MEM);
1146   }
1147}
1148
1149void i386_device::i386_mov_eax_m32()       // Opcode 0xa1
1150{
1151   UINT32 offset, ea;
1152   if( m_address_size ) {
1153      offset = FETCH32();
1154   } else {
1155      offset = FETCH16();
1156   }
1157   if( m_segment_prefix ) {
1158      ea = i386_translate(m_segment_override, offset, 0 );
1159   } else {
1160      ea = i386_translate(DS, offset, 0 );
1161   }
1162   REG32(EAX) = READ32(ea);
1163   CYCLES(CYCLES_MOV_MEM_ACC);
1164}
1165
1166void i386_device::i386_mov_m32_eax()       // Opcode 0xa3
1167{
1168   UINT32 offset, ea;
1169   if( m_address_size ) {
1170      offset = FETCH32();
1171   } else {
1172      offset = FETCH16();
1173   }
1174   if( m_segment_prefix ) {
1175      ea = i386_translate(m_segment_override, offset, 1 );
1176   } else {
1177      ea = i386_translate(DS, offset, 1 );
1178   }
1179   WRITE32(ea, REG32(EAX) );
1180   CYCLES(CYCLES_MOV_ACC_MEM);
1181}
1182
1183void i386_device::i386_mov_eax_i32()       // Opcode 0xb8
1184{
1185   REG32(EAX) = FETCH32();
1186   CYCLES(CYCLES_MOV_IMM_REG);
1187}
1188
1189void i386_device::i386_mov_ecx_i32()       // Opcode 0xb9
1190{
1191   REG32(ECX) = FETCH32();
1192   CYCLES(CYCLES_MOV_IMM_REG);
1193}
1194
1195void i386_device::i386_mov_edx_i32()       // Opcode 0xba
1196{
1197   REG32(EDX) = FETCH32();
1198   CYCLES(CYCLES_MOV_IMM_REG);
1199}
1200
1201void i386_device::i386_mov_ebx_i32()       // Opcode 0xbb
1202{
1203   REG32(EBX) = FETCH32();
1204   CYCLES(CYCLES_MOV_IMM_REG);
1205}
1206
1207void i386_device::i386_mov_esp_i32()       // Opcode 0xbc
1208{
1209   REG32(ESP) = FETCH32();
1210   CYCLES(CYCLES_MOV_IMM_REG);
1211}
1212
1213void i386_device::i386_mov_ebp_i32()       // Opcode 0xbd
1214{
1215   REG32(EBP) = FETCH32();
1216   CYCLES(CYCLES_MOV_IMM_REG);
1217}
1218
1219void i386_device::i386_mov_esi_i32()       // Opcode 0xbe
1220{
1221   REG32(ESI) = FETCH32();
1222   CYCLES(CYCLES_MOV_IMM_REG);
1223}
1224
1225void i386_device::i386_mov_edi_i32()       // Opcode 0xbf
1226{
1227   REG32(EDI) = FETCH32();
1228   CYCLES(CYCLES_MOV_IMM_REG);
1229}
1230
1231void i386_device::i386_movsd()             // Opcode 0xa5
1232{
1233   UINT32 eas, ead, v;
1234   if( m_segment_prefix ) {
1235      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1236   } else {
1237      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1238   }
1239   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
1240   v = READ32(eas);
1241   WRITE32(ead, v);
1242   BUMP_SI(4);
1243   BUMP_DI(4);
1244   CYCLES(CYCLES_MOVS);
1245}
1246
1247void i386_device::i386_movsx_r32_rm8()     // Opcode 0x0f be
1248{
1249   UINT8 modrm = FETCH();
1250   if( modrm >= 0xc0 ) {
1251      INT32 src = (INT8)LOAD_RM8(modrm);
1252      STORE_REG32(modrm, src);
1253      CYCLES(CYCLES_MOVSX_REG_REG);
1254   } else {
1255      UINT32 ea = GetEA(modrm,0);
1256      INT32 src = (INT8)READ8(ea);
1257      STORE_REG32(modrm, src);
1258      CYCLES(CYCLES_MOVSX_MEM_REG);
1259   }
1260}
1261
1262void i386_device::i386_movsx_r32_rm16()    // Opcode 0x0f bf
1263{
1264   UINT8 modrm = FETCH();
1265   if( modrm >= 0xc0 ) {
1266      INT32 src = (INT16)LOAD_RM16(modrm);
1267      STORE_REG32(modrm, src);
1268      CYCLES(CYCLES_MOVSX_REG_REG);
1269   } else {
1270      UINT32 ea = GetEA(modrm,0);
1271      INT32 src = (INT16)READ16(ea);
1272      STORE_REG32(modrm, src);
1273      CYCLES(CYCLES_MOVSX_MEM_REG);
1274   }
1275}
1276
1277void i386_device::i386_movzx_r32_rm8()     // Opcode 0x0f b6
1278{
1279   UINT8 modrm = FETCH();
1280   if( modrm >= 0xc0 ) {
1281      UINT32 src = (UINT8)LOAD_RM8(modrm);
1282      STORE_REG32(modrm, src);
1283      CYCLES(CYCLES_MOVZX_REG_REG);
1284   } else {
1285      UINT32 ea = GetEA(modrm,0);
1286      UINT32 src = (UINT8)READ8(ea);
1287      STORE_REG32(modrm, src);
1288      CYCLES(CYCLES_MOVZX_MEM_REG);
1289   }
1290}
1291
1292void i386_device::i386_movzx_r32_rm16()    // Opcode 0x0f b7
1293{
1294   UINT8 modrm = FETCH();
1295   if( modrm >= 0xc0 ) {
1296      UINT32 src = (UINT16)LOAD_RM16(modrm);
1297      STORE_REG32(modrm, src);
1298      CYCLES(CYCLES_MOVZX_REG_REG);
1299   } else {
1300      UINT32 ea = GetEA(modrm,0);
1301      UINT32 src = (UINT16)READ16(ea);
1302      STORE_REG32(modrm, src);
1303      CYCLES(CYCLES_MOVZX_MEM_REG);
1304   }
1305}
1306
1307void i386_device::i386_or_rm32_r32()       // Opcode 0x09
1308{
1309   UINT32 src, dst;
1310   UINT8 modrm = FETCH();
1311   if( modrm >= 0xc0 ) {
1312      src = LOAD_REG32(modrm);
1313      dst = LOAD_RM32(modrm);
1314      dst = OR32(dst, src);
1315      STORE_RM32(modrm, dst);
1316      CYCLES(CYCLES_ALU_REG_REG);
1317   } else {
1318      UINT32 ea = GetEA(modrm,1);
1319      src = LOAD_REG32(modrm);
1320      dst = READ32(ea);
1321      dst = OR32(dst, src);
1322      WRITE32(ea, dst);
1323      CYCLES(CYCLES_ALU_REG_MEM);
1324   }
1325}
1326
1327void i386_device::i386_or_r32_rm32()       // Opcode 0x0b
1328{
1329   UINT32 src, dst;
1330   UINT8 modrm = FETCH();
1331   if( modrm >= 0xc0 ) {
1332      src = LOAD_RM32(modrm);
1333      dst = LOAD_REG32(modrm);
1334      dst = OR32(dst, src);
1335      STORE_REG32(modrm, dst);
1336      CYCLES(CYCLES_ALU_REG_REG);
1337   } else {
1338      UINT32 ea = GetEA(modrm,0);
1339      src = READ32(ea);
1340      dst = LOAD_REG32(modrm);
1341      dst = OR32(dst, src);
1342      STORE_REG32(modrm, dst);
1343      CYCLES(CYCLES_ALU_MEM_REG);
1344   }
1345}
1346
1347void i386_device::i386_or_eax_i32()        // Opcode 0x0d
1348{
1349   UINT32 src, dst;
1350   src = FETCH32();
1351   dst = REG32(EAX);
1352   dst = OR32(dst, src);
1353   REG32(EAX) = dst;
1354   CYCLES(CYCLES_ALU_IMM_ACC);
1355}
1356
1357void i386_device::i386_out_eax_i8()        // Opcode 0xe7
1358{
1359   UINT16 port = FETCH();
1360   UINT32 data = REG32(EAX);
1361   WRITEPORT32(port, data);
1362   CYCLES(CYCLES_OUT_VAR);
1363}
1364
1365void i386_device::i386_out_eax_dx()        // Opcode 0xef
1366{
1367   UINT16 port = REG16(DX);
1368   UINT32 data = REG32(EAX);
1369   WRITEPORT32(port, data);
1370   CYCLES(CYCLES_OUT);
1371}
1372
1373void i386_device::i386_pop_eax()           // Opcode 0x58
1374{
1375   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1376   if(i386_limit_check(SS,offset+3) == 0)
1377      REG32(EAX) = POP32();
1378   else
1379      FAULT(FAULT_SS,0)
1380   CYCLES(CYCLES_POP_REG_SHORT);
1381}
1382
1383void i386_device::i386_pop_ecx()           // Opcode 0x59
1384{
1385   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1386   if(i386_limit_check(SS,offset+3) == 0)
1387      REG32(ECX) = POP32();
1388   else
1389      FAULT(FAULT_SS,0)
1390   CYCLES(CYCLES_POP_REG_SHORT);
1391}
1392
1393void i386_device::i386_pop_edx()           // Opcode 0x5a
1394{
1395   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1396   if(i386_limit_check(SS,offset+3) == 0)
1397      REG32(EDX) = POP32();
1398   else
1399      FAULT(FAULT_SS,0)
1400   CYCLES(CYCLES_POP_REG_SHORT);
1401}
1402
1403void i386_device::i386_pop_ebx()           // Opcode 0x5b
1404{
1405   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1406   if(i386_limit_check(SS,offset+3) == 0)
1407      REG32(EBX) = POP32();
1408   else
1409      FAULT(FAULT_SS,0)
1410   CYCLES(CYCLES_POP_REG_SHORT);
1411}
1412
1413void i386_device::i386_pop_esp()           // Opcode 0x5c
1414{
1415   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1416   if(i386_limit_check(SS,offset+3) == 0)
1417      REG32(ESP) = POP32();
1418   else
1419      FAULT(FAULT_SS,0)
1420   CYCLES(CYCLES_POP_REG_SHORT);
1421}
1422
1423void i386_device::i386_pop_ebp()           // Opcode 0x5d
1424{
1425   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1426   if(i386_limit_check(SS,offset+3) == 0)
1427      REG32(EBP) = POP32();
1428   else
1429      FAULT(FAULT_SS,0)
1430   CYCLES(CYCLES_POP_REG_SHORT);
1431}
1432
1433void i386_device::i386_pop_esi()           // Opcode 0x5e
1434{
1435   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1436   if(i386_limit_check(SS,offset+3) == 0)
1437      REG32(ESI) = POP32();
1438   else
1439      FAULT(FAULT_SS,0)
1440   CYCLES(CYCLES_POP_REG_SHORT);
1441}
1442
1443void i386_device::i386_pop_edi()           // Opcode 0x5f
1444{
1445   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1446   if(i386_limit_check(SS,offset+3) == 0)
1447      REG32(EDI) = POP32();
1448   else
1449      FAULT(FAULT_SS,0)
1450   CYCLES(CYCLES_POP_REG_SHORT);
1451}
1452
1453bool i386_device::i386_pop_seg32(int segment)
1454{
1455   UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1456   UINT32 value;
1457   bool fault;
1458   if(i386_limit_check(SS,offset+3) == 0)
1459   {
1460      ea = i386_translate(SS, offset, 0);
1461      value = READ32(ea);
1462      i386_sreg_load(value, segment, &fault);
1463      if(fault) return false;
1464      if(STACK_32BIT)
1465         REG32(ESP) = offset + 4;
1466      else
1467         REG16(SP) = offset + 4;
1468   }
1469   else
1470   {
1471      m_ext = 1;
1472      i386_trap_with_error(FAULT_SS,0,0,0);
1473      return false;
1474   }
1475   CYCLES(CYCLES_POP_SREG);
1476   return true;
1477}
1478
1479void i386_device::i386_pop_ds32()          // Opcode 0x1f
1480{
1481   i386_pop_seg32(DS);
1482}
1483
1484void i386_device::i386_pop_es32()          // Opcode 0x07
1485{
1486   i386_pop_seg32(ES);
1487}
1488
1489void i386_device::i386_pop_fs32()          // Opcode 0x0f a1
1490{
1491   i386_pop_seg32(FS);
1492}
1493
1494void i386_device::i386_pop_gs32()          // Opcode 0x0f a9
1495{
1496   i386_pop_seg32(GS);
1497}
1498
1499void i386_device::i386_pop_ss32()          // Opcode 0x17
1500{
1501   if(!i386_pop_seg32(SS)) return;
1502   if(m_IF != 0) // if external interrupts are enabled
1503   {
1504      m_IF = 0;  // reset IF for the next instruction
1505      m_delayed_interrupt_enable = 1;
1506   }
1507}
1508
1509void i386_device::i386_pop_rm32()          // Opcode 0x8f
1510{
1511   UINT8 modrm = FETCH();
1512   UINT32 value;
1513   UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1514   if(i386_limit_check(SS,offset+3) == 0)
1515   {
1516      // be careful here, if the write references the esp register
1517      // it expects the post-pop value but esp must be wound back
1518      // if the write faults
1519      UINT32 temp_sp = REG32(ESP);
1520      value = POP32();
1521
1522      if( modrm >= 0xc0 ) {
1523         STORE_RM32(modrm, value);
1524      } else {
1525         ea = GetEA(modrm,1);
1526         try
1527         {
1528            WRITE32(ea, value);
1529         }
1530         catch(UINT64 e)
1531         {
1532            REG32(ESP) = temp_sp;
1533            throw e;
1534         }
1535      }
1536   }
1537   else
1538      FAULT(FAULT_SS,0)
1539   CYCLES(CYCLES_POP_RM);
1540}
1541
1542void i386_device::i386_popad()             // Opcode 0x61
1543{
1544   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1545   if(i386_limit_check(SS,offset+31) == 0)
1546   {
1547      REG32(EDI) = POP32();
1548      REG32(ESI) = POP32();
1549      REG32(EBP) = POP32();
1550      REG32(ESP) += 4;
1551      REG32(EBX) = POP32();
1552      REG32(EDX) = POP32();
1553      REG32(ECX) = POP32();
1554      REG32(EAX) = POP32();
1555   }
1556   else
1557      FAULT(FAULT_SS,0)
1558   CYCLES(CYCLES_POPA);
1559}
1560
1561void i386_device::i386_popfd()             // Opcode 0x9d
1562{
1563   UINT32 value;
1564   UINT32 current = get_flags();
1565   UINT8 IOPL = (current >> 12) & 0x03;
1566   UINT32 mask = 0x00257fd5;  // VM, VIP and VIF cannot be set by POPF/POPFD
1567   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1568
1569   // IOPL can only change if CPL is 0
1570   if(m_CPL != 0)
1571      mask &= ~0x00003000;
1572
1573   // IF can only change if CPL is at least as privileged as IOPL
1574   if(m_CPL > IOPL)
1575      mask &= ~0x00000200;
1576
1577   if(V8086_MODE)
1578   {
1579      if(IOPL < 3)
1580      {
1581         logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",m_pc);
1582         FAULT(FAULT_GP,0)  // #GP(0)
1583      }
1584      mask &= ~0x00003000;  // IOPL cannot be changed while in V8086 mode
1585   }
1586
1587   if(i386_limit_check(SS,offset+3) == 0)
1588   {
1589      value = POP32();
1590      value &= ~0x00010000;  // RF will always return zero
1591      set_flags((current & ~mask) | (value & mask));  // mask out reserved bits
1592   }
1593   else
1594      FAULT(FAULT_SS,0)
1595   CYCLES(CYCLES_POPF);
1596}
1597
1598void i386_device::i386_push_eax()          // Opcode 0x50
1599{
1600   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1601   if(i386_limit_check(SS,offset-4) == 0)
1602      PUSH32(REG32(EAX) );
1603   else
1604      FAULT(FAULT_SS,0)
1605   CYCLES(CYCLES_PUSH_REG_SHORT);
1606}
1607
1608void i386_device::i386_push_ecx()          // Opcode 0x51
1609{
1610   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1611   if(i386_limit_check(SS,offset-4) == 0)
1612      PUSH32(REG32(ECX) );
1613   else
1614      FAULT(FAULT_SS,0)
1615   CYCLES(CYCLES_PUSH_REG_SHORT);
1616}
1617
1618void i386_device::i386_push_edx()          // Opcode 0x52
1619{
1620   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1621   if(i386_limit_check(SS,offset-4) == 0)
1622      PUSH32(REG32(EDX) );
1623   else
1624      FAULT(FAULT_SS,0)
1625   CYCLES(CYCLES_PUSH_REG_SHORT);
1626}
1627
1628void i386_device::i386_push_ebx()          // Opcode 0x53
1629{
1630   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1631   if(i386_limit_check(SS,offset-4) == 0)
1632      PUSH32(REG32(EBX) );
1633   else
1634      FAULT(FAULT_SS,0)
1635   CYCLES(CYCLES_PUSH_REG_SHORT);
1636}
1637
1638void i386_device::i386_push_esp()          // Opcode 0x54
1639{
1640   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1641   if(i386_limit_check(SS,offset-4) == 0)
1642      PUSH32(REG32(ESP) );
1643   else
1644      FAULT(FAULT_SS,0)
1645   CYCLES(CYCLES_PUSH_REG_SHORT);
1646}
1647
1648void i386_device::i386_push_ebp()          // Opcode 0x55
1649{
1650   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1651   if(i386_limit_check(SS,offset-4) == 0)
1652      PUSH32(REG32(EBP) );
1653   else
1654      FAULT(FAULT_SS,0)
1655   CYCLES(CYCLES_PUSH_REG_SHORT);
1656}
1657
1658void i386_device::i386_push_esi()          // Opcode 0x56
1659{
1660   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1661   if(i386_limit_check(SS,offset-4) == 0)
1662      PUSH32(REG32(ESI) );
1663   else
1664      FAULT(FAULT_SS,0)
1665   CYCLES(CYCLES_PUSH_REG_SHORT);
1666}
1667
1668void i386_device::i386_push_edi()          // Opcode 0x57
1669{
1670   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1671   if(i386_limit_check(SS,offset-4) == 0)
1672      PUSH32(REG32(EDI) );
1673   else
1674      FAULT(FAULT_SS,0)
1675   CYCLES(CYCLES_PUSH_REG_SHORT);
1676}
1677
1678void i386_device::i386_push_cs32()         // Opcode 0x0e
1679{
1680   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1681   if(i386_limit_check(SS,offset-4) == 0)
1682      PUSH32(m_sreg[CS].selector );
1683   else
1684      FAULT(FAULT_SS,0)
1685   CYCLES(CYCLES_PUSH_SREG);
1686}
1687
1688void i386_device::i386_push_ds32()         // Opcode 0x1e
1689{
1690   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1691   if(i386_limit_check(SS,offset-4) == 0)
1692      PUSH32(m_sreg[DS].selector );
1693   else
1694      FAULT(FAULT_SS,0)
1695   CYCLES(CYCLES_PUSH_SREG);
1696}
1697
1698void i386_device::i386_push_es32()         // Opcode 0x06
1699{
1700   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1701   if(i386_limit_check(SS,offset-4) == 0)
1702      PUSH32(m_sreg[ES].selector );
1703   else
1704      FAULT(FAULT_SS,0)
1705   CYCLES(CYCLES_PUSH_SREG);
1706}
1707
1708void i386_device::i386_push_fs32()         // Opcode 0x0f a0
1709{
1710   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1711   if(i386_limit_check(SS,offset-4) == 0)
1712      PUSH32(m_sreg[FS].selector );
1713   else
1714      FAULT(FAULT_SS,0)
1715   CYCLES(CYCLES_PUSH_SREG);
1716}
1717
1718void i386_device::i386_push_gs32()         // Opcode 0x0f a8
1719{
1720   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1721   if(i386_limit_check(SS,offset-4) == 0)
1722      PUSH32(m_sreg[GS].selector );
1723   else
1724      FAULT(FAULT_SS,0)
1725   CYCLES(CYCLES_PUSH_SREG);
1726}
1727
1728void i386_device::i386_push_ss32()         // Opcode 0x16
1729{
1730   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1731   if(i386_limit_check(SS,offset-4) == 0)
1732      PUSH32(m_sreg[SS].selector );
1733   else
1734      FAULT(FAULT_SS,0)
1735   CYCLES(CYCLES_PUSH_SREG);
1736}
1737
1738void i386_device::i386_push_i32()          // Opcode 0x68
1739{
1740   UINT32 value = FETCH32();
1741   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1742   if(i386_limit_check(SS,offset-4) == 0)
1743      PUSH32(value);
1744   else
1745      FAULT(FAULT_SS,0)
1746   CYCLES(CYCLES_PUSH_IMM);
1747}
1748
1749void i386_device::i386_pushad()            // Opcode 0x60
1750{
1751   UINT32 temp = REG32(ESP);
1752   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1753   if(i386_limit_check(SS,offset-32) == 0)
1754   {
1755      PUSH32(REG32(EAX) );
1756      PUSH32(REG32(ECX) );
1757      PUSH32(REG32(EDX) );
1758      PUSH32(REG32(EBX) );
1759      PUSH32(temp );
1760      PUSH32(REG32(EBP) );
1761      PUSH32(REG32(ESI) );
1762      PUSH32(REG32(EDI) );
1763   }
1764   else
1765      FAULT(FAULT_SS,0)
1766   CYCLES(CYCLES_PUSHA);
1767}
1768
1769void i386_device::i386_pushfd()            // Opcode 0x9c
1770{
1771   if(!m_IOP1 && !m_IOP2 && V8086_MODE)
1772      FAULT(FAULT_GP,0)
1773   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1774   if(i386_limit_check(SS,offset-4) == 0)
1775      PUSH32(get_flags() & 0x00fcffff );
1776   else
1777      FAULT(FAULT_SS,0)
1778   CYCLES(CYCLES_PUSHF);
1779}
1780
1781void i386_device::i386_ret_near32_i16()    // Opcode 0xc2
1782{
1783   INT16 disp = FETCH16();
1784   m_eip = POP32();
1785   REG32(ESP) += disp;
1786   CHANGE_PC(m_eip);
1787   CYCLES(CYCLES_RET_IMM);        /* TODO: Timing = 10 + m */
1788}
1789
1790void i386_device::i386_ret_near32()        // Opcode 0xc3
1791{
1792   m_eip = POP32();
1793   CHANGE_PC(m_eip);
1794   CYCLES(CYCLES_RET);        /* TODO: Timing = 10 + m */
1795}
1796
1797void i386_device::i386_sbb_rm32_r32()      // Opcode 0x19
1798{
1799   UINT32 src, dst;
1800   UINT8 modrm = FETCH();
1801   if( modrm >= 0xc0 ) {
1802      src = LOAD_REG32(modrm);
1803      dst = LOAD_RM32(modrm);
1804      dst = SBB32(dst, src, m_CF);
1805      STORE_RM32(modrm, dst);
1806      CYCLES(CYCLES_ALU_REG_REG);
1807   } else {
1808      UINT32 ea = GetEA(modrm,1);
1809      src = LOAD_REG32(modrm);
1810      dst = READ32(ea);
1811      dst = SBB32(dst, src, m_CF);
1812      WRITE32(ea, dst);
1813      CYCLES(CYCLES_ALU_REG_MEM);
1814   }
1815}
1816
1817void i386_device::i386_sbb_r32_rm32()      // Opcode 0x1b
1818{
1819   UINT32 src, dst;
1820   UINT8 modrm = FETCH();
1821   if( modrm >= 0xc0 ) {
1822      src = LOAD_RM32(modrm);
1823      dst = LOAD_REG32(modrm);
1824      dst = SBB32(dst, src, m_CF);
1825      STORE_REG32(modrm, dst);
1826      CYCLES(CYCLES_ALU_REG_REG);
1827   } else {
1828      UINT32 ea = GetEA(modrm,0);
1829      src = READ32(ea);
1830      dst = LOAD_REG32(modrm);
1831      dst = SBB32(dst, src, m_CF);
1832      STORE_REG32(modrm, dst);
1833      CYCLES(CYCLES_ALU_MEM_REG);
1834   }
1835}
1836
1837void i386_device::i386_sbb_eax_i32()       // Opcode 0x1d
1838{
1839   UINT32 src, dst;
1840   src = FETCH32();
1841   dst = REG32(EAX);
1842   dst = SBB32(dst, src, m_CF);
1843   REG32(EAX) = dst;
1844   CYCLES(CYCLES_ALU_IMM_ACC);
1845}
1846
1847void i386_device::i386_scasd()             // Opcode 0xaf
1848{
1849   UINT32 eas, src, dst;
1850   eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
1851   src = READ32(eas);
1852   dst = REG32(EAX);
1853   SUB32(dst, src);
1854   BUMP_DI(4);
1855   CYCLES(CYCLES_SCAS);
1856}
1857
1858void i386_device::i386_shld32_i8()         // Opcode 0x0f a4
1859{
1860   UINT8 modrm = FETCH();
1861   if( modrm >= 0xc0 ) {
1862      UINT32 dst = LOAD_RM32(modrm);
1863      UINT32 upper = LOAD_REG32(modrm);
1864      UINT8 shift = FETCH();
1865      shift &= 31;
1866      if( shift == 0 ) {
1867      } else {
1868         m_CF = (dst & (1 << (32-shift))) ? 1 : 0;
1869         dst = (dst << shift) | (upper >> (32-shift));
1870         m_OF = m_CF ^ (dst >> 31);
1871         SetSZPF32(dst);
1872      }
1873      STORE_RM32(modrm, dst);
1874      CYCLES(CYCLES_SHLD_REG);
1875   } else {
1876      UINT32 ea = GetEA(modrm,1);
1877      UINT32 dst = READ32(ea);
1878      UINT32 upper = LOAD_REG32(modrm);
1879      UINT8 shift = FETCH();
1880      shift &= 31;
1881      if( shift == 0 ) {
1882      } else {
1883         m_CF = (dst & (1 << (32-shift))) ? 1 : 0;
1884         dst = (dst << shift) | (upper >> (32-shift));
1885         m_OF = m_CF ^ (dst >> 31);
1886         SetSZPF32(dst);
1887      }
1888      WRITE32(ea, dst);
1889      CYCLES(CYCLES_SHLD_MEM);
1890   }
1891}
1892
1893void i386_device::i386_shld32_cl()         // Opcode 0x0f a5
1894{
1895   UINT8 modrm = FETCH();
1896   if( modrm >= 0xc0 ) {
1897      UINT32 dst = LOAD_RM32(modrm);
1898      UINT32 upper = LOAD_REG32(modrm);
1899      UINT8 shift = REG8(CL);
1900      shift &= 31;
1901      if( shift == 0 ) {
1902      } else {
1903         m_CF = (dst & (1 << (32-shift))) ? 1 : 0;
1904         dst = (dst << shift) | (upper >> (32-shift));
1905         m_OF = m_CF ^ (dst >> 31);
1906         SetSZPF32(dst);
1907      }
1908      STORE_RM32(modrm, dst);
1909      CYCLES(CYCLES_SHLD_REG);
1910   } else {
1911      UINT32 ea = GetEA(modrm,1);
1912      UINT32 dst = READ32(ea);
1913      UINT32 upper = LOAD_REG32(modrm);
1914      UINT8 shift = REG8(CL);
1915      shift &= 31;
1916      if( shift == 0 ) {
1917      } else {
1918         m_CF = (dst & (1 << (32-shift))) ? 1 : 0;
1919         dst = (dst << shift) | (upper >> (32-shift));
1920         m_OF = m_CF ^ (dst >> 31);
1921         SetSZPF32(dst);
1922      }
1923      WRITE32(ea, dst);
1924      CYCLES(CYCLES_SHLD_MEM);
1925   }
1926}
1927
1928void i386_device::i386_shrd32_i8()         // Opcode 0x0f ac
1929{
1930   UINT8 modrm = FETCH();
1931   if( modrm >= 0xc0 ) {
1932      UINT32 dst = LOAD_RM32(modrm);
1933      UINT32 upper = LOAD_REG32(modrm);
1934      UINT8 shift = FETCH();
1935      shift &= 31;
1936      if( shift == 0 ) {
1937      } else {
1938         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
1939         dst = (dst >> shift) | (upper << (32-shift));
1940         m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
1941         SetSZPF32(dst);
1942      }
1943      STORE_RM32(modrm, dst);
1944      CYCLES(CYCLES_SHRD_REG);
1945   } else {
1946      UINT32 ea = GetEA(modrm,1);
1947      UINT32 dst = READ32(ea);
1948      UINT32 upper = LOAD_REG32(modrm);
1949      UINT8 shift = FETCH();
1950      shift &= 31;
1951      if( shift == 0 ) {
1952      } else {
1953         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
1954         dst = (dst >> shift) | (upper << (32-shift));
1955         m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
1956         SetSZPF32(dst);
1957      }
1958      WRITE32(ea, dst);
1959      CYCLES(CYCLES_SHRD_MEM);
1960   }
1961}
1962
1963void i386_device::i386_shrd32_cl()         // Opcode 0x0f ad
1964{
1965   UINT8 modrm = FETCH();
1966   if( modrm >= 0xc0 ) {
1967      UINT32 dst = LOAD_RM32(modrm);
1968      UINT32 upper = LOAD_REG32(modrm);
1969      UINT8 shift = REG8(CL);
1970      shift &= 31;
1971      if( shift == 0 ) {
1972      } else {
1973         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
1974         dst = (dst >> shift) | (upper << (32-shift));
1975         m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
1976         SetSZPF32(dst);
1977      }
1978      STORE_RM32(modrm, dst);
1979      CYCLES(CYCLES_SHRD_REG);
1980   } else {
1981      UINT32 ea = GetEA(modrm,1);
1982      UINT32 dst = READ32(ea);
1983      UINT32 upper = LOAD_REG32(modrm);
1984      UINT8 shift = REG8(CL);
1985      shift &= 31;
1986      if( shift == 0 ) {
1987      } else {
1988         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
1989         dst = (dst >> shift) | (upper << (32-shift));
1990         m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
1991         SetSZPF32(dst);
1992      }
1993      WRITE32(ea, dst);
1994      CYCLES(CYCLES_SHRD_MEM);
1995   }
1996}
1997
1998void i386_device::i386_stosd()             // Opcode 0xab
1999{
2000   UINT32 eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
2001   WRITE32(eas, REG32(EAX));
2002   BUMP_DI(4);
2003   CYCLES(CYCLES_STOS);
2004}
2005
2006void i386_device::i386_sub_rm32_r32()      // Opcode 0x29
2007{
2008   UINT32 src, dst;
2009   UINT8 modrm = FETCH();
2010   if( modrm >= 0xc0 ) {
2011      src = LOAD_REG32(modrm);
2012      dst = LOAD_RM32(modrm);
2013      dst = SUB32(dst, src);
2014      STORE_RM32(modrm, dst);
2015      CYCLES(CYCLES_ALU_REG_REG);
2016   } else {
2017      UINT32 ea = GetEA(modrm,1);
2018      src = LOAD_REG32(modrm);
2019      dst = READ32(ea);
2020      dst = SUB32(dst, src);
2021      WRITE32(ea, dst);
2022      CYCLES(CYCLES_ALU_REG_MEM);
2023   }
2024}
2025
2026void i386_device::i386_sub_r32_rm32()      // Opcode 0x2b
2027{
2028   UINT32 src, dst;
2029   UINT8 modrm = FETCH();
2030   if( modrm >= 0xc0 ) {
2031      src = LOAD_RM32(modrm);
2032      dst = LOAD_REG32(modrm);
2033      dst = SUB32(dst, src);
2034      STORE_REG32(modrm, dst);
2035      CYCLES(CYCLES_ALU_REG_REG);
2036   } else {
2037      UINT32 ea = GetEA(modrm,1);
2038      src = READ32(ea);
2039      dst = LOAD_REG32(modrm);
2040      dst = SUB32(dst, src);
2041      STORE_REG32(modrm, dst);
2042      CYCLES(CYCLES_ALU_MEM_REG);
2043   }
2044}
2045
2046void i386_device::i386_sub_eax_i32()       // Opcode 0x2d
2047{
2048   UINT32 src, dst;
2049   src = FETCH32();
2050   dst = REG32(EAX);
2051   dst = SUB32(dst, src);
2052   REG32(EAX) = dst;
2053   CYCLES(CYCLES_ALU_IMM_ACC);
2054}
2055
2056void i386_device::i386_test_eax_i32()      // Opcode 0xa9
2057{
2058   UINT32 src = FETCH32();
2059   UINT32 dst = REG32(EAX);
2060   dst = src & dst;
2061   SetSZPF32(dst);
2062   m_CF = 0;
2063   m_OF = 0;
2064   CYCLES(CYCLES_TEST_IMM_ACC);
2065}
2066
2067void i386_device::i386_test_rm32_r32()     // Opcode 0x85
2068{
2069   UINT32 src, dst;
2070   UINT8 modrm = FETCH();
2071   if( modrm >= 0xc0 ) {
2072      src = LOAD_REG32(modrm);
2073      dst = LOAD_RM32(modrm);
2074      dst = src & dst;
2075      SetSZPF32(dst);
2076      m_CF = 0;
2077      m_OF = 0;
2078      CYCLES(CYCLES_TEST_REG_REG);
2079   } else {
2080      UINT32 ea = GetEA(modrm,0);
2081      src = LOAD_REG32(modrm);
2082      dst = READ32(ea);
2083      dst = src & dst;
2084      SetSZPF32(dst);
2085      m_CF = 0;
2086      m_OF = 0;
2087      CYCLES(CYCLES_TEST_REG_MEM);
2088   }
2089}
2090
2091void i386_device::i386_xchg_eax_ecx()      // Opcode 0x91
2092{
2093   UINT32 temp;
2094   temp = REG32(EAX);
2095   REG32(EAX) = REG32(ECX);
2096   REG32(ECX) = temp;
2097   CYCLES(CYCLES_XCHG_REG_REG);
2098}
2099
2100void i386_device::i386_xchg_eax_edx()      // Opcode 0x92
2101{
2102   UINT32 temp;
2103   temp = REG32(EAX);
2104   REG32(EAX) = REG32(EDX);
2105   REG32(EDX) = temp;
2106   CYCLES(CYCLES_XCHG_REG_REG);
2107}
2108
2109void i386_device::i386_xchg_eax_ebx()      // Opcode 0x93
2110{
2111   UINT32 temp;
2112   temp = REG32(EAX);
2113   REG32(EAX) = REG32(EBX);
2114   REG32(EBX) = temp;
2115   CYCLES(CYCLES_XCHG_REG_REG);
2116}
2117
2118void i386_device::i386_xchg_eax_esp()      // Opcode 0x94
2119{
2120   UINT32 temp;
2121   temp = REG32(EAX);
2122   REG32(EAX) = REG32(ESP);
2123   REG32(ESP) = temp;
2124   CYCLES(CYCLES_XCHG_REG_REG);
2125}
2126
2127void i386_device::i386_xchg_eax_ebp()      // Opcode 0x95
2128{
2129   UINT32 temp;
2130   temp = REG32(EAX);
2131   REG32(EAX) = REG32(EBP);
2132   REG32(EBP) = temp;
2133   CYCLES(CYCLES_XCHG_REG_REG);
2134}
2135
2136void i386_device::i386_xchg_eax_esi()      // Opcode 0x96
2137{
2138   UINT32 temp;
2139   temp = REG32(EAX);
2140   REG32(EAX) = REG32(ESI);
2141   REG32(ESI) = temp;
2142   CYCLES(CYCLES_XCHG_REG_REG);
2143}
2144
2145void i386_device::i386_xchg_eax_edi()      // Opcode 0x97
2146{
2147   UINT32 temp;
2148   temp = REG32(EAX);
2149   REG32(EAX) = REG32(EDI);
2150   REG32(EDI) = temp;
2151   CYCLES(CYCLES_XCHG_REG_REG);
2152}
2153
2154void i386_device::i386_xchg_r32_rm32()     // Opcode 0x87
2155{
2156   UINT8 modrm = FETCH();
2157   if( modrm >= 0xc0 ) {
2158      UINT32 src = LOAD_RM32(modrm);
2159      UINT32 dst = LOAD_REG32(modrm);
2160      STORE_REG32(modrm, src);
2161      STORE_RM32(modrm, dst);
2162      CYCLES(CYCLES_XCHG_REG_REG);
2163   } else {
2164      UINT32 ea = GetEA(modrm,1);
2165      UINT32 src = READ32(ea);
2166      UINT32 dst = LOAD_REG32(modrm);
2167      WRITE32(ea, dst);
2168      STORE_REG32(modrm, src);
2169      CYCLES(CYCLES_XCHG_REG_MEM);
2170   }
2171}
2172
2173void i386_device::i386_xor_rm32_r32()      // Opcode 0x31
2174{
2175   UINT32 src, dst;
2176   UINT8 modrm = FETCH();
2177   if( modrm >= 0xc0 ) {
2178      src = LOAD_REG32(modrm);
2179      dst = LOAD_RM32(modrm);
2180      dst = XOR32(dst, src);
2181      STORE_RM32(modrm, dst);
2182      CYCLES(CYCLES_ALU_REG_REG);
2183   } else {
2184      UINT32 ea = GetEA(modrm,1);
2185      src = LOAD_REG32(modrm);
2186      dst = READ32(ea);
2187      dst = XOR32(dst, src);
2188      WRITE32(ea, dst);
2189      CYCLES(CYCLES_ALU_REG_MEM);
2190   }
2191}
2192
2193void i386_device::i386_xor_r32_rm32()      // Opcode 0x33
2194{
2195   UINT32 src, dst;
2196   UINT8 modrm = FETCH();
2197   if( modrm >= 0xc0 ) {
2198      src = LOAD_RM32(modrm);
2199      dst = LOAD_REG32(modrm);
2200      dst = XOR32(dst, src);
2201      STORE_REG32(modrm, dst);
2202      CYCLES(CYCLES_ALU_REG_REG);
2203   } else {
2204      UINT32 ea = GetEA(modrm,0);
2205      src = READ32(ea);
2206      dst = LOAD_REG32(modrm);
2207      dst = XOR32(dst, src);
2208      STORE_REG32(modrm, dst);
2209      CYCLES(CYCLES_ALU_MEM_REG);
2210   }
2211}
2212
2213void i386_device::i386_xor_eax_i32()       // Opcode 0x35
2214{
2215   UINT32 src, dst;
2216   src = FETCH32();
2217   dst = REG32(EAX);
2218   dst = XOR32(dst, src);
2219   REG32(EAX) = dst;
2220   CYCLES(CYCLES_ALU_IMM_ACC);
2221}
2222
2223
2224
2225void i386_device::i386_group81_32()        // Opcode 0x81
2226{
2227   UINT32 ea;
2228   UINT32 src, dst;
2229   UINT8 modrm = FETCH();
2230
2231   switch( (modrm >> 3) & 0x7 )
2232   {
2233      case 0:     // ADD Rm32, i32
2234         if( modrm >= 0xc0 ) {
2235            dst = LOAD_RM32(modrm);
2236            src = FETCH32();
2237            dst = ADD32(dst, src);
2238            STORE_RM32(modrm, dst);
2239            CYCLES(CYCLES_ALU_REG_REG);
2240         } else {
2241            ea = GetEA(modrm,1);
2242            dst = READ32(ea);
2243            src = FETCH32();
2244            dst = ADD32(dst, src);
2245            WRITE32(ea, dst);
2246            CYCLES(CYCLES_ALU_REG_MEM);
2247         }
2248         break;
2249      case 1:     // OR Rm32, i32
2250         if( modrm >= 0xc0 ) {
2251            dst = LOAD_RM32(modrm);
2252            src = FETCH32();
2253            dst = OR32(dst, src);
2254            STORE_RM32(modrm, dst);
2255            CYCLES(CYCLES_ALU_REG_REG);
2256         } else {
2257            ea = GetEA(modrm,1);
2258            dst = READ32(ea);
2259            src = FETCH32();
2260            dst = OR32(dst, src);
2261            WRITE32(ea, dst);
2262            CYCLES(CYCLES_ALU_REG_MEM);
2263         }
2264         break;
2265      case 2:     // ADC Rm32, i32
2266         if( modrm >= 0xc0 ) {
2267            dst = LOAD_RM32(modrm);
2268            src = FETCH32();
2269            dst = ADC32(dst, src, m_CF);
2270            STORE_RM32(modrm, dst);
2271            CYCLES(CYCLES_ALU_REG_REG);
2272         } else {
2273            ea = GetEA(modrm,1);
2274            dst = READ32(ea);
2275            src = FETCH32();
2276            dst = ADC32(dst, src, m_CF);
2277            WRITE32(ea, dst);
2278            CYCLES(CYCLES_ALU_REG_MEM);
2279         }
2280         break;
2281      case 3:     // SBB Rm32, i32
2282         if( modrm >= 0xc0 ) {
2283            dst = LOAD_RM32(modrm);
2284            src = FETCH32();
2285            dst = SBB32(dst, src, m_CF);
2286            STORE_RM32(modrm, dst);
2287            CYCLES(CYCLES_ALU_REG_REG);
2288         } else {
2289            ea = GetEA(modrm,1);
2290            dst = READ32(ea);
2291            src = FETCH32();
2292            dst = SBB32(dst, src, m_CF);
2293            WRITE32(ea, dst);
2294            CYCLES(CYCLES_ALU_REG_MEM);
2295         }
2296         break;
2297      case 4:     // AND Rm32, i32
2298         if( modrm >= 0xc0 ) {
2299            dst = LOAD_RM32(modrm);
2300            src = FETCH32();
2301            dst = AND32(dst, src);
2302            STORE_RM32(modrm, dst);
2303            CYCLES(CYCLES_ALU_REG_REG);
2304         } else {
2305            ea = GetEA(modrm,1);
2306            dst = READ32(ea);
2307            src = FETCH32();
2308            dst = AND32(dst, src);
2309            WRITE32(ea, dst);
2310            CYCLES(CYCLES_ALU_REG_MEM);
2311         }
2312         break;
2313      case 5:     // SUB Rm32, i32
2314         if( modrm >= 0xc0 ) {
2315            dst = LOAD_RM32(modrm);
2316            src = FETCH32();
2317            dst = SUB32(dst, src);
2318            STORE_RM32(modrm, dst);
2319            CYCLES(CYCLES_ALU_REG_REG);
2320         } else {
2321            ea = GetEA(modrm,1);
2322            dst = READ32(ea);
2323            src = FETCH32();
2324            dst = SUB32(dst, src);
2325            WRITE32(ea, dst);
2326            CYCLES(CYCLES_ALU_REG_MEM);
2327         }
2328         break;
2329      case 6:     // XOR Rm32, i32
2330         if( modrm >= 0xc0 ) {
2331            dst = LOAD_RM32(modrm);
2332            src = FETCH32();
2333            dst = XOR32(dst, src);
2334            STORE_RM32(modrm, dst);
2335            CYCLES(CYCLES_ALU_REG_REG);
2336         } else {
2337            ea = GetEA(modrm,1);
2338            dst = READ32(ea);
2339            src = FETCH32();
2340            dst = XOR32(dst, src);
2341            WRITE32(ea, dst);
2342            CYCLES(CYCLES_ALU_REG_MEM);
2343         }
2344         break;
2345      case 7:     // CMP Rm32, i32
2346         if( modrm >= 0xc0 ) {
2347            dst = LOAD_RM32(modrm);
2348            src = FETCH32();
2349            SUB32(dst, src);
2350            CYCLES(CYCLES_CMP_REG_REG);
2351         } else {
2352            ea = GetEA(modrm,0);
2353            dst = READ32(ea);
2354            src = FETCH32();
2355            SUB32(dst, src);
2356            CYCLES(CYCLES_CMP_REG_MEM);
2357         }
2358         break;
2359   }
2360}
2361
2362void i386_device::i386_group83_32()        // Opcode 0x83
2363{
2364   UINT32 ea;
2365   UINT32 src, dst;
2366   UINT8 modrm = FETCH();
2367
2368   switch( (modrm >> 3) & 0x7 )
2369   {
2370      case 0:     // ADD Rm32, i32
2371         if( modrm >= 0xc0 ) {
2372            dst = LOAD_RM32(modrm);
2373            src = (UINT32)(INT32)(INT8)FETCH();
2374            dst = ADD32(dst, src);
2375            STORE_RM32(modrm, dst);
2376            CYCLES(CYCLES_ALU_REG_REG);
2377         } else {
2378            ea = GetEA(modrm,1);
2379            dst = READ32(ea);
2380            src = (UINT32)(INT32)(INT8)FETCH();
2381            dst = ADD32(dst, src);
2382            WRITE32(ea, dst);
2383            CYCLES(CYCLES_ALU_REG_MEM);
2384         }
2385         break;
2386      case 1:     // OR Rm32, i32
2387         if( modrm >= 0xc0 ) {
2388            dst = LOAD_RM32(modrm);
2389            src = (UINT32)(INT32)(INT8)FETCH();
2390            dst = OR32(dst, src);
2391            STORE_RM32(modrm, dst);
2392            CYCLES(CYCLES_ALU_REG_REG);
2393         } else {
2394            ea = GetEA(modrm,1);
2395            dst = READ32(ea);
2396            src = (UINT32)(INT32)(INT8)FETCH();
2397            dst = OR32(dst, src);
2398            WRITE32(ea, dst);
2399            CYCLES(CYCLES_ALU_REG_MEM);
2400         }
2401         break;
2402      case 2:     // ADC Rm32, i32
2403         if( modrm >= 0xc0 ) {
2404            dst = LOAD_RM32(modrm);
2405            src = (UINT32)(INT32)(INT8)FETCH();
2406            dst = ADC32(dst, src, m_CF);
2407            STORE_RM32(modrm, dst);
2408            CYCLES(CYCLES_ALU_REG_REG);
2409         } else {
2410            ea = GetEA(modrm,1);
2411            dst = READ32(ea);
2412            src = (UINT32)(INT32)(INT8)FETCH();
2413            dst = ADC32(dst, src, m_CF);
2414            WRITE32(ea, dst);
2415            CYCLES(CYCLES_ALU_REG_MEM);
2416         }
2417         break;
2418      case 3:     // SBB Rm32, i32
2419         if( modrm >= 0xc0 ) {
2420            dst = LOAD_RM32(modrm);
2421            src = ((UINT32)(INT32)(INT8)FETCH());
2422            dst = SBB32(dst, src, m_CF);
2423            STORE_RM32(modrm, dst);
2424            CYCLES(CYCLES_ALU_REG_REG);
2425         } else {
2426            ea = GetEA(modrm,1);
2427            dst = READ32(ea);
2428            src = ((UINT32)(INT32)(INT8)FETCH());
2429            dst = SBB32(dst, src, m_CF);
2430            WRITE32(ea, dst);
2431            CYCLES(CYCLES_ALU_REG_MEM);
2432         }
2433         break;
2434      case 4:     // AND Rm32, i32
2435         if( modrm >= 0xc0 ) {
2436            dst = LOAD_RM32(modrm);
2437            src = (UINT32)(INT32)(INT8)FETCH();
2438            dst = AND32(dst, src);
2439            STORE_RM32(modrm, dst);
2440            CYCLES(CYCLES_ALU_REG_REG);
2441         } else {
2442            ea = GetEA(modrm,1);
2443            dst = READ32(ea);
2444            src = (UINT32)(INT32)(INT8)FETCH();
2445            dst = AND32(dst, src);
2446            WRITE32(ea, dst);
2447            CYCLES(CYCLES_ALU_REG_MEM);
2448         }
2449         break;
2450      case 5:     // SUB Rm32, i32
2451         if( modrm >= 0xc0 ) {
2452            dst = LOAD_RM32(modrm);
2453            src = (UINT32)(INT32)(INT8)FETCH();
2454            dst = SUB32(dst, src);
2455            STORE_RM32(modrm, dst);
2456            CYCLES(CYCLES_ALU_REG_REG);
2457         } else {
2458            ea = GetEA(modrm,1);
2459            dst = READ32(ea);
2460            src = (UINT32)(INT32)(INT8)FETCH();
2461            dst = SUB32(dst, src);
2462            WRITE32(ea, dst);
2463            CYCLES(CYCLES_ALU_REG_MEM);
2464         }
2465         break;
2466      case 6:     // XOR Rm32, i32
2467         if( modrm >= 0xc0 ) {
2468            dst = LOAD_RM32(modrm);
2469            src = (UINT32)(INT32)(INT8)FETCH();
2470            dst = XOR32(dst, src);
2471            STORE_RM32(modrm, dst);
2472            CYCLES(CYCLES_ALU_REG_REG);
2473         } else {
2474            ea = GetEA(modrm,1);
2475            dst = READ32(ea);
2476            src = (UINT32)(INT32)(INT8)FETCH();
2477            dst = XOR32(dst, src);
2478            WRITE32(ea, dst);
2479            CYCLES(CYCLES_ALU_REG_MEM);
2480         }
2481         break;
2482      case 7:     // CMP Rm32, i32
2483         if( modrm >= 0xc0 ) {
2484            dst = LOAD_RM32(modrm);
2485            src = (UINT32)(INT32)(INT8)FETCH();
2486            SUB32(dst, src);
2487            CYCLES(CYCLES_CMP_REG_REG);
2488         } else {
2489            ea = GetEA(modrm,0);
2490            dst = READ32(ea);
2491            src = (UINT32)(INT32)(INT8)FETCH();
2492            SUB32(dst, src);
2493            CYCLES(CYCLES_CMP_REG_MEM);
2494         }
2495         break;
2496   }
2497}
2498
2499void i386_device::i386_groupC1_32()        // Opcode 0xc1
2500{
2501   UINT32 dst;
2502   UINT8 modrm = FETCH();
2503   UINT8 shift;
2504
2505   if( modrm >= 0xc0 ) {
2506      dst = LOAD_RM32(modrm);
2507      shift = FETCH() & 0x1f;
2508      dst = i386_shift_rotate32(modrm, dst, shift);
2509      STORE_RM32(modrm, dst);
2510   } else {
2511      UINT32 ea = GetEA(modrm,1);
2512      dst = READ32(ea);
2513      shift = FETCH() & 0x1f;
2514      dst = i386_shift_rotate32(modrm, dst, shift);
2515      WRITE32(ea, dst);
2516   }
2517}
2518
2519void i386_device::i386_groupD1_32()        // Opcode 0xd1
2520{
2521   UINT32 dst;
2522   UINT8 modrm = FETCH();
2523
2524   if( modrm >= 0xc0 ) {
2525      dst = LOAD_RM32(modrm);
2526      dst = i386_shift_rotate32(modrm, dst, 1);
2527      STORE_RM32(modrm, dst);
2528   } else {
2529      UINT32 ea = GetEA(modrm,1);
2530      dst = READ32(ea);
2531      dst = i386_shift_rotate32(modrm, dst, 1);
2532      WRITE32(ea, dst);
2533   }
2534}
2535
2536void i386_device::i386_groupD3_32()        // Opcode 0xd3
2537{
2538   UINT32 dst;
2539   UINT8 modrm = FETCH();
2540
2541   if( modrm >= 0xc0 ) {
2542      dst = LOAD_RM32(modrm);
2543      dst = i386_shift_rotate32(modrm, dst, REG8(CL));
2544      STORE_RM32(modrm, dst);
2545   } else {
2546      UINT32 ea = GetEA(modrm,1);
2547      dst = READ32(ea);
2548      dst = i386_shift_rotate32(modrm, dst, REG8(CL));
2549      WRITE32(ea, dst);
2550   }
2551}
2552
2553void i386_device::i386_groupF7_32()        // Opcode 0xf7
2554{
2555   UINT8 modrm = FETCH();
2556
2557   switch( (modrm >> 3) & 0x7 )
2558   {
2559      case 0:         /* TEST Rm32, i32 */
2560         if( modrm >= 0xc0 ) {
2561            UINT32 dst = LOAD_RM32(modrm);
2562            UINT32 src = FETCH32();
2563            dst &= src;
2564            m_CF = m_OF = m_AF = 0;
2565            SetSZPF32(dst);
2566            CYCLES(CYCLES_TEST_IMM_REG);
2567         } else {
2568            UINT32 ea = GetEA(modrm,0);
2569            UINT32 dst = READ32(ea);
2570            UINT32 src = FETCH32();
2571            dst &= src;
2572            m_CF = m_OF = m_AF = 0;
2573            SetSZPF32(dst);
2574            CYCLES(CYCLES_TEST_IMM_MEM);
2575         }
2576         break;
2577      case 2:         /* NOT Rm32 */
2578         if( modrm >= 0xc0 ) {
2579            UINT32 dst = LOAD_RM32(modrm);
2580            dst = ~dst;
2581            STORE_RM32(modrm, dst);
2582            CYCLES(CYCLES_NOT_REG);
2583         } else {
2584            UINT32 ea = GetEA(modrm,1);
2585            UINT32 dst = READ32(ea);
2586            dst = ~dst;
2587            WRITE32(ea, dst);
2588            CYCLES(CYCLES_NOT_MEM);
2589         }
2590         break;
2591      case 3:         /* NEG Rm32 */
2592         if( modrm >= 0xc0 ) {
2593            UINT32 dst = LOAD_RM32(modrm);
2594            dst = SUB32(0, dst );
2595            STORE_RM32(modrm, dst);
2596            CYCLES(CYCLES_NEG_REG);
2597         } else {
2598            UINT32 ea = GetEA(modrm,1);
2599            UINT32 dst = READ32(ea);
2600            dst = SUB32(0, dst );
2601            WRITE32(ea, dst);
2602            CYCLES(CYCLES_NEG_MEM);
2603         }
2604         break;
2605      case 4:         /* MUL EAX, Rm32 */
2606         {
2607            UINT64 result;
2608            UINT32 src, dst;
2609            if( modrm >= 0xc0 ) {
2610               src = LOAD_RM32(modrm);
2611               CYCLES(CYCLES_MUL32_ACC_REG);      /* TODO: Correct multiply timing */
2612            } else {
2613               UINT32 ea = GetEA(modrm,0);
2614               src = READ32(ea);
2615               CYCLES(CYCLES_MUL32_ACC_MEM);      /* TODO: Correct multiply timing */
2616            }
2617
2618            dst = REG32(EAX);
2619            result = (UINT64)src * (UINT64)dst;
2620            REG32(EDX) = (UINT32)(result >> 32);
2621            REG32(EAX) = (UINT32)result;
2622
2623            m_CF = m_OF = (REG32(EDX) != 0);
2624         }
2625         break;
2626      case 5:         /* IMUL EAX, Rm32 */
2627         {
2628            INT64 result;
2629            INT64 src, dst;
2630            if( modrm >= 0xc0 ) {
2631               src = (INT64)(INT32)LOAD_RM32(modrm);
2632               CYCLES(CYCLES_IMUL32_ACC_REG);     /* TODO: Correct multiply timing */
2633            } else {
2634               UINT32 ea = GetEA(modrm,0);
2635               src = (INT64)(INT32)READ32(ea);
2636               CYCLES(CYCLES_IMUL32_ACC_MEM);     /* TODO: Correct multiply timing */
2637            }
2638
2639            dst = (INT64)(INT32)REG32(EAX);
2640            result = src * dst;
2641
2642            REG32(EDX) = (UINT32)(result >> 32);
2643            REG32(EAX) = (UINT32)result;
2644
2645            m_CF = m_OF = !(result == (INT64)(INT32)result);
2646         }
2647         break;
2648      case 6:         /* DIV EAX, Rm32 */
2649         {
2650            UINT64 quotient, remainder, result;
2651            UINT32 src;
2652            if( modrm >= 0xc0 ) {
2653               src = LOAD_RM32(modrm);
2654               CYCLES(CYCLES_DIV32_ACC_REG);
2655            } else {
2656               UINT32 ea = GetEA(modrm,0);
2657               src = READ32(ea);
2658               CYCLES(CYCLES_DIV32_ACC_MEM);
2659            }
2660
2661            quotient = ((UINT64)(REG32(EDX)) << 32) | (UINT64)(REG32(EAX));
2662            if( src ) {
2663               remainder = quotient % (UINT64)src;
2664               result = quotient / (UINT64)src;
2665               if( result > 0xffffffff ) {
2666                  /* TODO: Divide error */
2667               } else {
2668                  REG32(EDX) = (UINT32)remainder;
2669                  REG32(EAX) = (UINT32)result;
2670               }
2671            } else {
2672               i386_trap(0, 0, 0);
2673            }
2674         }
2675         break;
2676      case 7:         /* IDIV EAX, Rm32 */
2677         {
2678            INT64 quotient, remainder, result;
2679            UINT32 src;
2680            if( modrm >= 0xc0 ) {
2681               src = LOAD_RM32(modrm);
2682               CYCLES(CYCLES_IDIV32_ACC_REG);
2683            } else {
2684               UINT32 ea = GetEA(modrm,0);
2685               src = READ32(ea);
2686               CYCLES(CYCLES_IDIV32_ACC_MEM);
2687            }
2688
2689            quotient = (((INT64)REG32(EDX)) << 32) | ((UINT64)REG32(EAX));
2690            if( src ) {
2691               remainder = quotient % (INT64)(INT32)src;
2692               result = quotient / (INT64)(INT32)src;
2693               if( result > 0xffffffff ) {
2694                  /* TODO: Divide error */
2695               } else {
2696                  REG32(EDX) = (UINT32)remainder;
2697                  REG32(EAX) = (UINT32)result;
2698               }
2699            } else {
2700               i386_trap(0, 0, 0);
2701            }
2702         }
2703         break;
2704   }
2705}
2706
2707void i386_device::i386_groupFF_32()        // Opcode 0xff
2708{
2709   UINT8 modrm = FETCH();
2710
2711   switch( (modrm >> 3) & 0x7 )
2712   {
2713      case 0:         /* INC Rm32 */
2714         if( modrm >= 0xc0 ) {
2715            UINT32 dst = LOAD_RM32(modrm);
2716            dst = INC32(dst);
2717            STORE_RM32(modrm, dst);
2718            CYCLES(CYCLES_INC_REG);
2719         } else {
2720            UINT32 ea = GetEA(modrm,1);
2721            UINT32 dst = READ32(ea);
2722            dst = INC32(dst);
2723            WRITE32(ea, dst);
2724            CYCLES(CYCLES_INC_MEM);
2725         }
2726         break;
2727      case 1:         /* DEC Rm32 */
2728         if( modrm >= 0xc0 ) {
2729            UINT32 dst = LOAD_RM32(modrm);
2730            dst = DEC32(dst);
2731            STORE_RM32(modrm, dst);
2732            CYCLES(CYCLES_DEC_REG);
2733         } else {
2734            UINT32 ea = GetEA(modrm,1);
2735            UINT32 dst = READ32(ea);
2736            dst = DEC32(dst);
2737            WRITE32(ea, dst);
2738            CYCLES(CYCLES_DEC_MEM);
2739         }
2740         break;
2741      case 2:         /* CALL Rm32 */
2742         {
2743            UINT32 address;
2744            if( modrm >= 0xc0 ) {
2745               address = LOAD_RM32(modrm);
2746               CYCLES(CYCLES_CALL_REG);       /* TODO: Timing = 7 + m */
2747            } else {
2748               UINT32 ea = GetEA(modrm,0);
2749               address = READ32(ea);
2750               CYCLES(CYCLES_CALL_MEM);       /* TODO: Timing = 10 + m */
2751            }
2752            PUSH32(m_eip );
2753            m_eip = address;
2754            CHANGE_PC(m_eip);
2755         }
2756         break;
2757      case 3:         /* CALL FAR Rm32 */
2758         {
2759            UINT16 selector;
2760            UINT32 address;
2761
2762            if( modrm >= 0xc0 )
2763            {
2764               report_invalid_modrm("groupFF_32", modrm);
2765            }
2766            else
2767            {
2768               UINT32 ea = GetEA(modrm,0);
2769               address = READ32(ea + 0);
2770               selector = READ16(ea + 4);
2771               CYCLES(CYCLES_CALL_MEM_INTERSEG);      /* TODO: Timing = 10 + m */
2772               if(PROTECTED_MODE && !V8086_MODE)
2773               {
2774                  i386_protected_mode_call(selector,address,1,1);
2775               }
2776               else
2777               {
2778                  PUSH32(m_sreg[CS].selector );
2779                  PUSH32(m_eip );
2780                  m_sreg[CS].selector = selector;
2781                  m_performed_intersegment_jump = 1;
2782                  i386_load_segment_descriptor(CS );
2783                  m_eip = address;
2784                  CHANGE_PC(m_eip);
2785               }
2786            }
2787         }
2788         break;
2789      case 4:         /* JMP Rm32 */
2790         {
2791            UINT32 address;
2792            if( modrm >= 0xc0 ) {
2793               address = LOAD_RM32(modrm);
2794               CYCLES(CYCLES_JMP_REG);        /* TODO: Timing = 7 + m */
2795            } else {
2796               UINT32 ea = GetEA(modrm,0);
2797               address = READ32(ea);
2798               CYCLES(CYCLES_JMP_MEM);        /* TODO: Timing = 10 + m */
2799            }
2800            m_eip = address;
2801            CHANGE_PC(m_eip);
2802         }
2803         break;
2804      case 5:         /* JMP FAR Rm32 */
2805         {
2806            UINT16 selector;
2807            UINT32 address;
2808
2809            if( modrm >= 0xc0 )
2810            {
2811               report_invalid_modrm("groupFF_32", modrm);
2812            }
2813            else
2814            {
2815               UINT32 ea = GetEA(modrm,0);
2816               address = READ32(ea + 0);
2817               selector = READ16(ea + 4);
2818               CYCLES(CYCLES_JMP_MEM_INTERSEG);       /* TODO: Timing = 10 + m */
2819               if(PROTECTED_MODE && !V8086_MODE)
2820               {
2821                  i386_protected_mode_jump(selector,address,1,1);
2822               }
2823               else
2824               {
2825                  m_sreg[CS].selector = selector;
2826                  m_performed_intersegment_jump = 1;
2827                  i386_load_segment_descriptor(CS );
2828                  m_eip = address;
2829                  CHANGE_PC(m_eip);
2830               }
2831            }
2832         }
2833         break;
2834      case 6:         /* PUSH Rm32 */
2835         {
2836            UINT32 value;
2837            if( modrm >= 0xc0 ) {
2838               value = LOAD_RM32(modrm);
2839            } else {
2840               UINT32 ea = GetEA(modrm,0);
2841               value = READ32(ea);
2842            }
2843            PUSH32(value);
2844            CYCLES(CYCLES_PUSH_RM);
2845         }
2846         break;
2847      default:
2848         report_invalid_modrm("groupFF_32", modrm);
2849         break;
2850   }
2851}
2852
2853void i386_device::i386_group0F00_32()          // Opcode 0x0f 00
2854{
2855   UINT32 address, ea;
2856   UINT8 modrm = FETCH();
2857   I386_SREG seg;
2858   UINT8 result;
2859
2860   switch( (modrm >> 3) & 0x7 )
2861   {
2862      case 0:         /* SLDT */
2863         if ( PROTECTED_MODE && !V8086_MODE )
2864         {
2865            if( modrm >= 0xc0 ) {
2866               STORE_RM32(modrm, m_ldtr.segment);
2867               CYCLES(CYCLES_SLDT_REG);
2868            } else {
2869               ea = GetEA(modrm,1);
2870               WRITE16(ea, m_ldtr.segment);
2871               CYCLES(CYCLES_SLDT_MEM);
2872            }
2873         }
2874         else
2875         {
2876            i386_trap(6, 0, 0);
2877         }
2878         break;
2879      case 1:         /* STR */
2880         if ( PROTECTED_MODE && !V8086_MODE )
2881         {
2882            if( modrm >= 0xc0 ) {
2883               STORE_RM32(modrm, m_task.segment);
2884               CYCLES(CYCLES_STR_REG);
2885            } else {
2886               ea = GetEA(modrm,1);
2887               WRITE16(ea, m_task.segment);
2888               CYCLES(CYCLES_STR_MEM);
2889            }
2890         }
2891         else
2892         {
2893            i386_trap(6, 0, 0);
2894         }
2895         break;
2896      case 2:         /* LLDT */
2897         if ( PROTECTED_MODE && !V8086_MODE )
2898         {
2899            if(m_CPL)
2900               FAULT(FAULT_GP,0)
2901            if( modrm >= 0xc0 ) {
2902               address = LOAD_RM32(modrm);
2903               m_ldtr.segment = address;
2904               CYCLES(CYCLES_LLDT_REG);
2905            } else {
2906               ea = GetEA(modrm,0);
2907               m_ldtr.segment = READ32(ea);
2908               CYCLES(CYCLES_LLDT_MEM);
2909            }
2910            memset(&seg, 0, sizeof(seg));
2911            seg.selector = m_ldtr.segment;
2912            i386_load_protected_mode_segment(&seg,NULL);
2913            m_ldtr.limit = seg.limit;
2914            m_ldtr.base = seg.base;
2915            m_ldtr.flags = seg.flags;
2916         }
2917         else
2918         {
2919            i386_trap(6, 0, 0);
2920         }
2921         break;
2922
2923      case 3:         /* LTR */
2924         if ( PROTECTED_MODE && !V8086_MODE )
2925         {
2926            if(m_CPL)
2927               FAULT(FAULT_GP,0)
2928            if( modrm >= 0xc0 ) {
2929               address = LOAD_RM32(modrm);
2930               m_task.segment = address;
2931               CYCLES(CYCLES_LTR_REG);
2932            } else {
2933               ea = GetEA(modrm,0);
2934               m_task.segment = READ32(ea);
2935               CYCLES(CYCLES_LTR_MEM);
2936            }
2937            memset(&seg, 0, sizeof(seg));
2938            seg.selector = m_task.segment;
2939            i386_load_protected_mode_segment(&seg,NULL);
2940            m_task.limit = seg.limit;
2941            m_task.base = seg.base;
2942            m_task.flags = seg.flags;
2943         }
2944         else
2945         {
2946            i386_trap(6, 0, 0);
2947         }
2948         break;
2949
2950      case 4:  /* VERR */
2951         if ( PROTECTED_MODE && !V8086_MODE )
2952         {
2953            if( modrm >= 0xc0 ) {
2954               address = LOAD_RM32(modrm);
2955               CYCLES(CYCLES_VERR_REG);
2956            } else {
2957               ea = GetEA(modrm,0);
2958               address = READ32(ea);
2959               CYCLES(CYCLES_VERR_MEM);
2960            }
2961            memset(&seg, 0, sizeof(seg));
2962            seg.selector = address;
2963            result = i386_load_protected_mode_segment(&seg,NULL);
2964            // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
2965            if(!(seg.flags & 0x10))
2966               result = 0;
2967            // check that the segment is readable
2968            if(seg.flags & 0x10)  // is code or data segment
2969            {
2970               if(seg.flags & 0x08)  // is code segment, so check if it's readable
2971               {
2972                  if(!(seg.flags & 0x02))
2973                  {
2974                     result = 0;
2975                  }
2976                  else
2977                  {  // check if conforming, these are always readable, regardless of privilege
2978                     if(!(seg.flags & 0x04))
2979                     {
2980                        // if not conforming, then we must check privilege levels (TODO: current privilege level check)
2981                        if(((seg.flags >> 5) & 0x03) < (address & 0x03))
2982                           result = 0;
2983                     }
2984                  }
2985               }
2986            }
2987            // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
2988            SetZF(result);
2989         }
2990         else
2991         {
2992            i386_trap(6, 0, 0);
2993            logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n");
2994         }
2995         break;
2996
2997      case 5:  /* VERW */
2998         if ( PROTECTED_MODE && !V8086_MODE )
2999         {
3000            if( modrm >= 0xc0 ) {
3001               address = LOAD_RM16(modrm);
3002               CYCLES(CYCLES_VERW_REG);
3003            } else {
3004               ea = GetEA(modrm,0);
3005               address = READ16(ea);
3006               CYCLES(CYCLES_VERW_MEM);
3007            }
3008            memset(&seg, 0, sizeof(seg));
3009            seg.selector = address;
3010            result = i386_load_protected_mode_segment(&seg,NULL);
3011            // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3012            if(!(seg.flags & 0x10))
3013               result = 0;
3014            // check that the segment is writable
3015            if(seg.flags & 0x10)  // is code or data segment
3016            {
3017               if(seg.flags & 0x08)  // is code segment (and thus, not writable)
3018               {
3019                  result = 0;
3020               }
3021               else
3022               {  // is data segment
3023                  if(!(seg.flags & 0x02))
3024                     result = 0;
3025               }
3026            }
3027            // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3028            if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3029               result = 0;
3030            SetZF(result);
3031         }
3032         else
3033         {
3034            i386_trap(6, 0, 0);
3035            logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n");
3036         }
3037         break;
3038
3039      default:
3040         report_invalid_modrm("group0F00_32", modrm);
3041         break;
3042   }
3043}
3044
3045void i386_device::i386_group0F01_32()      // Opcode 0x0f 01
3046{
3047   UINT8 modrm = FETCH();
3048   UINT32 address, ea;
3049
3050   switch( (modrm >> 3) & 0x7 )
3051   {
3052      case 0:         /* SGDT */
3053         {
3054            if( modrm >= 0xc0 ) {
3055               address = LOAD_RM32(modrm);
3056               ea = i386_translate(CS, address, 1 );
3057            } else {
3058               ea = GetEA(modrm,1);
3059            }
3060            WRITE16(ea, m_gdtr.limit);
3061            WRITE32(ea + 2, m_gdtr.base);
3062            CYCLES(CYCLES_SGDT);
3063            break;
3064         }
3065      case 1:         /* SIDT */
3066         {
3067            if (modrm >= 0xc0)
3068            {
3069               address = LOAD_RM32(modrm);
3070               ea = i386_translate(CS, address, 1 );
3071            }
3072            else
3073            {
3074               ea = GetEA(modrm,1);
3075            }
3076            WRITE16(ea, m_idtr.limit);
3077            WRITE32(ea + 2, m_idtr.base);
3078            CYCLES(CYCLES_SIDT);
3079            break;
3080         }
3081      case 2:         /* LGDT */
3082         {
3083            if(PROTECTED_MODE && m_CPL)
3084               FAULT(FAULT_GP,0)
3085            if( modrm >= 0xc0 ) {
3086               address = LOAD_RM32(modrm);
3087               ea = i386_translate(CS, address, 0 );
3088            } else {
3089               ea = GetEA(modrm,0);
3090            }
3091            m_gdtr.limit = READ16(ea);
3092            m_gdtr.base = READ32(ea + 2);
3093            CYCLES(CYCLES_LGDT);
3094            break;
3095         }
3096      case 3:         /* LIDT */
3097         {
3098            if(PROTECTED_MODE && m_CPL)
3099               FAULT(FAULT_GP,0)
3100            if( modrm >= 0xc0 ) {
3101               address = LOAD_RM32(modrm);
3102               ea = i386_translate(CS, address, 0 );
3103            } else {
3104               ea = GetEA(modrm,0);
3105            }
3106            m_idtr.limit = READ16(ea);
3107            m_idtr.base = READ32(ea + 2);
3108            CYCLES(CYCLES_LIDT);
3109            break;
3110         }
3111      case 4:         /* SMSW */
3112         {
3113            if( modrm >= 0xc0 ) {
3114               // smsw stores all of cr0 into register
3115               STORE_RM32(modrm, m_cr[0]);
3116               CYCLES(CYCLES_SMSW_REG);
3117            } else {
3118               /* always 16-bit memory operand */
3119               ea = GetEA(modrm,1);
3120               WRITE16(ea, m_cr[0]);
3121               CYCLES(CYCLES_SMSW_MEM);
3122            }
3123            break;
3124         }
3125      case 6:         /* LMSW */
3126         {
3127            if(PROTECTED_MODE && m_CPL)
3128               FAULT(FAULT_GP,0)
3129            UINT16 b;
3130            if( modrm >= 0xc0 ) {
3131               b = LOAD_RM16(modrm);
3132               CYCLES(CYCLES_LMSW_REG);
3133            } else {
3134               ea = GetEA(modrm,0);
3135               CYCLES(CYCLES_LMSW_MEM);
3136            b = READ16(ea);
3137            }
3138            if(PROTECTED_MODE)
3139               b |= 0x0001;  // cannot return to real mode using this instruction.
3140            m_cr[0] &= ~0x0000000f;
3141            m_cr[0] |= b & 0x0000000f;
3142            break;
3143         }
3144      default:
3145         report_invalid_modrm("group0F01_32", modrm);
3146         break;
3147   }
3148}
3149
3150void i386_device::i386_group0FBA_32()      // Opcode 0x0f ba
3151{
3152   UINT8 modrm = FETCH();
3153
3154   switch( (modrm >> 3) & 0x7 )
3155   {
3156      case 4:         /* BT Rm32, i8 */
3157         if( modrm >= 0xc0 ) {
3158            UINT32 dst = LOAD_RM32(modrm);
3159            UINT8 bit = FETCH();
3160
3161            if( dst & (1 << bit) )
3162               m_CF = 1;
3163            else
3164               m_CF = 0;
3165
3166            CYCLES(CYCLES_BT_IMM_REG);
3167         } else {
3168            UINT32 ea = GetEA(modrm,0);
3169            UINT32 dst = READ32(ea);
3170            UINT8 bit = FETCH();
3171
3172            if( dst & (1 << bit) )
3173               m_CF = 1;
3174            else
3175               m_CF = 0;
3176
3177            CYCLES(CYCLES_BT_IMM_MEM);
3178         }
3179         break;
3180      case 5:         /* BTS Rm32, i8 */
3181         if( modrm >= 0xc0 ) {
3182            UINT32 dst = LOAD_RM32(modrm);
3183            UINT8 bit = FETCH();
3184
3185            if( dst & (1 << bit) )
3186               m_CF = 1;
3187            else
3188               m_CF = 0;
3189            dst |= (1 << bit);
3190
3191            STORE_RM32(modrm, dst);
3192            CYCLES(CYCLES_BTS_IMM_REG);
3193         } else {
3194            UINT32 ea = GetEA(modrm,1);
3195            UINT32 dst = READ32(ea);
3196            UINT8 bit = FETCH();
3197
3198            if( dst & (1 << bit) )
3199               m_CF = 1;
3200            else
3201               m_CF = 0;
3202            dst |= (1 << bit);
3203
3204            WRITE32(ea, dst);
3205            CYCLES(CYCLES_BTS_IMM_MEM);
3206         }
3207         break;
3208      case 6:         /* BTR Rm32, i8 */
3209         if( modrm >= 0xc0 ) {
3210            UINT32 dst = LOAD_RM32(modrm);
3211            UINT8 bit = FETCH();
3212
3213            if( dst & (1 << bit) )
3214               m_CF = 1;
3215            else
3216               m_CF = 0;
3217            dst &= ~(1 << bit);
3218
3219            STORE_RM32(modrm, dst);
3220            CYCLES(CYCLES_BTR_IMM_REG);
3221         } else {
3222            UINT32 ea = GetEA(modrm,1);
3223            UINT32 dst = READ32(ea);
3224            UINT8 bit = FETCH();
3225
3226            if( dst & (1 << bit) )
3227               m_CF = 1;
3228            else
3229               m_CF = 0;
3230            dst &= ~(1 << bit);
3231
3232            WRITE32(ea, dst);
3233            CYCLES(CYCLES_BTR_IMM_MEM);
3234         }
3235         break;
3236      case 7:         /* BTC Rm32, i8 */
3237         if( modrm >= 0xc0 ) {
3238            UINT32 dst = LOAD_RM32(modrm);
3239            UINT8 bit = FETCH();
3240
3241            if( dst & (1 << bit) )
3242               m_CF = 1;
3243            else
3244               m_CF = 0;
3245            dst ^= (1 << bit);
3246
3247            STORE_RM32(modrm, dst);
3248            CYCLES(CYCLES_BTC_IMM_REG);
3249         } else {
3250            UINT32 ea = GetEA(modrm,1);
3251            UINT32 dst = READ32(ea);
3252            UINT8 bit = FETCH();
3253
3254            if( dst & (1 << bit) )
3255               m_CF = 1;
3256            else
3257               m_CF = 0;
3258            dst ^= (1 << bit);
3259
3260            WRITE32(ea, dst);
3261            CYCLES(CYCLES_BTC_IMM_MEM);
3262         }
3263         break;
3264      default:
3265         report_invalid_modrm("group0FBA_32", modrm);
3266         break;
3267   }
3268}
3269
3270void i386_device::i386_lar_r32_rm32()  // Opcode 0x0f 0x02
3271{
3272   UINT8 modrm = FETCH();
3273   I386_SREG seg;
3274   UINT8 type;
3275
3276   if(PROTECTED_MODE && !V8086_MODE)
3277   {
3278      memset(&seg,0,sizeof(seg));
3279      if(modrm >= 0xc0)
3280      {
3281         seg.selector = LOAD_RM32(modrm);
3282         CYCLES(CYCLES_LAR_REG);
3283      }
3284      else
3285      {
3286         UINT32 ea = GetEA(modrm,0);
3287         seg.selector = READ32(ea);
3288         CYCLES(CYCLES_LAR_MEM);
3289      }
3290      if(seg.selector == 0)
3291      {
3292         SetZF(0);  // not a valid segment
3293      }
3294      else
3295      {
3296         UINT64 desc;
3297         if(!i386_load_protected_mode_segment(&seg,&desc))
3298         {
3299            SetZF(0);
3300            return;
3301         }
3302         UINT8 DPL = (seg.flags >> 5) & 3;
3303         if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3304         {
3305            SetZF(0);
3306            return;
3307         }
3308         if(!(seg.flags & 0x10))  // special segment
3309         {
3310            // check for invalid segment types
3311            type = seg.flags & 0x000f;
3312            if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d)
3313            {
3314               SetZF(0);  // invalid segment type
3315            }
3316            else
3317            {
3318               STORE_REG32(modrm,(desc>>32) & 0x00ffff00);
3319               SetZF(1);
3320            }
3321         }
3322         else
3323         {
3324            STORE_REG32(modrm,(desc>>32) & 0x00ffff00);
3325            SetZF(1);
3326         }
3327      }
3328   }
3329   else
3330   {
3331      // illegal opcode
3332      i386_trap(6,0, 0);
3333      logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n");
3334   }
3335}
3336
3337void i386_device::i386_lsl_r32_rm32()  // Opcode 0x0f 0x03
3338{
3339   UINT8 modrm = FETCH();
3340   UINT32 limit;
3341   I386_SREG seg;
3342
3343   if(PROTECTED_MODE && !V8086_MODE)
3344   {
3345      memset(&seg, 0, sizeof(seg));
3346      if(modrm >= 0xc0)
3347      {
3348         seg.selector = LOAD_RM32(modrm);
3349      }
3350      else
3351      {
3352         UINT32 ea = GetEA(modrm,0);
3353         seg.selector = READ32(ea);
3354      }
3355      if(seg.selector == 0)
3356      {
3357         SetZF(0);  // not a valid segment
3358      }
3359      else
3360      {
3361         UINT8 type;
3362         if(!i386_load_protected_mode_segment(&seg,NULL))
3363         {
3364            SetZF(0);
3365            return;
3366         }
3367         UINT8 DPL = (seg.flags >> 5) & 3;
3368         if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3369         {
3370            SetZF(0);
3371            return;
3372         }
3373         type = seg.flags & 0x1f;
3374         switch(type)
3375         {
3376         case 0:
3377         case 4:
3378         case 5:
3379         case 6:
3380         case 7:
3381         case 8:
3382         case 10:
3383         case 12:
3384         case 13:
3385         case 14:
3386         case 15:
3387            SetZF(0);
3388            return;
3389         default:
3390            limit = seg.limit;
3391            STORE_REG32(modrm,limit);
3392            SetZF(1);
3393         }
3394      }
3395   }
3396   else
3397      i386_trap(6, 0, 0);
3398}
3399
3400void i386_device::i386_bound_r32_m32_m32() // Opcode 0x62
3401{
3402   UINT8 modrm;
3403   INT32 val, low, high;
3404
3405   modrm = FETCH();
3406
3407   if (modrm >= 0xc0)
3408   {
3409      low = high = LOAD_RM32(modrm);
3410   }
3411   else
3412   {
3413      UINT32 ea = GetEA(modrm,0);
3414      low = READ32(ea + 0);
3415      high = READ32(ea + 4);
3416   }
3417   val = LOAD_REG32(modrm);
3418
3419   if ((val < low) || (val > high))
3420   {
3421      CYCLES(CYCLES_BOUND_OUT_RANGE);
3422      i386_trap(5, 0, 0);
3423   }
3424   else
3425   {
3426      CYCLES(CYCLES_BOUND_IN_RANGE);
3427   }
3428}
3429
3430void i386_device::i386_retf32()            // Opcode 0xcb
3431{
3432   if(PROTECTED_MODE && !V8086_MODE)
3433   {
3434      i386_protected_mode_retf(0,1);
3435   }
3436   else
3437   {
3438      m_eip = POP32();
3439      m_sreg[CS].selector = POP32();
3440      i386_load_segment_descriptor(CS );
3441      CHANGE_PC(m_eip);
3442   }
3443
3444   CYCLES(CYCLES_RET_INTERSEG);
3445}
3446
3447void i386_device::i386_retf_i32()          // Opcode 0xca
3448{
3449   UINT16 count = FETCH16();
3450
3451   if(PROTECTED_MODE && !V8086_MODE)
3452   {
3453      i386_protected_mode_retf(count,1);
3454   }
3455   else
3456   {
3457      m_eip = POP32();
3458      m_sreg[CS].selector = POP32();
3459      i386_load_segment_descriptor(CS );
3460      CHANGE_PC(m_eip);
3461      REG32(ESP) += count;
3462   }
3463
3464   CYCLES(CYCLES_RET_IMM_INTERSEG);
3465}
3466
3467void i386_device::i386_load_far_pointer32(int s)
3468{
3469   UINT8 modrm = FETCH();
3470   UINT16 selector;
3471
3472   if( modrm >= 0xc0 ) {
3473      report_invalid_modrm("load_far_pointer32", modrm);
3474   } else {
3475      UINT32 ea = GetEA(modrm,0);
3476      STORE_REG32(modrm, READ32(ea + 0));
3477      selector = READ16(ea + 4);
3478      i386_sreg_load(selector,s,NULL);
3479   }
3480}
3481
3482void i386_device::i386_lds32()             // Opcode 0xc5
3483{
3484   i386_load_far_pointer32(DS);
3485   CYCLES(CYCLES_LDS);
3486}
3487
3488void i386_device::i386_lss32()             // Opcode 0x0f 0xb2
3489{
3490   i386_load_far_pointer32(SS);
3491   CYCLES(CYCLES_LSS);
3492}
3493
3494void i386_device::i386_les32()             // Opcode 0xc4
3495{
3496   i386_load_far_pointer32(ES);
3497   CYCLES(CYCLES_LES);
3498}
3499
3500void i386_device::i386_lfs32()             // Opcode 0x0f 0xb4
3501{
3502   i386_load_far_pointer32(FS);
3503   CYCLES(CYCLES_LFS);
3504}
3505
3506void i386_device::i386_lgs32()             // Opcode 0x0f 0xb5
3507{
3508   i386_load_far_pointer32(GS);
3509   CYCLES(CYCLES_LGS);
3510}
trunk/src/emu/cpu/i386/i386op16.c
r28738r28739
1UINT16 i386_device::i386_shift_rotate16(UINT8 modrm, UINT32 value, UINT8 shift)
2{
3   UINT32 src = value & 0xffff;
4   UINT16 dst = value;
5
6   if( shift == 0 ) {
7      CYCLES_RM(modrm, 3, 7);
8   } else if( shift == 1 ) {
9      switch( (modrm >> 3) & 0x7 )
10      {
11         case 0:         /* ROL rm16, 1 */
12            m_CF = (src & 0x8000) ? 1 : 0;
13            dst = (src << 1) + m_CF;
14            m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
15            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
16            break;
17         case 1:         /* ROR rm16, 1 */
18            m_CF = (src & 0x1) ? 1 : 0;
19            dst = (m_CF << 15) | (src >> 1);
20            m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
21            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
22            break;
23         case 2:         /* RCL rm16, 1 */
24            dst = (src << 1) + m_CF;
25            m_CF = (src & 0x8000) ? 1 : 0;
26            m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
27            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
28            break;
29         case 3:         /* RCR rm16, 1 */
30            dst = (m_CF << 15) | (src >> 1);
31            m_CF = src & 0x1;
32            m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
33            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
34            break;
35         case 4:         /* SHL/SAL rm16, 1 */
36         case 6:
37            dst = src << 1;
38            m_CF = (src & 0x8000) ? 1 : 0;
39            m_OF = (((m_CF << 15) ^ dst) & 0x8000) ? 1 : 0;
40            SetSZPF16(dst);
41            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
42            break;
43         case 5:         /* SHR rm16, 1 */
44            dst = src >> 1;
45            m_CF = src & 0x1;
46            m_OF = (dst & 0x8000) ? 1 : 0;
47            SetSZPF16(dst);
48            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
49            break;
50         case 7:         /* SAR rm16, 1 */
51            dst = (INT16)(src) >> 1;
52            m_CF = src & 0x1;
53            m_OF = 0;
54            SetSZPF16(dst);
55            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
56            break;
57      }
58   } else {
59      switch( (modrm >> 3) & 0x7 )
60      {
61         case 0:         /* ROL rm16, i8 */
62            if(!(shift & 15))
63            {
64               if(shift & 16)
65               {
66                  m_CF = src & 1;
67                  m_OF = (src & 1) ^ ((src >> 15) & 1);
68               }
69               break;
70            }
71            shift &= 15;
72            dst = ((src & ((UINT16)0xffff >> shift)) << shift) |
73                  ((src & ((UINT16)0xffff << (16-shift))) >> (16-shift));
74            m_CF = dst & 0x1;
75            m_OF = (dst & 1) ^ (dst >> 15);
76            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
77            break;
78         case 1:         /* ROR rm16, i8 */
79            if(!(shift & 15))
80            {
81               if(shift & 16)
82               {
83                  m_CF = (src >> 15) & 1;
84                  m_OF = ((src >> 15) & 1) ^ ((src >> 14) & 1);
85               }
86               break;
87            }
88            shift &= 15;
89            dst = ((src & ((UINT16)0xffff << shift)) >> shift) |
90                  ((src & ((UINT16)0xffff >> (16-shift))) << (16-shift));
91            m_CF = (dst >> 15) & 1;
92            m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
93            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
94            break;
95         case 2:         /* RCL rm16, i8 */
96            shift %= 17;
97            dst = ((src & ((UINT16)0xffff >> shift)) << shift) |
98                  ((src & ((UINT16)0xffff << (17-shift))) >> (17-shift)) |
99                  (m_CF << (shift-1));
100            if(shift) m_CF = (src >> (16-shift)) & 0x1;
101            m_OF = m_CF ^ ((dst >> 15) & 1);
102            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
103            break;
104         case 3:         /* RCR rm16, i8 */
105            shift %= 17;
106            dst = ((src & ((UINT16)0xffff << shift)) >> shift) |
107                  ((src & ((UINT16)0xffff >> (16-shift))) << (17-shift)) |
108                  (m_CF << (16-shift));
109            if(shift) m_CF = (src >> (shift-1)) & 0x1;
110            m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
111            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
112            break;
113         case 4:         /* SHL/SAL rm16, i8 */
114         case 6:
115            shift &= 31;
116            dst = src << shift;
117            m_CF = (shift <= 16) && (src & (1 << (16-shift)));
118            SetSZPF16(dst);
119            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
120            break;
121         case 5:         /* SHR rm16, i8 */
122            shift &= 31;
123            dst = src >> shift;
124            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
125            SetSZPF16(dst);
126            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
127            break;
128         case 7:         /* SAR rm16, i8 */
129            shift &= 31;
130            dst = (INT16)src >> shift;
131            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
132            SetSZPF16(dst);
133            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
134            break;
135      }
136
137   }
138   return dst;
139}
140
141
142
143void i386_device::i386_adc_rm16_r16()      // Opcode 0x11
144{
145   UINT16 src, dst;
146   UINT8 modrm = FETCH();
147   if( modrm >= 0xc0 ) {
148      src = LOAD_REG16(modrm);
149      dst = LOAD_RM16(modrm);
150      dst = ADC16(dst, src, m_CF);
151      STORE_RM16(modrm, dst);
152      CYCLES(CYCLES_ALU_REG_REG);
153   } else {
154      UINT32 ea = GetEA(modrm,1);
155      src = LOAD_REG16(modrm);
156      dst = READ16(ea);
157      dst = ADC16(dst, src, m_CF);
158      WRITE16(ea, dst);
159      CYCLES(CYCLES_ALU_REG_MEM);
160   }
161}
162
163void i386_device::i386_adc_r16_rm16()      // Opcode 0x13
164{
165   UINT16 src, dst;
166   UINT8 modrm = FETCH();
167   if( modrm >= 0xc0 ) {
168      src = LOAD_RM16(modrm);
169      dst = LOAD_REG16(modrm);
170      dst = ADC16(dst, src, m_CF);
171      STORE_REG16(modrm, dst);
172      CYCLES(CYCLES_ALU_REG_REG);
173   } else {
174      UINT32 ea = GetEA(modrm,0);
175      src = READ16(ea);
176      dst = LOAD_REG16(modrm);
177      dst = ADC16(dst, src, m_CF);
178      STORE_REG16(modrm, dst);
179      CYCLES(CYCLES_ALU_MEM_REG);
180   }
181}
182
183void i386_device::i386_adc_ax_i16()        // Opcode 0x15
184{
185   UINT16 src, dst;
186   src = FETCH16();
187   dst = REG16(AX);
188   dst = ADC16(dst, src, m_CF);
189   REG16(AX) = dst;
190   CYCLES(CYCLES_ALU_IMM_ACC);
191}
192
193void i386_device::i386_add_rm16_r16()      // Opcode 0x01
194{
195   UINT16 src, dst;
196   UINT8 modrm = FETCH();
197   if( modrm >= 0xc0 ) {
198      src = LOAD_REG16(modrm);
199      dst = LOAD_RM16(modrm);
200      dst = ADD16(dst, src);
201      STORE_RM16(modrm, dst);
202      CYCLES(CYCLES_ALU_REG_REG);
203   } else {
204      UINT32 ea = GetEA(modrm,1);
205      src = LOAD_REG16(modrm);
206      dst = READ16(ea);
207      dst = ADD16(dst, src);
208      WRITE16(ea, dst);
209      CYCLES(CYCLES_ALU_REG_MEM);
210   }
211}
212
213void i386_device::i386_add_r16_rm16()      // Opcode 0x03
214{
215   UINT16 src, dst;
216   UINT8 modrm = FETCH();
217   if( modrm >= 0xc0 ) {
218      src = LOAD_RM16(modrm);
219      dst = LOAD_REG16(modrm);
220      dst = ADD16(dst, src);
221      STORE_REG16(modrm, dst);
222      CYCLES(CYCLES_ALU_REG_REG);
223   } else {
224      UINT32 ea = GetEA(modrm,0);
225      src = READ16(ea);
226      dst = LOAD_REG16(modrm);
227      dst = ADD16(dst, src);
228      STORE_REG16(modrm, dst);
229      CYCLES(CYCLES_ALU_MEM_REG);
230   }
231}
232
233void i386_device::i386_add_ax_i16()        // Opcode 0x05
234{
235   UINT16 src, dst;
236   src = FETCH16();
237   dst = REG16(AX);
238   dst = ADD16(dst, src);
239   REG16(AX) = dst;
240   CYCLES(CYCLES_ALU_IMM_ACC);
241}
242
243void i386_device::i386_and_rm16_r16()      // Opcode 0x21
244{
245   UINT16 src, dst;
246   UINT8 modrm = FETCH();
247   if( modrm >= 0xc0 ) {
248      src = LOAD_REG16(modrm);
249      dst = LOAD_RM16(modrm);
250      dst = AND16(dst, src);
251      STORE_RM16(modrm, dst);
252      CYCLES(CYCLES_ALU_REG_REG);
253   } else {
254      UINT32 ea = GetEA(modrm,1);
255      src = LOAD_REG16(modrm);
256      dst = READ16(ea);
257      dst = AND16(dst, src);
258      WRITE16(ea, dst);
259      CYCLES(CYCLES_ALU_REG_MEM);
260   }
261}
262
263void i386_device::i386_and_r16_rm16()      // Opcode 0x23
264{
265   UINT16 src, dst;
266   UINT8 modrm = FETCH();
267   if( modrm >= 0xc0 ) {
268      src = LOAD_RM16(modrm);
269      dst = LOAD_REG16(modrm);
270      dst = AND16(dst, src);
271      STORE_REG16(modrm, dst);
272      CYCLES(CYCLES_ALU_REG_REG);
273   } else {
274      UINT32 ea = GetEA(modrm,0);
275      src = READ16(ea);
276      dst = LOAD_REG16(modrm);
277      dst = AND16(dst, src);
278      STORE_REG16(modrm, dst);
279      CYCLES(CYCLES_ALU_MEM_REG);
280   }
281}
282
283void i386_device::i386_and_ax_i16()        // Opcode 0x25
284{
285   UINT16 src, dst;
286   src = FETCH16();
287   dst = REG16(AX);
288   dst = AND16(dst, src);
289   REG16(AX) = dst;
290   CYCLES(CYCLES_ALU_IMM_ACC);
291}
292
293void i386_device::i386_bsf_r16_rm16()      // Opcode 0x0f bc
294{
295   UINT16 src, dst, temp;
296   UINT8 modrm = FETCH();
297
298   if( modrm >= 0xc0 ) {
299      src = LOAD_RM16(modrm);
300   } else {
301      UINT32 ea = GetEA(modrm,0);
302      src = READ16(ea);
303   }
304
305   dst = 0;
306
307   if( src == 0 ) {
308      m_ZF = 1;
309   } else {
310      m_ZF = 0;
311      temp = 0;
312      while( (src & (1 << temp)) == 0 ) {
313         temp++;
314         dst = temp;
315         CYCLES(CYCLES_BSF);
316      }
317      STORE_REG16(modrm, dst);
318   }
319   CYCLES(CYCLES_BSF_BASE);
320}
321
322void i386_device::i386_bsr_r16_rm16()      // Opcode 0x0f bd
323{
324   UINT16 src, dst, temp;
325   UINT8 modrm = FETCH();
326
327   if( modrm >= 0xc0 ) {
328      src = LOAD_RM16(modrm);
329   } else {
330      UINT32 ea = GetEA(modrm,0);
331      src = READ16(ea);
332   }
333
334   dst = 0;
335
336   if( src == 0 ) {
337      m_ZF = 1;
338   } else {
339      m_ZF = 0;
340      dst = temp = 15;
341      while( (src & (1 << temp)) == 0 ) {
342         temp--;
343         dst = temp;
344         CYCLES(CYCLES_BSR);
345      }
346      STORE_REG16(modrm, dst);
347   }
348   CYCLES(CYCLES_BSR_BASE);
349}
350
351
352void i386_device::i386_bt_rm16_r16()       // Opcode 0x0f a3
353{
354   UINT8 modrm = FETCH();
355   if( modrm >= 0xc0 ) {
356      UINT16 dst = LOAD_RM16(modrm);
357      UINT16 bit = LOAD_REG16(modrm);
358
359      if( dst & (1 << (bit & 0xf)) )
360         m_CF = 1;
361      else
362         m_CF = 0;
363
364      CYCLES(CYCLES_BT_REG_REG);
365   } else {
366      UINT8 segment;
367      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
368      UINT16 bit = LOAD_REG16(modrm);
369      ea += 2*(bit/16);
370      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),0);
371      bit %= 16;
372      UINT16 dst = READ16(ea);
373
374      if( dst & (1 << bit) )
375         m_CF = 1;
376      else
377         m_CF = 0;
378
379      CYCLES(CYCLES_BT_REG_MEM);
380   }
381}
382
383void i386_device::i386_btc_rm16_r16()      // Opcode 0x0f bb
384{
385   UINT8 modrm = FETCH();
386   if( modrm >= 0xc0 ) {
387      UINT16 dst = LOAD_RM16(modrm);
388      UINT16 bit = LOAD_REG16(modrm);
389
390      if( dst & (1 << (bit & 0xf)) )
391         m_CF = 1;
392      else
393         m_CF = 0;
394      dst ^= (1 << (bit & 0xf));
395
396      STORE_RM16(modrm, dst);
397      CYCLES(CYCLES_BTC_REG_REG);
398   } else {
399      UINT8 segment;
400      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
401      UINT16 bit = LOAD_REG16(modrm);
402      ea += 2*(bit/16);
403      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
404      bit %= 16;
405      UINT16 dst = READ16(ea);
406
407      if( dst & (1 << bit) )
408         m_CF = 1;
409      else
410         m_CF = 0;
411      dst ^= (1 << bit);
412
413      WRITE16(ea, dst);
414      CYCLES(CYCLES_BTC_REG_MEM);
415   }
416}
417
418void i386_device::i386_btr_rm16_r16()      // Opcode 0x0f b3
419{
420   UINT8 modrm = FETCH();
421   if( modrm >= 0xc0 ) {
422      UINT16 dst = LOAD_RM16(modrm);
423      UINT16 bit = LOAD_REG16(modrm);
424
425      if( dst & (1 << (bit & 0xf)) )
426         m_CF = 1;
427      else
428         m_CF = 0;
429      dst &= ~(1 << (bit & 0xf));
430
431      STORE_RM16(modrm, dst);
432      CYCLES(CYCLES_BTR_REG_REG);
433   } else {
434      UINT8 segment;
435      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
436      UINT16 bit = LOAD_REG16(modrm);
437      ea += 2*(bit/16);
438      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
439      bit %= 16;
440      UINT16 dst = READ16(ea);
441
442      if( dst & (1 << bit) )
443         m_CF = 1;
444      else
445         m_CF = 0;
446      dst &= ~(1 << bit);
447
448      WRITE16(ea, dst);
449      CYCLES(CYCLES_BTR_REG_MEM);
450   }
451}
452
453void i386_device::i386_bts_rm16_r16()      // Opcode 0x0f ab
454{
455   UINT8 modrm = FETCH();
456   if( modrm >= 0xc0 ) {
457      UINT16 dst = LOAD_RM16(modrm);
458      UINT16 bit = LOAD_REG16(modrm);
459
460      if( dst & (1 << (bit & 0xf)) )
461         m_CF = 1;
462      else
463         m_CF = 0;
464      dst |= (1 << (bit & 0xf));
465
466      STORE_RM16(modrm, dst);
467      CYCLES(CYCLES_BTS_REG_REG);
468   } else {
469      UINT8 segment;
470      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
471      UINT16 bit = LOAD_REG16(modrm);
472      ea += 2*(bit/16);
473      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
474      bit %= 16;
475      UINT16 dst = READ16(ea);
476
477      if( dst & (1 << bit) )
478         m_CF = 1;
479      else
480         m_CF = 0;
481      dst |= (1 << bit);
482
483      WRITE16(ea, dst);
484      CYCLES(CYCLES_BTS_REG_MEM);
485   }
486}
487
488void i386_device::i386_call_abs16()        // Opcode 0x9a
489{
490   UINT16 offset = FETCH16();
491   UINT16 ptr = FETCH16();
492
493   if( PROTECTED_MODE && !V8086_MODE)
494   {
495      i386_protected_mode_call(ptr,offset,0,0);
496   }
497   else
498   {
499      PUSH16(m_sreg[CS].selector );
500      PUSH16(m_eip );
501      m_sreg[CS].selector = ptr;
502      m_performed_intersegment_jump = 1;
503      m_eip = offset;
504      i386_load_segment_descriptor(CS);
505   }
506   CYCLES(CYCLES_CALL_INTERSEG);      /* TODO: Timing = 17 + m */
507   CHANGE_PC(m_eip);
508}
509
510void i386_device::i386_call_rel16()        // Opcode 0xe8
511{
512   INT16 disp = FETCH16();
513
514   PUSH16(m_eip );
515   if (m_sreg[CS].d)
516   {
517      m_eip += disp;
518   }
519   else
520   {
521      m_eip = (m_eip + disp) & 0xffff;
522   }
523   CHANGE_PC(m_eip);
524   CYCLES(CYCLES_CALL);       /* TODO: Timing = 7 + m */
525}
526
527void i386_device::i386_cbw()               // Opcode 0x98
528{
529   REG16(AX) = (INT16)((INT8)REG8(AL));
530   CYCLES(CYCLES_CBW);
531}
532
533void i386_device::i386_cmp_rm16_r16()      // Opcode 0x39
534{
535   UINT16 src, dst;
536   UINT8 modrm = FETCH();
537   if( modrm >= 0xc0 ) {
538      src = LOAD_REG16(modrm);
539      dst = LOAD_RM16(modrm);
540      SUB16(dst, src);
541      CYCLES(CYCLES_CMP_REG_REG);
542   } else {
543      UINT32 ea = GetEA(modrm,0);
544      src = LOAD_REG16(modrm);
545      dst = READ16(ea);
546      SUB16(dst, src);
547      CYCLES(CYCLES_CMP_REG_MEM);
548   }
549}
550
551void i386_device::i386_cmp_r16_rm16()      // Opcode 0x3b
552{
553   UINT16 src, dst;
554   UINT8 modrm = FETCH();
555   if( modrm >= 0xc0 ) {
556      src = LOAD_RM16(modrm);
557      dst = LOAD_REG16(modrm);
558      SUB16(dst, src);
559      CYCLES(CYCLES_CMP_REG_REG);
560   } else {
561      UINT32 ea = GetEA(modrm,0);
562      src = READ16(ea);
563      dst = LOAD_REG16(modrm);
564      SUB16(dst, src);
565      CYCLES(CYCLES_CMP_MEM_REG);
566   }
567}
568
569void i386_device::i386_cmp_ax_i16()        // Opcode 0x3d
570{
571   UINT16 src, dst;
572   src = FETCH16();
573   dst = REG16(AX);
574   SUB16(dst, src);
575   CYCLES(CYCLES_CMP_IMM_ACC);
576}
577
578void i386_device::i386_cmpsw()             // Opcode 0xa7
579{
580   UINT32 eas, ead;
581   UINT16 src, dst;
582   if( m_segment_prefix ) {
583      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
584   } else {
585      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
586   }
587   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
588   src = READ16(eas);
589   dst = READ16(ead);
590   SUB16(src,dst);
591   BUMP_SI(2);
592   BUMP_DI(2);
593   CYCLES(CYCLES_CMPS);
594}
595
596void i386_device::i386_cwd()               // Opcode 0x99
597{
598   if( REG16(AX) & 0x8000 ) {
599      REG16(DX) = 0xffff;
600   } else {
601      REG16(DX) = 0x0000;
602   }
603   CYCLES(CYCLES_CWD);
604}
605
606void i386_device::i386_dec_ax()            // Opcode 0x48
607{
608   REG16(AX) = DEC16(REG16(AX) );
609   CYCLES(CYCLES_DEC_REG);
610}
611
612void i386_device::i386_dec_cx()            // Opcode 0x49
613{
614   REG16(CX) = DEC16(REG16(CX) );
615   CYCLES(CYCLES_DEC_REG);
616}
617
618void i386_device::i386_dec_dx()            // Opcode 0x4a
619{
620   REG16(DX) = DEC16(REG16(DX) );
621   CYCLES(CYCLES_DEC_REG);
622}
623
624void i386_device::i386_dec_bx()            // Opcode 0x4b
625{
626   REG16(BX) = DEC16(REG16(BX) );
627   CYCLES(CYCLES_DEC_REG);
628}
629
630void i386_device::i386_dec_sp()            // Opcode 0x4c
631{
632   REG16(SP) = DEC16(REG16(SP) );
633   CYCLES(CYCLES_DEC_REG);
634}
635
636void i386_device::i386_dec_bp()            // Opcode 0x4d
637{
638   REG16(BP) = DEC16(REG16(BP) );
639   CYCLES(CYCLES_DEC_REG);
640}
641
642void i386_device::i386_dec_si()            // Opcode 0x4e
643{
644   REG16(SI) = DEC16(REG16(SI) );
645   CYCLES(CYCLES_DEC_REG);
646}
647
648void i386_device::i386_dec_di()            // Opcode 0x4f
649{
650   REG16(DI) = DEC16(REG16(DI) );
651   CYCLES(CYCLES_DEC_REG);
652}
653
654void i386_device::i386_imul_r16_rm16()     // Opcode 0x0f af
655{
656   UINT8 modrm = FETCH();
657   INT32 result;
658   INT32 src, dst;
659   if( modrm >= 0xc0 ) {
660      src = (INT32)(INT16)LOAD_RM16(modrm);
661      CYCLES(CYCLES_IMUL16_REG_REG);     /* TODO: Correct multiply timing */
662   } else {
663      UINT32 ea = GetEA(modrm,0);
664      src = (INT32)(INT16)READ16(ea);
665      CYCLES(CYCLES_IMUL16_REG_MEM);     /* TODO: Correct multiply timing */
666   }
667
668   dst = (INT32)(INT16)LOAD_REG16(modrm);
669   result = src * dst;
670
671   STORE_REG16(modrm, (UINT16)result);
672
673   m_CF = m_OF = !(result == (INT32)(INT16)result);
674}
675
676void i386_device::i386_imul_r16_rm16_i16() // Opcode 0x69
677{
678   UINT8 modrm = FETCH();
679   INT32 result;
680   INT32 src, dst;
681   if( modrm >= 0xc0 ) {
682      dst = (INT32)(INT16)LOAD_RM16(modrm);
683      CYCLES(CYCLES_IMUL16_REG_IMM_REG);     /* TODO: Correct multiply timing */
684   } else {
685      UINT32 ea = GetEA(modrm,0);
686      dst = (INT32)(INT16)READ16(ea);
687      CYCLES(CYCLES_IMUL16_MEM_IMM_REG);     /* TODO: Correct multiply timing */
688   }
689
690   src = (INT32)(INT16)FETCH16();
691   result = src * dst;
692
693   STORE_REG16(modrm, (UINT16)result);
694
695   m_CF = m_OF = !(result == (INT32)(INT16)result);
696}
697
698void i386_device::i386_imul_r16_rm16_i8()  // Opcode 0x6b
699{
700   UINT8 modrm = FETCH();
701   INT32 result;
702   INT32 src, dst;
703   if( modrm >= 0xc0 ) {
704      dst = (INT32)(INT16)LOAD_RM16(modrm);
705      CYCLES(CYCLES_IMUL16_REG_IMM_REG);     /* TODO: Correct multiply timing */
706   } else {
707      UINT32 ea = GetEA(modrm,0);
708      dst = (INT32)(INT16)READ16(ea);
709      CYCLES(CYCLES_IMUL16_MEM_IMM_REG);     /* TODO: Correct multiply timing */
710   }
711
712   src = (INT32)(INT8)FETCH();
713   result = src * dst;
714
715   STORE_REG16(modrm, (UINT16)result);
716
717   m_CF = m_OF = !(result == (INT32)(INT16)result);
718}
719
720void i386_device::i386_in_ax_i8()          // Opcode 0xe5
721{
722   UINT16 port = FETCH();
723   UINT16 data = READPORT16(port);
724   REG16(AX) = data;
725   CYCLES(CYCLES_IN_VAR);
726}
727
728void i386_device::i386_in_ax_dx()          // Opcode 0xed
729{
730   UINT16 port = REG16(DX);
731   UINT16 data = READPORT16(port);
732   REG16(AX) = data;
733   CYCLES(CYCLES_IN);
734}
735
736void i386_device::i386_inc_ax()            // Opcode 0x40
737{
738   REG16(AX) = INC16(REG16(AX) );
739   CYCLES(CYCLES_INC_REG);
740}
741
742void i386_device::i386_inc_cx()            // Opcode 0x41
743{
744   REG16(CX) = INC16(REG16(CX) );
745   CYCLES(CYCLES_INC_REG);
746}
747
748void i386_device::i386_inc_dx()            // Opcode 0x42
749{
750   REG16(DX) = INC16(REG16(DX) );
751   CYCLES(CYCLES_INC_REG);
752}
753
754void i386_device::i386_inc_bx()            // Opcode 0x43
755{
756   REG16(BX) = INC16(REG16(BX) );
757   CYCLES(CYCLES_INC_REG);
758}
759
760void i386_device::i386_inc_sp()            // Opcode 0x44
761{
762   REG16(SP) = INC16(REG16(SP) );
763   CYCLES(CYCLES_INC_REG);
764}
765
766void i386_device::i386_inc_bp()            // Opcode 0x45
767{
768   REG16(BP) = INC16(REG16(BP) );
769   CYCLES(CYCLES_INC_REG);
770}
771
772void i386_device::i386_inc_si()            // Opcode 0x46
773{
774   REG16(SI) = INC16(REG16(SI) );
775   CYCLES(CYCLES_INC_REG);
776}
777
778void i386_device::i386_inc_di()            // Opcode 0x47
779{
780   REG16(DI) = INC16(REG16(DI) );
781   CYCLES(CYCLES_INC_REG);
782}
783
784void i386_device::i386_iret16()            // Opcode 0xcf
785{
786   if( PROTECTED_MODE )
787   {
788      i386_protected_mode_iret(0);
789   }
790   else
791   {
792      /* TODO: #SS(0) exception */
793      /* TODO: #GP(0) exception */
794      m_eip = POP16();
795      m_sreg[CS].selector = POP16();
796      set_flags(POP16() );
797      i386_load_segment_descriptor(CS);
798      CHANGE_PC(m_eip);
799   }
800   CYCLES(CYCLES_IRET);
801}
802
803void i386_device::i386_ja_rel16()          // Opcode 0x0f 87
804{
805   INT16 disp = FETCH16();
806   if( m_CF == 0 && m_ZF == 0 ) {
807      if (m_sreg[CS].d)
808      {
809         m_eip += disp;
810      }
811      else
812      {
813         m_eip = (m_eip + disp) & 0xffff;
814      }
815      CHANGE_PC(m_eip);
816      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
817   } else {
818      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
819   }
820}
821
822void i386_device::i386_jbe_rel16()         // Opcode 0x0f 86
823{
824   INT16 disp = FETCH16();
825   if( m_CF != 0 || m_ZF != 0 ) {
826      if (m_sreg[CS].d)
827      {
828         m_eip += disp;
829      }
830      else
831      {
832         m_eip = (m_eip + disp) & 0xffff;
833      }
834      CHANGE_PC(m_eip);
835      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
836   } else {
837      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
838   }
839}
840
841void i386_device::i386_jc_rel16()          // Opcode 0x0f 82
842{
843   INT16 disp = FETCH16();
844   if( m_CF != 0 ) {
845      if (m_sreg[CS].d)
846      {
847         m_eip += disp;
848      }
849      else
850      {
851         m_eip = (m_eip + disp) & 0xffff;
852      }
853      CHANGE_PC(m_eip);
854      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
855   } else {
856      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
857   }
858}
859
860void i386_device::i386_jg_rel16()          // Opcode 0x0f 8f
861{
862   INT16 disp = FETCH16();
863   if( m_ZF == 0 && (m_SF == m_OF) ) {
864      if (m_sreg[CS].d)
865      {
866         m_eip += disp;
867      }
868      else
869      {
870         m_eip = (m_eip + disp) & 0xffff;
871      }
872      CHANGE_PC(m_eip);
873      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
874   } else {
875      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
876   }
877}
878
879void i386_device::i386_jge_rel16()         // Opcode 0x0f 8d
880{
881   INT16 disp = FETCH16();
882   if(m_SF == m_OF) {
883      if (m_sreg[CS].d)
884      {
885         m_eip += disp;
886      }
887      else
888      {
889         m_eip = (m_eip + disp) & 0xffff;
890      }
891      CHANGE_PC(m_eip);
892      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
893   } else {
894      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
895   }
896}
897
898void i386_device::i386_jl_rel16()          // Opcode 0x0f 8c
899{
900   INT16 disp = FETCH16();
901   if( (m_SF != m_OF) ) {
902      if (m_sreg[CS].d)
903      {
904         m_eip += disp;
905      }
906      else
907      {
908         m_eip = (m_eip + disp) & 0xffff;
909      }
910      CHANGE_PC(m_eip);
911      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
912   } else {
913      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
914   }
915}
916
917void i386_device::i386_jle_rel16()         // Opcode 0x0f 8e
918{
919   INT16 disp = FETCH16();
920   if( m_ZF != 0 || (m_SF != m_OF) ) {
921      if (m_sreg[CS].d)
922      {
923         m_eip += disp;
924      }
925      else
926      {
927         m_eip = (m_eip + disp) & 0xffff;
928      }
929      CHANGE_PC(m_eip);
930      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
931   } else {
932      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
933   }
934}
935
936void i386_device::i386_jnc_rel16()         // Opcode 0x0f 83
937{
938   INT16 disp = FETCH16();
939   if( m_CF == 0 ) {
940      if (m_sreg[CS].d)
941      {
942         m_eip += disp;
943      }
944      else
945      {
946         m_eip = (m_eip + disp) & 0xffff;
947      }
948      CHANGE_PC(m_eip);
949      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
950   } else {
951      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
952   }
953}
954
955void i386_device::i386_jno_rel16()         // Opcode 0x0f 81
956{
957   INT16 disp = FETCH16();
958   if( m_OF == 0 ) {
959      if (m_sreg[CS].d)
960      {
961         m_eip += disp;
962      }
963      else
964      {
965         m_eip = (m_eip + disp) & 0xffff;
966      }
967      CHANGE_PC(m_eip);
968      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
969   } else {
970      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
971   }
972}
973
974void i386_device::i386_jnp_rel16()         // Opcode 0x0f 8b
975{
976   INT16 disp = FETCH16();
977   if( m_PF == 0 ) {
978      if (m_sreg[CS].d)
979      {
980         m_eip += disp;
981      }
982      else
983      {
984         m_eip = (m_eip + disp) & 0xffff;
985      }
986      CHANGE_PC(m_eip);
987      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
988   } else {
989      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
990   }
991}
992
993void i386_device::i386_jns_rel16()         // Opcode 0x0f 89
994{
995   INT16 disp = FETCH16();
996   if( m_SF == 0 ) {
997      if (m_sreg[CS].d)
998      {
999         m_eip += disp;
1000      }
1001      else
1002      {
1003         m_eip = (m_eip + disp) & 0xffff;
1004      }
1005      CHANGE_PC(m_eip);
1006      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1007   } else {
1008      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1009   }
1010}
1011
1012void i386_device::i386_jnz_rel16()         // Opcode 0x0f 85
1013{
1014   INT16 disp = FETCH16();
1015   if( m_ZF == 0 ) {
1016      if (m_sreg[CS].d)
1017      {
1018         m_eip += disp;
1019      }
1020      else
1021      {
1022         m_eip = (m_eip + disp) & 0xffff;
1023      }
1024      CHANGE_PC(m_eip);
1025      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1026   } else {
1027      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1028   }
1029}
1030
1031void i386_device::i386_jo_rel16()          // Opcode 0x0f 80
1032{
1033   INT16 disp = FETCH16();
1034   if( m_OF != 0 ) {
1035      if (m_sreg[CS].d)
1036      {
1037         m_eip += disp;
1038      }
1039      else
1040      {
1041         m_eip = (m_eip + disp) & 0xffff;
1042      }
1043      CHANGE_PC(m_eip);
1044      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1045   } else {
1046      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1047   }
1048}
1049
1050void i386_device::i386_jp_rel16()          // Opcode 0x0f 8a
1051{
1052   INT16 disp = FETCH16();
1053   if( m_PF != 0 ) {
1054      if (m_sreg[CS].d)
1055      {
1056         m_eip += disp;
1057      }
1058      else
1059      {
1060         m_eip = (m_eip + disp) & 0xffff;
1061      }
1062      CHANGE_PC(m_eip);
1063      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1064   } else {
1065      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1066   }
1067}
1068
1069void i386_device::i386_js_rel16()          // Opcode 0x0f 88
1070{
1071   INT16 disp = FETCH16();
1072   if( m_SF != 0 ) {
1073      if (m_sreg[CS].d)
1074      {
1075         m_eip += disp;
1076      }
1077      else
1078      {
1079         m_eip = (m_eip + disp) & 0xffff;
1080      }
1081      CHANGE_PC(m_eip);
1082      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1083   } else {
1084      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1085   }
1086}
1087
1088void i386_device::i386_jz_rel16()          // Opcode 0x0f 84
1089{
1090   INT16 disp = FETCH16();
1091   if( m_ZF != 0 ) {
1092      if (m_sreg[CS].d)
1093      {
1094         m_eip += disp;
1095      }
1096      else
1097      {
1098         m_eip = (m_eip + disp) & 0xffff;
1099      }
1100      CHANGE_PC(m_eip);
1101      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1102   } else {
1103      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1104   }
1105}
1106
1107void i386_device::i386_jcxz16()            // Opcode 0xe3
1108{
1109   INT8 disp = FETCH();
1110   int val = (m_address_size)?(REG32(ECX) == 0):(REG16(CX) == 0);
1111   if( val ) {
1112      if (m_sreg[CS].d)
1113      {
1114         m_eip += disp;
1115      }
1116      else
1117      {
1118         m_eip = (m_eip + disp) & 0xffff;
1119      }
1120      CHANGE_PC(m_eip);
1121      CYCLES(CYCLES_JCXZ);       /* TODO: Timing = 9 + m */
1122   } else {
1123      CYCLES(CYCLES_JCXZ_NOBRANCH);
1124   }
1125}
1126
1127void i386_device::i386_jmp_rel16()         // Opcode 0xe9
1128{
1129   INT16 disp = FETCH16();
1130
1131   if (m_sreg[CS].d)
1132   {
1133      m_eip += disp;
1134   }
1135   else
1136   {
1137      m_eip = (m_eip + disp) & 0xffff;
1138   }
1139   CHANGE_PC(m_eip);
1140   CYCLES(CYCLES_JMP);        /* TODO: Timing = 7 + m */
1141}
1142
1143void i386_device::i386_jmp_abs16()         // Opcode 0xea
1144{
1145   UINT16 address = FETCH16();
1146   UINT16 segment = FETCH16();
1147
1148   if( PROTECTED_MODE && !V8086_MODE)
1149   {
1150      i386_protected_mode_jump(segment,address,0,0);
1151   }
1152   else
1153   {
1154      m_eip = address;
1155      m_sreg[CS].selector = segment;
1156      m_performed_intersegment_jump = 1;
1157      i386_load_segment_descriptor(CS);
1158      CHANGE_PC(m_eip);
1159   }
1160   CYCLES(CYCLES_JMP_INTERSEG);
1161}
1162
1163void i386_device::i386_lea16()             // Opcode 0x8d
1164{
1165   UINT8 modrm = FETCH();
1166   UINT32 ea = GetNonTranslatedEA(modrm,NULL);
1167   STORE_REG16(modrm, ea);
1168   CYCLES(CYCLES_LEA);
1169}
1170
1171void i386_device::i386_enter16()           // Opcode 0xc8
1172{
1173   UINT16 framesize = FETCH16();
1174   UINT8 level = FETCH() % 32;
1175   UINT8 x;
1176   UINT16 frameptr;
1177   PUSH16(REG16(BP));
1178
1179   if(!STACK_32BIT)
1180      frameptr = REG16(SP);
1181   else
1182      frameptr = REG32(ESP);
1183
1184   if(level > 0)
1185   {
1186      for(x=1;x<level-1;x++)
1187      {
1188         REG16(BP) -= 2;
1189         PUSH16(READ16(REG16(BP)));
1190      }
1191      PUSH16(frameptr);
1192   }
1193   REG16(BP) = frameptr;
1194   if(!STACK_32BIT)
1195      REG16(SP) -= framesize;
1196   else
1197      REG32(ESP) -= framesize;
1198   CYCLES(CYCLES_ENTER);
1199}
1200
1201void i386_device::i386_leave16()           // Opcode 0xc9
1202{
1203   if(!STACK_32BIT)
1204      REG16(SP) = REG16(BP);
1205   else
1206      REG32(ESP) = REG32(EBP);
1207   REG16(BP) = POP16();
1208   CYCLES(CYCLES_LEAVE);
1209}
1210
1211void i386_device::i386_lodsw()             // Opcode 0xad
1212{
1213   UINT32 eas;
1214   if( m_segment_prefix ) {
1215      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1216   } else {
1217      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1218   }
1219   REG16(AX) = READ16(eas);
1220   BUMP_SI(2);
1221   CYCLES(CYCLES_LODS);
1222}
1223
1224void i386_device::i386_loop16()            // Opcode 0xe2
1225{
1226   INT8 disp = FETCH();
1227   INT32 val = (m_address_size)?(--REG32(ECX)):(--REG16(CX));
1228   if( val != 0 ) {
1229      if (m_sreg[CS].d)
1230      {
1231         m_eip += disp;
1232      }
1233      else
1234      {
1235         m_eip = (m_eip + disp) & 0xffff;
1236      }
1237      CHANGE_PC(m_eip);
1238   }
1239   CYCLES(CYCLES_LOOP);       /* TODO: Timing = 11 + m */
1240}
1241
1242void i386_device::i386_loopne16()          // Opcode 0xe0
1243{
1244   INT8 disp = FETCH();
1245   INT32 val = (m_address_size)?(--REG32(ECX)):(--REG16(CX));
1246   if( val != 0 && m_ZF == 0 ) {
1247      if (m_sreg[CS].d)
1248      {
1249         m_eip += disp;
1250      }
1251      else
1252      {
1253         m_eip = (m_eip + disp) & 0xffff;
1254      }
1255      CHANGE_PC(m_eip);
1256   }
1257   CYCLES(CYCLES_LOOPNZ);     /* TODO: Timing = 11 + m */
1258}
1259
1260void i386_device::i386_loopz16()           // Opcode 0xe1
1261{
1262   INT8 disp = FETCH();
1263   INT32 val = (m_address_size)?(--REG32(ECX)):(--REG16(CX));
1264   if( val != 0 && m_ZF != 0 ) {
1265      if (m_sreg[CS].d)
1266      {
1267         m_eip += disp;
1268      }
1269      else
1270      {
1271         m_eip = (m_eip + disp) & 0xffff;
1272      }
1273      CHANGE_PC(m_eip);
1274   }
1275   CYCLES(CYCLES_LOOPZ);      /* TODO: Timing = 11 + m */
1276}
1277
1278void i386_device::i386_mov_rm16_r16()      // Opcode 0x89
1279{
1280   UINT16 src;
1281   UINT8 modrm = FETCH();
1282   if( modrm >= 0xc0 ) {
1283      src = LOAD_REG16(modrm);
1284      STORE_RM16(modrm, src);
1285      CYCLES(CYCLES_MOV_REG_REG);
1286   } else {
1287      UINT32 ea = GetEA(modrm,1);
1288      src = LOAD_REG16(modrm);
1289      WRITE16(ea, src);
1290      CYCLES(CYCLES_MOV_REG_MEM);
1291   }
1292}
1293
1294void i386_device::i386_mov_r16_rm16()      // Opcode 0x8b
1295{
1296   UINT16 src;
1297   UINT8 modrm = FETCH();
1298   if( modrm >= 0xc0 ) {
1299      src = LOAD_RM16(modrm);
1300      STORE_REG16(modrm, src);
1301      CYCLES(CYCLES_MOV_REG_REG);
1302   } else {
1303      UINT32 ea = GetEA(modrm,0);
1304      src = READ16(ea);
1305      STORE_REG16(modrm, src);
1306      CYCLES(CYCLES_MOV_MEM_REG);
1307   }
1308}
1309
1310void i386_device::i386_mov_rm16_i16()      // Opcode 0xc7
1311{
1312   UINT8 modrm = FETCH();
1313   if( modrm >= 0xc0 ) {
1314      UINT16 value = FETCH16();
1315      STORE_RM16(modrm, value);
1316      CYCLES(CYCLES_MOV_IMM_REG);
1317   } else {
1318      UINT32 ea = GetEA(modrm,1);
1319      UINT16 value = FETCH16();
1320      WRITE16(ea, value);
1321      CYCLES(CYCLES_MOV_IMM_MEM);
1322   }
1323}
1324
1325void i386_device::i386_mov_ax_m16()        // Opcode 0xa1
1326{
1327   UINT32 offset, ea;
1328   if( m_address_size ) {
1329      offset = FETCH32();
1330   } else {
1331      offset = FETCH16();
1332   }
1333   /* TODO: Not sure if this is correct... */
1334   if( m_segment_prefix ) {
1335      ea = i386_translate(m_segment_override, offset, 0 );
1336   } else {
1337      ea = i386_translate(DS, offset, 0 );
1338   }
1339   REG16(AX) = READ16(ea);
1340   CYCLES(CYCLES_MOV_MEM_ACC);
1341}
1342
1343void i386_device::i386_mov_m16_ax()        // Opcode 0xa3
1344{
1345   UINT32 offset, ea;
1346   if( m_address_size ) {
1347      offset = FETCH32();
1348   } else {
1349      offset = FETCH16();
1350   }
1351   /* TODO: Not sure if this is correct... */
1352   if( m_segment_prefix ) {
1353      ea = i386_translate(m_segment_override, offset, 1 );
1354   } else {
1355      ea = i386_translate(DS, offset, 1 );
1356   }
1357   WRITE16(ea, REG16(AX) );
1358   CYCLES(CYCLES_MOV_ACC_MEM);
1359}
1360
1361void i386_device::i386_mov_ax_i16()        // Opcode 0xb8
1362{
1363   REG16(AX) = FETCH16();
1364   CYCLES(CYCLES_MOV_IMM_REG);
1365}
1366
1367void i386_device::i386_mov_cx_i16()        // Opcode 0xb9
1368{
1369   REG16(CX) = FETCH16();
1370   CYCLES(CYCLES_MOV_IMM_REG);
1371}
1372
1373void i386_device::i386_mov_dx_i16()        // Opcode 0xba
1374{
1375   REG16(DX) = FETCH16();
1376   CYCLES(CYCLES_MOV_IMM_REG);
1377}
1378
1379void i386_device::i386_mov_bx_i16()        // Opcode 0xbb
1380{
1381   REG16(BX) = FETCH16();
1382   CYCLES(CYCLES_MOV_IMM_REG);
1383}
1384
1385void i386_device::i386_mov_sp_i16()        // Opcode 0xbc
1386{
1387   REG16(SP) = FETCH16();
1388   CYCLES(CYCLES_MOV_IMM_REG);
1389}
1390
1391void i386_device::i386_mov_bp_i16()        // Opcode 0xbd
1392{
1393   REG16(BP) = FETCH16();
1394   CYCLES(CYCLES_MOV_IMM_REG);
1395}
1396
1397void i386_device::i386_mov_si_i16()        // Opcode 0xbe
1398{
1399   REG16(SI) = FETCH16();
1400   CYCLES(CYCLES_MOV_IMM_REG);
1401}
1402
1403void i386_device::i386_mov_di_i16()        // Opcode 0xbf
1404{
1405   REG16(DI) = FETCH16();
1406   CYCLES(CYCLES_MOV_IMM_REG);
1407}
1408
1409void i386_device::i386_movsw()             // Opcode 0xa5
1410{
1411   UINT32 eas, ead;
1412   UINT16 v;
1413   if( m_segment_prefix ) {
1414      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1415   } else {
1416      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1417   }
1418   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
1419   v = READ16(eas);
1420   WRITE16(ead, v);
1421   BUMP_SI(2);
1422   BUMP_DI(2);
1423   CYCLES(CYCLES_MOVS);
1424}
1425
1426void i386_device::i386_movsx_r16_rm8()     // Opcode 0x0f be
1427{
1428   UINT8 modrm = FETCH();
1429   if( modrm >= 0xc0 ) {
1430      INT16 src = (INT8)LOAD_RM8(modrm);
1431      STORE_REG16(modrm, src);
1432      CYCLES(CYCLES_MOVSX_REG_REG);
1433   } else {
1434      UINT32 ea = GetEA(modrm,0);
1435      INT16 src = (INT8)READ8(ea);
1436      STORE_REG16(modrm, src);
1437      CYCLES(CYCLES_MOVSX_MEM_REG);
1438   }
1439}
1440
1441void i386_device::i386_movzx_r16_rm8()     // Opcode 0x0f b6
1442{
1443   UINT8 modrm = FETCH();
1444   if( modrm >= 0xc0 ) {
1445      UINT16 src = (UINT8)LOAD_RM8(modrm);
1446      STORE_REG16(modrm, src);
1447      CYCLES(CYCLES_MOVZX_REG_REG);
1448   } else {
1449      UINT32 ea = GetEA(modrm,0);
1450      UINT16 src = (UINT8)READ8(ea);
1451      STORE_REG16(modrm, src);
1452      CYCLES(CYCLES_MOVZX_MEM_REG);
1453   }
1454}
1455
1456void i386_device::i386_or_rm16_r16()       // Opcode 0x09
1457{
1458   UINT16 src, dst;
1459   UINT8 modrm = FETCH();
1460   if( modrm >= 0xc0 ) {
1461      src = LOAD_REG16(modrm);
1462      dst = LOAD_RM16(modrm);
1463      dst = OR16(dst, src);
1464      STORE_RM16(modrm, dst);
1465      CYCLES(CYCLES_ALU_REG_REG);
1466   } else {
1467      UINT32 ea = GetEA(modrm,1);
1468      src = LOAD_REG16(modrm);
1469      dst = READ16(ea);
1470      dst = OR16(dst, src);
1471      WRITE16(ea, dst);
1472      CYCLES(CYCLES_ALU_REG_MEM);
1473   }
1474}
1475
1476void i386_device::i386_or_r16_rm16()       // Opcode 0x0b
1477{
1478   UINT16 src, dst;
1479   UINT8 modrm = FETCH();
1480   if( modrm >= 0xc0 ) {
1481      src = LOAD_RM16(modrm);
1482      dst = LOAD_REG16(modrm);
1483      dst = OR16(dst, src);
1484      STORE_REG16(modrm, dst);
1485      CYCLES(CYCLES_ALU_REG_REG);
1486   } else {
1487      UINT32 ea = GetEA(modrm,0);
1488      src = READ16(ea);
1489      dst = LOAD_REG16(modrm);
1490      dst = OR16(dst, src);
1491      STORE_REG16(modrm, dst);
1492      CYCLES(CYCLES_ALU_MEM_REG);
1493   }
1494}
1495
1496void i386_device::i386_or_ax_i16()         // Opcode 0x0d
1497{
1498   UINT16 src, dst;
1499   src = FETCH16();
1500   dst = REG16(AX);
1501   dst = OR16(dst, src);
1502   REG16(AX) = dst;
1503   CYCLES(CYCLES_ALU_IMM_ACC);
1504}
1505
1506void i386_device::i386_out_ax_i8()         // Opcode 0xe7
1507{
1508   UINT16 port = FETCH();
1509   UINT16 data = REG16(AX);
1510   WRITEPORT16(port, data);
1511   CYCLES(CYCLES_OUT_VAR);
1512}
1513
1514void i386_device::i386_out_ax_dx()         // Opcode 0xef
1515{
1516   UINT16 port = REG16(DX);
1517   UINT16 data = REG16(AX);
1518   WRITEPORT16(port, data);
1519   CYCLES(CYCLES_OUT);
1520}
1521
1522void i386_device::i386_pop_ax()            // Opcode 0x58
1523{
1524   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1525   if(i386_limit_check(SS,offset+1) == 0)
1526      REG16(AX) = POP16();
1527   else
1528      FAULT(FAULT_SS,0)
1529   CYCLES(CYCLES_POP_REG_SHORT);
1530}
1531
1532void i386_device::i386_pop_cx()            // Opcode 0x59
1533{
1534   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1535   if(i386_limit_check(SS,offset+1) == 0)
1536      REG16(CX) = POP16();
1537   else
1538      FAULT(FAULT_SS,0)
1539   CYCLES(CYCLES_POP_REG_SHORT);
1540}
1541
1542void i386_device::i386_pop_dx()            // Opcode 0x5a
1543{
1544   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1545   if(i386_limit_check(SS,offset+1) == 0)
1546      REG16(DX) = POP16();
1547   else
1548      FAULT(FAULT_SS,0)
1549   CYCLES(CYCLES_POP_REG_SHORT);
1550}
1551
1552void i386_device::i386_pop_bx()            // Opcode 0x5b
1553{
1554   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1555   if(i386_limit_check(SS,offset+1) == 0)
1556      REG16(BX) = POP16();
1557   else
1558      FAULT(FAULT_SS,0)
1559   CYCLES(CYCLES_POP_REG_SHORT);
1560}
1561
1562void i386_device::i386_pop_sp()            // Opcode 0x5c
1563{
1564   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1565   if(i386_limit_check(SS,offset+1) == 0)
1566      REG16(SP) = POP16();
1567   else
1568      FAULT(FAULT_SS,0)
1569   CYCLES(CYCLES_POP_REG_SHORT);
1570}
1571
1572void i386_device::i386_pop_bp()            // Opcode 0x5d
1573{
1574   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1575   if(i386_limit_check(SS,offset+1) == 0)
1576      REG16(BP) = POP16();
1577   else
1578      FAULT(FAULT_SS,0)
1579   CYCLES(CYCLES_POP_REG_SHORT);
1580}
1581
1582void i386_device::i386_pop_si()            // Opcode 0x5e
1583{
1584   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1585   if(i386_limit_check(SS,offset+1) == 0)
1586      REG16(SI) = POP16();
1587   else
1588      FAULT(FAULT_SS,0)
1589   CYCLES(CYCLES_POP_REG_SHORT);
1590}
1591
1592void i386_device::i386_pop_di()            // Opcode 0x5f
1593{
1594   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1595   if(i386_limit_check(SS,offset+1) == 0)
1596      REG16(DI) = POP16();
1597   else
1598      FAULT(FAULT_SS,0)
1599   CYCLES(CYCLES_POP_REG_SHORT);
1600}
1601
1602bool i386_device::i386_pop_seg16(int segment)
1603{
1604   UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1605   UINT16 value;
1606   bool fault;
1607   if(i386_limit_check(SS,offset+1) == 0)
1608   {
1609      ea = i386_translate(SS, offset, 0);
1610      value = READ16(ea);
1611      i386_sreg_load(value, segment, &fault);
1612      if(fault) return false;
1613      if(STACK_32BIT)
1614         REG32(ESP) = offset + 2;
1615      else
1616         REG16(SP) = offset + 2;
1617   }
1618   else
1619   {
1620      m_ext = 1;
1621      i386_trap_with_error(FAULT_SS,0,0,0);
1622      return false;
1623   }
1624   CYCLES(CYCLES_POP_SREG);
1625   return true;
1626}
1627
1628void i386_device::i386_pop_ds16()          // Opcode 0x1f
1629{
1630   i386_pop_seg16(DS);
1631}
1632
1633void i386_device::i386_pop_es16()          // Opcode 0x07
1634{
1635   i386_pop_seg16(ES);
1636}
1637
1638void i386_device::i386_pop_fs16()          // Opcode 0x0f a1
1639{
1640   i386_pop_seg16(FS);
1641}
1642
1643void i386_device::i386_pop_gs16()          // Opcode 0x0f a9
1644{
1645   i386_pop_seg16(GS);
1646}
1647
1648void i386_device::i386_pop_ss16()          // Opcode 0x17
1649{
1650   if(!i386_pop_seg16(SS)) return;
1651   if(m_IF != 0) // if external interrupts are enabled
1652   {
1653      m_IF = 0;  // reset IF for the next instruction
1654      m_delayed_interrupt_enable = 1;
1655   }
1656}
1657
1658void i386_device::i386_pop_rm16()          // Opcode 0x8f
1659{
1660   UINT8 modrm = FETCH();
1661   UINT16 value;
1662   UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1663
1664   if(i386_limit_check(SS,offset+1) == 0)
1665   {
1666      UINT32 temp_sp = REG32(ESP);
1667      value = POP16();
1668
1669      if( modrm >= 0xc0 ) {
1670         STORE_RM16(modrm, value);
1671      } else {
1672         ea = GetEA(modrm,1);
1673         try
1674         {
1675            WRITE16(ea, value);
1676         }
1677         catch(UINT64 e)
1678         {
1679            REG32(ESP) = temp_sp;
1680            throw e;
1681         }
1682      }
1683   }
1684   else
1685      FAULT(FAULT_SS,0)
1686   CYCLES(CYCLES_POP_RM);
1687}
1688
1689void i386_device::i386_popa()              // Opcode 0x61
1690{
1691   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1692
1693   if(i386_limit_check(SS,offset+15) == 0)
1694   {
1695      REG16(DI) = POP16();
1696      REG16(SI) = POP16();
1697      REG16(BP) = POP16();
1698      REG16(SP) += 2;
1699      REG16(BX) = POP16();
1700      REG16(DX) = POP16();
1701      REG16(CX) = POP16();
1702      REG16(AX) = POP16();
1703   }
1704   else
1705      FAULT(FAULT_SS,0)
1706   CYCLES(CYCLES_POPA);
1707}
1708
1709void i386_device::i386_popf()              // Opcode 0x9d
1710{
1711   UINT32 value;
1712   UINT32 current = get_flags();
1713   UINT8 IOPL = (current >> 12) & 0x03;
1714   UINT32 mask = 0x7fd5;
1715   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1716
1717   // IOPL can only change if CPL is 0
1718   if(m_CPL != 0)
1719      mask &= ~0x00003000;
1720
1721   // IF can only change if CPL is at least as privileged as IOPL
1722   if(m_CPL > IOPL)
1723      mask &= ~0x00000200;
1724
1725   if(V8086_MODE)
1726   {
1727      if(IOPL < 3)
1728      {
1729         logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",m_pc);
1730         FAULT(FAULT_GP,0)  // #GP(0)
1731      }
1732      mask &= ~0x00003000;  // IOPL cannot be changed while in V8086 mode
1733   }
1734
1735   if(i386_limit_check(SS,offset+1) == 0)
1736   {
1737      value = POP16();
1738      set_flags((current & ~mask) | (value & mask));  // mask out reserved bits
1739   }
1740   else
1741      FAULT(FAULT_SS,0)
1742   CYCLES(CYCLES_POPF);
1743}
1744
1745void i386_device::i386_push_ax()           // Opcode 0x50
1746{
1747   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1748   if(i386_limit_check(SS,offset-2) == 0)
1749      PUSH16(REG16(AX) );
1750   else
1751      FAULT(FAULT_SS,0)
1752   CYCLES(CYCLES_PUSH_REG_SHORT);
1753}
1754
1755void i386_device::i386_push_cx()           // Opcode 0x51
1756{
1757   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1758   if(i386_limit_check(SS,offset-2) == 0)
1759      PUSH16(REG16(CX) );
1760   else
1761      FAULT(FAULT_SS,0)
1762   CYCLES(CYCLES_PUSH_REG_SHORT);
1763}
1764
1765void i386_device::i386_push_dx()           // Opcode 0x52
1766{
1767   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1768   if(i386_limit_check(SS,offset-2) == 0)
1769      PUSH16(REG16(DX) );
1770   else
1771      FAULT(FAULT_SS,0)
1772   CYCLES(CYCLES_PUSH_REG_SHORT);
1773}
1774
1775void i386_device::i386_push_bx()           // Opcode 0x53
1776{
1777   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1778   if(i386_limit_check(SS,offset-2) == 0)
1779      PUSH16(REG16(BX) );
1780   else
1781      FAULT(FAULT_SS,0)
1782   CYCLES(CYCLES_PUSH_REG_SHORT);
1783}
1784
1785void i386_device::i386_push_sp()           // Opcode 0x54
1786{
1787   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1788   if(i386_limit_check(SS,offset-2) == 0)
1789      PUSH16(REG16(SP) );
1790   else
1791      FAULT(FAULT_SS,0)
1792   CYCLES(CYCLES_PUSH_REG_SHORT);
1793}
1794
1795void i386_device::i386_push_bp()           // Opcode 0x55
1796{
1797   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1798   if(i386_limit_check(SS,offset-2) == 0)
1799      PUSH16(REG16(BP) );
1800   else
1801      FAULT(FAULT_SS,0)
1802   CYCLES(CYCLES_PUSH_REG_SHORT);
1803}
1804
1805void i386_device::i386_push_si()           // Opcode 0x56
1806{
1807   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1808   if(i386_limit_check(SS,offset-2) == 0)
1809      PUSH16(REG16(SI) );
1810   else
1811      FAULT(FAULT_SS,0)
1812   CYCLES(CYCLES_PUSH_REG_SHORT);
1813}
1814
1815void i386_device::i386_push_di()           // Opcode 0x57
1816{
1817   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1818   if(i386_limit_check(SS,offset-2) == 0)
1819      PUSH16(REG16(DI) );
1820   else
1821      FAULT(FAULT_SS,0)
1822   CYCLES(CYCLES_PUSH_REG_SHORT);
1823}
1824
1825void i386_device::i386_push_cs16()         // Opcode 0x0e
1826{
1827   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1828   if(i386_limit_check(SS,offset-2) == 0)
1829      PUSH16(m_sreg[CS].selector );
1830   else
1831      FAULT(FAULT_SS,0)
1832   CYCLES(CYCLES_PUSH_SREG);
1833}
1834
1835void i386_device::i386_push_ds16()         // Opcode 0x1e
1836{
1837   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1838   if(i386_limit_check(SS,offset-2) == 0)
1839      PUSH16(m_sreg[DS].selector );
1840   else
1841      FAULT(FAULT_SS,0)
1842   CYCLES(CYCLES_PUSH_SREG);
1843}
1844
1845void i386_device::i386_push_es16()         // Opcode 0x06
1846{
1847   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1848   if(i386_limit_check(SS,offset-2) == 0)
1849      PUSH16(m_sreg[ES].selector );
1850   else
1851      FAULT(FAULT_SS,0)
1852   CYCLES(CYCLES_PUSH_SREG);
1853}
1854
1855void i386_device::i386_push_fs16()         // Opcode 0x0f a0
1856{
1857   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1858   if(i386_limit_check(SS,offset-2) == 0)
1859      PUSH16(m_sreg[FS].selector );
1860   else
1861      FAULT(FAULT_SS,0)
1862   CYCLES(CYCLES_PUSH_SREG);
1863}
1864
1865void i386_device::i386_push_gs16()         // Opcode 0x0f a8
1866{
1867   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1868   if(i386_limit_check(SS,offset-2) == 0)
1869      PUSH16(m_sreg[GS].selector );
1870   else
1871      FAULT(FAULT_SS,0)
1872   CYCLES(CYCLES_PUSH_SREG);
1873}
1874
1875void i386_device::i386_push_ss16()         // Opcode 0x16
1876{
1877   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1878   if(i386_limit_check(SS,offset-2) == 0)
1879      PUSH16(m_sreg[SS].selector );
1880   else
1881      FAULT(FAULT_SS,0)
1882   CYCLES(CYCLES_PUSH_SREG);
1883}
1884
1885void i386_device::i386_push_i16()          // Opcode 0x68
1886{
1887   UINT16 value = FETCH16();
1888   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1889   if(i386_limit_check(SS,offset-2) == 0)
1890      PUSH16(value);
1891   else
1892      FAULT(FAULT_SS,0)
1893   CYCLES(CYCLES_PUSH_IMM);
1894}
1895
1896void i386_device::i386_pusha()             // Opcode 0x60
1897{
1898   UINT16 temp = REG16(SP);
1899   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1900   if(i386_limit_check(SS,offset-16) == 0)
1901   {
1902      PUSH16(REG16(AX) );
1903      PUSH16(REG16(CX) );
1904      PUSH16(REG16(DX) );
1905      PUSH16(REG16(BX) );
1906      PUSH16(temp );
1907      PUSH16(REG16(BP) );
1908      PUSH16(REG16(SI) );
1909      PUSH16(REG16(DI) );
1910   }
1911   else
1912      FAULT(FAULT_SS,0)
1913   CYCLES(CYCLES_PUSHA);
1914}
1915
1916void i386_device::i386_pushf()             // Opcode 0x9c
1917{
1918   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1919   if(i386_limit_check(SS,offset-2) == 0)
1920      PUSH16(get_flags() & 0xffff );
1921   else
1922      FAULT(FAULT_SS,0)
1923   CYCLES(CYCLES_PUSHF);
1924}
1925
1926void i386_device::i386_ret_near16_i16()    // Opcode 0xc2
1927{
1928   INT16 disp = FETCH16();
1929   m_eip = POP16();
1930   REG16(SP) += disp;
1931   CHANGE_PC(m_eip);
1932   CYCLES(CYCLES_RET_IMM);        /* TODO: Timing = 10 + m */
1933}
1934
1935void i386_device::i386_ret_near16()        // Opcode 0xc3
1936{
1937   m_eip = POP16();
1938   CHANGE_PC(m_eip);
1939   CYCLES(CYCLES_RET);        /* TODO: Timing = 10 + m */
1940}
1941
1942void i386_device::i386_sbb_rm16_r16()      // Opcode 0x19
1943{
1944   UINT16 src, dst;
1945   UINT8 modrm = FETCH();
1946   if( modrm >= 0xc0 ) {
1947      src = LOAD_REG16(modrm);
1948      dst = LOAD_RM16(modrm);
1949      dst = SBB16(dst, src, m_CF);
1950      STORE_RM16(modrm, dst);
1951      CYCLES(CYCLES_ALU_REG_REG);
1952   } else {
1953      UINT32 ea = GetEA(modrm,1);
1954      src = LOAD_REG16(modrm);
1955      dst = READ16(ea);
1956      dst = SBB16(dst, src, m_CF);
1957      WRITE16(ea, dst);
1958      CYCLES(CYCLES_ALU_REG_MEM);
1959   }
1960}
1961
1962void i386_device::i386_sbb_r16_rm16()      // Opcode 0x1b
1963{
1964   UINT16 src, dst;
1965   UINT8 modrm = FETCH();
1966   if( modrm >= 0xc0 ) {
1967      src = LOAD_RM16(modrm);
1968      dst = LOAD_REG16(modrm);
1969      dst = SBB16(dst, src, m_CF);
1970      STORE_REG16(modrm, dst);
1971      CYCLES(CYCLES_ALU_REG_REG);
1972   } else {
1973      UINT32 ea = GetEA(modrm,0);
1974      src = READ16(ea);
1975      dst = LOAD_REG16(modrm);
1976      dst = SBB16(dst, src, m_CF);
1977      STORE_REG16(modrm, dst);
1978      CYCLES(CYCLES_ALU_MEM_REG);
1979   }
1980}
1981
1982void i386_device::i386_sbb_ax_i16()        // Opcode 0x1d
1983{
1984   UINT16 src, dst;
1985   src = FETCH16();
1986   dst = REG16(AX);
1987   dst = SBB16(dst, src, m_CF);
1988   REG16(AX) = dst;
1989   CYCLES(CYCLES_ALU_IMM_ACC);
1990}
1991
1992void i386_device::i386_scasw()             // Opcode 0xaf
1993{
1994   UINT32 eas;
1995   UINT16 src, dst;
1996   eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
1997   src = READ16(eas);
1998   dst = REG16(AX);
1999   SUB16(dst, src);
2000   BUMP_DI(2);
2001   CYCLES(CYCLES_SCAS);
2002}
2003
2004void i386_device::i386_shld16_i8()         // Opcode 0x0f a4
2005{
2006   UINT8 modrm = FETCH();
2007   if( modrm >= 0xc0 ) {
2008      UINT16 dst = LOAD_RM16(modrm);
2009      UINT16 upper = LOAD_REG16(modrm);
2010      UINT8 shift = FETCH();
2011      shift &= 31;
2012      if( shift == 0 ) {
2013      } else if( shift > 15 ) {
2014         m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2015         // ppro and above should be (dst >> (32-shift))
2016         dst = (upper << (shift-16)) | (upper >> (32-shift));
2017         m_OF = m_CF ^ (dst >> 15);
2018         SetSZPF16(dst);
2019      } else {
2020         m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2021         dst = (dst << shift) | (upper >> (16-shift));
2022         m_OF = m_CF ^ (dst >> 15);
2023         SetSZPF16(dst);
2024      }
2025      STORE_RM16(modrm, dst);
2026      CYCLES(CYCLES_SHLD_REG);
2027   } else {
2028      UINT32 ea = GetEA(modrm,1);
2029      UINT16 dst = READ16(ea);
2030      UINT16 upper = LOAD_REG16(modrm);
2031      UINT8 shift = FETCH();
2032      shift &= 31;
2033      if( shift == 0 ) {
2034      } else if( shift > 15 ) {
2035         m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2036         dst = (upper << (shift-16)) | (upper >> (32-shift));
2037         m_OF = m_CF ^ (dst >> 15);
2038         SetSZPF16(dst);
2039      } else {
2040         m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2041         dst = (dst << shift) | (upper >> (16-shift));
2042         m_OF = m_CF ^ (dst >> 15);
2043         SetSZPF16(dst);
2044      }
2045      WRITE16(ea, dst);
2046      CYCLES(CYCLES_SHLD_MEM);
2047   }
2048}
2049
2050void i386_device::i386_shld16_cl()         // Opcode 0x0f a5
2051{
2052   UINT8 modrm = FETCH();
2053   if( modrm >= 0xc0 ) {
2054      UINT16 dst = LOAD_RM16(modrm);
2055      UINT16 upper = LOAD_REG16(modrm);
2056      UINT8 shift = REG8(CL);
2057      shift &= 31;
2058      if( shift == 0 ) {
2059      } else if( shift > 15 ) {
2060         m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2061         dst = (upper << (shift-16)) | (upper >> (32-shift));
2062         m_OF = m_CF ^ (dst >> 15);
2063         SetSZPF16(dst);
2064      } else {
2065         m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2066         dst = (dst << shift) | (upper >> (16-shift));
2067         m_OF = m_CF ^ (dst >> 15);
2068         SetSZPF16(dst);
2069      }
2070      STORE_RM16(modrm, dst);
2071      CYCLES(CYCLES_SHLD_REG);
2072   } else {
2073      UINT32 ea = GetEA(modrm,1);
2074      UINT16 dst = READ16(ea);
2075      UINT16 upper = LOAD_REG16(modrm);
2076      UINT8 shift = REG8(CL);
2077      shift &= 31;
2078      if( shift == 0 ) {
2079      } else if( shift > 15 ) {
2080         m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2081         dst = (upper << (shift-16)) | (upper >> (32-shift));
2082         m_OF = m_CF ^ (dst >> 15);
2083         SetSZPF16(dst);
2084      } else {
2085         m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2086         dst = (dst << shift) | (upper >> (16-shift));
2087         m_OF = m_CF ^ (dst >> 15);
2088         SetSZPF16(dst);
2089      }
2090      WRITE16(ea, dst);
2091      CYCLES(CYCLES_SHLD_MEM);
2092   }
2093}
2094
2095void i386_device::i386_shrd16_i8()         // Opcode 0x0f ac
2096{
2097   UINT8 modrm = FETCH();
2098   if( modrm >= 0xc0 ) {
2099      UINT16 dst = LOAD_RM16(modrm);
2100      UINT16 upper = LOAD_REG16(modrm);
2101      UINT8 shift = FETCH();
2102      shift &= 31;
2103      if( shift == 0) {
2104      } else if( shift > 15 ) {
2105         m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2106         dst = (upper >> (shift-16)) | (upper << (32-shift));
2107         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2108         SetSZPF16(dst);
2109      } else {
2110         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2111         dst = (dst >> shift) | (upper << (16-shift));
2112         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2113         SetSZPF16(dst);
2114      }
2115      STORE_RM16(modrm, dst);
2116      CYCLES(CYCLES_SHRD_REG);
2117   } else {
2118      UINT32 ea = GetEA(modrm,1);
2119      UINT16 dst = READ16(ea);
2120      UINT16 upper = LOAD_REG16(modrm);
2121      UINT8 shift = FETCH();
2122      shift &= 31;
2123      if( shift == 0) {
2124      } else if( shift > 15 ) {
2125         m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2126         dst = (upper >> (shift-16)) | (upper << (32-shift));
2127         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2128         SetSZPF16(dst);
2129      } else {
2130         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2131         dst = (dst >> shift) | (upper << (16-shift));
2132         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2133         SetSZPF16(dst);
2134      }
2135      WRITE16(ea, dst);
2136      CYCLES(CYCLES_SHRD_MEM);
2137   }
2138}
2139
2140void i386_device::i386_shrd16_cl()         // Opcode 0x0f ad
2141{
2142   UINT8 modrm = FETCH();
2143   if( modrm >= 0xc0 ) {
2144      UINT16 dst = LOAD_RM16(modrm);
2145      UINT16 upper = LOAD_REG16(modrm);
2146      UINT8 shift = REG8(CL);
2147      shift &= 31;
2148      if( shift == 0) {
2149      } else if( shift > 15 ) {
2150         m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2151         dst = (upper >> (shift-16)) | (upper << (32-shift));
2152         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2153         SetSZPF16(dst);
2154      } else {
2155         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2156         dst = (dst >> shift) | (upper << (16-shift));
2157         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2158         SetSZPF16(dst);
2159      }
2160      STORE_RM16(modrm, dst);
2161      CYCLES(CYCLES_SHRD_REG);
2162   } else {
2163      UINT32 ea = GetEA(modrm,1);
2164      UINT16 dst = READ16(ea);
2165      UINT16 upper = LOAD_REG16(modrm);
2166      UINT8 shift = REG8(CL);
2167      shift &= 31;
2168      if( shift == 0) {
2169      } else if( shift > 15 ) {
2170         m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2171         dst = (upper >> (shift-16)) | (upper << (32-shift));
2172         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2173         SetSZPF16(dst);
2174      } else {
2175         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2176         dst = (dst >> shift) | (upper << (16-shift));
2177         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2178         SetSZPF16(dst);
2179      }
2180      WRITE16(ea, dst);
2181      CYCLES(CYCLES_SHRD_MEM);
2182   }
2183}
2184
2185void i386_device::i386_stosw()             // Opcode 0xab
2186{
2187   UINT32 ead;
2188   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
2189   WRITE16(ead, REG16(AX));
2190   BUMP_DI(2);
2191   CYCLES(CYCLES_STOS);
2192}
2193
2194void i386_device::i386_sub_rm16_r16()      // Opcode 0x29
2195{
2196   UINT16 src, dst;
2197   UINT8 modrm = FETCH();
2198   if( modrm >= 0xc0 ) {
2199      src = LOAD_REG16(modrm);
2200      dst = LOAD_RM16(modrm);
2201      dst = SUB16(dst, src);
2202      STORE_RM16(modrm, dst);
2203      CYCLES(CYCLES_ALU_REG_REG);
2204   } else {
2205      UINT32 ea = GetEA(modrm,1);
2206      src = LOAD_REG16(modrm);
2207      dst = READ16(ea);
2208      dst = SUB16(dst, src);
2209      WRITE16(ea, dst);
2210      CYCLES(CYCLES_ALU_REG_MEM);
2211   }
2212}
2213
2214void i386_device::i386_sub_r16_rm16()      // Opcode 0x2b
2215{
2216   UINT16 src, dst;
2217   UINT8 modrm = FETCH();
2218   if( modrm >= 0xc0 ) {
2219      src = LOAD_RM16(modrm);
2220      dst = LOAD_REG16(modrm);
2221      dst = SUB16(dst, src);
2222      STORE_REG16(modrm, dst);
2223      CYCLES(CYCLES_ALU_REG_REG);
2224   } else {
2225      UINT32 ea = GetEA(modrm,0);
2226      src = READ16(ea);
2227      dst = LOAD_REG16(modrm);
2228      dst = SUB16(dst, src);
2229      STORE_REG16(modrm, dst);
2230      CYCLES(CYCLES_ALU_MEM_REG);
2231   }
2232}
2233
2234void i386_device::i386_sub_ax_i16()        // Opcode 0x2d
2235{
2236   UINT16 src, dst;
2237   src = FETCH16();
2238   dst = REG16(AX);
2239   dst = SUB16(dst, src);
2240   REG16(AX) = dst;
2241   CYCLES(CYCLES_ALU_IMM_ACC);
2242}
2243
2244void i386_device::i386_test_ax_i16()       // Opcode 0xa9
2245{
2246   UINT16 src = FETCH16();
2247   UINT16 dst = REG16(AX);
2248   dst = src & dst;
2249   SetSZPF16(dst);
2250   m_CF = 0;
2251   m_OF = 0;
2252   CYCLES(CYCLES_TEST_IMM_ACC);
2253}
2254
2255void i386_device::i386_test_rm16_r16()     // Opcode 0x85
2256{
2257   UINT16 src, dst;
2258   UINT8 modrm = FETCH();
2259   if( modrm >= 0xc0 ) {
2260      src = LOAD_REG16(modrm);
2261      dst = LOAD_RM16(modrm);
2262      dst = src & dst;
2263      SetSZPF16(dst);
2264      m_CF = 0;
2265      m_OF = 0;
2266      CYCLES(CYCLES_TEST_REG_REG);
2267   } else {
2268      UINT32 ea = GetEA(modrm,0);
2269      src = LOAD_REG16(modrm);
2270      dst = READ16(ea);
2271      dst = src & dst;
2272      SetSZPF16(dst);
2273      m_CF = 0;
2274      m_OF = 0;
2275      CYCLES(CYCLES_TEST_REG_MEM);
2276   }
2277}
2278
2279void i386_device::i386_xchg_ax_cx()        // Opcode 0x91
2280{
2281   UINT16 temp;
2282   temp = REG16(AX);
2283   REG16(AX) = REG16(CX);
2284   REG16(CX) = temp;
2285   CYCLES(CYCLES_XCHG_REG_REG);
2286}
2287
2288void i386_device::i386_xchg_ax_dx()        // Opcode 0x92
2289{
2290   UINT16 temp;
2291   temp = REG16(AX);
2292   REG16(AX) = REG16(DX);
2293   REG16(DX) = temp;
2294   CYCLES(CYCLES_XCHG_REG_REG);
2295}
2296
2297void i386_device::i386_xchg_ax_bx()        // Opcode 0x93
2298{
2299   UINT16 temp;
2300   temp = REG16(AX);
2301   REG16(AX) = REG16(BX);
2302   REG16(BX) = temp;
2303   CYCLES(CYCLES_XCHG_REG_REG);
2304}
2305
2306void i386_device::i386_xchg_ax_sp()        // Opcode 0x94
2307{
2308   UINT16 temp;
2309   temp = REG16(AX);
2310   REG16(AX) = REG16(SP);
2311   REG16(SP) = temp;
2312   CYCLES(CYCLES_XCHG_REG_REG);
2313}
2314
2315void i386_device::i386_xchg_ax_bp()        // Opcode 0x95
2316{
2317   UINT16 temp;
2318   temp = REG16(AX);
2319   REG16(AX) = REG16(BP);
2320   REG16(BP) = temp;
2321   CYCLES(CYCLES_XCHG_REG_REG);
2322}
2323
2324void i386_device::i386_xchg_ax_si()        // Opcode 0x96
2325{
2326   UINT16 temp;
2327   temp = REG16(AX);
2328   REG16(AX) = REG16(SI);
2329   REG16(SI) = temp;
2330   CYCLES(CYCLES_XCHG_REG_REG);
2331}
2332
2333void i386_device::i386_xchg_ax_di()        // Opcode 0x97
2334{
2335   UINT16 temp;
2336   temp = REG16(AX);
2337   REG16(AX) = REG16(DI);
2338   REG16(DI) = temp;
2339   CYCLES(CYCLES_XCHG_REG_REG);
2340}
2341
2342void i386_device::i386_xchg_r16_rm16()     // Opcode 0x87
2343{
2344   UINT8 modrm = FETCH();
2345   if( modrm >= 0xc0 ) {
2346      UINT16 src = LOAD_RM16(modrm);
2347      UINT16 dst = LOAD_REG16(modrm);
2348      STORE_REG16(modrm, src);
2349      STORE_RM16(modrm, dst);
2350      CYCLES(CYCLES_XCHG_REG_REG);
2351   } else {
2352      UINT32 ea = GetEA(modrm,1);
2353      UINT16 src = READ16(ea);
2354      UINT16 dst = LOAD_REG16(modrm);
2355      STORE_REG16(modrm, src);
2356      WRITE16(ea, dst);
2357      CYCLES(CYCLES_XCHG_REG_MEM);
2358   }
2359}
2360
2361void i386_device::i386_xor_rm16_r16()      // Opcode 0x31
2362{
2363   UINT16 src, dst;
2364   UINT8 modrm = FETCH();
2365   if( modrm >= 0xc0 ) {
2366      src = LOAD_REG16(modrm);
2367      dst = LOAD_RM16(modrm);
2368      dst = XOR16(dst, src);
2369      STORE_RM16(modrm, dst);
2370      CYCLES(CYCLES_ALU_REG_REG);
2371   } else {
2372      UINT32 ea = GetEA(modrm,1);
2373      src = LOAD_REG16(modrm);
2374      dst = READ16(ea);
2375      dst = XOR16(dst, src);
2376      WRITE16(ea, dst);
2377      CYCLES(CYCLES_ALU_REG_MEM);
2378   }
2379}
2380
2381void i386_device::i386_xor_r16_rm16()      // Opcode 0x33
2382{
2383   UINT16 src, dst;
2384   UINT8 modrm = FETCH();
2385   if( modrm >= 0xc0 ) {
2386      src = LOAD_RM16(modrm);
2387      dst = LOAD_REG16(modrm);
2388      dst = XOR16(dst, src);
2389      STORE_REG16(modrm, dst);
2390      CYCLES(CYCLES_ALU_REG_REG);
2391   } else {
2392      UINT32 ea = GetEA(modrm,0);
2393      src = READ16(ea);
2394      dst = LOAD_REG16(modrm);
2395      dst = XOR16(dst, src);
2396      STORE_REG16(modrm, dst);
2397      CYCLES(CYCLES_ALU_MEM_REG);
2398   }
2399}
2400
2401void i386_device::i386_xor_ax_i16()        // Opcode 0x35
2402{
2403   UINT16 src, dst;
2404   src = FETCH16();
2405   dst = REG16(AX);
2406   dst = XOR16(dst, src);
2407   REG16(AX) = dst;
2408   CYCLES(CYCLES_ALU_IMM_ACC);
2409}
2410
2411
2412
2413void i386_device::i386_group81_16()        // Opcode 0x81
2414{
2415   UINT32 ea;
2416   UINT16 src, dst;
2417   UINT8 modrm = FETCH();
2418
2419   switch( (modrm >> 3) & 0x7 )
2420   {
2421      case 0:     // ADD Rm16, i16
2422         if( modrm >= 0xc0 ) {
2423            dst = LOAD_RM16(modrm);
2424            src = FETCH16();
2425            dst = ADD16(dst, src);
2426            STORE_RM16(modrm, dst);
2427            CYCLES(CYCLES_ALU_REG_REG);
2428         } else {
2429            ea = GetEA(modrm,1);
2430            dst = READ16(ea);
2431            src = FETCH16();
2432            dst = ADD16(dst, src);
2433            WRITE16(ea, dst);
2434            CYCLES(CYCLES_ALU_REG_MEM);
2435         }
2436         break;
2437      case 1:     // OR Rm16, i16
2438         if( modrm >= 0xc0 ) {
2439            dst = LOAD_RM16(modrm);
2440            src = FETCH16();
2441            dst = OR16(dst, src);
2442            STORE_RM16(modrm, dst);
2443            CYCLES(CYCLES_ALU_REG_REG);
2444         } else {
2445            ea = GetEA(modrm,1);
2446            dst = READ16(ea);
2447            src = FETCH16();
2448            dst = OR16(dst, src);
2449            WRITE16(ea, dst);
2450            CYCLES(CYCLES_ALU_REG_MEM);
2451         }
2452         break;
2453      case 2:     // ADC Rm16, i16
2454         if( modrm >= 0xc0 ) {
2455            dst = LOAD_RM16(modrm);
2456            src = FETCH16();
2457            dst = ADC16(dst, src, m_CF);
2458            STORE_RM16(modrm, dst);
2459            CYCLES(CYCLES_ALU_REG_REG);
2460         } else {
2461            ea = GetEA(modrm,1);
2462            dst = READ16(ea);
2463            src = FETCH16();
2464            dst = ADC16(dst, src, m_CF);
2465            WRITE16(ea, dst);
2466            CYCLES(CYCLES_ALU_REG_MEM);
2467         }
2468         break;
2469      case 3:     // SBB Rm16, i16
2470         if( modrm >= 0xc0 ) {
2471            dst = LOAD_RM16(modrm);
2472            src = FETCH16();
2473            dst = SBB16(dst, src, m_CF);
2474            STORE_RM16(modrm, dst);
2475            CYCLES(CYCLES_ALU_REG_REG);
2476         } else {
2477            ea = GetEA(modrm,1);
2478            dst = READ16(ea);
2479            src = FETCH16();
2480            dst = SBB16(dst, src, m_CF);
2481            WRITE16(ea, dst);
2482            CYCLES(CYCLES_ALU_REG_MEM);
2483         }
2484         break;
2485      case 4:     // AND Rm16, i16
2486         if( modrm >= 0xc0 ) {
2487            dst = LOAD_RM16(modrm);
2488            src = FETCH16();
2489            dst = AND16(dst, src);
2490            STORE_RM16(modrm, dst);
2491            CYCLES(CYCLES_ALU_REG_REG);
2492         } else {
2493            ea = GetEA(modrm,1);
2494            dst = READ16(ea);
2495            src = FETCH16();
2496            dst = AND16(dst, src);
2497            WRITE16(ea, dst);
2498            CYCLES(CYCLES_ALU_REG_MEM);
2499         }
2500         break;
2501      case 5:     // SUB Rm16, i16
2502         if( modrm >= 0xc0 ) {
2503            dst = LOAD_RM16(modrm);
2504            src = FETCH16();
2505            dst = SUB16(dst, src);
2506            STORE_RM16(modrm, dst);
2507            CYCLES(CYCLES_ALU_REG_REG);
2508         } else {
2509            ea = GetEA(modrm,1);
2510            dst = READ16(ea);
2511            src = FETCH16();
2512            dst = SUB16(dst, src);
2513            WRITE16(ea, dst);
2514            CYCLES(CYCLES_ALU_REG_MEM);
2515         }
2516         break;
2517      case 6:     // XOR Rm16, i16
2518         if( modrm >= 0xc0 ) {
2519            dst = LOAD_RM16(modrm);
2520            src = FETCH16();
2521            dst = XOR16(dst, src);
2522            STORE_RM16(modrm, dst);
2523            CYCLES(CYCLES_ALU_REG_REG);
2524         } else {
2525            ea = GetEA(modrm,1);
2526            dst = READ16(ea);
2527            src = FETCH16();
2528            dst = XOR16(dst, src);
2529            WRITE16(ea, dst);
2530            CYCLES(CYCLES_ALU_REG_MEM);
2531         }
2532         break;
2533      case 7:     // CMP Rm16, i16
2534         if( modrm >= 0xc0 ) {
2535            dst = LOAD_RM16(modrm);
2536            src = FETCH16();
2537            SUB16(dst, src);
2538            CYCLES(CYCLES_CMP_REG_REG);
2539         } else {
2540            ea = GetEA(modrm,0);
2541            dst = READ16(ea);
2542            src = FETCH16();
2543            SUB16(dst, src);
2544            CYCLES(CYCLES_CMP_REG_MEM);
2545         }
2546         break;
2547   }
2548}
2549
2550void i386_device::i386_group83_16()        // Opcode 0x83
2551{
2552   UINT32 ea;
2553   UINT16 src, dst;
2554   UINT8 modrm = FETCH();
2555
2556   switch( (modrm >> 3) & 0x7 )
2557   {
2558      case 0:     // ADD Rm16, i16
2559         if( modrm >= 0xc0 ) {
2560            dst = LOAD_RM16(modrm);
2561            src = (UINT16)(INT16)(INT8)FETCH();
2562            dst = ADD16(dst, src);
2563            STORE_RM16(modrm, dst);
2564            CYCLES(CYCLES_ALU_REG_REG);
2565         } else {
2566            ea = GetEA(modrm,1);
2567            dst = READ16(ea);
2568            src = (UINT16)(INT16)(INT8)FETCH();
2569            dst = ADD16(dst, src);
2570            WRITE16(ea, dst);
2571            CYCLES(CYCLES_ALU_REG_MEM);
2572         }
2573         break;
2574      case 1:     // OR Rm16, i16
2575         if( modrm >= 0xc0 ) {
2576            dst = LOAD_RM16(modrm);
2577            src = (UINT16)(INT16)(INT8)FETCH();
2578            dst = OR16(dst, src);
2579            STORE_RM16(modrm, dst);
2580            CYCLES(CYCLES_ALU_REG_REG);
2581         } else {
2582            ea = GetEA(modrm,1);
2583            dst = READ16(ea);
2584            src = (UINT16)(INT16)(INT8)FETCH();
2585            dst = OR16(dst, src);
2586            WRITE16(ea, dst);
2587            CYCLES(CYCLES_ALU_REG_MEM);
2588         }
2589         break;
2590      case 2:     // ADC Rm16, i16
2591         if( modrm >= 0xc0 ) {
2592            dst = LOAD_RM16(modrm);
2593            src = (UINT16)(INT16)(INT8)FETCH();
2594            dst = ADC16(dst, src, m_CF);
2595            STORE_RM16(modrm, dst);
2596            CYCLES(CYCLES_ALU_REG_REG);
2597         } else {
2598            ea = GetEA(modrm,1);
2599            dst = READ16(ea);
2600            src = (UINT16)(INT16)(INT8)FETCH();
2601            dst = ADC16(dst, src, m_CF);
2602            WRITE16(ea, dst);
2603            CYCLES(CYCLES_ALU_REG_MEM);
2604         }
2605         break;
2606      case 3:     // SBB Rm16, i16
2607         if( modrm >= 0xc0 ) {
2608            dst = LOAD_RM16(modrm);
2609            src = ((UINT16)(INT16)(INT8)FETCH());
2610            dst = SBB16(dst, src, m_CF);
2611            STORE_RM16(modrm, dst);
2612            CYCLES(CYCLES_ALU_REG_REG);
2613         } else {
2614            ea = GetEA(modrm,1);
2615            dst = READ16(ea);
2616            src = ((UINT16)(INT16)(INT8)FETCH());
2617            dst = SBB16(dst, src, m_CF);
2618            WRITE16(ea, dst);
2619            CYCLES(CYCLES_ALU_REG_MEM);
2620         }
2621         break;
2622      case 4:     // AND Rm16, i16
2623         if( modrm >= 0xc0 ) {
2624            dst = LOAD_RM16(modrm);
2625            src = (UINT16)(INT16)(INT8)FETCH();
2626            dst = AND16(dst, src);
2627            STORE_RM16(modrm, dst);
2628            CYCLES(CYCLES_ALU_REG_REG);
2629         } else {
2630            ea = GetEA(modrm,1);
2631            dst = READ16(ea);
2632            src = (UINT16)(INT16)(INT8)FETCH();
2633            dst = AND16(dst, src);
2634            WRITE16(ea, dst);
2635            CYCLES(CYCLES_ALU_REG_MEM);
2636         }
2637         break;
2638      case 5:     // SUB Rm16, i16
2639         if( modrm >= 0xc0 ) {
2640            dst = LOAD_RM16(modrm);
2641            src = (UINT16)(INT16)(INT8)FETCH();
2642            dst = SUB16(dst, src);
2643            STORE_RM16(modrm, dst);
2644            CYCLES(CYCLES_ALU_REG_REG);
2645         } else {
2646            ea = GetEA(modrm,1);
2647            dst = READ16(ea);
2648            src = (UINT16)(INT16)(INT8)FETCH();
2649            dst = SUB16(dst, src);
2650            WRITE16(ea, dst);
2651            CYCLES(CYCLES_ALU_REG_MEM);
2652         }
2653         break;
2654      case 6:     // XOR Rm16, i16
2655         if( modrm >= 0xc0 ) {
2656            dst = LOAD_RM16(modrm);
2657            src = (UINT16)(INT16)(INT8)FETCH();
2658            dst = XOR16(dst, src);
2659            STORE_RM16(modrm, dst);
2660            CYCLES(CYCLES_ALU_REG_REG);
2661         } else {
2662            ea = GetEA(modrm,1);
2663            dst = READ16(ea);
2664            src = (UINT16)(INT16)(INT8)FETCH();
2665            dst = XOR16(dst, src);
2666            WRITE16(ea, dst);
2667            CYCLES(CYCLES_ALU_REG_MEM);
2668         }
2669         break;
2670      case 7:     // CMP Rm16, i16
2671         if( modrm >= 0xc0 ) {
2672            dst = LOAD_RM16(modrm);
2673            src = (UINT16)(INT16)(INT8)FETCH();
2674            SUB16(dst, src);
2675            CYCLES(CYCLES_CMP_REG_REG);
2676         } else {
2677            ea = GetEA(modrm,0);
2678            dst = READ16(ea);
2679            src = (UINT16)(INT16)(INT8)FETCH();
2680            SUB16(dst, src);
2681            CYCLES(CYCLES_CMP_REG_MEM);
2682         }
2683         break;
2684   }
2685}
2686
2687void i386_device::i386_groupC1_16()        // Opcode 0xc1
2688{
2689   UINT16 dst;
2690   UINT8 modrm = FETCH();
2691   UINT8 shift;
2692
2693   if( modrm >= 0xc0 ) {
2694      dst = LOAD_RM16(modrm);
2695      shift = FETCH() & 0x1f;
2696      dst = i386_shift_rotate16(modrm, dst, shift);
2697      STORE_RM16(modrm, dst);
2698   } else {
2699      UINT32 ea = GetEA(modrm,1);
2700      dst = READ16(ea);
2701      shift = FETCH() & 0x1f;
2702      dst = i386_shift_rotate16(modrm, dst, shift);
2703      WRITE16(ea, dst);
2704   }
2705}
2706
2707void i386_device::i386_groupD1_16()        // Opcode 0xd1
2708{
2709   UINT16 dst;
2710   UINT8 modrm = FETCH();
2711
2712   if( modrm >= 0xc0 ) {
2713      dst = LOAD_RM16(modrm);
2714      dst = i386_shift_rotate16(modrm, dst, 1);
2715      STORE_RM16(modrm, dst);
2716   } else {
2717      UINT32 ea = GetEA(modrm,1);
2718      dst = READ16(ea);
2719      dst = i386_shift_rotate16(modrm, dst, 1);
2720      WRITE16(ea, dst);
2721   }
2722}
2723
2724void i386_device::i386_groupD3_16()        // Opcode 0xd3
2725{
2726   UINT16 dst;
2727   UINT8 modrm = FETCH();
2728
2729   if( modrm >= 0xc0 ) {
2730      dst = LOAD_RM16(modrm);
2731      dst = i386_shift_rotate16(modrm, dst, REG8(CL));
2732      STORE_RM16(modrm, dst);
2733   } else {
2734      UINT32 ea = GetEA(modrm,1);
2735      dst = READ16(ea);
2736      dst = i386_shift_rotate16(modrm, dst, REG8(CL));
2737      WRITE16(ea, dst);
2738   }
2739}
2740
2741void i386_device::i386_groupF7_16()        // Opcode 0xf7
2742{
2743   UINT8 modrm = FETCH();
2744
2745   switch( (modrm >> 3) & 0x7 )
2746   {
2747      case 0:         /* TEST Rm16, i16 */
2748         if( modrm >= 0xc0 ) {
2749            UINT16 dst = LOAD_RM16(modrm);
2750            UINT16 src = FETCH16();
2751            dst &= src;
2752            m_CF = m_OF = m_AF = 0;
2753            SetSZPF16(dst);
2754            CYCLES(CYCLES_TEST_IMM_REG);
2755         } else {
2756            UINT32 ea = GetEA(modrm,0);
2757            UINT16 dst = READ16(ea);
2758            UINT16 src = FETCH16();
2759            dst &= src;
2760            m_CF = m_OF = m_AF = 0;
2761            SetSZPF16(dst);
2762            CYCLES(CYCLES_TEST_IMM_MEM);
2763         }
2764         break;
2765      case 2:         /* NOT Rm16 */
2766         if( modrm >= 0xc0 ) {
2767            UINT16 dst = LOAD_RM16(modrm);
2768            dst = ~dst;
2769            STORE_RM16(modrm, dst);
2770            CYCLES(CYCLES_NOT_REG);
2771         } else {
2772            UINT32 ea = GetEA(modrm,1);
2773            UINT16 dst = READ16(ea);
2774            dst = ~dst;
2775            WRITE16(ea, dst);
2776            CYCLES(CYCLES_NOT_MEM);
2777         }
2778         break;
2779      case 3:         /* NEG Rm16 */
2780         if( modrm >= 0xc0 ) {
2781            UINT16 dst = LOAD_RM16(modrm);
2782            dst = SUB16(0, dst );
2783            STORE_RM16(modrm, dst);
2784            CYCLES(CYCLES_NEG_REG);
2785         } else {
2786            UINT32 ea = GetEA(modrm,1);
2787            UINT16 dst = READ16(ea);
2788            dst = SUB16(0, dst );
2789            WRITE16(ea, dst);
2790            CYCLES(CYCLES_NEG_MEM);
2791         }
2792         break;
2793      case 4:         /* MUL AX, Rm16 */
2794         {
2795            UINT32 result;
2796            UINT16 src, dst;
2797            if( modrm >= 0xc0 ) {
2798               src = LOAD_RM16(modrm);
2799               CYCLES(CYCLES_MUL16_ACC_REG);      /* TODO: Correct multiply timing */
2800            } else {
2801               UINT32 ea = GetEA(modrm,0);
2802               src = READ16(ea);
2803               CYCLES(CYCLES_MUL16_ACC_MEM);      /* TODO: Correct multiply timing */
2804            }
2805
2806            dst = REG16(AX);
2807            result = (UINT32)src * (UINT32)dst;
2808            REG16(DX) = (UINT16)(result >> 16);
2809            REG16(AX) = (UINT16)result;
2810
2811            m_CF = m_OF = (REG16(DX) != 0);
2812         }
2813         break;
2814      case 5:         /* IMUL AX, Rm16 */
2815         {
2816            INT32 result;
2817            INT32 src, dst;
2818            if( modrm >= 0xc0 ) {
2819               src = (INT32)(INT16)LOAD_RM16(modrm);
2820               CYCLES(CYCLES_IMUL16_ACC_REG);     /* TODO: Correct multiply timing */
2821            } else {
2822               UINT32 ea = GetEA(modrm,0);
2823               src = (INT32)(INT16)READ16(ea);
2824               CYCLES(CYCLES_IMUL16_ACC_MEM);     /* TODO: Correct multiply timing */
2825            }
2826
2827            dst = (INT32)(INT16)REG16(AX);
2828            result = src * dst;
2829
2830            REG16(DX) = (UINT16)(result >> 16);
2831            REG16(AX) = (UINT16)result;
2832
2833            m_CF = m_OF = !(result == (INT32)(INT16)result);
2834         }
2835         break;
2836      case 6:         /* DIV AX, Rm16 */
2837         {
2838            UINT32 quotient, remainder, result;
2839            UINT16 src;
2840            if( modrm >= 0xc0 ) {
2841               src = LOAD_RM16(modrm);
2842               CYCLES(CYCLES_DIV16_ACC_REG);
2843            } else {
2844               UINT32 ea = GetEA(modrm,0);
2845               src = READ16(ea);
2846               CYCLES(CYCLES_DIV16_ACC_MEM);
2847            }
2848
2849            quotient = ((UINT32)(REG16(DX)) << 16) | (UINT32)(REG16(AX));
2850            if( src ) {
2851               remainder = quotient % (UINT32)src;
2852               result = quotient / (UINT32)src;
2853               if( result > 0xffff ) {
2854                  /* TODO: Divide error */
2855               } else {
2856                  REG16(DX) = (UINT16)remainder;
2857                  REG16(AX) = (UINT16)result;
2858
2859                  // this flag is actually undefined, enable on non-cyrix
2860                  if (m_cpuid_id0 != 0x69727943)
2861                     m_CF = 1;
2862               }
2863            } else {
2864               i386_trap(0, 0, 0);
2865            }
2866         }
2867         break;
2868      case 7:         /* IDIV AX, Rm16 */
2869         {
2870            INT32 quotient, remainder, result;
2871            UINT16 src;
2872            if( modrm >= 0xc0 ) {
2873               src = LOAD_RM16(modrm);
2874               CYCLES(CYCLES_IDIV16_ACC_REG);
2875            } else {
2876               UINT32 ea = GetEA(modrm,0);
2877               src = READ16(ea);
2878               CYCLES(CYCLES_IDIV16_ACC_MEM);
2879            }
2880
2881            quotient = (((INT32)REG16(DX)) << 16) | ((UINT32)REG16(AX));
2882            if( src ) {
2883               remainder = quotient % (INT32)(INT16)src;
2884               result = quotient / (INT32)(INT16)src;
2885               if( result > 0xffff ) {
2886                  /* TODO: Divide error */
2887               } else {
2888                  REG16(DX) = (UINT16)remainder;
2889                  REG16(AX) = (UINT16)result;
2890
2891                  // this flag is actually undefined, enable on non-cyrix
2892                  if (m_cpuid_id0 != 0x69727943)
2893                     m_CF = 1;
2894               }
2895            } else {
2896               i386_trap(0, 0, 0);
2897            }
2898         }
2899         break;
2900   }
2901}
2902
2903void i386_device::i386_groupFF_16()        // Opcode 0xff
2904{
2905   UINT8 modrm = FETCH();
2906
2907   switch( (modrm >> 3) & 0x7 )
2908   {
2909      case 0:         /* INC Rm16 */
2910         if( modrm >= 0xc0 ) {
2911            UINT16 dst = LOAD_RM16(modrm);
2912            dst = INC16(dst);
2913            STORE_RM16(modrm, dst);
2914            CYCLES(CYCLES_INC_REG);
2915         } else {
2916            UINT32 ea = GetEA(modrm,1);
2917            UINT16 dst = READ16(ea);
2918            dst = INC16(dst);
2919            WRITE16(ea, dst);
2920            CYCLES(CYCLES_INC_MEM);
2921         }
2922         break;
2923      case 1:         /* DEC Rm16 */
2924         if( modrm >= 0xc0 ) {
2925            UINT16 dst = LOAD_RM16(modrm);
2926            dst = DEC16(dst);
2927            STORE_RM16(modrm, dst);
2928            CYCLES(CYCLES_DEC_REG);
2929         } else {
2930            UINT32 ea = GetEA(modrm,1);
2931            UINT16 dst = READ16(ea);
2932            dst = DEC16(dst);
2933            WRITE16(ea, dst);
2934            CYCLES(CYCLES_DEC_MEM);
2935         }
2936         break;
2937      case 2:         /* CALL Rm16 */
2938         {
2939            UINT16 address;
2940            if( modrm >= 0xc0 ) {
2941               address = LOAD_RM16(modrm);
2942               CYCLES(CYCLES_CALL_REG);       /* TODO: Timing = 7 + m */
2943            } else {
2944               UINT32 ea = GetEA(modrm,0);
2945               address = READ16(ea);
2946               CYCLES(CYCLES_CALL_MEM);       /* TODO: Timing = 10 + m */
2947            }
2948            PUSH16(m_eip );
2949            m_eip = address;
2950            CHANGE_PC(m_eip);
2951         }
2952         break;
2953      case 3:         /* CALL FAR Rm16 */
2954         {
2955            UINT16 address, selector;
2956            if( modrm >= 0xc0 )
2957            {
2958               report_invalid_modrm("groupFF_16", modrm);
2959            }
2960            else
2961            {
2962               UINT32 ea = GetEA(modrm,0);
2963               address = READ16(ea + 0);
2964               selector = READ16(ea + 2);
2965               CYCLES(CYCLES_CALL_MEM_INTERSEG);      /* TODO: Timing = 10 + m */
2966
2967               if(PROTECTED_MODE && !V8086_MODE)
2968               {
2969                  i386_protected_mode_call(selector,address,1,0);
2970               }
2971               else
2972               {
2973                  PUSH16(m_sreg[CS].selector );
2974                  PUSH16(m_eip );
2975                  m_sreg[CS].selector = selector;
2976                  m_performed_intersegment_jump = 1;
2977                  i386_load_segment_descriptor(CS );
2978                  m_eip = address;
2979                  CHANGE_PC(m_eip);
2980               }
2981            }
2982         }
2983         break;
2984      case 4:         /* JMP Rm16 */
2985         {
2986            UINT16 address;
2987            if( modrm >= 0xc0 ) {
2988               address = LOAD_RM16(modrm);
2989               CYCLES(CYCLES_JMP_REG);        /* TODO: Timing = 7 + m */
2990            } else {
2991               UINT32 ea = GetEA(modrm,0);
2992               address = READ16(ea);
2993               CYCLES(CYCLES_JMP_MEM);        /* TODO: Timing = 10 + m */
2994            }
2995            m_eip = address;
2996            CHANGE_PC(m_eip);
2997         }
2998         break;
2999      case 5:         /* JMP FAR Rm16 */
3000         {
3001            UINT16 address, selector;
3002
3003            if( modrm >= 0xc0 )
3004            {
3005               report_invalid_modrm("groupFF_16", modrm);
3006            }
3007            else
3008            {
3009               UINT32 ea = GetEA(modrm,0);
3010               address = READ16(ea + 0);
3011               selector = READ16(ea + 2);
3012               CYCLES(CYCLES_JMP_MEM_INTERSEG);       /* TODO: Timing = 10 + m */
3013               if(PROTECTED_MODE && !V8086_MODE)
3014               {
3015                  i386_protected_mode_jump(selector,address,1,0);
3016               }
3017               else
3018               {
3019                  m_sreg[CS].selector = selector;
3020                  m_performed_intersegment_jump = 1;
3021                  i386_load_segment_descriptor(CS );
3022                  m_eip = address;
3023                  CHANGE_PC(m_eip);
3024               }
3025            }
3026         }
3027         break;
3028      case 6:         /* PUSH Rm16 */
3029         {
3030            UINT16 value;
3031            if( modrm >= 0xc0 ) {
3032               value = LOAD_RM16(modrm);
3033            } else {
3034               UINT32 ea = GetEA(modrm,0);
3035               value = READ16(ea);
3036            }
3037            PUSH16(value);
3038            CYCLES(CYCLES_PUSH_RM);
3039         }
3040         break;
3041      default:
3042         report_invalid_modrm("groupFF_16", modrm);
3043         break;
3044   }
3045}
3046
3047void i386_device::i386_group0F00_16()          // Opcode 0x0f 00
3048{
3049   UINT32 address, ea;
3050   UINT8 modrm = FETCH();
3051   I386_SREG seg;
3052   UINT8 result;
3053
3054   switch( (modrm >> 3) & 0x7 )
3055   {
3056      case 0:         /* SLDT */
3057         if ( PROTECTED_MODE && !V8086_MODE )
3058         {
3059            if( modrm >= 0xc0 ) {
3060               STORE_RM16(modrm, m_ldtr.segment);
3061               CYCLES(CYCLES_SLDT_REG);
3062            } else {
3063               ea = GetEA(modrm,1);
3064               WRITE16(ea, m_ldtr.segment);
3065               CYCLES(CYCLES_SLDT_MEM);
3066            }
3067         }
3068         else
3069         {
3070            i386_trap(6, 0, 0);
3071         }
3072         break;
3073      case 1:         /* STR */
3074         if ( PROTECTED_MODE && !V8086_MODE )
3075         {
3076            if( modrm >= 0xc0 ) {
3077               STORE_RM16(modrm, m_task.segment);
3078               CYCLES(CYCLES_STR_REG);
3079            } else {
3080               ea = GetEA(modrm,1);
3081               WRITE16(ea, m_task.segment);
3082               CYCLES(CYCLES_STR_MEM);
3083            }
3084         }
3085         else
3086         {
3087            i386_trap(6, 0, 0);
3088         }
3089         break;
3090      case 2:         /* LLDT */
3091         if ( PROTECTED_MODE && !V8086_MODE )
3092         {
3093            if(m_CPL)
3094               FAULT(FAULT_GP,0)
3095            if( modrm >= 0xc0 ) {
3096               address = LOAD_RM16(modrm);
3097               m_ldtr.segment = address;
3098               CYCLES(CYCLES_LLDT_REG);
3099            } else {
3100               ea = GetEA(modrm,0);
3101               m_ldtr.segment = READ16(ea);
3102               CYCLES(CYCLES_LLDT_MEM);
3103            }
3104            memset(&seg, 0, sizeof(seg));
3105            seg.selector = m_ldtr.segment;
3106            i386_load_protected_mode_segment(&seg,NULL);
3107            m_ldtr.limit = seg.limit;
3108            m_ldtr.base = seg.base;
3109            m_ldtr.flags = seg.flags;
3110         }
3111         else
3112         {
3113            i386_trap(6, 0, 0);
3114         }
3115         break;
3116
3117      case 3:         /* LTR */
3118         if ( PROTECTED_MODE && !V8086_MODE )
3119         {
3120            if(m_CPL)
3121               FAULT(FAULT_GP,0)
3122            if( modrm >= 0xc0 ) {
3123               address = LOAD_RM16(modrm);
3124               m_task.segment = address;
3125               CYCLES(CYCLES_LTR_REG);
3126            } else {
3127               ea = GetEA(modrm,0);
3128               m_task.segment = READ16(ea);
3129               CYCLES(CYCLES_LTR_MEM);
3130            }
3131            memset(&seg, 0, sizeof(seg));
3132            seg.selector = m_task.segment;
3133            i386_load_protected_mode_segment(&seg,NULL);
3134            m_task.limit = seg.limit;
3135            m_task.base = seg.base;
3136            m_task.flags = seg.flags;
3137         }
3138         else
3139         {
3140            i386_trap(6, 0, 0);
3141         }
3142         break;
3143
3144      case 4:  /* VERR */
3145         if ( PROTECTED_MODE && !V8086_MODE )
3146         {
3147            result = 1;
3148            if( modrm >= 0xc0 ) {
3149               address = LOAD_RM16(modrm);
3150               CYCLES(CYCLES_VERR_REG);
3151            } else {
3152               ea = GetEA(modrm,0);
3153               address = READ16(ea);
3154               CYCLES(CYCLES_VERR_MEM);
3155            }
3156            memset(&seg, 0, sizeof(seg));
3157            seg.selector = address;
3158            result = i386_load_protected_mode_segment(&seg,NULL);
3159            // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3160            if(!(seg.flags & 0x10))
3161               result = 0;
3162            // check that the segment is readable
3163            if(seg.flags & 0x10)  // is code or data segment
3164            {
3165               if(seg.flags & 0x08)  // is code segment, so check if it's readable
3166               {
3167                  if(!(seg.flags & 0x02))
3168                  {
3169                     result = 0;
3170                  }
3171                  else
3172                  {  // check if conforming, these are always readable, regardless of privilege
3173                     if(!(seg.flags & 0x04))
3174                     {
3175                        // if not conforming, then we must check privilege levels (TODO: current privilege level check)
3176                        if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3177                           result = 0;
3178                     }
3179                  }
3180               }
3181            }
3182            // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3183            SetZF(result);
3184         }
3185         else
3186         {
3187            i386_trap(6, 0, 0);
3188            logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n");
3189         }
3190         break;
3191
3192      case 5:  /* VERW */
3193         if ( PROTECTED_MODE && !V8086_MODE )
3194         {
3195            result = 1;
3196            if( modrm >= 0xc0 ) {
3197               address = LOAD_RM16(modrm);
3198               CYCLES(CYCLES_VERW_REG);
3199            } else {
3200               ea = GetEA(modrm,0);
3201               address = READ16(ea);
3202               CYCLES(CYCLES_VERW_MEM);
3203            }
3204            memset(&seg, 0, sizeof(seg));
3205            seg.selector = address;
3206            result = i386_load_protected_mode_segment(&seg,NULL);
3207            // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3208            if(!(seg.flags & 0x10))
3209               result = 0;
3210            // check that the segment is writable
3211            if(seg.flags & 0x10)  // is code or data segment
3212            {
3213               if(seg.flags & 0x08)  // is code segment (and thus, not writable)
3214               {
3215                  result = 0;
3216               }
3217               else
3218               {  // is data segment
3219                  if(!(seg.flags & 0x02))
3220                     result = 0;
3221               }
3222            }
3223            // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3224            if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3225               result = 0;
3226            SetZF(result);
3227         }
3228         else
3229         {
3230            i386_trap(6, 0, 0);
3231            logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n");
3232         }
3233         break;
3234
3235      default:
3236         report_invalid_modrm("group0F00_16", modrm);
3237         break;
3238   }
3239}
3240
3241void i386_device::i386_group0F01_16()      // Opcode 0x0f 01
3242{
3243   UINT8 modrm = FETCH();
3244   UINT16 address;
3245   UINT32 ea;
3246
3247   switch( (modrm >> 3) & 0x7 )
3248   {
3249      case 0:         /* SGDT */
3250         {
3251            if( modrm >= 0xc0 ) {
3252               address = LOAD_RM16(modrm);
3253               ea = i386_translate(CS, address, 1 );
3254            } else {
3255               ea = GetEA(modrm,1);
3256            }
3257            WRITE16(ea, m_gdtr.limit);
3258            WRITE32(ea + 2, m_gdtr.base & 0xffffff);
3259            CYCLES(CYCLES_SGDT);
3260            break;
3261         }
3262      case 1:         /* SIDT */
3263         {
3264            if (modrm >= 0xc0)
3265            {
3266               address = LOAD_RM16(modrm);
3267               ea = i386_translate(CS, address, 1 );
3268            }
3269            else
3270            {
3271               ea = GetEA(modrm,1);
3272            }
3273            WRITE16(ea, m_idtr.limit);
3274            WRITE32(ea + 2, m_idtr.base & 0xffffff);
3275            CYCLES(CYCLES_SIDT);
3276            break;
3277         }
3278      case 2:         /* LGDT */
3279         {
3280            if(PROTECTED_MODE && m_CPL)
3281               FAULT(FAULT_GP,0)
3282            if( modrm >= 0xc0 ) {
3283               address = LOAD_RM16(modrm);
3284               ea = i386_translate(CS, address, 0 );
3285            } else {
3286               ea = GetEA(modrm,0);
3287            }
3288            m_gdtr.limit = READ16(ea);
3289            m_gdtr.base = READ32(ea + 2) & 0xffffff;
3290            CYCLES(CYCLES_LGDT);
3291            break;
3292         }
3293      case 3:         /* LIDT */
3294         {
3295            if(PROTECTED_MODE && m_CPL)
3296               FAULT(FAULT_GP,0)
3297            if( modrm >= 0xc0 ) {
3298               address = LOAD_RM16(modrm);
3299               ea = i386_translate(CS, address, 0 );
3300            } else {
3301               ea = GetEA(modrm,0);
3302            }
3303            m_idtr.limit = READ16(ea);
3304            m_idtr.base = READ32(ea + 2) & 0xffffff;
3305            CYCLES(CYCLES_LIDT);
3306            break;
3307         }
3308      case 4:         /* SMSW */
3309         {
3310            if( modrm >= 0xc0 ) {
3311               STORE_RM16(modrm, m_cr[0]);
3312               CYCLES(CYCLES_SMSW_REG);
3313            } else {
3314               ea = GetEA(modrm,1);
3315               WRITE16(ea, m_cr[0]);
3316               CYCLES(CYCLES_SMSW_MEM);
3317            }
3318            break;
3319         }
3320      case 6:         /* LMSW */
3321         {
3322            if(PROTECTED_MODE && m_CPL)
3323               FAULT(FAULT_GP,0)
3324            UINT16 b;
3325            if( modrm >= 0xc0 ) {
3326               b = LOAD_RM16(modrm);
3327               CYCLES(CYCLES_LMSW_REG);
3328            } else {
3329               ea = GetEA(modrm,0);
3330               CYCLES(CYCLES_LMSW_MEM);
3331            b = READ16(ea);
3332            }
3333            if(PROTECTED_MODE)
3334               b |= 0x0001;  // cannot return to real mode using this instruction.
3335            m_cr[0] &= ~0x0000000f;
3336            m_cr[0] |= b & 0x0000000f;
3337            break;
3338         }
3339      default:
3340         report_invalid_modrm("group0F01_16", modrm);
3341         break;
3342   }
3343}
3344
3345void i386_device::i386_group0FBA_16()      // Opcode 0x0f ba
3346{
3347   UINT8 modrm = FETCH();
3348
3349   switch( (modrm >> 3) & 0x7 )
3350   {
3351      case 4:         /* BT Rm16, i8 */
3352         if( modrm >= 0xc0 ) {
3353            UINT16 dst = LOAD_RM16(modrm);
3354            UINT8 bit = FETCH();
3355
3356            if( dst & (1 << bit) )
3357               m_CF = 1;
3358            else
3359               m_CF = 0;
3360
3361            CYCLES(CYCLES_BT_IMM_REG);
3362         } else {
3363            UINT32 ea = GetEA(modrm,0);
3364            UINT16 dst = READ16(ea);
3365            UINT8 bit = FETCH();
3366
3367            if( dst & (1 << bit) )
3368               m_CF = 1;
3369            else
3370               m_CF = 0;
3371
3372            CYCLES(CYCLES_BT_IMM_MEM);
3373         }
3374         break;
3375      case 5:         /* BTS Rm16, i8 */
3376         if( modrm >= 0xc0 ) {
3377            UINT16 dst = LOAD_RM16(modrm);
3378            UINT8 bit = FETCH();
3379
3380            if( dst & (1 << bit) )
3381               m_CF = 1;
3382            else
3383               m_CF = 0;
3384            dst |= (1 << bit);
3385
3386            STORE_RM16(modrm, dst);
3387            CYCLES(CYCLES_BTS_IMM_REG);
3388         } else {
3389            UINT32 ea = GetEA(modrm,1);
3390            UINT16 dst = READ16(ea);
3391            UINT8 bit = FETCH();
3392
3393            if( dst & (1 << bit) )
3394               m_CF = 1;
3395            else
3396               m_CF = 0;
3397            dst |= (1 << bit);
3398
3399            WRITE16(ea, dst);
3400            CYCLES(CYCLES_BTS_IMM_MEM);
3401         }
3402         break;
3403      case 6:         /* BTR Rm16, i8 */
3404         if( modrm >= 0xc0 ) {
3405            UINT16 dst = LOAD_RM16(modrm);
3406            UINT8 bit = FETCH();
3407
3408            if( dst & (1 << bit) )
3409               m_CF = 1;
3410            else
3411               m_CF = 0;
3412            dst &= ~(1 << bit);
3413
3414            STORE_RM16(modrm, dst);
3415            CYCLES(CYCLES_BTR_IMM_REG);
3416         } else {
3417            UINT32 ea = GetEA(modrm,1);
3418            UINT16 dst = READ16(ea);
3419            UINT8 bit = FETCH();
3420
3421            if( dst & (1 << bit) )
3422               m_CF = 1;
3423            else
3424               m_CF = 0;
3425            dst &= ~(1 << bit);
3426
3427            WRITE16(ea, dst);
3428            CYCLES(CYCLES_BTR_IMM_MEM);
3429         }
3430         break;
3431      case 7:         /* BTC Rm16, i8 */
3432         if( modrm >= 0xc0 ) {
3433            UINT16 dst = LOAD_RM16(modrm);
3434            UINT8 bit = FETCH();
3435
3436            if( dst & (1 << bit) )
3437               m_CF = 1;
3438            else
3439               m_CF = 0;
3440            dst ^= (1 << bit);
3441
3442            STORE_RM16(modrm, dst);
3443            CYCLES(CYCLES_BTC_IMM_REG);
3444         } else {
3445            UINT32 ea = GetEA(modrm,1);
3446            UINT16 dst = READ16(ea);
3447            UINT8 bit = FETCH();
3448
3449            if( dst & (1 << bit) )
3450               m_CF = 1;
3451            else
3452               m_CF = 0;
3453            dst ^= (1 << bit);
3454
3455            WRITE16(ea, dst);
3456            CYCLES(CYCLES_BTC_IMM_MEM);
3457         }
3458         break;
3459      default:
3460         report_invalid_modrm("group0FBA_16", modrm);
3461         break;
3462   }
3463}
3464
3465void i386_device::i386_lar_r16_rm16()  // Opcode 0x0f 0x02
3466{
3467   UINT8 modrm = FETCH();
3468   I386_SREG seg;
3469   UINT8 type;
3470
3471   if(PROTECTED_MODE && !V8086_MODE)
3472   {
3473      memset(&seg,0,sizeof(seg));
3474      if(modrm >= 0xc0)
3475      {
3476         seg.selector = LOAD_RM16(modrm);
3477         CYCLES(CYCLES_LAR_REG);
3478      }
3479      else
3480      {
3481         UINT32 ea = GetEA(modrm,0);
3482         seg.selector = READ16(ea);
3483         CYCLES(CYCLES_LAR_MEM);
3484      }
3485      if(seg.selector == 0)
3486      {
3487         SetZF(0);  // not a valid segment
3488      //  logerror("i386 (%08x): LAR: Selector %04x is invalid type.\n",m_pc,seg.selector);
3489      }
3490      else
3491      {
3492         if(!i386_load_protected_mode_segment(&seg,NULL))
3493         {
3494            SetZF(0);
3495            return;
3496         }
3497         UINT8 DPL = (seg.flags >> 5) & 3;
3498         if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3499         {
3500            SetZF(0);
3501            return;
3502         }
3503         if(!(seg.flags & 0x10))  // special segment
3504         {
3505            // check for invalid segment types
3506            type = seg.flags & 0x000f;
3507            if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d)
3508            {
3509               SetZF(0);  // invalid segment type
3510            }
3511            else
3512            {
3513               STORE_REG16(modrm,(seg.flags << 8) & 0xff00);
3514               SetZF(1);
3515            }
3516         }
3517         else
3518         {  // data or code segment (both are valid for LAR)
3519            STORE_REG16(modrm,(seg.flags << 8) & 0xff00);
3520            SetZF(1);
3521         }
3522      }
3523   }
3524   else
3525   {
3526      // illegal opcode
3527      i386_trap(6,0, 0);
3528      logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n");
3529   }
3530}
3531
3532void i386_device::i386_lsl_r16_rm16()  // Opcode 0x0f 0x03
3533{
3534   UINT8 modrm = FETCH();
3535   UINT32 limit;
3536   I386_SREG seg;
3537
3538   if(PROTECTED_MODE && !V8086_MODE)
3539   {
3540      memset(&seg, 0, sizeof(seg));
3541      if(modrm >= 0xc0)
3542      {
3543         seg.selector = LOAD_RM16(modrm);
3544      }
3545      else
3546      {
3547         UINT32 ea = GetEA(modrm,0);
3548         seg.selector = READ16(ea);
3549      }
3550      if(seg.selector == 0)
3551      {
3552         SetZF(0);  // not a valid segment
3553      }
3554      else
3555      {
3556         UINT8 type;
3557         if(!i386_load_protected_mode_segment(&seg,NULL))
3558         {
3559            SetZF(0);
3560            return;
3561         }
3562         UINT8 DPL = (seg.flags >> 5) & 3;
3563         if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3564         {
3565            SetZF(0);
3566            return;
3567         }
3568         type = seg.flags & 0x1f;
3569         switch(type)
3570         {
3571         case 0:
3572         case 4:
3573         case 5:
3574         case 6:
3575         case 7:
3576         case 8:
3577         case 10:
3578         case 12:
3579         case 13:
3580         case 14:
3581         case 15:
3582            SetZF(0);
3583            return;
3584         default:
3585            limit = seg.limit;
3586            STORE_REG16(modrm,limit & 0x0000ffff);
3587            SetZF(1);
3588         }
3589      }
3590   }
3591   else
3592      i386_trap(6, 0, 0);
3593}
3594
3595void i386_device::i386_bound_r16_m16_m16() // Opcode 0x62
3596{
3597   UINT8 modrm;
3598   INT16 val, low, high;
3599
3600   modrm = FETCH();
3601
3602   if (modrm >= 0xc0)
3603   {
3604      low = high = LOAD_RM16(modrm);
3605   }
3606   else
3607   {
3608      UINT32 ea = GetEA(modrm,0);
3609      low = READ16(ea + 0);
3610      high = READ16(ea + 2);
3611   }
3612   val = LOAD_REG16(modrm);
3613
3614   if ((val < low) || (val > high))
3615   {
3616      CYCLES(CYCLES_BOUND_OUT_RANGE);
3617      i386_trap(5, 0, 0);
3618   }
3619   else
3620   {
3621      CYCLES(CYCLES_BOUND_IN_RANGE);
3622   }
3623}
3624
3625void i386_device::i386_retf16()            // Opcode 0xcb
3626{
3627   if(PROTECTED_MODE && !V8086_MODE)
3628   {
3629      i386_protected_mode_retf(0,0);
3630   }
3631   else
3632   {
3633      m_eip = POP16();
3634      m_sreg[CS].selector = POP16();
3635      i386_load_segment_descriptor(CS );
3636      CHANGE_PC(m_eip);
3637   }
3638
3639   CYCLES(CYCLES_RET_INTERSEG);
3640}
3641
3642void i386_device::i386_retf_i16()          // Opcode 0xca
3643{
3644   UINT16 count = FETCH16();
3645
3646   if(PROTECTED_MODE && !V8086_MODE)
3647   {
3648      i386_protected_mode_retf(count,0);
3649   }
3650   else
3651   {
3652      m_eip = POP16();
3653      m_sreg[CS].selector = POP16();
3654      i386_load_segment_descriptor(CS );
3655      CHANGE_PC(m_eip);
3656      REG16(SP) += count;
3657   }
3658
3659   CYCLES(CYCLES_RET_IMM_INTERSEG);
3660}
3661
3662bool i386_device::i386_load_far_pointer16(int s)
3663{
3664   UINT8 modrm = FETCH();
3665   UINT16 selector;
3666
3667   if( modrm >= 0xc0 ) {
3668      //logerror("i386: load_far_pointer16 NYI\n"); // don't log, NT will use this a lot
3669      i386_trap(6, 0, 0);
3670      return false;
3671   } else {
3672      UINT32 ea = GetEA(modrm,0);
3673      STORE_REG16(modrm, READ16(ea + 0));
3674      selector = READ16(ea + 2);
3675      i386_sreg_load(selector,s,NULL);
3676   }
3677   return true;
3678}
3679
3680void i386_device::i386_lds16()             // Opcode 0xc5
3681{
3682   if(i386_load_far_pointer16(DS))
3683      CYCLES(CYCLES_LDS);
3684}
3685
3686void i386_device::i386_lss16()             // Opcode 0x0f 0xb2
3687{
3688   if(i386_load_far_pointer16(SS))
3689      CYCLES(CYCLES_LSS);
3690}
3691
3692void i386_device::i386_les16()             // Opcode 0xc4
3693{
3694   if(i386_load_far_pointer16(ES))
3695      CYCLES(CYCLES_LES);
3696}
3697
3698void i386_device::i386_lfs16()             // Opcode 0x0f 0xb4
3699{
3700   if(i386_load_far_pointer16(FS))
3701      CYCLES(CYCLES_LFS);
3702}
3703
3704void i386_device::i386_lgs16()             // Opcode 0x0f 0xb5
3705{
3706   if(i386_load_far_pointer16(GS))
3707      CYCLES(CYCLES_LGS);
3708}
trunk/src/emu/cpu/i386/pentops.c
r28738r28739
1// Pentium+ specific opcodes
2
3extern flag float32_is_nan( float32 a ); // since its not defined in softfloat.h
4
5void i386_device::MMXPROLOG()
6{
7   //m_x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT); // top = 0
8   m_x87_tw = 0; // tag word = 0
9}
10
11void i386_device::READMMX(UINT32 ea,MMX_REG &r)
12{
13   r.q=READ64(ea);
14}
15
16void i386_device::WRITEMMX(UINT32 ea,MMX_REG &r)
17{
18   WRITE64(ea, r.q);
19}
20
21void i386_device::READXMM(UINT32 ea,XMM_REG &r)
22{
23   r.q[0]=READ64(ea);
24   r.q[1]=READ64(ea+8);
25}
26
27void i386_device::WRITEXMM(UINT32 ea,i386_device::XMM_REG &r)
28{
29   WRITE64(ea, r.q[0]);
30   WRITE64(ea+8, r.q[1]);
31}
32
33void i386_device::READXMM_LO64(UINT32 ea,i386_device::XMM_REG &r)
34{
35   r.q[0]=READ64(ea);
36}
37
38void i386_device::WRITEXMM_LO64(UINT32 ea,i386_device::XMM_REG &r)
39{
40   WRITE64(ea, r.q[0]);
41}
42
43void i386_device::READXMM_HI64(UINT32 ea,i386_device::XMM_REG &r)
44{
45   r.q[1]=READ64(ea);
46}
47
48void i386_device::WRITEXMM_HI64(UINT32 ea,i386_device::XMM_REG &r)
49{
50   WRITE64(ea, r.q[1]);
51}
52
53void i386_device::pentium_rdmsr()          // Opcode 0x0f 32
54{
55   UINT64 data;
56   UINT8 valid_msr = 0;
57
58   data = MSR_READ(REG32(ECX),&valid_msr);
59   REG32(EDX) = data >> 32;
60   REG32(EAX) = data & 0xffffffff;
61
62   if(m_CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized ...
63      FAULT(FAULT_GP,0) // ... throw a general exception fault
64
65   CYCLES(CYCLES_RDMSR);
66}
67
68void i386_device::pentium_wrmsr()          // Opcode 0x0f 30
69{
70   UINT64 data;
71   UINT8 valid_msr = 0;
72
73   data = (UINT64)REG32(EAX);
74   data |= (UINT64)(REG32(EDX)) << 32;
75
76   MSR_WRITE(REG32(ECX),data,&valid_msr);
77
78   if(m_CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized
79      FAULT(FAULT_GP,0) // ... throw a general exception fault
80
81   CYCLES(1);     // TODO: correct cycle count (~30-45)
82}
83
84void i386_device::pentium_rdtsc()          // Opcode 0x0f 31
85{
86   UINT64 ts = m_tsc + (m_base_cycles - m_cycles);
87   REG32(EAX) = (UINT32)(ts);
88   REG32(EDX) = (UINT32)(ts >> 32);
89
90   CYCLES(CYCLES_RDTSC);
91}
92
93void i386_device::pentium_ud2()    // Opcode 0x0f 0b
94{
95   i386_trap(6, 0, 0);
96}
97
98void i386_device::pentium_rsm()
99{
100   UINT32 smram_state = m_smbase + 0xfe00;
101   if(!m_smm)
102   {
103      logerror("i386: Invalid RSM outside SMM at %08X\n", m_pc - 1);
104      i386_trap(6, 0, 0);
105      return;
106   }
107
108   // load state, no sanity checks anywhere
109   m_smbase = READ32(smram_state+SMRAM_SMBASE);
110   m_cr[4] = READ32(smram_state+SMRAM_IP5_CR4);
111   m_sreg[ES].limit = READ32(smram_state+SMRAM_IP5_ESLIM);
112   m_sreg[ES].base = READ32(smram_state+SMRAM_IP5_ESBASE);
113   m_sreg[ES].flags = READ32(smram_state+SMRAM_IP5_ESACC);
114   m_sreg[CS].limit = READ32(smram_state+SMRAM_IP5_CSLIM);
115   m_sreg[CS].base = READ32(smram_state+SMRAM_IP5_CSBASE);
116   m_sreg[CS].flags = READ32(smram_state+SMRAM_IP5_CSACC);
117   m_sreg[SS].limit = READ32(smram_state+SMRAM_IP5_SSLIM);
118   m_sreg[SS].base = READ32(smram_state+SMRAM_IP5_SSBASE);
119   m_sreg[SS].flags = READ32(smram_state+SMRAM_IP5_SSACC);
120   m_sreg[DS].limit = READ32(smram_state+SMRAM_IP5_DSLIM);
121   m_sreg[DS].base = READ32(smram_state+SMRAM_IP5_DSBASE);
122   m_sreg[DS].flags = READ32(smram_state+SMRAM_IP5_DSACC);
123   m_sreg[FS].limit = READ32(smram_state+SMRAM_IP5_FSLIM);
124   m_sreg[FS].base = READ32(smram_state+SMRAM_IP5_FSBASE);
125   m_sreg[FS].flags = READ32(smram_state+SMRAM_IP5_FSACC);
126   m_sreg[GS].limit = READ32(smram_state+SMRAM_IP5_GSLIM);
127   m_sreg[GS].base = READ32(smram_state+SMRAM_IP5_GSBASE);
128   m_sreg[GS].flags = READ32(smram_state+SMRAM_IP5_GSACC);
129   m_ldtr.flags = READ32(smram_state+SMRAM_IP5_LDTACC);
130   m_ldtr.limit = READ32(smram_state+SMRAM_IP5_LDTLIM);
131   m_ldtr.base = READ32(smram_state+SMRAM_IP5_LDTBASE);
132   m_gdtr.limit = READ32(smram_state+SMRAM_IP5_GDTLIM);
133   m_gdtr.base = READ32(smram_state+SMRAM_IP5_GDTBASE);
134   m_idtr.limit = READ32(smram_state+SMRAM_IP5_IDTLIM);
135   m_idtr.base = READ32(smram_state+SMRAM_IP5_IDTBASE);
136   m_task.limit = READ32(smram_state+SMRAM_IP5_TRLIM);
137   m_task.base = READ32(smram_state+SMRAM_IP5_TRBASE);
138   m_task.flags = READ32(smram_state+SMRAM_IP5_TRACC);
139
140   m_sreg[ES].selector = READ32(smram_state+SMRAM_ES);
141   m_sreg[CS].selector = READ32(smram_state+SMRAM_CS);
142   m_sreg[SS].selector = READ32(smram_state+SMRAM_SS);
143   m_sreg[DS].selector = READ32(smram_state+SMRAM_DS);
144   m_sreg[FS].selector = READ32(smram_state+SMRAM_FS);
145   m_sreg[GS].selector = READ32(smram_state+SMRAM_GS);
146   m_ldtr.segment = READ32(smram_state+SMRAM_LDTR);
147   m_task.segment = READ32(smram_state+SMRAM_TR);
148
149   m_dr[7] = READ32(smram_state+SMRAM_DR7);
150   m_dr[6] = READ32(smram_state+SMRAM_DR6);
151   REG32(EAX) = READ32(smram_state+SMRAM_EAX);
152   REG32(ECX) = READ32(smram_state+SMRAM_ECX);
153   REG32(EDX) = READ32(smram_state+SMRAM_EDX);
154   REG32(EBX) = READ32(smram_state+SMRAM_EBX);
155   REG32(ESP) = READ32(smram_state+SMRAM_ESP);
156   REG32(EBP) = READ32(smram_state+SMRAM_EBP);
157   REG32(ESI) = READ32(smram_state+SMRAM_ESI);
158   REG32(EDI) = READ32(smram_state+SMRAM_EDI);
159   m_eip = READ32(smram_state+SMRAM_EIP);
160   m_eflags = READ32(smram_state+SMRAM_EAX);
161   m_cr[3] = READ32(smram_state+SMRAM_CR3);
162   m_cr[0] = READ32(smram_state+SMRAM_CR0);
163
164   m_CPL = (m_sreg[SS].flags >> 13) & 3; // cpl == dpl of ss
165
166   for(int i = 0; i < GS; i++)
167   {
168      if(PROTECTED_MODE && !V8086_MODE)
169      {
170         m_sreg[i].valid = m_sreg[i].selector ? true : false;
171         m_sreg[i].d = (m_sreg[i].flags & 0x4000) ? 1 : 0;
172      }
173      else
174         m_sreg[i].valid = true;
175   }
176
177   if(!m_smiact.isnull())
178      m_smiact(false);
179   m_smm = false;
180
181   CHANGE_PC(m_eip);
182   m_nmi_masked = false;
183   if(m_smi_latched)
184   {
185      pentium_smi();
186      return;
187   }
188   if(m_nmi_latched)
189   {
190      m_nmi_latched = false;
191      i386_trap(2, 1, 0);
192   }
193}
194
195void i386_device::pentium_prefetch_m8()    // Opcode 0x0f 18
196{
197   UINT8 modrm = FETCH();
198   UINT32 ea = GetEA(modrm,0);
199   CYCLES(1+(ea & 1)); // TODO: correct cycle count
200}
201
202void i386_device::pentium_cmovo_r16_rm16()    // Opcode 0x0f 40
203{
204   UINT16 src;
205   UINT8 modrm = FETCH();
206
207   if( modrm >= 0xc0 )
208   {
209      if (m_OF == 1)
210      {
211         src = LOAD_RM16(modrm);
212         STORE_REG16(modrm, src);
213      }
214      CYCLES(1); // TODO: correct cycle count
215   }
216   else
217   {
218      UINT32 ea = GetEA(modrm,0);
219      if (m_OF == 1)
220      {
221         src = READ16(ea);
222         STORE_REG16(modrm, src);
223      }
224      CYCLES(1); // TODO: correct cycle count
225   }
226}
227
228void i386_device::pentium_cmovo_r32_rm32()    // Opcode 0x0f 40
229{
230   UINT32 src;
231   UINT8 modrm = FETCH();
232
233   if( modrm >= 0xc0 )
234   {
235      if (m_OF == 1)
236      {
237         src = LOAD_RM32(modrm);
238         STORE_REG32(modrm, src);
239      }
240      CYCLES(1); // TODO: correct cycle count
241   }
242   else
243   {
244      UINT32 ea = GetEA(modrm,0);
245      if (m_OF == 1)
246      {
247         src = READ32(ea);
248         STORE_REG32(modrm, src);
249      }
250      CYCLES(1); // TODO: correct cycle count
251   }
252}
253
254void i386_device::pentium_cmovno_r16_rm16()    // Opcode 0x0f 41
255{
256   UINT16 src;
257   UINT8 modrm = FETCH();
258
259   if( modrm >= 0xc0 )
260   {
261      if (m_OF == 0)
262      {
263         src = LOAD_RM16(modrm);
264         STORE_REG16(modrm, src);
265      }
266      CYCLES(1); // TODO: correct cycle count
267   }
268   else
269   {
270      UINT32 ea = GetEA(modrm,0);
271      if (m_OF == 0)
272      {
273         src = READ16(ea);
274         STORE_REG16(modrm, src);
275      }
276      CYCLES(1); // TODO: correct cycle count
277   }
278}
279
280void i386_device::pentium_cmovno_r32_rm32()    // Opcode 0x0f 41
281{
282   UINT32 src;
283   UINT8 modrm = FETCH();
284
285   if( modrm >= 0xc0 )
286   {
287      if (m_OF == 0)
288      {
289         src = LOAD_RM32(modrm);
290         STORE_REG32(modrm, src);
291      }
292      CYCLES(1); // TODO: correct cycle count
293   }
294   else
295   {
296      UINT32 ea = GetEA(modrm,0);
297      if (m_OF == 0)
298      {
299         src = READ32(ea);
300         STORE_REG32(modrm, src);
301      }
302      CYCLES(1); // TODO: correct cycle count
303   }
304}
305
306void i386_device::pentium_cmovb_r16_rm16()    // Opcode 0x0f 42
307{
308   UINT16 src;
309   UINT8 modrm = FETCH();
310
311   if( modrm >= 0xc0 )
312   {
313      if (m_CF == 1)
314      {
315         src = LOAD_RM16(modrm);
316         STORE_REG16(modrm, src);
317      }
318      CYCLES(1); // TODO: correct cycle count
319   }
320   else
321   {
322      UINT32 ea = GetEA(modrm,0);
323      if (m_CF == 1)
324      {
325         src = READ16(ea);
326         STORE_REG16(modrm, src);
327      }
328      CYCLES(1); // TODO: correct cycle count
329   }
330}
331
332void i386_device::pentium_cmovb_r32_rm32()    // Opcode 0x0f 42
333{
334   UINT32 src;
335   UINT8 modrm = FETCH();
336
337   if( modrm >= 0xc0 )
338   {
339      if (m_CF == 1)
340      {
341         src = LOAD_RM32(modrm);
342         STORE_REG32(modrm, src);
343      }
344      CYCLES(1); // TODO: correct cycle count
345   }
346   else
347   {
348      UINT32 ea = GetEA(modrm,0);
349      if (m_CF == 1)
350      {
351         src = READ32(ea);
352         STORE_REG32(modrm, src);
353      }
354      CYCLES(1); // TODO: correct cycle count
355   }
356}
357
358void i386_device::pentium_cmovae_r16_rm16()    // Opcode 0x0f 43
359{
360   UINT16 src;
361   UINT8 modrm = FETCH();
362
363   if( modrm >= 0xc0 )
364   {
365      if (m_CF == 0)
366      {
367         src = LOAD_RM16(modrm);
368         STORE_REG16(modrm, src);
369      }
370      CYCLES(1); // TODO: correct cycle count
371   }
372   else
373   {
374      UINT32 ea = GetEA(modrm,0);
375      if (m_CF == 0)
376      {
377         src = READ16(ea);
378         STORE_REG16(modrm, src);
379      }
380      CYCLES(1); // TODO: correct cycle count
381   }
382}
383
384void i386_device::pentium_cmovae_r32_rm32()    // Opcode 0x0f 43
385{
386   UINT32 src;
387   UINT8 modrm = FETCH();
388
389   if( modrm >= 0xc0 )
390   {
391      if (m_CF == 0)
392      {
393         src = LOAD_RM32(modrm);
394         STORE_REG32(modrm, src);
395      }
396      CYCLES(1); // TODO: correct cycle count
397   }
398   else
399   {
400      UINT32 ea = GetEA(modrm,0);
401      if (m_CF == 0)
402      {
403         src = READ32(ea);
404         STORE_REG32(modrm, src);
405      }
406      CYCLES(1); // TODO: correct cycle count
407   }
408}
409
410void i386_device::pentium_cmove_r16_rm16()    // Opcode 0x0f 44
411{
412   UINT16 src;
413   UINT8 modrm = FETCH();
414
415   if( modrm >= 0xc0 )
416   {
417      if (m_ZF == 1)
418      {
419         src = LOAD_RM16(modrm);
420         STORE_REG16(modrm, src);
421      }
422      CYCLES(1); // TODO: correct cycle count
423   }
424   else
425   {
426      UINT32 ea = GetEA(modrm,0);
427      if (m_ZF == 1)
428      {
429         src = READ16(ea);
430         STORE_REG16(modrm, src);
431      }
432      CYCLES(1); // TODO: correct cycle count
433   }
434}
435
436void i386_device::pentium_cmove_r32_rm32()    // Opcode 0x0f 44
437{
438   UINT32 src;
439   UINT8 modrm = FETCH();
440
441   if( modrm >= 0xc0 )
442   {
443      if (m_ZF == 1)
444      {
445         src = LOAD_RM32(modrm);
446         STORE_REG32(modrm, src);
447      }
448      CYCLES(1); // TODO: correct cycle count
449   }
450   else
451   {
452      UINT32 ea = GetEA(modrm,0);
453      if (m_ZF == 1)
454      {
455         src = READ32(ea);
456         STORE_REG32(modrm, src);
457      }
458      CYCLES(1); // TODO: correct cycle count
459   }
460}
461
462void i386_device::pentium_cmovne_r16_rm16()    // Opcode 0x0f 45
463{
464   UINT16 src;
465   UINT8 modrm = FETCH();
466
467   if( modrm >= 0xc0 )
468   {
469      if (m_ZF == 0)
470      {
471         src = LOAD_RM16(modrm);
472         STORE_REG16(modrm, src);
473      }
474      CYCLES(1); // TODO: correct cycle count
475   }
476   else
477   {
478      UINT32 ea = GetEA(modrm,0);
479      if (m_ZF == 0)
480      {
481         src = READ16(ea);
482         STORE_REG16(modrm, src);
483      }
484      CYCLES(1); // TODO: correct cycle count
485   }
486}
487
488void i386_device::pentium_cmovne_r32_rm32()    // Opcode 0x0f 45
489{
490   UINT32 src;
491   UINT8 modrm = FETCH();
492
493   if( modrm >= 0xc0 )
494   {
495      if (m_ZF == 0)
496      {
497         src = LOAD_RM32(modrm);
498         STORE_REG32(modrm, src);
499      }
500      CYCLES(1); // TODO: correct cycle count
501   }
502   else
503   {
504      UINT32 ea = GetEA(modrm,0);
505      if (m_ZF == 0)
506      {
507         src = READ32(ea);
508         STORE_REG32(modrm, src);
509      }
510      CYCLES(1); // TODO: correct cycle count
511   }
512}
513
514void i386_device::pentium_cmovbe_r16_rm16()    // Opcode 0x0f 46
515{
516   UINT16 src;
517   UINT8 modrm = FETCH();
518
519   if( modrm >= 0xc0 )
520   {
521      if ((m_CF == 1) || (m_ZF == 1))
522      {
523         src = LOAD_RM16(modrm);
524         STORE_REG16(modrm, src);
525      }
526      CYCLES(1); // TODO: correct cycle count
527   }
528   else
529   {
530      UINT32 ea = GetEA(modrm,0);
531      if ((m_CF == 1) || (m_ZF == 1))
532      {
533         src = READ16(ea);
534         STORE_REG16(modrm, src);
535      }
536      CYCLES(1); // TODO: correct cycle count
537   }
538}
539
540void i386_device::pentium_cmovbe_r32_rm32()    // Opcode 0x0f 46
541{
542   UINT32 src;
543   UINT8 modrm = FETCH();
544
545   if( modrm >= 0xc0 )
546   {
547      if ((m_CF == 1) || (m_ZF == 1))
548      {
549         src = LOAD_RM32(modrm);
550         STORE_REG32(modrm, src);
551      }
552      CYCLES(1); // TODO: correct cycle count
553   }
554   else
555   {
556      UINT32 ea = GetEA(modrm,0);
557      if ((m_CF == 1) || (m_ZF == 1))
558      {
559         src = READ32(ea);
560         STORE_REG32(modrm, src);
561      }
562      CYCLES(1); // TODO: correct cycle count
563   }
564}
565
566void i386_device::pentium_cmova_r16_rm16()    // Opcode 0x0f 47
567{
568   UINT16 src;
569   UINT8 modrm = FETCH();
570
571   if( modrm >= 0xc0 )
572   {
573      if ((m_CF == 0) && (m_ZF == 0))
574      {
575         src = LOAD_RM16(modrm);
576         STORE_REG16(modrm, src);
577      }
578      CYCLES(1); // TODO: correct cycle count
579   }
580   else
581   {
582      UINT32 ea = GetEA(modrm,0);
583      if ((m_CF == 0) && (m_ZF == 0))
584      {
585         src = READ16(ea);
586         STORE_REG16(modrm, src);
587      }
588      CYCLES(1); // TODO: correct cycle count
589   }
590}
591
592void i386_device::pentium_cmova_r32_rm32()    // Opcode 0x0f 47
593{
594   UINT32 src;
595   UINT8 modrm = FETCH();
596
597   if( modrm >= 0xc0 )
598   {
599      if ((m_CF == 0) && (m_ZF == 0))
600      {
601         src = LOAD_RM32(modrm);
602         STORE_REG32(modrm, src);
603      }
604      CYCLES(1); // TODO: correct cycle count
605   }
606   else
607   {
608      UINT32 ea = GetEA(modrm,0);
609      if ((m_CF == 0) && (m_ZF == 0))
610      {
611         src = READ32(ea);
612         STORE_REG32(modrm, src);
613      }
614      CYCLES(1); // TODO: correct cycle count
615   }
616}
617
618void i386_device::pentium_cmovs_r16_rm16()    // Opcode 0x0f 48
619{
620   UINT16 src;
621   UINT8 modrm = FETCH();
622
623   if( modrm >= 0xc0 )
624   {
625      if (m_SF == 1)
626      {
627         src = LOAD_RM16(modrm);
628         STORE_REG16(modrm, src);
629      }
630      CYCLES(1); // TODO: correct cycle count
631   }
632   else
633   {
634      UINT32 ea = GetEA(modrm,0);
635      if (m_SF == 1)
636      {
637         src = READ16(ea);
638         STORE_REG16(modrm, src);
639      }
640      CYCLES(1); // TODO: correct cycle count
641   }
642}
643
644void i386_device::pentium_cmovs_r32_rm32()    // Opcode 0x0f 48
645{
646   UINT32 src;
647   UINT8 modrm = FETCH();
648
649   if( modrm >= 0xc0 )
650   {
651      if (m_SF == 1)
652      {
653         src = LOAD_RM32(modrm);
654         STORE_REG32(modrm, src);
655      }
656      CYCLES(1); // TODO: correct cycle count
657   }
658   else
659   {
660      UINT32 ea = GetEA(modrm,0);
661      if (m_SF == 1)
662      {
663         src = READ32(ea);
664         STORE_REG32(modrm, src);
665      }
666      CYCLES(1); // TODO: correct cycle count
667   }
668}
669
670void i386_device::pentium_cmovns_r16_rm16()    // Opcode 0x0f 49
671{
672   UINT16 src;
673   UINT8 modrm = FETCH();
674
675   if( modrm >= 0xc0 )
676   {
677      if (m_SF == 0)
678      {
679         src = LOAD_RM16(modrm);
680         STORE_REG16(modrm, src);
681      }
682      CYCLES(1); // TODO: correct cycle count
683   }
684   else
685   {
686      UINT32 ea = GetEA(modrm,0);
687      if (m_SF == 0)
688      {
689         src = READ16(ea);
690         STORE_REG16(modrm, src);
691      }
692      CYCLES(1); // TODO: correct cycle count
693   }
694}
695
696void i386_device::pentium_cmovns_r32_rm32()    // Opcode 0x0f 49
697{
698   UINT32 src;
699   UINT8 modrm = FETCH();
700
701   if( modrm >= 0xc0 )
702   {
703      if (m_SF == 0)
704      {
705         src = LOAD_RM32(modrm);
706         STORE_REG32(modrm, src);
707      }
708      CYCLES(1); // TODO: correct cycle count
709   }
710   else
711   {
712      UINT32 ea = GetEA(modrm,0);
713      if (m_SF == 0)
714      {
715         src = READ32(ea);
716         STORE_REG32(modrm, src);
717      }
718      CYCLES(1); // TODO: correct cycle count
719   }
720}
721
722void i386_device::pentium_cmovp_r16_rm16()    // Opcode 0x0f 4a
723{
724   UINT16 src;
725   UINT8 modrm = FETCH();
726
727   if( modrm >= 0xc0 )
728   {
729      if (m_PF == 1)
730      {
731         src = LOAD_RM16(modrm);
732         STORE_REG16(modrm, src);
733      }
734      CYCLES(1); // TODO: correct cycle count
735   }
736   else
737   {
738      UINT32 ea = GetEA(modrm,0);
739      if (m_PF == 1)
740      {
741         src = READ16(ea);
742         STORE_REG16(modrm, src);
743      }
744      CYCLES(1); // TODO: correct cycle count
745   }
746}
747
748void i386_device::pentium_cmovp_r32_rm32()    // Opcode 0x0f 4a
749{
750   UINT32 src;
751   UINT8 modrm = FETCH();
752
753   if( modrm >= 0xc0 )
754   {
755      if (m_PF == 1)
756      {
757         src = LOAD_RM32(modrm);
758         STORE_REG32(modrm, src);
759      }
760      CYCLES(1); // TODO: correct cycle count
761   }
762   else
763   {
764      UINT32 ea = GetEA(modrm,0);
765      if (m_PF == 1)
766      {
767         src = READ32(ea);
768         STORE_REG32(modrm, src);
769      }
770      CYCLES(1); // TODO: correct cycle count
771   }
772}
773
774void i386_device::pentium_cmovnp_r16_rm16()    // Opcode 0x0f 4b
775{
776   UINT16 src;
777   UINT8 modrm = FETCH();
778
779   if( modrm >= 0xc0 )
780   {
781      if (m_PF == 0)
782      {
783         src = LOAD_RM16(modrm);
784         STORE_REG16(modrm, src);
785      }
786      CYCLES(1); // TODO: correct cycle count
787   }
788   else
789   {
790      UINT32 ea = GetEA(modrm,0);
791      if (m_PF == 0)
792      {
793         src = READ16(ea);
794         STORE_REG16(modrm, src);
795      }
796      CYCLES(1); // TODO: correct cycle count
797   }
798}
799
800void i386_device::pentium_cmovnp_r32_rm32()    // Opcode 0x0f 4b
801{
802   UINT32 src;
803   UINT8 modrm = FETCH();
804
805   if( modrm >= 0xc0 )
806   {
807      if (m_PF == 0)
808      {
809         src = LOAD_RM32(modrm);
810         STORE_REG32(modrm, src);
811      }
812      CYCLES(1); // TODO: correct cycle count
813   }
814   else
815   {
816      UINT32 ea = GetEA(modrm,0);
817      if (m_PF == 0)
818      {
819         src = READ32(ea);
820         STORE_REG32(modrm, src);
821      }
822      CYCLES(1); // TODO: correct cycle count
823   }
824}
825
826void i386_device::pentium_cmovl_r16_rm16()    // Opcode 0x0f 4c
827{
828   UINT16 src;
829   UINT8 modrm = FETCH();
830
831   if( modrm >= 0xc0 )
832   {
833      if (m_SF != m_OF)
834      {
835         src = LOAD_RM16(modrm);
836         STORE_REG16(modrm, src);
837      }
838      CYCLES(1); // TODO: correct cycle count
839   }
840   else
841   {
842      UINT32 ea = GetEA(modrm,0);
843      if (m_SF != m_OF)
844      {
845         src = READ16(ea);
846         STORE_REG16(modrm, src);
847      }
848      CYCLES(1); // TODO: correct cycle count
849   }
850}
851
852void i386_device::pentium_cmovl_r32_rm32()    // Opcode 0x0f 4c
853{
854   UINT32 src;
855   UINT8 modrm = FETCH();
856
857   if( modrm >= 0xc0 )
858   {
859      if (m_SF != m_OF)
860      {
861         src = LOAD_RM32(modrm);
862         STORE_REG32(modrm, src);
863      }
864      CYCLES(1); // TODO: correct cycle count
865   }
866   else
867   {
868      UINT32 ea = GetEA(modrm,0);
869      if (m_SF != m_OF)
870      {
871         src = READ32(ea);
872         STORE_REG32(modrm, src);
873      }
874      CYCLES(1); // TODO: correct cycle count
875   }
876}
877
878void i386_device::pentium_cmovge_r16_rm16()    // Opcode 0x0f 4d
879{
880   UINT16 src;
881   UINT8 modrm = FETCH();
882
883   if( modrm >= 0xc0 )
884   {
885      if (m_SF == m_OF)
886      {
887         src = LOAD_RM16(modrm);
888         STORE_REG16(modrm, src);
889      }
890      CYCLES(1); // TODO: correct cycle count
891   }
892   else
893   {
894      UINT32 ea = GetEA(modrm,0);
895      if (m_SF == m_OF)
896      {
897         src = READ16(ea);
898         STORE_REG16(modrm, src);
899      }
900      CYCLES(1); // TODO: correct cycle count
901   }
902}
903
904void i386_device::pentium_cmovge_r32_rm32()    // Opcode 0x0f 4d
905{
906   UINT32 src;
907   UINT8 modrm = FETCH();
908
909   if( modrm >= 0xc0 )
910   {
911      if (m_SF == m_OF)
912      {
913         src = LOAD_RM32(modrm);
914         STORE_REG32(modrm, src);
915      }
916      CYCLES(1); // TODO: correct cycle count
917   }
918   else
919   {
920      UINT32 ea = GetEA(modrm,0);
921      if (m_SF == m_OF)
922      {
923         src = READ32(ea);
924         STORE_REG32(modrm, src);
925      }
926      CYCLES(1); // TODO: correct cycle count
927   }
928}
929
930void i386_device::pentium_cmovle_r16_rm16()    // Opcode 0x0f 4e
931{
932   UINT16 src;
933   UINT8 modrm = FETCH();
934
935   if( modrm >= 0xc0 )
936   {
937      if ((m_ZF == 1) || (m_SF != m_OF))
938      {
939         src = LOAD_RM16(modrm);
940         STORE_REG16(modrm, src);
941      }
942      CYCLES(1); // TODO: correct cycle count
943   }
944   else
945   {
946      UINT32 ea = GetEA(modrm,0);
947      if ((m_ZF == 1) || (m_SF != m_OF))
948      {
949         src = READ16(ea);
950         STORE_REG16(modrm, src);
951      }
952      CYCLES(1); // TODO: correct cycle count
953   }
954}
955
956void i386_device::pentium_cmovle_r32_rm32()    // Opcode 0x0f 4e
957{
958   UINT32 src;
959   UINT8 modrm = FETCH();
960
961   if( modrm >= 0xc0 )
962   {
963      if ((m_ZF == 1) || (m_SF != m_OF))
964      {
965         src = LOAD_RM32(modrm);
966         STORE_REG32(modrm, src);
967      }
968      CYCLES(1); // TODO: correct cycle count
969   }
970   else
971   {
972      UINT32 ea = GetEA(modrm,0);
973      if ((m_ZF == 1) || (m_SF != m_OF))
974      {
975         src = READ32(ea);
976         STORE_REG32(modrm, src);
977      }
978      CYCLES(1); // TODO: correct cycle count
979   }
980}
981
982void i386_device::pentium_cmovg_r16_rm16()    // Opcode 0x0f 4f
983{
984   UINT16 src;
985   UINT8 modrm = FETCH();
986
987   if( modrm >= 0xc0 )
988   {
989      if ((m_ZF == 0) && (m_SF == m_OF))
990      {
991         src = LOAD_RM16(modrm);
992         STORE_REG16(modrm, src);
993      }
994      CYCLES(1); // TODO: correct cycle count
995   }
996   else
997   {
998      UINT32 ea = GetEA(modrm,0);
999      if ((m_ZF == 0) && (m_SF == m_OF))
1000      {
1001         src = READ16(ea);
1002         STORE_REG16(modrm, src);
1003      }
1004      CYCLES(1); // TODO: correct cycle count
1005   }
1006}
1007
1008void i386_device::pentium_cmovg_r32_rm32()    // Opcode 0x0f 4f
1009{
1010   UINT32 src;
1011   UINT8 modrm = FETCH();
1012
1013   if( modrm >= 0xc0 )
1014   {
1015      if ((m_ZF == 0) && (m_SF == m_OF))
1016      {
1017         src = LOAD_RM32(modrm);
1018         STORE_REG32(modrm, src);
1019      }
1020      CYCLES(1); // TODO: correct cycle count
1021   }
1022   else
1023   {
1024      UINT32 ea = GetEA(modrm,0);
1025      if ((m_ZF == 0) && (m_SF == m_OF))
1026      {
1027         src = READ32(ea);
1028         STORE_REG32(modrm, src);
1029      }
1030      CYCLES(1); // TODO: correct cycle count
1031   }
1032}
1033
1034void i386_device::pentium_movnti_m16_r16() // Opcode 0f c3
1035{
1036   UINT8 modrm = FETCH();
1037   if( modrm >= 0xc0 ) {
1038      // unsupported by cpu
1039      CYCLES(1);     // TODO: correct cycle count
1040   } else {
1041      // since cache is not implemented
1042      UINT32 ea = GetEA(modrm, 0);
1043      WRITE16(ea,LOAD_RM16(modrm));
1044      CYCLES(1);     // TODO: correct cycle count
1045   }
1046}
1047
1048void i386_device::pentium_movnti_m32_r32() // Opcode 0f c3
1049{
1050   UINT8 modrm = FETCH();
1051   if( modrm >= 0xc0 ) {
1052      // unsupported by cpu
1053      CYCLES(1);     // TODO: correct cycle count
1054   } else {
1055      // since cache is not implemented
1056      UINT32 ea = GetEA(modrm, 0);
1057      WRITE32(ea,LOAD_RM32(modrm));
1058      CYCLES(1);     // TODO: correct cycle count
1059   }
1060}
1061
1062void i386_device::i386_cyrix_unknown()     // Opcode 0x0f 74
1063{
1064   logerror("Unemulated 0x0f 0x74 opcode called\n");
1065
1066   CYCLES(1);
1067}
1068
1069void i386_device::pentium_cmpxchg8b_m64()  // Opcode 0x0f c7
1070{
1071   UINT8 modm = FETCH();
1072   if( modm >= 0xc0 ) {
1073      report_invalid_modrm("cmpxchg8b_m64", modm);
1074   } else {
1075      UINT32 ea = GetEA(modm, 0);
1076      UINT64 value = READ64(ea);
1077      UINT64 edx_eax = (((UINT64) REG32(EDX)) << 32) | REG32(EAX);
1078      UINT64 ecx_ebx = (((UINT64) REG32(ECX)) << 32) | REG32(EBX);
1079
1080      if( value == edx_eax ) {
1081         WRITE64(ea, ecx_ebx);
1082         m_ZF = 1;
1083         CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
1084      } else {
1085         REG32(EDX) = (UINT32) (value >> 32);
1086         REG32(EAX) = (UINT32) (value >>  0);
1087         m_ZF = 0;
1088         CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
1089      }
1090   }
1091}
1092
1093void i386_device::pentium_movntq_m64_r64() // Opcode 0f e7
1094{
1095   //MMXPROLOG(); // TODO: check if needed
1096   UINT8 modrm = FETCH();
1097   if( modrm >= 0xc0 ) {
1098      CYCLES(1);     // unsupported
1099   } else {
1100      // since cache is not implemented
1101      UINT32 ea = GetEA(modrm, 0);
1102      WRITEMMX(ea, MMX((modrm >> 3) & 0x7));
1103      CYCLES(1);     // TODO: correct cycle count
1104   }
1105}
1106
1107void i386_device::pentium_maskmovq_r64_r64()  // Opcode 0f f7
1108{
1109   int s,m,n;
1110   UINT8 modm = FETCH();
1111   UINT32 ea = GetEA(7, 0); // ds:di/edi/rdi register
1112   MMXPROLOG();
1113   s=(modm >> 3) & 7;
1114   m=modm & 7;
1115   for (n=0;n <= 7;n++)
1116      if (MMX(m).b[n] & 127)
1117         WRITE8(ea+n, MMX(s).b[n]);
1118}
1119
1120void i386_device::pentium_popcnt_r16_rm16()    // Opcode f3 0f b8
1121{
1122   UINT16 src;
1123   UINT8 modrm = FETCH();
1124   int n,count;
1125
1126   if( modrm >= 0xc0 ) {
1127      src = LOAD_RM16(modrm);
1128   } else {
1129      UINT32 ea = GetEA(modrm,0);
1130      src = READ16(ea);
1131   }
1132   count=0;
1133   for (n=0;n < 16;n++) {
1134      count=count+(src & 1);
1135      src=src >> 1;
1136   }
1137   STORE_REG16(modrm, count);
1138   CYCLES(1); // TODO: correct cycle count
1139}
1140
1141void i386_device::pentium_popcnt_r32_rm32()    // Opcode f3 0f b8
1142{
1143   UINT32 src;
1144   UINT8 modrm = FETCH();
1145   int n,count;
1146
1147   if( modrm >= 0xc0 ) {
1148      src = LOAD_RM32(modrm);
1149   } else {
1150      UINT32 ea = GetEA(modrm,0);
1151      src = READ32(ea);
1152   }
1153   count=0;
1154   for (n=0;n < 32;n++) {
1155      count=count+(src & 1);
1156      src=src >> 1;
1157   }
1158   STORE_REG32(modrm, count);
1159   CYCLES(1); // TODO: correct cycle count
1160}
1161
1162void i386_device::pentium_tzcnt_r16_rm16()
1163{
1164   // for CPUs that don't support TZCNT, fall back to BSF
1165   i386_bsf_r16_rm16();
1166   // TODO: actually implement TZCNT
1167}
1168
1169void i386_device::pentium_tzcnt_r32_rm32()
1170{
1171   // for CPUs that don't support TZCNT, fall back to BSF
1172   i386_bsf_r32_rm32();
1173   // TODO: actually implement TZCNT
1174}
1175
1176INLINE INT8 SaturatedSignedWordToSignedByte(INT16 word)
1177{
1178   if (word > 127)
1179      return 127;
1180   if (word < -128)
1181      return -128;
1182   return (INT8)word;
1183}
1184
1185INLINE UINT8 SaturatedSignedWordToUnsignedByte(INT16 word)
1186{
1187   if (word > 255)
1188      return 255;
1189   if (word < 0)
1190      return 0;
1191   return (UINT8)word;
1192}
1193
1194INLINE INT16 SaturatedSignedDwordToSignedWord(INT32 dword)
1195{
1196   if (dword > 32767)
1197      return 32767;
1198   if (dword < -32768)
1199      return -32768;
1200   return (INT16)dword;
1201}
1202
1203void i386_device::mmx_group_0f71()  // Opcode 0f 71
1204{
1205   UINT8 modm = FETCH();
1206   UINT8 imm8 = FETCH();
1207   MMXPROLOG();
1208   if( modm >= 0xc0 ) {
1209      switch ( (modm & 0x38) >> 3 )
1210      {
1211         case 2: // psrlw
1212            MMX(modm & 7).w[0]=MMX(modm & 7).w[0] >> imm8;
1213            MMX(modm & 7).w[1]=MMX(modm & 7).w[1] >> imm8;
1214            MMX(modm & 7).w[2]=MMX(modm & 7).w[2] >> imm8;
1215            MMX(modm & 7).w[3]=MMX(modm & 7).w[3] >> imm8;
1216            break;
1217         case 4: // psraw
1218            MMX(modm & 7).s[0]=MMX(modm & 7).s[0] >> imm8;
1219            MMX(modm & 7).s[1]=MMX(modm & 7).s[1] >> imm8;
1220            MMX(modm & 7).s[2]=MMX(modm & 7).s[2] >> imm8;
1221            MMX(modm & 7).s[3]=MMX(modm & 7).s[3] >> imm8;
1222            break;
1223         case 6: // psllw
1224            MMX(modm & 7).w[0]=MMX(modm & 7).w[0] << imm8;
1225            MMX(modm & 7).w[1]=MMX(modm & 7).w[1] << imm8;
1226            MMX(modm & 7).w[2]=MMX(modm & 7).w[2] << imm8;
1227            MMX(modm & 7).w[3]=MMX(modm & 7).w[3] << imm8;
1228            break;
1229         default:
1230            report_invalid_modrm("mmx_group0f71", modm);
1231      }
1232   }
1233}
1234
1235void i386_device::mmx_group_0f72()  // Opcode 0f 72
1236{
1237   UINT8 modm = FETCH();
1238   UINT8 imm8 = FETCH();
1239   MMXPROLOG();
1240   if( modm >= 0xc0 ) {
1241      switch ( (modm & 0x38) >> 3 )
1242      {
1243         case 2: // psrld
1244            MMX(modm & 7).d[0]=MMX(modm & 7).d[0] >> imm8;
1245            MMX(modm & 7).d[1]=MMX(modm & 7).d[1] >> imm8;
1246            break;
1247         case 4: // psrad
1248            MMX(modm & 7).i[0]=MMX(modm & 7).i[0] >> imm8;
1249            MMX(modm & 7).i[1]=MMX(modm & 7).i[1] >> imm8;
1250            break;
1251         case 6: // pslld
1252            MMX(modm & 7).d[0]=MMX(modm & 7).d[0] << imm8;
1253            MMX(modm & 7).d[1]=MMX(modm & 7).d[1] << imm8;
1254            break;
1255         default:
1256            report_invalid_modrm("mmx_group0f72", modm);
1257      }
1258   }
1259}
1260
1261void i386_device::mmx_group_0f73()  // Opcode 0f 73
1262{
1263   UINT8 modm = FETCH();
1264   UINT8 imm8 = FETCH();
1265   MMXPROLOG();
1266   if( modm >= 0xc0 ) {
1267      switch ( (modm & 0x38) >> 3 )
1268      {
1269         case 2: // psrlq
1270            MMX(modm & 7).q=MMX(modm & 7).q >> imm8;
1271            break;
1272         case 6: // psllq
1273            MMX(modm & 7).q=MMX(modm & 7).q << imm8;
1274            break;
1275         default:
1276            report_invalid_modrm("mmx_group0f73", modm);
1277      }
1278   }
1279}
1280
1281void i386_device::mmx_psrlw_r64_rm64()  // Opcode 0f d1
1282{
1283   MMXPROLOG();
1284   UINT8 modrm = FETCH();
1285   if( modrm >= 0xc0 ) {
1286      int count=(int)MMX(modrm & 7).q;
1287      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count;
1288      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count;
1289      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count;
1290      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count;
1291   } else {
1292      MMX_REG src;
1293      UINT32 ea = GetEA(modrm, 0);
1294      READMMX(ea, src);
1295      int count=(int)src.q;
1296      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count;
1297      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count;
1298      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count;
1299      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count;
1300   }
1301   CYCLES(1);     // TODO: correct cycle count
1302}
1303
1304void i386_device::mmx_psrld_r64_rm64()  // Opcode 0f d2
1305{
1306   MMXPROLOG();
1307   UINT8 modrm = FETCH();
1308   if( modrm >= 0xc0 ) {
1309      int count=(int)MMX(modrm & 7).q;
1310      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count;
1311      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count;
1312   } else {
1313      MMX_REG src;
1314      UINT32 ea = GetEA(modrm, 0);
1315      READMMX(ea, src);
1316      int count=(int)src.q;
1317      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count;
1318      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count;
1319   }
1320   CYCLES(1);     // TODO: correct cycle count
1321}
1322
1323void i386_device::mmx_psrlq_r64_rm64()  // Opcode 0f d3
1324{
1325   MMXPROLOG();
1326   UINT8 modrm = FETCH();
1327   if( modrm >= 0xc0 ) {
1328      int count=(int)MMX(modrm & 7).q;
1329      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count;
1330   } else {
1331      MMX_REG src;
1332      UINT32 ea = GetEA(modrm, 0);
1333      READMMX(ea, src);
1334      int count=(int)src.q;
1335      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count;
1336   }
1337   CYCLES(1);     // TODO: correct cycle count
1338}
1339
1340void i386_device::mmx_paddq_r64_rm64()  // Opcode 0f d4
1341{
1342   MMXPROLOG();
1343   UINT8 modrm = FETCH();
1344   if( modrm >= 0xc0 ) {
1345      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+MMX(modrm & 7).q;
1346   } else {
1347      MMX_REG src;
1348      UINT32 ea = GetEA(modrm, 0);
1349      READMMX(ea, src);
1350      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+src.q;
1351   }
1352   CYCLES(1);     // TODO: correct cycle count
1353}
1354
1355void i386_device::mmx_pmullw_r64_rm64()  // Opcode 0f d5
1356{
1357   MMXPROLOG();
1358   UINT8 modrm = FETCH();
1359   if( modrm >= 0xc0 ) {
1360      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]) & 0xffff;
1361      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1]) & 0xffff;
1362      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]) & 0xffff;
1363      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3]) & 0xffff;
1364   } else {
1365      MMX_REG src;
1366      UINT32 ea = GetEA(modrm, 0);
1367      READMMX(ea, src);
1368      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)src.s[0]) & 0xffff;
1369      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)src.s[1]) & 0xffff;
1370      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)src.s[2]) & 0xffff;
1371      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)src.s[3]) & 0xffff;
1372   }
1373   CYCLES(1);     // TODO: correct cycle count
1374}
1375
1376void i386_device::mmx_psubusb_r64_rm64()  // Opcode 0f d8
1377{
1378   int n;
1379   MMXPROLOG();
1380   UINT8 modrm = FETCH();
1381   if( modrm >= 0xc0 ) {
1382      for (n=0;n < 8;n++)
1383         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 7).b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-MMX(modrm & 7).b[n];
1384   } else {
1385      MMX_REG src;
1386      UINT32 ea = GetEA(modrm, 0);
1387      READMMX(ea, src);
1388      for (n=0;n < 8;n++)
1389         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < src.b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-src.b[n];
1390   }
1391   CYCLES(1);     // TODO: correct cycle count
1392}
1393
1394void i386_device::mmx_psubusw_r64_rm64()  // Opcode 0f d9
1395{
1396   int n;
1397   MMXPROLOG();
1398   UINT8 modrm = FETCH();
1399   if( modrm >= 0xc0 ) {
1400      for (n=0;n < 4;n++)
1401         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < MMX(modrm & 7).w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-MMX(modrm & 7).w[n];
1402   } else {
1403      MMX_REG src;
1404      UINT32 ea = GetEA(modrm, 0);
1405      READMMX(ea, src);
1406      for (n=0;n < 4;n++)
1407         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < src.w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-src.w[n];
1408   }
1409   CYCLES(1);     // TODO: correct cycle count
1410}
1411
1412void i386_device::mmx_pand_r64_rm64()  // Opcode 0f db
1413{
1414   MMXPROLOG();
1415   UINT8 modrm = FETCH();
1416   if( modrm >= 0xc0 ) {
1417      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & MMX(modrm & 7).q;
1418   } else {
1419      MMX_REG src;
1420      UINT32 ea = GetEA(modrm, 0);
1421      READMMX(ea, src);
1422      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & src.q;
1423   }
1424   CYCLES(1);     // TODO: correct cycle count
1425}
1426
1427void i386_device::mmx_paddusb_r64_rm64()  // Opcode 0f dc
1428{
1429   int n;
1430   MMXPROLOG();
1431   UINT8 modrm = FETCH();
1432   if( modrm >= 0xc0 ) {
1433      for (n=0;n < 8;n++)
1434         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-MMX(modrm & 7).b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+MMX(modrm & 7).b[n];
1435   } else {
1436      MMX_REG src;
1437      UINT32 ea = GetEA(modrm, 0);
1438      READMMX(ea, src);
1439      for (n=0;n < 8;n++)
1440         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-src.b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+src.b[n];
1441   }
1442   CYCLES(1);     // TODO: correct cycle count
1443}
1444
1445void i386_device::mmx_paddusw_r64_rm64()  // Opcode 0f dd
1446{
1447   int n;
1448   MMXPROLOG();
1449   UINT8 modrm = FETCH();
1450   if( modrm >= 0xc0 ) {
1451      for (n=0;n < 4;n++)
1452         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-MMX(modrm & 7).w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+MMX(modrm & 7).w[n];
1453   } else {
1454      MMX_REG src;
1455      UINT32 ea = GetEA(modrm, 0);
1456      READMMX(ea, src);
1457      for (n=0;n < 4;n++)
1458         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-src.w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+src.w[n];
1459   }
1460   CYCLES(1);     // TODO: correct cycle count
1461}
1462
1463void i386_device::mmx_pandn_r64_rm64()  // Opcode 0f df
1464{
1465   MMXPROLOG();
1466   UINT8 modrm = FETCH();
1467   if( modrm >= 0xc0 ) {
1468      MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & MMX(modrm & 7).q;
1469   } else {
1470      MMX_REG src;
1471      UINT32 ea = GetEA(modrm, 0);
1472      READMMX(ea, src);
1473      MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & src.q;
1474   }
1475   CYCLES(1);     // TODO: correct cycle count
1476}
1477
1478void i386_device::mmx_psraw_r64_rm64()  // Opcode 0f e1
1479{
1480   MMXPROLOG();
1481   UINT8 modrm = FETCH();
1482   if( modrm >= 0xc0 ) {
1483      int count=(int)MMX(modrm & 7).q;
1484      MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count;
1485      MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count;
1486      MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count;
1487      MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count;
1488   } else {
1489      MMX_REG src;
1490      UINT32 ea = GetEA(modrm, 0);
1491      READMMX(ea, src);
1492      int count=(int)src.q;
1493      MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count;
1494      MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count;
1495      MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count;
1496      MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count;
1497   }
1498   CYCLES(1);     // TODO: correct cycle count
1499}
1500
1501void i386_device::mmx_psrad_r64_rm64()  // Opcode 0f e2
1502{
1503   MMXPROLOG();
1504   UINT8 modrm = FETCH();
1505   if( modrm >= 0xc0 ) {
1506      int count=(int)MMX(modrm & 7).q;
1507      MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count;
1508      MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count;
1509   } else {
1510      MMX_REG src;
1511      UINT32 ea = GetEA(modrm, 0);
1512      READMMX(ea, src);
1513      int count=(int)src.q;
1514      MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count;
1515      MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count;
1516   }
1517   CYCLES(1);     // TODO: correct cycle count
1518}
1519
1520void i386_device::mmx_pmulhw_r64_rm64()  // Opcode 0f e5
1521{
1522   MMXPROLOG();
1523   UINT8 modrm = FETCH();
1524   if( modrm >= 0xc0 ) {
1525      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]) >> 16;
1526      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1]) >> 16;
1527      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]) >> 16;
1528      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3]) >> 16;
1529   } else {
1530      MMX_REG src;
1531      UINT32 ea = GetEA(modrm, 0);
1532      READMMX(ea, src);
1533      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)src.s[0]) >> 16;
1534      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)src.s[1]) >> 16;
1535      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)src.s[2]) >> 16;
1536      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)src.s[3]) >> 16;
1537   }
1538   CYCLES(1);     // TODO: correct cycle count
1539}
1540
1541void i386_device::mmx_psubsb_r64_rm64()  // Opcode 0f e8
1542{
1543   int n;
1544   MMXPROLOG();
1545   UINT8 modrm = FETCH();
1546   if( modrm >= 0xc0 ) {
1547      for (n=0;n < 8;n++)
1548         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] - (INT16)MMX(modrm & 7).c[n]);
1549   } else {
1550      MMX_REG s;
1551      UINT32 ea = GetEA(modrm, 0);
1552      READMMX(ea, s);
1553      for (n=0;n < 8;n++)
1554         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] - (INT16)s.c[n]);
1555   }
1556   CYCLES(1);     // TODO: correct cycle count
1557}
1558
1559void i386_device::mmx_psubsw_r64_rm64()  // Opcode 0f e9
1560{
1561   int n;
1562   MMXPROLOG();
1563   UINT8 modrm = FETCH();
1564   if( modrm >= 0xc0 ) {
1565      for (n=0;n < 4;n++)
1566         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] - (INT32)MMX(modrm & 7).s[n]);
1567   } else {
1568      MMX_REG s;
1569      UINT32 ea = GetEA(modrm, 0);
1570      READMMX(ea, s);
1571      for (n=0;n < 4;n++)
1572         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] - (INT32)s.s[n]);
1573   }
1574   CYCLES(1);     // TODO: correct cycle count
1575}
1576
1577void i386_device::mmx_por_r64_rm64()  // Opcode 0f eb
1578{
1579   MMXPROLOG();
1580   UINT8 modrm = FETCH();
1581   if( modrm >= 0xc0 ) {
1582      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | MMX(modrm & 7).q;
1583   } else {
1584      MMX_REG s;
1585      UINT32 ea = GetEA(modrm, 0);
1586      READMMX(ea, s);
1587      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | s.q;
1588   }
1589   CYCLES(1);     // TODO: correct cycle count
1590}
1591
1592void i386_device::mmx_paddsb_r64_rm64()  // Opcode 0f ec
1593{
1594   int n;
1595   MMXPROLOG();
1596   UINT8 modrm = FETCH();
1597   if( modrm >= 0xc0 ) {
1598      for (n=0;n < 8;n++)
1599         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] + (INT16)MMX(modrm & 7).c[n]);
1600   } else {
1601      MMX_REG s;
1602      UINT32 ea = GetEA(modrm, 0);
1603      READMMX(ea, s);
1604      for (n=0;n < 8;n++)
1605         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] + (INT16)s.c[n]);
1606   }
1607   CYCLES(1);     // TODO: correct cycle count
1608}
1609
1610void i386_device::mmx_paddsw_r64_rm64()  // Opcode 0f ed
1611{
1612   int n;
1613   MMXPROLOG();
1614   UINT8 modrm = FETCH();
1615   if( modrm >= 0xc0 ) {
1616      for (n=0;n < 4;n++)
1617         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] + (INT32)MMX(modrm & 7).s[n]);
1618   } else {
1619      MMX_REG s;
1620      UINT32 ea = GetEA(modrm, 0);
1621      READMMX(ea, s);
1622      for (n=0;n < 4;n++)
1623         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] + (INT32)s.s[n]);
1624   }
1625   CYCLES(1);     // TODO: correct cycle count
1626}
1627
1628void i386_device::mmx_pxor_r64_rm64()  // Opcode 0f ef
1629{
1630   MMXPROLOG();
1631   UINT8 modrm = FETCH();
1632   if( modrm >= 0xc0 ) {
1633      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ MMX(modrm & 7).q;
1634   } else {
1635      MMX_REG s;
1636      UINT32 ea = GetEA(modrm, 0);
1637      READMMX(ea, s);
1638      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ s.q;
1639   }
1640   CYCLES(1);     // TODO: correct cycle count
1641}
1642
1643void i386_device::mmx_psllw_r64_rm64()  // Opcode 0f f1
1644{
1645   MMXPROLOG();
1646   UINT8 modrm = FETCH();
1647   if( modrm >= 0xc0 ) {
1648      int count=(int)MMX(modrm & 7).q;
1649      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count;
1650      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count;
1651      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count;
1652      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count;
1653   } else {
1654      MMX_REG s;
1655      UINT32 ea = GetEA(modrm, 0);
1656      READMMX(ea, s);
1657      int count=(int)s.q;
1658      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count;
1659      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count;
1660      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count;
1661      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count;
1662   }
1663   CYCLES(1);     // TODO: correct cycle count
1664}
1665
1666void i386_device::mmx_pslld_r64_rm64()  // Opcode 0f f2
1667{
1668   MMXPROLOG();
1669   UINT8 modrm = FETCH();
1670   if( modrm >= 0xc0 ) {
1671      int count=(int)MMX(modrm & 7).q;
1672      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count;
1673      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count;
1674   } else {
1675      MMX_REG s;
1676      UINT32 ea = GetEA(modrm, 0);
1677      READMMX(ea, s);
1678      int count=(int)s.q;
1679      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count;
1680      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count;
1681   }
1682   CYCLES(1);     // TODO: correct cycle count
1683}
1684
1685void i386_device::mmx_psllq_r64_rm64()  // Opcode 0f f3
1686{
1687   MMXPROLOG();
1688   UINT8 modrm = FETCH();
1689   if( modrm >= 0xc0 ) {
1690      int count=(int)MMX(modrm & 7).q;
1691      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count;
1692   } else {
1693      MMX_REG s;
1694      UINT32 ea = GetEA(modrm, 0);
1695      READMMX(ea, s);
1696      int count=(int)s.q;
1697      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count;
1698   }
1699   CYCLES(1);     // TODO: correct cycle count
1700}
1701
1702void i386_device::mmx_pmaddwd_r64_rm64()  // Opcode 0f f5
1703{
1704   MMXPROLOG();
1705   UINT8 modrm = FETCH();
1706   if( modrm >= 0xc0 ) {
1707      MMX((modrm >> 3) & 0x7).i[0]=(INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]+
1708                              (INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1];
1709      MMX((modrm >> 3) & 0x7).i[1]=(INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]+
1710                              (INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3];
1711   } else {
1712      MMX_REG s;
1713      UINT32 ea = GetEA(modrm, 0);
1714      READMMX(ea, s);
1715      MMX((modrm >> 3) & 0x7).i[0]=(INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)s.s[0]+
1716                              (INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)s.s[1];
1717      MMX((modrm >> 3) & 0x7).i[1]=(INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)s.s[2]+
1718                              (INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)s.s[3];
1719   }
1720   CYCLES(1);     // TODO: correct cycle count
1721}
1722
1723void i386_device::mmx_psubb_r64_rm64()  // Opcode 0f f8
1724{
1725   int n;
1726   MMXPROLOG();
1727   UINT8 modrm = FETCH();
1728   if( modrm >= 0xc0 ) {
1729      for (n=0;n < 8;n++)
1730         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - MMX(modrm & 7).b[n];
1731   } else {
1732      MMX_REG s;
1733      UINT32 ea = GetEA(modrm, 0);
1734      READMMX(ea, s);
1735      for (n=0;n < 8;n++)
1736         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - s.b[n];
1737   }
1738   CYCLES(1);     // TODO: correct cycle count
1739}
1740
1741void i386_device::mmx_psubw_r64_rm64()  // Opcode 0f f9
1742{
1743   int n;
1744   MMXPROLOG();
1745   UINT8 modrm = FETCH();
1746   if( modrm >= 0xc0 ) {
1747      for (n=0;n < 4;n++)
1748         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - MMX(modrm & 7).w[n];
1749   } else {
1750      MMX_REG s;
1751      UINT32 ea = GetEA(modrm, 0);
1752      READMMX(ea, s);
1753      for (n=0;n < 4;n++)
1754         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - s.w[n];
1755   }
1756   CYCLES(1);     // TODO: correct cycle count
1757}
1758
1759void i386_device::mmx_psubd_r64_rm64()  // Opcode 0f fa
1760{
1761   int n;
1762   MMXPROLOG();
1763   UINT8 modrm = FETCH();
1764   if( modrm >= 0xc0 ) {
1765      for (n=0;n < 2;n++)
1766         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - MMX(modrm & 7).d[n];
1767   } else {
1768      MMX_REG s;
1769      UINT32 ea = GetEA(modrm, 0);
1770      READMMX(ea, s);
1771      for (n=0;n < 2;n++)
1772         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - s.d[n];
1773   }
1774   CYCLES(1);     // TODO: correct cycle count
1775}
1776
1777void i386_device::mmx_paddb_r64_rm64()  // Opcode 0f fc
1778{
1779   int n;
1780   MMXPROLOG();
1781   UINT8 modrm = FETCH();
1782   if( modrm >= 0xc0 ) {
1783      for (n=0;n < 8;n++)
1784         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + MMX(modrm & 7).b[n];
1785   } else {
1786      MMX_REG s;
1787      UINT32 ea = GetEA(modrm, 0);
1788      READMMX(ea, s);
1789      for (n=0;n < 8;n++)
1790         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + s.b[n];
1791   }
1792   CYCLES(1);     // TODO: correct cycle count
1793}
1794
1795void i386_device::mmx_paddw_r64_rm64()  // Opcode 0f fd
1796{
1797   int n;
1798   MMXPROLOG();
1799   UINT8 modrm = FETCH();
1800   if( modrm >= 0xc0 ) {
1801      for (n=0;n < 4;n++)
1802         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + MMX(modrm & 7).w[n];
1803   } else {
1804      MMX_REG s;
1805      UINT32 ea = GetEA(modrm, 0);
1806      READMMX(ea, s);
1807      for (n=0;n < 4;n++)
1808         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + s.w[n];
1809   }
1810   CYCLES(1);     // TODO: correct cycle count
1811}
1812
1813void i386_device::mmx_paddd_r64_rm64()  // Opcode 0f fe
1814{
1815   int n;
1816   MMXPROLOG();
1817   UINT8 modrm = FETCH();
1818   if( modrm >= 0xc0 ) {
1819      for (n=0;n < 2;n++)
1820         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + MMX(modrm & 7).d[n];
1821   } else {
1822      MMX_REG s;
1823      UINT32 ea = GetEA(modrm, 0);
1824      READMMX(ea, s);
1825      for (n=0;n < 2;n++)
1826         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + s.d[n];
1827   }
1828   CYCLES(1);     // TODO: correct cycle count
1829}
1830
1831void i386_device::mmx_emms() // Opcode 0f 77
1832{
1833   m_x87_tw = 0xffff; // tag word = 0xffff
1834   // TODO
1835   CYCLES(1);     // TODO: correct cycle count
1836}
1837
1838void i386_device::mmx_movd_r64_rm32() // Opcode 0f 6e
1839{
1840   MMXPROLOG();
1841   UINT8 modrm = FETCH();
1842   if( modrm >= 0xc0 ) {
1843      MMX((modrm >> 3) & 0x7).d[0]=LOAD_RM32(modrm);
1844   } else {
1845      UINT32 ea = GetEA(modrm, 0);
1846      MMX((modrm >> 3) & 0x7).d[0]=READ32(ea);
1847   }
1848   MMX((modrm >> 3) & 0x7).d[1]=0;
1849   CYCLES(1);     // TODO: correct cycle count
1850}
1851
1852void i386_device::mmx_movq_r64_rm64() // Opcode 0f 6f
1853{
1854   MMXPROLOG();
1855   UINT8 modrm = FETCH();
1856   if( modrm >= 0xc0 ) {
1857      MMX((modrm >> 3) & 0x7).l=MMX(modrm & 0x7).l;
1858   } else {
1859      UINT32 ea = GetEA(modrm, 0);
1860      READMMX(ea, MMX((modrm >> 3) & 0x7));
1861   }
1862   CYCLES(1);     // TODO: correct cycle count
1863}
1864
1865void i386_device::mmx_movd_rm32_r64() // Opcode 0f 7e
1866{
1867   MMXPROLOG();
1868   UINT8 modrm = FETCH();
1869   if( modrm >= 0xc0 ) {
1870      STORE_RM32(modrm, MMX((modrm >> 3) & 0x7).d[0]);
1871   } else {
1872      UINT32 ea = GetEA(modrm, 0);
1873      WRITE32(ea, MMX((modrm >> 3) & 0x7).d[0]);
1874   }
1875   CYCLES(1);     // TODO: correct cycle count
1876}
1877
1878void i386_device::mmx_movq_rm64_r64() // Opcode 0f 7f
1879{
1880   MMXPROLOG();
1881   UINT8 modrm = FETCH();
1882   if( modrm >= 0xc0 ) {
1883      MMX(modrm & 0x7)=MMX((modrm >> 3) & 0x7);
1884   } else {
1885      UINT32 ea = GetEA(modrm, 0);
1886      WRITEMMX(ea, MMX((modrm >> 3) & 0x7));
1887   }
1888   CYCLES(1);     // TODO: correct cycle count
1889}
1890
1891void i386_device::mmx_pcmpeqb_r64_rm64() // Opcode 0f 74
1892{
1893   int c;
1894   MMXPROLOG();
1895   UINT8 modrm = FETCH();
1896   if( modrm >= 0xc0 ) {
1897      int s,d;
1898      s=modrm & 0x7;
1899      d=(modrm >> 3) & 0x7;
1900      for (c=0;c <= 7;c++)
1901         MMX(d).b[c]=(MMX(d).b[c] == MMX(s).b[c]) ? 0xff : 0;
1902   } else {
1903      MMX_REG s;
1904      int d=(modrm >> 3) & 0x7;
1905      UINT32 ea = GetEA(modrm, 0);
1906      READMMX(ea, s);
1907      for (c=0;c <= 7;c++)
1908         MMX(d).b[c]=(MMX(d).b[c] == s.b[c]) ? 0xff : 0;
1909   }
1910   CYCLES(1);     // TODO: correct cycle count
1911}
1912
1913void i386_device::mmx_pcmpeqw_r64_rm64() // Opcode 0f 75
1914{
1915   MMXPROLOG();
1916   UINT8 modrm = FETCH();
1917   if( modrm >= 0xc0 ) {
1918      int s,d;
1919      s=modrm & 0x7;
1920      d=(modrm >> 3) & 0x7;
1921      MMX(d).w[0]=(MMX(d).w[0] == MMX(s).w[0]) ? 0xffff : 0;
1922      MMX(d).w[1]=(MMX(d).w[1] == MMX(s).w[1]) ? 0xffff : 0;
1923      MMX(d).w[2]=(MMX(d).w[2] == MMX(s).w[2]) ? 0xffff : 0;
1924      MMX(d).w[3]=(MMX(d).w[3] == MMX(s).w[3]) ? 0xffff : 0;
1925   } else {
1926      MMX_REG s;
1927      int d=(modrm >> 3) & 0x7;
1928      UINT32 ea = GetEA(modrm, 0);
1929      READMMX(ea, s);
1930      MMX(d).w[0]=(MMX(d).w[0] == s.w[0]) ? 0xffff : 0;
1931      MMX(d).w[1]=(MMX(d).w[1] == s.w[1]) ? 0xffff : 0;
1932      MMX(d).w[2]=(MMX(d).w[2] == s.w[2]) ? 0xffff : 0;
1933      MMX(d).w[3]=(MMX(d).w[3] == s.w[3]) ? 0xffff : 0;
1934   }
1935   CYCLES(1);     // TODO: correct cycle count
1936}
1937
1938void i386_device::mmx_pcmpeqd_r64_rm64() // Opcode 0f 76
1939{
1940   MMXPROLOG();
1941   UINT8 modrm = FETCH();
1942   if( modrm >= 0xc0 ) {
1943      int s,d;
1944      s=modrm & 0x7;
1945      d=(modrm >> 3) & 0x7;
1946      MMX(d).d[0]=(MMX(d).d[0] == MMX(s).d[0]) ? 0xffffffff : 0;
1947      MMX(d).d[1]=(MMX(d).d[1] == MMX(s).d[1]) ? 0xffffffff : 0;
1948   } else {
1949      MMX_REG s;
1950      int d=(modrm >> 3) & 0x7;
1951      UINT32 ea = GetEA(modrm, 0);
1952      READMMX(ea, s);
1953      MMX(d).d[0]=(MMX(d).d[0] == s.d[0]) ? 0xffffffff : 0;
1954      MMX(d).d[1]=(MMX(d).d[1] == s.d[1]) ? 0xffffffff : 0;
1955   }
1956   CYCLES(1);     // TODO: correct cycle count
1957}
1958
1959void i386_device::mmx_pshufw_r64_rm64_i8() // Opcode 0f 70
1960{
1961   MMXPROLOG();
1962   UINT8 modrm = FETCH();
1963   if( modrm >= 0xc0 ) {
1964      MMX_REG t;
1965      int s,d;
1966      UINT8 imm8 = FETCH();
1967      s=modrm & 0x7;
1968      d=(modrm >> 3) & 0x7;
1969      t.q=MMX(s).q;
1970      MMX(d).w[0]=t.w[imm8 & 3];
1971      MMX(d).w[1]=t.w[(imm8 >> 2) & 3];
1972      MMX(d).w[2]=t.w[(imm8 >> 4) & 3];
1973      MMX(d).w[3]=t.w[(imm8 >> 6) & 3];
1974   } else {
1975      MMX_REG s;
1976      int d=(modrm >> 3) & 0x7;
1977      UINT32 ea = GetEA(modrm, 0);
1978      UINT8 imm8 = FETCH();
1979      READMMX(ea, s);
1980      MMX(d).w[0]=s.w[imm8 & 3];
1981      MMX(d).w[1]=s.w[(imm8 >> 2) & 3];
1982      MMX(d).w[2]=s.w[(imm8 >> 4) & 3];
1983      MMX(d).w[3]=s.w[(imm8 >> 6) & 3];
1984   }
1985   CYCLES(1);     // TODO: correct cycle count
1986}
1987
1988void i386_device::mmx_punpcklbw_r64_r64m32() // Opcode 0f 60
1989{
1990   MMXPROLOG();
1991   UINT8 modrm = FETCH();
1992   if( modrm >= 0xc0 ) {
1993      UINT32 t;
1994      int s,d;
1995      s=modrm & 0x7;
1996      d=(modrm >> 3) & 0x7;
1997      t=MMX(d).d[0];
1998      MMX(d).b[0]=t & 0xff;
1999      MMX(d).b[1]=MMX(s).b[0];
2000      MMX(d).b[2]=(t >> 8) & 0xff;
2001      MMX(d).b[3]=MMX(s).b[1];
2002      MMX(d).b[4]=(t >> 16) & 0xff;
2003      MMX(d).b[5]=MMX(s).b[2];
2004      MMX(d).b[6]=(t >> 24) & 0xff;
2005      MMX(d).b[7]=MMX(s).b[3];
2006   } else {
2007      UINT32 s,t;
2008      int d=(modrm >> 3) & 0x7;
2009      UINT32 ea = GetEA(modrm, 0);
2010      s = READ32(ea);
2011      t=MMX(d).d[0];
2012      MMX(d).b[0]=t & 0xff;
2013      MMX(d).b[1]=s & 0xff;
2014      MMX(d).b[2]=(t >> 8) & 0xff;
2015      MMX(d).b[3]=(s >> 8) & 0xff;
2016      MMX(d).b[4]=(t >> 16) & 0xff;
2017      MMX(d).b[5]=(s >> 16) & 0xff;
2018      MMX(d).b[6]=(t >> 24) & 0xff;
2019      MMX(d).b[7]=(s >> 24) & 0xff;
2020   }
2021   CYCLES(1);     // TODO: correct cycle count
2022}
2023
2024void i386_device::mmx_punpcklwd_r64_r64m32() // Opcode 0f 61
2025{
2026   MMXPROLOG();
2027   UINT8 modrm = FETCH();
2028   if( modrm >= 0xc0 ) {
2029      UINT16 t;
2030      int s,d;
2031      s=modrm & 0x7;
2032      d=(modrm >> 3) & 0x7;
2033      t=MMX(d).w[1];
2034      MMX(d).w[0]=MMX(d).w[0];
2035      MMX(d).w[1]=MMX(s).w[0];
2036      MMX(d).w[2]=t;
2037      MMX(d).w[3]=MMX(s).w[1];
2038   } else {
2039      UINT32 s;
2040      UINT16 t;
2041      int d=(modrm >> 3) & 0x7;
2042      UINT32 ea = GetEA(modrm, 0);
2043      s = READ32(ea);
2044      t=MMX(d).w[1];
2045      MMX(d).w[0]=MMX(d).w[0];
2046      MMX(d).w[1]=s & 0xffff;
2047      MMX(d).w[2]=t;
2048      MMX(d).w[3]=(s >> 16) & 0xffff;
2049   }
2050   CYCLES(1);     // TODO: correct cycle count
2051}
2052
2053void i386_device::mmx_punpckldq_r64_r64m32() // Opcode 0f 62
2054{
2055   MMXPROLOG();
2056   UINT8 modrm = FETCH();
2057   if( modrm >= 0xc0 ) {
2058      int s,d;
2059      s=modrm & 0x7;
2060      d=(modrm >> 3) & 0x7;
2061      MMX(d).d[0]=MMX(d).d[0];
2062      MMX(d).d[1]=MMX(s).d[0];
2063   } else {
2064      UINT32 s;
2065      int d=(modrm >> 3) & 0x7;
2066      UINT32 ea = GetEA(modrm, 0);
2067      s = READ32(ea);
2068      MMX(d).d[0]=MMX(d).d[0];
2069      MMX(d).d[1]=s;
2070   }
2071   CYCLES(1);     // TODO: correct cycle count
2072}
2073
2074void i386_device::mmx_packsswb_r64_rm64() // Opcode 0f 63
2075{
2076   MMXPROLOG();
2077   UINT8 modrm = FETCH();
2078   if( modrm >= 0xc0 ) {
2079      int s,d;
2080      s=modrm & 0x7;
2081      d=(modrm >> 3) & 0x7;
2082      MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]);
2083      MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]);
2084      MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]);
2085      MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]);
2086      MMX(d).c[4]=SaturatedSignedWordToSignedByte(MMX(s).s[0]);
2087      MMX(d).c[5]=SaturatedSignedWordToSignedByte(MMX(s).s[1]);
2088      MMX(d).c[6]=SaturatedSignedWordToSignedByte(MMX(s).s[2]);
2089      MMX(d).c[7]=SaturatedSignedWordToSignedByte(MMX(s).s[3]);
2090   } else {
2091      MMX_REG s;
2092      int d=(modrm >> 3) & 0x7;
2093      UINT32 ea = GetEA(modrm, 0);
2094      READMMX(ea, s);
2095      MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]);
2096      MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]);
2097      MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]);
2098      MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]);
2099      MMX(d).c[4]=SaturatedSignedWordToSignedByte(s.s[0]);
2100      MMX(d).c[5]=SaturatedSignedWordToSignedByte(s.s[1]);
2101      MMX(d).c[6]=SaturatedSignedWordToSignedByte(s.s[2]);
2102      MMX(d).c[7]=SaturatedSignedWordToSignedByte(s.s[3]);
2103   }
2104   CYCLES(1);     // TODO: correct cycle count
2105}
2106
2107void i386_device::mmx_pcmpgtb_r64_rm64() // Opcode 0f 64
2108{
2109   int c;
2110   MMXPROLOG();
2111   UINT8 modrm = FETCH();
2112   if( modrm >= 0xc0 ) {
2113      int s,d;
2114      s=modrm & 0x7;
2115      d=(modrm >> 3) & 0x7;
2116      for (c=0;c <= 7;c++)
2117         MMX(d).b[c]=(MMX(d).c[c] > MMX(s).c[c]) ? 0xff : 0;
2118   } else {
2119      MMX_REG s;
2120      int d=(modrm >> 3) & 0x7;
2121      UINT32 ea = GetEA(modrm, 0);
2122      READMMX(ea, s);
2123      for (c=0;c <= 7;c++)
2124         MMX(d).b[c]=(MMX(d).c[c] > s.c[c]) ? 0xff : 0;
2125   }
2126   CYCLES(1);     // TODO: correct cycle count
2127}
2128
2129void i386_device::mmx_pcmpgtw_r64_rm64() // Opcode 0f 65
2130{
2131   int c;
2132   MMXPROLOG();
2133   UINT8 modrm = FETCH();
2134   if( modrm >= 0xc0 ) {
2135      int s,d;
2136      s=modrm & 0x7;
2137      d=(modrm >> 3) & 0x7;
2138      for (c=0;c <= 3;c++)
2139         MMX(d).w[c]=(MMX(d).s[c] > MMX(s).s[c]) ? 0xffff : 0;
2140   } else {
2141      MMX_REG s;
2142      int d=(modrm >> 3) & 0x7;
2143      UINT32 ea = GetEA(modrm, 0);
2144      READMMX(ea, s);
2145      for (c=0;c <= 3;c++)
2146         MMX(d).w[c]=(MMX(d).s[c] > s.s[c]) ? 0xffff : 0;
2147   }
2148   CYCLES(1);     // TODO: correct cycle count
2149}
2150
2151void i386_device::mmx_pcmpgtd_r64_rm64() // Opcode 0f 66
2152{
2153   int c;
2154   MMXPROLOG();
2155   UINT8 modrm = FETCH();
2156   if( modrm >= 0xc0 ) {
2157      int s,d;
2158      s=modrm & 0x7;
2159      d=(modrm >> 3) & 0x7;
2160      for (c=0;c <= 1;c++)
2161         MMX(d).d[c]=(MMX(d).i[c] > MMX(s).i[c]) ? 0xffffffff : 0;
2162   } else {
2163      MMX_REG s;
2164      int d=(modrm >> 3) & 0x7;
2165      UINT32 ea = GetEA(modrm, 0);
2166      READMMX(ea, s);
2167      for (c=0;c <= 1;c++)
2168         MMX(d).d[c]=(MMX(d).i[c] > s.i[c]) ? 0xffffffff : 0;
2169   }
2170   CYCLES(1);     // TODO: correct cycle count
2171}
2172
2173void i386_device::mmx_packuswb_r64_rm64() // Opcode 0f 67
2174{
2175   MMXPROLOG();
2176   UINT8 modrm = FETCH();
2177   if( modrm >= 0xc0 ) {
2178      int s,d;
2179      s=modrm & 0x7;
2180      d=(modrm >> 3) & 0x7;
2181      MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(MMX(d).s[0]);
2182      MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(MMX(d).s[1]);
2183      MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(MMX(d).s[2]);
2184      MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(MMX(d).s[3]);
2185      MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(MMX(s).s[0]);
2186      MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(MMX(s).s[1]);
2187      MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(MMX(s).s[2]);
2188      MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(MMX(s).s[3]);
2189   } else {
2190      MMX_REG s;
2191      int d=(modrm >> 3) & 0x7;
2192      UINT32 ea = GetEA(modrm, 0);
2193      READMMX(ea, s);
2194      MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(MMX(d).s[0]);
2195      MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(MMX(d).s[1]);
2196      MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(MMX(d).s[2]);
2197      MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(MMX(d).s[3]);
2198      MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(s.s[0]);
2199      MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(s.s[1]);
2200      MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(s.s[2]);
2201      MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(s.s[3]);
2202   }
2203   CYCLES(1);     // TODO: correct cycle count
2204}
2205
2206void i386_device::mmx_punpckhbw_r64_rm64() // Opcode 0f 68
2207{
2208   MMXPROLOG();
2209   UINT8 modrm = FETCH();
2210   if( modrm >= 0xc0 ) {
2211      int s,d;
2212      s=modrm & 0x7;
2213      d=(modrm >> 3) & 0x7;
2214      MMX(d).b[0]=MMX(d).b[4];
2215      MMX(d).b[1]=MMX(s).b[4];
2216      MMX(d).b[2]=MMX(d).b[5];
2217      MMX(d).b[3]=MMX(s).b[5];
2218      MMX(d).b[4]=MMX(d).b[6];
2219      MMX(d).b[5]=MMX(s).b[6];
2220      MMX(d).b[6]=MMX(d).b[7];
2221      MMX(d).b[7]=MMX(s).b[7];
2222   } else {
2223      MMX_REG s;
2224      int d=(modrm >> 3) & 0x7;
2225      UINT32 ea = GetEA(modrm, 0);
2226      READMMX(ea, s);
2227      MMX(d).b[0]=MMX(d).b[4];
2228      MMX(d).b[1]=s.b[4];
2229      MMX(d).b[2]=MMX(d).b[5];
2230      MMX(d).b[3]=s.b[5];
2231      MMX(d).b[4]=MMX(d).b[6];
2232      MMX(d).b[5]=s.b[6];
2233      MMX(d).b[6]=MMX(d).b[7];
2234      MMX(d).b[7]=s.b[7];
2235   }
2236   CYCLES(1);     // TODO: correct cycle count
2237}
2238
2239void i386_device::mmx_punpckhwd_r64_rm64() // Opcode 0f 69
2240{
2241   MMXPROLOG();
2242   UINT8 modrm = FETCH();
2243   if( modrm >= 0xc0 ) {
2244      int s,d;
2245      s=modrm & 0x7;
2246      d=(modrm >> 3) & 0x7;
2247      MMX(d).w[0]=MMX(d).w[2];
2248      MMX(d).w[1]=MMX(s).w[2];
2249      MMX(d).w[2]=MMX(d).w[3];
2250      MMX(d).w[3]=MMX(s).w[3];
2251   } else {
2252      MMX_REG s;
2253      int d=(modrm >> 3) & 0x7;
2254      UINT32 ea = GetEA(modrm, 0);
2255      READMMX(ea, s);
2256      MMX(d).w[0]=MMX(d).w[2];
2257      MMX(d).w[1]=s.w[2];
2258      MMX(d).w[2]=MMX(d).w[3];
2259      MMX(d).w[3]=s.w[3];
2260   }
2261   CYCLES(1);     // TODO: correct cycle count
2262}
2263
2264void i386_device::mmx_punpckhdq_r64_rm64() // Opcode 0f 6a
2265{
2266   MMXPROLOG();
2267   UINT8 modrm = FETCH();
2268   if( modrm >= 0xc0 ) {
2269      int s,d;
2270      s=modrm & 0x7;
2271      d=(modrm >> 3) & 0x7;
2272      MMX(d).d[0]=MMX(d).d[1];
2273      MMX(d).d[1]=MMX(s).d[1];
2274   } else {
2275      MMX_REG s;
2276      int d=(modrm >> 3) & 0x7;
2277      UINT32 ea = GetEA(modrm, 0);
2278      READMMX(ea, s);
2279      MMX(d).d[0]=MMX(d).d[1];
2280      MMX(d).d[1]=s.d[1];
2281   }
2282   CYCLES(1);     // TODO: correct cycle count
2283}
2284
2285void i386_device::mmx_packssdw_r64_rm64() // Opcode 0f 6b
2286{
2287   MMXPROLOG();
2288   UINT8 modrm = FETCH();
2289   if( modrm >= 0xc0 ) {
2290      int s,d;
2291      s=modrm & 0x7;
2292      d=(modrm >> 3) & 0x7;
2293      MMX(d).s[0]=SaturatedSignedDwordToSignedWord(MMX(d).i[0]);
2294      MMX(d).s[1]=SaturatedSignedDwordToSignedWord(MMX(d).i[1]);
2295      MMX(d).s[2]=SaturatedSignedDwordToSignedWord(MMX(s).i[0]);
2296      MMX(d).s[3]=SaturatedSignedDwordToSignedWord(MMX(s).i[1]);
2297   } else {
2298      MMX_REG s;
2299      int d=(modrm >> 3) & 0x7;
2300      UINT32 ea = GetEA(modrm, 0);
2301      READMMX(ea, s);
2302      MMX(d).s[0]=SaturatedSignedDwordToSignedWord(MMX(d).i[0]);
2303      MMX(d).s[1]=SaturatedSignedDwordToSignedWord(MMX(d).i[1]);
2304      MMX(d).s[2]=SaturatedSignedDwordToSignedWord(s.i[0]);
2305      MMX(d).s[3]=SaturatedSignedDwordToSignedWord(s.i[1]);
2306   }
2307   CYCLES(1);     // TODO: correct cycle count
2308}
2309
2310void i386_device::sse_sse_group0fae()  // Opcode 0f ae
2311{
2312   UINT8 modm = FETCH();
2313   if( modm == 0xf8 ) {
2314      logerror("Unemulated SFENCE opcode called\n");
2315      CYCLES(1); // sfence instruction
2316   } else if( modm == 0xf0 ) {
2317      CYCLES(1); // mfence instruction
2318   } else if( modm == 0xe8 ) {
2319      CYCLES(1); // lfence instruction
2320   } else if( modm < 0xc0 ) {
2321      UINT32 ea;
2322      switch ( (modm & 0x38) >> 3 )
2323      {
2324         case 2: // ldmxcsr m32
2325            ea = GetEA(modm, 0);
2326            m_mxcsr = READ32(ea);
2327            break;
2328         case 3: // stmxcsr m32
2329            ea = GetEA(modm, 0);
2330            WRITE32(ea, m_mxcsr);
2331            break;
2332         case 7: // clflush m8
2333            GetNonTranslatedEA(modm, NULL);
2334            break;
2335         default:
2336            report_invalid_modrm("sse_group0fae", modm);
2337      }
2338   } else {
2339      report_invalid_modrm("sse_group0fae", modm);
2340   }
2341}
2342
2343void i386_device::sse_cvttps2dq_r128_rm128() // Opcode f3 0f 5b
2344{
2345   UINT8 modrm = FETCH();
2346   if( modrm >= 0xc0 ) {
2347      XMM((modrm >> 3) & 0x7).i[0]=(INT32)XMM(modrm & 0x7).f[0];
2348      XMM((modrm >> 3) & 0x7).i[1]=(INT32)XMM(modrm & 0x7).f[1];
2349      XMM((modrm >> 3) & 0x7).i[2]=(INT32)XMM(modrm & 0x7).f[2];
2350      XMM((modrm >> 3) & 0x7).i[3]=(INT32)XMM(modrm & 0x7).f[3];
2351   } else {
2352      XMM_REG src;
2353      UINT32 ea = GetEA(modrm, 0);
2354      READXMM(ea, src);
2355      XMM((modrm >> 3) & 0x7).i[0]=(INT32)src.f[0];
2356      XMM((modrm >> 3) & 0x7).i[1]=(INT32)src.f[1];
2357      XMM((modrm >> 3) & 0x7).i[2]=(INT32)src.f[2];
2358      XMM((modrm >> 3) & 0x7).i[3]=(INT32)src.f[3];
2359   }
2360   CYCLES(1);     // TODO: correct cycle count
2361}
2362
2363void i386_device::sse_cvtss2sd_r128_r128m32() // Opcode f3 0f 5a
2364{
2365   UINT8 modrm = FETCH();
2366   if( modrm >= 0xc0 ) {
2367      XMM((modrm >> 3) & 0x7).f64[0] = XMM(modrm & 0x7).f[0];
2368   } else {
2369      XMM_REG s;
2370      UINT32 ea = GetEA(modrm, 0);
2371      s.d[0] = READ32(ea);
2372      XMM((modrm >> 3) & 0x7).f64[0] = s.f[0];
2373   }
2374   CYCLES(1);     // TODO: correct cycle count
2375}
2376
2377void i386_device::sse_cvttss2si_r32_r128m32() // Opcode f3 0f 2c
2378{
2379   INT32 src;
2380   UINT8 modrm = FETCH(); // get mordm byte
2381   if( modrm >= 0xc0 ) { // if bits 7-6 are 11 the source is a xmm register (low doubleword)
2382      src = (INT32)XMM(modrm & 0x7).f[0^NATIVE_ENDIAN_VALUE_LE_BE(0,1)];
2383   } else { // otherwise is a memory address
2384      XMM_REG t;
2385      UINT32 ea = GetEA(modrm, 0);
2386      t.d[0] = READ32(ea);
2387      src = (INT32)t.f[0];
2388   }
2389   STORE_REG32(modrm, (UINT32)src);
2390   CYCLES(1);     // TODO: correct cycle count
2391}
2392
2393void i386_device::sse_cvtss2si_r32_r128m32() // Opcode f3 0f 2d
2394{
2395   INT32 src;
2396   UINT8 modrm = FETCH();
2397   if( modrm >= 0xc0 ) {
2398      src = (INT32)XMM(modrm & 0x7).f[0];
2399   } else {
2400      XMM_REG t;
2401      UINT32 ea = GetEA(modrm, 0);
2402      t.d[0] = READ32(ea);
2403      src = (INT32)t.f[0];
2404   }
2405   STORE_REG32(modrm, (UINT32)src);
2406   CYCLES(1);     // TODO: correct cycle count
2407}
2408
2409void i386_device::sse_cvtsi2ss_r128_rm32() // Opcode f3 0f 2a
2410{
2411   UINT8 modrm = FETCH();
2412   if( modrm >= 0xc0 ) {
2413      XMM((modrm >> 3) & 0x7).f[0] = (INT32)LOAD_RM32(modrm);
2414   } else {
2415      UINT32 ea = GetEA(modrm, 0);
2416      XMM((modrm >> 3) & 0x7).f[0] = (INT32)READ32(ea);
2417   }
2418   CYCLES(1);     // TODO: correct cycle count
2419}
2420
2421void i386_device::sse_cvtpi2ps_r128_rm64() // Opcode 0f 2a
2422{
2423   UINT8 modrm = FETCH();
2424   MMXPROLOG();
2425   if( modrm >= 0xc0 ) {
2426      XMM((modrm >> 3) & 0x7).f[0] = MMX(modrm & 0x7).i[0];
2427      XMM((modrm >> 3) & 0x7).f[1] = MMX(modrm & 0x7).i[1];
2428   } else {
2429      MMX_REG r;
2430      UINT32 ea = GetEA(modrm, 0);
2431      READMMX(ea, r);
2432      XMM((modrm >> 3) & 0x7).f[0] = r.i[0];
2433      XMM((modrm >> 3) & 0x7).f[1] = r.i[1];
2434   }
2435   CYCLES(1);     // TODO: correct cycle count
2436}
2437
2438void i386_device::sse_cvttps2pi_r64_r128m64() // Opcode 0f 2c
2439{
2440   UINT8 modrm = FETCH();
2441   MMXPROLOG();
2442   if( modrm >= 0xc0 ) {
2443      MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0];
2444      MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1];
2445   } else {
2446      XMM_REG r;
2447      UINT32 ea = GetEA(modrm, 0);
2448      READXMM(ea, r);
2449      XMM((modrm >> 3) & 0x7).i[0] = r.f[0];
2450      XMM((modrm >> 3) & 0x7).i[1] = r.f[1];
2451   }
2452   CYCLES(1);     // TODO: correct cycle count
2453}
2454
2455void i386_device::sse_cvtps2pi_r64_r128m64() // Opcode 0f 2d
2456{
2457   UINT8 modrm = FETCH();
2458   MMXPROLOG();
2459   if( modrm >= 0xc0 ) {
2460      MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0];
2461      MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1];
2462   } else {
2463      XMM_REG r;
2464      UINT32 ea = GetEA(modrm, 0);
2465      READXMM(ea, r);
2466      XMM((modrm >> 3) & 0x7).i[0] = r.f[0];
2467      XMM((modrm >> 3) & 0x7).i[1] = r.f[1];
2468   }
2469   CYCLES(1);     // TODO: correct cycle count
2470}
2471
2472void i386_device::sse_cvtps2pd_r128_r128m64() // Opcode 0f 5a
2473{
2474   UINT8 modrm = FETCH();
2475   if( modrm >= 0xc0 ) {
2476      XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).f[0];
2477      XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).f[1];
2478   } else {
2479      MMX_REG r;
2480      UINT32 ea = GetEA(modrm, 0);
2481      READMMX(ea, r);
2482      XMM((modrm >> 3) & 0x7).f64[0] = (double)r.f[0];
2483      XMM((modrm >> 3) & 0x7).f64[1] = (double)r.f[1];
2484   }
2485   CYCLES(1);     // TODO: correct cycle count
2486}
2487
2488void i386_device::sse_cvtdq2ps_r128_rm128() // Opcode 0f 5b
2489{
2490   UINT8 modrm = FETCH();
2491   if( modrm >= 0xc0 ) {
2492      XMM((modrm >> 3) & 0x7).f[0] = (float)XMM(modrm & 0x7).i[0];
2493      XMM((modrm >> 3) & 0x7).f[1] = (float)XMM(modrm & 0x7).i[1];
2494      XMM((modrm >> 3) & 0x7).f[2] = (float)XMM(modrm & 0x7).i[2];
2495      XMM((modrm >> 3) & 0x7).f[3] = (float)XMM(modrm & 0x7).i[3];
2496   } else {
2497      XMM_REG r;
2498      UINT32 ea = GetEA(modrm, 0);
2499      READXMM(ea, r);
2500      XMM((modrm >> 3) & 0x7).f[0] = (float)r.i[0];
2501      XMM((modrm >> 3) & 0x7).f[1] = (float)r.i[1];
2502      XMM((modrm >> 3) & 0x7).f[2] = (float)r.i[2];
2503      XMM((modrm >> 3) & 0x7).f[3] = (float)r.i[3];
2504   }
2505   CYCLES(1);     // TODO: correct cycle count
2506}
2507
2508void i386_device::sse_cvtdq2pd_r128_r128m64() // Opcode f3 0f e6
2509{
2510   UINT8 modrm = FETCH();
2511   if( modrm >= 0xc0 ) {
2512      XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).i[0];
2513      XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).i[1];
2514   } else {
2515      MMX_REG s;
2516      UINT32 ea = GetEA(modrm, 0);
2517      READMMX(ea, s);
2518      XMM((modrm >> 3) & 0x7).f64[0] = (double)s.i[0];
2519      XMM((modrm >> 3) & 0x7).f64[1] = (double)s.i[1];
2520   }
2521   CYCLES(1);     // TODO: correct cycle count
2522}
2523
2524void i386_device::sse_movss_r128_rm128() // Opcode f3 0f 10
2525{
2526   UINT8 modrm = FETCH();
2527   if( modrm >= 0xc0 ) {
2528      XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0];
2529   } else {
2530      UINT32 ea = GetEA(modrm, 0);
2531      XMM((modrm >> 3) & 0x7).d[0] = READ32(ea);
2532   }
2533   CYCLES(1);     // TODO: correct cycle count
2534}
2535
2536void i386_device::sse_movss_rm128_r128() // Opcode f3 0f 11
2537{
2538   UINT8 modrm = FETCH();
2539   if( modrm >= 0xc0 ) {
2540      XMM(modrm & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0];
2541   } else {
2542      UINT32 ea = GetEA(modrm, 0);
2543      WRITE32(ea, XMM((modrm >> 3) & 0x7).d[0]);
2544   }
2545   CYCLES(1);     // TODO: correct cycle count
2546}
2547
2548void i386_device::sse_movsldup_r128_rm128() // Opcode f3 0f 12
2549{
2550   UINT8 modrm = FETCH();
2551   if( modrm >= 0xc0 ) {
2552      XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0];
2553      XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[0];
2554      XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[2];
2555      XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[2];
2556   } else {
2557      XMM_REG src;
2558      UINT32 ea = GetEA(modrm, 0);
2559      READXMM(ea, src);
2560      XMM((modrm >> 3) & 0x7).d[0] = src.d[0];
2561      XMM((modrm >> 3) & 0x7).d[1] = src.d[0];
2562      XMM((modrm >> 3) & 0x7).d[2] = src.d[2];
2563      XMM((modrm >> 3) & 0x7).d[3] = src.d[2];
2564   }
2565   CYCLES(1);     // TODO: correct cycle count
2566}
2567
2568void i386_device::sse_movshdup_r128_rm128() // Opcode f3 0f 16
2569{
2570   UINT8 modrm = FETCH();
2571   if( modrm >= 0xc0 ) {
2572      XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[1];
2573      XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[1];
2574      XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[3];
2575      XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[3];
2576   } else {
2577      XMM_REG src;
2578      UINT32 ea = GetEA(modrm, 0);
2579      READXMM(ea, src);
2580      XMM((modrm >> 3) & 0x7).d[0] = src.d[1];
2581      XMM((modrm >> 3) & 0x7).d[1] = src.d[1];
2582      XMM((modrm >> 3) & 0x7).d[2] = src.d[3];
2583      XMM((modrm >> 3) & 0x7).d[3] = src.d[3];
2584   }
2585   CYCLES(1);     // TODO: correct cycle count
2586}
2587
2588void i386_device::sse_movaps_r128_rm128() // Opcode 0f 28
2589{
2590   UINT8 modrm = FETCH();
2591   if( modrm >= 0xc0 ) {
2592      XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7);
2593   } else {
2594      UINT32 ea = GetEA(modrm, 0);
2595      READXMM(ea, XMM((modrm >> 3) & 0x7));
2596   }
2597   CYCLES(1);     // TODO: correct cycle count
2598}
2599
2600void i386_device::sse_movaps_rm128_r128() // Opcode 0f 29
2601{
2602   UINT8 modrm = FETCH();
2603   if( modrm >= 0xc0 ) {
2604      XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7);
2605   } else {
2606      UINT32 ea = GetEA(modrm, 0);
2607      WRITEXMM(ea, XMM((modrm >> 3) & 0x7));
2608   }
2609   CYCLES(1);     // TODO: correct cycle count
2610}
2611
2612void i386_device::sse_movups_r128_rm128() // Opcode 0f 10
2613{
2614   UINT8 modrm = FETCH();
2615   if( modrm >= 0xc0 ) {
2616      XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7);
2617   } else {
2618      UINT32 ea = GetEA(modrm, 0);
2619      READXMM(ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
2620   }
2621   CYCLES(1);     // TODO: correct cycle count
2622}
2623
2624void i386_device::sse_movups_rm128_r128() // Opcode 0f 11
2625{
2626   UINT8 modrm = FETCH();
2627   if( modrm >= 0xc0 ) {
2628      XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7);
2629   } else {
2630      UINT32 ea = GetEA(modrm, 0);
2631      WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
2632   }
2633   CYCLES(1);     // TODO: correct cycle count
2634}
2635
2636void i386_device::sse_movlps_r128_m64() // Opcode 0f 12
2637{
2638   UINT8 modrm = FETCH();
2639   if( modrm >= 0xc0 ) {
2640      // unsupported by cpu
2641      CYCLES(1);     // TODO: correct cycle count
2642   } else {
2643      UINT32 ea = GetEA(modrm, 0);
2644      READXMM_LO64(ea, XMM((modrm >> 3) & 0x7));
2645      CYCLES(1);     // TODO: correct cycle count
2646   }
2647}
2648
2649void i386_device::sse_movlps_m64_r128() // Opcode 0f 13
2650{
2651   UINT8 modrm = FETCH();
2652   if( modrm >= 0xc0 ) {
2653      // unsupported by cpu
2654      CYCLES(1);     // TODO: correct cycle count
2655   } else {
2656      UINT32 ea = GetEA(modrm, 0);
2657      WRITEXMM_LO64(ea, XMM((modrm >> 3) & 0x7));
2658      CYCLES(1);     // TODO: correct cycle count
2659   }
2660}
2661
2662void i386_device::sse_movhps_r128_m64() // Opcode 0f 16
2663{
2664   UINT8 modrm = FETCH();
2665   if( modrm >= 0xc0 ) {
2666      // unsupported by cpu
2667      CYCLES(1);     // TODO: correct cycle count
2668   } else {
2669      UINT32 ea = GetEA(modrm, 0);
2670      READXMM_HI64(ea, XMM((modrm >> 3) & 0x7));
2671      CYCLES(1);     // TODO: correct cycle count
2672   }
2673}
2674
2675void i386_device::sse_movhps_m64_r128() // Opcode 0f 17
2676{
2677   UINT8 modrm = FETCH();
2678   if( modrm >= 0xc0 ) {
2679      // unsupported by cpu
2680      CYCLES(1);     // TODO: correct cycle count
2681   } else {
2682      UINT32 ea = GetEA(modrm, 0);
2683      WRITEXMM_HI64(ea, XMM((modrm >> 3) & 0x7));
2684      CYCLES(1);     // TODO: correct cycle count
2685   }
2686}
2687
2688void i386_device::sse_movntps_m128_r128() // Opcode 0f 2b
2689{
2690   UINT8 modrm = FETCH();
2691   if( modrm >= 0xc0 ) {
2692      // unsupported by cpu
2693      CYCLES(1);     // TODO: correct cycle count
2694   } else {
2695      // since cache is not implemented
2696      UINT32 ea = GetEA(modrm, 0);
2697      WRITEXMM(ea, XMM((modrm >> 3) & 0x7));
2698      CYCLES(1);     // TODO: correct cycle count
2699   }
2700}
2701
2702void i386_device::sse_movmskps_r16_r128() // Opcode 0f 50
2703{
2704   UINT8 modrm = FETCH();
2705   if( modrm >= 0xc0 ) {
2706      int b;
2707      b=(XMM(modrm & 0x7).d[0] >> 31) & 1;
2708      b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2);
2709      b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4);
2710      b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8);
2711      STORE_REG16(modrm, b);
2712   }
2713   CYCLES(1);     // TODO: correct cycle count
2714}
2715
2716void i386_device::sse_movmskps_r32_r128() // Opcode 0f 50
2717{
2718   UINT8 modrm = FETCH();
2719   if( modrm >= 0xc0 ) {
2720      int b;
2721      b=(XMM(modrm & 0x7).d[0] >> 31) & 1;
2722      b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2);
2723      b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4);
2724      b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8);
2725      STORE_REG32(modrm, b);
2726   }
2727   CYCLES(1);     // TODO: correct cycle count
2728}
2729
2730void i386_device::sse_movq2dq_r128_r64() // Opcode f3 0f d6
2731{
2732   MMXPROLOG();
2733   UINT8 modrm = FETCH();
2734   if( modrm >= 0xc0 ) {
2735      XMM((modrm >> 3) & 0x7).q[0] = MMX(modrm & 7).q;
2736      XMM((modrm >> 3) & 0x7).q[1] = 0;
2737   }
2738   CYCLES(1);     // TODO: correct cycle count
2739}
2740
2741void i386_device::sse_movdqu_r128_rm128() // Opcode f3 0f 6f
2742{
2743   MMXPROLOG();
2744   UINT8 modrm = FETCH();
2745   if( modrm >= 0xc0 ) {
2746      XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
2747      XMM((modrm >> 3) & 0x7).q[1] = XMM(modrm & 0x7).q[1];
2748   } else {
2749      UINT32 ea = GetEA(modrm, 0);
2750      READXMM(ea, XMM((modrm >> 3) & 0x7));
2751   }
2752   CYCLES(1);     // TODO: correct cycle count
2753}
2754
2755void i386_device::sse_movdqu_rm128_r128() // Opcode f3 0f 7f
2756{
2757   MMXPROLOG();
2758   UINT8 modrm = FETCH();
2759   if( modrm >= 0xc0 ) {
2760      XMM(modrm & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0];
2761      XMM(modrm & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1];
2762   } else {
2763      UINT32 ea = GetEA(modrm, 0);
2764      WRITEXMM(ea, XMM((modrm >> 3) & 0x7));
2765   }
2766   CYCLES(1);     // TODO: correct cycle count
2767}
2768
2769void i386_device::sse_movq_r128_r128m64() // Opcode f3 0f 7e
2770{
2771   MMXPROLOG();
2772   UINT8 modrm = FETCH();
2773   if( modrm >= 0xc0 ) {
2774      XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
2775      XMM((modrm >> 3) & 0x7).q[1] = 0;
2776   } else {
2777      UINT32 ea = GetEA(modrm, 0);
2778      XMM((modrm >> 3) & 0x7).q[0] = READ64(ea);
2779      XMM((modrm >> 3) & 0x7).q[1] = 0;
2780   }
2781   CYCLES(1);     // TODO: correct cycle count
2782}
2783
2784void i386_device::sse_pmovmskb_r16_r64() // Opcode 0f d7
2785{
2786   //MMXPROLOG();
2787   UINT8 modrm = FETCH();
2788   if( modrm >= 0xc0 ) {
2789      int b;
2790      b=(MMX(modrm & 0x7).b[0] >> 7) & 1;
2791      b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2);
2792      b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4);
2793      b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8);
2794      b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16);
2795      b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32);
2796      b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64);
2797      b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128);
2798      STORE_REG16(modrm, b);
2799   }
2800   CYCLES(1);     // TODO: correct cycle count
2801}
2802
2803void i386_device::sse_pmovmskb_r32_r64() // Opcode 0f d7
2804{
2805   //MMXPROLOG();
2806   UINT8 modrm = FETCH();
2807   if( modrm >= 0xc0 ) {
2808      int b;
2809      b=(MMX(modrm & 0x7).b[0] >> 7) & 1;
2810      b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2);
2811      b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4);
2812      b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8);
2813      b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16);
2814      b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32);
2815      b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64);
2816      b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128);
2817      STORE_REG32(modrm, b);
2818   }
2819   CYCLES(1);     // TODO: correct cycle count
2820}
2821
2822void i386_device::sse_xorps() // Opcode 0f 57
2823{
2824   UINT8 modrm = FETCH();
2825   if( modrm >= 0xc0 ) {
2826      XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ XMM(modrm & 0x7).d[0];
2827      XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ XMM(modrm & 0x7).d[1];
2828      XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ XMM(modrm & 0x7).d[2];
2829      XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ XMM(modrm & 0x7).d[3];
2830   } else {
2831      XMM_REG src;
2832      UINT32 ea = GetEA(modrm, 0);
2833      READXMM(ea, src);
2834      XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ src.d[0];
2835      XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ src.d[1];
2836      XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ src.d[2];
2837      XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ src.d[3];
2838   }
2839   CYCLES(1);     // TODO: correct cycle count
2840}
2841
2842void i386_device::sse_addps() // Opcode 0f 58
2843{
2844   UINT8 modrm = FETCH();
2845   if( modrm >= 0xc0 ) {
2846      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + XMM(modrm & 0x7).f[0];
2847      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] + XMM(modrm & 0x7).f[1];
2848      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] + XMM(modrm & 0x7).f[2];
2849      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] + XMM(modrm & 0x7).f[3];
2850   } else {
2851      XMM_REG src;
2852      UINT32 ea = GetEA(modrm, 0);
2853      READXMM(ea, src);
2854      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + src.f[0];
2855      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] + src.f[1];
2856      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] + src.f[2];
2857      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] + src.f[3];
2858   }
2859   CYCLES(1);     // TODO: correct cycle count
2860}
2861
2862void i386_device::sse_sqrtps_r128_rm128() // Opcode 0f 51
2863{
2864   UINT8 modrm = FETCH();
2865   if( modrm >= 0xc0 ) {
2866      XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]);
2867      XMM((modrm >> 3) & 0x7).f[1] = sqrt(XMM(modrm & 0x7).f[1]);
2868      XMM((modrm >> 3) & 0x7).f[2] = sqrt(XMM(modrm & 0x7).f[2]);
2869      XMM((modrm >> 3) & 0x7).f[3] = sqrt(XMM(modrm & 0x7).f[3]);
2870   } else {
2871      XMM_REG src;
2872      UINT32 ea = GetEA(modrm, 0);
2873      READXMM(ea, src);
2874      XMM((modrm >> 3) & 0x7).f[0] = sqrt(src.f[0]);
2875      XMM((modrm >> 3) & 0x7).f[1] = sqrt(src.f[1]);
2876      XMM((modrm >> 3) & 0x7).f[2] = sqrt(src.f[2]);
2877      XMM((modrm >> 3) & 0x7).f[3] = sqrt(src.f[3]);
2878   }
2879   CYCLES(1);     // TODO: correct cycle count
2880}
2881
2882void i386_device::sse_rsqrtps_r128_rm128() // Opcode 0f 52
2883{
2884   UINT8 modrm = FETCH();
2885   if( modrm >= 0xc0 ) {
2886      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]);
2887      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(XMM(modrm & 0x7).f[1]);
2888      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(XMM(modrm & 0x7).f[2]);
2889      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(XMM(modrm & 0x7).f[3]);
2890   } else {
2891      XMM_REG src;
2892      UINT32 ea = GetEA(modrm, 0);
2893      READXMM(ea, src);
2894      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(src.f[0]);
2895      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(src.f[1]);
2896      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(src.f[2]);
2897      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(src.f[3]);
2898   }
2899   CYCLES(1);     // TODO: correct cycle count
2900}
2901
2902void i386_device::sse_rcpps_r128_rm128() // Opcode 0f 53
2903{
2904   UINT8 modrm = FETCH();
2905   if( modrm >= 0xc0 ) {
2906      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / XMM(modrm & 0x7).f[0];
2907      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / XMM(modrm & 0x7).f[1];
2908      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / XMM(modrm & 0x7).f[2];
2909      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / XMM(modrm & 0x7).f[3];
2910   } else {
2911      XMM_REG src;
2912      UINT32 ea = GetEA(modrm, 0);
2913      READXMM(ea, src);
2914      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / src.f[0];
2915      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / src.f[1];
2916      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / src.f[2];
2917      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / src.f[3];
2918   }
2919   CYCLES(1);     // TODO: correct cycle count
2920}
2921
2922void i386_device::sse_andps_r128_rm128() // Opcode 0f 54
2923{
2924   UINT8 modrm = FETCH();
2925   if( modrm >= 0xc0 ) {
2926      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & XMM(modrm & 0x7).q[0];
2927      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & XMM(modrm & 0x7).q[1];
2928   } else {
2929      XMM_REG src;
2930      UINT32 ea = GetEA(modrm, 0);
2931      READXMM(ea, src);
2932      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & src.q[0];
2933      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & src.q[1];
2934   }
2935   CYCLES(1);     // TODO: correct cycle count
2936}
2937
2938void i386_device::sse_andnps_r128_rm128() // Opcode 0f 55
2939{
2940   UINT8 modrm = FETCH();
2941   if( modrm >= 0xc0 ) {
2942      XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & XMM(modrm & 0x7).q[0];
2943      XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & XMM(modrm & 0x7).q[1];
2944   } else {
2945      XMM_REG src;
2946      UINT32 ea = GetEA(modrm, 0);
2947      READXMM(ea, src);
2948      XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & src.q[0];
2949      XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & src.q[1];
2950   }
2951   CYCLES(1);     // TODO: correct cycle count
2952}
2953
2954void i386_device::sse_orps_r128_rm128() // Opcode 0f 56
2955{
2956   UINT8 modrm = FETCH();
2957   if( modrm >= 0xc0 ) {
2958      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | XMM(modrm & 0x7).q[0];
2959      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | XMM(modrm & 0x7).q[1];
2960   } else {
2961      XMM_REG src;
2962      UINT32 ea = GetEA(modrm, 0);
2963      READXMM(ea, src);
2964      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | src.q[0];
2965      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | src.q[1];
2966   }
2967   CYCLES(1);     // TODO: correct cycle count
2968}
2969
2970void i386_device::sse_mulps() // Opcode 0f 59 ????
2971{
2972   UINT8 modrm = FETCH();
2973   if( modrm >= 0xc0 ) {
2974      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0];
2975      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] * XMM(modrm & 0x7).f[1];
2976      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * XMM(modrm & 0x7).f[2];
2977      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] * XMM(modrm & 0x7).f[3];
2978   } else {
2979      XMM_REG src;
2980      UINT32 ea = GetEA(modrm, 0);
2981      READXMM(ea, src);
2982      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * src.f[0];
2983      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] * src.f[1];
2984      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * src.f[2];
2985      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] * src.f[3];
2986   }
2987   CYCLES(1);     // TODO: correct cycle count
2988}
2989
2990void i386_device::sse_subps() // Opcode 0f 5c
2991{
2992   UINT8 modrm = FETCH();
2993   if( modrm >= 0xc0 ) {
2994      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0];
2995      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - XMM(modrm & 0x7).f[1];
2996      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - XMM(modrm & 0x7).f[2];
2997      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - XMM(modrm & 0x7).f[3];
2998   } else {
2999      XMM_REG src;
3000      UINT32 ea = GetEA(modrm, 0);
3001      READXMM(ea, src);
3002      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0];
3003      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - src.f[1];
3004      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - src.f[2];
3005      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - src.f[3];
3006   }
3007   CYCLES(1);     // TODO: correct cycle count
3008}
3009
3010INLINE float sse_min_single(float src1, float src2)
3011{
3012   /*if ((src1 == 0) && (src2 == 0))
3013       return src2;
3014   if (src1 = SNaN)
3015       return src2;
3016   if (src2 = SNaN)
3017       return src2;*/
3018   if (src1 < src2)
3019      return src1;
3020   return src2;
3021}
3022
3023void i386_device::sse_minps() // Opcode 0f 5d
3024{
3025   UINT8 modrm = FETCH();
3026   if( modrm >= 0xc0 ) {
3027      XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
3028      XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]);
3029      XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]);
3030      XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]);
3031   } else {
3032      XMM_REG src;
3033      UINT32 ea = GetEA(modrm, 0);
3034      READXMM(ea, src);
3035      XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
3036      XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]);
3037      XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]);
3038      XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]);
3039   }
3040   CYCLES(1);     // TODO: correct cycle count
3041}
3042
3043void i386_device::sse_divps() // Opcode 0f 5e
3044{
3045   UINT8 modrm = FETCH();
3046   if( modrm >= 0xc0 ) {
3047      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0];
3048      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / XMM(modrm & 0x7).f[1];
3049      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / XMM(modrm & 0x7).f[2];
3050      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / XMM(modrm & 0x7).f[3];
3051   } else {
3052      XMM_REG src;
3053      UINT32 ea = GetEA(modrm, 0);
3054      READXMM(ea, src);
3055      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0];
3056      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / src.f[1];
3057      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / src.f[2];
3058      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / src.f[3];
3059   }
3060   CYCLES(1);     // TODO: correct cycle count
3061}
3062
3063INLINE float sse_max_single(float src1, float src2)
3064{
3065   /*if ((src1 == 0) && (src2 == 0))
3066       return src2;
3067   if (src1 = SNaN)
3068       return src2;
3069   if (src2 = SNaN)
3070       return src2;*/
3071   if (src1 > src2)
3072      return src1;
3073   return src2;
3074}
3075
3076void i386_device::sse_maxps() // Opcode 0f 5f
3077{
3078   UINT8 modrm = FETCH();
3079   if( modrm >= 0xc0 ) {
3080      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
3081      XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]);
3082      XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]);
3083      XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]);
3084   } else {
3085      XMM_REG src;
3086      UINT32 ea = GetEA(modrm, 0);
3087      READXMM(ea, src);
3088      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
3089      XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]);
3090      XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]);
3091      XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]);
3092   }
3093   CYCLES(1);     // TODO: correct cycle count
3094}
3095
3096void i386_device::sse_maxss_r128_r128m32() // Opcode f3 0f 5f
3097{
3098   UINT8 modrm = FETCH();
3099   if( modrm >= 0xc0 ) {
3100      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
3101   } else {
3102      XMM_REG src;
3103      UINT32 ea = GetEA(modrm, 0);
3104      src.d[0]=READ32(ea);
3105      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
3106   }
3107   CYCLES(1);     // TODO: correct cycle count
3108}
3109
3110void i386_device::sse_addss() // Opcode f3 0f 58
3111{
3112   UINT8 modrm = FETCH();
3113   if( modrm >= 0xc0 ) {
3114      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + XMM(modrm & 0x7).f[0];
3115   } else {
3116      XMM_REG src;
3117      UINT32 ea = GetEA(modrm, 0);
3118      READXMM(ea, src);
3119      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + src.f[0];
3120   }
3121   CYCLES(1);     // TODO: correct cycle count
3122}
3123
3124void i386_device::sse_subss() // Opcode f3 0f 5c
3125{
3126   UINT8 modrm = FETCH();
3127   if( modrm >= 0xc0 ) {
3128      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0];
3129   } else {
3130      XMM_REG src;
3131      UINT32 ea = GetEA(modrm, 0);
3132      READXMM(ea, src);
3133      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0];
3134   }
3135   CYCLES(1);     // TODO: correct cycle count
3136}
3137
3138void i386_device::sse_mulss() // Opcode f3 0f 5e
3139{
3140   UINT8 modrm = FETCH();
3141   if( modrm >= 0xc0 ) {
3142      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0];
3143   } else {
3144      XMM_REG src;
3145      UINT32 ea = GetEA(modrm, 0);
3146      READXMM(ea, src);
3147      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * src.f[0];
3148   }
3149   CYCLES(1);     // TODO: correct cycle count
3150}
3151
3152void i386_device::sse_divss() // Opcode 0f 59
3153{
3154   UINT8 modrm = FETCH();
3155   if( modrm >= 0xc0 ) {
3156      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0];
3157   } else {
3158      XMM_REG src;
3159      UINT32 ea = GetEA(modrm, 0);
3160      READXMM(ea, src);
3161      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0];
3162   }
3163   CYCLES(1);     // TODO: correct cycle count
3164}
3165
3166void i386_device::sse_rcpss_r128_r128m32() // Opcode f3 0f 53
3167{
3168   UINT8 modrm = FETCH();
3169   if( modrm >= 0xc0 ) {
3170      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / XMM(modrm & 0x7).f[0];
3171   } else {
3172      XMM_REG s;
3173      UINT32 ea = GetEA(modrm, 0);
3174      s.d[0]=READ32(ea);
3175      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / s.f[0];
3176   }
3177   CYCLES(1);     // TODO: correct cycle count
3178}
3179
3180void i386_device::sse_sqrtss_r128_r128m32() // Opcode f3 0f 51
3181{
3182   UINT8 modrm = FETCH();
3183   if( modrm >= 0xc0 ) {
3184      XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]);
3185   } else {
3186      XMM_REG s;
3187      UINT32 ea = GetEA(modrm, 0);
3188      s.d[0]=READ32(ea);
3189      XMM((modrm >> 3) & 0x7).f[0] = sqrt(s.f[0]);
3190   }
3191   CYCLES(1);     // TODO: correct cycle count
3192}
3193
3194void i386_device::sse_rsqrtss_r128_r128m32() // Opcode f3 0f 52
3195{
3196   UINT8 modrm = FETCH();
3197   if( modrm >= 0xc0 ) {
3198      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]);
3199   } else {
3200      XMM_REG s;
3201      UINT32 ea = GetEA(modrm, 0);
3202      s.d[0]=READ32(ea);
3203      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(s.f[0]);
3204   }
3205   CYCLES(1);     // TODO: correct cycle count
3206}
3207
3208void i386_device::sse_minss_r128_r128m32() // Opcode f3 0f 5d
3209{
3210   UINT8 modrm = FETCH();
3211   if( modrm >= 0xc0 ) {
3212      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < XMM(modrm & 0x7).f[0] ? XMM((modrm >> 3) & 0x7).f[0] : XMM(modrm & 0x7).f[0];
3213   } else {
3214      XMM_REG s;
3215      UINT32 ea = GetEA(modrm, 0);
3216      s.d[0] = READ32(ea);
3217      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < s.f[0] ? XMM((modrm >> 3) & 0x7).f[0] : s.f[0];
3218   }
3219   CYCLES(1);     // TODO: correct cycle count
3220}
3221
3222void i386_device::sse_comiss_r128_r128m32() // Opcode 0f 2f
3223{
3224   float32 a,b;
3225   UINT8 modrm = FETCH();
3226   if( modrm >= 0xc0 ) {
3227      a = XMM((modrm >> 3) & 0x7).d[0];
3228      b = XMM(modrm & 0x7).d[0];
3229   } else {
3230      XMM_REG src;
3231      UINT32 ea = GetEA(modrm, 0);
3232      READXMM(ea, src);
3233      a = XMM((modrm >> 3) & 0x7).d[0];
3234      b = src.d[0];
3235   }
3236   m_OF=0;
3237   m_SF=0;
3238   m_AF=0;
3239   if (float32_is_nan(a) || float32_is_nan(b))
3240   {
3241      m_ZF = 1;
3242      m_PF = 1;
3243      m_CF = 1;
3244   }
3245   else
3246   {
3247      m_ZF = 0;
3248      m_PF = 0;
3249      m_CF = 0;
3250      if (float32_eq(a, b))
3251         m_ZF = 1;
3252      if (float32_lt(a, b))
3253         m_CF = 1;
3254   }
3255   // should generate exception when at least one of the operands is either QNaN or SNaN
3256   CYCLES(1);     // TODO: correct cycle count
3257}
3258
3259void i386_device::sse_ucomiss_r128_r128m32() // Opcode 0f 2e
3260{
3261   float32 a,b;
3262   UINT8 modrm = FETCH();
3263   if( modrm >= 0xc0 ) {
3264      a = XMM((modrm >> 3) & 0x7).d[0];
3265      b = XMM(modrm & 0x7).d[0];
3266   } else {
3267      XMM_REG src;
3268      UINT32 ea = GetEA(modrm, 0);
3269      READXMM(ea, src);
3270      a = XMM((modrm >> 3) & 0x7).d[0];
3271      b = src.d[0];
3272   }
3273   m_OF=0;
3274   m_SF=0;
3275   m_AF=0;
3276   if (float32_is_nan(a) || float32_is_nan(b))
3277   {
3278      m_ZF = 1;
3279      m_PF = 1;
3280      m_CF = 1;
3281   }
3282   else
3283   {
3284      m_ZF = 0;
3285      m_PF = 0;
3286      m_CF = 0;
3287      if (float32_eq(a, b))
3288         m_ZF = 1;
3289      if (float32_lt(a, b))
3290         m_CF = 1;
3291   }
3292   // should generate exception when at least one of the operands is SNaN
3293   CYCLES(1);     // TODO: correct cycle count
3294}
3295
3296void i386_device::sse_shufps() // Opcode 0f 67
3297{
3298   UINT8 modrm = FETCH();
3299   UINT8 sel = FETCH();
3300   int m1,m2,m3,m4;
3301   int s,d;
3302   m1=sel & 3;
3303   m2=(sel >> 2) & 3;
3304   m3=(sel >> 4) & 3;
3305   m4=(sel >> 6) & 3;
3306   s=modrm & 0x7;
3307   d=(modrm >> 3) & 0x7;
3308   if( modrm >= 0xc0 ) {
3309      UINT32 t;
3310      t=XMM(d).d[m1];
3311      XMM(d).d[1]=XMM(d).d[m2];
3312      XMM(d).d[0]=t;
3313      XMM(d).d[2]=XMM(s).d[m3];
3314      XMM(d).d[3]=XMM(s).d[m4];
3315   } else {
3316      UINT32 t;
3317      XMM_REG src;
3318      UINT32 ea = GetEA(modrm, 0);
3319      READXMM(ea, src);
3320      t=XMM(d).d[m1];
3321      XMM(d).d[1]=XMM(d).d[m2];
3322      XMM(d).d[0]=t;
3323      XMM(d).d[2]=src.d[m3];
3324      XMM(d).d[3]=src.d[m4];
3325   }
3326   CYCLES(1);     // TODO: correct cycle count
3327}
3328
3329void i386_device::sse_unpcklps_r128_rm128() // Opcode 0f 14
3330{
3331   UINT8 modrm = FETCH();
3332   int s,d;
3333   s=modrm & 0x7;
3334   d=(modrm >> 3) & 0x7;
3335   if( modrm >= 0xc0 ) {
3336      XMM(d).d[3]=XMM(s).d[1];
3337      XMM(d).d[2]=XMM(d).d[1];
3338      XMM(d).d[1]=XMM(s).d[0];
3339      //XMM(d).d[0]=XMM(d).d[0];
3340   } else {
3341      XMM_REG src;
3342      UINT32 ea = GetEA(modrm, 0);
3343      READXMM(ea, src);
3344      XMM(d).d[3]=src.d[1];
3345      XMM(d).d[2]=XMM(d).d[1];
3346      XMM(d).d[1]=src.d[0];
3347   }
3348   CYCLES(1);     // TODO: correct cycle count
3349}
3350
3351void i386_device::sse_unpckhps_r128_rm128() // Opcode 0f 15
3352{
3353   UINT8 modrm = FETCH();
3354   int s,d;
3355   s=modrm & 0x7;
3356   d=(modrm >> 3) & 0x7;
3357   if( modrm >= 0xc0 ) {
3358      XMM(d).d[0]=XMM(d).d[2];
3359      XMM(d).d[1]=XMM(s).d[2];
3360      XMM(d).d[2]=XMM(d).d[3];
3361      XMM(d).d[3]=XMM(s).d[3];
3362   } else {
3363      XMM_REG src;
3364      UINT32 ea = GetEA(modrm, 0);
3365      READXMM(ea, src);
3366      XMM(d).d[0]=XMM(d).d[2];
3367      XMM(d).d[1]=src.d[2];
3368      XMM(d).d[2]=XMM(d).d[3];
3369      XMM(d).d[3]=src.d[3];
3370   }
3371   CYCLES(1);     // TODO: correct cycle count
3372}
3373
3374INLINE bool sse_issingleordered(float op1, float op2)
3375{
3376   // TODO: true when at least one of the two source operands being compared is a NaN
3377   return (op1 != op1) || (op1 != op2);
3378}
3379
3380INLINE bool sse_issingleunordered(float op1, float op2)
3381{
3382   // TODO: true when neither source operand is a NaN
3383   return !((op1 != op1) || (op1 != op2));
3384}
3385
3386void i386_device::sse_predicate_compare_single(UINT8 imm8, XMM_REG d, XMM_REG s)
3387{
3388   switch (imm8 & 7)
3389   {
3390   case 0:
3391      s.d[0]=s.f[0] == s.f[0] ? 0xffffffff : 0;
3392      d.d[1]=d.f[1] == s.f[1] ? 0xffffffff : 0;
3393      d.d[2]=d.f[2] == s.f[2] ? 0xffffffff : 0;
3394      d.d[3]=d.f[3] == s.f[3] ? 0xffffffff : 0;
3395      break;
3396   case 1:
3397      d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0;
3398      d.d[1]=d.f[1] < s.f[1] ? 0xffffffff : 0;
3399      d.d[2]=d.f[2] < s.f[2] ? 0xffffffff : 0;
3400      d.d[3]=d.f[3] < s.f[3] ? 0xffffffff : 0;
3401      break;
3402   case 2:
3403      d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0;
3404      d.d[1]=d.f[1] <= s.f[1] ? 0xffffffff : 0;
3405      d.d[2]=d.f[2] <= s.f[2] ? 0xffffffff : 0;
3406      d.d[3]=d.f[3] <= s.f[3] ? 0xffffffff : 0;
3407      break;
3408   case 3:
3409      d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3410      d.d[1]=sse_issingleunordered(d.f[1], s.f[1]) ? 0xffffffff : 0;
3411      d.d[2]=sse_issingleunordered(d.f[2], s.f[2]) ? 0xffffffff : 0;
3412      d.d[3]=sse_issingleunordered(d.f[3], s.f[3]) ? 0xffffffff : 0;
3413      break;
3414   case 4:
3415      d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0;
3416      d.d[1]=d.f[1] != s.f[1] ? 0xffffffff : 0;
3417      d.d[2]=d.f[2] != s.f[2] ? 0xffffffff : 0;
3418      d.d[3]=d.f[3] != s.f[3] ? 0xffffffff : 0;
3419      break;
3420   case 5:
3421      d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff;
3422      d.d[1]=d.f[1] < s.f[1] ? 0 : 0xffffffff;
3423      d.d[2]=d.f[2] < s.f[2] ? 0 : 0xffffffff;
3424      d.d[3]=d.f[3] < s.f[3] ? 0 : 0xffffffff;
3425      break;
3426   case 6:
3427      d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff;
3428      d.d[1]=d.f[1] <= s.f[1] ? 0 : 0xffffffff;
3429      d.d[2]=d.f[2] <= s.f[2] ? 0 : 0xffffffff;
3430      d.d[3]=d.f[3] <= s.f[3] ? 0 : 0xffffffff;
3431      break;
3432   case 7:
3433      d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3434      d.d[1]=sse_issingleordered(d.f[1], s.f[1]) ? 0xffffffff : 0;
3435      d.d[2]=sse_issingleordered(d.f[2], s.f[2]) ? 0xffffffff : 0;
3436      d.d[3]=sse_issingleordered(d.f[3], s.f[3]) ? 0xffffffff : 0;
3437      break;
3438   }
3439}
3440
3441void i386_device::sse_predicate_compare_single_scalar(UINT8 imm8, XMM_REG d, XMM_REG s)
3442{
3443   switch (imm8 & 7)
3444   {
3445   case 0:
3446      s.d[0]=s.f[0] == s.f[0] ? 0xffffffff : 0;
3447      break;
3448   case 1:
3449      d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0;
3450      break;
3451   case 2:
3452      d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0;
3453      break;
3454   case 3:
3455      d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3456      break;
3457   case 4:
3458      d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0;
3459      break;
3460   case 5:
3461      d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff;
3462      break;
3463   case 6:
3464      d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff;
3465      break;
3466   case 7:
3467      d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3468      break;
3469   }
3470}
3471
3472void i386_device::sse_cmpps_r128_rm128_i8() // Opcode 0f c2
3473{
3474   UINT8 modrm = FETCH();
3475   if( modrm >= 0xc0 ) {
3476      int s,d;
3477      UINT8 imm8 = FETCH();
3478      s=modrm & 0x7;
3479      d=(modrm >> 3) & 0x7;
3480      sse_predicate_compare_single(imm8, XMM(d), XMM(s));
3481   } else {
3482      int d;
3483      XMM_REG s;
3484      UINT32 ea = GetEA(modrm, 0);
3485      UINT8 imm8 = FETCH();
3486      READXMM(ea, s);
3487      d=(modrm >> 3) & 0x7;
3488      sse_predicate_compare_single(imm8, XMM(d), s);
3489   }
3490   CYCLES(1);     // TODO: correct cycle count
3491}
3492
3493void i386_device::sse_cmpss_r128_r128m32_i8() // Opcode f3 0f c2
3494{
3495   UINT8 modrm = FETCH();
3496   if( modrm >= 0xc0 ) {
3497      int s,d;
3498      UINT8 imm8 = FETCH();
3499      s=modrm & 0x7;
3500      d=(modrm >> 3) & 0x7;
3501      sse_predicate_compare_single_scalar(imm8, XMM(d), XMM(s));
3502   } else {
3503      int d;
3504      XMM_REG s;
3505      UINT32 ea = GetEA(modrm, 0);
3506      UINT8 imm8 = FETCH();
3507      s.d[0]=READ32(ea);
3508      d=(modrm >> 3) & 0x7;
3509      sse_predicate_compare_single_scalar(imm8, XMM(d), s);
3510   }
3511   CYCLES(1);     // TODO: correct cycle count
3512}
3513
3514void i386_device::sse_pinsrw_r64_r16m16_i8() // Opcode 0f c4
3515{
3516   MMXPROLOG();
3517   UINT8 modrm = FETCH();
3518   if( modrm >= 0xc0 ) {
3519      UINT8 imm8 = FETCH();
3520      UINT16 v = LOAD_RM16(modrm);
3521      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3522   } else {
3523      UINT32 ea = GetEA(modrm, 0);
3524      UINT8 imm8 = FETCH();
3525      UINT16 v = READ16(ea);
3526      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3527   }
3528   CYCLES(1);     // TODO: correct cycle count
3529}
3530
3531void i386_device::sse_pinsrw_r64_r32m16_i8() // Opcode 0f c4
3532{
3533   MMXPROLOG();
3534   UINT8 modrm = FETCH();
3535   if( modrm >= 0xc0 ) {
3536      UINT8 imm8 = FETCH();
3537      UINT16 v = (UINT16)LOAD_RM32(modrm);
3538      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3539   } else {
3540      UINT32 ea = GetEA(modrm, 0);
3541      UINT8 imm8 = FETCH();
3542      UINT16 v = READ16(ea);
3543      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3544   }
3545   CYCLES(1);     // TODO: correct cycle count
3546}
3547
3548void i386_device::sse_pextrw_r16_r64_i8() // Opcode 0f c5
3549{
3550   //MMXPROLOG();
3551   UINT8 modrm = FETCH();
3552   if( modrm >= 0xc0 ) {
3553      UINT8 imm8 = FETCH();
3554      STORE_REG16(modrm, MMX(modrm & 0x7).w[imm8 & 3]);
3555   } else {
3556      //UINT8 imm8 = FETCH();
3557      report_invalid_modrm("pextrw_r16_r64_i8", modrm);
3558   }
3559   CYCLES(1);     // TODO: correct cycle count
3560}
3561
3562void i386_device::sse_pextrw_r32_r64_i8() // Opcode 0f c5
3563{
3564   //MMXPROLOG();
3565   UINT8 modrm = FETCH();
3566   if( modrm >= 0xc0 ) {
3567      UINT8 imm8 = FETCH();
3568      STORE_REG32(modrm, MMX(modrm & 0x7).w[imm8 & 3]);
3569   } else {
3570      //UINT8 imm8 = FETCH();
3571      report_invalid_modrm("pextrw_r32_r64_i8", modrm);
3572   }
3573   CYCLES(1);     // TODO: correct cycle count
3574}
3575
3576void i386_device::sse_pminub_r64_rm64() // Opcode 0f da
3577{
3578   int n;
3579   MMXPROLOG();
3580   UINT8 modrm = FETCH();
3581   if( modrm >= 0xc0 ) {
3582      for (n=0;n < 8;n++)
3583         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n];
3584   } else {
3585      MMX_REG s;
3586      UINT32 ea = GetEA(modrm, 0);
3587      READMMX(ea, s);
3588      for (n=0;n < 8;n++)
3589         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n];
3590   }
3591   CYCLES(1);     // TODO: correct cycle count
3592}
3593
3594void i386_device::sse_pmaxub_r64_rm64() // Opcode 0f de
3595{
3596   int n;
3597   MMXPROLOG();
3598   UINT8 modrm = FETCH();
3599   if( modrm >= 0xc0 ) {
3600      for (n=0;n < 8;n++)
3601         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n];
3602   } else {
3603      MMX_REG s;
3604      UINT32 ea = GetEA(modrm, 0);
3605      READMMX(ea, s);
3606      for (n=0;n < 8;n++)
3607         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n];
3608   }
3609   CYCLES(1);     // TODO: correct cycle count
3610}
3611
3612void i386_device::sse_pavgb_r64_rm64() // Opcode 0f e0
3613{
3614   int n;
3615   MMXPROLOG();
3616   UINT8 modrm = FETCH();
3617   if( modrm >= 0xc0 ) {
3618      for (n=0;n < 8;n++)
3619         MMX((modrm >> 3) & 0x7).b[n] = ((UINT16)MMX((modrm >> 3) & 0x7).b[n] + (UINT16)MMX(modrm & 0x7).b[n] + 1) >> 1;
3620   } else {
3621      MMX_REG s;
3622      UINT32 ea = GetEA(modrm, 0);
3623      READMMX(ea, s);
3624      for (n=0;n < 8;n++)
3625         MMX((modrm >> 3) & 0x7).b[n] = ((UINT16)MMX((modrm >> 3) & 0x7).b[n] + (UINT16)s.b[n] + 1) >> 1;
3626   }
3627   CYCLES(1);     // TODO: correct cycle count
3628}
3629
3630void i386_device::sse_pavgw_r64_rm64() // Opcode 0f e3
3631{
3632   int n;
3633   MMXPROLOG();
3634   UINT8 modrm = FETCH();
3635   if( modrm >= 0xc0 ) {
3636      for (n=0;n < 4;n++)
3637         MMX((modrm >> 3) & 0x7).w[n] = ((UINT32)MMX((modrm >> 3) & 0x7).w[n] + (UINT32)MMX(modrm & 0x7).w[n] + 1) >> 1;
3638   } else {
3639      MMX_REG s;
3640      UINT32 ea = GetEA(modrm, 0);
3641      READMMX(ea, s);
3642      for (n=0;n < 4;n++)
3643         MMX((modrm >> 3) & 0x7).w[n] = ((UINT32)MMX((modrm >> 3) & 0x7).w[n] + (UINT32)s.w[n] + 1) >> 1;
3644   }
3645   CYCLES(1);     // TODO: correct cycle count
3646}
3647
3648void i386_device::sse_pmulhuw_r64_rm64()  // Opcode 0f e4
3649{
3650   MMXPROLOG();
3651   UINT8 modrm = FETCH();
3652   if( modrm >= 0xc0 ) {
3653      MMX((modrm >> 3) & 0x7).w[0]=((UINT32)MMX((modrm >> 3) & 0x7).w[0]*(UINT32)MMX(modrm & 7).w[0]) >> 16;
3654      MMX((modrm >> 3) & 0x7).w[1]=((UINT32)MMX((modrm >> 3) & 0x7).w[1]*(UINT32)MMX(modrm & 7).w[1]) >> 16;
3655      MMX((modrm >> 3) & 0x7).w[2]=((UINT32)MMX((modrm >> 3) & 0x7).w[2]*(UINT32)MMX(modrm & 7).w[2]) >> 16;
3656      MMX((modrm >> 3) & 0x7).w[3]=((UINT32)MMX((modrm >> 3) & 0x7).w[3]*(UINT32)MMX(modrm & 7).w[3]) >> 16;
3657   } else {
3658      MMX_REG s;
3659      UINT32 ea = GetEA(modrm, 0);
3660      READMMX(ea, s);
3661      MMX((modrm >> 3) & 0x7).w[0]=((UINT32)MMX((modrm >> 3) & 0x7).w[0]*(UINT32)s.w[0]) >> 16;
3662      MMX((modrm >> 3) & 0x7).w[1]=((UINT32)MMX((modrm >> 3) & 0x7).w[1]*(UINT32)s.w[1]) >> 16;
3663      MMX((modrm >> 3) & 0x7).w[2]=((UINT32)MMX((modrm >> 3) & 0x7).w[2]*(UINT32)s.w[2]) >> 16;
3664      MMX((modrm >> 3) & 0x7).w[3]=((UINT32)MMX((modrm >> 3) & 0x7).w[3]*(UINT32)s.w[3]) >> 16;
3665   }
3666   CYCLES(1);     // TODO: correct cycle count
3667}
3668
3669void i386_device::sse_pminsw_r64_rm64() // Opcode 0f ea
3670{
3671   int n;
3672   MMXPROLOG();
3673   UINT8 modrm = FETCH();
3674   if( modrm >= 0xc0 ) {
3675      for (n=0;n < 4;n++)
3676         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n];
3677   } else {
3678      MMX_REG s;
3679      UINT32 ea = GetEA(modrm, 0);
3680      READMMX(ea, s);
3681      for (n=0;n < 4;n++)
3682         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n];
3683   }
3684   CYCLES(1);     // TODO: correct cycle count
3685}
3686
3687void i386_device::sse_pmaxsw_r64_rm64() // Opcode 0f ee
3688{
3689   int n;
3690   MMXPROLOG();
3691   UINT8 modrm = FETCH();
3692   if( modrm >= 0xc0 ) {
3693      for (n=0;n < 4;n++)
3694         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n];
3695   } else {
3696      MMX_REG s;
3697      UINT32 ea = GetEA(modrm, 0);
3698      READMMX(ea, s);
3699      for (n=0;n < 4;n++)
3700         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n];
3701   }
3702   CYCLES(1);     // TODO: correct cycle count
3703}
3704
3705void i386_device::sse_pmuludq_r64_rm64() // Opcode 0f f4
3706{
3707   MMXPROLOG();
3708   UINT8 modrm = FETCH();
3709   if( modrm >= 0xc0 ) {
3710      MMX((modrm >> 3) & 0x7).q = (UINT64)MMX((modrm >> 3) & 0x7).d[0] * (UINT64)MMX(modrm & 0x7).d[0];
3711   } else {
3712      MMX_REG s;
3713      UINT32 ea = GetEA(modrm, 0);
3714      READMMX(ea, s);
3715      MMX((modrm >> 3) & 0x7).q = (UINT64)MMX((modrm >> 3) & 0x7).d[0] * (UINT64)s.d[0];
3716   }
3717   CYCLES(1);     // TODO: correct cycle count
3718}
3719
3720void i386_device::sse_psadbw_r64_rm64() // Opcode 0f f6
3721{
3722   int n;
3723   INT32 temp;
3724   MMXPROLOG();
3725   UINT8 modrm = FETCH();
3726   if( modrm >= 0xc0 ) {
3727      temp=0;
3728      for (n=0;n < 8;n++)
3729         temp += abs((INT32)MMX((modrm >> 3) & 0x7).b[n] - (INT32)MMX(modrm & 0x7).b[n]);
3730      MMX((modrm >> 3) & 0x7).l=(UINT64)temp & 0xffff;
3731   } else {
3732      MMX_REG s;
3733      UINT32 ea = GetEA(modrm, 0);
3734      READMMX(ea, s);
3735      temp=0;
3736      for (n=0;n < 8;n++)
3737         temp += abs((INT32)MMX((modrm >> 3) & 0x7).b[n] - (INT32)s.b[n]);
3738      MMX((modrm >> 3) & 0x7).l=(UINT64)temp & 0xffff;
3739   }
3740   CYCLES(1);     // TODO: correct cycle count
3741}
3742
3743void i386_device::sse_psubq_r64_rm64()  // Opcode 0f fb
3744{
3745   MMXPROLOG();
3746   UINT8 modrm = FETCH();
3747   if( modrm >= 0xc0 ) {
3748      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - MMX(modrm & 7).q;
3749   } else {
3750      MMX_REG s;
3751      UINT32 ea = GetEA(modrm, 0);
3752      READMMX(ea, s);
3753      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - s.q;
3754   }
3755   CYCLES(1);     // TODO: correct cycle count
3756}
3757
3758void i386_device::sse_pshufhw_r128_rm128_i8() // Opcode f3 0f 70
3759{
3760   UINT8 modrm = FETCH();
3761   if( modrm >= 0xc0 ) {
3762      XMM_REG t;
3763      int s,d;
3764      UINT8 imm8 = FETCH();
3765      s=modrm & 0x7;
3766      d=(modrm >> 3) & 0x7;
3767      t.q[0]=XMM(s).q[1];
3768      XMM(d).q[0]=XMM(s).q[0];
3769      XMM(d).w[4]=t.w[imm8 & 3];
3770      XMM(d).w[5]=t.w[(imm8 >> 2) & 3];
3771      XMM(d).w[6]=t.w[(imm8 >> 4) & 3];
3772      XMM(d).w[7]=t.w[(imm8 >> 6) & 3];
3773   } else {
3774      XMM_REG s;
3775      int d=(modrm >> 3) & 0x7;
3776      UINT32 ea = GetEA(modrm, 0);
3777      UINT8 imm8 = FETCH();
3778      READXMM(ea, s);
3779      XMM(d).q[0]=s.q[0];
3780      XMM(d).w[4]=s.w[4 + (imm8 & 3)];
3781      XMM(d).w[5]=s.w[4 + ((imm8 >> 2) & 3)];
3782      XMM(d).w[6]=s.w[4 + ((imm8 >> 4) & 3)];
3783      XMM(d).w[7]=s.w[4 + ((imm8 >> 6) & 3)];
3784   }
3785   CYCLES(1);     // TODO: correct cycle count
3786}
trunk/src/emu/cpu/i386/x87ops.c
r28738r28739
1/***************************************************************************
2
3    x87 FPU emulation
4
5    TODO:
6     - 80-bit precision for F2XM1, FYL2X, FPATAN
7     - Figure out why SoftFloat trig extensions produce bad values
8     - Cycle counts for all processors (currently using 486 counts)
9     - Precision-dependent cycle counts for divide instructions
10     - Last instruction, operand pointers etc.
11     - Fix FLDENV, FSTENV, FSAVE, FRSTOR and FPREM
12     - Status word C2 updates to reflect round up/down
13     - Handling of invalid and denormal numbers
14     - Remove redundant operand checks
15     - Exceptions
16
17***************************************************************************/
18
19#include <math.h>
20
21
22/*************************************
23 *
24 * Defines
25 *
26 *************************************/
27
28#define X87_SW_IE               0x0001
29#define X87_SW_DE               0x0002
30#define X87_SW_ZE               0x0004
31#define X87_SW_OE               0x0008
32#define X87_SW_UE               0x0010
33#define X87_SW_PE               0x0020
34#define X87_SW_SF               0x0040
35#define X87_SW_ES               0x0080
36#define X87_SW_C0               0x0100
37#define X87_SW_C1               0x0200
38#define X87_SW_C2               0x0400
39#define X87_SW_TOP_SHIFT        11
40#define X87_SW_TOP_MASK         7
41#define X87_SW_C3               0x4000
42#define X87_SW_BUSY             0x8000
43
44#define X87_CW_IM               0x0001
45#define X87_CW_DM               0x0002
46#define X87_CW_ZM               0x0004
47#define X87_CW_OM               0x0008
48#define X87_CW_UM               0x0010
49#define X87_CW_PM               0x0020
50#define X87_CW_PC_SHIFT         8
51#define X87_CW_PC_MASK          3
52#define X87_CW_PC_SINGLE        0
53#define X87_CW_PC_DOUBLE        2
54#define X87_CW_PC_EXTEND        3
55#define X87_CW_RC_SHIFT         10
56#define X87_CW_RC_MASK          3
57#define X87_CW_RC_NEAREST       0
58#define X87_CW_RC_DOWN          1
59#define X87_CW_RC_UP            2
60#define X87_CW_RC_ZERO          3
61
62#define X87_TW_MASK             3
63#define X87_TW_VALID            0
64#define X87_TW_ZERO             1
65#define X87_TW_SPECIAL          2
66#define X87_TW_EMPTY            3
67
68
69/*************************************
70 *
71 * Macros
72 *
73 *************************************/
74
75#define ST_TO_PHYS(x)           (((m_x87_sw >> X87_SW_TOP_SHIFT) + (x)) & X87_SW_TOP_MASK)
76#define ST(x)                   (m_x87_reg[ST_TO_PHYS(x)])
77#define X87_TW_FIELD_SHIFT(x)   ((x) << 1)
78#define X87_TAG(x)              ((m_x87_tw >> X87_TW_FIELD_SHIFT(x)) & X87_TW_MASK)
79#define X87_RC                  ((m_x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK)
80#define X87_IS_ST_EMPTY(x)      (X87_TAG(ST_TO_PHYS(x)) == X87_TW_EMPTY)
81#define X87_SW_C3_0             X87_SW_C0
82
83#define UNIMPLEMENTED           fatalerror("Unimplemented x87 op: %s (PC:%x)\n", __FUNCTION__, m_pc)
84
85
86/*************************************
87 *
88 * Constants
89 *
90 *************************************/
91
92static const floatx80 fx80_zero =   { 0x0000, U64(0x0000000000000000) };
93static const floatx80 fx80_one =    { 0x3fff, U64(0x8000000000000000) };
94
95static const floatx80 fx80_ninf =   { 0xffff, U64(0x8000000000000000) };
96static const floatx80 fx80_inan =   { 0xffff, U64(0xc000000000000000) };
97
98/* Maps x87 round modes to SoftFloat round modes */
99static const int x87_to_sf_rc[4] =
100{
101   float_round_nearest_even,
102   float_round_down,
103   float_round_up,
104   float_round_to_zero,
105};
106
107
108/*************************************
109 *
110 * SoftFloat helpers
111 *
112 *************************************/
113
114extern flag floatx80_is_nan( floatx80 a );
115
116INLINE int floatx80_is_zero(floatx80 fx)
117{
118   return (((fx.high & 0x7fff) == 0) && ((fx.low << 1) == 0));
119}
120
121INLINE int floatx80_is_inf(floatx80 fx)
122{
123   return (((fx.high & 0x7fff) == 0x7fff) && ((fx.low << 1) == 0));
124}
125
126INLINE int floatx80_is_denormal(floatx80 fx)
127{
128   return (((fx.high & 0x7fff) == 0) &&
129         ((fx.low & U64(0x8000000000000000)) == 0) &&
130         ((fx.low << 1) != 0));
131}
132
133INLINE floatx80 floatx80_abs(floatx80 fx)
134{
135   fx.high &= 0x7fff;
136   return fx;
137}
138
139INLINE double fx80_to_double(floatx80 fx)
140{
141   UINT64 d = floatx80_to_float64(fx);
142   return *(double*)&d;
143}
144
145INLINE floatx80 double_to_fx80(double in)
146{
147   return float64_to_floatx80(*(UINT64*)&in);
148}
149
150floatx80 i386_device::READ80(UINT32 ea)
151{
152   floatx80 t;
153
154   t.low = READ64(ea);
155   t.high = READ16(ea + 8);
156
157   return t;
158}
159
160void i386_device::WRITE80(UINT32 ea, floatx80 t)
161{
162   WRITE64(ea, t.low);
163   WRITE16(ea + 8, t.high);
164}
165
166
167/*************************************
168 *
169 * x87 stack handling
170 *
171 *************************************/
172
173void i386_device::x87_set_stack_top(int top)
174{
175   m_x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT);
176   m_x87_sw |= (top << X87_SW_TOP_SHIFT);
177}
178
179void i386_device::x87_set_tag(int reg, int tag)
180{
181   int shift = X87_TW_FIELD_SHIFT(reg);
182
183   m_x87_tw &= ~(X87_TW_MASK << shift);
184   m_x87_tw |= (tag << shift);
185}
186
187void i386_device::x87_write_stack(int i, floatx80 value, int update_tag)
188{
189   ST(i) = value;
190
191   if (update_tag)
192   {
193      int tag;
194
195      if (floatx80_is_zero(value))
196      {
197         tag = X87_TW_ZERO;
198      }
199      else if (floatx80_is_inf(value) || floatx80_is_nan(value))
200      {
201         tag = X87_TW_SPECIAL;
202      }
203      else
204      {
205         tag = X87_TW_VALID;
206      }
207
208      x87_set_tag(ST_TO_PHYS(i), tag);
209   }
210}
211
212void i386_device::x87_set_stack_underflow()
213{
214   m_x87_sw |= X87_SW_C1 | X87_SW_IE | X87_SW_SF;
215}
216
217void i386_device::x87_set_stack_overflow()
218{
219   m_x87_sw &= ~X87_SW_C1;
220   m_x87_sw |= X87_SW_IE | X87_SW_SF;
221}
222
223int i386_device::x87_inc_stack()
224{
225   int ret = 1;
226
227   // Check for stack underflow
228   if (X87_IS_ST_EMPTY(0))
229   {
230      ret = 0;
231      x87_set_stack_underflow();
232
233      // Don't update the stack if the exception is unmasked
234      if (~m_x87_cw & X87_CW_IM)
235         return ret;
236   }
237
238   x87_set_tag(ST_TO_PHYS(0), X87_TW_EMPTY);
239   x87_set_stack_top(ST_TO_PHYS(1));
240   return ret;
241}
242
243int i386_device::x87_dec_stack()
244{
245   int ret = 1;
246
247   // Check for stack overflow
248   if (!X87_IS_ST_EMPTY(7))
249   {
250      ret = 0;
251      x87_set_stack_overflow();
252
253      // Don't update the stack if the exception is unmasked
254      if (~m_x87_cw & X87_CW_IM)
255         return ret;
256   }
257
258   x87_set_stack_top(ST_TO_PHYS(7));
259   return ret;
260}
261
262
263/*************************************
264 *
265 * Exception handling
266 *
267 *************************************/
268
269int i386_device::x87_check_exceptions()
270{
271   /* Update the exceptions from SoftFloat */
272   if (float_exception_flags & float_flag_invalid)
273   {
274      m_x87_sw |= X87_SW_IE;
275      float_exception_flags &= ~float_flag_invalid;
276   }
277   if (float_exception_flags & float_flag_overflow)
278   {
279      m_x87_sw |= X87_SW_OE;
280      float_exception_flags &= ~float_flag_overflow;
281   }
282   if (float_exception_flags & float_flag_underflow)
283   {
284      m_x87_sw |= X87_SW_UE;
285      float_exception_flags &= ~float_flag_underflow;
286   }
287   if (float_exception_flags & float_flag_inexact)
288   {
289      m_x87_sw |= X87_SW_PE;
290      float_exception_flags &= ~float_flag_inexact;
291   }
292
293   if ((m_x87_sw & ~m_x87_cw) & 0x3f)
294   {
295      // m_device->execute().set_input_line(INPUT_LINE_FERR, RAISE_LINE);
296      logerror("Unmasked x87 exception (CW:%.4x, SW:%.4x)\n", m_x87_cw, m_x87_sw);
297      if (m_cr[0] & 0x20) // FIXME: 486 and up only
298      {
299         m_ext = 1;
300         i386_trap(FAULT_MF, 0, 0);
301      }
302      return 0;
303   }
304
305   return 1;
306}
307
308void i386_device::x87_write_cw(UINT16 cw)
309{
310   m_x87_cw = cw;
311
312   /* Update the SoftFloat rounding mode */
313   float_rounding_mode = x87_to_sf_rc[(m_x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK];
314}
315
316void i386_device::x87_reset()
317{
318   x87_write_cw(0x0037f);
319
320   m_x87_sw = 0;
321   m_x87_tw = 0xffff;
322
323   // TODO: FEA=0, FDS=0, FIP=0 FOP=0 FCS=0
324   m_x87_data_ptr = 0;
325   m_x87_inst_ptr = 0;
326   m_x87_opcode = 0;
327}
328
329
330/*************************************
331 *
332 * Core arithmetic
333 *
334 *************************************/
335
336floatx80 i386_device::x87_add(floatx80 a, floatx80 b)
337{
338   floatx80 result = { 0 };
339
340   switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
341   {
342      case X87_CW_PC_SINGLE:
343      {
344         float32 a32 = floatx80_to_float32(a);
345         float32 b32 = floatx80_to_float32(b);
346         result = float32_to_floatx80(float32_add(a32, b32));
347         break;
348      }
349      case X87_CW_PC_DOUBLE:
350      {
351         float64 a64 = floatx80_to_float64(a);
352         float64 b64 = floatx80_to_float64(b);
353         result = float64_to_floatx80(float64_add(a64, b64));
354         break;
355      }
356      case X87_CW_PC_EXTEND:
357      {
358         result = floatx80_add(a, b);
359         break;
360      }
361   }
362
363   return result;
364}
365
366floatx80 i386_device::x87_sub(floatx80 a, floatx80 b)
367{
368   floatx80 result = { 0 };
369
370   switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
371   {
372      case X87_CW_PC_SINGLE:
373      {
374         float32 a32 = floatx80_to_float32(a);
375         float32 b32 = floatx80_to_float32(b);
376         result = float32_to_floatx80(float32_sub(a32, b32));
377         break;
378      }
379      case X87_CW_PC_DOUBLE:
380      {
381         float64 a64 = floatx80_to_float64(a);
382         float64 b64 = floatx80_to_float64(b);
383         result = float64_to_floatx80(float64_sub(a64, b64));
384         break;
385      }
386      case X87_CW_PC_EXTEND:
387      {
388         result = floatx80_sub(a, b);
389         break;
390      }
391   }
392
393   return result;
394}
395
396floatx80 i386_device::x87_mul(floatx80 a, floatx80 b)
397{
398   floatx80 val = { 0 };
399
400   switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
401   {
402      case X87_CW_PC_SINGLE:
403      {
404         float32 a32 = floatx80_to_float32(a);
405         float32 b32 = floatx80_to_float32(b);
406         val = float32_to_floatx80(float32_mul(a32, b32));
407         break;
408      }
409      case X87_CW_PC_DOUBLE:
410      {
411         float64 a64 = floatx80_to_float64(a);
412         float64 b64 = floatx80_to_float64(b);
413         val = float64_to_floatx80(float64_mul(a64, b64));
414         break;
415      }
416      case X87_CW_PC_EXTEND:
417      {
418         val = floatx80_mul(a, b);
419         break;
420      }
421   }
422
423   return val;
424}
425
426
427floatx80 i386_device::x87_div(floatx80 a, floatx80 b)
428{
429   floatx80 val = { 0 };
430
431   switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
432   {
433      case X87_CW_PC_SINGLE:
434      {
435         float32 a32 = floatx80_to_float32(a);
436         float32 b32 = floatx80_to_float32(b);
437         val = float32_to_floatx80(float32_div(a32, b32));
438         break;
439      }
440      case X87_CW_PC_DOUBLE:
441      {
442         float64 a64 = floatx80_to_float64(a);
443         float64 b64 = floatx80_to_float64(b);
444         val = float64_to_floatx80(float64_div(a64, b64));
445         break;
446      }
447      case X87_CW_PC_EXTEND:
448      {
449         val = floatx80_div(a, b);
450         break;
451      }
452   }
453   return val;
454}
455
456
457/*************************************
458 *
459 * Instructions
460 *
461 *************************************/
462
463/*************************************
464 *
465 * Add
466 *
467 *************************************/
468
469void i386_device::x87_fadd_m32real(UINT8 modrm)
470{
471   floatx80 result;
472
473   UINT32 ea = GetEA(modrm, 0);
474   if (X87_IS_ST_EMPTY(0))
475   {
476      x87_set_stack_underflow();
477      result = fx80_inan;
478   }
479   else
480   {
481      UINT32 m32real = READ32(ea);
482
483      floatx80 a = ST(0);
484      floatx80 b = float32_to_floatx80(m32real);
485
486      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
487      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
488      {
489         m_x87_sw |= X87_SW_IE;
490         result = fx80_inan;
491      }
492      else
493      {
494         result = x87_add(a, b);
495      }
496   }
497
498   if (x87_check_exceptions())
499      x87_write_stack(0, result, TRUE);
500
501   CYCLES(8);
502}
503
504void i386_device::x87_fadd_m64real(UINT8 modrm)
505{
506   floatx80 result;
507
508   UINT32 ea = GetEA(modrm, 0);
509   if (X87_IS_ST_EMPTY(0))
510   {
511      x87_set_stack_underflow();
512      result = fx80_inan;
513   }
514   else
515   {
516      UINT64 m64real = READ64(ea);
517
518      floatx80 a = ST(0);
519      floatx80 b = float64_to_floatx80(m64real);
520
521      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
522      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
523      {
524         m_x87_sw |= X87_SW_IE;
525         result = fx80_inan;
526      }
527      else
528      {
529         result = x87_add(a, b);
530      }
531   }
532
533   if (x87_check_exceptions())
534      x87_write_stack(0, result, TRUE);
535
536   CYCLES(8);
537}
538
539void i386_device::x87_fadd_st_sti(UINT8 modrm)
540{
541   floatx80 result;
542   int i = modrm & 7;
543
544   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
545   {
546      x87_set_stack_underflow();
547      result = fx80_inan;
548   }
549   else
550   {
551      floatx80 a = ST(0);
552      floatx80 b = ST(i);
553
554      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
555      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
556      {
557         m_x87_sw |= X87_SW_IE;
558         result = fx80_inan;
559      }
560      else
561      {
562         result = x87_add(a, b);
563      }
564   }
565
566   if (x87_check_exceptions())
567      x87_write_stack(0, result, TRUE);
568
569   CYCLES(8);
570}
571
572void i386_device::x87_fadd_sti_st(UINT8 modrm)
573{
574   floatx80 result;
575   int i = modrm & 7;
576
577   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
578   {
579      x87_set_stack_underflow();
580      result = fx80_inan;
581   }
582   else
583   {
584      floatx80 a = ST(0);
585      floatx80 b = ST(i);
586
587      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
588      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
589      {
590         m_x87_sw |= X87_SW_IE;
591         result = fx80_inan;
592      }
593      else
594      {
595         result = x87_add(a, b);
596      }
597   }
598
599   if (x87_check_exceptions())
600      x87_write_stack(i, result, TRUE);
601
602   CYCLES(8);
603}
604
605void i386_device::x87_faddp(UINT8 modrm)
606{
607   floatx80 result;
608   int i = modrm & 7;
609
610   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
611   {
612      x87_set_stack_underflow();
613      result = fx80_inan;
614   }
615   else
616   {
617      floatx80 a = ST(0);
618      floatx80 b = ST(i);
619
620      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
621      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
622      {
623         m_x87_sw |= X87_SW_IE;
624         result = fx80_inan;
625      }
626      else
627      {
628         result = x87_add(a, b);
629      }
630   }
631
632   if (x87_check_exceptions())
633   {
634      x87_write_stack(i, result, TRUE);
635      x87_inc_stack();
636   }
637
638   CYCLES(8);
639}
640
641void i386_device::x87_fiadd_m32int(UINT8 modrm)
642{
643   floatx80 result;
644
645   UINT32 ea = GetEA(modrm, 0);
646   if (X87_IS_ST_EMPTY(0))
647   {
648      x87_set_stack_underflow();
649      result = fx80_inan;
650   }
651   else
652   {
653      INT32 m32int = READ32(ea);
654
655      floatx80 a = ST(0);
656      floatx80 b = int32_to_floatx80(m32int);
657
658      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
659      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
660      {
661         m_x87_sw |= X87_SW_IE;
662         result = fx80_inan;
663      }
664      else
665      {
666         result = x87_add(a, b);
667      }
668   }
669
670   if (x87_check_exceptions())
671      x87_write_stack(0, result, TRUE);
672
673   CYCLES(19);
674}
675
676void i386_device::x87_fiadd_m16int(UINT8 modrm)
677{
678   floatx80 result;
679
680   UINT32 ea = GetEA(modrm, 0);
681   if (X87_IS_ST_EMPTY(0))
682   {
683      x87_set_stack_underflow();
684      result = fx80_inan;
685   }
686   else
687   {
688      INT16 m16int = READ16(ea);
689
690      floatx80 a = ST(0);
691      floatx80 b = int32_to_floatx80(m16int);
692
693      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
694      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
695      {
696         m_x87_sw |= X87_SW_IE;
697         result = fx80_inan;
698      }
699      else
700      {
701         result = x87_add(a, b);
702      }
703   }
704
705   if (x87_check_exceptions())
706      x87_write_stack(0, result, TRUE);
707
708   CYCLES(20);
709}
710
711
712/*************************************
713 *
714 * Subtract
715 *
716 *************************************/
717
718void i386_device::x87_fsub_m32real(UINT8 modrm)
719{
720   floatx80 result;
721
722   UINT32 ea = GetEA(modrm, 0);
723   if (X87_IS_ST_EMPTY(0))
724   {
725      x87_set_stack_underflow();
726      result = fx80_inan;
727   }
728   else
729   {
730      UINT32 m32real = READ32(ea);
731
732      floatx80 a = ST(0);
733      floatx80 b = float32_to_floatx80(m32real);
734
735      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
736      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
737      {
738         m_x87_sw |= X87_SW_IE;
739         result = fx80_inan;
740      }
741      else
742      {
743         result = x87_sub(a, b);
744      }
745   }
746
747   if (x87_check_exceptions())
748      x87_write_stack(0, result, TRUE);
749
750   CYCLES(8);
751}
752
753void i386_device::x87_fsub_m64real(UINT8 modrm)
754{
755   floatx80 result;
756
757   UINT32 ea = GetEA(modrm, 0);
758   if (X87_IS_ST_EMPTY(0))
759   {
760      x87_set_stack_underflow();
761      result = fx80_inan;
762   }
763   else
764   {
765      UINT64 m64real = READ64(ea);
766
767      floatx80 a = ST(0);
768      floatx80 b = float64_to_floatx80(m64real);
769
770      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
771      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
772      {
773         m_x87_sw |= X87_SW_IE;
774         result = fx80_inan;
775      }
776      else
777      {
778         result = x87_sub(a, b);
779      }
780   }
781
782   if (x87_check_exceptions())
783      x87_write_stack(0, result, TRUE);
784
785   CYCLES(8);
786}
787
788void i386_device::x87_fsub_st_sti(UINT8 modrm)
789{
790   floatx80 result;
791   int i = modrm & 7;
792
793   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
794   {
795      x87_set_stack_underflow();
796      result = fx80_inan;
797   }
798   else
799   {
800      floatx80 a = ST(0);
801      floatx80 b = ST(i);
802
803      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
804      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
805      {
806         m_x87_sw |= X87_SW_IE;
807         result = fx80_inan;
808      }
809      else
810      {
811         result = x87_sub(a, b);
812      }
813   }
814
815   if (x87_check_exceptions())
816      x87_write_stack(0, result, TRUE);
817
818   CYCLES(8);
819}
820
821void i386_device::x87_fsub_sti_st(UINT8 modrm)
822{
823   floatx80 result;
824   int i = modrm & 7;
825
826   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
827   {
828      x87_set_stack_underflow();
829      result = fx80_inan;
830   }
831   else
832   {
833      floatx80 a = ST(i);
834      floatx80 b = ST(0);
835
836      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
837      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
838      {
839         m_x87_sw |= X87_SW_IE;
840         result = fx80_inan;
841      }
842      else
843      {
844         result = x87_sub(a, b);
845      }
846   }
847
848   if (x87_check_exceptions())
849      x87_write_stack(i, result, TRUE);
850
851   CYCLES(8);
852}
853
854void i386_device::x87_fsubp(UINT8 modrm)
855{
856   floatx80 result;
857   int i = modrm & 7;
858
859   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
860   {
861      x87_set_stack_underflow();
862      result = fx80_inan;
863   }
864   else
865   {
866      floatx80 a = ST(i);
867      floatx80 b = ST(0);
868
869      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
870      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
871      {
872         m_x87_sw |= X87_SW_IE;
873         result = fx80_inan;
874      }
875      else
876      {
877         result = x87_sub(a, b);
878      }
879   }
880
881   if (x87_check_exceptions())
882   {
883      x87_write_stack(i, result, TRUE);
884      x87_inc_stack();
885   }
886
887   CYCLES(8);
888}
889
890void i386_device::x87_fisub_m32int(UINT8 modrm)
891{
892   floatx80 result;
893
894   UINT32 ea = GetEA(modrm, 0);
895   if (X87_IS_ST_EMPTY(0))
896   {
897      x87_set_stack_underflow();
898      result = fx80_inan;
899   }
900   else
901   {
902      INT32 m32int = READ32(ea);
903
904      floatx80 a = ST(0);
905      floatx80 b = int32_to_floatx80(m32int);
906
907      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
908      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
909      {
910         m_x87_sw |= X87_SW_IE;
911         result = fx80_inan;
912      }
913      else
914      {
915         result = x87_sub(a, b);
916      }
917   }
918
919   if (x87_check_exceptions())
920      x87_write_stack(0, result, TRUE);
921
922   CYCLES(19);
923}
924
925void i386_device::x87_fisub_m16int(UINT8 modrm)
926{
927   floatx80 result;
928
929   UINT32 ea = GetEA(modrm, 0);
930   if (X87_IS_ST_EMPTY(0))
931   {
932      x87_set_stack_underflow();
933      result = fx80_inan;
934   }
935   else
936   {
937      INT16 m16int = READ16(ea);
938
939      floatx80 a = ST(0);
940      floatx80 b = int32_to_floatx80(m16int);
941
942      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
943      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
944      {
945         m_x87_sw |= X87_SW_IE;
946         result = fx80_inan;
947      }
948      else
949      {
950         result = x87_sub(a, b);
951      }
952   }
953
954   if (x87_check_exceptions())
955      x87_write_stack(0, result, TRUE);
956
957   CYCLES(20);
958}
959
960
961/*************************************
962 *
963 * Reverse Subtract
964 *
965 *************************************/
966
967void i386_device::x87_fsubr_m32real(UINT8 modrm)
968{
969   floatx80 result;
970
971   UINT32 ea = GetEA(modrm, 0);
972   if (X87_IS_ST_EMPTY(0))
973   {
974      x87_set_stack_underflow();
975      result = fx80_inan;
976   }
977   else
978   {
979      UINT32 m32real = READ32(ea);
980
981      floatx80 a = float32_to_floatx80(m32real);
982      floatx80 b = ST(0);
983
984      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
985      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
986      {
987         m_x87_sw |= X87_SW_IE;
988         result = fx80_inan;
989      }
990      else
991      {
992         result = x87_sub(a, b);
993      }
994   }
995
996   if (x87_check_exceptions())
997      x87_write_stack(0, result, TRUE);
998
999   CYCLES(8);
1000}
1001
1002void i386_device::x87_fsubr_m64real(UINT8 modrm)
1003{
1004   floatx80 result;
1005
1006   UINT32 ea = GetEA(modrm, 0);
1007   if (X87_IS_ST_EMPTY(0))
1008   {
1009      x87_set_stack_underflow();
1010      result = fx80_inan;
1011   }
1012   else
1013   {
1014      UINT64 m64real = READ64(ea);
1015
1016      floatx80 a = float64_to_floatx80(m64real);
1017      floatx80 b = ST(0);
1018
1019      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1020      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1021      {
1022         m_x87_sw |= X87_SW_IE;
1023         result = fx80_inan;
1024      }
1025      else
1026      {
1027         result = x87_sub(a, b);
1028      }
1029   }
1030
1031   if (x87_check_exceptions())
1032      x87_write_stack(0, result, TRUE);
1033
1034   CYCLES(8);
1035}
1036
1037void i386_device::x87_fsubr_st_sti(UINT8 modrm)
1038{
1039   floatx80 result;
1040   int i = modrm & 7;
1041
1042   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1043   {
1044      x87_set_stack_underflow();
1045      result = fx80_inan;
1046   }
1047   else
1048   {
1049      floatx80 a = ST(i);
1050      floatx80 b = ST(0);
1051
1052      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1053      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1054      {
1055         m_x87_sw |= X87_SW_IE;
1056         result = fx80_inan;
1057      }
1058      else
1059      {
1060         result = x87_sub(a, b);
1061      }
1062   }
1063
1064   if (x87_check_exceptions())
1065      x87_write_stack(0, result, TRUE);
1066
1067   CYCLES(8);
1068}
1069
1070void i386_device::x87_fsubr_sti_st(UINT8 modrm)
1071{
1072   floatx80 result;
1073   int i = modrm & 7;
1074
1075   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1076   {
1077      x87_set_stack_underflow();
1078      result = fx80_inan;
1079   }
1080   else
1081   {
1082      floatx80 a = ST(0);
1083      floatx80 b = ST(i);
1084
1085      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1086      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1087      {
1088         m_x87_sw |= X87_SW_IE;
1089         result = fx80_inan;
1090      }
1091      else
1092      {
1093         result = x87_sub(a, b);
1094      }
1095   }
1096
1097   if (x87_check_exceptions())
1098      x87_write_stack(i, result, TRUE);
1099
1100   CYCLES(8);
1101}
1102
1103void i386_device::x87_fsubrp(UINT8 modrm)
1104{
1105   floatx80 result;
1106   int i = modrm & 7;
1107
1108   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1109   {
1110      x87_set_stack_underflow();
1111      result = fx80_inan;
1112   }
1113   else
1114   {
1115      floatx80 a = ST(0);
1116      floatx80 b = ST(i);
1117
1118      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1119      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1120      {
1121         m_x87_sw |= X87_SW_IE;
1122         result = fx80_inan;
1123      }
1124      else
1125      {
1126         result = x87_sub(a, b);
1127      }
1128   }
1129
1130   if (x87_check_exceptions())
1131   {
1132      x87_write_stack(i, result, TRUE);
1133      x87_inc_stack();
1134   }
1135
1136   CYCLES(8);
1137}
1138
1139void i386_device::x87_fisubr_m32int(UINT8 modrm)
1140{
1141   floatx80 result;
1142
1143   UINT32 ea = GetEA(modrm, 0);
1144   if (X87_IS_ST_EMPTY(0))
1145   {
1146      x87_set_stack_underflow();
1147      result = fx80_inan;
1148   }
1149   else
1150   {
1151      INT32 m32int = READ32(ea);
1152
1153      floatx80 a = int32_to_floatx80(m32int);
1154      floatx80 b = ST(0);
1155
1156      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1157      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1158      {
1159         m_x87_sw |= X87_SW_IE;
1160         result = fx80_inan;
1161      }
1162      else
1163      {
1164         result = x87_sub(a, b);
1165      }
1166   }
1167
1168   if (x87_check_exceptions())
1169      x87_write_stack(0, result, TRUE);
1170
1171   CYCLES(19);
1172}
1173
1174void i386_device::x87_fisubr_m16int(UINT8 modrm)
1175{
1176   floatx80 result;
1177
1178   UINT32 ea = GetEA(modrm, 0);
1179   if (X87_IS_ST_EMPTY(0))
1180   {
1181      x87_set_stack_underflow();
1182      result = fx80_inan;
1183   }
1184   else
1185   {
1186      INT16 m16int = READ16(ea);
1187
1188      floatx80 a = int32_to_floatx80(m16int);
1189      floatx80 b = ST(0);
1190
1191      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1192      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1193      {
1194         m_x87_sw |= X87_SW_IE;
1195         result = fx80_inan;
1196      }
1197      else
1198      {
1199         result = x87_sub(a, b);
1200      }
1201   }
1202
1203   if (x87_check_exceptions())
1204      x87_write_stack(0, result, TRUE);
1205
1206   CYCLES(20);
1207}
1208
1209
1210/*************************************
1211 *
1212 * Divide
1213 *
1214 *************************************/
1215
1216void i386_device::x87_fdiv_m32real(UINT8 modrm)
1217{
1218   floatx80 result;
1219
1220   UINT32 ea = GetEA(modrm, 0);
1221   if (X87_IS_ST_EMPTY(0))
1222   {
1223      x87_set_stack_underflow();
1224      result = fx80_inan;
1225   }
1226   else
1227   {
1228      UINT32 m32real = READ32(ea);
1229
1230      floatx80 a = ST(0);
1231      floatx80 b = float32_to_floatx80(m32real);
1232
1233      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1234      {
1235         m_x87_sw |= X87_SW_IE;
1236         result = fx80_inan;
1237      }
1238      else
1239      {
1240         result = x87_div(a, b);
1241      }
1242   }
1243
1244   if (x87_check_exceptions())
1245      x87_write_stack(0, result, TRUE);
1246
1247   // 73, 62, 35
1248   CYCLES(73);
1249}
1250
1251void i386_device::x87_fdiv_m64real(UINT8 modrm)
1252{
1253   floatx80 result;
1254
1255   UINT32 ea = GetEA(modrm, 0);
1256   if (X87_IS_ST_EMPTY(0))
1257   {
1258      x87_set_stack_underflow();
1259      result = fx80_inan;
1260   }
1261   else
1262   {
1263      UINT64 m64real = READ64(ea);
1264
1265      floatx80 a = ST(0);
1266      floatx80 b = float64_to_floatx80(m64real);
1267
1268      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1269      {
1270         m_x87_sw |= X87_SW_IE;
1271         result = fx80_inan;
1272      }
1273      else
1274      {
1275         result = x87_div(a, b);
1276      }
1277   }
1278
1279   if (x87_check_exceptions())
1280      x87_write_stack(0, result, TRUE);
1281
1282   // 73, 62, 35
1283   CYCLES(73);
1284}
1285
1286void i386_device::x87_fdiv_st_sti(UINT8 modrm)
1287{
1288   int i = modrm & 7;
1289   floatx80 result;
1290
1291   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1292   {
1293      x87_set_stack_underflow();
1294      result = fx80_inan;
1295   }
1296   else
1297   {
1298      floatx80 a = ST(0);
1299      floatx80 b = ST(i);
1300
1301      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1302      {
1303         m_x87_sw |= X87_SW_IE;
1304         result = fx80_inan;
1305      }
1306      else
1307      {
1308         result = x87_div(a, b);
1309      }
1310   }
1311
1312   if (x87_check_exceptions())
1313   {
1314      x87_write_stack(0, result, TRUE);
1315   }
1316
1317   // 73, 62, 35
1318   CYCLES(73);
1319}
1320
1321void i386_device::x87_fdiv_sti_st(UINT8 modrm)
1322{
1323   int i = modrm & 7;
1324   floatx80 result;
1325
1326   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1327   {
1328      x87_set_stack_underflow();
1329      result = fx80_inan;
1330   }
1331   else
1332   {
1333      floatx80 a = ST(i);
1334      floatx80 b = ST(0);
1335
1336      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1337      {
1338         m_x87_sw |= X87_SW_IE;
1339         result = fx80_inan;
1340      }
1341      else
1342      {
1343         result = x87_div(a, b);
1344      }
1345   }
1346
1347   if (x87_check_exceptions())
1348   {
1349      x87_write_stack(i, result, TRUE);
1350   }
1351
1352   // 73, 62, 35
1353   CYCLES(73);
1354}
1355
1356void i386_device::x87_fdivp(UINT8 modrm)
1357{
1358   int i = modrm & 7;
1359   floatx80 result;
1360
1361   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1362   {
1363      x87_set_stack_underflow();
1364      result = fx80_inan;
1365   }
1366   else
1367   {
1368      floatx80 a = ST(i);
1369      floatx80 b = ST(0);
1370
1371      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1372      {
1373         m_x87_sw |= X87_SW_IE;
1374         result = fx80_inan;
1375      }
1376      else
1377      {
1378         result = x87_div(a, b);
1379      }
1380   }
1381
1382   if (x87_check_exceptions())
1383   {
1384      x87_write_stack(i, result, TRUE);
1385      x87_inc_stack();
1386   }
1387
1388   // 73, 62, 35
1389   CYCLES(73);
1390}
1391
1392void i386_device::x87_fidiv_m32int(UINT8 modrm)
1393{
1394   floatx80 result;
1395
1396   UINT32 ea = GetEA(modrm, 0);
1397   if (X87_IS_ST_EMPTY(0))
1398   {
1399      x87_set_stack_underflow();
1400      result = fx80_inan;
1401   }
1402   else
1403   {
1404      INT32 m32int = READ32(ea);
1405
1406      floatx80 a = ST(0);
1407      floatx80 b = int32_to_floatx80(m32int);
1408
1409      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1410      {
1411         m_x87_sw |= X87_SW_IE;
1412         result = fx80_inan;
1413      }
1414      else
1415      {
1416         result = x87_div(a, b);
1417      }
1418   }
1419
1420   if (x87_check_exceptions())
1421      x87_write_stack(0, result, TRUE);
1422
1423   // 73, 62, 35
1424   CYCLES(73);
1425}
1426
1427void i386_device::x87_fidiv_m16int(UINT8 modrm)
1428{
1429   floatx80 result;
1430
1431   UINT32 ea = GetEA(modrm, 0);
1432   if (X87_IS_ST_EMPTY(0))
1433   {
1434      x87_set_stack_underflow();
1435      result = fx80_inan;
1436   }
1437   else
1438   {
1439      INT16 m16int = READ32(ea);
1440
1441      floatx80 a = ST(0);
1442      floatx80 b = int32_to_floatx80(m16int);
1443
1444      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1445      {
1446         m_x87_sw |= X87_SW_IE;
1447         result = fx80_inan;
1448      }
1449      else
1450      {
1451         result = x87_div(a, b);
1452      }
1453   }
1454
1455   if (x87_check_exceptions())
1456      x87_write_stack(0, result, TRUE);
1457
1458   // 73, 62, 35
1459   CYCLES(73);
1460}
1461
1462
1463/*************************************
1464 *
1465 * Reverse Divide
1466 *
1467 *************************************/
1468
1469void i386_device::x87_fdivr_m32real(UINT8 modrm)
1470{
1471   floatx80 result;
1472
1473   UINT32 ea = GetEA(modrm, 0);
1474   if (X87_IS_ST_EMPTY(0))
1475   {
1476      x87_set_stack_underflow();
1477      result = fx80_inan;
1478   }
1479   else
1480   {
1481      UINT32 m32real = READ32(ea);
1482
1483      floatx80 a = float32_to_floatx80(m32real);
1484      floatx80 b = ST(0);
1485
1486      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1487      {
1488         m_x87_sw |= X87_SW_IE;
1489         result = fx80_inan;
1490      }
1491      else
1492      {
1493         result = x87_div(a, b);
1494      }
1495   }
1496
1497   if (x87_check_exceptions())
1498      x87_write_stack(0, result, TRUE);
1499
1500   // 73, 62, 35
1501   CYCLES(73);
1502}
1503
1504void i386_device::x87_fdivr_m64real(UINT8 modrm)
1505{
1506   floatx80 result;
1507
1508   UINT32 ea = GetEA(modrm, 0);
1509   if (X87_IS_ST_EMPTY(0))
1510   {
1511      x87_set_stack_underflow();
1512      result = fx80_inan;
1513   }
1514   else
1515   {
1516      UINT64 m64real = READ64(ea);
1517
1518      floatx80 a = float64_to_floatx80(m64real);
1519      floatx80 b = ST(0);
1520
1521      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1522      {
1523         m_x87_sw |= X87_SW_IE;
1524         result = fx80_inan;
1525      }
1526      else
1527      {
1528         result = x87_div(a, b);
1529      }
1530   }
1531
1532   if (x87_check_exceptions())
1533      x87_write_stack(0, result, TRUE);
1534
1535   // 73, 62, 35
1536   CYCLES(73);
1537}
1538
1539void i386_device::x87_fdivr_st_sti(UINT8 modrm)
1540{
1541   int i = modrm & 7;
1542   floatx80 result;
1543
1544   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1545   {
1546      x87_set_stack_underflow();
1547      result = fx80_inan;
1548   }
1549   else
1550   {
1551      floatx80 a = ST(i);
1552      floatx80 b = ST(0);
1553
1554      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1555      {
1556         m_x87_sw |= X87_SW_IE;
1557         result = fx80_inan;
1558      }
1559      else
1560      {
1561         result = x87_div(a, b);
1562      }
1563   }
1564
1565   if (x87_check_exceptions())
1566   {
1567      x87_write_stack(0, result, TRUE);
1568   }
1569
1570   // 73, 62, 35
1571   CYCLES(73);
1572}
1573
1574void i386_device::x87_fdivr_sti_st(UINT8 modrm)
1575{
1576   int i = modrm & 7;
1577   floatx80 result;
1578
1579   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1580   {
1581      x87_set_stack_underflow();
1582      result = fx80_inan;
1583   }
1584   else
1585   {
1586      floatx80 a = ST(0);
1587      floatx80 b = ST(i);
1588
1589      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1590      {
1591         m_x87_sw |= X87_SW_IE;
1592         result = fx80_inan;
1593      }
1594      else
1595      {
1596         result = x87_div(a, b);
1597      }
1598   }
1599
1600   if (x87_check_exceptions())
1601   {
1602      x87_write_stack(i, result, TRUE);
1603   }
1604
1605   // 73, 62, 35
1606   CYCLES(73);
1607}
1608
1609void i386_device::x87_fdivrp(UINT8 modrm)
1610{
1611   int i = modrm & 7;
1612   floatx80 result;
1613
1614   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1615   {
1616      x87_set_stack_underflow();
1617      result = fx80_inan;
1618   }
1619   else
1620   {
1621      floatx80 a = ST(0);
1622      floatx80 b = ST(i);
1623
1624      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1625      {
1626         m_x87_sw |= X87_SW_IE;
1627         result = fx80_inan;
1628      }
1629      else
1630      {
1631         result = x87_div(a, b);
1632      }
1633   }
1634
1635   if (x87_check_exceptions())
1636   {
1637      x87_write_stack(i, result, TRUE);
1638      x87_inc_stack();
1639   }
1640
1641   // 73, 62, 35
1642   CYCLES(73);
1643}
1644
1645
1646void i386_device::x87_fidivr_m32int(UINT8 modrm)
1647{
1648   floatx80 result;
1649
1650   UINT32 ea = GetEA(modrm, 0);
1651   if (X87_IS_ST_EMPTY(0))
1652   {
1653      x87_set_stack_underflow();
1654      result = fx80_inan;
1655   }
1656   else
1657   {
1658      INT32 m32int = READ32(ea);
1659
1660      floatx80 a = int32_to_floatx80(m32int);
1661      floatx80 b = ST(0);
1662
1663      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1664      {
1665         m_x87_sw |= X87_SW_IE;
1666         result = fx80_inan;
1667      }
1668      else
1669      {
1670         result = x87_div(a, b);
1671      }
1672   }
1673
1674   if (x87_check_exceptions())
1675      x87_write_stack(0, result, TRUE);
1676
1677   // 73, 62, 35
1678   CYCLES(73);
1679}
1680
1681void i386_device::x87_fidivr_m16int(UINT8 modrm)
1682{
1683   floatx80 result;
1684
1685   UINT32 ea = GetEA(modrm, 0);
1686   if (X87_IS_ST_EMPTY(0))
1687   {
1688      x87_set_stack_underflow();
1689      result = fx80_inan;
1690   }
1691   else
1692   {
1693      INT16 m16int = READ32(ea);
1694
1695      floatx80 a = int32_to_floatx80(m16int);
1696      floatx80 b = ST(0);
1697
1698      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1699      {
1700         m_x87_sw |= X87_SW_IE;
1701         result = fx80_inan;
1702      }
1703      else
1704      {
1705         result = x87_div(a, b);
1706      }
1707   }
1708
1709   if (x87_check_exceptions())
1710      x87_write_stack(0, result, TRUE);
1711
1712   // 73, 62, 35
1713   CYCLES(73);
1714}
1715
1716
1717/*************************************
1718 *
1719 * Multiply
1720 *
1721 *************************************/
1722
1723void i386_device::x87_fmul_m32real(UINT8 modrm)
1724{
1725   floatx80 result;
1726
1727   UINT32 ea = GetEA(modrm, 0);
1728   if (X87_IS_ST_EMPTY(0))
1729   {
1730      x87_set_stack_underflow();
1731      result = fx80_inan;
1732   }
1733   else
1734   {
1735      UINT32 m32real = READ32(ea);
1736
1737      floatx80 a = ST(0);
1738      floatx80 b = float32_to_floatx80(m32real);
1739
1740      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1741      {
1742         m_x87_sw |= X87_SW_IE;
1743         result = fx80_inan;
1744      }
1745      else
1746      {
1747         result = x87_mul(a, b);
1748      }
1749   }
1750
1751   if (x87_check_exceptions())
1752      x87_write_stack(0, result, TRUE);
1753
1754   CYCLES(11);
1755}
1756
1757void i386_device::x87_fmul_m64real(UINT8 modrm)
1758{
1759   floatx80 result;
1760
1761   UINT32 ea = GetEA(modrm, 0);
1762   if (X87_IS_ST_EMPTY(0))
1763   {
1764      x87_set_stack_underflow();
1765      result = fx80_inan;
1766   }
1767   else
1768   {
1769      UINT64 m64real = READ64(ea);
1770
1771      floatx80 a = ST(0);
1772      floatx80 b = float64_to_floatx80(m64real);
1773
1774      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1775      {
1776         m_x87_sw |= X87_SW_IE;
1777         result = fx80_inan;
1778      }
1779      else
1780      {
1781         result = x87_mul(a, b);
1782      }
1783   }
1784
1785   if (x87_check_exceptions())
1786      x87_write_stack(0, result, TRUE);
1787
1788   CYCLES(14);
1789}
1790
1791void i386_device::x87_fmul_st_sti(UINT8 modrm)
1792{
1793   floatx80 result;
1794   int i = modrm & 7;
1795
1796   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1797   {
1798      x87_set_stack_underflow();
1799      result = fx80_inan;
1800   }
1801   else
1802   {
1803      floatx80 a = ST(0);
1804      floatx80 b = ST(i);
1805
1806      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1807      {
1808         m_x87_sw |= X87_SW_IE;
1809         result = fx80_inan;
1810      }
1811      else
1812      {
1813         result = x87_mul(a, b);
1814      }
1815   }
1816
1817   if (x87_check_exceptions())
1818      x87_write_stack(0, result, TRUE);
1819
1820   CYCLES(16);
1821}
1822
1823void i386_device::x87_fmul_sti_st(UINT8 modrm)
1824{
1825   floatx80 result;
1826   int i = modrm & 7;
1827
1828   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1829   {
1830      x87_set_stack_underflow();
1831      result = fx80_inan;
1832   }
1833   else
1834   {
1835      floatx80 a = ST(0);
1836      floatx80 b = ST(i);
1837
1838      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1839      {
1840         m_x87_sw |= X87_SW_IE;
1841         result = fx80_inan;
1842      }
1843      else
1844      {
1845         result = x87_mul(a, b);
1846      }
1847   }
1848
1849   if (x87_check_exceptions())
1850      x87_write_stack(i, result, TRUE);
1851
1852   CYCLES(16);
1853}
1854
1855void i386_device::x87_fmulp(UINT8 modrm)
1856{
1857   floatx80 result;
1858   int i = modrm & 7;
1859
1860   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1861   {
1862      x87_set_stack_underflow();
1863      result = fx80_inan;
1864   }
1865   else
1866   {
1867      floatx80 a = ST(0);
1868      floatx80 b = ST(i);
1869
1870      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1871      {
1872         m_x87_sw |= X87_SW_IE;
1873         result = fx80_inan;
1874      }
1875      else
1876      {
1877         result = x87_mul(a, b);
1878      }
1879   }
1880
1881   if (x87_check_exceptions())
1882   {
1883      x87_write_stack(i, result, TRUE);
1884      x87_inc_stack();
1885   }
1886
1887   CYCLES(16);
1888}
1889
1890void i386_device::x87_fimul_m32int(UINT8 modrm)
1891{
1892   floatx80 result;
1893
1894   UINT32 ea = GetEA(modrm, 0);
1895   if (X87_IS_ST_EMPTY(0))
1896   {
1897      x87_set_stack_underflow();
1898      result = fx80_inan;
1899   }
1900   else
1901   {
1902      INT32 m32int = READ32(ea);
1903
1904      floatx80 a = ST(0);
1905      floatx80 b = int32_to_floatx80(m32int);
1906
1907      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1908      {
1909         m_x87_sw |= X87_SW_IE;
1910         result = fx80_inan;
1911      }
1912      else
1913      {
1914         result = x87_mul(a, b);
1915      }
1916   }
1917
1918   if (x87_check_exceptions())
1919      x87_write_stack(0, result, TRUE);
1920
1921   CYCLES(22);
1922}
1923
1924void i386_device::x87_fimul_m16int(UINT8 modrm)
1925{
1926   floatx80 result;
1927
1928   UINT32 ea = GetEA(modrm, 0);
1929   if (X87_IS_ST_EMPTY(0))
1930   {
1931      x87_set_stack_underflow();
1932      result = fx80_inan;
1933   }
1934   else
1935   {
1936      INT16 m16int = READ16(ea);
1937
1938      floatx80 a = ST(0);
1939      floatx80 b = int32_to_floatx80(m16int);
1940
1941      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1942      {
1943         m_x87_sw |= X87_SW_IE;
1944         result = fx80_inan;
1945      }
1946      else
1947      {
1948         result = x87_mul(a, b);
1949      }
1950   }
1951
1952   if (x87_check_exceptions())
1953      x87_write_stack(0, result, TRUE);
1954
1955   CYCLES(22);
1956}
1957
1958
1959/*************************************
1960 *
1961 * Miscellaneous arithmetic
1962 *
1963 *************************************/
1964
1965void i386_device::x87_fprem(UINT8 modrm)
1966{
1967   floatx80 result;
1968
1969   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
1970   {
1971      x87_set_stack_underflow();
1972      result = fx80_inan;
1973   }
1974   else
1975   {
1976      floatx80 a = ST(0);
1977      floatx80 b = ST(1);
1978
1979      m_x87_sw &= ~X87_SW_C0;
1980
1981      // TODO: Implement Cx bits
1982      result = floatx80_rem(a, b);
1983   }
1984
1985   if (x87_check_exceptions())
1986      x87_write_stack(0, result, TRUE);
1987
1988   CYCLES(84);
1989}
1990
1991void i386_device::x87_fprem1(UINT8 modrm)
1992{
1993   floatx80 result;
1994
1995   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
1996   {
1997      x87_set_stack_underflow();
1998      result = fx80_inan;
1999   }
2000   else
2001   {
2002      floatx80 a = ST(0);
2003      floatx80 b = ST(1);
2004
2005      m_x87_sw &= ~X87_SW_C0;
2006
2007      // TODO: Implement Cx bits
2008      result = floatx80_rem(a, b);
2009   }
2010
2011   if (x87_check_exceptions())
2012      x87_write_stack(0, result, TRUE);
2013
2014   CYCLES(94);
2015}
2016
2017void i386_device::x87_fsqrt(UINT8 modrm)
2018{
2019   floatx80 result;
2020
2021   if (X87_IS_ST_EMPTY(0))
2022   {
2023      x87_set_stack_underflow();
2024      result = fx80_inan;
2025   }
2026   else
2027   {
2028      floatx80 value = ST(0);
2029
2030      if ((!floatx80_is_zero(value) && (value.high & 0x8000)) ||
2031            floatx80_is_denormal(value))
2032      {
2033         m_x87_sw |= X87_SW_IE;
2034         result = fx80_inan;
2035      }
2036      else
2037      {
2038         result = floatx80_sqrt(value);
2039      }
2040   }
2041
2042   if (x87_check_exceptions())
2043      x87_write_stack(0, result, TRUE);
2044
2045   CYCLES(8);
2046}
2047
2048/*************************************
2049 *
2050 * Trigonometric
2051 *
2052 *************************************/
2053
2054void i386_device::x87_f2xm1(UINT8 modrm)
2055{
2056   floatx80 result;
2057
2058   if (X87_IS_ST_EMPTY(0))
2059   {
2060      x87_set_stack_underflow();
2061      result = fx80_inan;
2062   }
2063   else
2064   {
2065      // TODO: Inaccurate
2066      double x = fx80_to_double(ST(0));
2067      double res = pow(2.0, x) - 1;
2068      result = double_to_fx80(res);
2069   }
2070
2071   if (x87_check_exceptions())
2072   {
2073      x87_write_stack(0, result, TRUE);
2074   }
2075
2076   CYCLES(242);
2077}
2078
2079void i386_device::x87_fyl2x(UINT8 modrm)
2080{
2081   floatx80 result;
2082
2083   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2084   {
2085      x87_set_stack_underflow();
2086      result = fx80_inan;
2087   }
2088   else
2089   {
2090      floatx80 x = ST(0);
2091      floatx80 y = ST(1);
2092
2093      if (x.high & 0x8000)
2094      {
2095         m_x87_sw |= X87_SW_IE;
2096         result = fx80_inan;
2097      }
2098      else
2099      {
2100         // TODO: Inaccurate
2101         double d64 = fx80_to_double(x);
2102         double l2x = log(d64)/log(2.0);
2103         result = floatx80_mul(double_to_fx80(l2x), y);
2104      }
2105   }
2106
2107   if (x87_check_exceptions())
2108   {
2109      x87_write_stack(1, result, TRUE);
2110      x87_inc_stack();
2111   }
2112
2113   CYCLES(250);
2114}
2115
2116void i386_device::x87_fyl2xp1(UINT8 modrm)
2117{
2118   floatx80 result;
2119
2120   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2121   {
2122      x87_set_stack_underflow();
2123      result = fx80_inan;
2124   }
2125   else
2126   {
2127      floatx80 x = ST(0);
2128      floatx80 y = ST(1);
2129
2130      // TODO: Inaccurate
2131      double d64 = fx80_to_double(x);
2132      double l2x1 = log(d64 + 1.0)/log(2.0);
2133      result = floatx80_mul(double_to_fx80(l2x1), y);
2134   }
2135
2136   if (x87_check_exceptions())
2137   {
2138      x87_write_stack(1, result, TRUE);
2139      x87_inc_stack();
2140   }
2141
2142   CYCLES(313);
2143}
2144
2145void i386_device::x87_fptan(UINT8 modrm)
2146{
2147   floatx80 result1, result2;
2148
2149   if (X87_IS_ST_EMPTY(0))
2150   {
2151      x87_set_stack_underflow();
2152      result1 = fx80_inan;
2153      result2 = fx80_inan;
2154   }
2155   else if (!X87_IS_ST_EMPTY(7))
2156   {
2157      x87_set_stack_overflow();
2158      result1 = fx80_inan;
2159      result2 = fx80_inan;
2160   }
2161   else
2162   {
2163      result1 = ST(0);
2164      result2 = fx80_one;
2165
2166#if 0 // TODO: Function produces bad values
2167      if (floatx80_ftan(result1) != -1)
2168         m_x87_sw &= ~X87_SW_C2;
2169      else
2170         m_x87_sw |= X87_SW_C2;
2171#else
2172      double x = fx80_to_double(result1);
2173      x = tan(x);
2174      result1 = double_to_fx80(x);
2175
2176      m_x87_sw &= ~X87_SW_C2;
2177#endif
2178   }
2179
2180   if (x87_check_exceptions())
2181   {
2182      x87_write_stack(0, result1, TRUE);
2183      x87_dec_stack();
2184      x87_write_stack(0, result2, TRUE);
2185   }
2186
2187   CYCLES(244);
2188}
2189
2190void i386_device::x87_fpatan(UINT8 modrm)
2191{
2192   floatx80 result;
2193
2194   if (X87_IS_ST_EMPTY(0))
2195   {
2196      x87_set_stack_underflow();
2197      result = fx80_inan;
2198   }
2199   else
2200   {
2201      // TODO: Inaccurate
2202      double val = atan(fx80_to_double(ST(1)) / fx80_to_double(ST(0)));
2203      result = double_to_fx80(val);
2204   }
2205
2206   if (x87_check_exceptions())
2207   {
2208      x87_write_stack(1, result, TRUE);
2209      x87_inc_stack();
2210   }
2211
2212   CYCLES(289);
2213}
2214
2215void i386_device::x87_fsin(UINT8 modrm)
2216{
2217   floatx80 result;
2218
2219   if (X87_IS_ST_EMPTY(0))
2220   {
2221      x87_set_stack_underflow();
2222      result = fx80_inan;
2223   }
2224   else
2225   {
2226      result = ST(0);
2227
2228#if 0 // TODO: Function produces bad values
2229      if (floatx80_fsin(result) != -1)
2230         m_x87_sw &= ~X87_SW_C2;
2231      else
2232         m_x87_sw |= X87_SW_C2;
2233#else
2234      double x = fx80_to_double(result);
2235      x = sin(x);
2236      result = double_to_fx80(x);
2237
2238      m_x87_sw &= ~X87_SW_C2;
2239#endif
2240   }
2241
2242   if (x87_check_exceptions())
2243      x87_write_stack(0, result, TRUE);
2244
2245   CYCLES(241);
2246}
2247
2248void i386_device::x87_fcos(UINT8 modrm)
2249{
2250   floatx80 result;
2251
2252   if (X87_IS_ST_EMPTY(0))
2253   {
2254      x87_set_stack_underflow();
2255      result = fx80_inan;
2256   }
2257   else
2258   {
2259      result = ST(0);
2260
2261#if 0 // TODO: Function produces bad values
2262      if (floatx80_fcos(result) != -1)
2263         m_x87_sw &= ~X87_SW_C2;
2264      else
2265         m_x87_sw |= X87_SW_C2;
2266#else
2267      double x = fx80_to_double(result);
2268      x = cos(x);
2269      result = double_to_fx80(x);
2270
2271      m_x87_sw &= ~X87_SW_C2;
2272#endif
2273   }
2274
2275   if (x87_check_exceptions())
2276      x87_write_stack(0, result, TRUE);
2277
2278   CYCLES(241);
2279}
2280
2281void i386_device::x87_fsincos(UINT8 modrm)
2282{
2283   floatx80 s_result, c_result;
2284
2285   if (X87_IS_ST_EMPTY(0))
2286   {
2287      x87_set_stack_underflow();
2288      s_result = c_result = fx80_inan;
2289   }
2290   else if (!X87_IS_ST_EMPTY(7))
2291   {
2292      x87_set_stack_overflow();
2293      s_result = c_result = fx80_inan;
2294   }
2295   else
2296   {
2297      extern int sf_fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a);
2298
2299      s_result = c_result = ST(0);
2300
2301#if 0 // TODO: Function produces bad values
2302      if (sf_fsincos(s_result, &s_result, &c_result) != -1)
2303         m_x87_sw &= ~X87_SW_C2;
2304      else
2305         m_x87_sw |= X87_SW_C2;
2306#else
2307      double s = fx80_to_double(s_result);
2308      double c = fx80_to_double(c_result);
2309      s = sin(s);
2310      c = cos(c);
2311
2312      s_result = double_to_fx80(s);
2313      c_result = double_to_fx80(c);
2314
2315      m_x87_sw &= ~X87_SW_C2;
2316#endif
2317   }
2318
2319   if (x87_check_exceptions())
2320   {
2321      x87_write_stack(0, s_result, TRUE);
2322      x87_dec_stack();
2323      x87_write_stack(0, c_result, TRUE);
2324   }
2325
2326   CYCLES(291);
2327}
2328
2329
2330/*************************************
2331 *
2332 * Load data
2333 *
2334 *************************************/
2335
2336void i386_device::x87_fld_m32real(UINT8 modrm)
2337{
2338   floatx80 value;
2339
2340   UINT32 ea = GetEA(modrm, 0);
2341   if (x87_dec_stack())
2342   {
2343      UINT32 m32real = READ32(ea);
2344
2345      value = float32_to_floatx80(m32real);
2346
2347      m_x87_sw &= ~X87_SW_C1;
2348
2349      if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
2350      {
2351         m_x87_sw |= X87_SW_IE;
2352         value = fx80_inan;
2353      }
2354   }
2355   else
2356   {
2357      value = fx80_inan;
2358   }
2359
2360   if (x87_check_exceptions())
2361      x87_write_stack(0, value, TRUE);
2362
2363   CYCLES(3);
2364}
2365
2366void i386_device::x87_fld_m64real(UINT8 modrm)
2367{
2368   floatx80 value;
2369
2370   UINT32 ea = GetEA(modrm, 0);
2371   if (x87_dec_stack())
2372   {
2373      UINT64 m64real = READ64(ea);
2374
2375      value = float64_to_floatx80(m64real);
2376
2377      m_x87_sw &= ~X87_SW_C1;
2378
2379      if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
2380      {
2381         m_x87_sw |= X87_SW_IE;
2382         value = fx80_inan;
2383      }
2384   }
2385   else
2386   {
2387      value = fx80_inan;
2388   }
2389
2390   if (x87_check_exceptions())
2391      x87_write_stack(0, value, TRUE);
2392
2393   CYCLES(3);
2394}
2395
2396void i386_device::x87_fld_m80real(UINT8 modrm)
2397{
2398   floatx80 value;
2399
2400   UINT32 ea = GetEA(modrm, 0);
2401   if (x87_dec_stack())
2402   {
2403      m_x87_sw &= ~X87_SW_C1;
2404      value = READ80(ea);
2405   }
2406   else
2407   {
2408      value = fx80_inan;
2409   }
2410
2411   if (x87_check_exceptions())
2412      x87_write_stack(0, value, TRUE);
2413
2414   CYCLES(6);
2415}
2416
2417void i386_device::x87_fld_sti(UINT8 modrm)
2418{
2419   floatx80 value;
2420
2421   if (x87_dec_stack())
2422   {
2423      m_x87_sw &= ~X87_SW_C1;
2424      value = ST((modrm + 1) & 7);
2425   }
2426   else
2427   {
2428      value = fx80_inan;
2429   }
2430
2431   if (x87_check_exceptions())
2432      x87_write_stack(0, value, TRUE);
2433
2434   CYCLES(4);
2435}
2436
2437void i386_device::x87_fild_m16int(UINT8 modrm)
2438{
2439   floatx80 value;
2440
2441   UINT32 ea = GetEA(modrm, 0);
2442   if (!x87_dec_stack())
2443   {
2444      value = fx80_inan;
2445   }
2446   else
2447   {
2448      m_x87_sw &= ~X87_SW_C1;
2449
2450      INT16 m16int = READ16(ea);
2451      value = int32_to_floatx80(m16int);
2452   }
2453
2454   if (x87_check_exceptions())
2455      x87_write_stack(0, value, TRUE);
2456
2457   CYCLES(13);
2458}
2459
2460void i386_device::x87_fild_m32int(UINT8 modrm)
2461{
2462   floatx80 value;
2463
2464   UINT32 ea = GetEA(modrm, 0);
2465   if (!x87_dec_stack())
2466   {
2467      value = fx80_inan;
2468   }
2469   else
2470   {
2471      m_x87_sw &= ~X87_SW_C1;
2472
2473      INT32 m32int = READ32(ea);
2474      value = int32_to_floatx80(m32int);
2475   }
2476
2477   if (x87_check_exceptions())
2478      x87_write_stack(0, value, TRUE);
2479
2480   CYCLES(9);
2481}
2482
2483void i386_device::x87_fild_m64int(UINT8 modrm)
2484{
2485   floatx80 value;
2486
2487   UINT32 ea = GetEA(modrm, 0);
2488   if (!x87_dec_stack())
2489   {
2490      value = fx80_inan;
2491   }
2492   else
2493   {
2494      m_x87_sw &= ~X87_SW_C1;
2495
2496      INT64 m64int = READ64(ea);
2497      value = int64_to_floatx80(m64int);
2498   }
2499
2500   if (x87_check_exceptions())
2501      x87_write_stack(0, value, TRUE);
2502
2503   CYCLES(10);
2504}
2505
2506void i386_device::x87_fbld(UINT8 modrm)
2507{
2508   floatx80 value;
2509
2510   UINT32 ea = GetEA(modrm, 0);
2511   if (!x87_dec_stack())
2512   {
2513      value = fx80_inan;
2514   }
2515   else
2516   {
2517      m_x87_sw &= ~X87_SW_C1;
2518
2519      UINT64 m64val = 0;
2520      UINT16 sign;
2521
2522      value = READ80(ea);
2523
2524      sign = value.high & 0x8000;
2525      m64val += ((value.high >> 4) & 0xf) * 10;
2526      m64val += ((value.high >> 0) & 0xf);
2527
2528      for (int i = 60; i >= 0; i -= 4)
2529      {
2530         m64val *= 10;
2531         m64val += (value.low >> i) & 0xf;
2532      }
2533
2534      value = int64_to_floatx80(m64val);
2535      value.high |= sign;
2536   }
2537
2538   if (x87_check_exceptions())
2539      x87_write_stack(0, value, TRUE);
2540
2541   CYCLES(75);
2542}
2543
2544
2545/*************************************
2546 *
2547 * Store data
2548 *
2549 *************************************/
2550
2551void i386_device::x87_fst_m32real(UINT8 modrm)
2552{
2553   floatx80 value;
2554
2555   UINT32 ea = GetEA(modrm, 1);
2556   if (X87_IS_ST_EMPTY(0))
2557   {
2558      x87_set_stack_underflow();
2559      value = fx80_inan;
2560   }
2561   else
2562   {
2563      m_x87_sw &= ~X87_SW_C1;
2564      value = ST(0);
2565   }
2566
2567   if (x87_check_exceptions())
2568   {
2569      UINT32 m32real = floatx80_to_float32(value);
2570      WRITE32(ea, m32real);
2571   }
2572
2573   CYCLES(7);
2574}
2575
2576void i386_device::x87_fst_m64real(UINT8 modrm)
2577{
2578   floatx80 value;
2579
2580   UINT32 ea = GetEA(modrm, 1);
2581   if (X87_IS_ST_EMPTY(0))
2582   {
2583      x87_set_stack_underflow();
2584      value = fx80_inan;
2585   }
2586   else
2587   {
2588      m_x87_sw &= ~X87_SW_C1;
2589      value = ST(0);
2590   }
2591
2592   if (x87_check_exceptions())
2593   {
2594      UINT64 m64real = floatx80_to_float64(value);
2595      WRITE64(ea, m64real);
2596   }
2597
2598   CYCLES(8);
2599}
2600
2601void i386_device::x87_fst_sti(UINT8 modrm)
2602{
2603   int i = modrm & 7;
2604   floatx80 value;
2605
2606   if (X87_IS_ST_EMPTY(0))
2607   {
2608      x87_set_stack_underflow();
2609      value = fx80_inan;
2610   }
2611   else
2612   {
2613      m_x87_sw &= ~X87_SW_C1;
2614      value = ST(0);
2615   }
2616
2617   if (x87_check_exceptions())
2618      x87_write_stack(i, value, TRUE);
2619
2620   CYCLES(3);
2621}
2622
2623void i386_device::x87_fstp_m32real(UINT8 modrm)
2624{
2625   floatx80 value;
2626
2627   UINT32 ea = GetEA(modrm, 1);
2628   if (X87_IS_ST_EMPTY(0))
2629   {
2630      x87_set_stack_underflow();
2631      value = fx80_inan;
2632   }
2633   else
2634   {
2635      m_x87_sw &= ~X87_SW_C1;
2636      value = ST(0);
2637   }
2638
2639   if (x87_check_exceptions())
2640   {
2641      UINT32 m32real = floatx80_to_float32(value);
2642      WRITE32(ea, m32real);
2643      x87_inc_stack();
2644   }
2645
2646   CYCLES(7);
2647}
2648
2649void i386_device::x87_fstp_m64real(UINT8 modrm)
2650{
2651   floatx80 value;
2652
2653   if (X87_IS_ST_EMPTY(0))
2654   {
2655      x87_set_stack_underflow();
2656      value = fx80_inan;
2657   }
2658   else
2659   {
2660      m_x87_sw &= ~X87_SW_C1;
2661      value = ST(0);
2662   }
2663
2664
2665   UINT32 ea = GetEA(modrm, 1);
2666   if (x87_check_exceptions())
2667   {
2668      UINT64 m64real = floatx80_to_float64(value);
2669      WRITE64(ea, m64real);
2670      x87_inc_stack();
2671   }
2672
2673   CYCLES(8);
2674}
2675
2676void i386_device::x87_fstp_m80real(UINT8 modrm)
2677{
2678   floatx80 value;
2679
2680   if (X87_IS_ST_EMPTY(0))
2681   {
2682      x87_set_stack_underflow();
2683      value = fx80_inan;
2684   }
2685   else
2686   {
2687      m_x87_sw &= ~X87_SW_C1;
2688      value = ST(0);
2689   }
2690
2691   UINT32 ea = GetEA(modrm, 1);
2692   if (x87_check_exceptions())
2693   {
2694      WRITE80(ea, value);
2695      x87_inc_stack();
2696   }
2697
2698   CYCLES(6);
2699}
2700
2701void i386_device::x87_fstp_sti(UINT8 modrm)
2702{
2703   int i = modrm & 7;
2704   floatx80 value;
2705
2706   if (X87_IS_ST_EMPTY(0))
2707   {
2708      x87_set_stack_underflow();
2709      value = fx80_inan;
2710   }
2711   else
2712   {
2713      m_x87_sw &= ~X87_SW_C1;
2714      value = ST(0);
2715   }
2716
2717   if (x87_check_exceptions())
2718   {
2719      x87_write_stack(i, value, TRUE);
2720      x87_inc_stack();
2721   }
2722
2723   CYCLES(3);
2724}
2725
2726void i386_device::x87_fist_m16int(UINT8 modrm)
2727{
2728   INT16 m16int;
2729
2730   if (X87_IS_ST_EMPTY(0))
2731   {
2732      x87_set_stack_underflow();
2733      m16int = -32768;
2734   }
2735   else
2736   {
2737      floatx80 fx80 = floatx80_round_to_int(ST(0));
2738
2739      floatx80 lowerLim = int32_to_floatx80(-32768);
2740      floatx80 upperLim = int32_to_floatx80(32767);
2741
2742      m_x87_sw &= ~X87_SW_C1;
2743
2744      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2745         m16int = floatx80_to_int32(fx80);
2746      else
2747         m16int = -32768;
2748   }
2749
2750   UINT32 ea = GetEA(modrm, 1);
2751   if (x87_check_exceptions())
2752   {
2753      WRITE16(ea, m16int);
2754   }
2755
2756   CYCLES(29);
2757}
2758
2759void i386_device::x87_fist_m32int(UINT8 modrm)
2760{
2761   INT32 m32int;
2762
2763   if (X87_IS_ST_EMPTY(0))
2764   {
2765      x87_set_stack_underflow();
2766      m32int = 0x80000000;
2767   }
2768   else
2769   {
2770      floatx80 fx80 = floatx80_round_to_int(ST(0));
2771
2772      floatx80 lowerLim = int32_to_floatx80(0x80000000);
2773      floatx80 upperLim = int32_to_floatx80(0x7fffffff);
2774
2775      m_x87_sw &= ~X87_SW_C1;
2776
2777      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2778         m32int = floatx80_to_int32(fx80);
2779      else
2780         m32int = 0x80000000;
2781   }
2782
2783   UINT32 ea = GetEA(modrm, 1);
2784   if (x87_check_exceptions())
2785   {
2786      WRITE32(ea, m32int);
2787   }
2788
2789   CYCLES(28);
2790}
2791
2792void i386_device::x87_fistp_m16int(UINT8 modrm)
2793{
2794   INT16 m16int;
2795
2796   if (X87_IS_ST_EMPTY(0))
2797   {
2798      x87_set_stack_underflow();
2799      m16int = (UINT16)0x8000;
2800   }
2801   else
2802   {
2803      floatx80 fx80 = floatx80_round_to_int(ST(0));
2804
2805      floatx80 lowerLim = int32_to_floatx80(-32768);
2806      floatx80 upperLim = int32_to_floatx80(32767);
2807
2808      m_x87_sw &= ~X87_SW_C1;
2809
2810      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2811         m16int = floatx80_to_int32(fx80);
2812      else
2813         m16int = (UINT16)0x8000;
2814   }
2815
2816   UINT32 ea = GetEA(modrm, 1);
2817   if (x87_check_exceptions())
2818   {
2819      WRITE16(ea, m16int);
2820      x87_inc_stack();
2821   }
2822
2823   CYCLES(29);
2824}
2825
2826void i386_device::x87_fistp_m32int(UINT8 modrm)
2827{
2828   INT32 m32int;
2829
2830   if (X87_IS_ST_EMPTY(0))
2831   {
2832      x87_set_stack_underflow();
2833      m32int = 0x80000000;
2834   }
2835   else
2836   {
2837      floatx80 fx80 = floatx80_round_to_int(ST(0));
2838
2839      floatx80 lowerLim = int32_to_floatx80(0x80000000);
2840      floatx80 upperLim = int32_to_floatx80(0x7fffffff);
2841
2842      m_x87_sw &= ~X87_SW_C1;
2843
2844      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2845         m32int = floatx80_to_int32(fx80);
2846      else
2847         m32int = 0x80000000;
2848   }
2849
2850   UINT32 ea = GetEA(modrm, 1);
2851   if (x87_check_exceptions())
2852   {
2853      WRITE32(ea, m32int);
2854      x87_inc_stack();
2855   }
2856
2857   CYCLES(29);
2858}
2859
2860void i386_device::x87_fistp_m64int(UINT8 modrm)
2861{
2862   INT64 m64int;
2863
2864   if (X87_IS_ST_EMPTY(0))
2865   {
2866      x87_set_stack_underflow();
2867      m64int = U64(0x8000000000000000);
2868   }
2869   else
2870   {
2871      floatx80 fx80 = floatx80_round_to_int(ST(0));
2872
2873      floatx80 lowerLim = int64_to_floatx80(U64(0x8000000000000000));
2874      floatx80 upperLim = int64_to_floatx80(U64(0x7fffffffffffffff));
2875
2876      m_x87_sw &= ~X87_SW_C1;
2877
2878      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2879         m64int = floatx80_to_int64(fx80);
2880      else
2881         m64int = U64(0x8000000000000000);
2882   }
2883
2884   UINT32 ea = GetEA(modrm, 1);
2885   if (x87_check_exceptions())
2886   {
2887      WRITE64(ea, m64int);
2888      x87_inc_stack();
2889   }
2890
2891   CYCLES(29);
2892}
2893
2894void i386_device::x87_fbstp(UINT8 modrm)
2895{
2896   floatx80 result;
2897
2898   if (X87_IS_ST_EMPTY(0))
2899   {
2900      x87_set_stack_underflow();
2901      result = fx80_inan;
2902   }
2903   else
2904   {
2905      UINT64 u64 = floatx80_to_int64(floatx80_abs(ST(0)));
2906      result.low = 0;
2907
2908      for (int i = 0; i < 64; i += 4)
2909      {
2910         result.low += (u64 % 10) << i;
2911         u64 /= 10;
2912      }
2913
2914      result.high = (u64 % 10);
2915      result.high += ((u64 / 10) % 10) << 4;
2916      result.high |= ST(0).high & 0x8000;
2917   }
2918
2919   UINT32 ea = GetEA(modrm, 1);
2920   if (x87_check_exceptions())
2921   {
2922      WRITE80(ea, result);
2923      x87_inc_stack();
2924   }
2925
2926   CYCLES(175);
2927}
2928
2929
2930/*************************************
2931 *
2932 * Constant load
2933 *
2934 *************************************/
2935
2936void i386_device::x87_fld1(UINT8 modrm)
2937{
2938   floatx80 value;
2939   int tag;
2940
2941   if (x87_dec_stack())
2942   {
2943      m_x87_sw &= ~X87_SW_C1;
2944      value = fx80_one;
2945      tag = X87_TW_VALID;
2946   }
2947   else
2948   {
2949      value = fx80_inan;
2950      tag = X87_TW_SPECIAL;
2951   }
2952
2953   if (x87_check_exceptions())
2954   {
2955      x87_set_tag(ST_TO_PHYS(0), tag);
2956      x87_write_stack(0, value, FALSE);
2957   }
2958
2959   CYCLES(4);
2960}
2961
2962void i386_device::x87_fldl2t(UINT8 modrm)
2963{
2964   floatx80 value;
2965   int tag;
2966
2967   if (x87_dec_stack())
2968   {
2969      tag = X87_TW_VALID;
2970      value.high = 0x4000;
2971
2972      if (X87_RC == X87_CW_RC_UP)
2973         value.low =  U64(0xd49a784bcd1b8aff);
2974      else
2975         value.low = U64(0xd49a784bcd1b8afe);
2976
2977      m_x87_sw &= ~X87_SW_C1;
2978   }
2979   else
2980   {
2981      value = fx80_inan;
2982      tag = X87_TW_SPECIAL;
2983   }
2984
2985   if (x87_check_exceptions())
2986   {
2987      x87_set_tag(ST_TO_PHYS(0), tag);
2988      x87_write_stack(0, value, FALSE);
2989   }
2990
2991   CYCLES(8);
2992}
2993
2994void i386_device::x87_fldl2e(UINT8 modrm)
2995{
2996   floatx80 value;
2997   int tag;
2998
2999   if (x87_dec_stack())
3000   {
3001      int rc = X87_RC;
3002      tag = X87_TW_VALID;
3003      value.high = 0x3fff;
3004
3005      if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3006         value.low = U64(0xb8aa3b295c17f0bc);
3007      else
3008         value.low = U64(0xb8aa3b295c17f0bb);
3009
3010      m_x87_sw &= ~X87_SW_C1;
3011   }
3012   else
3013   {
3014      value = fx80_inan;
3015      tag = X87_TW_SPECIAL;
3016   }
3017
3018   if (x87_check_exceptions())
3019   {
3020      x87_set_tag(ST_TO_PHYS(0), tag);
3021      x87_write_stack(0, value, FALSE);
3022   }
3023
3024   CYCLES(8);
3025}
3026
3027void i386_device::x87_fldpi(UINT8 modrm)
3028{
3029   floatx80 value;
3030   int tag;
3031
3032   if (x87_dec_stack())
3033   {
3034      int rc = X87_RC;
3035      tag = X87_TW_VALID;
3036      value.high = 0x4000;
3037
3038      if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3039         value.low = U64(0xc90fdaa22168c235);
3040      else
3041         value.low = U64(0xc90fdaa22168c234);
3042
3043      m_x87_sw &= ~X87_SW_C1;
3044   }
3045   else
3046   {
3047      value = fx80_inan;
3048      tag = X87_TW_SPECIAL;
3049   }
3050
3051   if (x87_check_exceptions())
3052   {
3053      x87_set_tag(ST_TO_PHYS(0), tag);
3054      x87_write_stack(0, value, FALSE);
3055   }
3056
3057   CYCLES(8);
3058}
3059
3060void i386_device::x87_fldlg2(UINT8 modrm)
3061{
3062   floatx80 value;
3063   int tag;
3064
3065   if (x87_dec_stack())
3066   {
3067      int rc = X87_RC;
3068      tag = X87_TW_VALID;
3069      value.high = 0x3ffd;
3070
3071      if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3072         value.low = U64(0x9a209a84fbcff799);
3073      else
3074         value.low = U64(0x9a209a84fbcff798);
3075
3076      m_x87_sw &= ~X87_SW_C1;
3077   }
3078   else
3079   {
3080      value = fx80_inan;
3081      tag = X87_TW_SPECIAL;
3082   }
3083
3084   if (x87_check_exceptions())
3085   {
3086      x87_set_tag(ST_TO_PHYS(0), tag);
3087      x87_write_stack(0, value, FALSE);
3088   }
3089
3090   CYCLES(8);
3091}
3092
3093void i386_device::x87_fldln2(UINT8 modrm)
3094{
3095   floatx80 value;
3096   int tag;
3097
3098   if (x87_dec_stack())
3099   {
3100      int rc = X87_RC;
3101      tag = X87_TW_VALID;
3102      value.high = 0x3ffe;
3103
3104      if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3105         value.low = U64(0xb17217f7d1cf79ac);
3106      else
3107         value.low = U64(0xb17217f7d1cf79ab);
3108
3109      m_x87_sw &= ~X87_SW_C1;
3110   }
3111   else
3112   {
3113      value = fx80_inan;
3114      tag = X87_TW_SPECIAL;
3115   }
3116
3117   if (x87_check_exceptions())
3118   {
3119      x87_set_tag(ST_TO_PHYS(0), tag);
3120      x87_write_stack(0, value, FALSE);
3121   }
3122
3123   CYCLES(8);
3124}
3125
3126void i386_device::x87_fldz(UINT8 modrm)
3127{
3128   floatx80 value;
3129   int tag;
3130
3131   if (x87_dec_stack())
3132   {
3133      value = fx80_zero;
3134      tag = X87_TW_ZERO;
3135      m_x87_sw &= ~X87_SW_C1;
3136   }
3137   else
3138   {
3139      value = fx80_inan;
3140      tag = X87_TW_SPECIAL;
3141   }
3142
3143   if (x87_check_exceptions())
3144   {
3145      x87_set_tag(ST_TO_PHYS(0), tag);
3146      x87_write_stack(0, value, FALSE);
3147   }
3148
3149   CYCLES(4);
3150}
3151
3152
3153/*************************************
3154 *
3155 * Miscellaneous
3156 *
3157 *************************************/
3158
3159void i386_device::x87_fnop(UINT8 modrm)
3160{
3161   CYCLES(3);
3162}
3163
3164void i386_device::x87_fchs(UINT8 modrm)
3165{
3166   floatx80 value;
3167
3168   if (X87_IS_ST_EMPTY(0))
3169   {
3170      x87_set_stack_underflow();
3171      value = fx80_inan;
3172   }
3173   else
3174   {
3175      m_x87_sw &= ~X87_SW_C1;
3176
3177      value = ST(0);
3178      value.high ^= 0x8000;
3179   }
3180
3181   if (x87_check_exceptions())
3182      x87_write_stack(0, value, FALSE);
3183
3184   CYCLES(6);
3185}
3186
3187void i386_device::x87_fabs(UINT8 modrm)
3188{
3189   floatx80 value;
3190
3191   if (X87_IS_ST_EMPTY(0))
3192   {
3193      x87_set_stack_underflow();
3194      value = fx80_inan;
3195   }
3196   else
3197   {
3198      m_x87_sw &= ~X87_SW_C1;
3199
3200      value = ST(0);
3201      value.high &= 0x7fff;
3202   }
3203
3204   if (x87_check_exceptions())
3205      x87_write_stack(0, value, FALSE);
3206
3207   CYCLES(6);
3208}
3209
3210void i386_device::x87_fscale(UINT8 modrm)
3211{
3212   floatx80 value;
3213
3214   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
3215   {
3216      x87_set_stack_underflow();
3217      value = fx80_inan;
3218   }
3219   else
3220   {
3221      m_x87_sw &= ~X87_SW_C1;
3222      value = ST(0);
3223
3224      // Set the rounding mode to truncate
3225      UINT16 old_cw = m_x87_cw;
3226      UINT16 new_cw = (old_cw & ~(X87_CW_RC_MASK << X87_CW_RC_SHIFT)) | (X87_CW_RC_ZERO << X87_CW_RC_SHIFT);
3227      x87_write_cw(new_cw);
3228
3229      // Interpret ST(1) as an integer
3230      UINT32 st1 = floatx80_to_int32(floatx80_round_to_int(ST(1)));
3231
3232      // Restore the rounding mode
3233      x87_write_cw(old_cw);
3234
3235      // Get the unbiased exponent of ST(0)
3236      INT16 exp = (ST(0).high & 0x7fff) - 0x3fff;
3237
3238      // Calculate the new exponent
3239      exp = (exp + st1 + 0x3fff) & 0x7fff;
3240
3241      // Write it back
3242      value.high = (value.high & ~0x7fff) + exp;
3243   }
3244
3245   if (x87_check_exceptions())
3246      x87_write_stack(0, value, FALSE);
3247
3248   CYCLES(31);
3249}
3250
3251void i386_device::x87_frndint(UINT8 modrm)
3252{
3253   floatx80 value;
3254
3255   if (X87_IS_ST_EMPTY(0))
3256   {
3257      x87_set_stack_underflow();
3258      value = fx80_inan;
3259   }
3260   else
3261   {
3262      m_x87_sw &= ~X87_SW_C1;
3263
3264      value = floatx80_round_to_int(ST(0));
3265   }
3266
3267   if (x87_check_exceptions())
3268      x87_write_stack(0, value, TRUE);
3269
3270   CYCLES(21);
3271}
3272
3273void i386_device::x87_fxtract(UINT8 modrm)
3274{
3275   floatx80 sig80, exp80;
3276
3277   if (X87_IS_ST_EMPTY(0))
3278   {
3279      x87_set_stack_underflow();
3280      sig80 = exp80 = fx80_inan;
3281   }
3282   else if (!X87_IS_ST_EMPTY(7))
3283   {
3284      x87_set_stack_overflow();
3285      sig80 = exp80 = fx80_inan;
3286   }
3287   else
3288   {
3289      floatx80 value = ST(0);
3290
3291      if (floatx80_eq(value, fx80_zero))
3292      {
3293         m_x87_sw |= X87_SW_ZE;
3294
3295         exp80 = fx80_ninf;
3296         sig80 = fx80_zero;
3297      }
3298      else
3299      {
3300         // Extract the unbiased exponent
3301         exp80 = int32_to_floatx80((value.high & 0x7fff) - 0x3fff);
3302
3303         // For the significand, replicate the original value and set its true exponent to 0.
3304         sig80 = value;
3305         sig80.high &= ~0x7fff;
3306         sig80.high |=  0x3fff;
3307      }
3308   }
3309
3310   if (x87_check_exceptions())
3311   {
3312      x87_write_stack(0, exp80, TRUE);
3313      x87_dec_stack();
3314      x87_write_stack(0, sig80, TRUE);
3315   }
3316
3317   CYCLES(21);
3318}
3319
3320/*************************************
3321 *
3322 * Comparison
3323 *
3324 *************************************/
3325
3326void i386_device::x87_ftst(UINT8 modrm)
3327{
3328   if (X87_IS_ST_EMPTY(0))
3329   {
3330      x87_set_stack_underflow();
3331      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3332   }
3333   else
3334   {
3335      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3336
3337      if (floatx80_is_nan(ST(0)))
3338      {
3339         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3340         m_x87_sw |= X87_SW_IE;
3341      }
3342      else
3343      {
3344         if (floatx80_eq(ST(0), fx80_zero))
3345            m_x87_sw |= X87_SW_C3;
3346
3347         if (floatx80_lt(ST(0), fx80_zero))
3348            m_x87_sw |= X87_SW_C0;
3349      }
3350   }
3351
3352   x87_check_exceptions();
3353
3354   CYCLES(4);
3355}
3356
3357void i386_device::x87_fxam(UINT8 modrm)
3358{
3359   floatx80 value = ST(0);
3360
3361   m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3362
3363   // TODO: Unsupported and denormal values
3364   if (X87_IS_ST_EMPTY(0))
3365   {
3366      m_x87_sw |= X87_SW_C3 | X87_SW_C0;
3367   }
3368   else if (floatx80_is_zero(value))
3369   {
3370      m_x87_sw |= X87_SW_C3;
3371   }
3372   if (floatx80_is_nan(value))
3373   {
3374      m_x87_sw |= X87_SW_C0;
3375   }
3376   else if (floatx80_is_inf(value))
3377   {
3378      m_x87_sw |= X87_SW_C2 | X87_SW_C0;
3379   }
3380   else
3381   {
3382      m_x87_sw |= X87_SW_C2;
3383   }
3384
3385   if (value.high & 0x8000)
3386      m_x87_sw |= X87_SW_C1;
3387
3388   CYCLES(8);
3389}
3390
3391void i386_device::x87_ficom_m16int(UINT8 modrm)
3392{
3393   UINT32 ea = GetEA(modrm, 0);
3394   if (X87_IS_ST_EMPTY(0))
3395   {
3396      x87_set_stack_underflow();
3397      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3398   }
3399   else
3400   {
3401      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3402
3403      INT16 m16int = READ16(ea);
3404
3405      floatx80 a = ST(0);
3406      floatx80 b = int32_to_floatx80(m16int);
3407
3408      if (floatx80_is_nan(a))
3409      {
3410         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3411         m_x87_sw |= X87_SW_IE;
3412      }
3413      else
3414      {
3415         if (floatx80_eq(a, b))
3416            m_x87_sw |= X87_SW_C3;
3417
3418         if (floatx80_lt(a, b))
3419            m_x87_sw |= X87_SW_C0;
3420      }
3421   }
3422
3423   x87_check_exceptions();
3424
3425   CYCLES(16);
3426}
3427
3428void i386_device::x87_ficom_m32int(UINT8 modrm)
3429{
3430   UINT32 ea = GetEA(modrm, 0);
3431   if (X87_IS_ST_EMPTY(0))
3432   {
3433      x87_set_stack_underflow();
3434      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3435   }
3436   else
3437   {
3438      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3439
3440      INT32 m32int = READ32(ea);
3441
3442      floatx80 a = ST(0);
3443      floatx80 b = int32_to_floatx80(m32int);
3444
3445      if (floatx80_is_nan(a))
3446      {
3447         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3448         m_x87_sw |= X87_SW_IE;
3449      }
3450      else
3451      {
3452         if (floatx80_eq(a, b))
3453            m_x87_sw |= X87_SW_C3;
3454
3455         if (floatx80_lt(a, b))
3456            m_x87_sw |= X87_SW_C0;
3457      }
3458   }
3459
3460   x87_check_exceptions();
3461
3462   CYCLES(15);
3463}
3464
3465void i386_device::x87_ficomp_m16int(UINT8 modrm)
3466{
3467   UINT32 ea = GetEA(modrm, 0);
3468   if (X87_IS_ST_EMPTY(0))
3469   {
3470      x87_set_stack_underflow();
3471      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3472   }
3473   else
3474   {
3475      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3476
3477      INT16 m16int = READ16(ea);
3478
3479      floatx80 a = ST(0);
3480      floatx80 b = int32_to_floatx80(m16int);
3481
3482      if (floatx80_is_nan(a))
3483      {
3484         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3485         m_x87_sw |= X87_SW_IE;
3486      }
3487      else
3488      {
3489         if (floatx80_eq(a, b))
3490            m_x87_sw |= X87_SW_C3;
3491
3492         if (floatx80_lt(a, b))
3493            m_x87_sw |= X87_SW_C0;
3494      }
3495   }
3496
3497   if (x87_check_exceptions())
3498      x87_inc_stack();
3499
3500   CYCLES(16);
3501}
3502
3503void i386_device::x87_ficomp_m32int(UINT8 modrm)
3504{
3505   UINT32 ea = GetEA(modrm, 0);
3506   if (X87_IS_ST_EMPTY(0))
3507   {
3508      x87_set_stack_underflow();
3509      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3510   }
3511   else
3512   {
3513      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3514
3515      INT32 m32int = READ32(ea);
3516
3517      floatx80 a = ST(0);
3518      floatx80 b = int32_to_floatx80(m32int);
3519
3520      if (floatx80_is_nan(a))
3521      {
3522         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3523         m_x87_sw |= X87_SW_IE;
3524      }
3525      else
3526      {
3527         if (floatx80_eq(a, b))
3528            m_x87_sw |= X87_SW_C3;
3529
3530         if (floatx80_lt(a, b))
3531            m_x87_sw |= X87_SW_C0;
3532      }
3533   }
3534
3535   if (x87_check_exceptions())
3536      x87_inc_stack();
3537
3538   CYCLES(15);
3539}
3540
3541
3542void i386_device::x87_fcom_m32real(UINT8 modrm)
3543{
3544   UINT32 ea = GetEA(modrm, 0);
3545   if (X87_IS_ST_EMPTY(0))
3546   {
3547      x87_set_stack_underflow();
3548      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3549   }
3550   else
3551   {
3552      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3553
3554      UINT32 m32real = READ32(ea);
3555
3556      floatx80 a = ST(0);
3557      floatx80 b = float32_to_floatx80(m32real);
3558
3559      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3560      {
3561         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3562         m_x87_sw |= X87_SW_IE;
3563      }
3564      else
3565      {
3566         if (floatx80_eq(a, b))
3567            m_x87_sw |= X87_SW_C3;
3568
3569         if (floatx80_lt(a, b))
3570            m_x87_sw |= X87_SW_C0;
3571      }
3572   }
3573
3574   x87_check_exceptions();
3575
3576   CYCLES(4);
3577}
3578
3579void i386_device::x87_fcom_m64real(UINT8 modrm)
3580{
3581   UINT32 ea = GetEA(modrm, 0);
3582   if (X87_IS_ST_EMPTY(0))
3583   {
3584      x87_set_stack_underflow();
3585      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3586   }
3587   else
3588   {
3589      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3590
3591      UINT64 m64real = READ64(ea);
3592
3593      floatx80 a = ST(0);
3594      floatx80 b = float64_to_floatx80(m64real);
3595
3596      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3597      {
3598         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3599         m_x87_sw |= X87_SW_IE;
3600      }
3601      else
3602      {
3603         if (floatx80_eq(a, b))
3604            m_x87_sw |= X87_SW_C3;
3605
3606         if (floatx80_lt(a, b))
3607            m_x87_sw |= X87_SW_C0;
3608      }
3609   }
3610
3611   x87_check_exceptions();
3612
3613   CYCLES(4);
3614}
3615
3616void i386_device::x87_fcom_sti(UINT8 modrm)
3617{
3618   int i = modrm & 7;
3619
3620   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3621   {
3622      x87_set_stack_underflow();
3623      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3624   }
3625   else
3626   {
3627      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3628
3629      floatx80 a = ST(0);
3630      floatx80 b = ST(i);
3631
3632      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3633      {
3634         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3635         m_x87_sw |= X87_SW_IE;
3636      }
3637      else
3638      {
3639         if (floatx80_eq(a, b))
3640            m_x87_sw |= X87_SW_C3;
3641
3642         if (floatx80_lt(a, b))
3643            m_x87_sw |= X87_SW_C0;
3644      }
3645   }
3646
3647   x87_check_exceptions();
3648
3649   CYCLES(4);
3650}
3651
3652void i386_device::x87_fcomp_m32real(UINT8 modrm)
3653{
3654   UINT32 ea = GetEA(modrm, 0);
3655   if (X87_IS_ST_EMPTY(0))
3656   {
3657      x87_set_stack_underflow();
3658      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3659   }
3660   else
3661   {
3662      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3663
3664      UINT32 m32real = READ32(ea);
3665
3666      floatx80 a = ST(0);
3667      floatx80 b = float32_to_floatx80(m32real);
3668
3669      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3670      {
3671         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3672         m_x87_sw |= X87_SW_IE;
3673      }
3674      else
3675      {
3676         if (floatx80_eq(a, b))
3677            m_x87_sw |= X87_SW_C3;
3678
3679         if (floatx80_lt(a, b))
3680            m_x87_sw |= X87_SW_C0;
3681      }
3682   }
3683
3684   if (x87_check_exceptions())
3685      x87_inc_stack();
3686
3687   CYCLES(4);
3688}
3689
3690void i386_device::x87_fcomp_m64real(UINT8 modrm)
3691{
3692   UINT32 ea = GetEA(modrm, 0);
3693   if (X87_IS_ST_EMPTY(0))
3694   {
3695      x87_set_stack_underflow();
3696      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3697   }
3698   else
3699   {
3700      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3701
3702      UINT64 m64real = READ64(ea);
3703
3704      floatx80 a = ST(0);
3705      floatx80 b = float64_to_floatx80(m64real);
3706
3707      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3708      {
3709         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3710         m_x87_sw |= X87_SW_IE;
3711      }
3712      else
3713      {
3714         if (floatx80_eq(a, b))
3715            m_x87_sw |= X87_SW_C3;
3716
3717         if (floatx80_lt(a, b))
3718            m_x87_sw |= X87_SW_C0;
3719      }
3720   }
3721
3722   if (x87_check_exceptions())
3723      x87_inc_stack();
3724
3725   CYCLES(4);
3726}
3727
3728void i386_device::x87_fcomp_sti(UINT8 modrm)
3729{
3730   int i = modrm & 7;
3731
3732   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3733   {
3734      x87_set_stack_underflow();
3735      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3736   }
3737   else
3738   {
3739      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3740
3741      floatx80 a = ST(0);
3742      floatx80 b = ST(i);
3743
3744      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3745      {
3746         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3747         m_x87_sw |= X87_SW_IE;
3748      }
3749      else
3750      {
3751         if (floatx80_eq(a, b))
3752            m_x87_sw |= X87_SW_C3;
3753
3754         if (floatx80_lt(a, b))
3755            m_x87_sw |= X87_SW_C0;
3756      }
3757   }
3758
3759   if (x87_check_exceptions())
3760      x87_inc_stack();
3761
3762   CYCLES(4);
3763}
3764
3765void i386_device::x87_fcomip_sti(UINT8 modrm)
3766{
3767   int i = modrm & 7;
3768
3769   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3770   {
3771      x87_set_stack_underflow();
3772      m_ZF = 1;
3773      m_PF = 1;
3774      m_CF = 1;
3775   }
3776   else
3777   {
3778      m_x87_sw &= ~X87_SW_C1;
3779
3780      floatx80 a = ST(0);
3781      floatx80 b = ST(i);
3782
3783      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3784      {
3785         m_ZF = 1;
3786         m_PF = 1;
3787         m_CF = 1;
3788         m_x87_sw |= X87_SW_IE;
3789      }
3790      else
3791      {
3792         m_ZF = 0;
3793         m_PF = 0;
3794         m_CF = 0;
3795
3796         if (floatx80_eq(a, b))
3797            m_ZF = 1;
3798
3799         if (floatx80_lt(a, b))
3800            m_CF = 1;
3801      }
3802   }
3803
3804   if (x87_check_exceptions())
3805      x87_inc_stack();
3806
3807   CYCLES(4); // TODO: correct cycle count
3808}
3809
3810void i386_device::x87_fcompp(UINT8 modrm)
3811{
3812   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
3813   {
3814      x87_set_stack_underflow();
3815      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3816   }
3817   else
3818   {
3819      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3820
3821      floatx80 a = ST(0);
3822      floatx80 b = ST(1);
3823
3824      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3825      {
3826         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3827         m_x87_sw |= X87_SW_IE;
3828      }
3829      else
3830      {
3831         if (floatx80_eq(a, b))
3832            m_x87_sw |= X87_SW_C3;
3833
3834         if (floatx80_lt(a, b))
3835            m_x87_sw |= X87_SW_C0;
3836      }
3837   }
3838
3839   if (x87_check_exceptions())
3840   {
3841      x87_inc_stack();
3842      x87_inc_stack();
3843   }
3844
3845   CYCLES(5);
3846}
3847
3848
3849/*************************************
3850 *
3851 * Unordererd comparison
3852 *
3853 *************************************/
3854
3855void i386_device::x87_fucom_sti(UINT8 modrm)
3856{
3857   int i = modrm & 7;
3858
3859   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3860   {
3861      x87_set_stack_underflow();
3862      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3863   }
3864   else
3865   {
3866      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3867
3868      floatx80 a = ST(0);
3869      floatx80 b = ST(i);
3870
3871      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3872      {
3873         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3874
3875         if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
3876            m_x87_sw |= X87_SW_IE;
3877      }
3878      else
3879      {
3880         if (floatx80_eq(a, b))
3881            m_x87_sw |= X87_SW_C3;
3882
3883         if (floatx80_lt(a, b))
3884            m_x87_sw |= X87_SW_C0;
3885      }
3886   }
3887
3888   x87_check_exceptions();
3889
3890   CYCLES(4);
3891}
3892
3893void i386_device::x87_fucomp_sti(UINT8 modrm)
3894{
3895   int i = modrm & 7;
3896
3897   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3898   {
3899      x87_set_stack_underflow();
3900      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3901   }
3902   else
3903   {
3904      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3905
3906      floatx80 a = ST(0);
3907      floatx80 b = ST(i);
3908
3909      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3910      {
3911         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3912
3913         if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
3914            m_x87_sw |= X87_SW_IE;
3915      }
3916      else
3917      {
3918         if (floatx80_eq(a, b))
3919            m_x87_sw |= X87_SW_C3;
3920
3921         if (floatx80_lt(a, b))
3922            m_x87_sw |= X87_SW_C0;
3923      }
3924   }
3925
3926   if (x87_check_exceptions())
3927      x87_inc_stack();
3928
3929   CYCLES(4);
3930}
3931
3932void i386_device::x87_fucompp(UINT8 modrm)
3933{
3934   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
3935   {
3936      x87_set_stack_underflow();
3937      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3938   }
3939   else
3940   {
3941      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3942
3943      floatx80 a = ST(0);
3944      floatx80 b = ST(1);
3945
3946      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3947      {
3948         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3949
3950         if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
3951            m_x87_sw |= X87_SW_IE;
3952      }
3953      else
3954      {
3955         if (floatx80_eq(a, b))
3956            m_x87_sw |= X87_SW_C3;
3957
3958         if (floatx80_lt(a, b))
3959            m_x87_sw |= X87_SW_C0;
3960      }
3961   }
3962
3963   if (x87_check_exceptions())
3964   {
3965      x87_inc_stack();
3966      x87_inc_stack();
3967   }
3968
3969   CYCLES(4);
3970}
3971
3972
3973/*************************************
3974 *
3975 * Control
3976 *
3977 *************************************/
3978
3979void i386_device::x87_fdecstp(UINT8 modrm)
3980{
3981   m_x87_sw &= ~X87_SW_C1;
3982
3983   x87_dec_stack();
3984   x87_check_exceptions();
3985
3986   CYCLES(3);
3987}
3988
3989void i386_device::x87_fincstp(UINT8 modrm)
3990{
3991   m_x87_sw &= ~X87_SW_C1;
3992
3993   x87_inc_stack();
3994   x87_check_exceptions();
3995
3996   CYCLES(3);
3997}
3998
3999void i386_device::x87_fclex(UINT8 modrm)
4000{
4001   m_x87_sw &= ~0x80ff;
4002
4003   CYCLES(7);
4004}
4005
4006void i386_device::x87_ffree(UINT8 modrm)
4007{
4008   x87_set_tag(ST_TO_PHYS(modrm & 7), X87_TW_EMPTY);
4009
4010   CYCLES(3);
4011}
4012
4013void i386_device::x87_finit(UINT8 modrm)
4014{
4015   x87_reset();
4016
4017   CYCLES(17);
4018}
4019
4020void i386_device::x87_fldcw(UINT8 modrm)
4021{
4022   UINT32 ea = GetEA(modrm, 0);
4023   UINT16 cw = READ16(ea);
4024
4025   x87_write_cw(cw);
4026
4027   x87_check_exceptions();
4028
4029   CYCLES(4);
4030}
4031
4032void i386_device::x87_fstcw(UINT8 modrm)
4033{
4034   UINT32 ea = GetEA(modrm, 1);
4035   WRITE16(ea, m_x87_cw);
4036
4037   CYCLES(3);
4038}
4039
4040void i386_device::x87_fldenv(UINT8 modrm)
4041{
4042   // TODO: Pointers and selectors
4043   UINT32 ea = GetEA(modrm, 0);
4044
4045   if (m_operand_size)
4046   {
4047      // 32-bit real/protected mode
4048      x87_write_cw(READ16(ea));
4049      m_x87_sw = READ16(ea + 4);
4050      m_x87_tw = READ16(ea + 8);
4051   }
4052   else
4053   {
4054      // 16-bit real/protected mode
4055      x87_write_cw(READ16(ea));
4056      m_x87_sw = READ16(ea + 2);
4057      m_x87_tw = READ16(ea + 4);
4058   }
4059
4060   x87_check_exceptions();
4061
4062   CYCLES((m_cr[0] & 1) ? 34 : 44);
4063}
4064
4065void i386_device::x87_fstenv(UINT8 modrm)
4066{
4067   UINT32 ea = GetEA(modrm, 1);
4068
4069   // TODO: Pointers and selectors
4070   switch((m_cr[0] & 1)|(m_operand_size & 1)<<1)
4071   {
4072      case 0: // 16-bit real mode
4073         WRITE16(ea + 0, m_x87_cw);
4074         WRITE16(ea + 2, m_x87_sw);
4075         WRITE16(ea + 4, m_x87_tw);
4076//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4077//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4078//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4079//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4080         break;
4081      case 1: // 16-bit protected mode
4082         WRITE16(ea + 0, m_x87_cw);
4083         WRITE16(ea + 2, m_x87_sw);
4084         WRITE16(ea + 4, m_x87_tw);
4085//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4086//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4087//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4088//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4089         break;
4090      case 2: // 32-bit real mode
4091         WRITE16(ea + 0, m_x87_cw);
4092         WRITE16(ea + 4, m_x87_sw);
4093         WRITE16(ea + 8, m_x87_tw);
4094//          WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff);
4095//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4096//          WRITE16(ea + 20, m_fpu_data_ptr & 0xffff);
4097//          WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4098//          WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12);
4099         break;
4100      case 3: // 32-bit protected mode
4101         WRITE16(ea + 0,  m_x87_cw);
4102         WRITE16(ea + 4,  m_x87_sw);
4103         WRITE16(ea + 8,  m_x87_tw);
4104//          WRITE32(ea + 12, m_fpu_inst_ptr);
4105//          WRITE32(ea + 16, m_fpu_opcode);
4106//          WRITE32(ea + 20, m_fpu_data_ptr);
4107//          WRITE32(ea + 24, m_fpu_inst_ptr);
4108         break;
4109   }
4110
4111   CYCLES((m_cr[0] & 1) ? 56 : 67);
4112}
4113
4114void i386_device::x87_fsave(UINT8 modrm)
4115{
4116   UINT32 ea = GetEA(modrm, 1);
4117
4118   // TODO: Pointers and selectors
4119   switch((m_cr[0] & 1)|(m_operand_size & 1)<<1)
4120   {
4121      case 0: // 16-bit real mode
4122         WRITE16(ea + 0, m_x87_cw);
4123         WRITE16(ea + 2, m_x87_sw);
4124         WRITE16(ea + 4, m_x87_tw);
4125//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4126//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4127//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4128//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4129         ea += 14;
4130         break;
4131      case 1: // 16-bit protected mode
4132         WRITE16(ea + 0, m_x87_cw);
4133         WRITE16(ea + 2, m_x87_sw);
4134         WRITE16(ea + 4, m_x87_tw);
4135//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4136//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4137//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4138//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4139         ea += 14;
4140         break;
4141      case 2: // 32-bit real mode
4142         WRITE16(ea + 0, m_x87_cw);
4143         WRITE16(ea + 4, m_x87_sw);
4144         WRITE16(ea + 8, m_x87_tw);
4145//          WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff);
4146//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4147//          WRITE16(ea + 20, m_fpu_data_ptr & 0xffff);
4148//          WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4149//          WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12);
4150         ea += 28;
4151         break;
4152      case 3: // 32-bit protected mode
4153         WRITE16(ea + 0,  m_x87_cw);
4154         WRITE16(ea + 4,  m_x87_sw);
4155         WRITE16(ea + 8,  m_x87_tw);
4156//          WRITE32(ea + 12, m_fpu_inst_ptr);
4157//          WRITE32(ea + 16, m_fpu_opcode);
4158//          WRITE32(ea + 20, m_fpu_data_ptr);
4159//          WRITE32(ea + 24, m_fpu_inst_ptr);
4160         ea += 28;
4161         break;
4162   }
4163
4164   for (int i = 0; i < 8; ++i)
4165      x87_write_stack(i, READ80(ea + i*10), FALSE);
4166
4167   CYCLES((m_cr[0] & 1) ? 56 : 67);
4168}
4169
4170void i386_device::x87_frstor(UINT8 modrm)
4171{
4172   UINT32 ea = GetEA(modrm, 0);
4173
4174   // TODO: Pointers and selectors
4175   switch((m_cr[0] & 1)|(m_operand_size & 1)<<1)
4176   {
4177      case 0: // 16-bit real mode
4178         x87_write_cw(READ16(ea));
4179         m_x87_sw = READ16(ea + 2);
4180         m_x87_tw = READ16(ea + 4);
4181//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4182//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4183//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4184//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4185         ea += 14;
4186         break;
4187      case 1: // 16-bit protected mode
4188         x87_write_cw(READ16(ea));
4189         m_x87_sw = READ16(ea + 2);
4190         m_x87_tw = READ16(ea + 4);
4191//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4192//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4193//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4194//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4195         ea += 14;
4196         break;
4197      case 2: // 32-bit real mode
4198         x87_write_cw(READ16(ea));
4199         m_x87_sw = READ16(ea + 4);
4200         m_x87_tw = READ16(ea + 8);
4201//          WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff);
4202//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4203//          WRITE16(ea + 20, m_fpu_data_ptr & 0xffff);
4204//          WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4205//          WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12);
4206         ea += 28;
4207         break;
4208      case 3: // 32-bit protected mode
4209         x87_write_cw(READ16(ea));
4210         m_x87_sw = READ16(ea + 4);
4211         m_x87_tw = READ16(ea + 8);
4212//          WRITE32(ea + 12, m_fpu_inst_ptr);
4213//          WRITE32(ea + 16, m_fpu_opcode);
4214//          WRITE32(ea + 20, m_fpu_data_ptr);
4215//          WRITE32(ea + 24, m_fpu_inst_ptr);
4216         ea += 28;
4217         break;
4218   }
4219
4220   for (int i = 0; i < 8; ++i)
4221      WRITE80(ea + i*10, ST(i));
4222
4223   CYCLES((m_cr[0] & 1) ? 34 : 44);
4224}
4225
4226void i386_device::x87_fxch(UINT8 modrm)
4227{
4228   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
4229      x87_set_stack_underflow();
4230
4231   if (x87_check_exceptions())
4232   {
4233      floatx80 tmp = ST(0);
4234      ST(0) = ST(1);
4235      ST(1) = tmp;
4236
4237      // Swap the tags
4238      int tag0 = X87_TAG(ST_TO_PHYS(0));
4239      x87_set_tag(ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(1)));
4240      x87_set_tag(ST_TO_PHYS(1), tag0);
4241   }
4242
4243   CYCLES(4);
4244}
4245
4246void i386_device::x87_fxch_sti(UINT8 modrm)
4247{
4248   int i = modrm & 7;
4249
4250   if (X87_IS_ST_EMPTY(0))
4251   {
4252      ST(0) = fx80_inan;
4253      x87_set_tag(ST_TO_PHYS(0), X87_TW_SPECIAL);
4254      x87_set_stack_underflow();
4255   }
4256   if (X87_IS_ST_EMPTY(i))
4257   {
4258      ST(i) = fx80_inan;
4259      x87_set_tag(ST_TO_PHYS(i), X87_TW_SPECIAL);
4260      x87_set_stack_underflow();
4261   }
4262
4263   if (x87_check_exceptions())
4264   {
4265      floatx80 tmp = ST(0);
4266      ST(0) = ST(i);
4267      ST(i) = tmp;
4268
4269      // Swap the tags
4270      int tag0 = X87_TAG(ST_TO_PHYS(0));
4271      x87_set_tag(ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(i)));
4272      x87_set_tag(ST_TO_PHYS(i), tag0);
4273   }
4274
4275   CYCLES(4);
4276}
4277
4278void i386_device::x87_fstsw_ax(UINT8 modrm)
4279{
4280   REG16(AX) = m_x87_sw;
4281
4282   CYCLES(3);
4283}
4284
4285void i386_device::x87_fstsw_m2byte(UINT8 modrm)
4286{
4287   UINT32 ea = GetEA(modrm, 1);
4288
4289   WRITE16(ea, m_x87_sw);
4290
4291   CYCLES(3);
4292}
4293
4294void i386_device::x87_invalid(UINT8 modrm)
4295{
4296   // TODO
4297   fatalerror("x87 invalid instruction (PC:%.4x)\n", m_pc);
4298}
4299
4300
4301
4302/*************************************
4303 *
4304 * Instruction dispatch
4305 *
4306 *************************************/
4307
4308void i386_device::i386_x87_group_d8()
4309{
4310   UINT8 modrm = FETCH();
4311   (this->*m_opcode_table_x87_d8[modrm])(modrm);
4312}
4313
4314void i386_device::i386_x87_group_d9()
4315{
4316   UINT8 modrm = FETCH();
4317   (this->*m_opcode_table_x87_d9[modrm])(modrm);
4318}
4319
4320void i386_device::i386_x87_group_da()
4321{
4322   UINT8 modrm = FETCH();
4323   (this->*m_opcode_table_x87_da[modrm])(modrm);
4324}
4325
4326void i386_device::i386_x87_group_db()
4327{
4328   UINT8 modrm = FETCH();
4329   (this->*m_opcode_table_x87_db[modrm])(modrm);
4330}
4331
4332void i386_device::i386_x87_group_dc()
4333{
4334   UINT8 modrm = FETCH();
4335   (this->*m_opcode_table_x87_dc[modrm])(modrm);
4336}
4337
4338void i386_device::i386_x87_group_dd()
4339{
4340   UINT8 modrm = FETCH();
4341   (this->*m_opcode_table_x87_dd[modrm])(modrm);
4342}
4343
4344void i386_device::i386_x87_group_de()
4345{
4346   UINT8 modrm = FETCH();
4347   (this->*m_opcode_table_x87_de[modrm])(modrm);
4348}
4349
4350void i386_device::i386_x87_group_df()
4351{
4352   UINT8 modrm = FETCH();
4353   (this->*m_opcode_table_x87_df[modrm])(modrm);
4354}
4355
4356
4357/*************************************
4358 *
4359 * Opcode table building
4360 *
4361 *************************************/
4362
4363void i386_device::build_x87_opcode_table_d8()
4364{
4365   int modrm = 0;
4366
4367   for (modrm = 0; modrm < 0x100; ++modrm)
4368   {
4369      i386_modrm_func ptr = &i386_device::x87_invalid;
4370
4371      if (modrm < 0xc0)
4372      {
4373         switch ((modrm >> 3) & 0x7)
4374         {
4375            case 0x00: ptr = &i386_device::x87_fadd_m32real;  break;
4376            case 0x01: ptr = &i386_device::x87_fmul_m32real;  break;
4377            case 0x02: ptr = &i386_device::x87_fcom_m32real;  break;
4378            case 0x03: ptr = &i386_device::x87_fcomp_m32real; break;
4379            case 0x04: ptr = &i386_device::x87_fsub_m32real;  break;
4380            case 0x05: ptr = &i386_device::x87_fsubr_m32real; break;
4381            case 0x06: ptr = &i386_device::x87_fdiv_m32real;  break;
4382            case 0x07: ptr = &i386_device::x87_fdivr_m32real; break;
4383         }
4384      }
4385      else
4386      {
4387         switch (modrm)
4388         {
4389            case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_fadd_st_sti;  break;
4390            case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fmul_st_sti;  break;
4391            case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = &i386_device::x87_fcom_sti;     break;
4392            case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = &i386_device::x87_fcomp_sti;    break;
4393            case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fsub_st_sti;  break;
4394            case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fsubr_st_sti; break;
4395            case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fdiv_st_sti;  break;
4396            case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = &i386_device::x87_fdivr_st_sti; break;
4397         }
4398      }
4399
4400      m_opcode_table_x87_d8[modrm] = ptr;
4401   }
4402}
4403
4404
4405void i386_device::build_x87_opcode_table_d9()
4406{
4407   int modrm = 0;
4408
4409   for (modrm = 0; modrm < 0x100; ++modrm)
4410   {
4411      i386_modrm_func ptr = &i386_device::x87_invalid;
4412
4413      if (modrm < 0xc0)
4414      {
4415         switch ((modrm >> 3) & 0x7)
4416         {
4417            case 0x00: ptr = &i386_device::x87_fld_m32real;   break;
4418            case 0x02: ptr = &i386_device::x87_fst_m32real;   break;
4419            case 0x03: ptr = &i386_device::x87_fstp_m32real;  break;
4420            case 0x04: ptr = &i386_device::x87_fldenv;        break;
4421            case 0x05: ptr = &i386_device::x87_fldcw;         break;
4422            case 0x06: ptr = &i386_device::x87_fstenv;        break;
4423            case 0x07: ptr = &i386_device::x87_fstcw;         break;
4424         }
4425      }
4426      else
4427      {
4428         switch (modrm)
4429         {
4430            case 0xc0:
4431            case 0xc1:
4432            case 0xc2:
4433            case 0xc3:
4434            case 0xc4:
4435            case 0xc5:
4436            case 0xc6:
4437            case 0xc7: ptr = &i386_device::x87_fld_sti;   break;
4438
4439            case 0xc8:
4440            case 0xc9:
4441            case 0xca:
4442            case 0xcb:
4443            case 0xcc:
4444            case 0xcd:
4445            case 0xce:
4446            case 0xcf: ptr = &i386_device::x87_fxch_sti;  break;
4447
4448            case 0xd0: ptr = &i386_device::x87_fnop;      break;
4449            case 0xe0: ptr = &i386_device::x87_fchs;      break;
4450            case 0xe1: ptr = &i386_device::x87_fabs;      break;
4451            case 0xe4: ptr = &i386_device::x87_ftst;      break;
4452            case 0xe5: ptr = &i386_device::x87_fxam;      break;
4453            case 0xe8: ptr = &i386_device::x87_fld1;      break;
4454            case 0xe9: ptr = &i386_device::x87_fldl2t;    break;
4455            case 0xea: ptr = &i386_device::x87_fldl2e;    break;
4456            case 0xeb: ptr = &i386_device::x87_fldpi;     break;
4457            case 0xec: ptr = &i386_device::x87_fldlg2;    break;
4458            case 0xed: ptr = &i386_device::x87_fldln2;    break;
4459            case 0xee: ptr = &i386_device::x87_fldz;      break;
4460            case 0xf0: ptr = &i386_device::x87_f2xm1;     break;
4461            case 0xf1: ptr = &i386_device::x87_fyl2x;     break;
4462            case 0xf2: ptr = &i386_device::x87_fptan;     break;
4463            case 0xf3: ptr = &i386_device::x87_fpatan;    break;
4464            case 0xf4: ptr = &i386_device::x87_fxtract;   break;
4465            case 0xf5: ptr = &i386_device::x87_fprem1;    break;
4466            case 0xf6: ptr = &i386_device::x87_fdecstp;   break;
4467            case 0xf7: ptr = &i386_device::x87_fincstp;   break;
4468            case 0xf8: ptr = &i386_device::x87_fprem;     break;
4469            case 0xf9: ptr = &i386_device::x87_fyl2xp1;   break;
4470            case 0xfa: ptr = &i386_device::x87_fsqrt;     break;
4471            case 0xfb: ptr = &i386_device::x87_fsincos;   break;
4472            case 0xfc: ptr = &i386_device::x87_frndint;   break;
4473            case 0xfd: ptr = &i386_device::x87_fscale;    break;
4474            case 0xfe: ptr = &i386_device::x87_fsin;      break;
4475            case 0xff: ptr = &i386_device::x87_fcos;      break;
4476         }
4477      }
4478
4479      m_opcode_table_x87_d9[modrm] = ptr;
4480   }
4481}
4482
4483void i386_device::build_x87_opcode_table_da()
4484{
4485   int modrm = 0;
4486
4487   for (modrm = 0; modrm < 0x100; ++modrm)
4488   {
4489      i386_modrm_func ptr = &i386_device::x87_invalid;
4490
4491      if (modrm < 0xc0)
4492      {
4493         switch ((modrm >> 3) & 0x7)
4494         {
4495            case 0x00: ptr = &i386_device::x87_fiadd_m32int;  break;
4496            case 0x01: ptr = &i386_device::x87_fimul_m32int;  break;
4497            case 0x02: ptr = &i386_device::x87_ficom_m32int;  break;
4498            case 0x03: ptr = &i386_device::x87_ficomp_m32int; break;
4499            case 0x04: ptr = &i386_device::x87_fisub_m32int;  break;
4500            case 0x05: ptr = &i386_device::x87_fisubr_m32int; break;
4501            case 0x06: ptr = &i386_device::x87_fidiv_m32int;  break;
4502            case 0x07: ptr = &i386_device::x87_fidivr_m32int; break;
4503         }
4504      }
4505      else
4506      {
4507         switch (modrm)
4508         {
4509            case 0xe9: ptr = &i386_device::x87_fucompp;       break;
4510         }
4511      }
4512
4513      m_opcode_table_x87_da[modrm] = ptr;
4514   }
4515}
4516
4517
4518void i386_device::build_x87_opcode_table_db()
4519{
4520   int modrm = 0;
4521
4522   for (modrm = 0; modrm < 0x100; ++modrm)
4523   {
4524      i386_modrm_func ptr = &i386_device::x87_invalid;
4525
4526      if (modrm < 0xc0)
4527      {
4528         switch ((modrm >> 3) & 0x7)
4529         {
4530            case 0x00: ptr = &i386_device::x87_fild_m32int;   break;
4531            case 0x02: ptr = &i386_device::x87_fist_m32int;   break;
4532            case 0x03: ptr = &i386_device::x87_fistp_m32int;  break;
4533            case 0x05: ptr = &i386_device::x87_fld_m80real;   break;
4534            case 0x07: ptr = &i386_device::x87_fstp_m80real;  break;
4535         }
4536      }
4537      else
4538      {
4539         switch (modrm)
4540         {
4541            case 0xe0: ptr = &i386_device::x87_fnop;          break; /* FENI */
4542            case 0xe1: ptr = &i386_device::x87_fnop;          break; /* FDISI */
4543            case 0xe2: ptr = &i386_device::x87_fclex;         break;
4544            case 0xe3: ptr = &i386_device::x87_finit;         break;
4545            case 0xe4: ptr = &i386_device::x87_fnop;          break; /* FSETPM */
4546         }
4547      }
4548
4549      m_opcode_table_x87_db[modrm] = ptr;
4550   }
4551}
4552
4553
4554void i386_device::build_x87_opcode_table_dc()
4555{
4556   int modrm = 0;
4557
4558   for (modrm = 0; modrm < 0x100; ++modrm)
4559   {
4560      i386_modrm_func ptr = &i386_device::x87_invalid;
4561
4562      if (modrm < 0xc0)
4563      {
4564         switch ((modrm >> 3) & 0x7)
4565         {
4566            case 0x00: ptr = &i386_device::x87_fadd_m64real;  break;
4567            case 0x01: ptr = &i386_device::x87_fmul_m64real;  break;
4568            case 0x02: ptr = &i386_device::x87_fcom_m64real;  break;
4569            case 0x03: ptr = &i386_device::x87_fcomp_m64real; break;
4570            case 0x04: ptr = &i386_device::x87_fsub_m64real;  break;
4571            case 0x05: ptr = &i386_device::x87_fsubr_m64real; break;
4572            case 0x06: ptr = &i386_device::x87_fdiv_m64real;  break;
4573            case 0x07: ptr = &i386_device::x87_fdivr_m64real; break;
4574         }
4575      }
4576      else
4577      {
4578         switch (modrm)
4579         {
4580            case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_fadd_sti_st;  break;
4581            case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fmul_sti_st;  break;
4582            case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fsubr_sti_st; break;
4583            case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fsub_sti_st;  break;
4584            case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fdivr_sti_st; break;
4585            case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = &i386_device::x87_fdiv_sti_st;  break;
4586         }
4587      }
4588
4589      m_opcode_table_x87_dc[modrm] = ptr;
4590   }
4591}
4592
4593
4594void i386_device::build_x87_opcode_table_dd()
4595{
4596   int modrm = 0;
4597
4598   for (modrm = 0; modrm < 0x100; ++modrm)
4599   {
4600      i386_modrm_func ptr = &i386_device::x87_invalid;
4601
4602      if (modrm < 0xc0)
4603      {
4604         switch ((modrm >> 3) & 0x7)
4605         {
4606            case 0x00: ptr = &i386_device::x87_fld_m64real;   break;
4607            case 0x02: ptr = &i386_device::x87_fst_m64real;   break;
4608            case 0x03: ptr = &i386_device::x87_fstp_m64real;  break;
4609            case 0x04: ptr = &i386_device::x87_frstor;        break;
4610            case 0x06: ptr = &i386_device::x87_fsave;         break;
4611            case 0x07: ptr = &i386_device::x87_fstsw_m2byte;  break;
4612         }
4613      }
4614      else
4615      {
4616         switch (modrm)
4617         {
4618            case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_ffree;        break;
4619            case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fxch_sti;     break;
4620            case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = &i386_device::x87_fst_sti;      break;
4621            case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = &i386_device::x87_fstp_sti;     break;
4622            case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fucom_sti;    break;
4623            case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fucomp_sti;   break;
4624         }
4625      }
4626
4627      m_opcode_table_x87_dd[modrm] = ptr;
4628   }
4629}
4630
4631
4632void i386_device::build_x87_opcode_table_de()
4633{
4634   int modrm = 0;
4635
4636   for (modrm = 0; modrm < 0x100; ++modrm)
4637   {
4638      i386_modrm_func ptr = &i386_device::x87_invalid;
4639
4640      if (modrm < 0xc0)
4641      {
4642         switch ((modrm >> 3) & 0x7)
4643         {
4644            case 0x00: ptr = &i386_device::x87_fiadd_m16int;  break;
4645            case 0x01: ptr = &i386_device::x87_fimul_m16int;  break;
4646            case 0x02: ptr = &i386_device::x87_ficom_m16int;  break;
4647            case 0x03: ptr = &i386_device::x87_ficomp_m16int; break;
4648            case 0x04: ptr = &i386_device::x87_fisub_m16int;  break;
4649            case 0x05: ptr = &i386_device::x87_fisubr_m16int; break;
4650            case 0x06: ptr = &i386_device::x87_fidiv_m16int;  break;
4651            case 0x07: ptr = &i386_device::x87_fidivr_m16int; break;
4652         }
4653      }
4654      else
4655      {
4656         switch (modrm)
4657         {
4658            case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_faddp;    break;
4659            case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fmulp;    break;
4660            case 0xd9: ptr = &i386_device::x87_fcompp; break;
4661            case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fsubrp;   break;
4662            case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fsubp;    break;
4663            case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fdivrp;   break;
4664            case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = &i386_device::x87_fdivp;    break;
4665         }
4666      }
4667
4668      m_opcode_table_x87_de[modrm] = ptr;
4669   }
4670}
4671
4672
4673void i386_device::build_x87_opcode_table_df()
4674{
4675   int modrm = 0;
4676
4677   for (modrm = 0; modrm < 0x100; ++modrm)
4678   {
4679      i386_modrm_func ptr = &i386_device::x87_invalid;
4680
4681      if (modrm < 0xc0)
4682      {
4683         switch ((modrm >> 3) & 0x7)
4684         {
4685            case 0x00: ptr = &i386_device::x87_fild_m16int;   break;
4686            case 0x02: ptr = &i386_device::x87_fist_m16int;   break;
4687            case 0x03: ptr = &i386_device::x87_fistp_m16int;  break;
4688            case 0x04: ptr = &i386_device::x87_fbld;          break;
4689            case 0x05: ptr = &i386_device::x87_fild_m64int;   break;
4690            case 0x06: ptr = &i386_device::x87_fbstp;         break;
4691            case 0x07: ptr = &i386_device::x87_fistp_m64int;  break;
4692         }
4693      }
4694      else
4695      {
4696         switch (modrm)
4697         {
4698            case 0xe0: ptr = &i386_device::x87_fstsw_ax;      break;
4699            case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fcomip_sti;    break;
4700         }
4701      }
4702
4703      m_opcode_table_x87_df[modrm] = ptr;
4704   }
4705}
4706
4707void i386_device::build_x87_opcode_table()
4708{
4709   build_x87_opcode_table_d8();
4710   build_x87_opcode_table_d9();
4711   build_x87_opcode_table_da();
4712   build_x87_opcode_table_db();
4713   build_x87_opcode_table_dc();
4714   build_x87_opcode_table_dd();
4715   build_x87_opcode_table_de();
4716   build_x87_opcode_table_df();
4717}
trunk/src/emu/cpu/i386/pentops.inc
r0r28739
1// Pentium+ specific opcodes
2
3extern flag float32_is_nan( float32 a ); // since its not defined in softfloat.h
4
5void i386_device::MMXPROLOG()
6{
7   //m_x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT); // top = 0
8   m_x87_tw = 0; // tag word = 0
9}
10
11void i386_device::READMMX(UINT32 ea,MMX_REG &r)
12{
13   r.q=READ64(ea);
14}
15
16void i386_device::WRITEMMX(UINT32 ea,MMX_REG &r)
17{
18   WRITE64(ea, r.q);
19}
20
21void i386_device::READXMM(UINT32 ea,XMM_REG &r)
22{
23   r.q[0]=READ64(ea);
24   r.q[1]=READ64(ea+8);
25}
26
27void i386_device::WRITEXMM(UINT32 ea,i386_device::XMM_REG &r)
28{
29   WRITE64(ea, r.q[0]);
30   WRITE64(ea+8, r.q[1]);
31}
32
33void i386_device::READXMM_LO64(UINT32 ea,i386_device::XMM_REG &r)
34{
35   r.q[0]=READ64(ea);
36}
37
38void i386_device::WRITEXMM_LO64(UINT32 ea,i386_device::XMM_REG &r)
39{
40   WRITE64(ea, r.q[0]);
41}
42
43void i386_device::READXMM_HI64(UINT32 ea,i386_device::XMM_REG &r)
44{
45   r.q[1]=READ64(ea);
46}
47
48void i386_device::WRITEXMM_HI64(UINT32 ea,i386_device::XMM_REG &r)
49{
50   WRITE64(ea, r.q[1]);
51}
52
53void i386_device::pentium_rdmsr()          // Opcode 0x0f 32
54{
55   UINT64 data;
56   UINT8 valid_msr = 0;
57
58   data = MSR_READ(REG32(ECX),&valid_msr);
59   REG32(EDX) = data >> 32;
60   REG32(EAX) = data & 0xffffffff;
61
62   if(m_CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized ...
63      FAULT(FAULT_GP,0) // ... throw a general exception fault
64
65   CYCLES(CYCLES_RDMSR);
66}
67
68void i386_device::pentium_wrmsr()          // Opcode 0x0f 30
69{
70   UINT64 data;
71   UINT8 valid_msr = 0;
72
73   data = (UINT64)REG32(EAX);
74   data |= (UINT64)(REG32(EDX)) << 32;
75
76   MSR_WRITE(REG32(ECX),data,&valid_msr);
77
78   if(m_CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized
79      FAULT(FAULT_GP,0) // ... throw a general exception fault
80
81   CYCLES(1);     // TODO: correct cycle count (~30-45)
82}
83
84void i386_device::pentium_rdtsc()          // Opcode 0x0f 31
85{
86   UINT64 ts = m_tsc + (m_base_cycles - m_cycles);
87   REG32(EAX) = (UINT32)(ts);
88   REG32(EDX) = (UINT32)(ts >> 32);
89
90   CYCLES(CYCLES_RDTSC);
91}
92
93void i386_device::pentium_ud2()    // Opcode 0x0f 0b
94{
95   i386_trap(6, 0, 0);
96}
97
98void i386_device::pentium_rsm()
99{
100   UINT32 smram_state = m_smbase + 0xfe00;
101   if(!m_smm)
102   {
103      logerror("i386: Invalid RSM outside SMM at %08X\n", m_pc - 1);
104      i386_trap(6, 0, 0);
105      return;
106   }
107
108   // load state, no sanity checks anywhere
109   m_smbase = READ32(smram_state+SMRAM_SMBASE);
110   m_cr[4] = READ32(smram_state+SMRAM_IP5_CR4);
111   m_sreg[ES].limit = READ32(smram_state+SMRAM_IP5_ESLIM);
112   m_sreg[ES].base = READ32(smram_state+SMRAM_IP5_ESBASE);
113   m_sreg[ES].flags = READ32(smram_state+SMRAM_IP5_ESACC);
114   m_sreg[CS].limit = READ32(smram_state+SMRAM_IP5_CSLIM);
115   m_sreg[CS].base = READ32(smram_state+SMRAM_IP5_CSBASE);
116   m_sreg[CS].flags = READ32(smram_state+SMRAM_IP5_CSACC);
117   m_sreg[SS].limit = READ32(smram_state+SMRAM_IP5_SSLIM);
118   m_sreg[SS].base = READ32(smram_state+SMRAM_IP5_SSBASE);
119   m_sreg[SS].flags = READ32(smram_state+SMRAM_IP5_SSACC);
120   m_sreg[DS].limit = READ32(smram_state+SMRAM_IP5_DSLIM);
121   m_sreg[DS].base = READ32(smram_state+SMRAM_IP5_DSBASE);
122   m_sreg[DS].flags = READ32(smram_state+SMRAM_IP5_DSACC);
123   m_sreg[FS].limit = READ32(smram_state+SMRAM_IP5_FSLIM);
124   m_sreg[FS].base = READ32(smram_state+SMRAM_IP5_FSBASE);
125   m_sreg[FS].flags = READ32(smram_state+SMRAM_IP5_FSACC);
126   m_sreg[GS].limit = READ32(smram_state+SMRAM_IP5_GSLIM);
127   m_sreg[GS].base = READ32(smram_state+SMRAM_IP5_GSBASE);
128   m_sreg[GS].flags = READ32(smram_state+SMRAM_IP5_GSACC);
129   m_ldtr.flags = READ32(smram_state+SMRAM_IP5_LDTACC);
130   m_ldtr.limit = READ32(smram_state+SMRAM_IP5_LDTLIM);
131   m_ldtr.base = READ32(smram_state+SMRAM_IP5_LDTBASE);
132   m_gdtr.limit = READ32(smram_state+SMRAM_IP5_GDTLIM);
133   m_gdtr.base = READ32(smram_state+SMRAM_IP5_GDTBASE);
134   m_idtr.limit = READ32(smram_state+SMRAM_IP5_IDTLIM);
135   m_idtr.base = READ32(smram_state+SMRAM_IP5_IDTBASE);
136   m_task.limit = READ32(smram_state+SMRAM_IP5_TRLIM);
137   m_task.base = READ32(smram_state+SMRAM_IP5_TRBASE);
138   m_task.flags = READ32(smram_state+SMRAM_IP5_TRACC);
139
140   m_sreg[ES].selector = READ32(smram_state+SMRAM_ES);
141   m_sreg[CS].selector = READ32(smram_state+SMRAM_CS);
142   m_sreg[SS].selector = READ32(smram_state+SMRAM_SS);
143   m_sreg[DS].selector = READ32(smram_state+SMRAM_DS);
144   m_sreg[FS].selector = READ32(smram_state+SMRAM_FS);
145   m_sreg[GS].selector = READ32(smram_state+SMRAM_GS);
146   m_ldtr.segment = READ32(smram_state+SMRAM_LDTR);
147   m_task.segment = READ32(smram_state+SMRAM_TR);
148
149   m_dr[7] = READ32(smram_state+SMRAM_DR7);
150   m_dr[6] = READ32(smram_state+SMRAM_DR6);
151   REG32(EAX) = READ32(smram_state+SMRAM_EAX);
152   REG32(ECX) = READ32(smram_state+SMRAM_ECX);
153   REG32(EDX) = READ32(smram_state+SMRAM_EDX);
154   REG32(EBX) = READ32(smram_state+SMRAM_EBX);
155   REG32(ESP) = READ32(smram_state+SMRAM_ESP);
156   REG32(EBP) = READ32(smram_state+SMRAM_EBP);
157   REG32(ESI) = READ32(smram_state+SMRAM_ESI);
158   REG32(EDI) = READ32(smram_state+SMRAM_EDI);
159   m_eip = READ32(smram_state+SMRAM_EIP);
160   m_eflags = READ32(smram_state+SMRAM_EAX);
161   m_cr[3] = READ32(smram_state+SMRAM_CR3);
162   m_cr[0] = READ32(smram_state+SMRAM_CR0);
163
164   m_CPL = (m_sreg[SS].flags >> 13) & 3; // cpl == dpl of ss
165
166   for(int i = 0; i < GS; i++)
167   {
168      if(PROTECTED_MODE && !V8086_MODE)
169      {
170         m_sreg[i].valid = m_sreg[i].selector ? true : false;
171         m_sreg[i].d = (m_sreg[i].flags & 0x4000) ? 1 : 0;
172      }
173      else
174         m_sreg[i].valid = true;
175   }
176
177   if(!m_smiact.isnull())
178      m_smiact(false);
179   m_smm = false;
180
181   CHANGE_PC(m_eip);
182   m_nmi_masked = false;
183   if(m_smi_latched)
184   {
185      pentium_smi();
186      return;
187   }
188   if(m_nmi_latched)
189   {
190      m_nmi_latched = false;
191      i386_trap(2, 1, 0);
192   }
193}
194
195void i386_device::pentium_prefetch_m8()    // Opcode 0x0f 18
196{
197   UINT8 modrm = FETCH();
198   UINT32 ea = GetEA(modrm,0);
199   CYCLES(1+(ea & 1)); // TODO: correct cycle count
200}
201
202void i386_device::pentium_cmovo_r16_rm16()    // Opcode 0x0f 40
203{
204   UINT16 src;
205   UINT8 modrm = FETCH();
206
207   if( modrm >= 0xc0 )
208   {
209      if (m_OF == 1)
210      {
211         src = LOAD_RM16(modrm);
212         STORE_REG16(modrm, src);
213      }
214      CYCLES(1); // TODO: correct cycle count
215   }
216   else
217   {
218      UINT32 ea = GetEA(modrm,0);
219      if (m_OF == 1)
220      {
221         src = READ16(ea);
222         STORE_REG16(modrm, src);
223      }
224      CYCLES(1); // TODO: correct cycle count
225   }
226}
227
228void i386_device::pentium_cmovo_r32_rm32()    // Opcode 0x0f 40
229{
230   UINT32 src;
231   UINT8 modrm = FETCH();
232
233   if( modrm >= 0xc0 )
234   {
235      if (m_OF == 1)
236      {
237         src = LOAD_RM32(modrm);
238         STORE_REG32(modrm, src);
239      }
240      CYCLES(1); // TODO: correct cycle count
241   }
242   else
243   {
244      UINT32 ea = GetEA(modrm,0);
245      if (m_OF == 1)
246      {
247         src = READ32(ea);
248         STORE_REG32(modrm, src);
249      }
250      CYCLES(1); // TODO: correct cycle count
251   }
252}
253
254void i386_device::pentium_cmovno_r16_rm16()    // Opcode 0x0f 41
255{
256   UINT16 src;
257   UINT8 modrm = FETCH();
258
259   if( modrm >= 0xc0 )
260   {
261      if (m_OF == 0)
262      {
263         src = LOAD_RM16(modrm);
264         STORE_REG16(modrm, src);
265      }
266      CYCLES(1); // TODO: correct cycle count
267   }
268   else
269   {
270      UINT32 ea = GetEA(modrm,0);
271      if (m_OF == 0)
272      {
273         src = READ16(ea);
274         STORE_REG16(modrm, src);
275      }
276      CYCLES(1); // TODO: correct cycle count
277   }
278}
279
280void i386_device::pentium_cmovno_r32_rm32()    // Opcode 0x0f 41
281{
282   UINT32 src;
283   UINT8 modrm = FETCH();
284
285   if( modrm >= 0xc0 )
286   {
287      if (m_OF == 0)
288      {
289         src = LOAD_RM32(modrm);
290         STORE_REG32(modrm, src);
291      }
292      CYCLES(1); // TODO: correct cycle count
293   }
294   else
295   {
296      UINT32 ea = GetEA(modrm,0);
297      if (m_OF == 0)
298      {
299         src = READ32(ea);
300         STORE_REG32(modrm, src);
301      }
302      CYCLES(1); // TODO: correct cycle count
303   }
304}
305
306void i386_device::pentium_cmovb_r16_rm16()    // Opcode 0x0f 42
307{
308   UINT16 src;
309   UINT8 modrm = FETCH();
310
311   if( modrm >= 0xc0 )
312   {
313      if (m_CF == 1)
314      {
315         src = LOAD_RM16(modrm);
316         STORE_REG16(modrm, src);
317      }
318      CYCLES(1); // TODO: correct cycle count
319   }
320   else
321   {
322      UINT32 ea = GetEA(modrm,0);
323      if (m_CF == 1)
324      {
325         src = READ16(ea);
326         STORE_REG16(modrm, src);
327      }
328      CYCLES(1); // TODO: correct cycle count
329   }
330}
331
332void i386_device::pentium_cmovb_r32_rm32()    // Opcode 0x0f 42
333{
334   UINT32 src;
335   UINT8 modrm = FETCH();
336
337   if( modrm >= 0xc0 )
338   {
339      if (m_CF == 1)
340      {
341         src = LOAD_RM32(modrm);
342         STORE_REG32(modrm, src);
343      }
344      CYCLES(1); // TODO: correct cycle count
345   }
346   else
347   {
348      UINT32 ea = GetEA(modrm,0);
349      if (m_CF == 1)
350      {
351         src = READ32(ea);
352         STORE_REG32(modrm, src);
353      }
354      CYCLES(1); // TODO: correct cycle count
355   }
356}
357
358void i386_device::pentium_cmovae_r16_rm16()    // Opcode 0x0f 43
359{
360   UINT16 src;
361   UINT8 modrm = FETCH();
362
363   if( modrm >= 0xc0 )
364   {
365      if (m_CF == 0)
366      {
367         src = LOAD_RM16(modrm);
368         STORE_REG16(modrm, src);
369      }
370      CYCLES(1); // TODO: correct cycle count
371   }
372   else
373   {
374      UINT32 ea = GetEA(modrm,0);
375      if (m_CF == 0)
376      {
377         src = READ16(ea);
378         STORE_REG16(modrm, src);
379      }
380      CYCLES(1); // TODO: correct cycle count
381   }
382}
383
384void i386_device::pentium_cmovae_r32_rm32()    // Opcode 0x0f 43
385{
386   UINT32 src;
387   UINT8 modrm = FETCH();
388
389   if( modrm >= 0xc0 )
390   {
391      if (m_CF == 0)
392      {
393         src = LOAD_RM32(modrm);
394         STORE_REG32(modrm, src);
395      }
396      CYCLES(1); // TODO: correct cycle count
397   }
398   else
399   {
400      UINT32 ea = GetEA(modrm,0);
401      if (m_CF == 0)
402      {
403         src = READ32(ea);
404         STORE_REG32(modrm, src);
405      }
406      CYCLES(1); // TODO: correct cycle count
407   }
408}
409
410void i386_device::pentium_cmove_r16_rm16()    // Opcode 0x0f 44
411{
412   UINT16 src;
413   UINT8 modrm = FETCH();
414
415   if( modrm >= 0xc0 )
416   {
417      if (m_ZF == 1)
418      {
419         src = LOAD_RM16(modrm);
420         STORE_REG16(modrm, src);
421      }
422      CYCLES(1); // TODO: correct cycle count
423   }
424   else
425   {
426      UINT32 ea = GetEA(modrm,0);
427      if (m_ZF == 1)
428      {
429         src = READ16(ea);
430         STORE_REG16(modrm, src);
431      }
432      CYCLES(1); // TODO: correct cycle count
433   }
434}
435
436void i386_device::pentium_cmove_r32_rm32()    // Opcode 0x0f 44
437{
438   UINT32 src;
439   UINT8 modrm = FETCH();
440
441   if( modrm >= 0xc0 )
442   {
443      if (m_ZF == 1)
444      {
445         src = LOAD_RM32(modrm);
446         STORE_REG32(modrm, src);
447      }
448      CYCLES(1); // TODO: correct cycle count
449   }
450   else
451   {
452      UINT32 ea = GetEA(modrm,0);
453      if (m_ZF == 1)
454      {
455         src = READ32(ea);
456         STORE_REG32(modrm, src);
457      }
458      CYCLES(1); // TODO: correct cycle count
459   }
460}
461
462void i386_device::pentium_cmovne_r16_rm16()    // Opcode 0x0f 45
463{
464   UINT16 src;
465   UINT8 modrm = FETCH();
466
467   if( modrm >= 0xc0 )
468   {
469      if (m_ZF == 0)
470      {
471         src = LOAD_RM16(modrm);
472         STORE_REG16(modrm, src);
473      }
474      CYCLES(1); // TODO: correct cycle count
475   }
476   else
477   {
478      UINT32 ea = GetEA(modrm,0);
479      if (m_ZF == 0)
480      {
481         src = READ16(ea);
482         STORE_REG16(modrm, src);
483      }
484      CYCLES(1); // TODO: correct cycle count
485   }
486}
487
488void i386_device::pentium_cmovne_r32_rm32()    // Opcode 0x0f 45
489{
490   UINT32 src;
491   UINT8 modrm = FETCH();
492
493   if( modrm >= 0xc0 )
494   {
495      if (m_ZF == 0)
496      {
497         src = LOAD_RM32(modrm);
498         STORE_REG32(modrm, src);
499      }
500      CYCLES(1); // TODO: correct cycle count
501   }
502   else
503   {
504      UINT32 ea = GetEA(modrm,0);
505      if (m_ZF == 0)
506      {
507         src = READ32(ea);
508         STORE_REG32(modrm, src);
509      }
510      CYCLES(1); // TODO: correct cycle count
511   }
512}
513
514void i386_device::pentium_cmovbe_r16_rm16()    // Opcode 0x0f 46
515{
516   UINT16 src;
517   UINT8 modrm = FETCH();
518
519   if( modrm >= 0xc0 )
520   {
521      if ((m_CF == 1) || (m_ZF == 1))
522      {
523         src = LOAD_RM16(modrm);
524         STORE_REG16(modrm, src);
525      }
526      CYCLES(1); // TODO: correct cycle count
527   }
528   else
529   {
530      UINT32 ea = GetEA(modrm,0);
531      if ((m_CF == 1) || (m_ZF == 1))
532      {
533         src = READ16(ea);
534         STORE_REG16(modrm, src);
535      }
536      CYCLES(1); // TODO: correct cycle count
537   }
538}
539
540void i386_device::pentium_cmovbe_r32_rm32()    // Opcode 0x0f 46
541{
542   UINT32 src;
543   UINT8 modrm = FETCH();
544
545   if( modrm >= 0xc0 )
546   {
547      if ((m_CF == 1) || (m_ZF == 1))
548      {
549         src = LOAD_RM32(modrm);
550         STORE_REG32(modrm, src);
551      }
552      CYCLES(1); // TODO: correct cycle count
553   }
554   else
555   {
556      UINT32 ea = GetEA(modrm,0);
557      if ((m_CF == 1) || (m_ZF == 1))
558      {
559         src = READ32(ea);
560         STORE_REG32(modrm, src);
561      }
562      CYCLES(1); // TODO: correct cycle count
563   }
564}
565
566void i386_device::pentium_cmova_r16_rm16()    // Opcode 0x0f 47
567{
568   UINT16 src;
569   UINT8 modrm = FETCH();
570
571   if( modrm >= 0xc0 )
572   {
573      if ((m_CF == 0) && (m_ZF == 0))
574      {
575         src = LOAD_RM16(modrm);
576         STORE_REG16(modrm, src);
577      }
578      CYCLES(1); // TODO: correct cycle count
579   }
580   else
581   {
582      UINT32 ea = GetEA(modrm,0);
583      if ((m_CF == 0) && (m_ZF == 0))
584      {
585         src = READ16(ea);
586         STORE_REG16(modrm, src);
587      }
588      CYCLES(1); // TODO: correct cycle count
589   }
590}
591
592void i386_device::pentium_cmova_r32_rm32()    // Opcode 0x0f 47
593{
594   UINT32 src;
595   UINT8 modrm = FETCH();
596
597   if( modrm >= 0xc0 )
598   {
599      if ((m_CF == 0) && (m_ZF == 0))
600      {
601         src = LOAD_RM32(modrm);
602         STORE_REG32(modrm, src);
603      }
604      CYCLES(1); // TODO: correct cycle count
605   }
606   else
607   {
608      UINT32 ea = GetEA(modrm,0);
609      if ((m_CF == 0) && (m_ZF == 0))
610      {
611         src = READ32(ea);
612         STORE_REG32(modrm, src);
613      }
614      CYCLES(1); // TODO: correct cycle count
615   }
616}
617
618void i386_device::pentium_cmovs_r16_rm16()    // Opcode 0x0f 48
619{
620   UINT16 src;
621   UINT8 modrm = FETCH();
622
623   if( modrm >= 0xc0 )
624   {
625      if (m_SF == 1)
626      {
627         src = LOAD_RM16(modrm);
628         STORE_REG16(modrm, src);
629      }
630      CYCLES(1); // TODO: correct cycle count
631   }
632   else
633   {
634      UINT32 ea = GetEA(modrm,0);
635      if (m_SF == 1)
636      {
637         src = READ16(ea);
638         STORE_REG16(modrm, src);
639      }
640      CYCLES(1); // TODO: correct cycle count
641   }
642}
643
644void i386_device::pentium_cmovs_r32_rm32()    // Opcode 0x0f 48
645{
646   UINT32 src;
647   UINT8 modrm = FETCH();
648
649   if( modrm >= 0xc0 )
650   {
651      if (m_SF == 1)
652      {
653         src = LOAD_RM32(modrm);
654         STORE_REG32(modrm, src);
655      }
656      CYCLES(1); // TODO: correct cycle count
657   }
658   else
659   {
660      UINT32 ea = GetEA(modrm,0);
661      if (m_SF == 1)
662      {
663         src = READ32(ea);
664         STORE_REG32(modrm, src);
665      }
666      CYCLES(1); // TODO: correct cycle count
667   }
668}
669
670void i386_device::pentium_cmovns_r16_rm16()    // Opcode 0x0f 49
671{
672   UINT16 src;
673   UINT8 modrm = FETCH();
674
675   if( modrm >= 0xc0 )
676   {
677      if (m_SF == 0)
678      {
679         src = LOAD_RM16(modrm);
680         STORE_REG16(modrm, src);
681      }
682      CYCLES(1); // TODO: correct cycle count
683   }
684   else
685   {
686      UINT32 ea = GetEA(modrm,0);
687      if (m_SF == 0)
688      {
689         src = READ16(ea);
690         STORE_REG16(modrm, src);
691      }
692      CYCLES(1); // TODO: correct cycle count
693   }
694}
695
696void i386_device::pentium_cmovns_r32_rm32()    // Opcode 0x0f 49
697{
698   UINT32 src;
699   UINT8 modrm = FETCH();
700
701   if( modrm >= 0xc0 )
702   {
703      if (m_SF == 0)
704      {
705         src = LOAD_RM32(modrm);
706         STORE_REG32(modrm, src);
707      }
708      CYCLES(1); // TODO: correct cycle count
709   }
710   else
711   {
712      UINT32 ea = GetEA(modrm,0);
713      if (m_SF == 0)
714      {
715         src = READ32(ea);
716         STORE_REG32(modrm, src);
717      }
718      CYCLES(1); // TODO: correct cycle count
719   }
720}
721
722void i386_device::pentium_cmovp_r16_rm16()    // Opcode 0x0f 4a
723{
724   UINT16 src;
725   UINT8 modrm = FETCH();
726
727   if( modrm >= 0xc0 )
728   {
729      if (m_PF == 1)
730      {
731         src = LOAD_RM16(modrm);
732         STORE_REG16(modrm, src);
733      }
734      CYCLES(1); // TODO: correct cycle count
735   }
736   else
737   {
738      UINT32 ea = GetEA(modrm,0);
739      if (m_PF == 1)
740      {
741         src = READ16(ea);
742         STORE_REG16(modrm, src);
743      }
744      CYCLES(1); // TODO: correct cycle count
745   }
746}
747
748void i386_device::pentium_cmovp_r32_rm32()    // Opcode 0x0f 4a
749{
750   UINT32 src;
751   UINT8 modrm = FETCH();
752
753   if( modrm >= 0xc0 )
754   {
755      if (m_PF == 1)
756      {
757         src = LOAD_RM32(modrm);
758         STORE_REG32(modrm, src);
759      }
760      CYCLES(1); // TODO: correct cycle count
761   }
762   else
763   {
764      UINT32 ea = GetEA(modrm,0);
765      if (m_PF == 1)
766      {
767         src = READ32(ea);
768         STORE_REG32(modrm, src);
769      }
770      CYCLES(1); // TODO: correct cycle count
771   }
772}
773
774void i386_device::pentium_cmovnp_r16_rm16()    // Opcode 0x0f 4b
775{
776   UINT16 src;
777   UINT8 modrm = FETCH();
778
779   if( modrm >= 0xc0 )
780   {
781      if (m_PF == 0)
782      {
783         src = LOAD_RM16(modrm);
784         STORE_REG16(modrm, src);
785      }
786      CYCLES(1); // TODO: correct cycle count
787   }
788   else
789   {
790      UINT32 ea = GetEA(modrm,0);
791      if (m_PF == 0)
792      {
793         src = READ16(ea);
794         STORE_REG16(modrm, src);
795      }
796      CYCLES(1); // TODO: correct cycle count
797   }
798}
799
800void i386_device::pentium_cmovnp_r32_rm32()    // Opcode 0x0f 4b
801{
802   UINT32 src;
803   UINT8 modrm = FETCH();
804
805   if( modrm >= 0xc0 )
806   {
807      if (m_PF == 0)
808      {
809         src = LOAD_RM32(modrm);
810         STORE_REG32(modrm, src);
811      }
812      CYCLES(1); // TODO: correct cycle count
813   }
814   else
815   {
816      UINT32 ea = GetEA(modrm,0);
817      if (m_PF == 0)
818      {
819         src = READ32(ea);
820         STORE_REG32(modrm, src);
821      }
822      CYCLES(1); // TODO: correct cycle count
823   }
824}
825
826void i386_device::pentium_cmovl_r16_rm16()    // Opcode 0x0f 4c
827{
828   UINT16 src;
829   UINT8 modrm = FETCH();
830
831   if( modrm >= 0xc0 )
832   {
833      if (m_SF != m_OF)
834      {
835         src = LOAD_RM16(modrm);
836         STORE_REG16(modrm, src);
837      }
838      CYCLES(1); // TODO: correct cycle count
839   }
840   else
841   {
842      UINT32 ea = GetEA(modrm,0);
843      if (m_SF != m_OF)
844      {
845         src = READ16(ea);
846         STORE_REG16(modrm, src);
847      }
848      CYCLES(1); // TODO: correct cycle count
849   }
850}
851
852void i386_device::pentium_cmovl_r32_rm32()    // Opcode 0x0f 4c
853{
854   UINT32 src;
855   UINT8 modrm = FETCH();
856
857   if( modrm >= 0xc0 )
858   {
859      if (m_SF != m_OF)
860      {
861         src = LOAD_RM32(modrm);
862         STORE_REG32(modrm, src);
863      }
864      CYCLES(1); // TODO: correct cycle count
865   }
866   else
867   {
868      UINT32 ea = GetEA(modrm,0);
869      if (m_SF != m_OF)
870      {
871         src = READ32(ea);
872         STORE_REG32(modrm, src);
873      }
874      CYCLES(1); // TODO: correct cycle count
875   }
876}
877
878void i386_device::pentium_cmovge_r16_rm16()    // Opcode 0x0f 4d
879{
880   UINT16 src;
881   UINT8 modrm = FETCH();
882
883   if( modrm >= 0xc0 )
884   {
885      if (m_SF == m_OF)
886      {
887         src = LOAD_RM16(modrm);
888         STORE_REG16(modrm, src);
889      }
890      CYCLES(1); // TODO: correct cycle count
891   }
892   else
893   {
894      UINT32 ea = GetEA(modrm,0);
895      if (m_SF == m_OF)
896      {
897         src = READ16(ea);
898         STORE_REG16(modrm, src);
899      }
900      CYCLES(1); // TODO: correct cycle count
901   }
902}
903
904void i386_device::pentium_cmovge_r32_rm32()    // Opcode 0x0f 4d
905{
906   UINT32 src;
907   UINT8 modrm = FETCH();
908
909   if( modrm >= 0xc0 )
910   {
911      if (m_SF == m_OF)
912      {
913         src = LOAD_RM32(modrm);
914         STORE_REG32(modrm, src);
915      }
916      CYCLES(1); // TODO: correct cycle count
917   }
918   else
919   {
920      UINT32 ea = GetEA(modrm,0);
921      if (m_SF == m_OF)
922      {
923         src = READ32(ea);
924         STORE_REG32(modrm, src);
925      }
926      CYCLES(1); // TODO: correct cycle count
927   }
928}
929
930void i386_device::pentium_cmovle_r16_rm16()    // Opcode 0x0f 4e
931{
932   UINT16 src;
933   UINT8 modrm = FETCH();
934
935   if( modrm >= 0xc0 )
936   {
937      if ((m_ZF == 1) || (m_SF != m_OF))
938      {
939         src = LOAD_RM16(modrm);
940         STORE_REG16(modrm, src);
941      }
942      CYCLES(1); // TODO: correct cycle count
943   }
944   else
945   {
946      UINT32 ea = GetEA(modrm,0);
947      if ((m_ZF == 1) || (m_SF != m_OF))
948      {
949         src = READ16(ea);
950         STORE_REG16(modrm, src);
951      }
952      CYCLES(1); // TODO: correct cycle count
953   }
954}
955
956void i386_device::pentium_cmovle_r32_rm32()    // Opcode 0x0f 4e
957{
958   UINT32 src;
959   UINT8 modrm = FETCH();
960
961   if( modrm >= 0xc0 )
962   {
963      if ((m_ZF == 1) || (m_SF != m_OF))
964      {
965         src = LOAD_RM32(modrm);
966         STORE_REG32(modrm, src);
967      }
968      CYCLES(1); // TODO: correct cycle count
969   }
970   else
971   {
972      UINT32 ea = GetEA(modrm,0);
973      if ((m_ZF == 1) || (m_SF != m_OF))
974      {
975         src = READ32(ea);
976         STORE_REG32(modrm, src);
977      }
978      CYCLES(1); // TODO: correct cycle count
979   }
980}
981
982void i386_device::pentium_cmovg_r16_rm16()    // Opcode 0x0f 4f
983{
984   UINT16 src;
985   UINT8 modrm = FETCH();
986
987   if( modrm >= 0xc0 )
988   {
989      if ((m_ZF == 0) && (m_SF == m_OF))
990      {
991         src = LOAD_RM16(modrm);
992         STORE_REG16(modrm, src);
993      }
994      CYCLES(1); // TODO: correct cycle count
995   }
996   else
997   {
998      UINT32 ea = GetEA(modrm,0);
999      if ((m_ZF == 0) && (m_SF == m_OF))
1000      {
1001         src = READ16(ea);
1002         STORE_REG16(modrm, src);
1003      }
1004      CYCLES(1); // TODO: correct cycle count
1005   }
1006}
1007
1008void i386_device::pentium_cmovg_r32_rm32()    // Opcode 0x0f 4f
1009{
1010   UINT32 src;
1011   UINT8 modrm = FETCH();
1012
1013   if( modrm >= 0xc0 )
1014   {
1015      if ((m_ZF == 0) && (m_SF == m_OF))
1016      {
1017         src = LOAD_RM32(modrm);
1018         STORE_REG32(modrm, src);
1019      }
1020      CYCLES(1); // TODO: correct cycle count
1021   }
1022   else
1023   {
1024      UINT32 ea = GetEA(modrm,0);
1025      if ((m_ZF == 0) && (m_SF == m_OF))
1026      {
1027         src = READ32(ea);
1028         STORE_REG32(modrm, src);
1029      }
1030      CYCLES(1); // TODO: correct cycle count
1031   }
1032}
1033
1034void i386_device::pentium_movnti_m16_r16() // Opcode 0f c3
1035{
1036   UINT8 modrm = FETCH();
1037   if( modrm >= 0xc0 ) {
1038      // unsupported by cpu
1039      CYCLES(1);     // TODO: correct cycle count
1040   } else {
1041      // since cache is not implemented
1042      UINT32 ea = GetEA(modrm, 0);
1043      WRITE16(ea,LOAD_RM16(modrm));
1044      CYCLES(1);     // TODO: correct cycle count
1045   }
1046}
1047
1048void i386_device::pentium_movnti_m32_r32() // Opcode 0f c3
1049{
1050   UINT8 modrm = FETCH();
1051   if( modrm >= 0xc0 ) {
1052      // unsupported by cpu
1053      CYCLES(1);     // TODO: correct cycle count
1054   } else {
1055      // since cache is not implemented
1056      UINT32 ea = GetEA(modrm, 0);
1057      WRITE32(ea,LOAD_RM32(modrm));
1058      CYCLES(1);     // TODO: correct cycle count
1059   }
1060}
1061
1062void i386_device::i386_cyrix_unknown()     // Opcode 0x0f 74
1063{
1064   logerror("Unemulated 0x0f 0x74 opcode called\n");
1065
1066   CYCLES(1);
1067}
1068
1069void i386_device::pentium_cmpxchg8b_m64()  // Opcode 0x0f c7
1070{
1071   UINT8 modm = FETCH();
1072   if( modm >= 0xc0 ) {
1073      report_invalid_modrm("cmpxchg8b_m64", modm);
1074   } else {
1075      UINT32 ea = GetEA(modm, 0);
1076      UINT64 value = READ64(ea);
1077      UINT64 edx_eax = (((UINT64) REG32(EDX)) << 32) | REG32(EAX);
1078      UINT64 ecx_ebx = (((UINT64) REG32(ECX)) << 32) | REG32(EBX);
1079
1080      if( value == edx_eax ) {
1081         WRITE64(ea, ecx_ebx);
1082         m_ZF = 1;
1083         CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
1084      } else {
1085         REG32(EDX) = (UINT32) (value >> 32);
1086         REG32(EAX) = (UINT32) (value >>  0);
1087         m_ZF = 0;
1088         CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
1089      }
1090   }
1091}
1092
1093void i386_device::pentium_movntq_m64_r64() // Opcode 0f e7
1094{
1095   //MMXPROLOG(); // TODO: check if needed
1096   UINT8 modrm = FETCH();
1097   if( modrm >= 0xc0 ) {
1098      CYCLES(1);     // unsupported
1099   } else {
1100      // since cache is not implemented
1101      UINT32 ea = GetEA(modrm, 0);
1102      WRITEMMX(ea, MMX((modrm >> 3) & 0x7));
1103      CYCLES(1);     // TODO: correct cycle count
1104   }
1105}
1106
1107void i386_device::pentium_maskmovq_r64_r64()  // Opcode 0f f7
1108{
1109   int s,m,n;
1110   UINT8 modm = FETCH();
1111   UINT32 ea = GetEA(7, 0); // ds:di/edi/rdi register
1112   MMXPROLOG();
1113   s=(modm >> 3) & 7;
1114   m=modm & 7;
1115   for (n=0;n <= 7;n++)
1116      if (MMX(m).b[n] & 127)
1117         WRITE8(ea+n, MMX(s).b[n]);
1118}
1119
1120void i386_device::pentium_popcnt_r16_rm16()    // Opcode f3 0f b8
1121{
1122   UINT16 src;
1123   UINT8 modrm = FETCH();
1124   int n,count;
1125
1126   if( modrm >= 0xc0 ) {
1127      src = LOAD_RM16(modrm);
1128   } else {
1129      UINT32 ea = GetEA(modrm,0);
1130      src = READ16(ea);
1131   }
1132   count=0;
1133   for (n=0;n < 16;n++) {
1134      count=count+(src & 1);
1135      src=src >> 1;
1136   }
1137   STORE_REG16(modrm, count);
1138   CYCLES(1); // TODO: correct cycle count
1139}
1140
1141void i386_device::pentium_popcnt_r32_rm32()    // Opcode f3 0f b8
1142{
1143   UINT32 src;
1144   UINT8 modrm = FETCH();
1145   int n,count;
1146
1147   if( modrm >= 0xc0 ) {
1148      src = LOAD_RM32(modrm);
1149   } else {
1150      UINT32 ea = GetEA(modrm,0);
1151      src = READ32(ea);
1152   }
1153   count=0;
1154   for (n=0;n < 32;n++) {
1155      count=count+(src & 1);
1156      src=src >> 1;
1157   }
1158   STORE_REG32(modrm, count);
1159   CYCLES(1); // TODO: correct cycle count
1160}
1161
1162void i386_device::pentium_tzcnt_r16_rm16()
1163{
1164   // for CPUs that don't support TZCNT, fall back to BSF
1165   i386_bsf_r16_rm16();
1166   // TODO: actually implement TZCNT
1167}
1168
1169void i386_device::pentium_tzcnt_r32_rm32()
1170{
1171   // for CPUs that don't support TZCNT, fall back to BSF
1172   i386_bsf_r32_rm32();
1173   // TODO: actually implement TZCNT
1174}
1175
1176INLINE INT8 SaturatedSignedWordToSignedByte(INT16 word)
1177{
1178   if (word > 127)
1179      return 127;
1180   if (word < -128)
1181      return -128;
1182   return (INT8)word;
1183}
1184
1185INLINE UINT8 SaturatedSignedWordToUnsignedByte(INT16 word)
1186{
1187   if (word > 255)
1188      return 255;
1189   if (word < 0)
1190      return 0;
1191   return (UINT8)word;
1192}
1193
1194INLINE INT16 SaturatedSignedDwordToSignedWord(INT32 dword)
1195{
1196   if (dword > 32767)
1197      return 32767;
1198   if (dword < -32768)
1199      return -32768;
1200   return (INT16)dword;
1201}
1202
1203void i386_device::mmx_group_0f71()  // Opcode 0f 71
1204{
1205   UINT8 modm = FETCH();
1206   UINT8 imm8 = FETCH();
1207   MMXPROLOG();
1208   if( modm >= 0xc0 ) {
1209      switch ( (modm & 0x38) >> 3 )
1210      {
1211         case 2: // psrlw
1212            MMX(modm & 7).w[0]=MMX(modm & 7).w[0] >> imm8;
1213            MMX(modm & 7).w[1]=MMX(modm & 7).w[1] >> imm8;
1214            MMX(modm & 7).w[2]=MMX(modm & 7).w[2] >> imm8;
1215            MMX(modm & 7).w[3]=MMX(modm & 7).w[3] >> imm8;
1216            break;
1217         case 4: // psraw
1218            MMX(modm & 7).s[0]=MMX(modm & 7).s[0] >> imm8;
1219            MMX(modm & 7).s[1]=MMX(modm & 7).s[1] >> imm8;
1220            MMX(modm & 7).s[2]=MMX(modm & 7).s[2] >> imm8;
1221            MMX(modm & 7).s[3]=MMX(modm & 7).s[3] >> imm8;
1222            break;
1223         case 6: // psllw
1224            MMX(modm & 7).w[0]=MMX(modm & 7).w[0] << imm8;
1225            MMX(modm & 7).w[1]=MMX(modm & 7).w[1] << imm8;
1226            MMX(modm & 7).w[2]=MMX(modm & 7).w[2] << imm8;
1227            MMX(modm & 7).w[3]=MMX(modm & 7).w[3] << imm8;
1228            break;
1229         default:
1230            report_invalid_modrm("mmx_group0f71", modm);
1231      }
1232   }
1233}
1234
1235void i386_device::mmx_group_0f72()  // Opcode 0f 72
1236{
1237   UINT8 modm = FETCH();
1238   UINT8 imm8 = FETCH();
1239   MMXPROLOG();
1240   if( modm >= 0xc0 ) {
1241      switch ( (modm & 0x38) >> 3 )
1242      {
1243         case 2: // psrld
1244            MMX(modm & 7).d[0]=MMX(modm & 7).d[0] >> imm8;
1245            MMX(modm & 7).d[1]=MMX(modm & 7).d[1] >> imm8;
1246            break;
1247         case 4: // psrad
1248            MMX(modm & 7).i[0]=MMX(modm & 7).i[0] >> imm8;
1249            MMX(modm & 7).i[1]=MMX(modm & 7).i[1] >> imm8;
1250            break;
1251         case 6: // pslld
1252            MMX(modm & 7).d[0]=MMX(modm & 7).d[0] << imm8;
1253            MMX(modm & 7).d[1]=MMX(modm & 7).d[1] << imm8;
1254            break;
1255         default:
1256            report_invalid_modrm("mmx_group0f72", modm);
1257      }
1258   }
1259}
1260
1261void i386_device::mmx_group_0f73()  // Opcode 0f 73
1262{
1263   UINT8 modm = FETCH();
1264   UINT8 imm8 = FETCH();
1265   MMXPROLOG();
1266   if( modm >= 0xc0 ) {
1267      switch ( (modm & 0x38) >> 3 )
1268      {
1269         case 2: // psrlq
1270            MMX(modm & 7).q=MMX(modm & 7).q >> imm8;
1271            break;
1272         case 6: // psllq
1273            MMX(modm & 7).q=MMX(modm & 7).q << imm8;
1274            break;
1275         default:
1276            report_invalid_modrm("mmx_group0f73", modm);
1277      }
1278   }
1279}
1280
1281void i386_device::mmx_psrlw_r64_rm64()  // Opcode 0f d1
1282{
1283   MMXPROLOG();
1284   UINT8 modrm = FETCH();
1285   if( modrm >= 0xc0 ) {
1286      int count=(int)MMX(modrm & 7).q;
1287      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count;
1288      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count;
1289      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count;
1290      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count;
1291   } else {
1292      MMX_REG src;
1293      UINT32 ea = GetEA(modrm, 0);
1294      READMMX(ea, src);
1295      int count=(int)src.q;
1296      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count;
1297      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count;
1298      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count;
1299      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count;
1300   }
1301   CYCLES(1);     // TODO: correct cycle count
1302}
1303
1304void i386_device::mmx_psrld_r64_rm64()  // Opcode 0f d2
1305{
1306   MMXPROLOG();
1307   UINT8 modrm = FETCH();
1308   if( modrm >= 0xc0 ) {
1309      int count=(int)MMX(modrm & 7).q;
1310      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count;
1311      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count;
1312   } else {
1313      MMX_REG src;
1314      UINT32 ea = GetEA(modrm, 0);
1315      READMMX(ea, src);
1316      int count=(int)src.q;
1317      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count;
1318      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count;
1319   }
1320   CYCLES(1);     // TODO: correct cycle count
1321}
1322
1323void i386_device::mmx_psrlq_r64_rm64()  // Opcode 0f d3
1324{
1325   MMXPROLOG();
1326   UINT8 modrm = FETCH();
1327   if( modrm >= 0xc0 ) {
1328      int count=(int)MMX(modrm & 7).q;
1329      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count;
1330   } else {
1331      MMX_REG src;
1332      UINT32 ea = GetEA(modrm, 0);
1333      READMMX(ea, src);
1334      int count=(int)src.q;
1335      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count;
1336   }
1337   CYCLES(1);     // TODO: correct cycle count
1338}
1339
1340void i386_device::mmx_paddq_r64_rm64()  // Opcode 0f d4
1341{
1342   MMXPROLOG();
1343   UINT8 modrm = FETCH();
1344   if( modrm >= 0xc0 ) {
1345      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+MMX(modrm & 7).q;
1346   } else {
1347      MMX_REG src;
1348      UINT32 ea = GetEA(modrm, 0);
1349      READMMX(ea, src);
1350      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+src.q;
1351   }
1352   CYCLES(1);     // TODO: correct cycle count
1353}
1354
1355void i386_device::mmx_pmullw_r64_rm64()  // Opcode 0f d5
1356{
1357   MMXPROLOG();
1358   UINT8 modrm = FETCH();
1359   if( modrm >= 0xc0 ) {
1360      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]) & 0xffff;
1361      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1]) & 0xffff;
1362      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]) & 0xffff;
1363      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3]) & 0xffff;
1364   } else {
1365      MMX_REG src;
1366      UINT32 ea = GetEA(modrm, 0);
1367      READMMX(ea, src);
1368      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)src.s[0]) & 0xffff;
1369      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)src.s[1]) & 0xffff;
1370      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)src.s[2]) & 0xffff;
1371      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)src.s[3]) & 0xffff;
1372   }
1373   CYCLES(1);     // TODO: correct cycle count
1374}
1375
1376void i386_device::mmx_psubusb_r64_rm64()  // Opcode 0f d8
1377{
1378   int n;
1379   MMXPROLOG();
1380   UINT8 modrm = FETCH();
1381   if( modrm >= 0xc0 ) {
1382      for (n=0;n < 8;n++)
1383         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 7).b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-MMX(modrm & 7).b[n];
1384   } else {
1385      MMX_REG src;
1386      UINT32 ea = GetEA(modrm, 0);
1387      READMMX(ea, src);
1388      for (n=0;n < 8;n++)
1389         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < src.b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-src.b[n];
1390   }
1391   CYCLES(1);     // TODO: correct cycle count
1392}
1393
1394void i386_device::mmx_psubusw_r64_rm64()  // Opcode 0f d9
1395{
1396   int n;
1397   MMXPROLOG();
1398   UINT8 modrm = FETCH();
1399   if( modrm >= 0xc0 ) {
1400      for (n=0;n < 4;n++)
1401         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < MMX(modrm & 7).w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-MMX(modrm & 7).w[n];
1402   } else {
1403      MMX_REG src;
1404      UINT32 ea = GetEA(modrm, 0);
1405      READMMX(ea, src);
1406      for (n=0;n < 4;n++)
1407         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < src.w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-src.w[n];
1408   }
1409   CYCLES(1);     // TODO: correct cycle count
1410}
1411
1412void i386_device::mmx_pand_r64_rm64()  // Opcode 0f db
1413{
1414   MMXPROLOG();
1415   UINT8 modrm = FETCH();
1416   if( modrm >= 0xc0 ) {
1417      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & MMX(modrm & 7).q;
1418   } else {
1419      MMX_REG src;
1420      UINT32 ea = GetEA(modrm, 0);
1421      READMMX(ea, src);
1422      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & src.q;
1423   }
1424   CYCLES(1);     // TODO: correct cycle count
1425}
1426
1427void i386_device::mmx_paddusb_r64_rm64()  // Opcode 0f dc
1428{
1429   int n;
1430   MMXPROLOG();
1431   UINT8 modrm = FETCH();
1432   if( modrm >= 0xc0 ) {
1433      for (n=0;n < 8;n++)
1434         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-MMX(modrm & 7).b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+MMX(modrm & 7).b[n];
1435   } else {
1436      MMX_REG src;
1437      UINT32 ea = GetEA(modrm, 0);
1438      READMMX(ea, src);
1439      for (n=0;n < 8;n++)
1440         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-src.b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+src.b[n];
1441   }
1442   CYCLES(1);     // TODO: correct cycle count
1443}
1444
1445void i386_device::mmx_paddusw_r64_rm64()  // Opcode 0f dd
1446{
1447   int n;
1448   MMXPROLOG();
1449   UINT8 modrm = FETCH();
1450   if( modrm >= 0xc0 ) {
1451      for (n=0;n < 4;n++)
1452         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-MMX(modrm & 7).w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+MMX(modrm & 7).w[n];
1453   } else {
1454      MMX_REG src;
1455      UINT32 ea = GetEA(modrm, 0);
1456      READMMX(ea, src);
1457      for (n=0;n < 4;n++)
1458         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-src.w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+src.w[n];
1459   }
1460   CYCLES(1);     // TODO: correct cycle count
1461}
1462
1463void i386_device::mmx_pandn_r64_rm64()  // Opcode 0f df
1464{
1465   MMXPROLOG();
1466   UINT8 modrm = FETCH();
1467   if( modrm >= 0xc0 ) {
1468      MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & MMX(modrm & 7).q;
1469   } else {
1470      MMX_REG src;
1471      UINT32 ea = GetEA(modrm, 0);
1472      READMMX(ea, src);
1473      MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & src.q;
1474   }
1475   CYCLES(1);     // TODO: correct cycle count
1476}
1477
1478void i386_device::mmx_psraw_r64_rm64()  // Opcode 0f e1
1479{
1480   MMXPROLOG();
1481   UINT8 modrm = FETCH();
1482   if( modrm >= 0xc0 ) {
1483      int count=(int)MMX(modrm & 7).q;
1484      MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count;
1485      MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count;
1486      MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count;
1487      MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count;
1488   } else {
1489      MMX_REG src;
1490      UINT32 ea = GetEA(modrm, 0);
1491      READMMX(ea, src);
1492      int count=(int)src.q;
1493      MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count;
1494      MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count;
1495      MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count;
1496      MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count;
1497   }
1498   CYCLES(1);     // TODO: correct cycle count
1499}
1500
1501void i386_device::mmx_psrad_r64_rm64()  // Opcode 0f e2
1502{
1503   MMXPROLOG();
1504   UINT8 modrm = FETCH();
1505   if( modrm >= 0xc0 ) {
1506      int count=(int)MMX(modrm & 7).q;
1507      MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count;
1508      MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count;
1509   } else {
1510      MMX_REG src;
1511      UINT32 ea = GetEA(modrm, 0);
1512      READMMX(ea, src);
1513      int count=(int)src.q;
1514      MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count;
1515      MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count;
1516   }
1517   CYCLES(1);     // TODO: correct cycle count
1518}
1519
1520void i386_device::mmx_pmulhw_r64_rm64()  // Opcode 0f e5
1521{
1522   MMXPROLOG();
1523   UINT8 modrm = FETCH();
1524   if( modrm >= 0xc0 ) {
1525      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]) >> 16;
1526      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1]) >> 16;
1527      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]) >> 16;
1528      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3]) >> 16;
1529   } else {
1530      MMX_REG src;
1531      UINT32 ea = GetEA(modrm, 0);
1532      READMMX(ea, src);
1533      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)src.s[0]) >> 16;
1534      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)src.s[1]) >> 16;
1535      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)src.s[2]) >> 16;
1536      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)src.s[3]) >> 16;
1537   }
1538   CYCLES(1);     // TODO: correct cycle count
1539}
1540
1541void i386_device::mmx_psubsb_r64_rm64()  // Opcode 0f e8
1542{
1543   int n;
1544   MMXPROLOG();
1545   UINT8 modrm = FETCH();
1546   if( modrm >= 0xc0 ) {
1547      for (n=0;n < 8;n++)
1548         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] - (INT16)MMX(modrm & 7).c[n]);
1549   } else {
1550      MMX_REG s;
1551      UINT32 ea = GetEA(modrm, 0);
1552      READMMX(ea, s);
1553      for (n=0;n < 8;n++)
1554         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] - (INT16)s.c[n]);
1555   }
1556   CYCLES(1);     // TODO: correct cycle count
1557}
1558
1559void i386_device::mmx_psubsw_r64_rm64()  // Opcode 0f e9
1560{
1561   int n;
1562   MMXPROLOG();
1563   UINT8 modrm = FETCH();
1564   if( modrm >= 0xc0 ) {
1565      for (n=0;n < 4;n++)
1566         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] - (INT32)MMX(modrm & 7).s[n]);
1567   } else {
1568      MMX_REG s;
1569      UINT32 ea = GetEA(modrm, 0);
1570      READMMX(ea, s);
1571      for (n=0;n < 4;n++)
1572         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] - (INT32)s.s[n]);
1573   }
1574   CYCLES(1);     // TODO: correct cycle count
1575}
1576
1577void i386_device::mmx_por_r64_rm64()  // Opcode 0f eb
1578{
1579   MMXPROLOG();
1580   UINT8 modrm = FETCH();
1581   if( modrm >= 0xc0 ) {
1582      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | MMX(modrm & 7).q;
1583   } else {
1584      MMX_REG s;
1585      UINT32 ea = GetEA(modrm, 0);
1586      READMMX(ea, s);
1587      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | s.q;
1588   }
1589   CYCLES(1);     // TODO: correct cycle count
1590}
1591
1592void i386_device::mmx_paddsb_r64_rm64()  // Opcode 0f ec
1593{
1594   int n;
1595   MMXPROLOG();
1596   UINT8 modrm = FETCH();
1597   if( modrm >= 0xc0 ) {
1598      for (n=0;n < 8;n++)
1599         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] + (INT16)MMX(modrm & 7).c[n]);
1600   } else {
1601      MMX_REG s;
1602      UINT32 ea = GetEA(modrm, 0);
1603      READMMX(ea, s);
1604      for (n=0;n < 8;n++)
1605         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] + (INT16)s.c[n]);
1606   }
1607   CYCLES(1);     // TODO: correct cycle count
1608}
1609
1610void i386_device::mmx_paddsw_r64_rm64()  // Opcode 0f ed
1611{
1612   int n;
1613   MMXPROLOG();
1614   UINT8 modrm = FETCH();
1615   if( modrm >= 0xc0 ) {
1616      for (n=0;n < 4;n++)
1617         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] + (INT32)MMX(modrm & 7).s[n]);
1618   } else {
1619      MMX_REG s;
1620      UINT32 ea = GetEA(modrm, 0);
1621      READMMX(ea, s);
1622      for (n=0;n < 4;n++)
1623         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] + (INT32)s.s[n]);
1624   }
1625   CYCLES(1);     // TODO: correct cycle count
1626}
1627
1628void i386_device::mmx_pxor_r64_rm64()  // Opcode 0f ef
1629{
1630   MMXPROLOG();
1631   UINT8 modrm = FETCH();
1632   if( modrm >= 0xc0 ) {
1633      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ MMX(modrm & 7).q;
1634   } else {
1635      MMX_REG s;
1636      UINT32 ea = GetEA(modrm, 0);
1637      READMMX(ea, s);
1638      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ s.q;
1639   }
1640   CYCLES(1);     // TODO: correct cycle count
1641}
1642
1643void i386_device::mmx_psllw_r64_rm64()  // Opcode 0f f1
1644{
1645   MMXPROLOG();
1646   UINT8 modrm = FETCH();
1647   if( modrm >= 0xc0 ) {
1648      int count=(int)MMX(modrm & 7).q;
1649      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count;
1650      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count;
1651      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count;
1652      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count;
1653   } else {
1654      MMX_REG s;
1655      UINT32 ea = GetEA(modrm, 0);
1656      READMMX(ea, s);
1657      int count=(int)s.q;
1658      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count;
1659      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count;
1660      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count;
1661      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count;
1662   }
1663   CYCLES(1);     // TODO: correct cycle count
1664}
1665
1666void i386_device::mmx_pslld_r64_rm64()  // Opcode 0f f2
1667{
1668   MMXPROLOG();
1669   UINT8 modrm = FETCH();
1670   if( modrm >= 0xc0 ) {
1671      int count=(int)MMX(modrm & 7).q;
1672      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count;
1673      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count;
1674   } else {
1675      MMX_REG s;
1676      UINT32 ea = GetEA(modrm, 0);
1677      READMMX(ea, s);
1678      int count=(int)s.q;
1679      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count;
1680      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count;
1681   }
1682   CYCLES(1);     // TODO: correct cycle count
1683}
1684
1685void i386_device::mmx_psllq_r64_rm64()  // Opcode 0f f3
1686{
1687   MMXPROLOG();
1688   UINT8 modrm = FETCH();
1689   if( modrm >= 0xc0 ) {
1690      int count=(int)MMX(modrm & 7).q;
1691      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count;
1692   } else {
1693      MMX_REG s;
1694      UINT32 ea = GetEA(modrm, 0);
1695      READMMX(ea, s);
1696      int count=(int)s.q;
1697      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count;
1698   }
1699   CYCLES(1);     // TODO: correct cycle count
1700}
1701
1702void i386_device::mmx_pmaddwd_r64_rm64()  // Opcode 0f f5
1703{
1704   MMXPROLOG();
1705   UINT8 modrm = FETCH();
1706   if( modrm >= 0xc0 ) {
1707      MMX((modrm >> 3) & 0x7).i[0]=(INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]+
1708                              (INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1];
1709      MMX((modrm >> 3) & 0x7).i[1]=(INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]+
1710                              (INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3];
1711   } else {
1712      MMX_REG s;
1713      UINT32 ea = GetEA(modrm, 0);
1714      READMMX(ea, s);
1715      MMX((modrm >> 3) & 0x7).i[0]=(INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)s.s[0]+
1716                              (INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)s.s[1];
1717      MMX((modrm >> 3) & 0x7).i[1]=(INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)s.s[2]+
1718                              (INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)s.s[3];
1719   }
1720   CYCLES(1);     // TODO: correct cycle count
1721}
1722
1723void i386_device::mmx_psubb_r64_rm64()  // Opcode 0f f8
1724{
1725   int n;
1726   MMXPROLOG();
1727   UINT8 modrm = FETCH();
1728   if( modrm >= 0xc0 ) {
1729      for (n=0;n < 8;n++)
1730         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - MMX(modrm & 7).b[n];
1731   } else {
1732      MMX_REG s;
1733      UINT32 ea = GetEA(modrm, 0);
1734      READMMX(ea, s);
1735      for (n=0;n < 8;n++)
1736         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - s.b[n];
1737   }
1738   CYCLES(1);     // TODO: correct cycle count
1739}
1740
1741void i386_device::mmx_psubw_r64_rm64()  // Opcode 0f f9
1742{
1743   int n;
1744   MMXPROLOG();
1745   UINT8 modrm = FETCH();
1746   if( modrm >= 0xc0 ) {
1747      for (n=0;n < 4;n++)
1748         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - MMX(modrm & 7).w[n];
1749   } else {
1750      MMX_REG s;
1751      UINT32 ea = GetEA(modrm, 0);
1752      READMMX(ea, s);
1753      for (n=0;n < 4;n++)
1754         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - s.w[n];
1755   }
1756   CYCLES(1);     // TODO: correct cycle count
1757}
1758
1759void i386_device::mmx_psubd_r64_rm64()  // Opcode 0f fa
1760{
1761   int n;
1762   MMXPROLOG();
1763   UINT8 modrm = FETCH();
1764   if( modrm >= 0xc0 ) {
1765      for (n=0;n < 2;n++)
1766         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - MMX(modrm & 7).d[n];
1767   } else {
1768      MMX_REG s;
1769      UINT32 ea = GetEA(modrm, 0);
1770      READMMX(ea, s);
1771      for (n=0;n < 2;n++)
1772         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - s.d[n];
1773   }
1774   CYCLES(1);     // TODO: correct cycle count
1775}
1776
1777void i386_device::mmx_paddb_r64_rm64()  // Opcode 0f fc
1778{
1779   int n;
1780   MMXPROLOG();
1781   UINT8 modrm = FETCH();
1782   if( modrm >= 0xc0 ) {
1783      for (n=0;n < 8;n++)
1784         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + MMX(modrm & 7).b[n];
1785   } else {
1786      MMX_REG s;
1787      UINT32 ea = GetEA(modrm, 0);
1788      READMMX(ea, s);
1789      for (n=0;n < 8;n++)
1790         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + s.b[n];
1791   }
1792   CYCLES(1);     // TODO: correct cycle count
1793}
1794
1795void i386_device::mmx_paddw_r64_rm64()  // Opcode 0f fd
1796{
1797   int n;
1798   MMXPROLOG();
1799   UINT8 modrm = FETCH();
1800   if( modrm >= 0xc0 ) {
1801      for (n=0;n < 4;n++)
1802         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + MMX(modrm & 7).w[n];
1803   } else {
1804      MMX_REG s;
1805      UINT32 ea = GetEA(modrm, 0);
1806      READMMX(ea, s);
1807      for (n=0;n < 4;n++)
1808         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + s.w[n];
1809   }
1810   CYCLES(1);     // TODO: correct cycle count
1811}
1812
1813void i386_device::mmx_paddd_r64_rm64()  // Opcode 0f fe
1814{
1815   int n;
1816   MMXPROLOG();
1817   UINT8 modrm = FETCH();
1818   if( modrm >= 0xc0 ) {
1819      for (n=0;n < 2;n++)
1820         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + MMX(modrm & 7).d[n];
1821   } else {
1822      MMX_REG s;
1823      UINT32 ea = GetEA(modrm, 0);
1824      READMMX(ea, s);
1825      for (n=0;n < 2;n++)
1826         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + s.d[n];
1827   }
1828   CYCLES(1);     // TODO: correct cycle count
1829}
1830
1831void i386_device::mmx_emms() // Opcode 0f 77
1832{
1833   m_x87_tw = 0xffff; // tag word = 0xffff
1834   // TODO
1835   CYCLES(1);     // TODO: correct cycle count
1836}
1837
1838void i386_device::mmx_movd_r64_rm32() // Opcode 0f 6e
1839{
1840   MMXPROLOG();
1841   UINT8 modrm = FETCH();
1842   if( modrm >= 0xc0 ) {
1843      MMX((modrm >> 3) & 0x7).d[0]=LOAD_RM32(modrm);
1844   } else {
1845      UINT32 ea = GetEA(modrm, 0);
1846      MMX((modrm >> 3) & 0x7).d[0]=READ32(ea);
1847   }
1848   MMX((modrm >> 3) & 0x7).d[1]=0;
1849   CYCLES(1);     // TODO: correct cycle count
1850}
1851
1852void i386_device::mmx_movq_r64_rm64() // Opcode 0f 6f
1853{
1854   MMXPROLOG();
1855   UINT8 modrm = FETCH();
1856   if( modrm >= 0xc0 ) {
1857      MMX((modrm >> 3) & 0x7).l=MMX(modrm & 0x7).l;
1858   } else {
1859      UINT32 ea = GetEA(modrm, 0);
1860      READMMX(ea, MMX((modrm >> 3) & 0x7));
1861   }
1862   CYCLES(1);     // TODO: correct cycle count
1863}
1864
1865void i386_device::mmx_movd_rm32_r64() // Opcode 0f 7e
1866{
1867   MMXPROLOG();
1868   UINT8 modrm = FETCH();
1869   if( modrm >= 0xc0 ) {
1870      STORE_RM32(modrm, MMX((modrm >> 3) & 0x7).d[0]);
1871   } else {
1872      UINT32 ea = GetEA(modrm, 0);
1873      WRITE32(ea, MMX((modrm >> 3) & 0x7).d[0]);
1874   }
1875   CYCLES(1);     // TODO: correct cycle count
1876}
1877
1878void i386_device::mmx_movq_rm64_r64() // Opcode 0f 7f
1879{
1880   MMXPROLOG();
1881   UINT8 modrm = FETCH();
1882   if( modrm >= 0xc0 ) {
1883      MMX(modrm & 0x7)=MMX((modrm >> 3) & 0x7);
1884   } else {
1885      UINT32 ea = GetEA(modrm, 0);
1886      WRITEMMX(ea, MMX((modrm >> 3) & 0x7));
1887   }
1888   CYCLES(1);     // TODO: correct cycle count
1889}
1890
1891void i386_device::mmx_pcmpeqb_r64_rm64() // Opcode 0f 74
1892{
1893   int c;
1894   MMXPROLOG();
1895   UINT8 modrm = FETCH();
1896   if( modrm >= 0xc0 ) {
1897      int s,d;
1898      s=modrm & 0x7;
1899      d=(modrm >> 3) & 0x7;
1900      for (c=0;c <= 7;c++)
1901         MMX(d).b[c]=(MMX(d).b[c] == MMX(s).b[c]) ? 0xff : 0;
1902   } else {
1903      MMX_REG s;
1904      int d=(modrm >> 3) & 0x7;
1905      UINT32 ea = GetEA(modrm, 0);
1906      READMMX(ea, s);
1907      for (c=0;c <= 7;c++)
1908         MMX(d).b[c]=(MMX(d).b[c] == s.b[c]) ? 0xff : 0;
1909   }
1910   CYCLES(1);     // TODO: correct cycle count
1911}
1912
1913void i386_device::mmx_pcmpeqw_r64_rm64() // Opcode 0f 75
1914{
1915   MMXPROLOG();
1916   UINT8 modrm = FETCH();
1917   if( modrm >= 0xc0 ) {
1918      int s,d;
1919      s=modrm & 0x7;
1920      d=(modrm >> 3) & 0x7;
1921      MMX(d).w[0]=(MMX(d).w[0] == MMX(s).w[0]) ? 0xffff : 0;
1922      MMX(d).w[1]=(MMX(d).w[1] == MMX(s).w[1]) ? 0xffff : 0;
1923      MMX(d).w[2]=(MMX(d).w[2] == MMX(s).w[2]) ? 0xffff : 0;
1924      MMX(d).w[3]=(MMX(d).w[3] == MMX(s).w[3]) ? 0xffff : 0;
1925   } else {
1926      MMX_REG s;
1927      int d=(modrm >> 3) & 0x7;
1928      UINT32 ea = GetEA(modrm, 0);
1929      READMMX(ea, s);
1930      MMX(d).w[0]=(MMX(d).w[0] == s.w[0]) ? 0xffff : 0;
1931      MMX(d).w[1]=(MMX(d).w[1] == s.w[1]) ? 0xffff : 0;
1932      MMX(d).w[2]=(MMX(d).w[2] == s.w[2]) ? 0xffff : 0;
1933      MMX(d).w[3]=(MMX(d).w[3] == s.w[3]) ? 0xffff : 0;
1934   }
1935   CYCLES(1);     // TODO: correct cycle count
1936}
1937
1938void i386_device::mmx_pcmpeqd_r64_rm64() // Opcode 0f 76
1939{
1940   MMXPROLOG();
1941   UINT8 modrm = FETCH();
1942   if( modrm >= 0xc0 ) {
1943      int s,d;
1944      s=modrm & 0x7;
1945      d=(modrm >> 3) & 0x7;
1946      MMX(d).d[0]=(MMX(d).d[0] == MMX(s).d[0]) ? 0xffffffff : 0;
1947      MMX(d).d[1]=(MMX(d).d[1] == MMX(s).d[1]) ? 0xffffffff : 0;
1948   } else {
1949      MMX_REG s;
1950      int d=(modrm >> 3) & 0x7;
1951      UINT32 ea = GetEA(modrm, 0);
1952      READMMX(ea, s);
1953      MMX(d).d[0]=(MMX(d).d[0] == s.d[0]) ? 0xffffffff : 0;
1954      MMX(d).d[1]=(MMX(d).d[1] == s.d[1]) ? 0xffffffff : 0;
1955   }
1956   CYCLES(1);     // TODO: correct cycle count
1957}
1958
1959void i386_device::mmx_pshufw_r64_rm64_i8() // Opcode 0f 70
1960{
1961   MMXPROLOG();
1962   UINT8 modrm = FETCH();
1963   if( modrm >= 0xc0 ) {
1964      MMX_REG t;
1965      int s,d;
1966      UINT8 imm8 = FETCH();
1967      s=modrm & 0x7;
1968      d=(modrm >> 3) & 0x7;
1969      t.q=MMX(s).q;
1970      MMX(d).w[0]=t.w[imm8 & 3];
1971      MMX(d).w[1]=t.w[(imm8 >> 2) & 3];
1972      MMX(d).w[2]=t.w[(imm8 >> 4) & 3];
1973      MMX(d).w[3]=t.w[(imm8 >> 6) & 3];
1974   } else {
1975      MMX_REG s;
1976      int d=(modrm >> 3) & 0x7;
1977      UINT32 ea = GetEA(modrm, 0);
1978      UINT8 imm8 = FETCH();
1979      READMMX(ea, s);
1980      MMX(d).w[0]=s.w[imm8 & 3];
1981      MMX(d).w[1]=s.w[(imm8 >> 2) & 3];
1982      MMX(d).w[2]=s.w[(imm8 >> 4) & 3];
1983      MMX(d).w[3]=s.w[(imm8 >> 6) & 3];
1984   }
1985   CYCLES(1);     // TODO: correct cycle count
1986}
1987
1988void i386_device::mmx_punpcklbw_r64_r64m32() // Opcode 0f 60
1989{
1990   MMXPROLOG();
1991   UINT8 modrm = FETCH();
1992   if( modrm >= 0xc0 ) {
1993      UINT32 t;
1994      int s,d;
1995      s=modrm & 0x7;
1996      d=(modrm >> 3) & 0x7;
1997      t=MMX(d).d[0];
1998      MMX(d).b[0]=t & 0xff;
1999      MMX(d).b[1]=MMX(s).b[0];
2000      MMX(d).b[2]=(t >> 8) & 0xff;
2001      MMX(d).b[3]=MMX(s).b[1];
2002      MMX(d).b[4]=(t >> 16) & 0xff;
2003      MMX(d).b[5]=MMX(s).b[2];
2004      MMX(d).b[6]=(t >> 24) & 0xff;
2005      MMX(d).b[7]=MMX(s).b[3];
2006   } else {
2007      UINT32 s,t;
2008      int d=(modrm >> 3) & 0x7;
2009      UINT32 ea = GetEA(modrm, 0);
2010      s = READ32(ea);
2011      t=MMX(d).d[0];
2012      MMX(d).b[0]=t & 0xff;
2013      MMX(d).b[1]=s & 0xff;
2014      MMX(d).b[2]=(t >> 8) & 0xff;
2015      MMX(d).b[3]=(s >> 8) & 0xff;
2016      MMX(d).b[4]=(t >> 16) & 0xff;
2017      MMX(d).b[5]=(s >> 16) & 0xff;
2018      MMX(d).b[6]=(t >> 24) & 0xff;
2019      MMX(d).b[7]=(s >> 24) & 0xff;
2020   }
2021   CYCLES(1);     // TODO: correct cycle count
2022}
2023
2024void i386_device::mmx_punpcklwd_r64_r64m32() // Opcode 0f 61
2025{
2026   MMXPROLOG();
2027   UINT8 modrm = FETCH();
2028   if( modrm >= 0xc0 ) {
2029      UINT16 t;
2030      int s,d;
2031      s=modrm & 0x7;
2032      d=(modrm >> 3) & 0x7;
2033      t=MMX(d).w[1];
2034      MMX(d).w[0]=MMX(d).w[0];
2035      MMX(d).w[1]=MMX(s).w[0];
2036      MMX(d).w[2]=t;
2037      MMX(d).w[3]=MMX(s).w[1];
2038   } else {
2039      UINT32 s;
2040      UINT16 t;
2041      int d=(modrm >> 3) & 0x7;
2042      UINT32 ea = GetEA(modrm, 0);
2043      s = READ32(ea);
2044      t=MMX(d).w[1];
2045      MMX(d).w[0]=MMX(d).w[0];
2046      MMX(d).w[1]=s & 0xffff;
2047      MMX(d).w[2]=t;
2048      MMX(d).w[3]=(s >> 16) & 0xffff;
2049   }
2050   CYCLES(1);     // TODO: correct cycle count
2051}
2052
2053void i386_device::mmx_punpckldq_r64_r64m32() // Opcode 0f 62
2054{
2055   MMXPROLOG();
2056   UINT8 modrm = FETCH();
2057   if( modrm >= 0xc0 ) {
2058      int s,d;
2059      s=modrm & 0x7;
2060      d=(modrm >> 3) & 0x7;
2061      MMX(d).d[0]=MMX(d).d[0];
2062      MMX(d).d[1]=MMX(s).d[0];
2063   } else {
2064      UINT32 s;
2065      int d=(modrm >> 3) & 0x7;
2066      UINT32 ea = GetEA(modrm, 0);
2067      s = READ32(ea);
2068      MMX(d).d[0]=MMX(d).d[0];
2069      MMX(d).d[1]=s;
2070   }
2071   CYCLES(1);     // TODO: correct cycle count
2072}
2073
2074void i386_device::mmx_packsswb_r64_rm64() // Opcode 0f 63
2075{
2076   MMXPROLOG();
2077   UINT8 modrm = FETCH();
2078   if( modrm >= 0xc0 ) {
2079      int s,d;
2080      s=modrm & 0x7;
2081      d=(modrm >> 3) & 0x7;
2082      MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]);
2083      MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]);
2084      MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]);
2085      MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]);
2086      MMX(d).c[4]=SaturatedSignedWordToSignedByte(MMX(s).s[0]);
2087      MMX(d).c[5]=SaturatedSignedWordToSignedByte(MMX(s).s[1]);
2088      MMX(d).c[6]=SaturatedSignedWordToSignedByte(MMX(s).s[2]);
2089      MMX(d).c[7]=SaturatedSignedWordToSignedByte(MMX(s).s[3]);
2090   } else {
2091      MMX_REG s;
2092      int d=(modrm >> 3) & 0x7;
2093      UINT32 ea = GetEA(modrm, 0);
2094      READMMX(ea, s);
2095      MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]);
2096      MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]);
2097      MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]);
2098      MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]);
2099      MMX(d).c[4]=SaturatedSignedWordToSignedByte(s.s[0]);
2100      MMX(d).c[5]=SaturatedSignedWordToSignedByte(s.s[1]);
2101      MMX(d).c[6]=SaturatedSignedWordToSignedByte(s.s[2]);
2102      MMX(d).c[7]=SaturatedSignedWordToSignedByte(s.s[3]);
2103   }
2104   CYCLES(1);     // TODO: correct cycle count
2105}
2106
2107void i386_device::mmx_pcmpgtb_r64_rm64() // Opcode 0f 64
2108{
2109   int c;
2110   MMXPROLOG();
2111   UINT8 modrm = FETCH();
2112   if( modrm >= 0xc0 ) {
2113      int s,d;
2114      s=modrm & 0x7;
2115      d=(modrm >> 3) & 0x7;
2116      for (c=0;c <= 7;c++)
2117         MMX(d).b[c]=(MMX(d).c[c] > MMX(s).c[c]) ? 0xff : 0;
2118   } else {
2119      MMX_REG s;
2120      int d=(modrm >> 3) & 0x7;
2121      UINT32 ea = GetEA(modrm, 0);
2122      READMMX(ea, s);
2123      for (c=0;c <= 7;c++)
2124         MMX(d).b[c]=(MMX(d).c[c] > s.c[c]) ? 0xff : 0;
2125   }
2126   CYCLES(1);     // TODO: correct cycle count
2127}
2128
2129void i386_device::mmx_pcmpgtw_r64_rm64() // Opcode 0f 65
2130{
2131   int c;
2132   MMXPROLOG();
2133   UINT8 modrm = FETCH();
2134   if( modrm >= 0xc0 ) {
2135      int s,d;
2136      s=modrm & 0x7;
2137      d=(modrm >> 3) & 0x7;
2138      for (c=0;c <= 3;c++)
2139         MMX(d).w[c]=(MMX(d).s[c] > MMX(s).s[c]) ? 0xffff : 0;
2140   } else {
2141      MMX_REG s;
2142      int d=(modrm >> 3) & 0x7;
2143      UINT32 ea = GetEA(modrm, 0);
2144      READMMX(ea, s);
2145      for (c=0;c <= 3;c++)
2146         MMX(d).w[c]=(MMX(d).s[c] > s.s[c]) ? 0xffff : 0;
2147   }
2148   CYCLES(1);     // TODO: correct cycle count
2149}
2150
2151void i386_device::mmx_pcmpgtd_r64_rm64() // Opcode 0f 66
2152{
2153   int c;
2154   MMXPROLOG();
2155   UINT8 modrm = FETCH();
2156   if( modrm >= 0xc0 ) {
2157      int s,d;
2158      s=modrm & 0x7;
2159      d=(modrm >> 3) & 0x7;
2160      for (c=0;c <= 1;c++)
2161         MMX(d).d[c]=(MMX(d).i[c] > MMX(s).i[c]) ? 0xffffffff : 0;
2162   } else {
2163      MMX_REG s;
2164      int d=(modrm >> 3) & 0x7;
2165      UINT32 ea = GetEA(modrm, 0);
2166      READMMX(ea, s);
2167      for (c=0;c <= 1;c++)
2168         MMX(d).d[c]=(MMX(d).i[c] > s.i[c]) ? 0xffffffff : 0;
2169   }
2170   CYCLES(1);     // TODO: correct cycle count
2171}
2172
2173void i386_device::mmx_packuswb_r64_rm64() // Opcode 0f 67
2174{
2175   MMXPROLOG();
2176   UINT8 modrm = FETCH();
2177   if( modrm >= 0xc0 ) {
2178      int s,d;
2179      s=modrm & 0x7;
2180      d=(modrm >> 3) & 0x7;
2181      MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(MMX(d).s[0]);
2182      MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(MMX(d).s[1]);
2183      MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(MMX(d).s[2]);
2184      MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(MMX(d).s[3]);
2185      MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(MMX(s).s[0]);
2186      MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(MMX(s).s[1]);
2187      MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(MMX(s).s[2]);
2188      MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(MMX(s).s[3]);
2189   } else {
2190      MMX_REG s;
2191      int d=(modrm >> 3) & 0x7;
2192      UINT32 ea = GetEA(modrm, 0);
2193      READMMX(ea, s);
2194      MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(MMX(d).s[0]);
2195      MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(MMX(d).s[1]);
2196      MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(MMX(d).s[2]);
2197      MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(MMX(d).s[3]);
2198      MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(s.s[0]);
2199      MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(s.s[1]);
2200      MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(s.s[2]);
2201      MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(s.s[3]);
2202   }
2203   CYCLES(1);     // TODO: correct cycle count
2204}
2205
2206void i386_device::mmx_punpckhbw_r64_rm64() // Opcode 0f 68
2207{
2208   MMXPROLOG();
2209   UINT8 modrm = FETCH();
2210   if( modrm >= 0xc0 ) {
2211      int s,d;
2212      s=modrm & 0x7;
2213      d=(modrm >> 3) & 0x7;
2214      MMX(d).b[0]=MMX(d).b[4];
2215      MMX(d).b[1]=MMX(s).b[4];
2216      MMX(d).b[2]=MMX(d).b[5];
2217      MMX(d).b[3]=MMX(s).b[5];
2218      MMX(d).b[4]=MMX(d).b[6];
2219      MMX(d).b[5]=MMX(s).b[6];
2220      MMX(d).b[6]=MMX(d).b[7];
2221      MMX(d).b[7]=MMX(s).b[7];
2222   } else {
2223      MMX_REG s;
2224      int d=(modrm >> 3) & 0x7;
2225      UINT32 ea = GetEA(modrm, 0);
2226      READMMX(ea, s);
2227      MMX(d).b[0]=MMX(d).b[4];
2228      MMX(d).b[1]=s.b[4];
2229      MMX(d).b[2]=MMX(d).b[5];
2230      MMX(d).b[3]=s.b[5];
2231      MMX(d).b[4]=MMX(d).b[6];
2232      MMX(d).b[5]=s.b[6];
2233      MMX(d).b[6]=MMX(d).b[7];
2234      MMX(d).b[7]=s.b[7];
2235   }
2236   CYCLES(1);     // TODO: correct cycle count
2237}
2238
2239void i386_device::mmx_punpckhwd_r64_rm64() // Opcode 0f 69
2240{
2241   MMXPROLOG();
2242   UINT8 modrm = FETCH();
2243   if( modrm >= 0xc0 ) {
2244      int s,d;
2245      s=modrm & 0x7;
2246      d=(modrm >> 3) & 0x7;
2247      MMX(d).w[0]=MMX(d).w[2];
2248      MMX(d).w[1]=MMX(s).w[2];
2249      MMX(d).w[2]=MMX(d).w[3];
2250      MMX(d).w[3]=MMX(s).w[3];
2251   } else {
2252      MMX_REG s;
2253      int d=(modrm >> 3) & 0x7;
2254      UINT32 ea = GetEA(modrm, 0);
2255      READMMX(ea, s);
2256      MMX(d).w[0]=MMX(d).w[2];
2257      MMX(d).w[1]=s.w[2];
2258      MMX(d).w[2]=MMX(d).w[3];
2259      MMX(d).w[3]=s.w[3];
2260   }
2261   CYCLES(1);     // TODO: correct cycle count
2262}
2263
2264void i386_device::mmx_punpckhdq_r64_rm64() // Opcode 0f 6a
2265{
2266   MMXPROLOG();
2267   UINT8 modrm = FETCH();
2268   if( modrm >= 0xc0 ) {
2269      int s,d;
2270      s=modrm & 0x7;
2271      d=(modrm >> 3) & 0x7;
2272      MMX(d).d[0]=MMX(d).d[1];
2273      MMX(d).d[1]=MMX(s).d[1];
2274   } else {
2275      MMX_REG s;
2276      int d=(modrm >> 3) & 0x7;
2277      UINT32 ea = GetEA(modrm, 0);
2278      READMMX(ea, s);
2279      MMX(d).d[0]=MMX(d).d[1];
2280      MMX(d).d[1]=s.d[1];
2281   }
2282   CYCLES(1);     // TODO: correct cycle count
2283}
2284
2285void i386_device::mmx_packssdw_r64_rm64() // Opcode 0f 6b
2286{
2287   MMXPROLOG();
2288   UINT8 modrm = FETCH();
2289   if( modrm >= 0xc0 ) {
2290      int s,d;
2291      s=modrm & 0x7;
2292      d=(modrm >> 3) & 0x7;
2293      MMX(d).s[0]=SaturatedSignedDwordToSignedWord(MMX(d).i[0]);
2294      MMX(d).s[1]=SaturatedSignedDwordToSignedWord(MMX(d).i[1]);
2295      MMX(d).s[2]=SaturatedSignedDwordToSignedWord(MMX(s).i[0]);
2296      MMX(d).s[3]=SaturatedSignedDwordToSignedWord(MMX(s).i[1]);
2297   } else {
2298      MMX_REG s;
2299      int d=(modrm >> 3) & 0x7;
2300      UINT32 ea = GetEA(modrm, 0);
2301      READMMX(ea, s);
2302      MMX(d).s[0]=SaturatedSignedDwordToSignedWord(MMX(d).i[0]);
2303      MMX(d).s[1]=SaturatedSignedDwordToSignedWord(MMX(d).i[1]);
2304      MMX(d).s[2]=SaturatedSignedDwordToSignedWord(s.i[0]);
2305      MMX(d).s[3]=SaturatedSignedDwordToSignedWord(s.i[1]);
2306   }
2307   CYCLES(1);     // TODO: correct cycle count
2308}
2309
2310void i386_device::sse_sse_group0fae()  // Opcode 0f ae
2311{
2312   UINT8 modm = FETCH();
2313   if( modm == 0xf8 ) {
2314      logerror("Unemulated SFENCE opcode called\n");
2315      CYCLES(1); // sfence instruction
2316   } else if( modm == 0xf0 ) {
2317      CYCLES(1); // mfence instruction
2318   } else if( modm == 0xe8 ) {
2319      CYCLES(1); // lfence instruction
2320   } else if( modm < 0xc0 ) {
2321      UINT32 ea;
2322      switch ( (modm & 0x38) >> 3 )
2323      {
2324         case 2: // ldmxcsr m32
2325            ea = GetEA(modm, 0);
2326            m_mxcsr = READ32(ea);
2327            break;
2328         case 3: // stmxcsr m32
2329            ea = GetEA(modm, 0);
2330            WRITE32(ea, m_mxcsr);
2331            break;
2332         case 7: // clflush m8
2333            GetNonTranslatedEA(modm, NULL);
2334            break;
2335         default:
2336            report_invalid_modrm("sse_group0fae", modm);
2337      }
2338   } else {
2339      report_invalid_modrm("sse_group0fae", modm);
2340   }
2341}
2342
2343void i386_device::sse_cvttps2dq_r128_rm128() // Opcode f3 0f 5b
2344{
2345   UINT8 modrm = FETCH();
2346   if( modrm >= 0xc0 ) {
2347      XMM((modrm >> 3) & 0x7).i[0]=(INT32)XMM(modrm & 0x7).f[0];
2348      XMM((modrm >> 3) & 0x7).i[1]=(INT32)XMM(modrm & 0x7).f[1];
2349      XMM((modrm >> 3) & 0x7).i[2]=(INT32)XMM(modrm & 0x7).f[2];
2350      XMM((modrm >> 3) & 0x7).i[3]=(INT32)XMM(modrm & 0x7).f[3];
2351   } else {
2352      XMM_REG src;
2353      UINT32 ea = GetEA(modrm, 0);
2354      READXMM(ea, src);
2355      XMM((modrm >> 3) & 0x7).i[0]=(INT32)src.f[0];
2356      XMM((modrm >> 3) & 0x7).i[1]=(INT32)src.f[1];
2357      XMM((modrm >> 3) & 0x7).i[2]=(INT32)src.f[2];
2358      XMM((modrm >> 3) & 0x7).i[3]=(INT32)src.f[3];
2359   }
2360   CYCLES(1);     // TODO: correct cycle count
2361}
2362
2363void i386_device::sse_cvtss2sd_r128_r128m32() // Opcode f3 0f 5a
2364{
2365   UINT8 modrm = FETCH();
2366   if( modrm >= 0xc0 ) {
2367      XMM((modrm >> 3) & 0x7).f64[0] = XMM(modrm & 0x7).f[0];
2368   } else {
2369      XMM_REG s;
2370      UINT32 ea = GetEA(modrm, 0);
2371      s.d[0] = READ32(ea);
2372      XMM((modrm >> 3) & 0x7).f64[0] = s.f[0];
2373   }
2374   CYCLES(1);     // TODO: correct cycle count
2375}
2376
2377void i386_device::sse_cvttss2si_r32_r128m32() // Opcode f3 0f 2c
2378{
2379   INT32 src;
2380   UINT8 modrm = FETCH(); // get mordm byte
2381   if( modrm >= 0xc0 ) { // if bits 7-6 are 11 the source is a xmm register (low doubleword)
2382      src = (INT32)XMM(modrm & 0x7).f[0^NATIVE_ENDIAN_VALUE_LE_BE(0,1)];
2383   } else { // otherwise is a memory address
2384      XMM_REG t;
2385      UINT32 ea = GetEA(modrm, 0);
2386      t.d[0] = READ32(ea);
2387      src = (INT32)t.f[0];
2388   }
2389   STORE_REG32(modrm, (UINT32)src);
2390   CYCLES(1);     // TODO: correct cycle count
2391}
2392
2393void i386_device::sse_cvtss2si_r32_r128m32() // Opcode f3 0f 2d
2394{
2395   INT32 src;
2396   UINT8 modrm = FETCH();
2397   if( modrm >= 0xc0 ) {
2398      src = (INT32)XMM(modrm & 0x7).f[0];
2399   } else {
2400      XMM_REG t;
2401      UINT32 ea = GetEA(modrm, 0);
2402      t.d[0] = READ32(ea);
2403      src = (INT32)t.f[0];
2404   }
2405   STORE_REG32(modrm, (UINT32)src);
2406   CYCLES(1);     // TODO: correct cycle count
2407}
2408
2409void i386_device::sse_cvtsi2ss_r128_rm32() // Opcode f3 0f 2a
2410{
2411   UINT8 modrm = FETCH();
2412   if( modrm >= 0xc0 ) {
2413      XMM((modrm >> 3) & 0x7).f[0] = (INT32)LOAD_RM32(modrm);
2414   } else {
2415      UINT32 ea = GetEA(modrm, 0);
2416      XMM((modrm >> 3) & 0x7).f[0] = (INT32)READ32(ea);
2417   }
2418   CYCLES(1);     // TODO: correct cycle count
2419}
2420
2421void i386_device::sse_cvtpi2ps_r128_rm64() // Opcode 0f 2a
2422{
2423   UINT8 modrm = FETCH();
2424   MMXPROLOG();
2425   if( modrm >= 0xc0 ) {
2426      XMM((modrm >> 3) & 0x7).f[0] = MMX(modrm & 0x7).i[0];
2427      XMM((modrm >> 3) & 0x7).f[1] = MMX(modrm & 0x7).i[1];
2428   } else {
2429      MMX_REG r;
2430      UINT32 ea = GetEA(modrm, 0);
2431      READMMX(ea, r);
2432      XMM((modrm >> 3) & 0x7).f[0] = r.i[0];
2433      XMM((modrm >> 3) & 0x7).f[1] = r.i[1];
2434   }
2435   CYCLES(1);     // TODO: correct cycle count
2436}
2437
2438void i386_device::sse_cvttps2pi_r64_r128m64() // Opcode 0f 2c
2439{
2440   UINT8 modrm = FETCH();
2441   MMXPROLOG();
2442   if( modrm >= 0xc0 ) {
2443      MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0];
2444      MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1];
2445   } else {
2446      XMM_REG r;
2447      UINT32 ea = GetEA(modrm, 0);
2448      READXMM(ea, r);
2449      XMM((modrm >> 3) & 0x7).i[0] = r.f[0];
2450      XMM((modrm >> 3) & 0x7).i[1] = r.f[1];
2451   }
2452   CYCLES(1);     // TODO: correct cycle count
2453}
2454
2455void i386_device::sse_cvtps2pi_r64_r128m64() // Opcode 0f 2d
2456{
2457   UINT8 modrm = FETCH();
2458   MMXPROLOG();
2459   if( modrm >= 0xc0 ) {
2460      MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0];
2461      MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1];
2462   } else {
2463      XMM_REG r;
2464      UINT32 ea = GetEA(modrm, 0);
2465      READXMM(ea, r);
2466      XMM((modrm >> 3) & 0x7).i[0] = r.f[0];
2467      XMM((modrm >> 3) & 0x7).i[1] = r.f[1];
2468   }
2469   CYCLES(1);     // TODO: correct cycle count
2470}
2471
2472void i386_device::sse_cvtps2pd_r128_r128m64() // Opcode 0f 5a
2473{
2474   UINT8 modrm = FETCH();
2475   if( modrm >= 0xc0 ) {
2476      XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).f[0];
2477      XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).f[1];
2478   } else {
2479      MMX_REG r;
2480      UINT32 ea = GetEA(modrm, 0);
2481      READMMX(ea, r);
2482      XMM((modrm >> 3) & 0x7).f64[0] = (double)r.f[0];
2483      XMM((modrm >> 3) & 0x7).f64[1] = (double)r.f[1];
2484   }
2485   CYCLES(1);     // TODO: correct cycle count
2486}
2487
2488void i386_device::sse_cvtdq2ps_r128_rm128() // Opcode 0f 5b
2489{
2490   UINT8 modrm = FETCH();
2491   if( modrm >= 0xc0 ) {
2492      XMM((modrm >> 3) & 0x7).f[0] = (float)XMM(modrm & 0x7).i[0];
2493      XMM((modrm >> 3) & 0x7).f[1] = (float)XMM(modrm & 0x7).i[1];
2494      XMM((modrm >> 3) & 0x7).f[2] = (float)XMM(modrm & 0x7).i[2];
2495      XMM((modrm >> 3) & 0x7).f[3] = (float)XMM(modrm & 0x7).i[3];
2496   } else {
2497      XMM_REG r;
2498      UINT32 ea = GetEA(modrm, 0);
2499      READXMM(ea, r);
2500      XMM((modrm >> 3) & 0x7).f[0] = (float)r.i[0];
2501      XMM((modrm >> 3) & 0x7).f[1] = (float)r.i[1];
2502      XMM((modrm >> 3) & 0x7).f[2] = (float)r.i[2];
2503      XMM((modrm >> 3) & 0x7).f[3] = (float)r.i[3];
2504   }
2505   CYCLES(1);     // TODO: correct cycle count
2506}
2507
2508void i386_device::sse_cvtdq2pd_r128_r128m64() // Opcode f3 0f e6
2509{
2510   UINT8 modrm = FETCH();
2511   if( modrm >= 0xc0 ) {
2512      XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).i[0];
2513      XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).i[1];
2514   } else {
2515      MMX_REG s;
2516      UINT32 ea = GetEA(modrm, 0);
2517      READMMX(ea, s);
2518      XMM((modrm >> 3) & 0x7).f64[0] = (double)s.i[0];
2519      XMM((modrm >> 3) & 0x7).f64[1] = (double)s.i[1];
2520   }
2521   CYCLES(1);     // TODO: correct cycle count
2522}
2523
2524void i386_device::sse_movss_r128_rm128() // Opcode f3 0f 10
2525{
2526   UINT8 modrm = FETCH();
2527   if( modrm >= 0xc0 ) {
2528      XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0];
2529   } else {
2530      UINT32 ea = GetEA(modrm, 0);
2531      XMM((modrm >> 3) & 0x7).d[0] = READ32(ea);
2532   }
2533   CYCLES(1);     // TODO: correct cycle count
2534}
2535
2536void i386_device::sse_movss_rm128_r128() // Opcode f3 0f 11
2537{
2538   UINT8 modrm = FETCH();
2539   if( modrm >= 0xc0 ) {
2540      XMM(modrm & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0];
2541   } else {
2542      UINT32 ea = GetEA(modrm, 0);
2543      WRITE32(ea, XMM((modrm >> 3) & 0x7).d[0]);
2544   }
2545   CYCLES(1);     // TODO: correct cycle count
2546}
2547
2548void i386_device::sse_movsldup_r128_rm128() // Opcode f3 0f 12
2549{
2550   UINT8 modrm = FETCH();
2551   if( modrm >= 0xc0 ) {
2552      XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0];
2553      XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[0];
2554      XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[2];
2555      XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[2];
2556   } else {
2557      XMM_REG src;
2558      UINT32 ea = GetEA(modrm, 0);
2559      READXMM(ea, src);
2560      XMM((modrm >> 3) & 0x7).d[0] = src.d[0];
2561      XMM((modrm >> 3) & 0x7).d[1] = src.d[0];
2562      XMM((modrm >> 3) & 0x7).d[2] = src.d[2];
2563      XMM((modrm >> 3) & 0x7).d[3] = src.d[2];
2564   }
2565   CYCLES(1);     // TODO: correct cycle count
2566}
2567
2568void i386_device::sse_movshdup_r128_rm128() // Opcode f3 0f 16
2569{
2570   UINT8 modrm = FETCH();
2571   if( modrm >= 0xc0 ) {
2572      XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[1];
2573      XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[1];
2574      XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[3];
2575      XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[3];
2576   } else {
2577      XMM_REG src;
2578      UINT32 ea = GetEA(modrm, 0);
2579      READXMM(ea, src);
2580      XMM((modrm >> 3) & 0x7).d[0] = src.d[1];
2581      XMM((modrm >> 3) & 0x7).d[1] = src.d[1];
2582      XMM((modrm >> 3) & 0x7).d[2] = src.d[3];
2583      XMM((modrm >> 3) & 0x7).d[3] = src.d[3];
2584   }
2585   CYCLES(1);     // TODO: correct cycle count
2586}
2587
2588void i386_device::sse_movaps_r128_rm128() // Opcode 0f 28
2589{
2590   UINT8 modrm = FETCH();
2591   if( modrm >= 0xc0 ) {
2592      XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7);
2593   } else {
2594      UINT32 ea = GetEA(modrm, 0);
2595      READXMM(ea, XMM((modrm >> 3) & 0x7));
2596   }
2597   CYCLES(1);     // TODO: correct cycle count
2598}
2599
2600void i386_device::sse_movaps_rm128_r128() // Opcode 0f 29
2601{
2602   UINT8 modrm = FETCH();
2603   if( modrm >= 0xc0 ) {
2604      XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7);
2605   } else {
2606      UINT32 ea = GetEA(modrm, 0);
2607      WRITEXMM(ea, XMM((modrm >> 3) & 0x7));
2608   }
2609   CYCLES(1);     // TODO: correct cycle count
2610}
2611
2612void i386_device::sse_movups_r128_rm128() // Opcode 0f 10
2613{
2614   UINT8 modrm = FETCH();
2615   if( modrm >= 0xc0 ) {
2616      XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7);
2617   } else {
2618      UINT32 ea = GetEA(modrm, 0);
2619      READXMM(ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
2620   }
2621   CYCLES(1);     // TODO: correct cycle count
2622}
2623
2624void i386_device::sse_movups_rm128_r128() // Opcode 0f 11
2625{
2626   UINT8 modrm = FETCH();
2627   if( modrm >= 0xc0 ) {
2628      XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7);
2629   } else {
2630      UINT32 ea = GetEA(modrm, 0);
2631      WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
2632   }
2633   CYCLES(1);     // TODO: correct cycle count
2634}
2635
2636void i386_device::sse_movlps_r128_m64() // Opcode 0f 12
2637{
2638   UINT8 modrm = FETCH();
2639   if( modrm >= 0xc0 ) {
2640      // unsupported by cpu
2641      CYCLES(1);     // TODO: correct cycle count
2642   } else {
2643      UINT32 ea = GetEA(modrm, 0);
2644      READXMM_LO64(ea, XMM((modrm >> 3) & 0x7));
2645      CYCLES(1);     // TODO: correct cycle count
2646   }
2647}
2648
2649void i386_device::sse_movlps_m64_r128() // Opcode 0f 13
2650{
2651   UINT8 modrm = FETCH();
2652   if( modrm >= 0xc0 ) {
2653      // unsupported by cpu
2654      CYCLES(1);     // TODO: correct cycle count
2655   } else {
2656      UINT32 ea = GetEA(modrm, 0);
2657      WRITEXMM_LO64(ea, XMM((modrm >> 3) & 0x7));
2658      CYCLES(1);     // TODO: correct cycle count
2659   }
2660}
2661
2662void i386_device::sse_movhps_r128_m64() // Opcode 0f 16
2663{
2664   UINT8 modrm = FETCH();
2665   if( modrm >= 0xc0 ) {
2666      // unsupported by cpu
2667      CYCLES(1);     // TODO: correct cycle count
2668   } else {
2669      UINT32 ea = GetEA(modrm, 0);
2670      READXMM_HI64(ea, XMM((modrm >> 3) & 0x7));
2671      CYCLES(1);     // TODO: correct cycle count
2672   }
2673}
2674
2675void i386_device::sse_movhps_m64_r128() // Opcode 0f 17
2676{
2677   UINT8 modrm = FETCH();
2678   if( modrm >= 0xc0 ) {
2679      // unsupported by cpu
2680      CYCLES(1);     // TODO: correct cycle count
2681   } else {
2682      UINT32 ea = GetEA(modrm, 0);
2683      WRITEXMM_HI64(ea, XMM((modrm >> 3) & 0x7));
2684      CYCLES(1);     // TODO: correct cycle count
2685   }
2686}
2687
2688void i386_device::sse_movntps_m128_r128() // Opcode 0f 2b
2689{
2690   UINT8 modrm = FETCH();
2691   if( modrm >= 0xc0 ) {
2692      // unsupported by cpu
2693      CYCLES(1);     // TODO: correct cycle count
2694   } else {
2695      // since cache is not implemented
2696      UINT32 ea = GetEA(modrm, 0);
2697      WRITEXMM(ea, XMM((modrm >> 3) & 0x7));
2698      CYCLES(1);     // TODO: correct cycle count
2699   }
2700}
2701
2702void i386_device::sse_movmskps_r16_r128() // Opcode 0f 50
2703{
2704   UINT8 modrm = FETCH();
2705   if( modrm >= 0xc0 ) {
2706      int b;
2707      b=(XMM(modrm & 0x7).d[0] >> 31) & 1;
2708      b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2);
2709      b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4);
2710      b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8);
2711      STORE_REG16(modrm, b);
2712   }
2713   CYCLES(1);     // TODO: correct cycle count
2714}
2715
2716void i386_device::sse_movmskps_r32_r128() // Opcode 0f 50
2717{
2718   UINT8 modrm = FETCH();
2719   if( modrm >= 0xc0 ) {
2720      int b;
2721      b=(XMM(modrm & 0x7).d[0] >> 31) & 1;
2722      b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2);
2723      b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4);
2724      b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8);
2725      STORE_REG32(modrm, b);
2726   }
2727   CYCLES(1);     // TODO: correct cycle count
2728}
2729
2730void i386_device::sse_movq2dq_r128_r64() // Opcode f3 0f d6
2731{
2732   MMXPROLOG();
2733   UINT8 modrm = FETCH();
2734   if( modrm >= 0xc0 ) {
2735      XMM((modrm >> 3) & 0x7).q[0] = MMX(modrm & 7).q;
2736      XMM((modrm >> 3) & 0x7).q[1] = 0;
2737   }
2738   CYCLES(1);     // TODO: correct cycle count
2739}
2740
2741void i386_device::sse_movdqu_r128_rm128() // Opcode f3 0f 6f
2742{
2743   MMXPROLOG();
2744   UINT8 modrm = FETCH();
2745   if( modrm >= 0xc0 ) {
2746      XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
2747      XMM((modrm >> 3) & 0x7).q[1] = XMM(modrm & 0x7).q[1];
2748   } else {
2749      UINT32 ea = GetEA(modrm, 0);
2750      READXMM(ea, XMM((modrm >> 3) & 0x7));
2751   }
2752   CYCLES(1);     // TODO: correct cycle count
2753}
2754
2755void i386_device::sse_movdqu_rm128_r128() // Opcode f3 0f 7f
2756{
2757   MMXPROLOG();
2758   UINT8 modrm = FETCH();
2759   if( modrm >= 0xc0 ) {
2760      XMM(modrm & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0];
2761      XMM(modrm & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1];
2762   } else {
2763      UINT32 ea = GetEA(modrm, 0);
2764      WRITEXMM(ea, XMM((modrm >> 3) & 0x7));
2765   }
2766   CYCLES(1);     // TODO: correct cycle count
2767}
2768
2769void i386_device::sse_movq_r128_r128m64() // Opcode f3 0f 7e
2770{
2771   MMXPROLOG();
2772   UINT8 modrm = FETCH();
2773   if( modrm >= 0xc0 ) {
2774      XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
2775      XMM((modrm >> 3) & 0x7).q[1] = 0;
2776   } else {
2777      UINT32 ea = GetEA(modrm, 0);
2778      XMM((modrm >> 3) & 0x7).q[0] = READ64(ea);
2779      XMM((modrm >> 3) & 0x7).q[1] = 0;
2780   }
2781   CYCLES(1);     // TODO: correct cycle count
2782}
2783
2784void i386_device::sse_pmovmskb_r16_r64() // Opcode 0f d7
2785{
2786   //MMXPROLOG();
2787   UINT8 modrm = FETCH();
2788   if( modrm >= 0xc0 ) {
2789      int b;
2790      b=(MMX(modrm & 0x7).b[0] >> 7) & 1;
2791      b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2);
2792      b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4);
2793      b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8);
2794      b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16);
2795      b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32);
2796      b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64);
2797      b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128);
2798      STORE_REG16(modrm, b);
2799   }
2800   CYCLES(1);     // TODO: correct cycle count
2801}
2802
2803void i386_device::sse_pmovmskb_r32_r64() // Opcode 0f d7
2804{
2805   //MMXPROLOG();
2806   UINT8 modrm = FETCH();
2807   if( modrm >= 0xc0 ) {
2808      int b;
2809      b=(MMX(modrm & 0x7).b[0] >> 7) & 1;
2810      b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2);
2811      b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4);
2812      b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8);
2813      b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16);
2814      b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32);
2815      b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64);
2816      b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128);
2817      STORE_REG32(modrm, b);
2818   }
2819   CYCLES(1);     // TODO: correct cycle count
2820}
2821
2822void i386_device::sse_xorps() // Opcode 0f 57
2823{
2824   UINT8 modrm = FETCH();
2825   if( modrm >= 0xc0 ) {
2826      XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ XMM(modrm & 0x7).d[0];
2827      XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ XMM(modrm & 0x7).d[1];
2828      XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ XMM(modrm & 0x7).d[2];
2829      XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ XMM(modrm & 0x7).d[3];
2830   } else {
2831      XMM_REG src;
2832      UINT32 ea = GetEA(modrm, 0);
2833      READXMM(ea, src);
2834      XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ src.d[0];
2835      XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ src.d[1];
2836      XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ src.d[2];
2837      XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ src.d[3];
2838   }
2839   CYCLES(1);     // TODO: correct cycle count
2840}
2841
2842void i386_device::sse_addps() // Opcode 0f 58
2843{
2844   UINT8 modrm = FETCH();
2845   if( modrm >= 0xc0 ) {
2846      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + XMM(modrm & 0x7).f[0];
2847      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] + XMM(modrm & 0x7).f[1];
2848      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] + XMM(modrm & 0x7).f[2];
2849      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] + XMM(modrm & 0x7).f[3];
2850   } else {
2851      XMM_REG src;
2852      UINT32 ea = GetEA(modrm, 0);
2853      READXMM(ea, src);
2854      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + src.f[0];
2855      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] + src.f[1];
2856      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] + src.f[2];
2857      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] + src.f[3];
2858   }
2859   CYCLES(1);     // TODO: correct cycle count
2860}
2861
2862void i386_device::sse_sqrtps_r128_rm128() // Opcode 0f 51
2863{
2864   UINT8 modrm = FETCH();
2865   if( modrm >= 0xc0 ) {
2866      XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]);
2867      XMM((modrm >> 3) & 0x7).f[1] = sqrt(XMM(modrm & 0x7).f[1]);
2868      XMM((modrm >> 3) & 0x7).f[2] = sqrt(XMM(modrm & 0x7).f[2]);
2869      XMM((modrm >> 3) & 0x7).f[3] = sqrt(XMM(modrm & 0x7).f[3]);
2870   } else {
2871      XMM_REG src;
2872      UINT32 ea = GetEA(modrm, 0);
2873      READXMM(ea, src);
2874      XMM((modrm >> 3) & 0x7).f[0] = sqrt(src.f[0]);
2875      XMM((modrm >> 3) & 0x7).f[1] = sqrt(src.f[1]);
2876      XMM((modrm >> 3) & 0x7).f[2] = sqrt(src.f[2]);
2877      XMM((modrm >> 3) & 0x7).f[3] = sqrt(src.f[3]);
2878   }
2879   CYCLES(1);     // TODO: correct cycle count
2880}
2881
2882void i386_device::sse_rsqrtps_r128_rm128() // Opcode 0f 52
2883{
2884   UINT8 modrm = FETCH();
2885   if( modrm >= 0xc0 ) {
2886      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]);
2887      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(XMM(modrm & 0x7).f[1]);
2888      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(XMM(modrm & 0x7).f[2]);
2889      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(XMM(modrm & 0x7).f[3]);
2890   } else {
2891      XMM_REG src;
2892      UINT32 ea = GetEA(modrm, 0);
2893      READXMM(ea, src);
2894      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(src.f[0]);
2895      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(src.f[1]);
2896      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(src.f[2]);
2897      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(src.f[3]);
2898   }
2899   CYCLES(1);     // TODO: correct cycle count
2900}
2901
2902void i386_device::sse_rcpps_r128_rm128() // Opcode 0f 53
2903{
2904   UINT8 modrm = FETCH();
2905   if( modrm >= 0xc0 ) {
2906      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / XMM(modrm & 0x7).f[0];
2907      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / XMM(modrm & 0x7).f[1];
2908      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / XMM(modrm & 0x7).f[2];
2909      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / XMM(modrm & 0x7).f[3];
2910   } else {
2911      XMM_REG src;
2912      UINT32 ea = GetEA(modrm, 0);
2913      READXMM(ea, src);
2914      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / src.f[0];
2915      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / src.f[1];
2916      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / src.f[2];
2917      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / src.f[3];
2918   }
2919   CYCLES(1);     // TODO: correct cycle count
2920}
2921
2922void i386_device::sse_andps_r128_rm128() // Opcode 0f 54
2923{
2924   UINT8 modrm = FETCH();
2925   if( modrm >= 0xc0 ) {
2926      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & XMM(modrm & 0x7).q[0];
2927      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & XMM(modrm & 0x7).q[1];
2928   } else {
2929      XMM_REG src;
2930      UINT32 ea = GetEA(modrm, 0);
2931      READXMM(ea, src);
2932      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & src.q[0];
2933      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & src.q[1];
2934   }
2935   CYCLES(1);     // TODO: correct cycle count
2936}
2937
2938void i386_device::sse_andnps_r128_rm128() // Opcode 0f 55
2939{
2940   UINT8 modrm = FETCH();
2941   if( modrm >= 0xc0 ) {
2942      XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & XMM(modrm & 0x7).q[0];
2943      XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & XMM(modrm & 0x7).q[1];
2944   } else {
2945      XMM_REG src;
2946      UINT32 ea = GetEA(modrm, 0);
2947      READXMM(ea, src);
2948      XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & src.q[0];
2949      XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & src.q[1];
2950   }
2951   CYCLES(1);     // TODO: correct cycle count
2952}
2953
2954void i386_device::sse_orps_r128_rm128() // Opcode 0f 56
2955{
2956   UINT8 modrm = FETCH();
2957   if( modrm >= 0xc0 ) {
2958      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | XMM(modrm & 0x7).q[0];
2959      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | XMM(modrm & 0x7).q[1];
2960   } else {
2961      XMM_REG src;
2962      UINT32 ea = GetEA(modrm, 0);
2963      READXMM(ea, src);
2964      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | src.q[0];
2965      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | src.q[1];
2966   }
2967   CYCLES(1);     // TODO: correct cycle count
2968}
2969
2970void i386_device::sse_mulps() // Opcode 0f 59 ????
2971{
2972   UINT8 modrm = FETCH();
2973   if( modrm >= 0xc0 ) {
2974      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0];
2975      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] * XMM(modrm & 0x7).f[1];
2976      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * XMM(modrm & 0x7).f[2];
2977      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] * XMM(modrm & 0x7).f[3];
2978   } else {
2979      XMM_REG src;
2980      UINT32 ea = GetEA(modrm, 0);
2981      READXMM(ea, src);
2982      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * src.f[0];
2983      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] * src.f[1];
2984      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * src.f[2];
2985      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] * src.f[3];
2986   }
2987   CYCLES(1);     // TODO: correct cycle count
2988}
2989
2990void i386_device::sse_subps() // Opcode 0f 5c
2991{
2992   UINT8 modrm = FETCH();
2993   if( modrm >= 0xc0 ) {
2994      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0];
2995      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - XMM(modrm & 0x7).f[1];
2996      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - XMM(modrm & 0x7).f[2];
2997      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - XMM(modrm & 0x7).f[3];
2998   } else {
2999      XMM_REG src;
3000      UINT32 ea = GetEA(modrm, 0);
3001      READXMM(ea, src);
3002      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0];
3003      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - src.f[1];
3004      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - src.f[2];
3005      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - src.f[3];
3006   }
3007   CYCLES(1);     // TODO: correct cycle count
3008}
3009
3010INLINE float sse_min_single(float src1, float src2)
3011{
3012   /*if ((src1 == 0) && (src2 == 0))
3013       return src2;
3014   if (src1 = SNaN)
3015       return src2;
3016   if (src2 = SNaN)
3017       return src2;*/
3018   if (src1 < src2)
3019      return src1;
3020   return src2;
3021}
3022
3023void i386_device::sse_minps() // Opcode 0f 5d
3024{
3025   UINT8 modrm = FETCH();
3026   if( modrm >= 0xc0 ) {
3027      XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
3028      XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]);
3029      XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]);
3030      XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]);
3031   } else {
3032      XMM_REG src;
3033      UINT32 ea = GetEA(modrm, 0);
3034      READXMM(ea, src);
3035      XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
3036      XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]);
3037      XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]);
3038      XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]);
3039   }
3040   CYCLES(1);     // TODO: correct cycle count
3041}
3042
3043void i386_device::sse_divps() // Opcode 0f 5e
3044{
3045   UINT8 modrm = FETCH();
3046   if( modrm >= 0xc0 ) {
3047      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0];
3048      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / XMM(modrm & 0x7).f[1];
3049      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / XMM(modrm & 0x7).f[2];
3050      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / XMM(modrm & 0x7).f[3];
3051   } else {
3052      XMM_REG src;
3053      UINT32 ea = GetEA(modrm, 0);
3054      READXMM(ea, src);
3055      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0];
3056      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / src.f[1];
3057      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / src.f[2];
3058      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / src.f[3];
3059   }
3060   CYCLES(1);     // TODO: correct cycle count
3061}
3062
3063INLINE float sse_max_single(float src1, float src2)
3064{
3065   /*if ((src1 == 0) && (src2 == 0))
3066       return src2;
3067   if (src1 = SNaN)
3068       return src2;
3069   if (src2 = SNaN)
3070       return src2;*/
3071   if (src1 > src2)
3072      return src1;
3073   return src2;
3074}
3075
3076void i386_device::sse_maxps() // Opcode 0f 5f
3077{
3078   UINT8 modrm = FETCH();
3079   if( modrm >= 0xc0 ) {
3080      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
3081      XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]);
3082      XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]);
3083      XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]);
3084   } else {
3085      XMM_REG src;
3086      UINT32 ea = GetEA(modrm, 0);
3087      READXMM(ea, src);
3088      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
3089      XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]);
3090      XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]);
3091      XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]);
3092   }
3093   CYCLES(1);     // TODO: correct cycle count
3094}
3095
3096void i386_device::sse_maxss_r128_r128m32() // Opcode f3 0f 5f
3097{
3098   UINT8 modrm = FETCH();
3099   if( modrm >= 0xc0 ) {
3100      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
3101   } else {
3102      XMM_REG src;
3103      UINT32 ea = GetEA(modrm, 0);
3104      src.d[0]=READ32(ea);
3105      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
3106   }
3107   CYCLES(1);     // TODO: correct cycle count
3108}
3109
3110void i386_device::sse_addss() // Opcode f3 0f 58
3111{
3112   UINT8 modrm = FETCH();
3113   if( modrm >= 0xc0 ) {
3114      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + XMM(modrm & 0x7).f[0];
3115   } else {
3116      XMM_REG src;
3117      UINT32 ea = GetEA(modrm, 0);
3118      READXMM(ea, src);
3119      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + src.f[0];
3120   }
3121   CYCLES(1);     // TODO: correct cycle count
3122}
3123
3124void i386_device::sse_subss() // Opcode f3 0f 5c
3125{
3126   UINT8 modrm = FETCH();
3127   if( modrm >= 0xc0 ) {
3128      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0];
3129   } else {
3130      XMM_REG src;
3131      UINT32 ea = GetEA(modrm, 0);
3132      READXMM(ea, src);
3133      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0];
3134   }
3135   CYCLES(1);     // TODO: correct cycle count
3136}
3137
3138void i386_device::sse_mulss() // Opcode f3 0f 5e
3139{
3140   UINT8 modrm = FETCH();
3141   if( modrm >= 0xc0 ) {
3142      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0];
3143   } else {
3144      XMM_REG src;
3145      UINT32 ea = GetEA(modrm, 0);
3146      READXMM(ea, src);
3147      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * src.f[0];
3148   }
3149   CYCLES(1);     // TODO: correct cycle count
3150}
3151
3152void i386_device::sse_divss() // Opcode 0f 59
3153{
3154   UINT8 modrm = FETCH();
3155   if( modrm >= 0xc0 ) {
3156      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0];
3157   } else {
3158      XMM_REG src;
3159      UINT32 ea = GetEA(modrm, 0);
3160      READXMM(ea, src);
3161      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0];
3162   }
3163   CYCLES(1);     // TODO: correct cycle count
3164}
3165
3166void i386_device::sse_rcpss_r128_r128m32() // Opcode f3 0f 53
3167{
3168   UINT8 modrm = FETCH();
3169   if( modrm >= 0xc0 ) {
3170      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / XMM(modrm & 0x7).f[0];
3171   } else {
3172      XMM_REG s;
3173      UINT32 ea = GetEA(modrm, 0);
3174      s.d[0]=READ32(ea);
3175      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / s.f[0];
3176   }
3177   CYCLES(1);     // TODO: correct cycle count
3178}
3179
3180void i386_device::sse_sqrtss_r128_r128m32() // Opcode f3 0f 51
3181{
3182   UINT8 modrm = FETCH();
3183   if( modrm >= 0xc0 ) {
3184      XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]);
3185   } else {
3186      XMM_REG s;
3187      UINT32 ea = GetEA(modrm, 0);
3188      s.d[0]=READ32(ea);
3189      XMM((modrm >> 3) & 0x7).f[0] = sqrt(s.f[0]);
3190   }
3191   CYCLES(1);     // TODO: correct cycle count
3192}
3193
3194void i386_device::sse_rsqrtss_r128_r128m32() // Opcode f3 0f 52
3195{
3196   UINT8 modrm = FETCH();
3197   if( modrm >= 0xc0 ) {
3198      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]);
3199   } else {
3200      XMM_REG s;
3201      UINT32 ea = GetEA(modrm, 0);
3202      s.d[0]=READ32(ea);
3203      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(s.f[0]);
3204   }
3205   CYCLES(1);     // TODO: correct cycle count
3206}
3207
3208void i386_device::sse_minss_r128_r128m32() // Opcode f3 0f 5d
3209{
3210   UINT8 modrm = FETCH();
3211   if( modrm >= 0xc0 ) {
3212      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < XMM(modrm & 0x7).f[0] ? XMM((modrm >> 3) & 0x7).f[0] : XMM(modrm & 0x7).f[0];
3213   } else {
3214      XMM_REG s;
3215      UINT32 ea = GetEA(modrm, 0);
3216      s.d[0] = READ32(ea);
3217      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < s.f[0] ? XMM((modrm >> 3) & 0x7).f[0] : s.f[0];
3218   }
3219   CYCLES(1);     // TODO: correct cycle count
3220}
3221
3222void i386_device::sse_comiss_r128_r128m32() // Opcode 0f 2f
3223{
3224   float32 a,b;
3225   UINT8 modrm = FETCH();
3226   if( modrm >= 0xc0 ) {
3227      a = XMM((modrm >> 3) & 0x7).d[0];
3228      b = XMM(modrm & 0x7).d[0];
3229   } else {
3230      XMM_REG src;
3231      UINT32 ea = GetEA(modrm, 0);
3232      READXMM(ea, src);
3233      a = XMM((modrm >> 3) & 0x7).d[0];
3234      b = src.d[0];
3235   }
3236   m_OF=0;
3237   m_SF=0;
3238   m_AF=0;
3239   if (float32_is_nan(a) || float32_is_nan(b))
3240   {
3241      m_ZF = 1;
3242      m_PF = 1;
3243      m_CF = 1;
3244   }
3245   else
3246   {
3247      m_ZF = 0;
3248      m_PF = 0;
3249      m_CF = 0;
3250      if (float32_eq(a, b))
3251         m_ZF = 1;
3252      if (float32_lt(a, b))
3253         m_CF = 1;
3254   }
3255   // should generate exception when at least one of the operands is either QNaN or SNaN
3256   CYCLES(1);     // TODO: correct cycle count
3257}
3258
3259void i386_device::sse_ucomiss_r128_r128m32() // Opcode 0f 2e
3260{
3261   float32 a,b;
3262   UINT8 modrm = FETCH();
3263   if( modrm >= 0xc0 ) {
3264      a = XMM((modrm >> 3) & 0x7).d[0];
3265      b = XMM(modrm & 0x7).d[0];
3266   } else {
3267      XMM_REG src;
3268      UINT32 ea = GetEA(modrm, 0);
3269      READXMM(ea, src);
3270      a = XMM((modrm >> 3) & 0x7).d[0];
3271      b = src.d[0];
3272   }
3273   m_OF=0;
3274   m_SF=0;
3275   m_AF=0;
3276   if (float32_is_nan(a) || float32_is_nan(b))
3277   {
3278      m_ZF = 1;
3279      m_PF = 1;
3280      m_CF = 1;
3281   }
3282   else
3283   {
3284      m_ZF = 0;
3285      m_PF = 0;
3286      m_CF = 0;
3287      if (float32_eq(a, b))
3288         m_ZF = 1;
3289      if (float32_lt(a, b))
3290         m_CF = 1;
3291   }
3292   // should generate exception when at least one of the operands is SNaN
3293   CYCLES(1);     // TODO: correct cycle count
3294}
3295
3296void i386_device::sse_shufps() // Opcode 0f 67
3297{
3298   UINT8 modrm = FETCH();
3299   UINT8 sel = FETCH();
3300   int m1,m2,m3,m4;
3301   int s,d;
3302   m1=sel & 3;
3303   m2=(sel >> 2) & 3;
3304   m3=(sel >> 4) & 3;
3305   m4=(sel >> 6) & 3;
3306   s=modrm & 0x7;
3307   d=(modrm >> 3) & 0x7;
3308   if( modrm >= 0xc0 ) {
3309      UINT32 t;
3310      t=XMM(d).d[m1];
3311      XMM(d).d[1]=XMM(d).d[m2];
3312      XMM(d).d[0]=t;
3313      XMM(d).d[2]=XMM(s).d[m3];
3314      XMM(d).d[3]=XMM(s).d[m4];
3315   } else {
3316      UINT32 t;
3317      XMM_REG src;
3318      UINT32 ea = GetEA(modrm, 0);
3319      READXMM(ea, src);
3320      t=XMM(d).d[m1];
3321      XMM(d).d[1]=XMM(d).d[m2];
3322      XMM(d).d[0]=t;
3323      XMM(d).d[2]=src.d[m3];
3324      XMM(d).d[3]=src.d[m4];
3325   }
3326   CYCLES(1);     // TODO: correct cycle count
3327}
3328
3329void i386_device::sse_unpcklps_r128_rm128() // Opcode 0f 14
3330{
3331   UINT8 modrm = FETCH();
3332   int s,d;
3333   s=modrm & 0x7;
3334   d=(modrm >> 3) & 0x7;
3335   if( modrm >= 0xc0 ) {
3336      XMM(d).d[3]=XMM(s).d[1];
3337      XMM(d).d[2]=XMM(d).d[1];
3338      XMM(d).d[1]=XMM(s).d[0];
3339      //XMM(d).d[0]=XMM(d).d[0];
3340   } else {
3341      XMM_REG src;
3342      UINT32 ea = GetEA(modrm, 0);
3343      READXMM(ea, src);
3344      XMM(d).d[3]=src.d[1];
3345      XMM(d).d[2]=XMM(d).d[1];
3346      XMM(d).d[1]=src.d[0];
3347   }
3348   CYCLES(1);     // TODO: correct cycle count
3349}
3350
3351void i386_device::sse_unpckhps_r128_rm128() // Opcode 0f 15
3352{
3353   UINT8 modrm = FETCH();
3354   int s,d;
3355   s=modrm & 0x7;
3356   d=(modrm >> 3) & 0x7;
3357   if( modrm >= 0xc0 ) {
3358      XMM(d).d[0]=XMM(d).d[2];
3359      XMM(d).d[1]=XMM(s).d[2];
3360      XMM(d).d[2]=XMM(d).d[3];
3361      XMM(d).d[3]=XMM(s).d[3];
3362   } else {
3363      XMM_REG src;
3364      UINT32 ea = GetEA(modrm, 0);
3365      READXMM(ea, src);
3366      XMM(d).d[0]=XMM(d).d[2];
3367      XMM(d).d[1]=src.d[2];
3368      XMM(d).d[2]=XMM(d).d[3];
3369      XMM(d).d[3]=src.d[3];
3370   }
3371   CYCLES(1);     // TODO: correct cycle count
3372}
3373
3374INLINE bool sse_issingleordered(float op1, float op2)
3375{
3376   // TODO: true when at least one of the two source operands being compared is a NaN
3377   return (op1 != op1) || (op1 != op2);
3378}
3379
3380INLINE bool sse_issingleunordered(float op1, float op2)
3381{
3382   // TODO: true when neither source operand is a NaN
3383   return !((op1 != op1) || (op1 != op2));
3384}
3385
3386void i386_device::sse_predicate_compare_single(UINT8 imm8, XMM_REG d, XMM_REG s)
3387{
3388   switch (imm8 & 7)
3389   {
3390   case 0:
3391      s.d[0]=s.f[0] == s.f[0] ? 0xffffffff : 0;
3392      d.d[1]=d.f[1] == s.f[1] ? 0xffffffff : 0;
3393      d.d[2]=d.f[2] == s.f[2] ? 0xffffffff : 0;
3394      d.d[3]=d.f[3] == s.f[3] ? 0xffffffff : 0;
3395      break;
3396   case 1:
3397      d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0;
3398      d.d[1]=d.f[1] < s.f[1] ? 0xffffffff : 0;
3399      d.d[2]=d.f[2] < s.f[2] ? 0xffffffff : 0;
3400      d.d[3]=d.f[3] < s.f[3] ? 0xffffffff : 0;
3401      break;
3402   case 2:
3403      d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0;
3404      d.d[1]=d.f[1] <= s.f[1] ? 0xffffffff : 0;
3405      d.d[2]=d.f[2] <= s.f[2] ? 0xffffffff : 0;
3406      d.d[3]=d.f[3] <= s.f[3] ? 0xffffffff : 0;
3407      break;
3408   case 3:
3409      d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3410      d.d[1]=sse_issingleunordered(d.f[1], s.f[1]) ? 0xffffffff : 0;
3411      d.d[2]=sse_issingleunordered(d.f[2], s.f[2]) ? 0xffffffff : 0;
3412      d.d[3]=sse_issingleunordered(d.f[3], s.f[3]) ? 0xffffffff : 0;
3413      break;
3414   case 4:
3415      d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0;
3416      d.d[1]=d.f[1] != s.f[1] ? 0xffffffff : 0;
3417      d.d[2]=d.f[2] != s.f[2] ? 0xffffffff : 0;
3418      d.d[3]=d.f[3] != s.f[3] ? 0xffffffff : 0;
3419      break;
3420   case 5:
3421      d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff;
3422      d.d[1]=d.f[1] < s.f[1] ? 0 : 0xffffffff;
3423      d.d[2]=d.f[2] < s.f[2] ? 0 : 0xffffffff;
3424      d.d[3]=d.f[3] < s.f[3] ? 0 : 0xffffffff;
3425      break;
3426   case 6:
3427      d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff;
3428      d.d[1]=d.f[1] <= s.f[1] ? 0 : 0xffffffff;
3429      d.d[2]=d.f[2] <= s.f[2] ? 0 : 0xffffffff;
3430      d.d[3]=d.f[3] <= s.f[3] ? 0 : 0xffffffff;
3431      break;
3432   case 7:
3433      d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3434      d.d[1]=sse_issingleordered(d.f[1], s.f[1]) ? 0xffffffff : 0;
3435      d.d[2]=sse_issingleordered(d.f[2], s.f[2]) ? 0xffffffff : 0;
3436      d.d[3]=sse_issingleordered(d.f[3], s.f[3]) ? 0xffffffff : 0;
3437      break;
3438   }
3439}
3440
3441void i386_device::sse_predicate_compare_single_scalar(UINT8 imm8, XMM_REG d, XMM_REG s)
3442{
3443   switch (imm8 & 7)
3444   {
3445   case 0:
3446      s.d[0]=s.f[0] == s.f[0] ? 0xffffffff : 0;
3447      break;
3448   case 1:
3449      d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0;
3450      break;
3451   case 2:
3452      d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0;
3453      break;
3454   case 3:
3455      d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3456      break;
3457   case 4:
3458      d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0;
3459      break;
3460   case 5:
3461      d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff;
3462      break;
3463   case 6:
3464      d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff;
3465      break;
3466   case 7:
3467      d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3468      break;
3469   }
3470}
3471
3472void i386_device::sse_cmpps_r128_rm128_i8() // Opcode 0f c2
3473{
3474   UINT8 modrm = FETCH();
3475   if( modrm >= 0xc0 ) {
3476      int s,d;
3477      UINT8 imm8 = FETCH();
3478      s=modrm & 0x7;
3479      d=(modrm >> 3) & 0x7;
3480      sse_predicate_compare_single(imm8, XMM(d), XMM(s));
3481   } else {
3482      int d;
3483      XMM_REG s;
3484      UINT32 ea = GetEA(modrm, 0);
3485      UINT8 imm8 = FETCH();
3486      READXMM(ea, s);
3487      d=(modrm >> 3) & 0x7;
3488      sse_predicate_compare_single(imm8, XMM(d), s);
3489   }
3490   CYCLES(1);     // TODO: correct cycle count
3491}
3492
3493void i386_device::sse_cmpss_r128_r128m32_i8() // Opcode f3 0f c2
3494{
3495   UINT8 modrm = FETCH();
3496   if( modrm >= 0xc0 ) {
3497      int s,d;
3498      UINT8 imm8 = FETCH();
3499      s=modrm & 0x7;
3500      d=(modrm >> 3) & 0x7;
3501      sse_predicate_compare_single_scalar(imm8, XMM(d), XMM(s));
3502   } else {
3503      int d;
3504      XMM_REG s;
3505      UINT32 ea = GetEA(modrm, 0);
3506      UINT8 imm8 = FETCH();
3507      s.d[0]=READ32(ea);
3508      d=(modrm >> 3) & 0x7;
3509      sse_predicate_compare_single_scalar(imm8, XMM(d), s);
3510   }
3511   CYCLES(1);     // TODO: correct cycle count
3512}
3513
3514void i386_device::sse_pinsrw_r64_r16m16_i8() // Opcode 0f c4
3515{
3516   MMXPROLOG();
3517   UINT8 modrm = FETCH();
3518   if( modrm >= 0xc0 ) {
3519      UINT8 imm8 = FETCH();
3520      UINT16 v = LOAD_RM16(modrm);
3521      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3522   } else {
3523      UINT32 ea = GetEA(modrm, 0);
3524      UINT8 imm8 = FETCH();
3525      UINT16 v = READ16(ea);
3526      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3527   }
3528   CYCLES(1);     // TODO: correct cycle count
3529}
3530
3531void i386_device::sse_pinsrw_r64_r32m16_i8() // Opcode 0f c4
3532{
3533   MMXPROLOG();
3534   UINT8 modrm = FETCH();
3535   if( modrm >= 0xc0 ) {
3536      UINT8 imm8 = FETCH();
3537      UINT16 v = (UINT16)LOAD_RM32(modrm);
3538      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3539   } else {
3540      UINT32 ea = GetEA(modrm, 0);
3541      UINT8 imm8 = FETCH();
3542      UINT16 v = READ16(ea);
3543      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3544   }
3545   CYCLES(1);     // TODO: correct cycle count
3546}
3547
3548void i386_device::sse_pextrw_r16_r64_i8() // Opcode 0f c5
3549{
3550   //MMXPROLOG();
3551   UINT8 modrm = FETCH();
3552   if( modrm >= 0xc0 ) {
3553      UINT8 imm8 = FETCH();
3554      STORE_REG16(modrm, MMX(modrm & 0x7).w[imm8 & 3]);
3555   } else {
3556      //UINT8 imm8 = FETCH();
3557      report_invalid_modrm("pextrw_r16_r64_i8", modrm);
3558   }
3559   CYCLES(1);     // TODO: correct cycle count
3560}
3561
3562void i386_device::sse_pextrw_r32_r64_i8() // Opcode 0f c5
3563{
3564   //MMXPROLOG();
3565   UINT8 modrm = FETCH();
3566   if( modrm >= 0xc0 ) {
3567      UINT8 imm8 = FETCH();
3568      STORE_REG32(modrm, MMX(modrm & 0x7).w[imm8 & 3]);
3569   } else {
3570      //UINT8 imm8 = FETCH();
3571      report_invalid_modrm("pextrw_r32_r64_i8", modrm);
3572   }
3573   CYCLES(1);     // TODO: correct cycle count
3574}
3575
3576void i386_device::sse_pminub_r64_rm64() // Opcode 0f da
3577{
3578   int n;
3579   MMXPROLOG();
3580   UINT8 modrm = FETCH();
3581   if( modrm >= 0xc0 ) {
3582      for (n=0;n < 8;n++)
3583         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n];
3584   } else {
3585      MMX_REG s;
3586      UINT32 ea = GetEA(modrm, 0);
3587      READMMX(ea, s);
3588      for (n=0;n < 8;n++)
3589         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n];
3590   }
3591   CYCLES(1);     // TODO: correct cycle count
3592}
3593
3594void i386_device::sse_pmaxub_r64_rm64() // Opcode 0f de
3595{
3596   int n;
3597   MMXPROLOG();
3598   UINT8 modrm = FETCH();
3599   if( modrm >= 0xc0 ) {
3600      for (n=0;n < 8;n++)
3601         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n];
3602   } else {
3603      MMX_REG s;
3604      UINT32 ea = GetEA(modrm, 0);
3605      READMMX(ea, s);
3606      for (n=0;n < 8;n++)
3607         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n];
3608   }
3609   CYCLES(1);     // TODO: correct cycle count
3610}
3611
3612void i386_device::sse_pavgb_r64_rm64() // Opcode 0f e0
3613{
3614   int n;
3615   MMXPROLOG();
3616   UINT8 modrm = FETCH();
3617   if( modrm >= 0xc0 ) {
3618      for (n=0;n < 8;n++)
3619         MMX((modrm >> 3) & 0x7).b[n] = ((UINT16)MMX((modrm >> 3) & 0x7).b[n] + (UINT16)MMX(modrm & 0x7).b[n] + 1) >> 1;
3620   } else {
3621      MMX_REG s;
3622      UINT32 ea = GetEA(modrm, 0);
3623      READMMX(ea, s);
3624      for (n=0;n < 8;n++)
3625         MMX((modrm >> 3) & 0x7).b[n] = ((UINT16)MMX((modrm >> 3) & 0x7).b[n] + (UINT16)s.b[n] + 1) >> 1;
3626   }
3627   CYCLES(1);     // TODO: correct cycle count
3628}
3629
3630void i386_device::sse_pavgw_r64_rm64() // Opcode 0f e3
3631{
3632   int n;
3633   MMXPROLOG();
3634   UINT8 modrm = FETCH();
3635   if( modrm >= 0xc0 ) {
3636      for (n=0;n < 4;n++)
3637         MMX((modrm >> 3) & 0x7).w[n] = ((UINT32)MMX((modrm >> 3) & 0x7).w[n] + (UINT32)MMX(modrm & 0x7).w[n] + 1) >> 1;
3638   } else {
3639      MMX_REG s;
3640      UINT32 ea = GetEA(modrm, 0);
3641      READMMX(ea, s);
3642      for (n=0;n < 4;n++)
3643         MMX((modrm >> 3) & 0x7).w[n] = ((UINT32)MMX((modrm >> 3) & 0x7).w[n] + (UINT32)s.w[n] + 1) >> 1;
3644   }
3645   CYCLES(1);     // TODO: correct cycle count
3646}
3647
3648void i386_device::sse_pmulhuw_r64_rm64()  // Opcode 0f e4
3649{
3650   MMXPROLOG();
3651   UINT8 modrm = FETCH();
3652   if( modrm >= 0xc0 ) {
3653      MMX((modrm >> 3) & 0x7).w[0]=((UINT32)MMX((modrm >> 3) & 0x7).w[0]*(UINT32)MMX(modrm & 7).w[0]) >> 16;
3654      MMX((modrm >> 3) & 0x7).w[1]=((UINT32)MMX((modrm >> 3) & 0x7).w[1]*(UINT32)MMX(modrm & 7).w[1]) >> 16;
3655      MMX((modrm >> 3) & 0x7).w[2]=((UINT32)MMX((modrm >> 3) & 0x7).w[2]*(UINT32)MMX(modrm & 7).w[2]) >> 16;
3656      MMX((modrm >> 3) & 0x7).w[3]=((UINT32)MMX((modrm >> 3) & 0x7).w[3]*(UINT32)MMX(modrm & 7).w[3]) >> 16;
3657   } else {
3658      MMX_REG s;
3659      UINT32 ea = GetEA(modrm, 0);
3660      READMMX(ea, s);
3661      MMX((modrm >> 3) & 0x7).w[0]=((UINT32)MMX((modrm >> 3) & 0x7).w[0]*(UINT32)s.w[0]) >> 16;
3662      MMX((modrm >> 3) & 0x7).w[1]=((UINT32)MMX((modrm >> 3) & 0x7).w[1]*(UINT32)s.w[1]) >> 16;
3663      MMX((modrm >> 3) & 0x7).w[2]=((UINT32)MMX((modrm >> 3) & 0x7).w[2]*(UINT32)s.w[2]) >> 16;
3664      MMX((modrm >> 3) & 0x7).w[3]=((UINT32)MMX((modrm >> 3) & 0x7).w[3]*(UINT32)s.w[3]) >> 16;
3665   }
3666   CYCLES(1);     // TODO: correct cycle count
3667}
3668
3669void i386_device::sse_pminsw_r64_rm64() // Opcode 0f ea
3670{
3671   int n;
3672   MMXPROLOG();
3673   UINT8 modrm = FETCH();
3674   if( modrm >= 0xc0 ) {
3675      for (n=0;n < 4;n++)
3676         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n];
3677   } else {
3678      MMX_REG s;
3679      UINT32 ea = GetEA(modrm, 0);
3680      READMMX(ea, s);
3681      for (n=0;n < 4;n++)
3682         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n];
3683   }
3684   CYCLES(1);     // TODO: correct cycle count
3685}
3686
3687void i386_device::sse_pmaxsw_r64_rm64() // Opcode 0f ee
3688{
3689   int n;
3690   MMXPROLOG();
3691   UINT8 modrm = FETCH();
3692   if( modrm >= 0xc0 ) {
3693      for (n=0;n < 4;n++)
3694         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n];
3695   } else {
3696      MMX_REG s;
3697      UINT32 ea = GetEA(modrm, 0);
3698      READMMX(ea, s);
3699      for (n=0;n < 4;n++)
3700         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n];
3701   }
3702   CYCLES(1);     // TODO: correct cycle count
3703}
3704
3705void i386_device::sse_pmuludq_r64_rm64() // Opcode 0f f4
3706{
3707   MMXPROLOG();
3708   UINT8 modrm = FETCH();
3709   if( modrm >= 0xc0 ) {
3710      MMX((modrm >> 3) & 0x7).q = (UINT64)MMX((modrm >> 3) & 0x7).d[0] * (UINT64)MMX(modrm & 0x7).d[0];
3711   } else {
3712      MMX_REG s;
3713      UINT32 ea = GetEA(modrm, 0);
3714      READMMX(ea, s);
3715      MMX((modrm >> 3) & 0x7).q = (UINT64)MMX((modrm >> 3) & 0x7).d[0] * (UINT64)s.d[0];
3716   }
3717   CYCLES(1);     // TODO: correct cycle count
3718}
3719
3720void i386_device::sse_psadbw_r64_rm64() // Opcode 0f f6
3721{
3722   int n;
3723   INT32 temp;
3724   MMXPROLOG();
3725   UINT8 modrm = FETCH();
3726   if( modrm >= 0xc0 ) {
3727      temp=0;
3728      for (n=0;n < 8;n++)
3729         temp += abs((INT32)MMX((modrm >> 3) & 0x7).b[n] - (INT32)MMX(modrm & 0x7).b[n]);
3730      MMX((modrm >> 3) & 0x7).l=(UINT64)temp & 0xffff;
3731   } else {
3732      MMX_REG s;
3733      UINT32 ea = GetEA(modrm, 0);
3734      READMMX(ea, s);
3735      temp=0;
3736      for (n=0;n < 8;n++)
3737         temp += abs((INT32)MMX((modrm >> 3) & 0x7).b[n] - (INT32)s.b[n]);
3738      MMX((modrm >> 3) & 0x7).l=(UINT64)temp & 0xffff;
3739   }
3740   CYCLES(1);     // TODO: correct cycle count
3741}
3742
3743void i386_device::sse_psubq_r64_rm64()  // Opcode 0f fb
3744{
3745   MMXPROLOG();
3746   UINT8 modrm = FETCH();
3747   if( modrm >= 0xc0 ) {
3748      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - MMX(modrm & 7).q;
3749   } else {
3750      MMX_REG s;
3751      UINT32 ea = GetEA(modrm, 0);
3752      READMMX(ea, s);
3753      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - s.q;
3754   }
3755   CYCLES(1);     // TODO: correct cycle count
3756}
3757
3758void i386_device::sse_pshufhw_r128_rm128_i8() // Opcode f3 0f 70
3759{
3760   UINT8 modrm = FETCH();
3761   if( modrm >= 0xc0 ) {
3762      XMM_REG t;
3763      int s,d;
3764      UINT8 imm8 = FETCH();
3765      s=modrm & 0x7;
3766      d=(modrm >> 3) & 0x7;
3767      t.q[0]=XMM(s).q[1];
3768      XMM(d).q[0]=XMM(s).q[0];
3769      XMM(d).w[4]=t.w[imm8 & 3];
3770      XMM(d).w[5]=t.w[(imm8 >> 2) & 3];
3771      XMM(d).w[6]=t.w[(imm8 >> 4) & 3];
3772      XMM(d).w[7]=t.w[(imm8 >> 6) & 3];
3773   } else {
3774      XMM_REG s;
3775      int d=(modrm >> 3) & 0x7;
3776      UINT32 ea = GetEA(modrm, 0);
3777      UINT8 imm8 = FETCH();
3778      READXMM(ea, s);
3779      XMM(d).q[0]=s.q[0];
3780      XMM(d).w[4]=s.w[4 + (imm8 & 3)];
3781      XMM(d).w[5]=s.w[4 + ((imm8 >> 2) & 3)];
3782      XMM(d).w[6]=s.w[4 + ((imm8 >> 4) & 3)];
3783      XMM(d).w[7]=s.w[4 + ((imm8 >> 6) & 3)];
3784   }
3785   CYCLES(1);     // TODO: correct cycle count
3786}
Property changes on: trunk/src/emu/cpu/i386/pentops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/i386/x87ops.inc
r0r28739
1/***************************************************************************
2
3    x87 FPU emulation
4
5    TODO:
6     - 80-bit precision for F2XM1, FYL2X, FPATAN
7     - Figure out why SoftFloat trig extensions produce bad values
8     - Cycle counts for all processors (currently using 486 counts)
9     - Precision-dependent cycle counts for divide instructions
10     - Last instruction, operand pointers etc.
11     - Fix FLDENV, FSTENV, FSAVE, FRSTOR and FPREM
12     - Status word C2 updates to reflect round up/down
13     - Handling of invalid and denormal numbers
14     - Remove redundant operand checks
15     - Exceptions
16
17***************************************************************************/
18
19#include <math.h>
20
21
22/*************************************
23 *
24 * Defines
25 *
26 *************************************/
27
28#define X87_SW_IE               0x0001
29#define X87_SW_DE               0x0002
30#define X87_SW_ZE               0x0004
31#define X87_SW_OE               0x0008
32#define X87_SW_UE               0x0010
33#define X87_SW_PE               0x0020
34#define X87_SW_SF               0x0040
35#define X87_SW_ES               0x0080
36#define X87_SW_C0               0x0100
37#define X87_SW_C1               0x0200
38#define X87_SW_C2               0x0400
39#define X87_SW_TOP_SHIFT        11
40#define X87_SW_TOP_MASK         7
41#define X87_SW_C3               0x4000
42#define X87_SW_BUSY             0x8000
43
44#define X87_CW_IM               0x0001
45#define X87_CW_DM               0x0002
46#define X87_CW_ZM               0x0004
47#define X87_CW_OM               0x0008
48#define X87_CW_UM               0x0010
49#define X87_CW_PM               0x0020
50#define X87_CW_PC_SHIFT         8
51#define X87_CW_PC_MASK          3
52#define X87_CW_PC_SINGLE        0
53#define X87_CW_PC_DOUBLE        2
54#define X87_CW_PC_EXTEND        3
55#define X87_CW_RC_SHIFT         10
56#define X87_CW_RC_MASK          3
57#define X87_CW_RC_NEAREST       0
58#define X87_CW_RC_DOWN          1
59#define X87_CW_RC_UP            2
60#define X87_CW_RC_ZERO          3
61
62#define X87_TW_MASK             3
63#define X87_TW_VALID            0
64#define X87_TW_ZERO             1
65#define X87_TW_SPECIAL          2
66#define X87_TW_EMPTY            3
67
68
69/*************************************
70 *
71 * Macros
72 *
73 *************************************/
74
75#define ST_TO_PHYS(x)           (((m_x87_sw >> X87_SW_TOP_SHIFT) + (x)) & X87_SW_TOP_MASK)
76#define ST(x)                   (m_x87_reg[ST_TO_PHYS(x)])
77#define X87_TW_FIELD_SHIFT(x)   ((x) << 1)
78#define X87_TAG(x)              ((m_x87_tw >> X87_TW_FIELD_SHIFT(x)) & X87_TW_MASK)
79#define X87_RC                  ((m_x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK)
80#define X87_IS_ST_EMPTY(x)      (X87_TAG(ST_TO_PHYS(x)) == X87_TW_EMPTY)
81#define X87_SW_C3_0             X87_SW_C0
82
83#define UNIMPLEMENTED           fatalerror("Unimplemented x87 op: %s (PC:%x)\n", __FUNCTION__, m_pc)
84
85
86/*************************************
87 *
88 * Constants
89 *
90 *************************************/
91
92static const floatx80 fx80_zero =   { 0x0000, U64(0x0000000000000000) };
93static const floatx80 fx80_one =    { 0x3fff, U64(0x8000000000000000) };
94
95static const floatx80 fx80_ninf =   { 0xffff, U64(0x8000000000000000) };
96static const floatx80 fx80_inan =   { 0xffff, U64(0xc000000000000000) };
97
98/* Maps x87 round modes to SoftFloat round modes */
99static const int x87_to_sf_rc[4] =
100{
101   float_round_nearest_even,
102   float_round_down,
103   float_round_up,
104   float_round_to_zero,
105};
106
107
108/*************************************
109 *
110 * SoftFloat helpers
111 *
112 *************************************/
113
114extern flag floatx80_is_nan( floatx80 a );
115
116INLINE int floatx80_is_zero(floatx80 fx)
117{
118   return (((fx.high & 0x7fff) == 0) && ((fx.low << 1) == 0));
119}
120
121INLINE int floatx80_is_inf(floatx80 fx)
122{
123   return (((fx.high & 0x7fff) == 0x7fff) && ((fx.low << 1) == 0));
124}
125
126INLINE int floatx80_is_denormal(floatx80 fx)
127{
128   return (((fx.high & 0x7fff) == 0) &&
129         ((fx.low & U64(0x8000000000000000)) == 0) &&
130         ((fx.low << 1) != 0));
131}
132
133INLINE floatx80 floatx80_abs(floatx80 fx)
134{
135   fx.high &= 0x7fff;
136   return fx;
137}
138
139INLINE double fx80_to_double(floatx80 fx)
140{
141   UINT64 d = floatx80_to_float64(fx);
142   return *(double*)&d;
143}
144
145INLINE floatx80 double_to_fx80(double in)
146{
147   return float64_to_floatx80(*(UINT64*)&in);
148}
149
150floatx80 i386_device::READ80(UINT32 ea)
151{
152   floatx80 t;
153
154   t.low = READ64(ea);
155   t.high = READ16(ea + 8);
156
157   return t;
158}
159
160void i386_device::WRITE80(UINT32 ea, floatx80 t)
161{
162   WRITE64(ea, t.low);
163   WRITE16(ea + 8, t.high);
164}
165
166
167/*************************************
168 *
169 * x87 stack handling
170 *
171 *************************************/
172
173void i386_device::x87_set_stack_top(int top)
174{
175   m_x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT);
176   m_x87_sw |= (top << X87_SW_TOP_SHIFT);
177}
178
179void i386_device::x87_set_tag(int reg, int tag)
180{
181   int shift = X87_TW_FIELD_SHIFT(reg);
182
183   m_x87_tw &= ~(X87_TW_MASK << shift);
184   m_x87_tw |= (tag << shift);
185}
186
187void i386_device::x87_write_stack(int i, floatx80 value, int update_tag)
188{
189   ST(i) = value;
190
191   if (update_tag)
192   {
193      int tag;
194
195      if (floatx80_is_zero(value))
196      {
197         tag = X87_TW_ZERO;
198      }
199      else if (floatx80_is_inf(value) || floatx80_is_nan(value))
200      {
201         tag = X87_TW_SPECIAL;
202      }
203      else
204      {
205         tag = X87_TW_VALID;
206      }
207
208      x87_set_tag(ST_TO_PHYS(i), tag);
209   }
210}
211
212void i386_device::x87_set_stack_underflow()
213{
214   m_x87_sw |= X87_SW_C1 | X87_SW_IE | X87_SW_SF;
215}
216
217void i386_device::x87_set_stack_overflow()
218{
219   m_x87_sw &= ~X87_SW_C1;
220   m_x87_sw |= X87_SW_IE | X87_SW_SF;
221}
222
223int i386_device::x87_inc_stack()
224{
225   int ret = 1;
226
227   // Check for stack underflow
228   if (X87_IS_ST_EMPTY(0))
229   {
230      ret = 0;
231      x87_set_stack_underflow();
232
233      // Don't update the stack if the exception is unmasked
234      if (~m_x87_cw & X87_CW_IM)
235         return ret;
236   }
237
238   x87_set_tag(ST_TO_PHYS(0), X87_TW_EMPTY);
239   x87_set_stack_top(ST_TO_PHYS(1));
240   return ret;
241}
242
243int i386_device::x87_dec_stack()
244{
245   int ret = 1;
246
247   // Check for stack overflow
248   if (!X87_IS_ST_EMPTY(7))
249   {
250      ret = 0;
251      x87_set_stack_overflow();
252
253      // Don't update the stack if the exception is unmasked
254      if (~m_x87_cw & X87_CW_IM)
255         return ret;
256   }
257
258   x87_set_stack_top(ST_TO_PHYS(7));
259   return ret;
260}
261
262
263/*************************************
264 *
265 * Exception handling
266 *
267 *************************************/
268
269int i386_device::x87_check_exceptions()
270{
271   /* Update the exceptions from SoftFloat */
272   if (float_exception_flags & float_flag_invalid)
273   {
274      m_x87_sw |= X87_SW_IE;
275      float_exception_flags &= ~float_flag_invalid;
276   }
277   if (float_exception_flags & float_flag_overflow)
278   {
279      m_x87_sw |= X87_SW_OE;
280      float_exception_flags &= ~float_flag_overflow;
281   }
282   if (float_exception_flags & float_flag_underflow)
283   {
284      m_x87_sw |= X87_SW_UE;
285      float_exception_flags &= ~float_flag_underflow;
286   }
287   if (float_exception_flags & float_flag_inexact)
288   {
289      m_x87_sw |= X87_SW_PE;
290      float_exception_flags &= ~float_flag_inexact;
291   }
292
293   if ((m_x87_sw & ~m_x87_cw) & 0x3f)
294   {
295      // m_device->execute().set_input_line(INPUT_LINE_FERR, RAISE_LINE);
296      logerror("Unmasked x87 exception (CW:%.4x, SW:%.4x)\n", m_x87_cw, m_x87_sw);
297      if (m_cr[0] & 0x20) // FIXME: 486 and up only
298      {
299         m_ext = 1;
300         i386_trap(FAULT_MF, 0, 0);
301      }
302      return 0;
303   }
304
305   return 1;
306}
307
308void i386_device::x87_write_cw(UINT16 cw)
309{
310   m_x87_cw = cw;
311
312   /* Update the SoftFloat rounding mode */
313   float_rounding_mode = x87_to_sf_rc[(m_x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK];
314}
315
316void i386_device::x87_reset()
317{
318   x87_write_cw(0x0037f);
319
320   m_x87_sw = 0;
321   m_x87_tw = 0xffff;
322
323   // TODO: FEA=0, FDS=0, FIP=0 FOP=0 FCS=0
324   m_x87_data_ptr = 0;
325   m_x87_inst_ptr = 0;
326   m_x87_opcode = 0;
327}
328
329
330/*************************************
331 *
332 * Core arithmetic
333 *
334 *************************************/
335
336floatx80 i386_device::x87_add(floatx80 a, floatx80 b)
337{
338   floatx80 result = { 0 };
339
340   switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
341   {
342      case X87_CW_PC_SINGLE:
343      {
344         float32 a32 = floatx80_to_float32(a);
345         float32 b32 = floatx80_to_float32(b);
346         result = float32_to_floatx80(float32_add(a32, b32));
347         break;
348      }
349      case X87_CW_PC_DOUBLE:
350      {
351         float64 a64 = floatx80_to_float64(a);
352         float64 b64 = floatx80_to_float64(b);
353         result = float64_to_floatx80(float64_add(a64, b64));
354         break;
355      }
356      case X87_CW_PC_EXTEND:
357      {
358         result = floatx80_add(a, b);
359         break;
360      }
361   }
362
363   return result;
364}
365
366floatx80 i386_device::x87_sub(floatx80 a, floatx80 b)
367{
368   floatx80 result = { 0 };
369
370   switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
371   {
372      case X87_CW_PC_SINGLE:
373      {
374         float32 a32 = floatx80_to_float32(a);
375         float32 b32 = floatx80_to_float32(b);
376         result = float32_to_floatx80(float32_sub(a32, b32));
377         break;
378      }
379      case X87_CW_PC_DOUBLE:
380      {
381         float64 a64 = floatx80_to_float64(a);
382         float64 b64 = floatx80_to_float64(b);
383         result = float64_to_floatx80(float64_sub(a64, b64));
384         break;
385      }
386      case X87_CW_PC_EXTEND:
387      {
388         result = floatx80_sub(a, b);
389         break;
390      }
391   }
392
393   return result;
394}
395
396floatx80 i386_device::x87_mul(floatx80 a, floatx80 b)
397{
398   floatx80 val = { 0 };
399
400   switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
401   {
402      case X87_CW_PC_SINGLE:
403      {
404         float32 a32 = floatx80_to_float32(a);
405         float32 b32 = floatx80_to_float32(b);
406         val = float32_to_floatx80(float32_mul(a32, b32));
407         break;
408      }
409      case X87_CW_PC_DOUBLE:
410      {
411         float64 a64 = floatx80_to_float64(a);
412         float64 b64 = floatx80_to_float64(b);
413         val = float64_to_floatx80(float64_mul(a64, b64));
414         break;
415      }
416      case X87_CW_PC_EXTEND:
417      {
418         val = floatx80_mul(a, b);
419         break;
420      }
421   }
422
423   return val;
424}
425
426
427floatx80 i386_device::x87_div(floatx80 a, floatx80 b)
428{
429   floatx80 val = { 0 };
430
431   switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
432   {
433      case X87_CW_PC_SINGLE:
434      {
435         float32 a32 = floatx80_to_float32(a);
436         float32 b32 = floatx80_to_float32(b);
437         val = float32_to_floatx80(float32_div(a32, b32));
438         break;
439      }
440      case X87_CW_PC_DOUBLE:
441      {
442         float64 a64 = floatx80_to_float64(a);
443         float64 b64 = floatx80_to_float64(b);
444         val = float64_to_floatx80(float64_div(a64, b64));
445         break;
446      }
447      case X87_CW_PC_EXTEND:
448      {
449         val = floatx80_div(a, b);
450         break;
451      }
452   }
453   return val;
454}
455
456
457/*************************************
458 *
459 * Instructions
460 *
461 *************************************/
462
463/*************************************
464 *
465 * Add
466 *
467 *************************************/
468
469void i386_device::x87_fadd_m32real(UINT8 modrm)
470{
471   floatx80 result;
472
473   UINT32 ea = GetEA(modrm, 0);
474   if (X87_IS_ST_EMPTY(0))
475   {
476      x87_set_stack_underflow();
477      result = fx80_inan;
478   }
479   else
480   {
481      UINT32 m32real = READ32(ea);
482
483      floatx80 a = ST(0);
484      floatx80 b = float32_to_floatx80(m32real);
485
486      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
487      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
488      {
489         m_x87_sw |= X87_SW_IE;
490         result = fx80_inan;
491      }
492      else
493      {
494         result = x87_add(a, b);
495      }
496   }
497
498   if (x87_check_exceptions())
499      x87_write_stack(0, result, TRUE);
500
501   CYCLES(8);
502}
503
504void i386_device::x87_fadd_m64real(UINT8 modrm)
505{
506   floatx80 result;
507
508   UINT32 ea = GetEA(modrm, 0);
509   if (X87_IS_ST_EMPTY(0))
510   {
511      x87_set_stack_underflow();
512      result = fx80_inan;
513   }
514   else
515   {
516      UINT64 m64real = READ64(ea);
517
518      floatx80 a = ST(0);
519      floatx80 b = float64_to_floatx80(m64real);
520
521      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
522      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
523      {
524         m_x87_sw |= X87_SW_IE;
525         result = fx80_inan;
526      }
527      else
528      {
529         result = x87_add(a, b);
530      }
531   }
532
533   if (x87_check_exceptions())
534      x87_write_stack(0, result, TRUE);
535
536   CYCLES(8);
537}
538
539void i386_device::x87_fadd_st_sti(UINT8 modrm)
540{
541   floatx80 result;
542   int i = modrm & 7;
543
544   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
545   {
546      x87_set_stack_underflow();
547      result = fx80_inan;
548   }
549   else
550   {
551      floatx80 a = ST(0);
552      floatx80 b = ST(i);
553
554      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
555      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
556      {
557         m_x87_sw |= X87_SW_IE;
558         result = fx80_inan;
559      }
560      else
561      {
562         result = x87_add(a, b);
563      }
564   }
565
566   if (x87_check_exceptions())
567      x87_write_stack(0, result, TRUE);
568
569   CYCLES(8);
570}
571
572void i386_device::x87_fadd_sti_st(UINT8 modrm)
573{
574   floatx80 result;
575   int i = modrm & 7;
576
577   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
578   {
579      x87_set_stack_underflow();
580      result = fx80_inan;
581   }
582   else
583   {
584      floatx80 a = ST(0);
585      floatx80 b = ST(i);
586
587      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
588      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
589      {
590         m_x87_sw |= X87_SW_IE;
591         result = fx80_inan;
592      }
593      else
594      {
595         result = x87_add(a, b);
596      }
597   }
598
599   if (x87_check_exceptions())
600      x87_write_stack(i, result, TRUE);
601
602   CYCLES(8);
603}
604
605void i386_device::x87_faddp(UINT8 modrm)
606{
607   floatx80 result;
608   int i = modrm & 7;
609
610   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
611   {
612      x87_set_stack_underflow();
613      result = fx80_inan;
614   }
615   else
616   {
617      floatx80 a = ST(0);
618      floatx80 b = ST(i);
619
620      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
621      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
622      {
623         m_x87_sw |= X87_SW_IE;
624         result = fx80_inan;
625      }
626      else
627      {
628         result = x87_add(a, b);
629      }
630   }
631
632   if (x87_check_exceptions())
633   {
634      x87_write_stack(i, result, TRUE);
635      x87_inc_stack();
636   }
637
638   CYCLES(8);
639}
640
641void i386_device::x87_fiadd_m32int(UINT8 modrm)
642{
643   floatx80 result;
644
645   UINT32 ea = GetEA(modrm, 0);
646   if (X87_IS_ST_EMPTY(0))
647   {
648      x87_set_stack_underflow();
649      result = fx80_inan;
650   }
651   else
652   {
653      INT32 m32int = READ32(ea);
654
655      floatx80 a = ST(0);
656      floatx80 b = int32_to_floatx80(m32int);
657
658      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
659      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
660      {
661         m_x87_sw |= X87_SW_IE;
662         result = fx80_inan;
663      }
664      else
665      {
666         result = x87_add(a, b);
667      }
668   }
669
670   if (x87_check_exceptions())
671      x87_write_stack(0, result, TRUE);
672
673   CYCLES(19);
674}
675
676void i386_device::x87_fiadd_m16int(UINT8 modrm)
677{
678   floatx80 result;
679
680   UINT32 ea = GetEA(modrm, 0);
681   if (X87_IS_ST_EMPTY(0))
682   {
683      x87_set_stack_underflow();
684      result = fx80_inan;
685   }
686   else
687   {
688      INT16 m16int = READ16(ea);
689
690      floatx80 a = ST(0);
691      floatx80 b = int32_to_floatx80(m16int);
692
693      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
694      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
695      {
696         m_x87_sw |= X87_SW_IE;
697         result = fx80_inan;
698      }
699      else
700      {
701         result = x87_add(a, b);
702      }
703   }
704
705   if (x87_check_exceptions())
706      x87_write_stack(0, result, TRUE);
707
708   CYCLES(20);
709}
710
711
712/*************************************
713 *
714 * Subtract
715 *
716 *************************************/
717
718void i386_device::x87_fsub_m32real(UINT8 modrm)
719{
720   floatx80 result;
721
722   UINT32 ea = GetEA(modrm, 0);
723   if (X87_IS_ST_EMPTY(0))
724   {
725      x87_set_stack_underflow();
726      result = fx80_inan;
727   }
728   else
729   {
730      UINT32 m32real = READ32(ea);
731
732      floatx80 a = ST(0);
733      floatx80 b = float32_to_floatx80(m32real);
734
735      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
736      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
737      {
738         m_x87_sw |= X87_SW_IE;
739         result = fx80_inan;
740      }
741      else
742      {
743         result = x87_sub(a, b);
744      }
745   }
746
747   if (x87_check_exceptions())
748      x87_write_stack(0, result, TRUE);
749
750   CYCLES(8);
751}
752
753void i386_device::x87_fsub_m64real(UINT8 modrm)
754{
755   floatx80 result;
756
757   UINT32 ea = GetEA(modrm, 0);
758   if (X87_IS_ST_EMPTY(0))
759   {
760      x87_set_stack_underflow();
761      result = fx80_inan;
762   }
763   else
764   {
765      UINT64 m64real = READ64(ea);
766
767      floatx80 a = ST(0);
768      floatx80 b = float64_to_floatx80(m64real);
769
770      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
771      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
772      {
773         m_x87_sw |= X87_SW_IE;
774         result = fx80_inan;
775      }
776      else
777      {
778         result = x87_sub(a, b);
779      }
780   }
781
782   if (x87_check_exceptions())
783      x87_write_stack(0, result, TRUE);
784
785   CYCLES(8);
786}
787
788void i386_device::x87_fsub_st_sti(UINT8 modrm)
789{
790   floatx80 result;
791   int i = modrm & 7;
792
793   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
794   {
795      x87_set_stack_underflow();
796      result = fx80_inan;
797   }
798   else
799   {
800      floatx80 a = ST(0);
801      floatx80 b = ST(i);
802
803      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
804      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
805      {
806         m_x87_sw |= X87_SW_IE;
807         result = fx80_inan;
808      }
809      else
810      {
811         result = x87_sub(a, b);
812      }
813   }
814
815   if (x87_check_exceptions())
816      x87_write_stack(0, result, TRUE);
817
818   CYCLES(8);
819}
820
821void i386_device::x87_fsub_sti_st(UINT8 modrm)
822{
823   floatx80 result;
824   int i = modrm & 7;
825
826   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
827   {
828      x87_set_stack_underflow();
829      result = fx80_inan;
830   }
831   else
832   {
833      floatx80 a = ST(i);
834      floatx80 b = ST(0);
835
836      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
837      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
838      {
839         m_x87_sw |= X87_SW_IE;
840         result = fx80_inan;
841      }
842      else
843      {
844         result = x87_sub(a, b);
845      }
846   }
847
848   if (x87_check_exceptions())
849      x87_write_stack(i, result, TRUE);
850
851   CYCLES(8);
852}
853
854void i386_device::x87_fsubp(UINT8 modrm)
855{
856   floatx80 result;
857   int i = modrm & 7;
858
859   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
860   {
861      x87_set_stack_underflow();
862      result = fx80_inan;
863   }
864   else
865   {
866      floatx80 a = ST(i);
867      floatx80 b = ST(0);
868
869      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
870      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
871      {
872         m_x87_sw |= X87_SW_IE;
873         result = fx80_inan;
874      }
875      else
876      {
877         result = x87_sub(a, b);
878      }
879   }
880
881   if (x87_check_exceptions())
882   {
883      x87_write_stack(i, result, TRUE);
884      x87_inc_stack();
885   }
886
887   CYCLES(8);
888}
889
890void i386_device::x87_fisub_m32int(UINT8 modrm)
891{
892   floatx80 result;
893
894   UINT32 ea = GetEA(modrm, 0);
895   if (X87_IS_ST_EMPTY(0))
896   {
897      x87_set_stack_underflow();
898      result = fx80_inan;
899   }
900   else
901   {
902      INT32 m32int = READ32(ea);
903
904      floatx80 a = ST(0);
905      floatx80 b = int32_to_floatx80(m32int);
906
907      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
908      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
909      {
910         m_x87_sw |= X87_SW_IE;
911         result = fx80_inan;
912      }
913      else
914      {
915         result = x87_sub(a, b);
916      }
917   }
918
919   if (x87_check_exceptions())
920      x87_write_stack(0, result, TRUE);
921
922   CYCLES(19);
923}
924
925void i386_device::x87_fisub_m16int(UINT8 modrm)
926{
927   floatx80 result;
928
929   UINT32 ea = GetEA(modrm, 0);
930   if (X87_IS_ST_EMPTY(0))
931   {
932      x87_set_stack_underflow();
933      result = fx80_inan;
934   }
935   else
936   {
937      INT16 m16int = READ16(ea);
938
939      floatx80 a = ST(0);
940      floatx80 b = int32_to_floatx80(m16int);
941
942      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
943      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
944      {
945         m_x87_sw |= X87_SW_IE;
946         result = fx80_inan;
947      }
948      else
949      {
950         result = x87_sub(a, b);
951      }
952   }
953
954   if (x87_check_exceptions())
955      x87_write_stack(0, result, TRUE);
956
957   CYCLES(20);
958}
959
960
961/*************************************
962 *
963 * Reverse Subtract
964 *
965 *************************************/
966
967void i386_device::x87_fsubr_m32real(UINT8 modrm)
968{
969   floatx80 result;
970
971   UINT32 ea = GetEA(modrm, 0);
972   if (X87_IS_ST_EMPTY(0))
973   {
974      x87_set_stack_underflow();
975      result = fx80_inan;
976   }
977   else
978   {
979      UINT32 m32real = READ32(ea);
980
981      floatx80 a = float32_to_floatx80(m32real);
982      floatx80 b = ST(0);
983
984      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
985      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
986      {
987         m_x87_sw |= X87_SW_IE;
988         result = fx80_inan;
989      }
990      else
991      {
992         result = x87_sub(a, b);
993      }
994   }
995
996   if (x87_check_exceptions())
997      x87_write_stack(0, result, TRUE);
998
999   CYCLES(8);
1000}
1001
1002void i386_device::x87_fsubr_m64real(UINT8 modrm)
1003{
1004   floatx80 result;
1005
1006   UINT32 ea = GetEA(modrm, 0);
1007   if (X87_IS_ST_EMPTY(0))
1008   {
1009      x87_set_stack_underflow();
1010      result = fx80_inan;
1011   }
1012   else
1013   {
1014      UINT64 m64real = READ64(ea);
1015
1016      floatx80 a = float64_to_floatx80(m64real);
1017      floatx80 b = ST(0);
1018
1019      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1020      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1021      {
1022         m_x87_sw |= X87_SW_IE;
1023         result = fx80_inan;
1024      }
1025      else
1026      {
1027         result = x87_sub(a, b);
1028      }
1029   }
1030
1031   if (x87_check_exceptions())
1032      x87_write_stack(0, result, TRUE);
1033
1034   CYCLES(8);
1035}
1036
1037void i386_device::x87_fsubr_st_sti(UINT8 modrm)
1038{
1039   floatx80 result;
1040   int i = modrm & 7;
1041
1042   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1043   {
1044      x87_set_stack_underflow();
1045      result = fx80_inan;
1046   }
1047   else
1048   {
1049      floatx80 a = ST(i);
1050      floatx80 b = ST(0);
1051
1052      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1053      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1054      {
1055         m_x87_sw |= X87_SW_IE;
1056         result = fx80_inan;
1057      }
1058      else
1059      {
1060         result = x87_sub(a, b);
1061      }
1062   }
1063
1064   if (x87_check_exceptions())
1065      x87_write_stack(0, result, TRUE);
1066
1067   CYCLES(8);
1068}
1069
1070void i386_device::x87_fsubr_sti_st(UINT8 modrm)
1071{
1072   floatx80 result;
1073   int i = modrm & 7;
1074
1075   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1076   {
1077      x87_set_stack_underflow();
1078      result = fx80_inan;
1079   }
1080   else
1081   {
1082      floatx80 a = ST(0);
1083      floatx80 b = ST(i);
1084
1085      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1086      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1087      {
1088         m_x87_sw |= X87_SW_IE;
1089         result = fx80_inan;
1090      }
1091      else
1092      {
1093         result = x87_sub(a, b);
1094      }
1095   }
1096
1097   if (x87_check_exceptions())
1098      x87_write_stack(i, result, TRUE);
1099
1100   CYCLES(8);
1101}
1102
1103void i386_device::x87_fsubrp(UINT8 modrm)
1104{
1105   floatx80 result;
1106   int i = modrm & 7;
1107
1108   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1109   {
1110      x87_set_stack_underflow();
1111      result = fx80_inan;
1112   }
1113   else
1114   {
1115      floatx80 a = ST(0);
1116      floatx80 b = ST(i);
1117
1118      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1119      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1120      {
1121         m_x87_sw |= X87_SW_IE;
1122         result = fx80_inan;
1123      }
1124      else
1125      {
1126         result = x87_sub(a, b);
1127      }
1128   }
1129
1130   if (x87_check_exceptions())
1131   {
1132      x87_write_stack(i, result, TRUE);
1133      x87_inc_stack();
1134   }
1135
1136   CYCLES(8);
1137}
1138
1139void i386_device::x87_fisubr_m32int(UINT8 modrm)
1140{
1141   floatx80 result;
1142
1143   UINT32 ea = GetEA(modrm, 0);
1144   if (X87_IS_ST_EMPTY(0))
1145   {
1146      x87_set_stack_underflow();
1147      result = fx80_inan;
1148   }
1149   else
1150   {
1151      INT32 m32int = READ32(ea);
1152
1153      floatx80 a = int32_to_floatx80(m32int);
1154      floatx80 b = ST(0);
1155
1156      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1157      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1158      {
1159         m_x87_sw |= X87_SW_IE;
1160         result = fx80_inan;
1161      }
1162      else
1163      {
1164         result = x87_sub(a, b);
1165      }
1166   }
1167
1168   if (x87_check_exceptions())
1169      x87_write_stack(0, result, TRUE);
1170
1171   CYCLES(19);
1172}
1173
1174void i386_device::x87_fisubr_m16int(UINT8 modrm)
1175{
1176   floatx80 result;
1177
1178   UINT32 ea = GetEA(modrm, 0);
1179   if (X87_IS_ST_EMPTY(0))
1180   {
1181      x87_set_stack_underflow();
1182      result = fx80_inan;
1183   }
1184   else
1185   {
1186      INT16 m16int = READ16(ea);
1187
1188      floatx80 a = int32_to_floatx80(m16int);
1189      floatx80 b = ST(0);
1190
1191      if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1192      || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1193      {
1194         m_x87_sw |= X87_SW_IE;
1195         result = fx80_inan;
1196      }
1197      else
1198      {
1199         result = x87_sub(a, b);
1200      }
1201   }
1202
1203   if (x87_check_exceptions())
1204      x87_write_stack(0, result, TRUE);
1205
1206   CYCLES(20);
1207}
1208
1209
1210/*************************************
1211 *
1212 * Divide
1213 *
1214 *************************************/
1215
1216void i386_device::x87_fdiv_m32real(UINT8 modrm)
1217{
1218   floatx80 result;
1219
1220   UINT32 ea = GetEA(modrm, 0);
1221   if (X87_IS_ST_EMPTY(0))
1222   {
1223      x87_set_stack_underflow();
1224      result = fx80_inan;
1225   }
1226   else
1227   {
1228      UINT32 m32real = READ32(ea);
1229
1230      floatx80 a = ST(0);
1231      floatx80 b = float32_to_floatx80(m32real);
1232
1233      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1234      {
1235         m_x87_sw |= X87_SW_IE;
1236         result = fx80_inan;
1237      }
1238      else
1239      {
1240         result = x87_div(a, b);
1241      }
1242   }
1243
1244   if (x87_check_exceptions())
1245      x87_write_stack(0, result, TRUE);
1246
1247   // 73, 62, 35
1248   CYCLES(73);
1249}
1250
1251void i386_device::x87_fdiv_m64real(UINT8 modrm)
1252{
1253   floatx80 result;
1254
1255   UINT32 ea = GetEA(modrm, 0);
1256   if (X87_IS_ST_EMPTY(0))
1257   {
1258      x87_set_stack_underflow();
1259      result = fx80_inan;
1260   }
1261   else
1262   {
1263      UINT64 m64real = READ64(ea);
1264
1265      floatx80 a = ST(0);
1266      floatx80 b = float64_to_floatx80(m64real);
1267
1268      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1269      {
1270         m_x87_sw |= X87_SW_IE;
1271         result = fx80_inan;
1272      }
1273      else
1274      {
1275         result = x87_div(a, b);
1276      }
1277   }
1278
1279   if (x87_check_exceptions())
1280      x87_write_stack(0, result, TRUE);
1281
1282   // 73, 62, 35
1283   CYCLES(73);
1284}
1285
1286void i386_device::x87_fdiv_st_sti(UINT8 modrm)
1287{
1288   int i = modrm & 7;
1289   floatx80 result;
1290
1291   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1292   {
1293      x87_set_stack_underflow();
1294      result = fx80_inan;
1295   }
1296   else
1297   {
1298      floatx80 a = ST(0);
1299      floatx80 b = ST(i);
1300
1301      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1302      {
1303         m_x87_sw |= X87_SW_IE;
1304         result = fx80_inan;
1305      }
1306      else
1307      {
1308         result = x87_div(a, b);
1309      }
1310   }
1311
1312   if (x87_check_exceptions())
1313   {
1314      x87_write_stack(0, result, TRUE);
1315   }
1316
1317   // 73, 62, 35
1318   CYCLES(73);
1319}
1320
1321void i386_device::x87_fdiv_sti_st(UINT8 modrm)
1322{
1323   int i = modrm & 7;
1324   floatx80 result;
1325
1326   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1327   {
1328      x87_set_stack_underflow();
1329      result = fx80_inan;
1330   }
1331   else
1332   {
1333      floatx80 a = ST(i);
1334      floatx80 b = ST(0);
1335
1336      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1337      {
1338         m_x87_sw |= X87_SW_IE;
1339         result = fx80_inan;
1340      }
1341      else
1342      {
1343         result = x87_div(a, b);
1344      }
1345   }
1346
1347   if (x87_check_exceptions())
1348   {
1349      x87_write_stack(i, result, TRUE);
1350   }
1351
1352   // 73, 62, 35
1353   CYCLES(73);
1354}
1355
1356void i386_device::x87_fdivp(UINT8 modrm)
1357{
1358   int i = modrm & 7;
1359   floatx80 result;
1360
1361   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1362   {
1363      x87_set_stack_underflow();
1364      result = fx80_inan;
1365   }
1366   else
1367   {
1368      floatx80 a = ST(i);
1369      floatx80 b = ST(0);
1370
1371      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1372      {
1373         m_x87_sw |= X87_SW_IE;
1374         result = fx80_inan;
1375      }
1376      else
1377      {
1378         result = x87_div(a, b);
1379      }
1380   }
1381
1382   if (x87_check_exceptions())
1383   {
1384      x87_write_stack(i, result, TRUE);
1385      x87_inc_stack();
1386   }
1387
1388   // 73, 62, 35
1389   CYCLES(73);
1390}
1391
1392void i386_device::x87_fidiv_m32int(UINT8 modrm)
1393{
1394   floatx80 result;
1395
1396   UINT32 ea = GetEA(modrm, 0);
1397   if (X87_IS_ST_EMPTY(0))
1398   {
1399      x87_set_stack_underflow();
1400      result = fx80_inan;
1401   }
1402   else
1403   {
1404      INT32 m32int = READ32(ea);
1405
1406      floatx80 a = ST(0);
1407      floatx80 b = int32_to_floatx80(m32int);
1408
1409      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1410      {
1411         m_x87_sw |= X87_SW_IE;
1412         result = fx80_inan;
1413      }
1414      else
1415      {
1416         result = x87_div(a, b);
1417      }
1418   }
1419
1420   if (x87_check_exceptions())
1421      x87_write_stack(0, result, TRUE);
1422
1423   // 73, 62, 35
1424   CYCLES(73);
1425}
1426
1427void i386_device::x87_fidiv_m16int(UINT8 modrm)
1428{
1429   floatx80 result;
1430
1431   UINT32 ea = GetEA(modrm, 0);
1432   if (X87_IS_ST_EMPTY(0))
1433   {
1434      x87_set_stack_underflow();
1435      result = fx80_inan;
1436   }
1437   else
1438   {
1439      INT16 m16int = READ32(ea);
1440
1441      floatx80 a = ST(0);
1442      floatx80 b = int32_to_floatx80(m16int);
1443
1444      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1445      {
1446         m_x87_sw |= X87_SW_IE;
1447         result = fx80_inan;
1448      }
1449      else
1450      {
1451         result = x87_div(a, b);
1452      }
1453   }
1454
1455   if (x87_check_exceptions())
1456      x87_write_stack(0, result, TRUE);
1457
1458   // 73, 62, 35
1459   CYCLES(73);
1460}
1461
1462
1463/*************************************
1464 *
1465 * Reverse Divide
1466 *
1467 *************************************/
1468
1469void i386_device::x87_fdivr_m32real(UINT8 modrm)
1470{
1471   floatx80 result;
1472
1473   UINT32 ea = GetEA(modrm, 0);
1474   if (X87_IS_ST_EMPTY(0))
1475   {
1476      x87_set_stack_underflow();
1477      result = fx80_inan;
1478   }
1479   else
1480   {
1481      UINT32 m32real = READ32(ea);
1482
1483      floatx80 a = float32_to_floatx80(m32real);
1484      floatx80 b = ST(0);
1485
1486      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1487      {
1488         m_x87_sw |= X87_SW_IE;
1489         result = fx80_inan;
1490      }
1491      else
1492      {
1493         result = x87_div(a, b);
1494      }
1495   }
1496
1497   if (x87_check_exceptions())
1498      x87_write_stack(0, result, TRUE);
1499
1500   // 73, 62, 35
1501   CYCLES(73);
1502}
1503
1504void i386_device::x87_fdivr_m64real(UINT8 modrm)
1505{
1506   floatx80 result;
1507
1508   UINT32 ea = GetEA(modrm, 0);
1509   if (X87_IS_ST_EMPTY(0))
1510   {
1511      x87_set_stack_underflow();
1512      result = fx80_inan;
1513   }
1514   else
1515   {
1516      UINT64 m64real = READ64(ea);
1517
1518      floatx80 a = float64_to_floatx80(m64real);
1519      floatx80 b = ST(0);
1520
1521      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1522      {
1523         m_x87_sw |= X87_SW_IE;
1524         result = fx80_inan;
1525      }
1526      else
1527      {
1528         result = x87_div(a, b);
1529      }
1530   }
1531
1532   if (x87_check_exceptions())
1533      x87_write_stack(0, result, TRUE);
1534
1535   // 73, 62, 35
1536   CYCLES(73);
1537}
1538
1539void i386_device::x87_fdivr_st_sti(UINT8 modrm)
1540{
1541   int i = modrm & 7;
1542   floatx80 result;
1543
1544   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1545   {
1546      x87_set_stack_underflow();
1547      result = fx80_inan;
1548   }
1549   else
1550   {
1551      floatx80 a = ST(i);
1552      floatx80 b = ST(0);
1553
1554      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1555      {
1556         m_x87_sw |= X87_SW_IE;
1557         result = fx80_inan;
1558      }
1559      else
1560      {
1561         result = x87_div(a, b);
1562      }
1563   }
1564
1565   if (x87_check_exceptions())
1566   {
1567      x87_write_stack(0, result, TRUE);
1568   }
1569
1570   // 73, 62, 35
1571   CYCLES(73);
1572}
1573
1574void i386_device::x87_fdivr_sti_st(UINT8 modrm)
1575{
1576   int i = modrm & 7;
1577   floatx80 result;
1578
1579   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1580   {
1581      x87_set_stack_underflow();
1582      result = fx80_inan;
1583   }
1584   else
1585   {
1586      floatx80 a = ST(0);
1587      floatx80 b = ST(i);
1588
1589      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1590      {
1591         m_x87_sw |= X87_SW_IE;
1592         result = fx80_inan;
1593      }
1594      else
1595      {
1596         result = x87_div(a, b);
1597      }
1598   }
1599
1600   if (x87_check_exceptions())
1601   {
1602      x87_write_stack(i, result, TRUE);
1603   }
1604
1605   // 73, 62, 35
1606   CYCLES(73);
1607}
1608
1609void i386_device::x87_fdivrp(UINT8 modrm)
1610{
1611   int i = modrm & 7;
1612   floatx80 result;
1613
1614   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1615   {
1616      x87_set_stack_underflow();
1617      result = fx80_inan;
1618   }
1619   else
1620   {
1621      floatx80 a = ST(0);
1622      floatx80 b = ST(i);
1623
1624      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1625      {
1626         m_x87_sw |= X87_SW_IE;
1627         result = fx80_inan;
1628      }
1629      else
1630      {
1631         result = x87_div(a, b);
1632      }
1633   }
1634
1635   if (x87_check_exceptions())
1636   {
1637      x87_write_stack(i, result, TRUE);
1638      x87_inc_stack();
1639   }
1640
1641   // 73, 62, 35
1642   CYCLES(73);
1643}
1644
1645
1646void i386_device::x87_fidivr_m32int(UINT8 modrm)
1647{
1648   floatx80 result;
1649
1650   UINT32 ea = GetEA(modrm, 0);
1651   if (X87_IS_ST_EMPTY(0))
1652   {
1653      x87_set_stack_underflow();
1654      result = fx80_inan;
1655   }
1656   else
1657   {
1658      INT32 m32int = READ32(ea);
1659
1660      floatx80 a = int32_to_floatx80(m32int);
1661      floatx80 b = ST(0);
1662
1663      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1664      {
1665         m_x87_sw |= X87_SW_IE;
1666         result = fx80_inan;
1667      }
1668      else
1669      {
1670         result = x87_div(a, b);
1671      }
1672   }
1673
1674   if (x87_check_exceptions())
1675      x87_write_stack(0, result, TRUE);
1676
1677   // 73, 62, 35
1678   CYCLES(73);
1679}
1680
1681void i386_device::x87_fidivr_m16int(UINT8 modrm)
1682{
1683   floatx80 result;
1684
1685   UINT32 ea = GetEA(modrm, 0);
1686   if (X87_IS_ST_EMPTY(0))
1687   {
1688      x87_set_stack_underflow();
1689      result = fx80_inan;
1690   }
1691   else
1692   {
1693      INT16 m16int = READ32(ea);
1694
1695      floatx80 a = int32_to_floatx80(m16int);
1696      floatx80 b = ST(0);
1697
1698      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1699      {
1700         m_x87_sw |= X87_SW_IE;
1701         result = fx80_inan;
1702      }
1703      else
1704      {
1705         result = x87_div(a, b);
1706      }
1707   }
1708
1709   if (x87_check_exceptions())
1710      x87_write_stack(0, result, TRUE);
1711
1712   // 73, 62, 35
1713   CYCLES(73);
1714}
1715
1716
1717/*************************************
1718 *
1719 * Multiply
1720 *
1721 *************************************/
1722
1723void i386_device::x87_fmul_m32real(UINT8 modrm)
1724{
1725   floatx80 result;
1726
1727   UINT32 ea = GetEA(modrm, 0);
1728   if (X87_IS_ST_EMPTY(0))
1729   {
1730      x87_set_stack_underflow();
1731      result = fx80_inan;
1732   }
1733   else
1734   {
1735      UINT32 m32real = READ32(ea);
1736
1737      floatx80 a = ST(0);
1738      floatx80 b = float32_to_floatx80(m32real);
1739
1740      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1741      {
1742         m_x87_sw |= X87_SW_IE;
1743         result = fx80_inan;
1744      }
1745      else
1746      {
1747         result = x87_mul(a, b);
1748      }
1749   }
1750
1751   if (x87_check_exceptions())
1752      x87_write_stack(0, result, TRUE);
1753
1754   CYCLES(11);
1755}
1756
1757void i386_device::x87_fmul_m64real(UINT8 modrm)
1758{
1759   floatx80 result;
1760
1761   UINT32 ea = GetEA(modrm, 0);
1762   if (X87_IS_ST_EMPTY(0))
1763   {
1764      x87_set_stack_underflow();
1765      result = fx80_inan;
1766   }
1767   else
1768   {
1769      UINT64 m64real = READ64(ea);
1770
1771      floatx80 a = ST(0);
1772      floatx80 b = float64_to_floatx80(m64real);
1773
1774      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1775      {
1776         m_x87_sw |= X87_SW_IE;
1777         result = fx80_inan;
1778      }
1779      else
1780      {
1781         result = x87_mul(a, b);
1782      }
1783   }
1784
1785   if (x87_check_exceptions())
1786      x87_write_stack(0, result, TRUE);
1787
1788   CYCLES(14);
1789}
1790
1791void i386_device::x87_fmul_st_sti(UINT8 modrm)
1792{
1793   floatx80 result;
1794   int i = modrm & 7;
1795
1796   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1797   {
1798      x87_set_stack_underflow();
1799      result = fx80_inan;
1800   }
1801   else
1802   {
1803      floatx80 a = ST(0);
1804      floatx80 b = ST(i);
1805
1806      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1807      {
1808         m_x87_sw |= X87_SW_IE;
1809         result = fx80_inan;
1810      }
1811      else
1812      {
1813         result = x87_mul(a, b);
1814      }
1815   }
1816
1817   if (x87_check_exceptions())
1818      x87_write_stack(0, result, TRUE);
1819
1820   CYCLES(16);
1821}
1822
1823void i386_device::x87_fmul_sti_st(UINT8 modrm)
1824{
1825   floatx80 result;
1826   int i = modrm & 7;
1827
1828   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1829   {
1830      x87_set_stack_underflow();
1831      result = fx80_inan;
1832   }
1833   else
1834   {
1835      floatx80 a = ST(0);
1836      floatx80 b = ST(i);
1837
1838      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1839      {
1840         m_x87_sw |= X87_SW_IE;
1841         result = fx80_inan;
1842      }
1843      else
1844      {
1845         result = x87_mul(a, b);
1846      }
1847   }
1848
1849   if (x87_check_exceptions())
1850      x87_write_stack(i, result, TRUE);
1851
1852   CYCLES(16);
1853}
1854
1855void i386_device::x87_fmulp(UINT8 modrm)
1856{
1857   floatx80 result;
1858   int i = modrm & 7;
1859
1860   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1861   {
1862      x87_set_stack_underflow();
1863      result = fx80_inan;
1864   }
1865   else
1866   {
1867      floatx80 a = ST(0);
1868      floatx80 b = ST(i);
1869
1870      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1871      {
1872         m_x87_sw |= X87_SW_IE;
1873         result = fx80_inan;
1874      }
1875      else
1876      {
1877         result = x87_mul(a, b);
1878      }
1879   }
1880
1881   if (x87_check_exceptions())
1882   {
1883      x87_write_stack(i, result, TRUE);
1884      x87_inc_stack();
1885   }
1886
1887   CYCLES(16);
1888}
1889
1890void i386_device::x87_fimul_m32int(UINT8 modrm)
1891{
1892   floatx80 result;
1893
1894   UINT32 ea = GetEA(modrm, 0);
1895   if (X87_IS_ST_EMPTY(0))
1896   {
1897      x87_set_stack_underflow();
1898      result = fx80_inan;
1899   }
1900   else
1901   {
1902      INT32 m32int = READ32(ea);
1903
1904      floatx80 a = ST(0);
1905      floatx80 b = int32_to_floatx80(m32int);
1906
1907      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1908      {
1909         m_x87_sw |= X87_SW_IE;
1910         result = fx80_inan;
1911      }
1912      else
1913      {
1914         result = x87_mul(a, b);
1915      }
1916   }
1917
1918   if (x87_check_exceptions())
1919      x87_write_stack(0, result, TRUE);
1920
1921   CYCLES(22);
1922}
1923
1924void i386_device::x87_fimul_m16int(UINT8 modrm)
1925{
1926   floatx80 result;
1927
1928   UINT32 ea = GetEA(modrm, 0);
1929   if (X87_IS_ST_EMPTY(0))
1930   {
1931      x87_set_stack_underflow();
1932      result = fx80_inan;
1933   }
1934   else
1935   {
1936      INT16 m16int = READ16(ea);
1937
1938      floatx80 a = ST(0);
1939      floatx80 b = int32_to_floatx80(m16int);
1940
1941      if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1942      {
1943         m_x87_sw |= X87_SW_IE;
1944         result = fx80_inan;
1945      }
1946      else
1947      {
1948         result = x87_mul(a, b);
1949      }
1950   }
1951
1952   if (x87_check_exceptions())
1953      x87_write_stack(0, result, TRUE);
1954
1955   CYCLES(22);
1956}
1957
1958
1959/*************************************
1960 *
1961 * Miscellaneous arithmetic
1962 *
1963 *************************************/
1964
1965void i386_device::x87_fprem(UINT8 modrm)
1966{
1967   floatx80 result;
1968
1969   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
1970   {
1971      x87_set_stack_underflow();
1972      result = fx80_inan;
1973   }
1974   else
1975   {
1976      floatx80 a = ST(0);
1977      floatx80 b = ST(1);
1978
1979      m_x87_sw &= ~X87_SW_C0;
1980
1981      // TODO: Implement Cx bits
1982      result = floatx80_rem(a, b);
1983   }
1984
1985   if (x87_check_exceptions())
1986      x87_write_stack(0, result, TRUE);
1987
1988   CYCLES(84);
1989}
1990
1991void i386_device::x87_fprem1(UINT8 modrm)
1992{
1993   floatx80 result;
1994
1995   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
1996   {
1997      x87_set_stack_underflow();
1998      result = fx80_inan;
1999   }
2000   else
2001   {
2002      floatx80 a = ST(0);
2003      floatx80 b = ST(1);
2004
2005      m_x87_sw &= ~X87_SW_C0;
2006
2007      // TODO: Implement Cx bits
2008      result = floatx80_rem(a, b);
2009   }
2010
2011   if (x87_check_exceptions())
2012      x87_write_stack(0, result, TRUE);
2013
2014   CYCLES(94);
2015}
2016
2017void i386_device::x87_fsqrt(UINT8 modrm)
2018{
2019   floatx80 result;
2020
2021   if (X87_IS_ST_EMPTY(0))
2022   {
2023      x87_set_stack_underflow();
2024      result = fx80_inan;
2025   }
2026   else
2027   {
2028      floatx80 value = ST(0);
2029
2030      if ((!floatx80_is_zero(value) && (value.high & 0x8000)) ||
2031            floatx80_is_denormal(value))
2032      {
2033         m_x87_sw |= X87_SW_IE;
2034         result = fx80_inan;
2035      }
2036      else
2037      {
2038         result = floatx80_sqrt(value);
2039      }
2040   }
2041
2042   if (x87_check_exceptions())
2043      x87_write_stack(0, result, TRUE);
2044
2045   CYCLES(8);
2046}
2047
2048/*************************************
2049 *
2050 * Trigonometric
2051 *
2052 *************************************/
2053
2054void i386_device::x87_f2xm1(UINT8 modrm)
2055{
2056   floatx80 result;
2057
2058   if (X87_IS_ST_EMPTY(0))
2059   {
2060      x87_set_stack_underflow();
2061      result = fx80_inan;
2062   }
2063   else
2064   {
2065      // TODO: Inaccurate
2066      double x = fx80_to_double(ST(0));
2067      double res = pow(2.0, x) - 1;
2068      result = double_to_fx80(res);
2069   }
2070
2071   if (x87_check_exceptions())
2072   {
2073      x87_write_stack(0, result, TRUE);
2074   }
2075
2076   CYCLES(242);
2077}
2078
2079void i386_device::x87_fyl2x(UINT8 modrm)
2080{
2081   floatx80 result;
2082
2083   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2084   {
2085      x87_set_stack_underflow();
2086      result = fx80_inan;
2087   }
2088   else
2089   {
2090      floatx80 x = ST(0);
2091      floatx80 y = ST(1);
2092
2093      if (x.high & 0x8000)
2094      {
2095         m_x87_sw |= X87_SW_IE;
2096         result = fx80_inan;
2097      }
2098      else
2099      {
2100         // TODO: Inaccurate
2101         double d64 = fx80_to_double(x);
2102         double l2x = log(d64)/log(2.0);
2103         result = floatx80_mul(double_to_fx80(l2x), y);
2104      }
2105   }
2106
2107   if (x87_check_exceptions())
2108   {
2109      x87_write_stack(1, result, TRUE);
2110      x87_inc_stack();
2111   }
2112
2113   CYCLES(250);
2114}
2115
2116void i386_device::x87_fyl2xp1(UINT8 modrm)
2117{
2118   floatx80 result;
2119
2120   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2121   {
2122      x87_set_stack_underflow();
2123      result = fx80_inan;
2124   }
2125   else
2126   {
2127      floatx80 x = ST(0);
2128      floatx80 y = ST(1);
2129
2130      // TODO: Inaccurate
2131      double d64 = fx80_to_double(x);
2132      double l2x1 = log(d64 + 1.0)/log(2.0);
2133      result = floatx80_mul(double_to_fx80(l2x1), y);
2134   }
2135
2136   if (x87_check_exceptions())
2137   {
2138      x87_write_stack(1, result, TRUE);
2139      x87_inc_stack();
2140   }
2141
2142   CYCLES(313);
2143}
2144
2145void i386_device::x87_fptan(UINT8 modrm)
2146{
2147   floatx80 result1, result2;
2148
2149   if (X87_IS_ST_EMPTY(0))
2150   {
2151      x87_set_stack_underflow();
2152      result1 = fx80_inan;
2153      result2 = fx80_inan;
2154   }
2155   else if (!X87_IS_ST_EMPTY(7))
2156   {
2157      x87_set_stack_overflow();
2158      result1 = fx80_inan;
2159      result2 = fx80_inan;
2160   }
2161   else
2162   {
2163      result1 = ST(0);
2164      result2 = fx80_one;
2165
2166#if 0 // TODO: Function produces bad values
2167      if (floatx80_ftan(result1) != -1)
2168         m_x87_sw &= ~X87_SW_C2;
2169      else
2170         m_x87_sw |= X87_SW_C2;
2171#else
2172      double x = fx80_to_double(result1);
2173      x = tan(x);
2174      result1 = double_to_fx80(x);
2175
2176      m_x87_sw &= ~X87_SW_C2;
2177#endif
2178   }
2179
2180   if (x87_check_exceptions())
2181   {
2182      x87_write_stack(0, result1, TRUE);
2183      x87_dec_stack();
2184      x87_write_stack(0, result2, TRUE);
2185   }
2186
2187   CYCLES(244);
2188}
2189
2190void i386_device::x87_fpatan(UINT8 modrm)
2191{
2192   floatx80 result;
2193
2194   if (X87_IS_ST_EMPTY(0))
2195   {
2196      x87_set_stack_underflow();
2197      result = fx80_inan;
2198   }
2199   else
2200   {
2201      // TODO: Inaccurate
2202      double val = atan(fx80_to_double(ST(1)) / fx80_to_double(ST(0)));
2203      result = double_to_fx80(val);
2204   }
2205
2206   if (x87_check_exceptions())
2207   {
2208      x87_write_stack(1, result, TRUE);
2209      x87_inc_stack();
2210   }
2211
2212   CYCLES(289);
2213}
2214
2215void i386_device::x87_fsin(UINT8 modrm)
2216{
2217   floatx80 result;
2218
2219   if (X87_IS_ST_EMPTY(0))
2220   {
2221      x87_set_stack_underflow();
2222      result = fx80_inan;
2223   }
2224   else
2225   {
2226      result = ST(0);
2227
2228#if 0 // TODO: Function produces bad values
2229      if (floatx80_fsin(result) != -1)
2230         m_x87_sw &= ~X87_SW_C2;
2231      else
2232         m_x87_sw |= X87_SW_C2;
2233#else
2234      double x = fx80_to_double(result);
2235      x = sin(x);
2236      result = double_to_fx80(x);
2237
2238      m_x87_sw &= ~X87_SW_C2;
2239#endif
2240   }
2241
2242   if (x87_check_exceptions())
2243      x87_write_stack(0, result, TRUE);
2244
2245   CYCLES(241);
2246}
2247
2248void i386_device::x87_fcos(UINT8 modrm)
2249{
2250   floatx80 result;
2251
2252   if (X87_IS_ST_EMPTY(0))
2253   {
2254      x87_set_stack_underflow();
2255      result = fx80_inan;
2256   }
2257   else
2258   {
2259      result = ST(0);
2260
2261#if 0 // TODO: Function produces bad values
2262      if (floatx80_fcos(result) != -1)
2263         m_x87_sw &= ~X87_SW_C2;
2264      else
2265         m_x87_sw |= X87_SW_C2;
2266#else
2267      double x = fx80_to_double(result);
2268      x = cos(x);
2269      result = double_to_fx80(x);
2270
2271      m_x87_sw &= ~X87_SW_C2;
2272#endif
2273   }
2274
2275   if (x87_check_exceptions())
2276      x87_write_stack(0, result, TRUE);
2277
2278   CYCLES(241);
2279}
2280
2281void i386_device::x87_fsincos(UINT8 modrm)
2282{
2283   floatx80 s_result, c_result;
2284
2285   if (X87_IS_ST_EMPTY(0))
2286   {
2287      x87_set_stack_underflow();
2288      s_result = c_result = fx80_inan;
2289   }
2290   else if (!X87_IS_ST_EMPTY(7))
2291   {
2292      x87_set_stack_overflow();
2293      s_result = c_result = fx80_inan;
2294   }
2295   else
2296   {
2297      extern int sf_fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a);
2298
2299      s_result = c_result = ST(0);
2300
2301#if 0 // TODO: Function produces bad values
2302      if (sf_fsincos(s_result, &s_result, &c_result) != -1)
2303         m_x87_sw &= ~X87_SW_C2;
2304      else
2305         m_x87_sw |= X87_SW_C2;
2306#else
2307      double s = fx80_to_double(s_result);
2308      double c = fx80_to_double(c_result);
2309      s = sin(s);
2310      c = cos(c);
2311
2312      s_result = double_to_fx80(s);
2313      c_result = double_to_fx80(c);
2314
2315      m_x87_sw &= ~X87_SW_C2;
2316#endif
2317   }
2318
2319   if (x87_check_exceptions())
2320   {
2321      x87_write_stack(0, s_result, TRUE);
2322      x87_dec_stack();
2323      x87_write_stack(0, c_result, TRUE);
2324   }
2325
2326   CYCLES(291);
2327}
2328
2329
2330/*************************************
2331 *
2332 * Load data
2333 *
2334 *************************************/
2335
2336void i386_device::x87_fld_m32real(UINT8 modrm)
2337{
2338   floatx80 value;
2339
2340   UINT32 ea = GetEA(modrm, 0);
2341   if (x87_dec_stack())
2342   {
2343      UINT32 m32real = READ32(ea);
2344
2345      value = float32_to_floatx80(m32real);
2346
2347      m_x87_sw &= ~X87_SW_C1;
2348
2349      if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
2350      {
2351         m_x87_sw |= X87_SW_IE;
2352         value = fx80_inan;
2353      }
2354   }
2355   else
2356   {
2357      value = fx80_inan;
2358   }
2359
2360   if (x87_check_exceptions())
2361      x87_write_stack(0, value, TRUE);
2362
2363   CYCLES(3);
2364}
2365
2366void i386_device::x87_fld_m64real(UINT8 modrm)
2367{
2368   floatx80 value;
2369
2370   UINT32 ea = GetEA(modrm, 0);
2371   if (x87_dec_stack())
2372   {
2373      UINT64 m64real = READ64(ea);
2374
2375      value = float64_to_floatx80(m64real);
2376
2377      m_x87_sw &= ~X87_SW_C1;
2378
2379      if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
2380      {
2381         m_x87_sw |= X87_SW_IE;
2382         value = fx80_inan;
2383      }
2384   }
2385   else
2386   {
2387      value = fx80_inan;
2388   }
2389
2390   if (x87_check_exceptions())
2391      x87_write_stack(0, value, TRUE);
2392
2393   CYCLES(3);
2394}
2395
2396void i386_device::x87_fld_m80real(UINT8 modrm)
2397{
2398   floatx80 value;
2399
2400   UINT32 ea = GetEA(modrm, 0);
2401   if (x87_dec_stack())
2402   {
2403      m_x87_sw &= ~X87_SW_C1;
2404      value = READ80(ea);
2405   }
2406   else
2407   {
2408      value = fx80_inan;
2409   }
2410
2411   if (x87_check_exceptions())
2412      x87_write_stack(0, value, TRUE);
2413
2414   CYCLES(6);
2415}
2416
2417void i386_device::x87_fld_sti(UINT8 modrm)
2418{
2419   floatx80 value;
2420
2421   if (x87_dec_stack())
2422   {
2423      m_x87_sw &= ~X87_SW_C1;
2424      value = ST((modrm + 1) & 7);
2425   }
2426   else
2427   {
2428      value = fx80_inan;
2429   }
2430
2431   if (x87_check_exceptions())
2432      x87_write_stack(0, value, TRUE);
2433
2434   CYCLES(4);
2435}
2436
2437void i386_device::x87_fild_m16int(UINT8 modrm)
2438{
2439   floatx80 value;
2440
2441   UINT32 ea = GetEA(modrm, 0);
2442   if (!x87_dec_stack())
2443   {
2444      value = fx80_inan;
2445   }
2446   else
2447   {
2448      m_x87_sw &= ~X87_SW_C1;
2449
2450      INT16 m16int = READ16(ea);
2451      value = int32_to_floatx80(m16int);
2452   }
2453
2454   if (x87_check_exceptions())
2455      x87_write_stack(0, value, TRUE);
2456
2457   CYCLES(13);
2458}
2459
2460void i386_device::x87_fild_m32int(UINT8 modrm)
2461{
2462   floatx80 value;
2463
2464   UINT32 ea = GetEA(modrm, 0);
2465   if (!x87_dec_stack())
2466   {
2467      value = fx80_inan;
2468   }
2469   else
2470   {
2471      m_x87_sw &= ~X87_SW_C1;
2472
2473      INT32 m32int = READ32(ea);
2474      value = int32_to_floatx80(m32int);
2475   }
2476
2477   if (x87_check_exceptions())
2478      x87_write_stack(0, value, TRUE);
2479
2480   CYCLES(9);
2481}
2482
2483void i386_device::x87_fild_m64int(UINT8 modrm)
2484{
2485   floatx80 value;
2486
2487   UINT32 ea = GetEA(modrm, 0);
2488   if (!x87_dec_stack())
2489   {
2490      value = fx80_inan;
2491   }
2492   else
2493   {
2494      m_x87_sw &= ~X87_SW_C1;
2495
2496      INT64 m64int = READ64(ea);
2497      value = int64_to_floatx80(m64int);
2498   }
2499
2500   if (x87_check_exceptions())
2501      x87_write_stack(0, value, TRUE);
2502
2503   CYCLES(10);
2504}
2505
2506void i386_device::x87_fbld(UINT8 modrm)
2507{
2508   floatx80 value;
2509
2510   UINT32 ea = GetEA(modrm, 0);
2511   if (!x87_dec_stack())
2512   {
2513      value = fx80_inan;
2514   }
2515   else
2516   {
2517      m_x87_sw &= ~X87_SW_C1;
2518
2519      UINT64 m64val = 0;
2520      UINT16 sign;
2521
2522      value = READ80(ea);
2523
2524      sign = value.high & 0x8000;
2525      m64val += ((value.high >> 4) & 0xf) * 10;
2526      m64val += ((value.high >> 0) & 0xf);
2527
2528      for (int i = 60; i >= 0; i -= 4)
2529      {
2530         m64val *= 10;
2531         m64val += (value.low >> i) & 0xf;
2532      }
2533
2534      value = int64_to_floatx80(m64val);
2535      value.high |= sign;
2536   }
2537
2538   if (x87_check_exceptions())
2539      x87_write_stack(0, value, TRUE);
2540
2541   CYCLES(75);
2542}
2543
2544
2545/*************************************
2546 *
2547 * Store data
2548 *
2549 *************************************/
2550
2551void i386_device::x87_fst_m32real(UINT8 modrm)
2552{
2553   floatx80 value;
2554
2555   UINT32 ea = GetEA(modrm, 1);
2556   if (X87_IS_ST_EMPTY(0))
2557   {
2558      x87_set_stack_underflow();
2559      value = fx80_inan;
2560   }
2561   else
2562   {
2563      m_x87_sw &= ~X87_SW_C1;
2564      value = ST(0);
2565   }
2566
2567   if (x87_check_exceptions())
2568   {
2569      UINT32 m32real = floatx80_to_float32(value);
2570      WRITE32(ea, m32real);
2571   }
2572
2573   CYCLES(7);
2574}
2575
2576void i386_device::x87_fst_m64real(UINT8 modrm)
2577{
2578   floatx80 value;
2579
2580   UINT32 ea = GetEA(modrm, 1);
2581   if (X87_IS_ST_EMPTY(0))
2582   {
2583      x87_set_stack_underflow();
2584      value = fx80_inan;
2585   }
2586   else
2587   {
2588      m_x87_sw &= ~X87_SW_C1;
2589      value = ST(0);
2590   }
2591
2592   if (x87_check_exceptions())
2593   {
2594      UINT64 m64real = floatx80_to_float64(value);
2595      WRITE64(ea, m64real);
2596   }
2597
2598   CYCLES(8);
2599}
2600
2601void i386_device::x87_fst_sti(UINT8 modrm)
2602{
2603   int i = modrm & 7;
2604   floatx80 value;
2605
2606   if (X87_IS_ST_EMPTY(0))
2607   {
2608      x87_set_stack_underflow();
2609      value = fx80_inan;
2610   }
2611   else
2612   {
2613      m_x87_sw &= ~X87_SW_C1;
2614      value = ST(0);
2615   }
2616
2617   if (x87_check_exceptions())
2618      x87_write_stack(i, value, TRUE);
2619
2620   CYCLES(3);
2621}
2622
2623void i386_device::x87_fstp_m32real(UINT8 modrm)
2624{
2625   floatx80 value;
2626
2627   UINT32 ea = GetEA(modrm, 1);
2628   if (X87_IS_ST_EMPTY(0))
2629   {
2630      x87_set_stack_underflow();
2631      value = fx80_inan;
2632   }
2633   else
2634   {
2635      m_x87_sw &= ~X87_SW_C1;
2636      value = ST(0);
2637   }
2638
2639   if (x87_check_exceptions())
2640   {
2641      UINT32 m32real = floatx80_to_float32(value);
2642      WRITE32(ea, m32real);
2643      x87_inc_stack();
2644   }
2645
2646   CYCLES(7);
2647}
2648
2649void i386_device::x87_fstp_m64real(UINT8 modrm)
2650{
2651   floatx80 value;
2652
2653   if (X87_IS_ST_EMPTY(0))
2654   {
2655      x87_set_stack_underflow();
2656      value = fx80_inan;
2657   }
2658   else
2659   {
2660      m_x87_sw &= ~X87_SW_C1;
2661      value = ST(0);
2662   }
2663
2664
2665   UINT32 ea = GetEA(modrm, 1);
2666   if (x87_check_exceptions())
2667   {
2668      UINT64 m64real = floatx80_to_float64(value);
2669      WRITE64(ea, m64real);
2670      x87_inc_stack();
2671   }
2672
2673   CYCLES(8);
2674}
2675
2676void i386_device::x87_fstp_m80real(UINT8 modrm)
2677{
2678   floatx80 value;
2679
2680   if (X87_IS_ST_EMPTY(0))
2681   {
2682      x87_set_stack_underflow();
2683      value = fx80_inan;
2684   }
2685   else
2686   {
2687      m_x87_sw &= ~X87_SW_C1;
2688      value = ST(0);
2689   }
2690
2691   UINT32 ea = GetEA(modrm, 1);
2692   if (x87_check_exceptions())
2693   {
2694      WRITE80(ea, value);
2695      x87_inc_stack();
2696   }
2697
2698   CYCLES(6);
2699}
2700
2701void i386_device::x87_fstp_sti(UINT8 modrm)
2702{
2703   int i = modrm & 7;
2704   floatx80 value;
2705
2706   if (X87_IS_ST_EMPTY(0))
2707   {
2708      x87_set_stack_underflow();
2709      value = fx80_inan;
2710   }
2711   else
2712   {
2713      m_x87_sw &= ~X87_SW_C1;
2714      value = ST(0);
2715   }
2716
2717   if (x87_check_exceptions())
2718   {
2719      x87_write_stack(i, value, TRUE);
2720      x87_inc_stack();
2721   }
2722
2723   CYCLES(3);
2724}
2725
2726void i386_device::x87_fist_m16int(UINT8 modrm)
2727{
2728   INT16 m16int;
2729
2730   if (X87_IS_ST_EMPTY(0))
2731   {
2732      x87_set_stack_underflow();
2733      m16int = -32768;
2734   }
2735   else
2736   {
2737      floatx80 fx80 = floatx80_round_to_int(ST(0));
2738
2739      floatx80 lowerLim = int32_to_floatx80(-32768);
2740      floatx80 upperLim = int32_to_floatx80(32767);
2741
2742      m_x87_sw &= ~X87_SW_C1;
2743
2744      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2745         m16int = floatx80_to_int32(fx80);
2746      else
2747         m16int = -32768;
2748   }
2749
2750   UINT32 ea = GetEA(modrm, 1);
2751   if (x87_check_exceptions())
2752   {
2753      WRITE16(ea, m16int);
2754   }
2755
2756   CYCLES(29);
2757}
2758
2759void i386_device::x87_fist_m32int(UINT8 modrm)
2760{
2761   INT32 m32int;
2762
2763   if (X87_IS_ST_EMPTY(0))
2764   {
2765      x87_set_stack_underflow();
2766      m32int = 0x80000000;
2767   }
2768   else
2769   {
2770      floatx80 fx80 = floatx80_round_to_int(ST(0));
2771
2772      floatx80 lowerLim = int32_to_floatx80(0x80000000);
2773      floatx80 upperLim = int32_to_floatx80(0x7fffffff);
2774
2775      m_x87_sw &= ~X87_SW_C1;
2776
2777      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2778         m32int = floatx80_to_int32(fx80);
2779      else
2780         m32int = 0x80000000;
2781   }
2782
2783   UINT32 ea = GetEA(modrm, 1);
2784   if (x87_check_exceptions())
2785   {
2786      WRITE32(ea, m32int);
2787   }
2788
2789   CYCLES(28);
2790}
2791
2792void i386_device::x87_fistp_m16int(UINT8 modrm)
2793{
2794   INT16 m16int;
2795
2796   if (X87_IS_ST_EMPTY(0))
2797   {
2798      x87_set_stack_underflow();
2799      m16int = (UINT16)0x8000;
2800   }
2801   else
2802   {
2803      floatx80 fx80 = floatx80_round_to_int(ST(0));
2804
2805      floatx80 lowerLim = int32_to_floatx80(-32768);
2806      floatx80 upperLim = int32_to_floatx80(32767);
2807
2808      m_x87_sw &= ~X87_SW_C1;
2809
2810      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2811         m16int = floatx80_to_int32(fx80);
2812      else
2813         m16int = (UINT16)0x8000;
2814   }
2815
2816   UINT32 ea = GetEA(modrm, 1);
2817   if (x87_check_exceptions())
2818   {
2819      WRITE16(ea, m16int);
2820      x87_inc_stack();
2821   }
2822
2823   CYCLES(29);
2824}
2825
2826void i386_device::x87_fistp_m32int(UINT8 modrm)
2827{
2828   INT32 m32int;
2829
2830   if (X87_IS_ST_EMPTY(0))
2831   {
2832      x87_set_stack_underflow();
2833      m32int = 0x80000000;
2834   }
2835   else
2836   {
2837      floatx80 fx80 = floatx80_round_to_int(ST(0));
2838
2839      floatx80 lowerLim = int32_to_floatx80(0x80000000);
2840      floatx80 upperLim = int32_to_floatx80(0x7fffffff);
2841
2842      m_x87_sw &= ~X87_SW_C1;
2843
2844      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2845         m32int = floatx80_to_int32(fx80);
2846      else
2847         m32int = 0x80000000;
2848   }
2849
2850   UINT32 ea = GetEA(modrm, 1);
2851   if (x87_check_exceptions())
2852   {
2853      WRITE32(ea, m32int);
2854      x87_inc_stack();
2855   }
2856
2857   CYCLES(29);
2858}
2859
2860void i386_device::x87_fistp_m64int(UINT8 modrm)
2861{
2862   INT64 m64int;
2863
2864   if (X87_IS_ST_EMPTY(0))
2865   {
2866      x87_set_stack_underflow();
2867      m64int = U64(0x8000000000000000);
2868   }
2869   else
2870   {
2871      floatx80 fx80 = floatx80_round_to_int(ST(0));
2872
2873      floatx80 lowerLim = int64_to_floatx80(U64(0x8000000000000000));
2874      floatx80 upperLim = int64_to_floatx80(U64(0x7fffffffffffffff));
2875
2876      m_x87_sw &= ~X87_SW_C1;
2877
2878      if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
2879         m64int = floatx80_to_int64(fx80);
2880      else
2881         m64int = U64(0x8000000000000000);
2882   }
2883
2884   UINT32 ea = GetEA(modrm, 1);
2885   if (x87_check_exceptions())
2886   {
2887      WRITE64(ea, m64int);
2888      x87_inc_stack();
2889   }
2890
2891   CYCLES(29);
2892}
2893
2894void i386_device::x87_fbstp(UINT8 modrm)
2895{
2896   floatx80 result;
2897
2898   if (X87_IS_ST_EMPTY(0))
2899   {
2900      x87_set_stack_underflow();
2901      result = fx80_inan;
2902   }
2903   else
2904   {
2905      UINT64 u64 = floatx80_to_int64(floatx80_abs(ST(0)));
2906      result.low = 0;
2907
2908      for (int i = 0; i < 64; i += 4)
2909      {
2910         result.low += (u64 % 10) << i;
2911         u64 /= 10;
2912      }
2913
2914      result.high = (u64 % 10);
2915      result.high += ((u64 / 10) % 10) << 4;
2916      result.high |= ST(0).high & 0x8000;
2917   }
2918
2919   UINT32 ea = GetEA(modrm, 1);
2920   if (x87_check_exceptions())
2921   {
2922      WRITE80(ea, result);
2923      x87_inc_stack();
2924   }
2925
2926   CYCLES(175);
2927}
2928
2929
2930/*************************************
2931 *
2932 * Constant load
2933 *
2934 *************************************/
2935
2936void i386_device::x87_fld1(UINT8 modrm)
2937{
2938   floatx80 value;
2939   int tag;
2940
2941   if (x87_dec_stack())
2942   {
2943      m_x87_sw &= ~X87_SW_C1;
2944      value = fx80_one;
2945      tag = X87_TW_VALID;
2946   }
2947   else
2948   {
2949      value = fx80_inan;
2950      tag = X87_TW_SPECIAL;
2951   }
2952
2953   if (x87_check_exceptions())
2954   {
2955      x87_set_tag(ST_TO_PHYS(0), tag);
2956      x87_write_stack(0, value, FALSE);
2957   }
2958
2959   CYCLES(4);
2960}
2961
2962void i386_device::x87_fldl2t(UINT8 modrm)
2963{
2964   floatx80 value;
2965   int tag;
2966
2967   if (x87_dec_stack())
2968   {
2969      tag = X87_TW_VALID;
2970      value.high = 0x4000;
2971
2972      if (X87_RC == X87_CW_RC_UP)
2973         value.low =  U64(0xd49a784bcd1b8aff);
2974      else
2975         value.low = U64(0xd49a784bcd1b8afe);
2976
2977      m_x87_sw &= ~X87_SW_C1;
2978   }
2979   else
2980   {
2981      value = fx80_inan;
2982      tag = X87_TW_SPECIAL;
2983   }
2984
2985   if (x87_check_exceptions())
2986   {
2987      x87_set_tag(ST_TO_PHYS(0), tag);
2988      x87_write_stack(0, value, FALSE);
2989   }
2990
2991   CYCLES(8);
2992}
2993
2994void i386_device::x87_fldl2e(UINT8 modrm)
2995{
2996   floatx80 value;
2997   int tag;
2998
2999   if (x87_dec_stack())
3000   {
3001      int rc = X87_RC;
3002      tag = X87_TW_VALID;
3003      value.high = 0x3fff;
3004
3005      if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3006         value.low = U64(0xb8aa3b295c17f0bc);
3007      else
3008         value.low = U64(0xb8aa3b295c17f0bb);
3009
3010      m_x87_sw &= ~X87_SW_C1;
3011   }
3012   else
3013   {
3014      value = fx80_inan;
3015      tag = X87_TW_SPECIAL;
3016   }
3017
3018   if (x87_check_exceptions())
3019   {
3020      x87_set_tag(ST_TO_PHYS(0), tag);
3021      x87_write_stack(0, value, FALSE);
3022   }
3023
3024   CYCLES(8);
3025}
3026
3027void i386_device::x87_fldpi(UINT8 modrm)
3028{
3029   floatx80 value;
3030   int tag;
3031
3032   if (x87_dec_stack())
3033   {
3034      int rc = X87_RC;
3035      tag = X87_TW_VALID;
3036      value.high = 0x4000;
3037
3038      if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3039         value.low = U64(0xc90fdaa22168c235);
3040      else
3041         value.low = U64(0xc90fdaa22168c234);
3042
3043      m_x87_sw &= ~X87_SW_C1;
3044   }
3045   else
3046   {
3047      value = fx80_inan;
3048      tag = X87_TW_SPECIAL;
3049   }
3050
3051   if (x87_check_exceptions())
3052   {
3053      x87_set_tag(ST_TO_PHYS(0), tag);
3054      x87_write_stack(0, value, FALSE);
3055   }
3056
3057   CYCLES(8);
3058}
3059
3060void i386_device::x87_fldlg2(UINT8 modrm)
3061{
3062   floatx80 value;
3063   int tag;
3064
3065   if (x87_dec_stack())
3066   {
3067      int rc = X87_RC;
3068      tag = X87_TW_VALID;
3069      value.high = 0x3ffd;
3070
3071      if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3072         value.low = U64(0x9a209a84fbcff799);
3073      else
3074         value.low = U64(0x9a209a84fbcff798);
3075
3076      m_x87_sw &= ~X87_SW_C1;
3077   }
3078   else
3079   {
3080      value = fx80_inan;
3081      tag = X87_TW_SPECIAL;
3082   }
3083
3084   if (x87_check_exceptions())
3085   {
3086      x87_set_tag(ST_TO_PHYS(0), tag);
3087      x87_write_stack(0, value, FALSE);
3088   }
3089
3090   CYCLES(8);
3091}
3092
3093void i386_device::x87_fldln2(UINT8 modrm)
3094{
3095   floatx80 value;
3096   int tag;
3097
3098   if (x87_dec_stack())
3099   {
3100      int rc = X87_RC;
3101      tag = X87_TW_VALID;
3102      value.high = 0x3ffe;
3103
3104      if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3105         value.low = U64(0xb17217f7d1cf79ac);
3106      else
3107         value.low = U64(0xb17217f7d1cf79ab);
3108
3109      m_x87_sw &= ~X87_SW_C1;
3110   }
3111   else
3112   {
3113      value = fx80_inan;
3114      tag = X87_TW_SPECIAL;
3115   }
3116
3117   if (x87_check_exceptions())
3118   {
3119      x87_set_tag(ST_TO_PHYS(0), tag);
3120      x87_write_stack(0, value, FALSE);
3121   }
3122
3123   CYCLES(8);
3124}
3125
3126void i386_device::x87_fldz(UINT8 modrm)
3127{
3128   floatx80 value;
3129   int tag;
3130
3131   if (x87_dec_stack())
3132   {
3133      value = fx80_zero;
3134      tag = X87_TW_ZERO;
3135      m_x87_sw &= ~X87_SW_C1;
3136   }
3137   else
3138   {
3139      value = fx80_inan;
3140      tag = X87_TW_SPECIAL;
3141   }
3142
3143   if (x87_check_exceptions())
3144   {
3145      x87_set_tag(ST_TO_PHYS(0), tag);
3146      x87_write_stack(0, value, FALSE);
3147   }
3148
3149   CYCLES(4);
3150}
3151
3152
3153/*************************************
3154 *
3155 * Miscellaneous
3156 *
3157 *************************************/
3158
3159void i386_device::x87_fnop(UINT8 modrm)
3160{
3161   CYCLES(3);
3162}
3163
3164void i386_device::x87_fchs(UINT8 modrm)
3165{
3166   floatx80 value;
3167
3168   if (X87_IS_ST_EMPTY(0))
3169   {
3170      x87_set_stack_underflow();
3171      value = fx80_inan;
3172   }
3173   else
3174   {
3175      m_x87_sw &= ~X87_SW_C1;
3176
3177      value = ST(0);
3178      value.high ^= 0x8000;
3179   }
3180
3181   if (x87_check_exceptions())
3182      x87_write_stack(0, value, FALSE);
3183
3184   CYCLES(6);
3185}
3186
3187void i386_device::x87_fabs(UINT8 modrm)
3188{
3189   floatx80 value;
3190
3191   if (X87_IS_ST_EMPTY(0))
3192   {
3193      x87_set_stack_underflow();
3194      value = fx80_inan;
3195   }
3196   else
3197   {
3198      m_x87_sw &= ~X87_SW_C1;
3199
3200      value = ST(0);
3201      value.high &= 0x7fff;
3202   }
3203
3204   if (x87_check_exceptions())
3205      x87_write_stack(0, value, FALSE);
3206
3207   CYCLES(6);
3208}
3209
3210void i386_device::x87_fscale(UINT8 modrm)
3211{
3212   floatx80 value;
3213
3214   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
3215   {
3216      x87_set_stack_underflow();
3217      value = fx80_inan;
3218   }
3219   else
3220   {
3221      m_x87_sw &= ~X87_SW_C1;
3222      value = ST(0);
3223
3224      // Set the rounding mode to truncate
3225      UINT16 old_cw = m_x87_cw;
3226      UINT16 new_cw = (old_cw & ~(X87_CW_RC_MASK << X87_CW_RC_SHIFT)) | (X87_CW_RC_ZERO << X87_CW_RC_SHIFT);
3227      x87_write_cw(new_cw);
3228
3229      // Interpret ST(1) as an integer
3230      UINT32 st1 = floatx80_to_int32(floatx80_round_to_int(ST(1)));
3231
3232      // Restore the rounding mode
3233      x87_write_cw(old_cw);
3234
3235      // Get the unbiased exponent of ST(0)
3236      INT16 exp = (ST(0).high & 0x7fff) - 0x3fff;
3237
3238      // Calculate the new exponent
3239      exp = (exp + st1 + 0x3fff) & 0x7fff;
3240
3241      // Write it back
3242      value.high = (value.high & ~0x7fff) + exp;
3243   }
3244
3245   if (x87_check_exceptions())
3246      x87_write_stack(0, value, FALSE);
3247
3248   CYCLES(31);
3249}
3250
3251void i386_device::x87_frndint(UINT8 modrm)
3252{
3253   floatx80 value;
3254
3255   if (X87_IS_ST_EMPTY(0))
3256   {
3257      x87_set_stack_underflow();
3258      value = fx80_inan;
3259   }
3260   else
3261   {
3262      m_x87_sw &= ~X87_SW_C1;
3263
3264      value = floatx80_round_to_int(ST(0));
3265   }
3266
3267   if (x87_check_exceptions())
3268      x87_write_stack(0, value, TRUE);
3269
3270   CYCLES(21);
3271}
3272
3273void i386_device::x87_fxtract(UINT8 modrm)
3274{
3275   floatx80 sig80, exp80;
3276
3277   if (X87_IS_ST_EMPTY(0))
3278   {
3279      x87_set_stack_underflow();
3280      sig80 = exp80 = fx80_inan;
3281   }
3282   else if (!X87_IS_ST_EMPTY(7))
3283   {
3284      x87_set_stack_overflow();
3285      sig80 = exp80 = fx80_inan;
3286   }
3287   else
3288   {
3289      floatx80 value = ST(0);
3290
3291      if (floatx80_eq(value, fx80_zero))
3292      {
3293         m_x87_sw |= X87_SW_ZE;
3294
3295         exp80 = fx80_ninf;
3296         sig80 = fx80_zero;
3297      }
3298      else
3299      {
3300         // Extract the unbiased exponent
3301         exp80 = int32_to_floatx80((value.high & 0x7fff) - 0x3fff);
3302
3303         // For the significand, replicate the original value and set its true exponent to 0.
3304         sig80 = value;
3305         sig80.high &= ~0x7fff;
3306         sig80.high |=  0x3fff;
3307      }
3308   }
3309
3310   if (x87_check_exceptions())
3311   {
3312      x87_write_stack(0, exp80, TRUE);
3313      x87_dec_stack();
3314      x87_write_stack(0, sig80, TRUE);
3315   }
3316
3317   CYCLES(21);
3318}
3319
3320/*************************************
3321 *
3322 * Comparison
3323 *
3324 *************************************/
3325
3326void i386_device::x87_ftst(UINT8 modrm)
3327{
3328   if (X87_IS_ST_EMPTY(0))
3329   {
3330      x87_set_stack_underflow();
3331      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3332   }
3333   else
3334   {
3335      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3336
3337      if (floatx80_is_nan(ST(0)))
3338      {
3339         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3340         m_x87_sw |= X87_SW_IE;
3341      }
3342      else
3343      {
3344         if (floatx80_eq(ST(0), fx80_zero))
3345            m_x87_sw |= X87_SW_C3;
3346
3347         if (floatx80_lt(ST(0), fx80_zero))
3348            m_x87_sw |= X87_SW_C0;
3349      }
3350   }
3351
3352   x87_check_exceptions();
3353
3354   CYCLES(4);
3355}
3356
3357void i386_device::x87_fxam(UINT8 modrm)
3358{
3359   floatx80 value = ST(0);
3360
3361   m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3362
3363   // TODO: Unsupported and denormal values
3364   if (X87_IS_ST_EMPTY(0))
3365   {
3366      m_x87_sw |= X87_SW_C3 | X87_SW_C0;
3367   }
3368   else if (floatx80_is_zero(value))
3369   {
3370      m_x87_sw |= X87_SW_C3;
3371   }
3372   if (floatx80_is_nan(value))
3373   {
3374      m_x87_sw |= X87_SW_C0;
3375   }
3376   else if (floatx80_is_inf(value))
3377   {
3378      m_x87_sw |= X87_SW_C2 | X87_SW_C0;
3379   }
3380   else
3381   {
3382      m_x87_sw |= X87_SW_C2;
3383   }
3384
3385   if (value.high & 0x8000)
3386      m_x87_sw |= X87_SW_C1;
3387
3388   CYCLES(8);
3389}
3390
3391void i386_device::x87_ficom_m16int(UINT8 modrm)
3392{
3393   UINT32 ea = GetEA(modrm, 0);
3394   if (X87_IS_ST_EMPTY(0))
3395   {
3396      x87_set_stack_underflow();
3397      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3398   }
3399   else
3400   {
3401      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3402
3403      INT16 m16int = READ16(ea);
3404
3405      floatx80 a = ST(0);
3406      floatx80 b = int32_to_floatx80(m16int);
3407
3408      if (floatx80_is_nan(a))
3409      {
3410         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3411         m_x87_sw |= X87_SW_IE;
3412      }
3413      else
3414      {
3415         if (floatx80_eq(a, b))
3416            m_x87_sw |= X87_SW_C3;
3417
3418         if (floatx80_lt(a, b))
3419            m_x87_sw |= X87_SW_C0;
3420      }
3421   }
3422
3423   x87_check_exceptions();
3424
3425   CYCLES(16);
3426}
3427
3428void i386_device::x87_ficom_m32int(UINT8 modrm)
3429{
3430   UINT32 ea = GetEA(modrm, 0);
3431   if (X87_IS_ST_EMPTY(0))
3432   {
3433      x87_set_stack_underflow();
3434      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3435   }
3436   else
3437   {
3438      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3439
3440      INT32 m32int = READ32(ea);
3441
3442      floatx80 a = ST(0);
3443      floatx80 b = int32_to_floatx80(m32int);
3444
3445      if (floatx80_is_nan(a))
3446      {
3447         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3448         m_x87_sw |= X87_SW_IE;
3449      }
3450      else
3451      {
3452         if (floatx80_eq(a, b))
3453            m_x87_sw |= X87_SW_C3;
3454
3455         if (floatx80_lt(a, b))
3456            m_x87_sw |= X87_SW_C0;
3457      }
3458   }
3459
3460   x87_check_exceptions();
3461
3462   CYCLES(15);
3463}
3464
3465void i386_device::x87_ficomp_m16int(UINT8 modrm)
3466{
3467   UINT32 ea = GetEA(modrm, 0);
3468   if (X87_IS_ST_EMPTY(0))
3469   {
3470      x87_set_stack_underflow();
3471      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3472   }
3473   else
3474   {
3475      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3476
3477      INT16 m16int = READ16(ea);
3478
3479      floatx80 a = ST(0);
3480      floatx80 b = int32_to_floatx80(m16int);
3481
3482      if (floatx80_is_nan(a))
3483      {
3484         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3485         m_x87_sw |= X87_SW_IE;
3486      }
3487      else
3488      {
3489         if (floatx80_eq(a, b))
3490            m_x87_sw |= X87_SW_C3;
3491
3492         if (floatx80_lt(a, b))
3493            m_x87_sw |= X87_SW_C0;
3494      }
3495   }
3496
3497   if (x87_check_exceptions())
3498      x87_inc_stack();
3499
3500   CYCLES(16);
3501}
3502
3503void i386_device::x87_ficomp_m32int(UINT8 modrm)
3504{
3505   UINT32 ea = GetEA(modrm, 0);
3506   if (X87_IS_ST_EMPTY(0))
3507   {
3508      x87_set_stack_underflow();
3509      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3510   }
3511   else
3512   {
3513      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3514
3515      INT32 m32int = READ32(ea);
3516
3517      floatx80 a = ST(0);
3518      floatx80 b = int32_to_floatx80(m32int);
3519
3520      if (floatx80_is_nan(a))
3521      {
3522         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3523         m_x87_sw |= X87_SW_IE;
3524      }
3525      else
3526      {
3527         if (floatx80_eq(a, b))
3528            m_x87_sw |= X87_SW_C3;
3529
3530         if (floatx80_lt(a, b))
3531            m_x87_sw |= X87_SW_C0;
3532      }
3533   }
3534
3535   if (x87_check_exceptions())
3536      x87_inc_stack();
3537
3538   CYCLES(15);
3539}
3540
3541
3542void i386_device::x87_fcom_m32real(UINT8 modrm)
3543{
3544   UINT32 ea = GetEA(modrm, 0);
3545   if (X87_IS_ST_EMPTY(0))
3546   {
3547      x87_set_stack_underflow();
3548      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3549   }
3550   else
3551   {
3552      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3553
3554      UINT32 m32real = READ32(ea);
3555
3556      floatx80 a = ST(0);
3557      floatx80 b = float32_to_floatx80(m32real);
3558
3559      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3560      {
3561         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3562         m_x87_sw |= X87_SW_IE;
3563      }
3564      else
3565      {
3566         if (floatx80_eq(a, b))
3567            m_x87_sw |= X87_SW_C3;
3568
3569         if (floatx80_lt(a, b))
3570            m_x87_sw |= X87_SW_C0;
3571      }
3572   }
3573
3574   x87_check_exceptions();
3575
3576   CYCLES(4);
3577}
3578
3579void i386_device::x87_fcom_m64real(UINT8 modrm)
3580{
3581   UINT32 ea = GetEA(modrm, 0);
3582   if (X87_IS_ST_EMPTY(0))
3583   {
3584      x87_set_stack_underflow();
3585      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3586   }
3587   else
3588   {
3589      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3590
3591      UINT64 m64real = READ64(ea);
3592
3593      floatx80 a = ST(0);
3594      floatx80 b = float64_to_floatx80(m64real);
3595
3596      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3597      {
3598         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3599         m_x87_sw |= X87_SW_IE;
3600      }
3601      else
3602      {
3603         if (floatx80_eq(a, b))
3604            m_x87_sw |= X87_SW_C3;
3605
3606         if (floatx80_lt(a, b))
3607            m_x87_sw |= X87_SW_C0;
3608      }
3609   }
3610
3611   x87_check_exceptions();
3612
3613   CYCLES(4);
3614}
3615
3616void i386_device::x87_fcom_sti(UINT8 modrm)
3617{
3618   int i = modrm & 7;
3619
3620   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3621   {
3622      x87_set_stack_underflow();
3623      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3624   }
3625   else
3626   {
3627      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3628
3629      floatx80 a = ST(0);
3630      floatx80 b = ST(i);
3631
3632      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3633      {
3634         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3635         m_x87_sw |= X87_SW_IE;
3636      }
3637      else
3638      {
3639         if (floatx80_eq(a, b))
3640            m_x87_sw |= X87_SW_C3;
3641
3642         if (floatx80_lt(a, b))
3643            m_x87_sw |= X87_SW_C0;
3644      }
3645   }
3646
3647   x87_check_exceptions();
3648
3649   CYCLES(4);
3650}
3651
3652void i386_device::x87_fcomp_m32real(UINT8 modrm)
3653{
3654   UINT32 ea = GetEA(modrm, 0);
3655   if (X87_IS_ST_EMPTY(0))
3656   {
3657      x87_set_stack_underflow();
3658      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3659   }
3660   else
3661   {
3662      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3663
3664      UINT32 m32real = READ32(ea);
3665
3666      floatx80 a = ST(0);
3667      floatx80 b = float32_to_floatx80(m32real);
3668
3669      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3670      {
3671         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3672         m_x87_sw |= X87_SW_IE;
3673      }
3674      else
3675      {
3676         if (floatx80_eq(a, b))
3677            m_x87_sw |= X87_SW_C3;
3678
3679         if (floatx80_lt(a, b))
3680            m_x87_sw |= X87_SW_C0;
3681      }
3682   }
3683
3684   if (x87_check_exceptions())
3685      x87_inc_stack();
3686
3687   CYCLES(4);
3688}
3689
3690void i386_device::x87_fcomp_m64real(UINT8 modrm)
3691{
3692   UINT32 ea = GetEA(modrm, 0);
3693   if (X87_IS_ST_EMPTY(0))
3694   {
3695      x87_set_stack_underflow();
3696      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3697   }
3698   else
3699   {
3700      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3701
3702      UINT64 m64real = READ64(ea);
3703
3704      floatx80 a = ST(0);
3705      floatx80 b = float64_to_floatx80(m64real);
3706
3707      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3708      {
3709         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3710         m_x87_sw |= X87_SW_IE;
3711      }
3712      else
3713      {
3714         if (floatx80_eq(a, b))
3715            m_x87_sw |= X87_SW_C3;
3716
3717         if (floatx80_lt(a, b))
3718            m_x87_sw |= X87_SW_C0;
3719      }
3720   }
3721
3722   if (x87_check_exceptions())
3723      x87_inc_stack();
3724
3725   CYCLES(4);
3726}
3727
3728void i386_device::x87_fcomp_sti(UINT8 modrm)
3729{
3730   int i = modrm & 7;
3731
3732   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3733   {
3734      x87_set_stack_underflow();
3735      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3736   }
3737   else
3738   {
3739      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3740
3741      floatx80 a = ST(0);
3742      floatx80 b = ST(i);
3743
3744      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3745      {
3746         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3747         m_x87_sw |= X87_SW_IE;
3748      }
3749      else
3750      {
3751         if (floatx80_eq(a, b))
3752            m_x87_sw |= X87_SW_C3;
3753
3754         if (floatx80_lt(a, b))
3755            m_x87_sw |= X87_SW_C0;
3756      }
3757   }
3758
3759   if (x87_check_exceptions())
3760      x87_inc_stack();
3761
3762   CYCLES(4);
3763}
3764
3765void i386_device::x87_fcomip_sti(UINT8 modrm)
3766{
3767   int i = modrm & 7;
3768
3769   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3770   {
3771      x87_set_stack_underflow();
3772      m_ZF = 1;
3773      m_PF = 1;
3774      m_CF = 1;
3775   }
3776   else
3777   {
3778      m_x87_sw &= ~X87_SW_C1;
3779
3780      floatx80 a = ST(0);
3781      floatx80 b = ST(i);
3782
3783      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3784      {
3785         m_ZF = 1;
3786         m_PF = 1;
3787         m_CF = 1;
3788         m_x87_sw |= X87_SW_IE;
3789      }
3790      else
3791      {
3792         m_ZF = 0;
3793         m_PF = 0;
3794         m_CF = 0;
3795
3796         if (floatx80_eq(a, b))
3797            m_ZF = 1;
3798
3799         if (floatx80_lt(a, b))
3800            m_CF = 1;
3801      }
3802   }
3803
3804   if (x87_check_exceptions())
3805      x87_inc_stack();
3806
3807   CYCLES(4); // TODO: correct cycle count
3808}
3809
3810void i386_device::x87_fcompp(UINT8 modrm)
3811{
3812   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
3813   {
3814      x87_set_stack_underflow();
3815      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3816   }
3817   else
3818   {
3819      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3820
3821      floatx80 a = ST(0);
3822      floatx80 b = ST(1);
3823
3824      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3825      {
3826         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3827         m_x87_sw |= X87_SW_IE;
3828      }
3829      else
3830      {
3831         if (floatx80_eq(a, b))
3832            m_x87_sw |= X87_SW_C3;
3833
3834         if (floatx80_lt(a, b))
3835            m_x87_sw |= X87_SW_C0;
3836      }
3837   }
3838
3839   if (x87_check_exceptions())
3840   {
3841      x87_inc_stack();
3842      x87_inc_stack();
3843   }
3844
3845   CYCLES(5);
3846}
3847
3848
3849/*************************************
3850 *
3851 * Unordererd comparison
3852 *
3853 *************************************/
3854
3855void i386_device::x87_fucom_sti(UINT8 modrm)
3856{
3857   int i = modrm & 7;
3858
3859   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3860   {
3861      x87_set_stack_underflow();
3862      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3863   }
3864   else
3865   {
3866      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3867
3868      floatx80 a = ST(0);
3869      floatx80 b = ST(i);
3870
3871      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3872      {
3873         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3874
3875         if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
3876            m_x87_sw |= X87_SW_IE;
3877      }
3878      else
3879      {
3880         if (floatx80_eq(a, b))
3881            m_x87_sw |= X87_SW_C3;
3882
3883         if (floatx80_lt(a, b))
3884            m_x87_sw |= X87_SW_C0;
3885      }
3886   }
3887
3888   x87_check_exceptions();
3889
3890   CYCLES(4);
3891}
3892
3893void i386_device::x87_fucomp_sti(UINT8 modrm)
3894{
3895   int i = modrm & 7;
3896
3897   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3898   {
3899      x87_set_stack_underflow();
3900      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3901   }
3902   else
3903   {
3904      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3905
3906      floatx80 a = ST(0);
3907      floatx80 b = ST(i);
3908
3909      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3910      {
3911         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3912
3913         if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
3914            m_x87_sw |= X87_SW_IE;
3915      }
3916      else
3917      {
3918         if (floatx80_eq(a, b))
3919            m_x87_sw |= X87_SW_C3;
3920
3921         if (floatx80_lt(a, b))
3922            m_x87_sw |= X87_SW_C0;
3923      }
3924   }
3925
3926   if (x87_check_exceptions())
3927      x87_inc_stack();
3928
3929   CYCLES(4);
3930}
3931
3932void i386_device::x87_fucompp(UINT8 modrm)
3933{
3934   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
3935   {
3936      x87_set_stack_underflow();
3937      m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3938   }
3939   else
3940   {
3941      m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3942
3943      floatx80 a = ST(0);
3944      floatx80 b = ST(1);
3945
3946      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3947      {
3948         m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3949
3950         if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
3951            m_x87_sw |= X87_SW_IE;
3952      }
3953      else
3954      {
3955         if (floatx80_eq(a, b))
3956            m_x87_sw |= X87_SW_C3;
3957
3958         if (floatx80_lt(a, b))
3959            m_x87_sw |= X87_SW_C0;
3960      }
3961   }
3962
3963   if (x87_check_exceptions())
3964   {
3965      x87_inc_stack();
3966      x87_inc_stack();
3967   }
3968
3969   CYCLES(4);
3970}
3971
3972
3973/*************************************
3974 *
3975 * Control
3976 *
3977 *************************************/
3978
3979void i386_device::x87_fdecstp(UINT8 modrm)
3980{
3981   m_x87_sw &= ~X87_SW_C1;
3982
3983   x87_dec_stack();
3984   x87_check_exceptions();
3985
3986   CYCLES(3);
3987}
3988
3989void i386_device::x87_fincstp(UINT8 modrm)
3990{
3991   m_x87_sw &= ~X87_SW_C1;
3992
3993   x87_inc_stack();
3994   x87_check_exceptions();
3995
3996   CYCLES(3);
3997}
3998
3999void i386_device::x87_fclex(UINT8 modrm)
4000{
4001   m_x87_sw &= ~0x80ff;
4002
4003   CYCLES(7);
4004}
4005
4006void i386_device::x87_ffree(UINT8 modrm)
4007{
4008   x87_set_tag(ST_TO_PHYS(modrm & 7), X87_TW_EMPTY);
4009
4010   CYCLES(3);
4011}
4012
4013void i386_device::x87_finit(UINT8 modrm)
4014{
4015   x87_reset();
4016
4017   CYCLES(17);
4018}
4019
4020void i386_device::x87_fldcw(UINT8 modrm)
4021{
4022   UINT32 ea = GetEA(modrm, 0);
4023   UINT16 cw = READ16(ea);
4024
4025   x87_write_cw(cw);
4026
4027   x87_check_exceptions();
4028
4029   CYCLES(4);
4030}
4031
4032void i386_device::x87_fstcw(UINT8 modrm)
4033{
4034   UINT32 ea = GetEA(modrm, 1);
4035   WRITE16(ea, m_x87_cw);
4036
4037   CYCLES(3);
4038}
4039
4040void i386_device::x87_fldenv(UINT8 modrm)
4041{
4042   // TODO: Pointers and selectors
4043   UINT32 ea = GetEA(modrm, 0);
4044
4045   if (m_operand_size)
4046   {
4047      // 32-bit real/protected mode
4048      x87_write_cw(READ16(ea));
4049      m_x87_sw = READ16(ea + 4);
4050      m_x87_tw = READ16(ea + 8);
4051   }
4052   else
4053   {
4054      // 16-bit real/protected mode
4055      x87_write_cw(READ16(ea));
4056      m_x87_sw = READ16(ea + 2);
4057      m_x87_tw = READ16(ea + 4);
4058   }
4059
4060   x87_check_exceptions();
4061
4062   CYCLES((m_cr[0] & 1) ? 34 : 44);
4063}
4064
4065void i386_device::x87_fstenv(UINT8 modrm)
4066{
4067   UINT32 ea = GetEA(modrm, 1);
4068
4069   // TODO: Pointers and selectors
4070   switch((m_cr[0] & 1)|(m_operand_size & 1)<<1)
4071   {
4072      case 0: // 16-bit real mode
4073         WRITE16(ea + 0, m_x87_cw);
4074         WRITE16(ea + 2, m_x87_sw);
4075         WRITE16(ea + 4, m_x87_tw);
4076//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4077//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4078//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4079//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4080         break;
4081      case 1: // 16-bit protected mode
4082         WRITE16(ea + 0, m_x87_cw);
4083         WRITE16(ea + 2, m_x87_sw);
4084         WRITE16(ea + 4, m_x87_tw);
4085//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4086//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4087//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4088//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4089         break;
4090      case 2: // 32-bit real mode
4091         WRITE16(ea + 0, m_x87_cw);
4092         WRITE16(ea + 4, m_x87_sw);
4093         WRITE16(ea + 8, m_x87_tw);
4094//          WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff);
4095//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4096//          WRITE16(ea + 20, m_fpu_data_ptr & 0xffff);
4097//          WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4098//          WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12);
4099         break;
4100      case 3: // 32-bit protected mode
4101         WRITE16(ea + 0,  m_x87_cw);
4102         WRITE16(ea + 4,  m_x87_sw);
4103         WRITE16(ea + 8,  m_x87_tw);
4104//          WRITE32(ea + 12, m_fpu_inst_ptr);
4105//          WRITE32(ea + 16, m_fpu_opcode);
4106//          WRITE32(ea + 20, m_fpu_data_ptr);
4107//          WRITE32(ea + 24, m_fpu_inst_ptr);
4108         break;
4109   }
4110
4111   CYCLES((m_cr[0] & 1) ? 56 : 67);
4112}
4113
4114void i386_device::x87_fsave(UINT8 modrm)
4115{
4116   UINT32 ea = GetEA(modrm, 1);
4117
4118   // TODO: Pointers and selectors
4119   switch((m_cr[0] & 1)|(m_operand_size & 1)<<1)
4120   {
4121      case 0: // 16-bit real mode
4122         WRITE16(ea + 0, m_x87_cw);
4123         WRITE16(ea + 2, m_x87_sw);
4124         WRITE16(ea + 4, m_x87_tw);
4125//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4126//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4127//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4128//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4129         ea += 14;
4130         break;
4131      case 1: // 16-bit protected mode
4132         WRITE16(ea + 0, m_x87_cw);
4133         WRITE16(ea + 2, m_x87_sw);
4134         WRITE16(ea + 4, m_x87_tw);
4135//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4136//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4137//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4138//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4139         ea += 14;
4140         break;
4141      case 2: // 32-bit real mode
4142         WRITE16(ea + 0, m_x87_cw);
4143         WRITE16(ea + 4, m_x87_sw);
4144         WRITE16(ea + 8, m_x87_tw);
4145//          WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff);
4146//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4147//          WRITE16(ea + 20, m_fpu_data_ptr & 0xffff);
4148//          WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4149//          WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12);
4150         ea += 28;
4151         break;
4152      case 3: // 32-bit protected mode
4153         WRITE16(ea + 0,  m_x87_cw);
4154         WRITE16(ea + 4,  m_x87_sw);
4155         WRITE16(ea + 8,  m_x87_tw);
4156//          WRITE32(ea + 12, m_fpu_inst_ptr);
4157//          WRITE32(ea + 16, m_fpu_opcode);
4158//          WRITE32(ea + 20, m_fpu_data_ptr);
4159//          WRITE32(ea + 24, m_fpu_inst_ptr);
4160         ea += 28;
4161         break;
4162   }
4163
4164   for (int i = 0; i < 8; ++i)
4165      x87_write_stack(i, READ80(ea + i*10), FALSE);
4166
4167   CYCLES((m_cr[0] & 1) ? 56 : 67);
4168}
4169
4170void i386_device::x87_frstor(UINT8 modrm)
4171{
4172   UINT32 ea = GetEA(modrm, 0);
4173
4174   // TODO: Pointers and selectors
4175   switch((m_cr[0] & 1)|(m_operand_size & 1)<<1)
4176   {
4177      case 0: // 16-bit real mode
4178         x87_write_cw(READ16(ea));
4179         m_x87_sw = READ16(ea + 2);
4180         m_x87_tw = READ16(ea + 4);
4181//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4182//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4183//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4184//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4185         ea += 14;
4186         break;
4187      case 1: // 16-bit protected mode
4188         x87_write_cw(READ16(ea));
4189         m_x87_sw = READ16(ea + 2);
4190         m_x87_tw = READ16(ea + 4);
4191//          WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
4192//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4193//          WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
4194//          WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
4195         ea += 14;
4196         break;
4197      case 2: // 32-bit real mode
4198         x87_write_cw(READ16(ea));
4199         m_x87_sw = READ16(ea + 4);
4200         m_x87_tw = READ16(ea + 8);
4201//          WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff);
4202//          WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4203//          WRITE16(ea + 20, m_fpu_data_ptr & 0xffff);
4204//          WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4));
4205//          WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12);
4206         ea += 28;
4207         break;
4208      case 3: // 32-bit protected mode
4209         x87_write_cw(READ16(ea));
4210         m_x87_sw = READ16(ea + 4);
4211         m_x87_tw = READ16(ea + 8);
4212//          WRITE32(ea + 12, m_fpu_inst_ptr);
4213//          WRITE32(ea + 16, m_fpu_opcode);
4214//          WRITE32(ea + 20, m_fpu_data_ptr);
4215//          WRITE32(ea + 24, m_fpu_inst_ptr);
4216         ea += 28;
4217         break;
4218   }
4219
4220   for (int i = 0; i < 8; ++i)
4221      WRITE80(ea + i*10, ST(i));
4222
4223   CYCLES((m_cr[0] & 1) ? 34 : 44);
4224}
4225
4226void i386_device::x87_fxch(UINT8 modrm)
4227{
4228   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
4229      x87_set_stack_underflow();
4230
4231   if (x87_check_exceptions())
4232   {
4233      floatx80 tmp = ST(0);
4234      ST(0) = ST(1);
4235      ST(1) = tmp;
4236
4237      // Swap the tags
4238      int tag0 = X87_TAG(ST_TO_PHYS(0));
4239      x87_set_tag(ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(1)));
4240      x87_set_tag(ST_TO_PHYS(1), tag0);
4241   }
4242
4243   CYCLES(4);
4244}
4245
4246void i386_device::x87_fxch_sti(UINT8 modrm)
4247{
4248   int i = modrm & 7;
4249
4250   if (X87_IS_ST_EMPTY(0))
4251   {
4252      ST(0) = fx80_inan;
4253      x87_set_tag(ST_TO_PHYS(0), X87_TW_SPECIAL);
4254      x87_set_stack_underflow();
4255   }
4256   if (X87_IS_ST_EMPTY(i))
4257   {
4258      ST(i) = fx80_inan;
4259      x87_set_tag(ST_TO_PHYS(i), X87_TW_SPECIAL);
4260      x87_set_stack_underflow();
4261   }
4262
4263   if (x87_check_exceptions())
4264   {
4265      floatx80 tmp = ST(0);
4266      ST(0) = ST(i);
4267      ST(i) = tmp;
4268
4269      // Swap the tags
4270      int tag0 = X87_TAG(ST_TO_PHYS(0));
4271      x87_set_tag(ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(i)));
4272      x87_set_tag(ST_TO_PHYS(i), tag0);
4273   }
4274
4275   CYCLES(4);
4276}
4277
4278void i386_device::x87_fstsw_ax(UINT8 modrm)
4279{
4280   REG16(AX) = m_x87_sw;
4281
4282   CYCLES(3);
4283}
4284
4285void i386_device::x87_fstsw_m2byte(UINT8 modrm)
4286{
4287   UINT32 ea = GetEA(modrm, 1);
4288
4289   WRITE16(ea, m_x87_sw);
4290
4291   CYCLES(3);
4292}
4293
4294void i386_device::x87_invalid(UINT8 modrm)
4295{
4296   // TODO
4297   fatalerror("x87 invalid instruction (PC:%.4x)\n", m_pc);
4298}
4299
4300
4301
4302/*************************************
4303 *
4304 * Instruction dispatch
4305 *
4306 *************************************/
4307
4308void i386_device::i386_x87_group_d8()
4309{
4310   UINT8 modrm = FETCH();
4311   (this->*m_opcode_table_x87_d8[modrm])(modrm);
4312}
4313
4314void i386_device::i386_x87_group_d9()
4315{
4316   UINT8 modrm = FETCH();
4317   (this->*m_opcode_table_x87_d9[modrm])(modrm);
4318}
4319
4320void i386_device::i386_x87_group_da()
4321{
4322   UINT8 modrm = FETCH();
4323   (this->*m_opcode_table_x87_da[modrm])(modrm);
4324}
4325
4326void i386_device::i386_x87_group_db()
4327{
4328   UINT8 modrm = FETCH();
4329   (this->*m_opcode_table_x87_db[modrm])(modrm);
4330}
4331
4332void i386_device::i386_x87_group_dc()
4333{
4334   UINT8 modrm = FETCH();
4335   (this->*m_opcode_table_x87_dc[modrm])(modrm);
4336}
4337
4338void i386_device::i386_x87_group_dd()
4339{
4340   UINT8 modrm = FETCH();
4341   (this->*m_opcode_table_x87_dd[modrm])(modrm);
4342}
4343
4344void i386_device::i386_x87_group_de()
4345{
4346   UINT8 modrm = FETCH();
4347   (this->*m_opcode_table_x87_de[modrm])(modrm);
4348}
4349
4350void i386_device::i386_x87_group_df()
4351{
4352   UINT8 modrm = FETCH();
4353   (this->*m_opcode_table_x87_df[modrm])(modrm);
4354}
4355
4356
4357/*************************************
4358 *
4359 * Opcode table building
4360 *
4361 *************************************/
4362
4363void i386_device::build_x87_opcode_table_d8()
4364{
4365   int modrm = 0;
4366
4367   for (modrm = 0; modrm < 0x100; ++modrm)
4368   {
4369      i386_modrm_func ptr = &i386_device::x87_invalid;
4370
4371      if (modrm < 0xc0)
4372      {
4373         switch ((modrm >> 3) & 0x7)
4374         {
4375            case 0x00: ptr = &i386_device::x87_fadd_m32real;  break;
4376            case 0x01: ptr = &i386_device::x87_fmul_m32real;  break;
4377            case 0x02: ptr = &i386_device::x87_fcom_m32real;  break;
4378            case 0x03: ptr = &i386_device::x87_fcomp_m32real; break;
4379            case 0x04: ptr = &i386_device::x87_fsub_m32real;  break;
4380            case 0x05: ptr = &i386_device::x87_fsubr_m32real; break;
4381            case 0x06: ptr = &i386_device::x87_fdiv_m32real;  break;
4382            case 0x07: ptr = &i386_device::x87_fdivr_m32real; break;
4383         }
4384      }
4385      else
4386      {
4387         switch (modrm)
4388         {
4389            case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_fadd_st_sti;  break;
4390            case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fmul_st_sti;  break;
4391            case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = &i386_device::x87_fcom_sti;     break;
4392            case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = &i386_device::x87_fcomp_sti;    break;
4393            case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fsub_st_sti;  break;
4394            case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fsubr_st_sti; break;
4395            case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fdiv_st_sti;  break;
4396            case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = &i386_device::x87_fdivr_st_sti; break;
4397         }
4398      }
4399
4400      m_opcode_table_x87_d8[modrm] = ptr;
4401   }
4402}
4403
4404
4405void i386_device::build_x87_opcode_table_d9()
4406{
4407   int modrm = 0;
4408
4409   for (modrm = 0; modrm < 0x100; ++modrm)
4410   {
4411      i386_modrm_func ptr = &i386_device::x87_invalid;
4412
4413      if (modrm < 0xc0)
4414      {
4415         switch ((modrm >> 3) & 0x7)
4416         {
4417            case 0x00: ptr = &i386_device::x87_fld_m32real;   break;
4418            case 0x02: ptr = &i386_device::x87_fst_m32real;   break;
4419            case 0x03: ptr = &i386_device::x87_fstp_m32real;  break;
4420            case 0x04: ptr = &i386_device::x87_fldenv;        break;
4421            case 0x05: ptr = &i386_device::x87_fldcw;         break;
4422            case 0x06: ptr = &i386_device::x87_fstenv;        break;
4423            case 0x07: ptr = &i386_device::x87_fstcw;         break;
4424         }
4425      }
4426      else
4427      {
4428         switch (modrm)
4429         {
4430            case 0xc0:
4431            case 0xc1:
4432            case 0xc2:
4433            case 0xc3:
4434            case 0xc4:
4435            case 0xc5:
4436            case 0xc6:
4437            case 0xc7: ptr = &i386_device::x87_fld_sti;   break;
4438
4439            case 0xc8:
4440            case 0xc9:
4441            case 0xca:
4442            case 0xcb:
4443            case 0xcc:
4444            case 0xcd:
4445            case 0xce:
4446            case 0xcf: ptr = &i386_device::x87_fxch_sti;  break;
4447
4448            case 0xd0: ptr = &i386_device::x87_fnop;      break;
4449            case 0xe0: ptr = &i386_device::x87_fchs;      break;
4450            case 0xe1: ptr = &i386_device::x87_fabs;      break;
4451            case 0xe4: ptr = &i386_device::x87_ftst;      break;
4452            case 0xe5: ptr = &i386_device::x87_fxam;      break;
4453            case 0xe8: ptr = &i386_device::x87_fld1;      break;
4454            case 0xe9: ptr = &i386_device::x87_fldl2t;    break;
4455            case 0xea: ptr = &i386_device::x87_fldl2e;    break;
4456            case 0xeb: ptr = &i386_device::x87_fldpi;     break;
4457            case 0xec: ptr = &i386_device::x87_fldlg2;    break;
4458            case 0xed: ptr = &i386_device::x87_fldln2;    break;
4459            case 0xee: ptr = &i386_device::x87_fldz;      break;
4460            case 0xf0: ptr = &i386_device::x87_f2xm1;     break;
4461            case 0xf1: ptr = &i386_device::x87_fyl2x;     break;
4462            case 0xf2: ptr = &i386_device::x87_fptan;     break;
4463            case 0xf3: ptr = &i386_device::x87_fpatan;    break;
4464            case 0xf4: ptr = &i386_device::x87_fxtract;   break;
4465            case 0xf5: ptr = &i386_device::x87_fprem1;    break;
4466            case 0xf6: ptr = &i386_device::x87_fdecstp;   break;
4467            case 0xf7: ptr = &i386_device::x87_fincstp;   break;
4468            case 0xf8: ptr = &i386_device::x87_fprem;     break;
4469            case 0xf9: ptr = &i386_device::x87_fyl2xp1;   break;
4470            case 0xfa: ptr = &i386_device::x87_fsqrt;     break;
4471            case 0xfb: ptr = &i386_device::x87_fsincos;   break;
4472            case 0xfc: ptr = &i386_device::x87_frndint;   break;
4473            case 0xfd: ptr = &i386_device::x87_fscale;    break;
4474            case 0xfe: ptr = &i386_device::x87_fsin;      break;
4475            case 0xff: ptr = &i386_device::x87_fcos;      break;
4476         }
4477      }
4478
4479      m_opcode_table_x87_d9[modrm] = ptr;
4480   }
4481}
4482
4483void i386_device::build_x87_opcode_table_da()
4484{
4485   int modrm = 0;
4486
4487   for (modrm = 0; modrm < 0x100; ++modrm)
4488   {
4489      i386_modrm_func ptr = &i386_device::x87_invalid;
4490
4491      if (modrm < 0xc0)
4492      {
4493         switch ((modrm >> 3) & 0x7)
4494         {
4495            case 0x00: ptr = &i386_device::x87_fiadd_m32int;  break;
4496            case 0x01: ptr = &i386_device::x87_fimul_m32int;  break;
4497            case 0x02: ptr = &i386_device::x87_ficom_m32int;  break;
4498            case 0x03: ptr = &i386_device::x87_ficomp_m32int; break;
4499            case 0x04: ptr = &i386_device::x87_fisub_m32int;  break;
4500            case 0x05: ptr = &i386_device::x87_fisubr_m32int; break;
4501            case 0x06: ptr = &i386_device::x87_fidiv_m32int;  break;
4502            case 0x07: ptr = &i386_device::x87_fidivr_m32int; break;
4503         }
4504      }
4505      else
4506      {
4507         switch (modrm)
4508         {
4509            case 0xe9: ptr = &i386_device::x87_fucompp;       break;
4510         }
4511      }
4512
4513      m_opcode_table_x87_da[modrm] = ptr;
4514   }
4515}
4516
4517
4518void i386_device::build_x87_opcode_table_db()
4519{
4520   int modrm = 0;
4521
4522   for (modrm = 0; modrm < 0x100; ++modrm)
4523   {
4524      i386_modrm_func ptr = &i386_device::x87_invalid;
4525
4526      if (modrm < 0xc0)
4527      {
4528         switch ((modrm >> 3) & 0x7)
4529         {
4530            case 0x00: ptr = &i386_device::x87_fild_m32int;   break;
4531            case 0x02: ptr = &i386_device::x87_fist_m32int;   break;
4532            case 0x03: ptr = &i386_device::x87_fistp_m32int;  break;
4533            case 0x05: ptr = &i386_device::x87_fld_m80real;   break;
4534            case 0x07: ptr = &i386_device::x87_fstp_m80real;  break;
4535         }
4536      }
4537      else
4538      {
4539         switch (modrm)
4540         {
4541            case 0xe0: ptr = &i386_device::x87_fnop;          break; /* FENI */
4542            case 0xe1: ptr = &i386_device::x87_fnop;          break; /* FDISI */
4543            case 0xe2: ptr = &i386_device::x87_fclex;         break;
4544            case 0xe3: ptr = &i386_device::x87_finit;         break;
4545            case 0xe4: ptr = &i386_device::x87_fnop;          break; /* FSETPM */
4546         }
4547      }
4548
4549      m_opcode_table_x87_db[modrm] = ptr;
4550   }
4551}
4552
4553
4554void i386_device::build_x87_opcode_table_dc()
4555{
4556   int modrm = 0;
4557
4558   for (modrm = 0; modrm < 0x100; ++modrm)
4559   {
4560      i386_modrm_func ptr = &i386_device::x87_invalid;
4561
4562      if (modrm < 0xc0)
4563      {
4564         switch ((modrm >> 3) & 0x7)
4565         {
4566            case 0x00: ptr = &i386_device::x87_fadd_m64real;  break;
4567            case 0x01: ptr = &i386_device::x87_fmul_m64real;  break;
4568            case 0x02: ptr = &i386_device::x87_fcom_m64real;  break;
4569            case 0x03: ptr = &i386_device::x87_fcomp_m64real; break;
4570            case 0x04: ptr = &i386_device::x87_fsub_m64real;  break;
4571            case 0x05: ptr = &i386_device::x87_fsubr_m64real; break;
4572            case 0x06: ptr = &i386_device::x87_fdiv_m64real;  break;
4573            case 0x07: ptr = &i386_device::x87_fdivr_m64real; break;
4574         }
4575      }
4576      else
4577      {
4578         switch (modrm)
4579         {
4580            case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_fadd_sti_st;  break;
4581            case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fmul_sti_st;  break;
4582            case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fsubr_sti_st; break;
4583            case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fsub_sti_st;  break;
4584            case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fdivr_sti_st; break;
4585            case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = &i386_device::x87_fdiv_sti_st;  break;
4586         }
4587      }
4588
4589      m_opcode_table_x87_dc[modrm] = ptr;
4590   }
4591}
4592
4593
4594void i386_device::build_x87_opcode_table_dd()
4595{
4596   int modrm = 0;
4597
4598   for (modrm = 0; modrm < 0x100; ++modrm)
4599   {
4600      i386_modrm_func ptr = &i386_device::x87_invalid;
4601
4602      if (modrm < 0xc0)
4603      {
4604         switch ((modrm >> 3) & 0x7)
4605         {
4606            case 0x00: ptr = &i386_device::x87_fld_m64real;   break;
4607            case 0x02: ptr = &i386_device::x87_fst_m64real;   break;
4608            case 0x03: ptr = &i386_device::x87_fstp_m64real;  break;
4609            case 0x04: ptr = &i386_device::x87_frstor;        break;
4610            case 0x06: ptr = &i386_device::x87_fsave;         break;
4611            case 0x07: ptr = &i386_device::x87_fstsw_m2byte;  break;
4612         }
4613      }
4614      else
4615      {
4616         switch (modrm)
4617         {
4618            case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_ffree;        break;
4619            case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fxch_sti;     break;
4620            case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = &i386_device::x87_fst_sti;      break;
4621            case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = &i386_device::x87_fstp_sti;     break;
4622            case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fucom_sti;    break;
4623            case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fucomp_sti;   break;
4624         }
4625      }
4626
4627      m_opcode_table_x87_dd[modrm] = ptr;
4628   }
4629}
4630
4631
4632void i386_device::build_x87_opcode_table_de()
4633{
4634   int modrm = 0;
4635
4636   for (modrm = 0; modrm < 0x100; ++modrm)
4637   {
4638      i386_modrm_func ptr = &i386_device::x87_invalid;
4639
4640      if (modrm < 0xc0)
4641      {
4642         switch ((modrm >> 3) & 0x7)
4643         {
4644            case 0x00: ptr = &i386_device::x87_fiadd_m16int;  break;
4645            case 0x01: ptr = &i386_device::x87_fimul_m16int;  break;
4646            case 0x02: ptr = &i386_device::x87_ficom_m16int;  break;
4647            case 0x03: ptr = &i386_device::x87_ficomp_m16int; break;
4648            case 0x04: ptr = &i386_device::x87_fisub_m16int;  break;
4649            case 0x05: ptr = &i386_device::x87_fisubr_m16int; break;
4650            case 0x06: ptr = &i386_device::x87_fidiv_m16int;  break;
4651            case 0x07: ptr = &i386_device::x87_fidivr_m16int; break;
4652         }
4653      }
4654      else
4655      {
4656         switch (modrm)
4657         {
4658            case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_faddp;    break;
4659            case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fmulp;    break;
4660            case 0xd9: ptr = &i386_device::x87_fcompp; break;
4661            case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fsubrp;   break;
4662            case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fsubp;    break;
4663            case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fdivrp;   break;
4664            case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = &i386_device::x87_fdivp;    break;
4665         }
4666      }
4667
4668      m_opcode_table_x87_de[modrm] = ptr;
4669   }
4670}
4671
4672
4673void i386_device::build_x87_opcode_table_df()
4674{
4675   int modrm = 0;
4676
4677   for (modrm = 0; modrm < 0x100; ++modrm)
4678   {
4679      i386_modrm_func ptr = &i386_device::x87_invalid;
4680
4681      if (modrm < 0xc0)
4682      {
4683         switch ((modrm >> 3) & 0x7)
4684         {
4685            case 0x00: ptr = &i386_device::x87_fild_m16int;   break;
4686            case 0x02: ptr = &i386_device::x87_fist_m16int;   break;
4687            case 0x03: ptr = &i386_device::x87_fistp_m16int;  break;
4688            case 0x04: ptr = &i386_device::x87_fbld;          break;
4689            case 0x05: ptr = &i386_device::x87_fild_m64int;   break;
4690            case 0x06: ptr = &i386_device::x87_fbstp;         break;
4691            case 0x07: ptr = &i386_device::x87_fistp_m64int;  break;
4692         }
4693      }
4694      else
4695      {
4696         switch (modrm)
4697         {
4698            case 0xe0: ptr = &i386_device::x87_fstsw_ax;      break;
4699            case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fcomip_sti;    break;
4700         }
4701      }
4702
4703      m_opcode_table_x87_df[modrm] = ptr;
4704   }
4705}
4706
4707void i386_device::build_x87_opcode_table()
4708{
4709   build_x87_opcode_table_d8();
4710   build_x87_opcode_table_d9();
4711   build_x87_opcode_table_da();
4712   build_x87_opcode_table_db();
4713   build_x87_opcode_table_dc();
4714   build_x87_opcode_table_dd();
4715   build_x87_opcode_table_de();
4716   build_x87_opcode_table_df();
4717}
Property changes on: trunk/src/emu/cpu/i386/x87ops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/i386/i386ops.inc
r0r28739
1UINT8 i386_device::i386_shift_rotate8(UINT8 modrm, UINT32 value, UINT8 shift)
2{
3   UINT32 src = value & 0xff;
4   UINT8 dst = value;
5
6   if( shift == 0 ) {
7      CYCLES_RM(modrm, 3, 7);
8   } else if( shift == 1 ) {
9      switch( (modrm >> 3) & 0x7 )
10      {
11         case 0:         /* ROL rm8, 1 */
12            m_CF = (src & 0x80) ? 1 : 0;
13            dst = (src << 1) + m_CF;
14            m_OF = ((src ^ dst) & 0x80) ? 1 : 0;
15            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
16            break;
17         case 1:         /* ROR rm8, 1 */
18            m_CF = (src & 0x1) ? 1 : 0;
19            dst = (m_CF << 7) | (src >> 1);
20            m_OF = ((src ^ dst) & 0x80) ? 1 : 0;
21            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
22            break;
23         case 2:         /* RCL rm8, 1 */
24            dst = (src << 1) + m_CF;
25            m_CF = (src & 0x80) ? 1 : 0;
26            m_OF = ((src ^ dst) & 0x80) ? 1 : 0;
27            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
28            break;
29         case 3:         /* RCR rm8, 1 */
30            dst = (m_CF << 7) | (src >> 1);
31            m_CF = src & 0x1;
32            m_OF = ((src ^ dst) & 0x80) ? 1 : 0;
33            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
34            break;
35         case 4:         /* SHL/SAL rm8, 1 */
36         case 6:
37            dst = src << 1;
38            m_CF = (src & 0x80) ? 1 : 0;
39            m_OF = (((m_CF << 7) ^ dst) & 0x80) ? 1 : 0;
40            SetSZPF8(dst);
41            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
42            break;
43         case 5:         /* SHR rm8, 1 */
44            dst = src >> 1;
45            m_CF = src & 0x1;
46            m_OF = (dst & 0x80) ? 1 : 0;
47            SetSZPF8(dst);
48            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
49            break;
50         case 7:         /* SAR rm8, 1 */
51            dst = (INT8)(src) >> 1;
52            m_CF = src & 0x1;
53            m_OF = 0;
54            SetSZPF8(dst);
55            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
56            break;
57      }
58
59   } else {
60      switch( (modrm >> 3) & 0x7 )
61      {
62         case 0:         /* ROL rm8, i8 */
63            if(!(shift & 7))
64            {
65               if(shift & 0x18)
66               {
67                  m_CF = src & 1;
68                  m_OF = (src & 1) ^ ((src >> 7) & 1);
69               }
70               break;
71            }
72            shift &= 7;
73            dst = ((src & ((UINT8)0xff >> shift)) << shift) |
74                  ((src & ((UINT8)0xff << (8-shift))) >> (8-shift));
75            m_CF = dst & 0x1;
76            m_OF = (dst & 1) ^ (dst >> 7);
77            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
78            break;
79         case 1:         /* ROR rm8, i8 */
80            if(!(shift & 7))
81            {
82               if(shift & 0x18)
83               {
84                  m_CF = (src >> 7) & 1;
85                  m_OF = ((src >> 7) & 1) ^ ((src >> 6) & 1);
86               }
87               break;
88            }
89            shift &= 7;
90            dst = ((src & ((UINT8)0xff << shift)) >> shift) |
91                  ((src & ((UINT8)0xff >> (8-shift))) << (8-shift));
92            m_CF = (dst >> 7) & 1;
93            m_OF = ((dst >> 7) ^ (dst >> 6)) & 1;
94            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
95            break;
96         case 2:         /* RCL rm8, i8 */
97            shift %= 9;
98            dst = ((src & ((UINT8)0xff >> shift)) << shift) |
99                  ((src & ((UINT8)0xff << (9-shift))) >> (9-shift)) |
100                  (m_CF << (shift-1));
101            if(shift) m_CF = (src >> (8-shift)) & 0x1;
102            m_OF = m_CF ^ ((dst >> 7) & 1);
103            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
104            break;
105         case 3:         /* RCR rm8, i8 */
106            shift %= 9;
107            dst = ((src & ((UINT8)0xff << shift)) >> shift) |
108                  ((src & ((UINT8)0xff >> (8-shift))) << (9-shift)) |
109                  (m_CF << (8-shift));
110            if(shift) m_CF = (src >> (shift-1)) & 0x1;
111            m_OF = ((dst >> 7) ^ (dst >> 6)) & 1;
112            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
113            break;
114         case 4:         /* SHL/SAL rm8, i8 */
115         case 6:
116            shift &= 31;
117            dst = src << shift;
118            m_CF = (shift <= 8) && ((src >> (8 - shift)) & 1);
119            SetSZPF8(dst);
120            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
121            break;
122         case 5:         /* SHR rm8, i8 */
123            shift &= 31;
124            dst = src >> shift;
125            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
126            SetSZPF8(dst);
127            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
128            break;
129         case 7:         /* SAR rm8, i8 */
130            shift &= 31;
131            dst = (INT8)src >> shift;
132            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
133            SetSZPF8(dst);
134            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
135            break;
136      }
137   }
138
139   return dst;
140}
141
142
143
144void i386_device::i386_adc_rm8_r8()        // Opcode 0x10
145{
146   UINT8 src, dst;
147   UINT8 modrm = FETCH();
148   if( modrm >= 0xc0 ) {
149      src = LOAD_REG8(modrm);
150      dst = LOAD_RM8(modrm);
151      dst = ADC8(dst, src, m_CF);
152      STORE_RM8(modrm, dst);
153      CYCLES(CYCLES_ALU_REG_REG);
154   } else {
155      UINT32 ea = GetEA(modrm,1);
156      src = LOAD_REG8(modrm);
157      dst = READ8(ea);
158      dst = ADC8(dst, src, m_CF);
159      WRITE8(ea, dst);
160      CYCLES(CYCLES_ALU_REG_MEM);
161   }
162}
163
164void i386_device::i386_adc_r8_rm8()        // Opcode 0x12
165{
166   UINT8 src, dst;
167   UINT8 modrm = FETCH();
168   if( modrm >= 0xc0 ) {
169      src = LOAD_RM8(modrm);
170      dst = LOAD_REG8(modrm);
171      dst = ADC8(dst, src, m_CF);
172      STORE_REG8(modrm, dst);
173      CYCLES(CYCLES_ALU_REG_REG);
174   } else {
175      UINT32 ea = GetEA(modrm,0);
176      src = READ8(ea);
177      dst = LOAD_REG8(modrm);
178      dst = ADC8(dst, src, m_CF);
179      STORE_REG8(modrm, dst);
180      CYCLES(CYCLES_ALU_MEM_REG);
181   }
182}
183
184void i386_device::i386_adc_al_i8()     // Opcode 0x14
185{
186   UINT8 src, dst;
187   src = FETCH();
188   dst = REG8(AL);
189   dst = ADC8(dst, src, m_CF);
190   REG8(AL) = dst;
191   CYCLES(CYCLES_ALU_IMM_ACC);
192}
193
194void i386_device::i386_add_rm8_r8()        // Opcode 0x00
195{
196   UINT8 src, dst;
197   UINT8 modrm = FETCH();
198   if( modrm >= 0xc0 ) {
199      src = LOAD_REG8(modrm);
200      dst = LOAD_RM8(modrm);
201      dst = ADD8(dst, src);
202      STORE_RM8(modrm, dst);
203      CYCLES(CYCLES_ALU_REG_REG);
204   } else {
205      UINT32 ea = GetEA(modrm,1);
206      src = LOAD_REG8(modrm);
207      dst = READ8(ea);
208      dst = ADD8(dst, src);
209      WRITE8(ea, dst);
210      CYCLES(CYCLES_ALU_REG_MEM);
211   }
212}
213
214void i386_device::i386_add_r8_rm8()        // Opcode 0x02
215{
216   UINT8 src, dst;
217   UINT8 modrm = FETCH();
218   if( modrm >= 0xc0 ) {
219      src = LOAD_RM8(modrm);
220      dst = LOAD_REG8(modrm);
221      dst = ADD8(dst, src);
222      STORE_REG8(modrm, dst);
223      CYCLES(CYCLES_ALU_REG_REG);
224   } else {
225      UINT32 ea = GetEA(modrm,0);
226      src = READ8(ea);
227      dst = LOAD_REG8(modrm);
228      dst = ADD8(dst, src);
229      STORE_REG8(modrm, dst);
230      CYCLES(CYCLES_ALU_MEM_REG);
231   }
232}
233
234void i386_device::i386_add_al_i8()     // Opcode 0x04
235{
236   UINT8 src, dst;
237   src = FETCH();
238   dst = REG8(AL);
239   dst = ADD8(dst, src);
240   REG8(AL) = dst;
241   CYCLES(CYCLES_ALU_IMM_ACC);
242}
243
244void i386_device::i386_and_rm8_r8()        // Opcode 0x20
245{
246   UINT8 src, dst;
247   UINT8 modrm = FETCH();
248   if( modrm >= 0xc0 ) {
249      src = LOAD_REG8(modrm);
250      dst = LOAD_RM8(modrm);
251      dst = AND8(dst, src);
252      STORE_RM8(modrm, dst);
253      CYCLES(CYCLES_ALU_REG_REG);
254   } else {
255      UINT32 ea = GetEA(modrm,1);
256      src = LOAD_REG8(modrm);
257      dst = READ8(ea);
258      dst = AND8(dst, src);
259      WRITE8(ea, dst);
260      CYCLES(CYCLES_ALU_REG_MEM);
261   }
262}
263
264void i386_device::i386_and_r8_rm8()        // Opcode 0x22
265{
266   UINT8 src, dst;
267   UINT8 modrm = FETCH();
268   if( modrm >= 0xc0 ) {
269      src = LOAD_RM8(modrm);
270      dst = LOAD_REG8(modrm);
271      dst = AND8(dst, src);
272      STORE_REG8(modrm, dst);
273      CYCLES(CYCLES_ALU_REG_REG);
274   } else {
275      UINT32 ea = GetEA(modrm,0);
276      src = READ8(ea);
277      dst = LOAD_REG8(modrm);
278      dst = AND8(dst, src);
279      STORE_REG8(modrm, dst);
280      CYCLES(CYCLES_ALU_MEM_REG);
281   }
282}
283
284void i386_device::i386_and_al_i8()         // Opcode 0x24
285{
286   UINT8 src, dst;
287   src = FETCH();
288   dst = REG8(AL);
289   dst = AND8(dst, src);
290   REG8(AL) = dst;
291   CYCLES(CYCLES_ALU_IMM_ACC);
292}
293
294void i386_device::i386_clc()               // Opcode 0xf8
295{
296   m_CF = 0;
297   CYCLES(CYCLES_CLC);
298}
299
300void i386_device::i386_cld()               // Opcode 0xfc
301{
302   m_DF = 0;
303   CYCLES(CYCLES_CLD);
304}
305
306void i386_device::i386_cli()               // Opcode 0xfa
307{
308   if(PROTECTED_MODE)
309   {
310      UINT8 IOPL = m_IOP1 | (m_IOP2 << 1);
311      if(m_CPL > IOPL)
312         FAULT(FAULT_GP,0);
313   }
314   m_IF = 0;
315   CYCLES(CYCLES_CLI);
316}
317
318void i386_device::i386_cmc()               // Opcode 0xf5
319{
320   m_CF ^= 1;
321   CYCLES(CYCLES_CMC);
322}
323
324void i386_device::i386_cmp_rm8_r8()        // Opcode 0x38
325{
326   UINT8 src, dst;
327   UINT8 modrm = FETCH();
328   if( modrm >= 0xc0 ) {
329      src = LOAD_REG8(modrm);
330      dst = LOAD_RM8(modrm);
331      SUB8(dst, src);
332      CYCLES(CYCLES_CMP_REG_REG);
333   } else {
334      UINT32 ea = GetEA(modrm,0);
335      src = LOAD_REG8(modrm);
336      dst = READ8(ea);
337      SUB8(dst, src);
338      CYCLES(CYCLES_CMP_REG_MEM);
339   }
340}
341
342void i386_device::i386_cmp_r8_rm8()        // Opcode 0x3a
343{
344   UINT8 src, dst;
345   UINT8 modrm = FETCH();
346   if( modrm >= 0xc0 ) {
347      src = LOAD_RM8(modrm);
348      dst = LOAD_REG8(modrm);
349      SUB8(dst, src);
350      CYCLES(CYCLES_CMP_REG_REG);
351   } else {
352      UINT32 ea = GetEA(modrm,0);
353      src = READ8(ea);
354      dst = LOAD_REG8(modrm);
355      SUB8(dst, src);
356      CYCLES(CYCLES_CMP_MEM_REG);
357   }
358}
359
360void i386_device::i386_cmp_al_i8()         // Opcode 0x3c
361{
362   UINT8 src, dst;
363   src = FETCH();
364   dst = REG8(AL);
365   SUB8(dst, src);
366   CYCLES(CYCLES_CMP_IMM_ACC);
367}
368
369void i386_device::i386_cmpsb()             // Opcode 0xa6
370{
371   UINT32 eas, ead;
372   UINT8 src, dst;
373   if( m_segment_prefix ) {
374      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
375   } else {
376      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
377   }
378   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
379   src = READ8(eas);
380   dst = READ8(ead);
381   SUB8(src, dst);
382   BUMP_SI(1);
383   BUMP_DI(1);
384   CYCLES(CYCLES_CMPS);
385}
386
387void i386_device::i386_in_al_i8()          // Opcode 0xe4
388{
389   UINT16 port = FETCH();
390   UINT8 data = READPORT8(port);
391   REG8(AL) = data;
392   CYCLES(CYCLES_IN_VAR);
393}
394
395void i386_device::i386_in_al_dx()          // Opcode 0xec
396{
397   UINT16 port = REG16(DX);
398   UINT8 data = READPORT8(port);
399   REG8(AL) = data;
400   CYCLES(CYCLES_IN);
401}
402
403void i386_device::i386_ja_rel8()           // Opcode 0x77
404{
405   INT8 disp = FETCH();
406   if( m_CF == 0 && m_ZF == 0 ) {
407      NEAR_BRANCH(disp);
408      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
409   } else {
410      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
411   }
412}
413
414void i386_device::i386_jbe_rel8()          // Opcode 0x76
415{
416   INT8 disp = FETCH();
417   if( m_CF != 0 || m_ZF != 0 ) {
418      NEAR_BRANCH(disp);
419      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
420   } else {
421      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
422   }
423}
424
425void i386_device::i386_jc_rel8()           // Opcode 0x72
426{
427   INT8 disp = FETCH();
428   if( m_CF != 0 ) {
429      NEAR_BRANCH(disp);
430      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
431   } else {
432      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
433   }
434}
435
436void i386_device::i386_jg_rel8()           // Opcode 0x7f
437{
438   INT8 disp = FETCH();
439   if( m_ZF == 0 && (m_SF == m_OF) ) {
440      NEAR_BRANCH(disp);
441      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
442   } else {
443      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
444   }
445}
446
447void i386_device::i386_jge_rel8()          // Opcode 0x7d
448{
449   INT8 disp = FETCH();
450   if(m_SF == m_OF) {
451      NEAR_BRANCH(disp);
452      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
453   } else {
454      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
455   }
456}
457
458void i386_device::i386_jl_rel8()           // Opcode 0x7c
459{
460   INT8 disp = FETCH();
461   if( (m_SF != m_OF) ) {
462      NEAR_BRANCH(disp);
463      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
464   } else {
465      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
466   }
467}
468
469void i386_device::i386_jle_rel8()      // Opcode 0x7e
470{
471   INT8 disp = FETCH();
472   if( m_ZF != 0 || (m_SF != m_OF) ) {
473      NEAR_BRANCH(disp);
474      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
475   } else {
476      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
477   }
478}
479
480void i386_device::i386_jnc_rel8()          // Opcode 0x73
481{
482   INT8 disp = FETCH();
483   if( m_CF == 0 ) {
484      NEAR_BRANCH(disp);
485      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
486   } else {
487      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
488   }
489}
490
491void i386_device::i386_jno_rel8()          // Opcode 0x71
492{
493   INT8 disp = FETCH();
494   if( m_OF == 0 ) {
495      NEAR_BRANCH(disp);
496      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
497   } else {
498      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
499   }
500}
501
502void i386_device::i386_jnp_rel8()          // Opcode 0x7b
503{
504   INT8 disp = FETCH();
505   if( m_PF == 0 ) {
506      NEAR_BRANCH(disp);
507      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
508   } else {
509      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
510   }
511}
512
513void i386_device::i386_jns_rel8()          // Opcode 0x79
514{
515   INT8 disp = FETCH();
516   if( m_SF == 0 ) {
517      NEAR_BRANCH(disp);
518      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
519   } else {
520      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
521   }
522}
523
524void i386_device::i386_jnz_rel8()          // Opcode 0x75
525{
526   INT8 disp = FETCH();
527   if( m_ZF == 0 ) {
528      NEAR_BRANCH(disp);
529      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
530   } else {
531      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
532   }
533}
534
535void i386_device::i386_jo_rel8()           // Opcode 0x70
536{
537   INT8 disp = FETCH();
538   if( m_OF != 0 ) {
539      NEAR_BRANCH(disp);
540      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
541   } else {
542      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
543   }
544}
545
546void i386_device::i386_jp_rel8()           // Opcode 0x7a
547{
548   INT8 disp = FETCH();
549   if( m_PF != 0 ) {
550      NEAR_BRANCH(disp);
551      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
552   } else {
553      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
554   }
555}
556
557void i386_device::i386_js_rel8()           // Opcode 0x78
558{
559   INT8 disp = FETCH();
560   if( m_SF != 0 ) {
561      NEAR_BRANCH(disp);
562      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
563   } else {
564      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
565   }
566}
567
568void i386_device::i386_jz_rel8()           // Opcode 0x74
569{
570   INT8 disp = FETCH();
571   if( m_ZF != 0 ) {
572      NEAR_BRANCH(disp);
573      CYCLES(CYCLES_JCC_DISP8);      /* TODO: Timing = 7 + m */
574   } else {
575      CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
576   }
577}
578
579void i386_device::i386_jmp_rel8()          // Opcode 0xeb
580{
581   INT8 disp = FETCH();
582   NEAR_BRANCH(disp);
583   CYCLES(CYCLES_JMP_SHORT);      /* TODO: Timing = 7 + m */
584}
585
586void i386_device::i386_lahf()              // Opcode 0x9f
587{
588   REG8(AH) = get_flags() & 0xd7;
589   CYCLES(CYCLES_LAHF);
590}
591
592void i386_device::i386_lodsb()             // Opcode 0xac
593{
594   UINT32 eas;
595   if( m_segment_prefix ) {
596      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
597   } else {
598      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
599   }
600   REG8(AL) = READ8(eas);
601   BUMP_SI(1);
602   CYCLES(CYCLES_LODS);
603}
604
605void i386_device::i386_mov_rm8_r8()        // Opcode 0x88
606{
607   UINT8 src;
608   UINT8 modrm = FETCH();
609   if( modrm >= 0xc0 ) {
610      src = LOAD_REG8(modrm);
611      STORE_RM8(modrm, src);
612      CYCLES(CYCLES_MOV_REG_REG);
613   } else {
614      UINT32 ea = GetEA(modrm,1);
615      src = LOAD_REG8(modrm);
616      WRITE8(ea, src);
617      CYCLES(CYCLES_MOV_REG_MEM);
618   }
619}
620
621void i386_device::i386_mov_r8_rm8()        // Opcode 0x8a
622{
623   UINT8 src;
624   UINT8 modrm = FETCH();
625   if( modrm >= 0xc0 ) {
626      src = LOAD_RM8(modrm);
627      STORE_REG8(modrm, src);
628      CYCLES(CYCLES_MOV_REG_REG);
629   } else {
630      UINT32 ea = GetEA(modrm,0);
631      src = READ8(ea);
632      STORE_REG8(modrm, src);
633      CYCLES(CYCLES_MOV_MEM_REG);
634   }
635}
636
637void i386_device::i386_mov_rm8_i8()        // Opcode 0xc6
638{
639   UINT8 modrm = FETCH();
640   if( modrm >= 0xc0 ) {
641      UINT8 value = FETCH();
642      STORE_RM8(modrm, value);
643      CYCLES(CYCLES_MOV_IMM_REG);
644   } else {
645      UINT32 ea = GetEA(modrm,1);
646      UINT8 value = FETCH();
647      WRITE8(ea, value);
648      CYCLES(CYCLES_MOV_IMM_MEM);
649   }
650}
651
652void i386_device::i386_mov_r32_cr()        // Opcode 0x0f 20
653{
654   if(PROTECTED_MODE && m_CPL)
655      FAULT(FAULT_GP, 0);
656   UINT8 modrm = FETCH();
657   UINT8 cr = (modrm >> 3) & 0x7;
658
659   STORE_RM32(modrm, m_cr[cr]);
660   CYCLES(CYCLES_MOV_CR_REG);
661}
662
663void i386_device::i386_mov_r32_dr()        // Opcode 0x0f 21
664{
665   if(PROTECTED_MODE && m_CPL)
666      FAULT(FAULT_GP, 0);
667   UINT8 modrm = FETCH();
668   UINT8 dr = (modrm >> 3) & 0x7;
669
670   STORE_RM32(modrm, m_dr[dr]);
671   switch(dr)
672   {
673      case 0:
674      case 1:
675      case 2:
676      case 3:
677         CYCLES(CYCLES_MOV_REG_DR0_3);
678         break;
679      case 6:
680      case 7:
681         CYCLES(CYCLES_MOV_REG_DR6_7);
682         break;
683   }
684}
685
686void i386_device::i386_mov_cr_r32()        // Opcode 0x0f 22
687{
688   if(PROTECTED_MODE && m_CPL)
689      FAULT(FAULT_GP, 0);
690   UINT8 modrm = FETCH();
691   UINT8 cr = (modrm >> 3) & 0x7;
692   UINT32 data = LOAD_RM32(modrm);
693   switch(cr)
694   {
695      case 0:
696         data &= 0xfffeffff; // wp not supported on 386
697         CYCLES(CYCLES_MOV_REG_CR0);
698         break;
699      case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
700      case 3:
701         CYCLES(CYCLES_MOV_REG_CR3);
702         vtlb_flush_dynamic(m_vtlb);
703         break;
704      case 4: CYCLES(1); break; // TODO
705      default:
706         logerror("i386: mov_cr_r32 CR%d!\n", cr);
707         return;
708   }
709   m_cr[cr] = data;
710}
711
712void i386_device::i386_mov_dr_r32()        // Opcode 0x0f 23
713{
714   if(PROTECTED_MODE && m_CPL)
715      FAULT(FAULT_GP, 0);
716   UINT8 modrm = FETCH();
717   UINT8 dr = (modrm >> 3) & 0x7;
718
719   m_dr[dr] = LOAD_RM32(modrm);
720   switch(dr)
721   {
722      case 0:
723      case 1:
724      case 2:
725      case 3:
726         CYCLES(CYCLES_MOV_DR0_3_REG);
727         break;
728      case 6:
729      case 7:
730         CYCLES(CYCLES_MOV_DR6_7_REG);
731         break;
732      default:
733         logerror("i386: mov_dr_r32 DR%d!\n", dr);
734         return;
735   }
736}
737
738void i386_device::i386_mov_al_m8()         // Opcode 0xa0
739{
740   UINT32 offset, ea;
741   if( m_address_size ) {
742      offset = FETCH32();
743   } else {
744      offset = FETCH16();
745   }
746   /* TODO: Not sure if this is correct... */
747   if( m_segment_prefix ) {
748      ea = i386_translate(m_segment_override, offset, 0 );
749   } else {
750      ea = i386_translate(DS, offset, 0 );
751   }
752   REG8(AL) = READ8(ea);
753   CYCLES(CYCLES_MOV_IMM_MEM);
754}
755
756void i386_device::i386_mov_m8_al()         // Opcode 0xa2
757{
758   UINT32 offset, ea;
759   if( m_address_size ) {
760      offset = FETCH32();
761   } else {
762      offset = FETCH16();
763   }
764   /* TODO: Not sure if this is correct... */
765   if( m_segment_prefix ) {
766      ea = i386_translate(m_segment_override, offset, 1 );
767   } else {
768      ea = i386_translate(DS, offset, 1 );
769   }
770   WRITE8(ea, REG8(AL) );
771   CYCLES(CYCLES_MOV_MEM_ACC);
772}
773
774void i386_device::i386_mov_rm16_sreg()     // Opcode 0x8c
775{
776   UINT8 modrm = FETCH();
777   int s = (modrm >> 3) & 0x7;
778
779   if( modrm >= 0xc0 ) {
780      if(m_operand_size)
781         STORE_RM32(modrm, m_sreg[s].selector);
782      else
783         STORE_RM16(modrm, m_sreg[s].selector);
784      CYCLES(CYCLES_MOV_SREG_REG);
785   } else {
786      UINT32 ea = GetEA(modrm,1);
787      WRITE16(ea, m_sreg[s].selector);
788      CYCLES(CYCLES_MOV_SREG_MEM);
789   }
790}
791
792void i386_device::i386_mov_sreg_rm16()     // Opcode 0x8e
793{
794   UINT16 selector;
795   UINT8 modrm = FETCH();
796   bool fault;
797   int s = (modrm >> 3) & 0x7;
798
799   if( modrm >= 0xc0 ) {
800      selector = LOAD_RM16(modrm);
801      CYCLES(CYCLES_MOV_REG_SREG);
802   } else {
803      UINT32 ea = GetEA(modrm,0);
804      selector = READ16(ea);
805      CYCLES(CYCLES_MOV_MEM_SREG);
806   }
807
808   i386_sreg_load(selector,s,&fault);
809   if((s == SS) && !fault)
810   {
811      if(m_IF != 0) // if external interrupts are enabled
812      {
813         m_IF = 0;  // reset IF for the next instruction
814         m_delayed_interrupt_enable = 1;
815      }
816   }
817}
818
819void i386_device::i386_mov_al_i8()         // Opcode 0xb0
820{
821   REG8(AL) = FETCH();
822   CYCLES(CYCLES_MOV_IMM_REG);
823}
824
825void i386_device::i386_mov_cl_i8()         // Opcode 0xb1
826{
827   REG8(CL) = FETCH();
828   CYCLES(CYCLES_MOV_IMM_REG);
829}
830
831void i386_device::i386_mov_dl_i8()         // Opcode 0xb2
832{
833   REG8(DL) = FETCH();
834   CYCLES(CYCLES_MOV_IMM_REG);
835}
836
837void i386_device::i386_mov_bl_i8()         // Opcode 0xb3
838{
839   REG8(BL) = FETCH();
840   CYCLES(CYCLES_MOV_IMM_REG);
841}
842
843void i386_device::i386_mov_ah_i8()         // Opcode 0xb4
844{
845   REG8(AH) = FETCH();
846   CYCLES(CYCLES_MOV_IMM_REG);
847}
848
849void i386_device::i386_mov_ch_i8()         // Opcode 0xb5
850{
851   REG8(CH) = FETCH();
852   CYCLES(CYCLES_MOV_IMM_REG);
853}
854
855void i386_device::i386_mov_dh_i8()         // Opcode 0xb6
856{
857   REG8(DH) = FETCH();
858   CYCLES(CYCLES_MOV_IMM_REG);
859}
860
861void i386_device::i386_mov_bh_i8()         // Opcode 0xb7
862{
863   REG8(BH) = FETCH();
864   CYCLES(CYCLES_MOV_IMM_REG);
865}
866
867void i386_device::i386_movsb()             // Opcode 0xa4
868{
869   UINT32 eas, ead;
870   UINT8 v;
871   if( m_segment_prefix ) {
872      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
873   } else {
874      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
875   }
876   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
877   v = READ8(eas);
878   WRITE8(ead, v);
879   BUMP_SI(1);
880   BUMP_DI(1);
881   CYCLES(CYCLES_MOVS);
882}
883
884void i386_device::i386_or_rm8_r8()         // Opcode 0x08
885{
886   UINT8 src, dst;
887   UINT8 modrm = FETCH();
888   if( modrm >= 0xc0 ) {
889      src = LOAD_REG8(modrm);
890      dst = LOAD_RM8(modrm);
891      dst = OR8(dst, src);
892      STORE_RM8(modrm, dst);
893      CYCLES(CYCLES_ALU_REG_REG);
894   } else {
895      UINT32 ea = GetEA(modrm,1);
896      src = LOAD_REG8(modrm);
897      dst = READ8(ea);
898      dst = OR8(dst, src);
899      WRITE8(ea, dst);
900      CYCLES(CYCLES_ALU_REG_MEM);
901   }
902}
903
904void i386_device::i386_or_r8_rm8()         // Opcode 0x0a
905{
906   UINT8 src, dst;
907   UINT8 modrm = FETCH();
908   if( modrm >= 0xc0 ) {
909      src = LOAD_RM8(modrm);
910      dst = LOAD_REG8(modrm);
911      dst = OR8(dst, src);
912      STORE_REG8(modrm, dst);
913      CYCLES(CYCLES_ALU_REG_REG);
914   } else {
915      UINT32 ea = GetEA(modrm,0);
916      src = READ8(ea);
917      dst = LOAD_REG8(modrm);
918      dst = OR8(dst, src);
919      STORE_REG8(modrm, dst);
920      CYCLES(CYCLES_ALU_MEM_REG);
921   }
922}
923
924void i386_device::i386_or_al_i8()          // Opcode 0x0c
925{
926   UINT8 src, dst;
927   src = FETCH();
928   dst = REG8(AL);
929   dst = OR8(dst, src);
930   REG8(EAX) = dst;
931   CYCLES(CYCLES_ALU_IMM_ACC);
932}
933
934void i386_device::i386_out_al_i8()         // Opcode 0xe6
935{
936   UINT16 port = FETCH();
937   UINT8 data = REG8(AL);
938   WRITEPORT8(port, data);
939   CYCLES(CYCLES_OUT_VAR);
940}
941
942void i386_device::i386_out_al_dx()         // Opcode 0xee
943{
944   UINT16 port = REG16(DX);
945   UINT8 data = REG8(AL);
946   WRITEPORT8(port, data);
947   CYCLES(CYCLES_OUT);
948}
949
950
951void i386_device::i386_arpl()           // Opcode 0x63
952{
953   UINT16 src, dst;
954   UINT8 modrm = FETCH();
955   UINT8 flag = 0;
956
957   if(PROTECTED_MODE && !V8086_MODE)
958   {
959         if( modrm >= 0xc0 ) {
960         src = LOAD_REG16(modrm);
961         dst = LOAD_RM16(modrm);
962         if( (dst&0x3) < (src&0x3) ) {
963            dst = (dst&0xfffc) | (src&0x3);
964            flag = 1;
965            STORE_RM16(modrm, dst);
966         }
967      } else {
968         UINT32 ea = GetEA(modrm,1);
969         src = LOAD_REG16(modrm);
970         dst = READ16(ea);
971         if( (dst&0x3) < (src&0x3) ) {
972            dst = (dst&0xfffc) | (src&0x3);
973            flag = 1;
974            WRITE16(ea, dst);
975         }
976      }
977      SetZF(flag);
978   }
979   else
980      i386_trap(6, 0, 0);  // invalid opcode in real mode or v8086 mode
981}
982
983void i386_device::i386_push_i8()           // Opcode 0x6a
984{
985   UINT8 value = FETCH();
986   PUSH8(value);
987   CYCLES(CYCLES_PUSH_IMM);
988}
989
990void i386_device::i386_ins_generic(int size)
991{
992   UINT32 ead;
993   UINT8 vb;
994   UINT16 vw;
995   UINT32 vd;
996
997   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
998
999   switch(size) {
1000   case 1:
1001      vb = READPORT8(REG16(DX));
1002      WRITE8(ead, vb);
1003      break;
1004   case 2:
1005      vw = READPORT16(REG16(DX));
1006      WRITE16(ead, vw);
1007      break;
1008   case 4:
1009      vd = READPORT32(REG16(DX));
1010      WRITE32(ead, vd);
1011      break;
1012   }
1013
1014   if(m_address_size)
1015      REG32(EDI) += ((m_DF) ? -1 : 1) * size;
1016   else
1017      REG16(DI) += ((m_DF) ? -1 : 1) * size;
1018   CYCLES(CYCLES_INS);    // TODO: Confirm this value
1019}
1020
1021void i386_device::i386_insb()              // Opcode 0x6c
1022{
1023   i386_ins_generic(1);
1024}
1025
1026void i386_device::i386_insw()              // Opcode 0x6d
1027{
1028   i386_ins_generic(2);
1029}
1030
1031void i386_device::i386_insd()              // Opcode 0x6d
1032{
1033   i386_ins_generic(4);
1034}
1035
1036void i386_device::i386_outs_generic(int size)
1037{
1038   UINT32 eas;
1039   UINT8 vb;
1040   UINT16 vw;
1041   UINT32 vd;
1042
1043   if( m_segment_prefix ) {
1044      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1045   } else {
1046      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1047   }
1048
1049   switch(size) {
1050   case 1:
1051      vb = READ8(eas);
1052      WRITEPORT8(REG16(DX), vb);
1053      break;
1054   case 2:
1055      vw = READ16(eas);
1056      WRITEPORT16(REG16(DX), vw);
1057      break;
1058   case 4:
1059      vd = READ32(eas);
1060      WRITEPORT32(REG16(DX), vd);
1061      break;
1062   }
1063
1064   if(m_address_size)
1065      REG32(ESI) += ((m_DF) ? -1 : 1) * size;
1066   else
1067      REG16(SI) += ((m_DF) ? -1 : 1) * size;
1068   CYCLES(CYCLES_OUTS);   // TODO: Confirm this value
1069}
1070
1071void i386_device::i386_outsb()             // Opcode 0x6e
1072{
1073   i386_outs_generic(1);
1074}
1075
1076void i386_device::i386_outsw()             // Opcode 0x6f
1077{
1078   i386_outs_generic(2);
1079}
1080
1081void i386_device::i386_outsd()             // Opcode 0x6f
1082{
1083   i386_outs_generic(4);
1084}
1085
1086void i386_device::i386_repeat(int invert_flag)
1087{
1088   UINT32 repeated_eip = m_eip;
1089   UINT32 repeated_pc = m_pc;
1090   UINT8 opcode; // = FETCH();
1091//  UINT32 eas, ead;
1092   UINT32 count;
1093   INT32 cycle_base = 0, cycle_adjustment = 0;
1094   UINT8 prefix_flag=1;
1095   UINT8 *flag = NULL;
1096
1097
1098   do {
1099   repeated_eip = m_eip;
1100   repeated_pc = m_pc;
1101   opcode = FETCH();
1102   switch(opcode) {
1103      case 0x0f:
1104      if (invert_flag == 0)
1105         i386_decode_three_bytef3(); // sse f3 0f
1106      else
1107         i386_decode_three_bytef2(); // sse f2 0f
1108      return;
1109      case 0x26:
1110      m_segment_override=ES;
1111      m_segment_prefix=1;
1112      break;
1113      case 0x2e:
1114      m_segment_override=CS;
1115      m_segment_prefix=1;
1116      break;
1117      case 0x36:
1118      m_segment_override=SS;
1119      m_segment_prefix=1;
1120      break;
1121      case 0x3e:
1122      m_segment_override=DS;
1123      m_segment_prefix=1;
1124      break;
1125      case 0x64:
1126      m_segment_override=FS;
1127      m_segment_prefix=1;
1128      break;
1129      case 0x65:
1130      m_segment_override=GS;
1131      m_segment_prefix=1;
1132      break;
1133      case 0x66:
1134      m_operand_size ^= 1;
1135      break;
1136      case 0x67:
1137      m_address_size ^= 1;
1138      break;
1139      default:
1140      prefix_flag=0;
1141   }
1142   } while (prefix_flag);
1143
1144
1145   if( m_segment_prefix ) {
1146      // FIXME: the following does not work if both address override and segment override are used
1147      i386_translate(m_segment_override, m_sreg[m_segment_prefix].d ? REG32(ESI) : REG16(SI), -1 );
1148   } else {
1149      //eas =
1150      i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), -1 );
1151   }
1152   i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), -1 );
1153
1154   switch(opcode)
1155   {
1156      case 0x6c:
1157      case 0x6d:
1158         /* INSB, INSW, INSD */
1159         // TODO: cycle count
1160         cycle_base = 8;
1161         cycle_adjustment = -4;
1162         flag = NULL;
1163         break;
1164
1165      case 0x6e:
1166      case 0x6f:
1167         /* OUTSB, OUTSW, OUTSD */
1168         // TODO: cycle count
1169         cycle_base = 8;
1170         cycle_adjustment = -4;
1171         flag = NULL;
1172         break;
1173
1174      case 0xa4:
1175      case 0xa5:
1176         /* MOVSB, MOVSW, MOVSD */
1177         cycle_base = 8;
1178         cycle_adjustment = -4;
1179         flag = NULL;
1180         break;
1181
1182      case 0xa6:
1183      case 0xa7:
1184         /* CMPSB, CMPSW, CMPSD */
1185         cycle_base = 5;
1186         cycle_adjustment = -1;
1187         flag = &m_ZF;
1188         break;
1189
1190      case 0xac:
1191      case 0xad:
1192         /* LODSB, LODSW, LODSD */
1193         cycle_base = 5;
1194         cycle_adjustment = 1;
1195         flag = NULL;
1196         break;
1197
1198      case 0xaa:
1199      case 0xab:
1200         /* STOSB, STOSW, STOSD */
1201         cycle_base = 5;
1202         cycle_adjustment = 0;
1203         flag = NULL;
1204         break;
1205
1206      case 0xae:
1207      case 0xaf:
1208         /* SCASB, SCASW, SCASD */
1209         cycle_base = 5;
1210         cycle_adjustment = 0;
1211         flag = &m_ZF;
1212         break;
1213
1214      case 0x90:
1215         CYCLES(CYCLES_NOP);
1216         return;
1217
1218      case 0xc2: // sigh
1219      case 0xc3:
1220         m_pc--;
1221         return;
1222
1223      default:
1224         fatalerror("i386: Invalid REP/opcode %02X combination\n",opcode);
1225         break;
1226   }
1227
1228   if( m_address_size ) {
1229      if( REG32(ECX) == 0 )
1230         return;
1231   } else {
1232      if( REG16(CX) == 0 )
1233         return;
1234   }
1235
1236   /* now actually perform the repeat */
1237   CYCLES_NUM(cycle_base);
1238   do
1239   {
1240      m_eip = repeated_eip;
1241      m_pc = repeated_pc;
1242      try
1243      {
1244         i386_decode_opcode();
1245      }
1246      catch (UINT64 e)
1247      {
1248         m_eip = m_prev_eip;
1249         throw e;
1250      }
1251
1252      CYCLES_NUM(cycle_adjustment);
1253
1254      if (m_address_size)
1255         count = --REG32(ECX);
1256      else
1257         count = --REG16(CX);
1258      if (m_cycles <= 0)
1259         goto outofcycles;
1260   }
1261   while( count && (!flag || (invert_flag ? !*flag : *flag)) );
1262   return;
1263
1264outofcycles:
1265   /* if we run out of cycles to execute, and we are still in the repeat, we need
1266    * to exit this instruction in such a way to go right back into it when we have
1267    * time to execute cycles */
1268   if(flag && (invert_flag ? *flag : !*flag))
1269      return;
1270   m_eip = m_prev_eip;
1271   CHANGE_PC(m_eip);
1272   CYCLES_NUM(-cycle_base);
1273}
1274
1275void i386_device::i386_rep()               // Opcode 0xf3
1276{
1277   i386_repeat(0);
1278}
1279
1280void i386_device::i386_repne()             // Opcode 0xf2
1281{
1282   i386_repeat(1);
1283}
1284
1285void i386_device::i386_sahf()              // Opcode 0x9e
1286{
1287   set_flags((get_flags() & 0xffffff00) | (REG8(AH) & 0xd7) );
1288   CYCLES(CYCLES_SAHF);
1289}
1290
1291void i386_device::i386_sbb_rm8_r8()        // Opcode 0x18
1292{
1293   UINT8 src, dst;
1294   UINT8 modrm = FETCH();
1295   if( modrm >= 0xc0 ) {
1296      src = LOAD_REG8(modrm);
1297      dst = LOAD_RM8(modrm);
1298      dst = SBB8(dst, src, m_CF);
1299      STORE_RM8(modrm, dst);
1300      CYCLES(CYCLES_ALU_REG_REG);
1301   } else {
1302      UINT32 ea = GetEA(modrm,1);
1303      src = LOAD_REG8(modrm);
1304      dst = READ8(ea);
1305      dst = SBB8(dst, src, m_CF);
1306      WRITE8(ea, dst);
1307      CYCLES(CYCLES_ALU_REG_MEM);
1308   }
1309}
1310
1311void i386_device::i386_sbb_r8_rm8()        // Opcode 0x1a
1312{
1313   UINT8 src, dst;
1314   UINT8 modrm = FETCH();
1315   if( modrm >= 0xc0 ) {
1316      src = LOAD_RM8(modrm);
1317      dst = LOAD_REG8(modrm);
1318      dst = SBB8(dst, src, m_CF);
1319      STORE_REG8(modrm, dst);
1320      CYCLES(CYCLES_ALU_REG_REG);
1321   } else {
1322      UINT32 ea = GetEA(modrm,0);
1323      src = READ8(ea);
1324      dst = LOAD_REG8(modrm);
1325      dst = SBB8(dst, src, m_CF);
1326      STORE_REG8(modrm, dst);
1327      CYCLES(CYCLES_ALU_MEM_REG);
1328   }
1329}
1330
1331void i386_device::i386_sbb_al_i8()         // Opcode 0x1c
1332{
1333   UINT8 src, dst;
1334   src = FETCH();
1335   dst = REG8(AL);
1336   dst = SBB8(dst, src, m_CF);
1337   REG8(EAX) = dst;
1338   CYCLES(CYCLES_ALU_IMM_ACC);
1339}
1340
1341void i386_device::i386_scasb()             // Opcode 0xae
1342{
1343   UINT32 eas;
1344   UINT8 src, dst;
1345   eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
1346   src = READ8(eas);
1347   dst = REG8(AL);
1348   SUB8(dst, src);
1349   BUMP_DI(1);
1350   CYCLES(CYCLES_SCAS);
1351}
1352
1353void i386_device::i386_setalc()            // Opcode 0xd6 (undocumented)
1354{
1355   if( m_CF ) {
1356      REG8(AL) = 0xff;
1357   } else {
1358      REG8(AL) = 0;
1359   }
1360   CYCLES(3);
1361}
1362
1363void i386_device::i386_seta_rm8()          // Opcode 0x0f 97
1364{
1365   UINT8 modrm = FETCH();
1366   UINT8 value = 0;
1367   if( m_CF == 0 && m_ZF == 0 ) {
1368      value = 1;
1369   }
1370   if( modrm >= 0xc0 ) {
1371      STORE_RM8(modrm, value);
1372      CYCLES(CYCLES_SETCC_REG);
1373   } else {
1374      UINT32 ea = GetEA(modrm,1);
1375      WRITE8(ea, value);
1376      CYCLES(CYCLES_SETCC_MEM);
1377   }
1378}
1379
1380void i386_device::i386_setbe_rm8()         // Opcode 0x0f 96
1381{
1382   UINT8 modrm = FETCH();
1383   UINT8 value = 0;
1384   if( m_CF != 0 || m_ZF != 0 ) {
1385      value = 1;
1386   }
1387   if( modrm >= 0xc0 ) {
1388      STORE_RM8(modrm, value);
1389      CYCLES(CYCLES_SETCC_REG);
1390   } else {
1391      UINT32 ea = GetEA(modrm,1);
1392      WRITE8(ea, value);
1393      CYCLES(CYCLES_SETCC_MEM);
1394   }
1395}
1396
1397void i386_device::i386_setc_rm8()          // Opcode 0x0f 92
1398{
1399   UINT8 modrm = FETCH();
1400   UINT8 value = 0;
1401   if( m_CF != 0 ) {
1402      value = 1;
1403   }
1404   if( modrm >= 0xc0 ) {
1405      STORE_RM8(modrm, value);
1406      CYCLES(CYCLES_SETCC_REG);
1407   } else {
1408      UINT32 ea = GetEA(modrm,1);
1409      WRITE8(ea, value);
1410      CYCLES(CYCLES_SETCC_MEM);
1411   }
1412}
1413
1414void i386_device::i386_setg_rm8()          // Opcode 0x0f 9f
1415{
1416   UINT8 modrm = FETCH();
1417   UINT8 value = 0;
1418   if( m_ZF == 0 && (m_SF == m_OF) ) {
1419      value = 1;
1420   }
1421   if( modrm >= 0xc0 ) {
1422      STORE_RM8(modrm, value);
1423      CYCLES(CYCLES_SETCC_REG);
1424   } else {
1425      UINT32 ea = GetEA(modrm,1);
1426      WRITE8(ea, value);
1427      CYCLES(CYCLES_SETCC_MEM);
1428   }
1429}
1430
1431void i386_device::i386_setge_rm8()         // Opcode 0x0f 9d
1432{
1433   UINT8 modrm = FETCH();
1434   UINT8 value = 0;
1435   if(m_SF == m_OF) {
1436      value = 1;
1437   }
1438   if( modrm >= 0xc0 ) {
1439      STORE_RM8(modrm, value);
1440      CYCLES(CYCLES_SETCC_REG);
1441   } else {
1442      UINT32 ea = GetEA(modrm,1);
1443      WRITE8(ea, value);
1444      CYCLES(CYCLES_SETCC_MEM);
1445   }
1446}
1447
1448void i386_device::i386_setl_rm8()          // Opcode 0x0f 9c
1449{
1450   UINT8 modrm = FETCH();
1451   UINT8 value = 0;
1452   if( m_SF != m_OF ) {
1453      value = 1;
1454   }
1455   if( modrm >= 0xc0 ) {
1456      STORE_RM8(modrm, value);
1457      CYCLES(CYCLES_SETCC_REG);
1458   } else {
1459      UINT32 ea = GetEA(modrm,1);
1460      WRITE8(ea, value);
1461      CYCLES(CYCLES_SETCC_MEM);
1462   }
1463}
1464
1465void i386_device::i386_setle_rm8()         // Opcode 0x0f 9e
1466{
1467   UINT8 modrm = FETCH();
1468   UINT8 value = 0;
1469   if( m_ZF != 0 || (m_SF != m_OF) ) {
1470      value = 1;
1471   }
1472   if( modrm >= 0xc0 ) {
1473      STORE_RM8(modrm, value);
1474      CYCLES(CYCLES_SETCC_REG);
1475   } else {
1476      UINT32 ea = GetEA(modrm,1);
1477      WRITE8(ea, value);
1478      CYCLES(CYCLES_SETCC_MEM);
1479   }
1480}
1481
1482void i386_device::i386_setnc_rm8()         // Opcode 0x0f 93
1483{
1484   UINT8 modrm = FETCH();
1485   UINT8 value = 0;
1486   if( m_CF == 0 ) {
1487      value = 1;
1488   }
1489   if( modrm >= 0xc0 ) {
1490      STORE_RM8(modrm, value);
1491      CYCLES(CYCLES_SETCC_REG);
1492   } else {
1493      UINT32 ea = GetEA(modrm,1);
1494      WRITE8(ea, value);
1495      CYCLES(CYCLES_SETCC_MEM);
1496   }
1497}
1498
1499void i386_device::i386_setno_rm8()         // Opcode 0x0f 91
1500{
1501   UINT8 modrm = FETCH();
1502   UINT8 value = 0;
1503   if( m_OF == 0 ) {
1504      value = 1;
1505   }
1506   if( modrm >= 0xc0 ) {
1507      STORE_RM8(modrm, value);
1508      CYCLES(CYCLES_SETCC_REG);
1509   } else {
1510      UINT32 ea = GetEA(modrm,1);
1511      WRITE8(ea, value);
1512      CYCLES(CYCLES_SETCC_MEM);
1513   }
1514}
1515
1516void i386_device::i386_setnp_rm8()         // Opcode 0x0f 9b
1517{
1518   UINT8 modrm = FETCH();
1519   UINT8 value = 0;
1520   if( m_PF == 0 ) {
1521      value = 1;
1522   }
1523   if( modrm >= 0xc0 ) {
1524      STORE_RM8(modrm, value);
1525      CYCLES(CYCLES_SETCC_REG);
1526   } else {
1527      UINT32 ea = GetEA(modrm,1);
1528      WRITE8(ea, value);
1529      CYCLES(CYCLES_SETCC_MEM);
1530   }
1531}
1532
1533void i386_device::i386_setns_rm8()         // Opcode 0x0f 99
1534{
1535   UINT8 modrm = FETCH();
1536   UINT8 value = 0;
1537   if( m_SF == 0 ) {
1538      value = 1;
1539   }
1540   if( modrm >= 0xc0 ) {
1541      STORE_RM8(modrm, value);
1542      CYCLES(CYCLES_SETCC_REG);
1543   } else {
1544      UINT32 ea = GetEA(modrm,1);
1545      WRITE8(ea, value);
1546      CYCLES(CYCLES_SETCC_MEM);
1547   }
1548}
1549
1550void i386_device::i386_setnz_rm8()         // Opcode 0x0f 95
1551{
1552   UINT8 modrm = FETCH();
1553   UINT8 value = 0;
1554   if( m_ZF == 0 ) {
1555      value = 1;
1556   }
1557   if( modrm >= 0xc0 ) {
1558      STORE_RM8(modrm, value);
1559      CYCLES(CYCLES_SETCC_REG);
1560   } else {
1561      UINT32 ea = GetEA(modrm,1);
1562      WRITE8(ea, value);
1563      CYCLES(CYCLES_SETCC_MEM);
1564   }
1565}
1566
1567void i386_device::i386_seto_rm8()          // Opcode 0x0f 90
1568{
1569   UINT8 modrm = FETCH();
1570   UINT8 value = 0;
1571   if( m_OF != 0 ) {
1572      value = 1;
1573   }
1574   if( modrm >= 0xc0 ) {
1575      STORE_RM8(modrm, value);
1576      CYCLES(CYCLES_SETCC_REG);
1577   } else {
1578      UINT32 ea = GetEA(modrm,1);
1579      WRITE8(ea, value);
1580      CYCLES(CYCLES_SETCC_MEM);
1581   }
1582}
1583
1584void i386_device::i386_setp_rm8()          // Opcode 0x0f 9a
1585{
1586   UINT8 modrm = FETCH();
1587   UINT8 value = 0;
1588   if( m_PF != 0 ) {
1589      value = 1;
1590   }
1591   if( modrm >= 0xc0 ) {
1592      STORE_RM8(modrm, value);
1593      CYCLES(CYCLES_SETCC_REG);
1594   } else {
1595      UINT32 ea = GetEA(modrm,1);
1596      WRITE8(ea, value);
1597      CYCLES(CYCLES_SETCC_MEM);
1598   }
1599}
1600
1601void i386_device::i386_sets_rm8()          // Opcode 0x0f 98
1602{
1603   UINT8 modrm = FETCH();
1604   UINT8 value = 0;
1605   if( m_SF != 0 ) {
1606      value = 1;
1607   }
1608   if( modrm >= 0xc0 ) {
1609      STORE_RM8(modrm, value);
1610      CYCLES(CYCLES_SETCC_REG);
1611   } else {
1612      UINT32 ea = GetEA(modrm,1);
1613      WRITE8(ea, value);
1614      CYCLES(CYCLES_SETCC_MEM);
1615   }
1616}
1617
1618void i386_device::i386_setz_rm8()          // Opcode 0x0f 94
1619{
1620   UINT8 modrm = FETCH();
1621   UINT8 value = 0;
1622   if( m_ZF != 0 ) {
1623      value = 1;
1624   }
1625   if( modrm >= 0xc0 ) {
1626      STORE_RM8(modrm, value);
1627      CYCLES(CYCLES_SETCC_REG);
1628   } else {
1629      UINT32 ea = GetEA(modrm,1);
1630      WRITE8(ea, value);
1631      CYCLES(CYCLES_SETCC_MEM);
1632   }
1633}
1634
1635void i386_device::i386_stc()               // Opcode 0xf9
1636{
1637   m_CF = 1;
1638   CYCLES(CYCLES_STC);
1639}
1640
1641void i386_device::i386_std()               // Opcode 0xfd
1642{
1643   m_DF = 1;
1644   CYCLES(CYCLES_STD);
1645}
1646
1647void i386_device::i386_sti()               // Opcode 0xfb
1648{
1649   if(PROTECTED_MODE)
1650   {
1651      UINT8 IOPL = m_IOP1 | (m_IOP2 << 1);
1652      if(m_CPL > IOPL)
1653         FAULT(FAULT_GP,0);
1654   }
1655   m_delayed_interrupt_enable = 1;  // IF is set after the next instruction.
1656   CYCLES(CYCLES_STI);
1657}
1658
1659void i386_device::i386_stosb()             // Opcode 0xaa
1660{
1661   UINT32 ead;
1662   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
1663   WRITE8(ead, REG8(AL));
1664   BUMP_DI(1);
1665   CYCLES(CYCLES_STOS);
1666}
1667
1668void i386_device::i386_sub_rm8_r8()        // Opcode 0x28
1669{
1670   UINT8 src, dst;
1671   UINT8 modrm = FETCH();
1672   if( modrm >= 0xc0 ) {
1673      src = LOAD_REG8(modrm);
1674      dst = LOAD_RM8(modrm);
1675      dst = SUB8(dst, src);
1676      STORE_RM8(modrm, dst);
1677      CYCLES(CYCLES_ALU_REG_REG);
1678   } else {
1679      UINT32 ea = GetEA(modrm,1);
1680      src = LOAD_REG8(modrm);
1681      dst = READ8(ea);
1682      dst = SUB8(dst, src);
1683      WRITE8(ea, dst);
1684      CYCLES(CYCLES_ALU_REG_MEM);
1685   }
1686}
1687
1688void i386_device::i386_sub_r8_rm8()        // Opcode 0x2a
1689{
1690   UINT8 src, dst;
1691   UINT8 modrm = FETCH();
1692   if( modrm >= 0xc0 ) {
1693      src = LOAD_RM8(modrm);
1694      dst = LOAD_REG8(modrm);
1695      dst = SUB8(dst, src);
1696      STORE_REG8(modrm, dst);
1697      CYCLES(CYCLES_ALU_REG_REG);
1698   } else {
1699      UINT32 ea = GetEA(modrm,0);
1700      src = READ8(ea);
1701      dst = LOAD_REG8(modrm);
1702      dst = SUB8(dst, src);
1703      STORE_REG8(modrm, dst);
1704      CYCLES(CYCLES_ALU_MEM_REG);
1705   }
1706}
1707
1708void i386_device::i386_sub_al_i8()         // Opcode 0x2c
1709{
1710   UINT8 src, dst;
1711   src = FETCH();
1712   dst = REG8(EAX);
1713   dst = SUB8(dst, src);
1714   REG8(EAX) = dst;
1715   CYCLES(CYCLES_ALU_IMM_ACC);
1716}
1717
1718void i386_device::i386_test_al_i8()        // Opcode 0xa8
1719{
1720   UINT8 src = FETCH();
1721   UINT8 dst = REG8(AL);
1722   dst = src & dst;
1723   SetSZPF8(dst);
1724   m_CF = 0;
1725   m_OF = 0;
1726   CYCLES(CYCLES_ALU_IMM_ACC);
1727}
1728
1729void i386_device::i386_test_rm8_r8()       // Opcode 0x84
1730{
1731   UINT8 src, dst;
1732   UINT8 modrm = FETCH();
1733   if( modrm >= 0xc0 ) {
1734      src = LOAD_REG8(modrm);
1735      dst = LOAD_RM8(modrm);
1736      dst = src & dst;
1737      SetSZPF8(dst);
1738      m_CF = 0;
1739      m_OF = 0;
1740      CYCLES(CYCLES_TEST_REG_REG);
1741   } else {
1742      UINT32 ea = GetEA(modrm,0);
1743      src = LOAD_REG8(modrm);
1744      dst = READ8(ea);
1745      dst = src & dst;
1746      SetSZPF8(dst);
1747      m_CF = 0;
1748      m_OF = 0;
1749      CYCLES(CYCLES_TEST_REG_MEM);
1750   }
1751}
1752
1753void i386_device::i386_xchg_r8_rm8()       // Opcode 0x86
1754{
1755   UINT8 modrm = FETCH();
1756   if( modrm >= 0xc0 ) {
1757      UINT8 src = LOAD_RM8(modrm);
1758      UINT8 dst = LOAD_REG8(modrm);
1759      STORE_REG8(modrm, src);
1760      STORE_RM8(modrm, dst);
1761      CYCLES(CYCLES_XCHG_REG_REG);
1762   } else {
1763      UINT32 ea = GetEA(modrm,1);
1764      UINT8 src = READ8(ea);
1765      UINT8 dst = LOAD_REG8(modrm);
1766      WRITE8(ea, dst);
1767      STORE_REG8(modrm, src);
1768      CYCLES(CYCLES_XCHG_REG_MEM);
1769   }
1770}
1771
1772void i386_device::i386_xor_rm8_r8()        // Opcode 0x30
1773{
1774   UINT8 src, dst;
1775   UINT8 modrm = FETCH();
1776   if( modrm >= 0xc0 ) {
1777      src = LOAD_REG8(modrm);
1778      dst = LOAD_RM8(modrm);
1779      dst = XOR8(dst, src);
1780      STORE_RM8(modrm, dst);
1781      CYCLES(CYCLES_ALU_REG_REG);
1782   } else {
1783      UINT32 ea = GetEA(modrm,1);
1784      src = LOAD_REG8(modrm);
1785      dst = READ8(ea);
1786      dst = XOR8(dst, src);
1787      WRITE8(ea, dst);
1788      CYCLES(CYCLES_ALU_REG_MEM);
1789   }
1790}
1791
1792void i386_device::i386_xor_r8_rm8()        // Opcode 0x32
1793{
1794   UINT32 src, dst;
1795   UINT8 modrm = FETCH();
1796   if( modrm >= 0xc0 ) {
1797      src = LOAD_RM8(modrm);
1798      dst = LOAD_REG8(modrm);
1799      dst = XOR8(dst, src);
1800      STORE_REG8(modrm, dst);
1801      CYCLES(CYCLES_ALU_REG_REG);
1802   } else {
1803      UINT32 ea = GetEA(modrm,0);
1804      src = READ8(ea);
1805      dst = LOAD_REG8(modrm);
1806      dst = XOR8(dst, src);
1807      STORE_REG8(modrm, dst);
1808      CYCLES(CYCLES_ALU_MEM_REG);
1809   }
1810}
1811
1812void i386_device::i386_xor_al_i8()         // Opcode 0x34
1813{
1814   UINT8 src, dst;
1815   src = FETCH();
1816   dst = REG8(AL);
1817   dst = XOR8(dst, src);
1818   REG8(AL) = dst;
1819   CYCLES(CYCLES_ALU_IMM_ACC);
1820}
1821
1822
1823
1824void i386_device::i386_group80_8()         // Opcode 0x80
1825{
1826   UINT32 ea;
1827   UINT8 src, dst;
1828   UINT8 modrm = FETCH();
1829
1830   switch( (modrm >> 3) & 0x7 )
1831   {
1832      case 0:     // ADD Rm8, i8
1833         if( modrm >= 0xc0 ) {
1834            dst = LOAD_RM8(modrm);
1835            src = FETCH();
1836            dst = ADD8(dst, src);
1837            STORE_RM8(modrm, dst);
1838            CYCLES(CYCLES_ALU_REG_REG);
1839         } else {
1840            ea = GetEA(modrm,0);
1841            dst = READ8(ea);
1842            src = FETCH();
1843            dst = ADD8(dst, src);
1844            WRITE8(ea, dst);
1845            CYCLES(CYCLES_ALU_REG_MEM);
1846         }
1847         break;
1848      case 1:     // OR Rm8, i8
1849         if( modrm >= 0xc0 ) {
1850            dst = LOAD_RM8(modrm);
1851            src = FETCH();
1852            dst = OR8(dst, src);
1853            STORE_RM8(modrm, dst);
1854            CYCLES(CYCLES_ALU_REG_REG);
1855         } else {
1856            ea = GetEA(modrm,1);
1857            dst = READ8(ea);
1858            src = FETCH();
1859            dst = OR8(dst, src);
1860            WRITE8(ea, dst);
1861            CYCLES(CYCLES_ALU_REG_MEM);
1862         }
1863         break;
1864      case 2:     // ADC Rm8, i8
1865         if( modrm >= 0xc0 ) {
1866            dst = LOAD_RM8(modrm);
1867            src = FETCH();
1868            dst = ADC8(dst, src, m_CF);
1869            STORE_RM8(modrm, dst);
1870            CYCLES(CYCLES_ALU_REG_REG);
1871         } else {
1872            ea = GetEA(modrm,1);
1873            dst = READ8(ea);
1874            src = FETCH();
1875            dst = ADC8(dst, src, m_CF);
1876            WRITE8(ea, dst);
1877            CYCLES(CYCLES_ALU_REG_MEM);
1878         }
1879         break;
1880      case 3:     // SBB Rm8, i8
1881         if( modrm >= 0xc0 ) {
1882            dst = LOAD_RM8(modrm);
1883            src = FETCH();
1884            dst = SBB8(dst, src, m_CF);
1885            STORE_RM8(modrm, dst);
1886            CYCLES(CYCLES_ALU_REG_REG);
1887         } else {
1888            ea = GetEA(modrm,1);
1889            dst = READ8(ea);
1890            src = FETCH();
1891            dst = SBB8(dst, src, m_CF);
1892            WRITE8(ea, dst);
1893            CYCLES(CYCLES_ALU_REG_MEM);
1894         }
1895         break;
1896      case 4:     // AND Rm8, i8
1897         if( modrm >= 0xc0 ) {
1898            dst = LOAD_RM8(modrm);
1899            src = FETCH();
1900            dst = AND8(dst, src);
1901            STORE_RM8(modrm, dst);
1902            CYCLES(CYCLES_ALU_REG_REG);
1903         } else {
1904            ea = GetEA(modrm,1);
1905            dst = READ8(ea);
1906            src = FETCH();
1907            dst = AND8(dst, src);
1908            WRITE8(ea, dst);
1909            CYCLES(CYCLES_ALU_REG_MEM);
1910         }
1911         break;
1912      case 5:     // SUB Rm8, i8
1913         if( modrm >= 0xc0 ) {
1914            dst = LOAD_RM8(modrm);
1915            src = FETCH();
1916            dst = SUB8(dst, src);
1917            STORE_RM8(modrm, dst);
1918            CYCLES(CYCLES_ALU_REG_REG);
1919         } else {
1920            ea = GetEA(modrm,1);
1921            dst = READ8(ea);
1922            src = FETCH();
1923            dst = SUB8(dst, src);
1924            WRITE8(ea, dst);
1925            CYCLES(CYCLES_ALU_REG_MEM);
1926         }
1927         break;
1928      case 6:     // XOR Rm8, i8
1929         if( modrm >= 0xc0 ) {
1930            dst = LOAD_RM8(modrm);
1931            src = FETCH();
1932            dst = XOR8(dst, src);
1933            STORE_RM8(modrm, dst);
1934            CYCLES(CYCLES_ALU_REG_REG);
1935         } else {
1936            ea = GetEA(modrm,1);
1937            dst = READ8(ea);
1938            src = FETCH();
1939            dst = XOR8(dst, src);
1940            WRITE8(ea, dst);
1941            CYCLES(CYCLES_ALU_REG_MEM);
1942         }
1943         break;
1944      case 7:     // CMP Rm8, i8
1945         if( modrm >= 0xc0 ) {
1946            dst = LOAD_RM8(modrm);
1947            src = FETCH();
1948            SUB8(dst, src);
1949            CYCLES(CYCLES_CMP_REG_REG);
1950         } else {
1951            ea = GetEA(modrm,0);
1952            dst = READ8(ea);
1953            src = FETCH();
1954            SUB8(dst, src);
1955            CYCLES(CYCLES_CMP_REG_MEM);
1956         }
1957         break;
1958   }
1959}
1960
1961void i386_device::i386_groupC0_8()         // Opcode 0xc0
1962{
1963   UINT8 dst;
1964   UINT8 modrm = FETCH();
1965   UINT8 shift;
1966
1967   if( modrm >= 0xc0 ) {
1968      dst = LOAD_RM8(modrm);
1969      shift = FETCH() & 0x1f;
1970      dst = i386_shift_rotate8(modrm, dst, shift);
1971      STORE_RM8(modrm, dst);
1972   } else {
1973      UINT32 ea = GetEA(modrm,1);
1974      dst = READ8(ea);
1975      shift = FETCH() & 0x1f;
1976      dst = i386_shift_rotate8(modrm, dst, shift);
1977      WRITE8(ea, dst);
1978   }
1979}
1980
1981void i386_device::i386_groupD0_8()         // Opcode 0xd0
1982{
1983   UINT8 dst;
1984   UINT8 modrm = FETCH();
1985
1986   if( modrm >= 0xc0 ) {
1987      dst = LOAD_RM8(modrm);
1988      dst = i386_shift_rotate8(modrm, dst, 1);
1989      STORE_RM8(modrm, dst);
1990   } else {
1991      UINT32 ea = GetEA(modrm,1);
1992      dst = READ8(ea);
1993      dst = i386_shift_rotate8(modrm, dst, 1);
1994      WRITE8(ea, dst);
1995   }
1996}
1997
1998void i386_device::i386_groupD2_8()         // Opcode 0xd2
1999{
2000   UINT8 dst;
2001   UINT8 modrm = FETCH();
2002
2003   if( modrm >= 0xc0 ) {
2004      dst = LOAD_RM8(modrm);
2005      dst = i386_shift_rotate8(modrm, dst, REG8(CL));
2006      STORE_RM8(modrm, dst);
2007   } else {
2008      UINT32 ea = GetEA(modrm,1);
2009      dst = READ8(ea);
2010      dst = i386_shift_rotate8(modrm, dst, REG8(CL));
2011      WRITE8(ea, dst);
2012   }
2013}
2014
2015void i386_device::i386_groupF6_8()         // Opcode 0xf6
2016{
2017   UINT8 modrm = FETCH();
2018
2019   switch( (modrm >> 3) & 0x7 )
2020   {
2021      case 0:         /* TEST Rm8, i8 */
2022         if( modrm >= 0xc0 ) {
2023            UINT8 dst = LOAD_RM8(modrm);
2024            UINT8 src = FETCH();
2025            dst &= src;
2026            m_CF = m_OF = m_AF = 0;
2027            SetSZPF8(dst);
2028            CYCLES(CYCLES_TEST_IMM_REG);
2029         } else {
2030            UINT32 ea = GetEA(modrm,0);
2031            UINT8 dst = READ8(ea);
2032            UINT8 src = FETCH();
2033            dst &= src;
2034            m_CF = m_OF = m_AF = 0;
2035            SetSZPF8(dst);
2036            CYCLES(CYCLES_TEST_IMM_MEM);
2037         }
2038         break;
2039      case 2:         /* NOT Rm8 */
2040         if( modrm >= 0xc0 ) {
2041            UINT8 dst = LOAD_RM8(modrm);
2042            dst = ~dst;
2043            STORE_RM8(modrm, dst);
2044            CYCLES(CYCLES_NOT_REG);
2045         } else {
2046            UINT32 ea = GetEA(modrm,1);
2047            UINT8 dst = READ8(ea);
2048            dst = ~dst;
2049            WRITE8(ea, dst);
2050            CYCLES(CYCLES_NOT_MEM);
2051         }
2052         break;
2053      case 3:         /* NEG Rm8 */
2054         if( modrm >= 0xc0 ) {
2055            UINT8 dst = LOAD_RM8(modrm);
2056            dst = SUB8(0, dst );
2057            STORE_RM8(modrm, dst);
2058            CYCLES(CYCLES_NEG_REG);
2059         } else {
2060            UINT32 ea = GetEA(modrm,1);
2061            UINT8 dst = READ8(ea);
2062            dst = SUB8(0, dst );
2063            WRITE8(ea, dst);
2064            CYCLES(CYCLES_NEG_MEM);
2065         }
2066         break;
2067      case 4:         /* MUL AL, Rm8 */
2068         {
2069            UINT16 result;
2070            UINT8 src, dst;
2071            if( modrm >= 0xc0 ) {
2072               src = LOAD_RM8(modrm);
2073               CYCLES(CYCLES_MUL8_ACC_REG);       /* TODO: Correct multiply timing */
2074            } else {
2075               UINT32 ea = GetEA(modrm,0);
2076               src = READ8(ea);
2077               CYCLES(CYCLES_MUL8_ACC_MEM);       /* TODO: Correct multiply timing */
2078            }
2079
2080            dst = REG8(AL);
2081            result = (UINT16)src * (UINT16)dst;
2082            REG16(AX) = (UINT16)result;
2083
2084            m_CF = m_OF = (REG16(AX) > 0xff);
2085         }
2086         break;
2087      case 5:         /* IMUL AL, Rm8 */
2088         {
2089            INT16 result;
2090            INT16 src, dst;
2091            if( modrm >= 0xc0 ) {
2092               src = (INT16)(INT8)LOAD_RM8(modrm);
2093               CYCLES(CYCLES_IMUL8_ACC_REG);      /* TODO: Correct multiply timing */
2094            } else {
2095               UINT32 ea = GetEA(modrm,0);
2096               src = (INT16)(INT8)READ8(ea);
2097               CYCLES(CYCLES_IMUL8_ACC_MEM);      /* TODO: Correct multiply timing */
2098            }
2099
2100            dst = (INT16)(INT8)REG8(AL);
2101            result = src * dst;
2102
2103            REG16(AX) = (UINT16)result;
2104
2105            m_CF = m_OF = !(result == (INT16)(INT8)result);
2106         }
2107         break;
2108      case 6:         /* DIV AL, Rm8 */
2109         {
2110            UINT16 quotient, remainder, result;
2111            UINT8 src;
2112            if( modrm >= 0xc0 ) {
2113               src = LOAD_RM8(modrm);
2114               CYCLES(CYCLES_DIV8_ACC_REG);
2115            } else {
2116               UINT32 ea = GetEA(modrm,0);
2117               src = READ8(ea);
2118               CYCLES(CYCLES_DIV8_ACC_MEM);
2119            }
2120
2121            quotient = (UINT16)REG16(AX);
2122            if( src ) {
2123               remainder = quotient % (UINT16)src;
2124               result = quotient / (UINT16)src;
2125               if( result > 0xff ) {
2126                  /* TODO: Divide error */
2127               } else {
2128                  REG8(AH) = (UINT8)remainder & 0xff;
2129                  REG8(AL) = (UINT8)result & 0xff;
2130
2131                  // this flag is actually undefined, enable on non-cyrix
2132                  if (m_cpuid_id0 != 0x69727943)
2133                     m_CF = 1;
2134               }
2135            } else {
2136               i386_trap(0, 0, 0);
2137            }
2138         }
2139         break;
2140      case 7:         /* IDIV AL, Rm8 */
2141         {
2142            INT16 quotient, remainder, result;
2143            UINT8 src;
2144            if( modrm >= 0xc0 ) {
2145               src = LOAD_RM8(modrm);
2146               CYCLES(CYCLES_IDIV8_ACC_REG);
2147            } else {
2148               UINT32 ea = GetEA(modrm,0);
2149               src = READ8(ea);
2150               CYCLES(CYCLES_IDIV8_ACC_MEM);
2151            }
2152
2153            quotient = (INT16)REG16(AX);
2154            if( src ) {
2155               remainder = quotient % (INT16)(INT8)src;
2156               result = quotient / (INT16)(INT8)src;
2157               if( result > 0xff ) {
2158                  /* TODO: Divide error */
2159               } else {
2160                  REG8(AH) = (UINT8)remainder & 0xff;
2161                  REG8(AL) = (UINT8)result & 0xff;
2162
2163                  // this flag is actually undefined, enable on non-cyrix
2164                  if (m_cpuid_id0 != 0x69727943)
2165                     m_CF = 1;
2166               }
2167            } else {
2168               i386_trap(0, 0, 0);
2169            }
2170         }
2171         break;
2172   }
2173}
2174
2175void i386_device::i386_groupFE_8()         // Opcode 0xfe
2176{
2177   UINT8 modrm = FETCH();
2178
2179   switch( (modrm >> 3) & 0x7 )
2180   {
2181      case 0:         /* INC Rm8 */
2182         if( modrm >= 0xc0 ) {
2183            UINT8 dst = LOAD_RM8(modrm);
2184            dst = INC8(dst);
2185            STORE_RM8(modrm, dst);
2186            CYCLES(CYCLES_INC_REG);
2187         } else {
2188            UINT32 ea = GetEA(modrm,1);
2189            UINT8 dst = READ8(ea);
2190            dst = INC8(dst);
2191            WRITE8(ea, dst);
2192            CYCLES(CYCLES_INC_MEM);
2193         }
2194         break;
2195      case 1:         /* DEC Rm8 */
2196         if( modrm >= 0xc0 ) {
2197            UINT8 dst = LOAD_RM8(modrm);
2198            dst = DEC8(dst);
2199            STORE_RM8(modrm, dst);
2200            CYCLES(CYCLES_DEC_REG);
2201         } else {
2202            UINT32 ea = GetEA(modrm,1);
2203            UINT8 dst = READ8(ea);
2204            dst = DEC8(dst);
2205            WRITE8(ea, dst);
2206            CYCLES(CYCLES_DEC_MEM);
2207         }
2208         break;
2209      case 6:         /* PUSH Rm8*/
2210         {
2211            UINT8 value;
2212            if( modrm >= 0xc0 ) {
2213               value = LOAD_RM8(modrm);
2214            } else {
2215               UINT32 ea = GetEA(modrm,0);
2216               value = READ8(ea);
2217            }
2218            if( m_operand_size ) {
2219               PUSH32(value);
2220            } else {
2221               PUSH16(value);
2222            }
2223            CYCLES(CYCLES_PUSH_RM);
2224         }
2225         break;
2226      default:
2227         report_invalid_modrm("groupFE_8", modrm);
2228         break;
2229   }
2230}
2231
2232
2233
2234void i386_device::i386_segment_CS()        // Opcode 0x2e
2235{
2236   m_segment_prefix = 1;
2237   m_segment_override = CS;
2238
2239   i386_decode_opcode();
2240}
2241
2242void i386_device::i386_segment_DS()        // Opcode 0x3e
2243{
2244   m_segment_prefix = 1;
2245   m_segment_override = DS;
2246   CYCLES(0); // TODO: Specify cycle count
2247   i386_decode_opcode();
2248}
2249
2250void i386_device::i386_segment_ES()        // Opcode 0x26
2251{
2252   m_segment_prefix = 1;
2253   m_segment_override = ES;
2254   CYCLES(0); // TODO: Specify cycle count
2255   i386_decode_opcode();
2256}
2257
2258void i386_device::i386_segment_FS()        // Opcode 0x64
2259{
2260   m_segment_prefix = 1;
2261   m_segment_override = FS;
2262   CYCLES(1); // TODO: Specify cycle count
2263   i386_decode_opcode();
2264}
2265
2266void i386_device::i386_segment_GS()        // Opcode 0x65
2267{
2268   m_segment_prefix = 1;
2269   m_segment_override = GS;
2270   CYCLES(1); // TODO: Specify cycle count
2271   i386_decode_opcode();
2272}
2273
2274void i386_device::i386_segment_SS()        // Opcode 0x36
2275{
2276   m_segment_prefix = 1;
2277   m_segment_override = SS;
2278   CYCLES(0); // TODO: Specify cycle count
2279   i386_decode_opcode();
2280}
2281
2282void i386_device::i386_operand_size()      // Opcode prefix 0x66
2283{
2284   if(m_operand_prefix == 0)
2285   {
2286      m_operand_size ^= 1;
2287      m_operand_prefix = 1;
2288   }
2289   m_opcode = FETCH();
2290   if (m_opcode == 0x0f)
2291      i386_decode_three_byte66();
2292   else
2293   {
2294      if( m_operand_size )
2295         (this->*m_opcode_table1_32[m_opcode])();
2296      else
2297         (this->*m_opcode_table1_16[m_opcode])();
2298   }
2299}
2300
2301void i386_device::i386_address_size()      // Opcode 0x67
2302{
2303   if(m_address_prefix == 0)
2304   {
2305      m_address_size ^= 1;
2306      m_address_prefix = 1;
2307   }
2308   i386_decode_opcode();
2309}
2310
2311void i386_device::i386_nop()               // Opcode 0x90
2312{
2313   CYCLES(CYCLES_NOP);
2314}
2315
2316void i386_device::i386_int3()              // Opcode 0xcc
2317{
2318   CYCLES(CYCLES_INT3);
2319   m_ext = 0; // not an external interrupt
2320   i386_trap(3, 1, 0);
2321   m_ext = 1;
2322}
2323
2324void i386_device::i386_int()               // Opcode 0xcd
2325{
2326   int interrupt = FETCH();
2327   CYCLES(CYCLES_INT);
2328   m_ext = 0; // not an external interrupt
2329   i386_trap(interrupt, 1, 0);
2330   m_ext = 1;
2331}
2332
2333void i386_device::i386_into()              // Opcode 0xce
2334{
2335   if( m_OF ) {
2336      m_ext = 0;
2337      i386_trap(4, 1, 0);
2338      m_ext = 1;
2339      CYCLES(CYCLES_INTO_OF1);
2340   }
2341   else
2342   {
2343      CYCLES(CYCLES_INTO_OF0);
2344   }
2345}
2346
2347static UINT32 i386_escape_ea;   // hack around GCC 4.6 error because we need the side effects of GetEA()
2348void i386_device::i386_escape()            // Opcodes 0xd8 - 0xdf
2349{
2350   UINT8 modrm = FETCH();
2351   if(modrm < 0xc0)
2352   {
2353      i386_escape_ea = GetEA(modrm,0);
2354   }
2355   CYCLES(3); // TODO: confirm this
2356   (void) LOAD_RM8(modrm);
2357}
2358
2359void i386_device::i386_hlt()               // Opcode 0xf4
2360{
2361   if(PROTECTED_MODE && m_CPL != 0)
2362      FAULT(FAULT_GP,0);
2363   m_halted = 1;
2364   CYCLES(CYCLES_HLT);
2365   if (m_cycles > 0)
2366      m_cycles = 0;
2367}
2368
2369void i386_device::i386_decimal_adjust(int direction)
2370{
2371   UINT8 tmpAL = REG8(AL);
2372   UINT8 tmpCF = m_CF;
2373
2374   if (m_AF || ((REG8(AL) & 0xf) > 9))
2375   {
2376      UINT16 t= (UINT16)REG8(AL) + (direction * 0x06);
2377      REG8(AL) = (UINT8)t&0xff;
2378      m_AF = 1;
2379      if (t & 0x100)
2380         m_CF = 1;
2381      if (direction > 0)
2382         tmpAL = REG8(AL);
2383   }
2384
2385   if (tmpCF || (tmpAL > 0x99))
2386   {
2387      REG8(AL) += (direction * 0x60);
2388      m_CF = 1;
2389   }
2390
2391   SetSZPF8(REG8(AL));
2392}
2393
2394void i386_device::i386_daa()               // Opcode 0x27
2395{
2396   i386_decimal_adjust(+1);
2397   CYCLES(CYCLES_DAA);
2398}
2399
2400void i386_device::i386_das()               // Opcode 0x2f
2401{
2402   i386_decimal_adjust(-1);
2403   CYCLES(CYCLES_DAS);
2404}
2405
2406void i386_device::i386_aaa()               // Opcode 0x37
2407{
2408   if( ( (REG8(AL) & 0x0f) > 9) || (m_AF != 0) ) {
2409      REG16(AX) = REG16(AX) + 6;
2410      REG8(AH) = REG8(AH) + 1;
2411      m_AF = 1;
2412      m_CF = 1;
2413   } else {
2414      m_AF = 0;
2415      m_CF = 0;
2416   }
2417   REG8(AL) = REG8(AL) & 0x0f;
2418   CYCLES(CYCLES_AAA);
2419}
2420
2421void i386_device::i386_aas()               // Opcode 0x3f
2422{
2423   if (m_AF || ((REG8(AL) & 0xf) > 9))
2424   {
2425      REG16(AX) -= 6;
2426      REG8(AH) -= 1;
2427      m_AF = 1;
2428      m_CF = 1;
2429   }
2430   else
2431   {
2432      m_AF = 0;
2433      m_CF = 0;
2434   }
2435   REG8(AL) &= 0x0f;
2436   CYCLES(CYCLES_AAS);
2437}
2438
2439void i386_device::i386_aad()               // Opcode 0xd5
2440{
2441   UINT8 tempAL = REG8(AL);
2442   UINT8 tempAH = REG8(AH);
2443   UINT8 i = FETCH();
2444
2445   REG8(AL) = (tempAL + (tempAH * i)) & 0xff;
2446   REG8(AH) = 0;
2447   SetSZPF8( REG8(AL) );
2448   CYCLES(CYCLES_AAD);
2449}
2450
2451void i386_device::i386_aam()               // Opcode 0xd4
2452{
2453   UINT8 tempAL = REG8(AL);
2454   UINT8 i = FETCH();
2455
2456   if(!i)
2457   {
2458      i386_trap(0, 0, 0);
2459      return;
2460   }
2461   REG8(AH) = tempAL / i;
2462   REG8(AL) = tempAL % i;
2463   SetSZPF8( REG8(AL) );
2464   CYCLES(CYCLES_AAM);
2465}
2466
2467void i386_device::i386_clts()              // Opcode 0x0f 0x06
2468{
2469   // Privileged instruction, CPL must be zero.  Can be used in real or v86 mode.
2470   if(PROTECTED_MODE && m_CPL != 0)
2471      FAULT(FAULT_GP,0)
2472   m_cr[0] &= ~0x08;   /* clear TS bit */
2473   CYCLES(CYCLES_CLTS);
2474}
2475
2476void i386_device::i386_wait()              // Opcode 0x9B
2477{
2478   // TODO
2479}
2480
2481void i386_device::i386_lock()              // Opcode 0xf0
2482{
2483   // lock doesn't depend on iopl on 386
2484   // TODO: lock causes UD on unlockable opcodes
2485   CYCLES(CYCLES_LOCK);       // TODO: Determine correct cycle count
2486   i386_decode_opcode();
2487}
2488
2489void i386_device::i386_mov_r32_tr()        // Opcode 0x0f 24
2490{
2491   FETCH();
2492   CYCLES(1);     // TODO: correct cycle count
2493}
2494
2495void i386_device::i386_mov_tr_r32()        // Opcode 0x0f 26
2496{
2497   FETCH();
2498   CYCLES(1);     // TODO: correct cycle count
2499}
2500
2501void i386_device::i386_loadall()       // Opcode 0x0f 0x07 (0x0f 0x05 on 80286), undocumented
2502{
2503   fatalerror("i386: LOADALL unimplemented at %08X\n", m_pc - 1);
2504}
2505
2506void i386_device::i386_invalid()
2507{
2508   report_invalid_opcode();
2509   i386_trap(6, 0, 0);
2510}
2511
2512void i386_device::i386_xlat()          // Opcode 0xd7
2513{
2514   UINT32 ea;
2515   if( m_segment_prefix ) {
2516      if(!m_address_size)
2517      {
2518         ea = i386_translate(m_segment_override, REG16(BX) + REG8(AL), 0 );
2519      }
2520      else
2521      {
2522         ea = i386_translate(m_segment_override, REG32(EBX) + REG8(AL), 0 );
2523      }
2524   } else {
2525      if(!m_address_size)
2526      {
2527         ea = i386_translate(DS, REG16(BX) + REG8(AL), 0 );
2528      }
2529      else
2530      {
2531         ea = i386_translate(DS, REG32(EBX) + REG8(AL), 0 );
2532      }
2533   }
2534   REG8(AL) = READ8(ea);
2535   CYCLES(CYCLES_XLAT);
2536}
Property changes on: trunk/src/emu/cpu/i386/i386ops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/i386/i486ops.inc
r0r28739
1// Intel 486+ specific opcodes
2
3void i386_device::i486_cpuid()             // Opcode 0x0F A2
4{
5   if (m_cpuid_id0 == 0)
6   {
7      // this 486 doesn't support the CPUID instruction
8      logerror("CPUID not supported at %08x!\n", m_eip);
9      i386_trap(6, 0, 0);
10   }
11   else
12   {
13      switch (REG32(EAX))
14      {
15         case 0:
16         {
17            REG32(EAX) = m_cpuid_max_input_value_eax;
18            REG32(EBX) = m_cpuid_id0;
19            REG32(ECX) = m_cpuid_id2;
20            REG32(EDX) = m_cpuid_id1;
21            CYCLES(CYCLES_CPUID);
22            break;
23         }
24
25         case 1:
26         {
27            REG32(EAX) = m_cpu_version;
28            REG32(EDX) = m_feature_flags;
29            CYCLES(CYCLES_CPUID_EAX1);
30            break;
31         }
32      }
33   }
34}
35
36void i386_device::i486_invd()              // Opcode 0x0f 08
37{
38   // Nothing to do ?
39   CYCLES(CYCLES_INVD);
40}
41
42void i386_device::i486_wbinvd()            // Opcode 0x0f 09
43{
44   // Nothing to do ?
45}
46
47void i386_device::i486_cmpxchg_rm8_r8()    // Opcode 0x0f b0
48{
49   UINT8 modrm = FETCH();
50   if( modrm >= 0xc0 ) {
51      UINT8 dst = LOAD_RM8(modrm);
52      UINT8 src = LOAD_REG8(modrm);
53
54      if( REG8(AL) == dst ) {
55         STORE_RM8(modrm, src);
56         m_ZF = 1;
57         CYCLES(CYCLES_CMPXCHG_REG_REG_T);
58      } else {
59         REG8(AL) = dst;
60         m_ZF = 0;
61         CYCLES(CYCLES_CMPXCHG_REG_REG_F);
62      }
63   } else {
64      // TODO: Check write if needed
65      UINT32 ea = GetEA(modrm,0);
66      UINT8 dst = READ8(ea);
67      UINT8 src = LOAD_REG8(modrm);
68
69      if( REG8(AL) == dst ) {
70         WRITE8(ea, src);
71         m_ZF = 1;
72         CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
73      } else {
74         REG8(AL) = dst;
75         m_ZF = 0;
76         CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
77      }
78   }
79}
80
81void i386_device::i486_cmpxchg_rm16_r16()  // Opcode 0x0f b1
82{
83   UINT8 modrm = FETCH();
84   if( modrm >= 0xc0 ) {
85      UINT16 dst = LOAD_RM16(modrm);
86      UINT16 src = LOAD_REG16(modrm);
87
88      if( REG16(AX) == dst ) {
89         STORE_RM16(modrm, src);
90         m_ZF = 1;
91         CYCLES(CYCLES_CMPXCHG_REG_REG_T);
92      } else {
93         REG16(AX) = dst;
94         m_ZF = 0;
95         CYCLES(CYCLES_CMPXCHG_REG_REG_F);
96      }
97   } else {
98      UINT32 ea = GetEA(modrm,0);
99      UINT16 dst = READ16(ea);
100      UINT16 src = LOAD_REG16(modrm);
101
102      if( REG16(AX) == dst ) {
103         WRITE16(ea, src);
104         m_ZF = 1;
105         CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
106      } else {
107         REG16(AX) = dst;
108         m_ZF = 0;
109         CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
110      }
111   }
112}
113
114void i386_device::i486_cmpxchg_rm32_r32()  // Opcode 0x0f b1
115{
116   UINT8 modrm = FETCH();
117   if( modrm >= 0xc0 ) {
118      UINT32 dst = LOAD_RM32(modrm);
119      UINT32 src = LOAD_REG32(modrm);
120
121      if( REG32(EAX) == dst ) {
122         STORE_RM32(modrm, src);
123         m_ZF = 1;
124         CYCLES(CYCLES_CMPXCHG_REG_REG_T);
125      } else {
126         REG32(EAX) = dst;
127         m_ZF = 0;
128         CYCLES(CYCLES_CMPXCHG_REG_REG_F);
129      }
130   } else {
131      UINT32 ea = GetEA(modrm,0);
132      UINT32 dst = READ32(ea);
133      UINT32 src = LOAD_REG32(modrm);
134
135      if( REG32(EAX) == dst ) {
136         WRITE32(ea, src);
137         m_ZF = 1;
138         CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
139      } else {
140         REG32(EAX) = dst;
141         m_ZF = 0;
142         CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
143      }
144   }
145}
146
147void i386_device::i486_xadd_rm8_r8()   // Opcode 0x0f c0
148{
149   UINT8 modrm = FETCH();
150   if( modrm >= 0xc0 ) {
151      UINT8 dst = LOAD_RM8(modrm);
152      UINT8 src = LOAD_REG8(modrm);
153      STORE_REG8(modrm, dst);
154      STORE_RM8(modrm, dst + src);
155      CYCLES(CYCLES_XADD_REG_REG);
156   } else {
157      UINT32 ea = GetEA(modrm,1);
158      UINT8 dst = READ8(ea);
159      UINT8 src = LOAD_REG8(modrm);
160      WRITE8(ea, dst + src);
161      STORE_REG8(modrm, dst);
162      CYCLES(CYCLES_XADD_REG_MEM);
163   }
164}
165
166void i386_device::i486_xadd_rm16_r16() // Opcode 0x0f c1
167{
168   UINT8 modrm = FETCH();
169   if( modrm >= 0xc0 ) {
170      UINT16 dst = LOAD_RM16(modrm);
171      UINT16 src = LOAD_REG16(modrm);
172      STORE_REG16(modrm, dst);
173      STORE_RM16(modrm, dst + src);
174      CYCLES(CYCLES_XADD_REG_REG);
175   } else {
176      UINT32 ea = GetEA(modrm,1);
177      UINT16 dst = READ16(ea);
178      UINT16 src = LOAD_REG16(modrm);
179      WRITE16(ea, dst + src);
180      STORE_REG16(modrm, dst);
181      CYCLES(CYCLES_XADD_REG_MEM);
182   }
183}
184
185void i386_device::i486_xadd_rm32_r32() // Opcode 0x0f c1
186{
187   UINT8 modrm = FETCH();
188   if( modrm >= 0xc0 ) {
189      UINT32 dst = LOAD_RM32(modrm);
190      UINT32 src = LOAD_REG32(modrm);
191      STORE_REG32(modrm, dst);
192      STORE_RM32(modrm, dst + src);
193      CYCLES(CYCLES_XADD_REG_REG);
194   } else {
195      UINT32 ea = GetEA(modrm,1);
196      UINT32 dst = READ32(ea);
197      UINT32 src = LOAD_REG32(modrm);
198      WRITE32(ea, dst + src);
199      STORE_REG32(modrm, dst);
200      CYCLES(CYCLES_XADD_REG_MEM);
201   }
202}
203
204void i386_device::i486_group0F01_16()      // Opcode 0x0f 01
205{
206   UINT8 modrm = FETCH();
207   UINT16 address;
208   UINT32 ea;
209
210   switch( (modrm >> 3) & 0x7 )
211   {
212      case 0:         /* SGDT */
213         {
214            if( modrm >= 0xc0 ) {
215               address = LOAD_RM16(modrm);
216               ea = i386_translate( CS, address, 1 );
217            } else {
218               ea = GetEA(modrm,1);
219            }
220            WRITE16(ea, m_gdtr.limit);
221            WRITE32(ea + 2, m_gdtr.base & 0xffffff);
222            CYCLES(CYCLES_SGDT);
223            break;
224         }
225      case 1:         /* SIDT */
226         {
227            if (modrm >= 0xc0)
228            {
229               address = LOAD_RM16(modrm);
230               ea = i386_translate( CS, address, 1 );
231            }
232            else
233            {
234               ea = GetEA(modrm,1);
235            }
236            WRITE16(ea, m_idtr.limit);
237            WRITE32(ea + 2, m_idtr.base & 0xffffff);
238            CYCLES(CYCLES_SIDT);
239            break;
240         }
241      case 2:         /* LGDT */
242         {
243            if(PROTECTED_MODE && m_CPL)
244               FAULT(FAULT_GP,0)
245            if( modrm >= 0xc0 ) {
246               address = LOAD_RM16(modrm);
247               ea = i386_translate( CS, address, 0 );
248            } else {
249               ea = GetEA(modrm,0);
250            }
251            m_gdtr.limit = READ16(ea);
252            m_gdtr.base = READ32(ea + 2) & 0xffffff;
253            CYCLES(CYCLES_LGDT);
254            break;
255         }
256      case 3:         /* LIDT */
257         {
258            if(PROTECTED_MODE && m_CPL)
259               FAULT(FAULT_GP,0)
260            if( modrm >= 0xc0 ) {
261               address = LOAD_RM16(modrm);
262               ea = i386_translate( CS, address, 0 );
263            } else {
264               ea = GetEA(modrm,0);
265            }
266            m_idtr.limit = READ16(ea);
267            m_idtr.base = READ32(ea + 2) & 0xffffff;
268            CYCLES(CYCLES_LIDT);
269            break;
270         }
271      case 4:         /* SMSW */
272         {
273            if( modrm >= 0xc0 ) {
274               STORE_RM16(modrm, m_cr[0]);
275               CYCLES(CYCLES_SMSW_REG);
276            } else {
277               ea = GetEA(modrm,1);
278               WRITE16(ea, m_cr[0]);
279               CYCLES(CYCLES_SMSW_MEM);
280            }
281            break;
282         }
283      case 6:         /* LMSW */
284         {
285            UINT16 b;
286            if(PROTECTED_MODE && m_CPL)
287               FAULT(FAULT_GP,0)
288            if( modrm >= 0xc0 ) {
289               b = LOAD_RM16(modrm);
290               CYCLES(CYCLES_LMSW_REG);
291            } else {
292               ea = GetEA(modrm,0);
293               CYCLES(CYCLES_LMSW_MEM);
294               b = READ16(ea);
295            }
296            if(PROTECTED_MODE)
297               b |= 0x0001;  // cannot return to real mode using this instruction.
298            m_cr[0] &= ~0x0000000f;
299            m_cr[0] |= b & 0x0000000f;
300            break;
301         }
302      case 7:         /* INVLPG */
303         {
304            if(PROTECTED_MODE && m_CPL)
305               FAULT(FAULT_GP,0)
306            if(modrm >= 0xc0)
307            {
308               logerror("i486: invlpg with modrm %02X\n", modrm);
309               FAULT(FAULT_UD,0)
310            }
311            ea = GetEA(modrm,-1);
312            CYCLES(25); // TODO: add to cycles.h
313            vtlb_flush_address(m_vtlb, ea);
314            break;
315         }
316      default:
317         report_invalid_modrm("group0F01_16", modrm);
318         break;
319   }
320}
321
322void i386_device::i486_group0F01_32()      // Opcode 0x0f 01
323{
324   UINT8 modrm = FETCH();
325   UINT32 address, ea;
326
327   switch( (modrm >> 3) & 0x7 )
328   {
329      case 0:         /* SGDT */
330         {
331            if( modrm >= 0xc0 ) {
332               address = LOAD_RM32(modrm);
333               ea = i386_translate( CS, address, 1 );
334            } else {
335               ea = GetEA(modrm,1);
336            }
337            WRITE16(ea, m_gdtr.limit);
338            WRITE32(ea + 2, m_gdtr.base);
339            CYCLES(CYCLES_SGDT);
340            break;
341         }
342      case 1:         /* SIDT */
343         {
344            if (modrm >= 0xc0)
345            {
346               address = LOAD_RM32(modrm);
347               ea = i386_translate( CS, address, 1 );
348            }
349            else
350            {
351               ea = GetEA(modrm,1);
352            }
353            WRITE16(ea, m_idtr.limit);
354            WRITE32(ea + 2, m_idtr.base);
355            CYCLES(CYCLES_SIDT);
356            break;
357         }
358      case 2:         /* LGDT */
359         {
360            if(PROTECTED_MODE && m_CPL)
361               FAULT(FAULT_GP,0)
362            if( modrm >= 0xc0 ) {
363               address = LOAD_RM32(modrm);
364               ea = i386_translate( CS, address, 0 );
365            } else {
366               ea = GetEA(modrm,0);
367            }
368            m_gdtr.limit = READ16(ea);
369            m_gdtr.base = READ32(ea + 2);
370            CYCLES(CYCLES_LGDT);
371            break;
372         }
373      case 3:         /* LIDT */
374         {
375            if(PROTECTED_MODE && m_CPL)
376               FAULT(FAULT_GP,0)
377            if( modrm >= 0xc0 ) {
378               address = LOAD_RM32(modrm);
379               ea = i386_translate( CS, address, 0 );
380            } else {
381               ea = GetEA(modrm,0);
382            }
383            m_idtr.limit = READ16(ea);
384            m_idtr.base = READ32(ea + 2);
385            CYCLES(CYCLES_LIDT);
386            break;
387         }
388      case 4:         /* SMSW */
389         {
390            if( modrm >= 0xc0 ) {
391               STORE_RM32(modrm, m_cr[0] & 0xffff);
392               CYCLES(CYCLES_SMSW_REG);
393            } else {
394               /* always 16-bit memory operand */
395               ea = GetEA(modrm,1);
396               WRITE16(ea, m_cr[0]);
397               CYCLES(CYCLES_SMSW_MEM);
398            }
399            break;
400         }
401      case 6:         /* LMSW */
402         {
403            if(PROTECTED_MODE && m_CPL)
404               FAULT(FAULT_GP,0)
405            UINT16 b;
406            if( modrm >= 0xc0 ) {
407               b = LOAD_RM16(modrm);
408               CYCLES(CYCLES_LMSW_REG);
409            } else {
410               ea = GetEA(modrm,0);
411               CYCLES(CYCLES_LMSW_MEM);
412            b = READ16(ea);
413            }
414            if(PROTECTED_MODE)
415               b |= 0x0001;  // cannot return to real mode using this instruction.
416            m_cr[0] &= ~0x0000000f;
417            m_cr[0] |= b & 0x0000000f;
418            break;
419         }
420      case 7:         /* INVLPG */
421         {
422            if(PROTECTED_MODE && m_CPL)
423               FAULT(FAULT_GP,0)
424            if(modrm >= 0xc0)
425            {
426               logerror("i486: invlpg with modrm %02X\n", modrm);
427               FAULT(FAULT_UD,0)
428            }
429            ea = GetEA(modrm,-1);
430            CYCLES(25); // TODO: add to cycles.h
431            vtlb_flush_address(m_vtlb, ea);
432            break;
433         }
434      default:
435         report_invalid_modrm("group0F01_32", modrm);
436         break;
437   }
438}
439
440void i386_device::i486_bswap_eax()     // Opcode 0x0f 38
441{
442   REG32(EAX) = SWITCH_ENDIAN_32(REG32(EAX));
443   CYCLES(1);     // TODO
444}
445
446void i386_device::i486_bswap_ecx()     // Opcode 0x0f 39
447{
448   REG32(ECX) = SWITCH_ENDIAN_32(REG32(ECX));
449   CYCLES(1);     // TODO
450}
451
452void i386_device::i486_bswap_edx()     // Opcode 0x0f 3A
453{
454   REG32(EDX) = SWITCH_ENDIAN_32(REG32(EDX));
455   CYCLES(1);     // TODO
456}
457
458void i386_device::i486_bswap_ebx()     // Opcode 0x0f 3B
459{
460   REG32(EBX) = SWITCH_ENDIAN_32(REG32(EBX));
461   CYCLES(1);     // TODO
462}
463
464void i386_device::i486_bswap_esp()     // Opcode 0x0f 3C
465{
466   REG32(ESP) = SWITCH_ENDIAN_32(REG32(ESP));
467   CYCLES(1);     // TODO
468}
469
470void i386_device::i486_bswap_ebp()     // Opcode 0x0f 3D
471{
472   REG32(EBP) = SWITCH_ENDIAN_32(REG32(EBP));
473   CYCLES(1);     // TODO
474}
475
476void i386_device::i486_bswap_esi()     // Opcode 0x0f 3E
477{
478   REG32(ESI) = SWITCH_ENDIAN_32(REG32(ESI));
479   CYCLES(1);     // TODO
480}
481
482void i386_device::i486_bswap_edi()     // Opcode 0x0f 3F
483{
484   REG32(EDI) = SWITCH_ENDIAN_32(REG32(EDI));
485   CYCLES(1);     // TODO
486}
487
488void i386_device::i486_mov_cr_r32()        // Opcode 0x0f 22
489{
490   if(PROTECTED_MODE && m_CPL)
491      FAULT(FAULT_GP, 0);
492   UINT8 modrm = FETCH();
493   UINT8 cr = (modrm >> 3) & 0x7;
494   UINT32 oldcr = m_cr[cr];
495   UINT32 data = LOAD_RM32(modrm);
496   switch(cr)
497   {
498      case 0:
499         CYCLES(CYCLES_MOV_REG_CR0);
500         if((oldcr ^ m_cr[cr]) & 0x80010000)
501            vtlb_flush_dynamic(m_vtlb);
502         break;
503      case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
504      case 3:
505         CYCLES(CYCLES_MOV_REG_CR3);
506         vtlb_flush_dynamic(m_vtlb);
507         break;
508      case 4: CYCLES(1); break; // TODO
509      default:
510         logerror("i386: mov_cr_r32 CR%d!\n", cr);
511         return;
512   }
513   m_cr[cr] = data;
514}
Property changes on: trunk/src/emu/cpu/i386/i486ops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/i386/i386op32.inc
r0r28739
1UINT32 i386_device::i386_shift_rotate32(UINT8 modrm, UINT32 value, UINT8 shift)
2{
3   UINT32 dst, src;
4   dst = value;
5   src = value;
6
7   if( shift == 0 ) {
8      CYCLES_RM(modrm, 3, 7);
9   } else if( shift == 1 ) {
10      switch( (modrm >> 3) & 0x7 )
11      {
12         case 0:         /* ROL rm32, 1 */
13            m_CF = (src & 0x80000000) ? 1 : 0;
14            dst = (src << 1) + m_CF;
15            m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
16            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
17            break;
18         case 1:         /* ROR rm32, 1 */
19            m_CF = (src & 0x1) ? 1 : 0;
20            dst = (m_CF << 31) | (src >> 1);
21            m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
22            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
23            break;
24         case 2:         /* RCL rm32, 1 */
25            dst = (src << 1) + m_CF;
26            m_CF = (src & 0x80000000) ? 1 : 0;
27            m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
28            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
29            break;
30         case 3:         /* RCR rm32, 1 */
31            dst = (m_CF << 31) | (src >> 1);
32            m_CF = src & 0x1;
33            m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
34            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
35            break;
36         case 4:         /* SHL/SAL rm32, 1 */
37         case 6:
38            dst = src << 1;
39            m_CF = (src & 0x80000000) ? 1 : 0;
40            m_OF = (((m_CF << 31) ^ dst) & 0x80000000) ? 1 : 0;
41            SetSZPF32(dst);
42            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
43            break;
44         case 5:         /* SHR rm32, 1 */
45            dst = src >> 1;
46            m_CF = src & 0x1;
47            m_OF = (src & 0x80000000) ? 1 : 0;
48            SetSZPF32(dst);
49            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
50            break;
51         case 7:         /* SAR rm32, 1 */
52            dst = (INT32)(src) >> 1;
53            m_CF = src & 0x1;
54            m_OF = 0;
55            SetSZPF32(dst);
56            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
57            break;
58      }
59
60   } else {
61      shift &= 31;
62      switch( (modrm >> 3) & 0x7 )
63      {
64         case 0:         /* ROL rm32, i8 */
65            dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
66                  ((src & ((UINT32)0xffffffff << (32-shift))) >> (32-shift));
67            m_CF = dst & 0x1;
68            m_OF = (dst & 1) ^ (dst >> 31);
69            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
70            break;
71         case 1:         /* ROR rm32, i8 */
72            dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
73                  ((src & ((UINT32)0xffffffff >> (32-shift))) << (32-shift));
74            m_CF = (dst >> 31) & 0x1;
75            m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
76            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
77            break;
78         case 2:         /* RCL rm32, i8 */
79            dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
80                  ((src & ((UINT32)0xffffffff << (33-shift))) >> (33-shift)) |
81                  (m_CF << (shift-1));
82            m_CF = (src >> (32-shift)) & 0x1;
83            m_OF = m_CF ^ ((dst >> 31) & 1);
84            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
85            break;
86         case 3:         /* RCR rm32, i8 */
87            dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
88                  ((src & ((UINT32)0xffffffff >> (32-shift))) << (33-shift)) |
89                  (m_CF << (32-shift));
90            m_CF = (src >> (shift-1)) & 0x1;
91            m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
92            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
93            break;
94         case 4:         /* SHL/SAL rm32, i8 */
95         case 6:
96            dst = src << shift;
97            m_CF = (src & (1 << (32-shift))) ? 1 : 0;
98            SetSZPF32(dst);
99            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
100            break;
101         case 5:         /* SHR rm32, i8 */
102            dst = src >> shift;
103            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
104            SetSZPF32(dst);
105            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
106            break;
107         case 7:         /* SAR rm32, i8 */
108            dst = (INT32)src >> shift;
109            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
110            SetSZPF32(dst);
111            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
112            break;
113      }
114
115   }
116   return dst;
117}
118
119
120
121void i386_device::i386_adc_rm32_r32()      // Opcode 0x11
122{
123   UINT32 src, dst;
124   UINT8 modrm = FETCH();
125   if( modrm >= 0xc0 ) {
126      src = LOAD_REG32(modrm);
127      dst = LOAD_RM32(modrm);
128      dst = ADC32(dst, src, m_CF);
129      STORE_RM32(modrm, dst);
130      CYCLES(CYCLES_ALU_REG_REG);
131   } else {
132      UINT32 ea = GetEA(modrm,1);
133      src = LOAD_REG32(modrm);
134      dst = READ32(ea);
135      dst = ADC32(dst, src, m_CF);
136      WRITE32(ea, dst);
137      CYCLES(CYCLES_ALU_REG_MEM);
138   }
139}
140
141void i386_device::i386_adc_r32_rm32()      // Opcode 0x13
142{
143   UINT32 src, dst;
144   UINT8 modrm = FETCH();
145   if( modrm >= 0xc0 ) {
146      src = LOAD_RM32(modrm);
147      dst = LOAD_REG32(modrm);
148      dst = ADC32(dst, src, m_CF);
149      STORE_REG32(modrm, dst);
150      CYCLES(CYCLES_ALU_REG_REG);
151   } else {
152      UINT32 ea = GetEA(modrm,0);
153      src = READ32(ea);
154      dst = LOAD_REG32(modrm);
155      dst = ADC32(dst, src, m_CF);
156      STORE_REG32(modrm, dst);
157      CYCLES(CYCLES_ALU_MEM_REG);
158   }
159}
160
161void i386_device::i386_adc_eax_i32()       // Opcode 0x15
162{
163   UINT32 src, dst;
164   src = FETCH32();
165   dst = REG32(EAX);
166   dst = ADC32(dst, src, m_CF);
167   REG32(EAX) = dst;
168   CYCLES(CYCLES_ALU_IMM_ACC);
169}
170
171void i386_device::i386_add_rm32_r32()      // Opcode 0x01
172{
173   UINT32 src, dst;
174   UINT8 modrm = FETCH();
175   if( modrm >= 0xc0 ) {
176      src = LOAD_REG32(modrm);
177      dst = LOAD_RM32(modrm);
178      dst = ADD32(dst, src);
179      STORE_RM32(modrm, dst);
180      CYCLES(CYCLES_ALU_REG_REG);
181   } else {
182      UINT32 ea = GetEA(modrm,1);
183      src = LOAD_REG32(modrm);
184      dst = READ32(ea);
185      dst = ADD32(dst, src);
186      WRITE32(ea, dst);
187      CYCLES(CYCLES_ALU_REG_MEM);
188   }
189}
190
191void i386_device::i386_add_r32_rm32()      // Opcode 0x03
192{
193   UINT32 src, dst;
194   UINT8 modrm = FETCH();
195   if( modrm >= 0xc0 ) {
196      src = LOAD_RM32(modrm);
197      dst = LOAD_REG32(modrm);
198      dst = ADD32(dst, src);
199      STORE_REG32(modrm, dst);
200      CYCLES(CYCLES_ALU_REG_REG);
201   } else {
202      UINT32 ea = GetEA(modrm,0);
203      src = READ32(ea);
204      dst = LOAD_REG32(modrm);
205      dst = ADD32(dst, src);
206      STORE_REG32(modrm, dst);
207      CYCLES(CYCLES_ALU_MEM_REG);
208   }
209}
210
211void i386_device::i386_add_eax_i32()       // Opcode 0x05
212{
213   UINT32 src, dst;
214   src = FETCH32();
215   dst = REG32(EAX);
216   dst = ADD32(dst, src);
217   REG32(EAX) = dst;
218   CYCLES(CYCLES_ALU_IMM_ACC);
219}
220
221void i386_device::i386_and_rm32_r32()      // Opcode 0x21
222{
223   UINT32 src, dst;
224   UINT8 modrm = FETCH();
225   if( modrm >= 0xc0 ) {
226      src = LOAD_REG32(modrm);
227      dst = LOAD_RM32(modrm);
228      dst = AND32(dst, src);
229      STORE_RM32(modrm, dst);
230      CYCLES(CYCLES_ALU_REG_REG);
231   } else {
232      UINT32 ea = GetEA(modrm,1);
233      src = LOAD_REG32(modrm);
234      dst = READ32(ea);
235      dst = AND32(dst, src);
236      WRITE32(ea, dst);
237      CYCLES(CYCLES_ALU_REG_MEM);
238   }
239}
240
241void i386_device::i386_and_r32_rm32()      // Opcode 0x23
242{
243   UINT32 src, dst;
244   UINT8 modrm = FETCH();
245   if( modrm >= 0xc0 ) {
246      src = LOAD_RM32(modrm);
247      dst = LOAD_REG32(modrm);
248      dst = AND32(dst, src);
249      STORE_REG32(modrm, dst);
250      CYCLES(CYCLES_ALU_REG_REG);
251   } else {
252      UINT32 ea = GetEA(modrm,0);
253      src = READ32(ea);
254      dst = LOAD_REG32(modrm);
255      dst = AND32(dst, src);
256      STORE_REG32(modrm, dst);
257      CYCLES(CYCLES_ALU_MEM_REG);
258   }
259}
260
261void i386_device::i386_and_eax_i32()       // Opcode 0x25
262{
263   UINT32 src, dst;
264   src = FETCH32();
265   dst = REG32(EAX);
266   dst = AND32(dst, src);
267   REG32(EAX) = dst;
268   CYCLES(CYCLES_ALU_IMM_ACC);
269}
270
271void i386_device::i386_bsf_r32_rm32()      // Opcode 0x0f bc
272{
273   UINT32 src, dst, temp;
274   UINT8 modrm = FETCH();
275
276   if( modrm >= 0xc0 ) {
277      src = LOAD_RM32(modrm);
278   } else {
279      UINT32 ea = GetEA(modrm,0);
280      src = READ32(ea);
281   }
282
283   dst = 0;
284
285   if( src == 0 ) {
286      m_ZF = 1;
287   } else {
288      m_ZF = 0;
289      temp = 0;
290      while( (src & (1 << temp)) == 0 ) {
291         temp++;
292         dst = temp;
293         CYCLES(CYCLES_BSF);
294      }
295      STORE_REG32(modrm, dst);
296   }
297   CYCLES(CYCLES_BSF_BASE);
298}
299
300void i386_device::i386_bsr_r32_rm32()      // Opcode 0x0f bd
301{
302   UINT32 src, dst, temp;
303   UINT8 modrm = FETCH();
304
305   if( modrm >= 0xc0 ) {
306      src = LOAD_RM32(modrm);
307   } else {
308      UINT32 ea = GetEA(modrm,0);
309      src = READ32(ea);
310   }
311
312   dst = 0;
313
314   if( src == 0 ) {
315      m_ZF = 1;
316   } else {
317      m_ZF = 0;
318      dst = temp = 31;
319      while( (src & (1 << temp)) == 0 ) {
320         temp--;
321         dst = temp;
322         CYCLES(CYCLES_BSR);
323      }
324      STORE_REG32(modrm, dst);
325   }
326   CYCLES(CYCLES_BSR_BASE);
327}
328
329void i386_device::i386_bt_rm32_r32()       // Opcode 0x0f a3
330{
331   UINT8 modrm = FETCH();
332   if( modrm >= 0xc0 ) {
333      UINT32 dst = LOAD_RM32(modrm);
334      UINT32 bit = LOAD_REG32(modrm);
335
336      if( dst & (1 << bit) )
337         m_CF = 1;
338      else
339         m_CF = 0;
340
341      CYCLES(CYCLES_BT_REG_REG);
342   } else {
343      UINT8 segment;
344      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
345      UINT32 bit = LOAD_REG32(modrm);
346      ea += 4*(bit/32);
347      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),0);
348      bit %= 32;
349      UINT32 dst = READ32(ea);
350
351      if( dst & (1 << bit) )
352         m_CF = 1;
353      else
354         m_CF = 0;
355
356      CYCLES(CYCLES_BT_REG_MEM);
357   }
358}
359
360void i386_device::i386_btc_rm32_r32()      // Opcode 0x0f bb
361{
362   UINT8 modrm = FETCH();
363   if( modrm >= 0xc0 ) {
364      UINT32 dst = LOAD_RM32(modrm);
365      UINT32 bit = LOAD_REG32(modrm);
366
367      if( dst & (1 << bit) )
368         m_CF = 1;
369      else
370         m_CF = 0;
371      dst ^= (1 << bit);
372
373      STORE_RM32(modrm, dst);
374      CYCLES(CYCLES_BTC_REG_REG);
375   } else {
376      UINT8 segment;
377      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
378      UINT32 bit = LOAD_REG32(modrm);
379      ea += 4*(bit/32);
380      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
381      bit %= 32;
382      UINT32 dst = READ32(ea);
383
384      if( dst & (1 << bit) )
385         m_CF = 1;
386      else
387         m_CF = 0;
388      dst ^= (1 << bit);
389
390      WRITE32(ea, dst);
391      CYCLES(CYCLES_BTC_REG_MEM);
392   }
393}
394
395void i386_device::i386_btr_rm32_r32()      // Opcode 0x0f b3
396{
397   UINT8 modrm = FETCH();
398   if( modrm >= 0xc0 ) {
399      UINT32 dst = LOAD_RM32(modrm);
400      UINT32 bit = LOAD_REG32(modrm);
401
402      if( dst & (1 << bit) )
403         m_CF = 1;
404      else
405         m_CF = 0;
406      dst &= ~(1 << bit);
407
408      STORE_RM32(modrm, dst);
409      CYCLES(CYCLES_BTR_REG_REG);
410   } else {
411      UINT8 segment;
412      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
413      UINT32 bit = LOAD_REG32(modrm);
414      ea += 4*(bit/32);
415      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
416      bit %= 32;
417      UINT32 dst = READ32(ea);
418
419      if( dst & (1 << bit) )
420         m_CF = 1;
421      else
422         m_CF = 0;
423      dst &= ~(1 << bit);
424
425      WRITE32(ea, dst);
426      CYCLES(CYCLES_BTR_REG_MEM);
427   }
428}
429
430void i386_device::i386_bts_rm32_r32()      // Opcode 0x0f ab
431{
432   UINT8 modrm = FETCH();
433   if( modrm >= 0xc0 ) {
434      UINT32 dst = LOAD_RM32(modrm);
435      UINT32 bit = LOAD_REG32(modrm);
436
437      if( dst & (1 << bit) )
438         m_CF = 1;
439      else
440         m_CF = 0;
441      dst |= (1 << bit);
442
443      STORE_RM32(modrm, dst);
444      CYCLES(CYCLES_BTS_REG_REG);
445   } else {
446      UINT8 segment;
447      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
448      UINT32 bit = LOAD_REG32(modrm);
449      ea += 4*(bit/32);
450      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
451      bit %= 32;
452      UINT32 dst = READ32(ea);
453
454      if( dst & (1 << bit) )
455         m_CF = 1;
456      else
457         m_CF = 0;
458      dst |= (1 << bit);
459
460      WRITE32(ea, dst);
461      CYCLES(CYCLES_BTS_REG_MEM);
462   }
463}
464
465void i386_device::i386_call_abs32()        // Opcode 0x9a
466{
467   UINT32 offset = FETCH32();
468   UINT16 ptr = FETCH16();
469
470   if(PROTECTED_MODE && !V8086_MODE)
471   {
472      i386_protected_mode_call(ptr,offset,0,1);
473   }
474   else
475   {
476      PUSH32(m_sreg[CS].selector );
477      PUSH32(m_eip );
478      m_sreg[CS].selector = ptr;
479      m_performed_intersegment_jump = 1;
480      m_eip = offset;
481      i386_load_segment_descriptor(CS);
482   }
483   CYCLES(CYCLES_CALL_INTERSEG);
484   CHANGE_PC(m_eip);
485}
486
487void i386_device::i386_call_rel32()        // Opcode 0xe8
488{
489   INT32 disp = FETCH32();
490   PUSH32(m_eip );
491   m_eip += disp;
492   CHANGE_PC(m_eip);
493   CYCLES(CYCLES_CALL);       /* TODO: Timing = 7 + m */
494}
495
496void i386_device::i386_cdq()               // Opcode 0x99
497{
498   if( REG32(EAX) & 0x80000000 ) {
499      REG32(EDX) = 0xffffffff;
500   } else {
501      REG32(EDX) = 0x00000000;
502   }
503   CYCLES(CYCLES_CWD);
504}
505
506void i386_device::i386_cmp_rm32_r32()      // Opcode 0x39
507{
508   UINT32 src, dst;
509   UINT8 modrm = FETCH();
510   if( modrm >= 0xc0 ) {
511      src = LOAD_REG32(modrm);
512      dst = LOAD_RM32(modrm);
513      SUB32(dst, src);
514      CYCLES(CYCLES_CMP_REG_REG);
515   } else {
516      UINT32 ea = GetEA(modrm,0);
517      src = LOAD_REG32(modrm);
518      dst = READ32(ea);
519      SUB32(dst, src);
520      CYCLES(CYCLES_CMP_REG_MEM);
521   }
522}
523
524void i386_device::i386_cmp_r32_rm32()      // Opcode 0x3b
525{
526   UINT32 src, dst;
527   UINT8 modrm = FETCH();
528   if( modrm >= 0xc0 ) {
529      src = LOAD_RM32(modrm);
530      dst = LOAD_REG32(modrm);
531      SUB32(dst, src);
532      CYCLES(CYCLES_CMP_REG_REG);
533   } else {
534      UINT32 ea = GetEA(modrm,0);
535      src = READ32(ea);
536      dst = LOAD_REG32(modrm);
537      SUB32(dst, src);
538      CYCLES(CYCLES_CMP_MEM_REG);
539   }
540}
541
542void i386_device::i386_cmp_eax_i32()       // Opcode 0x3d
543{
544   UINT32 src, dst;
545   src = FETCH32();
546   dst = REG32(EAX);
547   SUB32(dst, src);
548   CYCLES(CYCLES_CMP_IMM_ACC);
549}
550
551void i386_device::i386_cmpsd()             // Opcode 0xa7
552{
553   UINT32 eas, ead, src, dst;
554   if( m_segment_prefix ) {
555      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
556   } else {
557      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
558   }
559   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
560   src = READ32(eas);
561   dst = READ32(ead);
562   SUB32(src,dst);
563   BUMP_SI(4);
564   BUMP_DI(4);
565   CYCLES(CYCLES_CMPS);
566}
567
568void i386_device::i386_cwde()              // Opcode 0x98
569{
570   REG32(EAX) = (INT32)((INT16)REG16(AX));
571   CYCLES(CYCLES_CBW);
572}
573
574void i386_device::i386_dec_eax()           // Opcode 0x48
575{
576   REG32(EAX) = DEC32(REG32(EAX) );
577   CYCLES(CYCLES_DEC_REG);
578}
579
580void i386_device::i386_dec_ecx()           // Opcode 0x49
581{
582   REG32(ECX) = DEC32(REG32(ECX) );
583   CYCLES(CYCLES_DEC_REG);
584}
585
586void i386_device::i386_dec_edx()           // Opcode 0x4a
587{
588   REG32(EDX) = DEC32(REG32(EDX) );
589   CYCLES(CYCLES_DEC_REG);
590}
591
592void i386_device::i386_dec_ebx()           // Opcode 0x4b
593{
594   REG32(EBX) = DEC32(REG32(EBX) );
595   CYCLES(CYCLES_DEC_REG);
596}
597
598void i386_device::i386_dec_esp()           // Opcode 0x4c
599{
600   REG32(ESP) = DEC32(REG32(ESP) );
601   CYCLES(CYCLES_DEC_REG);
602}
603
604void i386_device::i386_dec_ebp()           // Opcode 0x4d
605{
606   REG32(EBP) = DEC32(REG32(EBP) );
607   CYCLES(CYCLES_DEC_REG);
608}
609
610void i386_device::i386_dec_esi()           // Opcode 0x4e
611{
612   REG32(ESI) = DEC32(REG32(ESI) );
613   CYCLES(CYCLES_DEC_REG);
614}
615
616void i386_device::i386_dec_edi()           // Opcode 0x4f
617{
618   REG32(EDI) = DEC32(REG32(EDI) );
619   CYCLES(CYCLES_DEC_REG);
620}
621
622void i386_device::i386_imul_r32_rm32()     // Opcode 0x0f af
623{
624   UINT8 modrm = FETCH();
625   INT64 result;
626   INT64 src, dst;
627   if( modrm >= 0xc0 ) {
628      src = (INT64)(INT32)LOAD_RM32(modrm);
629      CYCLES(CYCLES_IMUL32_REG_REG);     /* TODO: Correct multiply timing */
630   } else {
631      UINT32 ea = GetEA(modrm,0);
632      src = (INT64)(INT32)READ32(ea);
633      CYCLES(CYCLES_IMUL32_REG_REG);     /* TODO: Correct multiply timing */
634   }
635
636   dst = (INT64)(INT32)LOAD_REG32(modrm);
637   result = src * dst;
638
639   STORE_REG32(modrm, (UINT32)result);
640
641   m_CF = m_OF = !(result == (INT64)(INT32)result);
642}
643
644void i386_device::i386_imul_r32_rm32_i32() // Opcode 0x69
645{
646   UINT8 modrm = FETCH();
647   INT64 result;
648   INT64 src, dst;
649   if( modrm >= 0xc0 ) {
650      dst = (INT64)(INT32)LOAD_RM32(modrm);
651      CYCLES(CYCLES_IMUL32_REG_IMM_REG);     /* TODO: Correct multiply timing */
652   } else {
653      UINT32 ea = GetEA(modrm,0);
654      dst = (INT64)(INT32)READ32(ea);
655      CYCLES(CYCLES_IMUL32_MEM_IMM_REG);     /* TODO: Correct multiply timing */
656   }
657
658   src = (INT64)(INT32)FETCH32();
659   result = src * dst;
660
661   STORE_REG32(modrm, (UINT32)result);
662
663   m_CF = m_OF = !(result == (INT64)(INT32)result);
664}
665
666void i386_device::i386_imul_r32_rm32_i8()  // Opcode 0x6b
667{
668   UINT8 modrm = FETCH();
669   INT64 result;
670   INT64 src, dst;
671   if( modrm >= 0xc0 ) {
672      dst = (INT64)(INT32)LOAD_RM32(modrm);
673      CYCLES(CYCLES_IMUL32_REG_IMM_REG);     /* TODO: Correct multiply timing */
674   } else {
675      UINT32 ea = GetEA(modrm,0);
676      dst = (INT64)(INT32)READ32(ea);
677      CYCLES(CYCLES_IMUL32_MEM_IMM_REG);     /* TODO: Correct multiply timing */
678   }
679
680   src = (INT64)(INT8)FETCH();
681   result = src * dst;
682
683   STORE_REG32(modrm, (UINT32)result);
684
685   m_CF = m_OF = !(result == (INT64)(INT32)result);
686}
687
688void i386_device::i386_in_eax_i8()         // Opcode 0xe5
689{
690   UINT16 port = FETCH();
691   UINT32 data = READPORT32(port);
692   REG32(EAX) = data;
693   CYCLES(CYCLES_IN_VAR);
694}
695
696void i386_device::i386_in_eax_dx()         // Opcode 0xed
697{
698   UINT16 port = REG16(DX);
699   UINT32 data = READPORT32(port);
700   REG32(EAX) = data;
701   CYCLES(CYCLES_IN);
702}
703
704void i386_device::i386_inc_eax()           // Opcode 0x40
705{
706   REG32(EAX) = INC32(REG32(EAX) );
707   CYCLES(CYCLES_INC_REG);
708}
709
710void i386_device::i386_inc_ecx()           // Opcode 0x41
711{
712   REG32(ECX) = INC32(REG32(ECX) );
713   CYCLES(CYCLES_INC_REG);
714}
715
716void i386_device::i386_inc_edx()           // Opcode 0x42
717{
718   REG32(EDX) = INC32(REG32(EDX) );
719   CYCLES(CYCLES_INC_REG);
720}
721
722void i386_device::i386_inc_ebx()           // Opcode 0x43
723{
724   REG32(EBX) = INC32(REG32(EBX) );
725   CYCLES(CYCLES_INC_REG);
726}
727
728void i386_device::i386_inc_esp()           // Opcode 0x44
729{
730   REG32(ESP) = INC32(REG32(ESP) );
731   CYCLES(CYCLES_INC_REG);
732}
733
734void i386_device::i386_inc_ebp()           // Opcode 0x45
735{
736   REG32(EBP) = INC32(REG32(EBP) );
737   CYCLES(CYCLES_INC_REG);
738}
739
740void i386_device::i386_inc_esi()           // Opcode 0x46
741{
742   REG32(ESI) = INC32(REG32(ESI) );
743   CYCLES(CYCLES_INC_REG);
744}
745
746void i386_device::i386_inc_edi()           // Opcode 0x47
747{
748   REG32(EDI) = INC32(REG32(EDI) );
749   CYCLES(CYCLES_INC_REG);
750}
751
752void i386_device::i386_iret32()            // Opcode 0xcf
753{
754   if( PROTECTED_MODE )
755   {
756      i386_protected_mode_iret(1);
757   }
758   else
759   {
760      /* TODO: #SS(0) exception */
761      /* TODO: #GP(0) exception */
762      m_eip = POP32();
763      m_sreg[CS].selector = POP32() & 0xffff;
764      set_flags(POP32() );
765      i386_load_segment_descriptor(CS);
766      CHANGE_PC(m_eip);
767   }
768   CYCLES(CYCLES_IRET);
769}
770
771void i386_device::i386_ja_rel32()          // Opcode 0x0f 87
772{
773   INT32 disp = FETCH32();
774   if( m_CF == 0 && m_ZF == 0 ) {
775      m_eip += disp;
776      CHANGE_PC(m_eip);
777      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
778   } else {
779      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
780   }
781}
782
783void i386_device::i386_jbe_rel32()         // Opcode 0x0f 86
784{
785   INT32 disp = FETCH32();
786   if( m_CF != 0 || m_ZF != 0 ) {
787      m_eip += disp;
788      CHANGE_PC(m_eip);
789      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
790   } else {
791      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
792   }
793}
794
795void i386_device::i386_jc_rel32()          // Opcode 0x0f 82
796{
797   INT32 disp = FETCH32();
798   if( m_CF != 0 ) {
799      m_eip += disp;
800      CHANGE_PC(m_eip);
801      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
802   } else {
803      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
804   }
805}
806
807void i386_device::i386_jg_rel32()          // Opcode 0x0f 8f
808{
809   INT32 disp = FETCH32();
810   if( m_ZF == 0 && (m_SF == m_OF) ) {
811      m_eip += disp;
812      CHANGE_PC(m_eip);
813      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
814   } else {
815      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
816   }
817}
818
819void i386_device::i386_jge_rel32()         // Opcode 0x0f 8d
820{
821   INT32 disp = FETCH32();
822   if(m_SF == m_OF) {
823      m_eip += disp;
824      CHANGE_PC(m_eip);
825      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
826   } else {
827      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
828   }
829}
830
831void i386_device::i386_jl_rel32()          // Opcode 0x0f 8c
832{
833   INT32 disp = FETCH32();
834   if( (m_SF != m_OF) ) {
835      m_eip += disp;
836      CHANGE_PC(m_eip);
837      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
838   } else {
839      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
840   }
841}
842
843void i386_device::i386_jle_rel32()         // Opcode 0x0f 8e
844{
845   INT32 disp = FETCH32();
846   if( m_ZF != 0 || (m_SF != m_OF) ) {
847      m_eip += disp;
848      CHANGE_PC(m_eip);
849      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
850   } else {
851      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
852   }
853}
854
855void i386_device::i386_jnc_rel32()         // Opcode 0x0f 83
856{
857   INT32 disp = FETCH32();
858   if( m_CF == 0 ) {
859      m_eip += disp;
860      CHANGE_PC(m_eip);
861      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
862   } else {
863      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
864   }
865}
866
867void i386_device::i386_jno_rel32()         // Opcode 0x0f 81
868{
869   INT32 disp = FETCH32();
870   if( m_OF == 0 ) {
871      m_eip += disp;
872      CHANGE_PC(m_eip);
873      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
874   } else {
875      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
876   }
877}
878
879void i386_device::i386_jnp_rel32()         // Opcode 0x0f 8b
880{
881   INT32 disp = FETCH32();
882   if( m_PF == 0 ) {
883      m_eip += disp;
884      CHANGE_PC(m_eip);
885      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
886   } else {
887      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
888   }
889}
890
891void i386_device::i386_jns_rel32()         // Opcode 0x0f 89
892{
893   INT32 disp = FETCH32();
894   if( m_SF == 0 ) {
895      m_eip += disp;
896      CHANGE_PC(m_eip);
897      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
898   } else {
899      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
900   }
901}
902
903void i386_device::i386_jnz_rel32()         // Opcode 0x0f 85
904{
905   INT32 disp = FETCH32();
906   if( m_ZF == 0 ) {
907      m_eip += disp;
908      CHANGE_PC(m_eip);
909      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
910   } else {
911      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
912   }
913}
914
915void i386_device::i386_jo_rel32()          // Opcode 0x0f 80
916{
917   INT32 disp = FETCH32();
918   if( m_OF != 0 ) {
919      m_eip += disp;
920      CHANGE_PC(m_eip);
921      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
922   } else {
923      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
924   }
925}
926
927void i386_device::i386_jp_rel32()          // Opcode 0x0f 8a
928{
929   INT32 disp = FETCH32();
930   if( m_PF != 0 ) {
931      m_eip += disp;
932      CHANGE_PC(m_eip);
933      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
934   } else {
935      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
936   }
937}
938
939void i386_device::i386_js_rel32()          // Opcode 0x0f 88
940{
941   INT32 disp = FETCH32();
942   if( m_SF != 0 ) {
943      m_eip += disp;
944      CHANGE_PC(m_eip);
945      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
946   } else {
947      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
948   }
949}
950
951void i386_device::i386_jz_rel32()          // Opcode 0x0f 84
952{
953   INT32 disp = FETCH32();
954   if( m_ZF != 0 ) {
955      m_eip += disp;
956      CHANGE_PC(m_eip);
957      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
958   } else {
959      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
960   }
961}
962
963void i386_device::i386_jcxz32()            // Opcode 0xe3
964{
965   INT8 disp = FETCH();
966   int val = (m_address_size)?(REG32(ECX) == 0):(REG16(CX) == 0);
967   if( val ) {
968      m_eip += disp;
969      CHANGE_PC(m_eip);
970      CYCLES(CYCLES_JCXZ);       /* TODO: Timing = 9 + m */
971   } else {
972      CYCLES(CYCLES_JCXZ_NOBRANCH);
973   }
974}
975
976void i386_device::i386_jmp_rel32()         // Opcode 0xe9
977{
978   UINT32 disp = FETCH32();
979   /* TODO: Segment limit */
980   m_eip += disp;
981   CHANGE_PC(m_eip);
982   CYCLES(CYCLES_JMP);        /* TODO: Timing = 7 + m */
983}
984
985void i386_device::i386_jmp_abs32()         // Opcode 0xea
986{
987   UINT32 address = FETCH32();
988   UINT16 segment = FETCH16();
989
990   if( PROTECTED_MODE && !V8086_MODE)
991   {
992      i386_protected_mode_jump(segment,address,0,1);
993   }
994   else
995   {
996      m_eip = address;
997      m_sreg[CS].selector = segment;
998      m_performed_intersegment_jump = 1;
999      i386_load_segment_descriptor(CS);
1000      CHANGE_PC(m_eip);
1001   }
1002   CYCLES(CYCLES_JMP_INTERSEG);
1003}
1004
1005void i386_device::i386_lea32()             // Opcode 0x8d
1006{
1007   UINT8 modrm = FETCH();
1008   UINT32 ea = GetNonTranslatedEA(modrm,NULL);
1009   if (!m_address_size)
1010   {
1011      ea &= 0xffff;
1012   }
1013   STORE_REG32(modrm, ea);
1014   CYCLES(CYCLES_LEA);
1015}
1016
1017void i386_device::i386_enter32()           // Opcode 0xc8
1018{
1019   UINT16 framesize = FETCH16();
1020   UINT8 level = FETCH() % 32;
1021   UINT8 x;
1022   UINT32 frameptr;
1023   PUSH32(REG32(EBP));
1024   if(!STACK_32BIT)
1025      frameptr = REG16(SP);
1026   else
1027      frameptr = REG32(ESP);
1028
1029   if(level > 0)
1030   {
1031      for(x=1;x<level-1;x++)
1032      {
1033         REG32(EBP) -= 4;
1034         PUSH32(READ32(REG32(EBP)));
1035      }
1036      PUSH32(frameptr);
1037   }
1038   REG32(EBP) = frameptr;
1039   if(!STACK_32BIT)
1040      REG16(SP) -= framesize;
1041   else
1042      REG32(ESP) -= framesize;
1043   CYCLES(CYCLES_ENTER);
1044}
1045
1046void i386_device::i386_leave32()           // Opcode 0xc9
1047{
1048   if(!STACK_32BIT)
1049      REG16(SP) = REG16(BP);
1050   else
1051      REG32(ESP) = REG32(EBP);
1052   REG32(EBP) = POP32();
1053   CYCLES(CYCLES_LEAVE);
1054}
1055
1056void i386_device::i386_lodsd()             // Opcode 0xad
1057{
1058   UINT32 eas;
1059   if( m_segment_prefix ) {
1060      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1061   } else {
1062      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1063   }
1064   REG32(EAX) = READ32(eas);
1065   BUMP_SI(4);
1066   CYCLES(CYCLES_LODS);
1067}
1068
1069void i386_device::i386_loop32()            // Opcode 0xe2
1070{
1071   INT8 disp = FETCH();
1072   INT32 reg = (m_address_size)?--REG32(ECX):--REG16(CX);
1073   if( reg != 0 ) {
1074      m_eip += disp;
1075      CHANGE_PC(m_eip);
1076   }
1077   CYCLES(CYCLES_LOOP);       /* TODO: Timing = 11 + m */
1078}
1079
1080void i386_device::i386_loopne32()          // Opcode 0xe0
1081{
1082   INT8 disp = FETCH();
1083   INT32 reg = (m_address_size)?--REG32(ECX):--REG16(CX);
1084   if( reg != 0 && m_ZF == 0 ) {
1085      m_eip += disp;
1086      CHANGE_PC(m_eip);
1087   }
1088   CYCLES(CYCLES_LOOPNZ);     /* TODO: Timing = 11 + m */
1089}
1090
1091void i386_device::i386_loopz32()           // Opcode 0xe1
1092{
1093   INT8 disp = FETCH();
1094   INT32 reg = (m_address_size)?--REG32(ECX):--REG16(CX);
1095   if( reg != 0 && m_ZF != 0 ) {
1096      m_eip += disp;
1097      CHANGE_PC(m_eip);
1098   }
1099   CYCLES(CYCLES_LOOPZ);      /* TODO: Timing = 11 + m */
1100}
1101
1102void i386_device::i386_mov_rm32_r32()      // Opcode 0x89
1103{
1104   UINT32 src;
1105   UINT8 modrm = FETCH();
1106   if( modrm >= 0xc0 ) {
1107      src = LOAD_REG32(modrm);
1108      STORE_RM32(modrm, src);
1109      CYCLES(CYCLES_MOV_REG_REG);
1110   } else {
1111      UINT32 ea = GetEA(modrm,1);
1112      src = LOAD_REG32(modrm);
1113      WRITE32(ea, src);
1114      CYCLES(CYCLES_MOV_REG_MEM);
1115   }
1116}
1117
1118void i386_device::i386_mov_r32_rm32()      // Opcode 0x8b
1119{
1120   UINT32 src;
1121   UINT8 modrm = FETCH();
1122   if( modrm >= 0xc0 ) {
1123      src = LOAD_RM32(modrm);
1124      STORE_REG32(modrm, src);
1125      CYCLES(CYCLES_MOV_REG_REG);
1126   } else {
1127      UINT32 ea = GetEA(modrm,0);
1128      src = READ32(ea);
1129      STORE_REG32(modrm, src);
1130      CYCLES(CYCLES_MOV_MEM_REG);
1131   }
1132}
1133
1134void i386_device::i386_mov_rm32_i32()      // Opcode 0xc7
1135{
1136   UINT8 modrm = FETCH();
1137   if( modrm >= 0xc0 ) {
1138      UINT32 value = FETCH32();
1139      STORE_RM32(modrm, value);
1140      CYCLES(CYCLES_MOV_IMM_REG);
1141   } else {
1142      UINT32 ea = GetEA(modrm,1);
1143      UINT32 value = FETCH32();
1144      WRITE32(ea, value);
1145      CYCLES(CYCLES_MOV_IMM_MEM);
1146   }
1147}
1148
1149void i386_device::i386_mov_eax_m32()       // Opcode 0xa1
1150{
1151   UINT32 offset, ea;
1152   if( m_address_size ) {
1153      offset = FETCH32();
1154   } else {
1155      offset = FETCH16();
1156   }
1157   if( m_segment_prefix ) {
1158      ea = i386_translate(m_segment_override, offset, 0 );
1159   } else {
1160      ea = i386_translate(DS, offset, 0 );
1161   }
1162   REG32(EAX) = READ32(ea);
1163   CYCLES(CYCLES_MOV_MEM_ACC);
1164}
1165
1166void i386_device::i386_mov_m32_eax()       // Opcode 0xa3
1167{
1168   UINT32 offset, ea;
1169   if( m_address_size ) {
1170      offset = FETCH32();
1171   } else {
1172      offset = FETCH16();
1173   }
1174   if( m_segment_prefix ) {
1175      ea = i386_translate(m_segment_override, offset, 1 );
1176   } else {
1177      ea = i386_translate(DS, offset, 1 );
1178   }
1179   WRITE32(ea, REG32(EAX) );
1180   CYCLES(CYCLES_MOV_ACC_MEM);
1181}
1182
1183void i386_device::i386_mov_eax_i32()       // Opcode 0xb8
1184{
1185   REG32(EAX) = FETCH32();
1186   CYCLES(CYCLES_MOV_IMM_REG);
1187}
1188
1189void i386_device::i386_mov_ecx_i32()       // Opcode 0xb9
1190{
1191   REG32(ECX) = FETCH32();
1192   CYCLES(CYCLES_MOV_IMM_REG);
1193}
1194
1195void i386_device::i386_mov_edx_i32()       // Opcode 0xba
1196{
1197   REG32(EDX) = FETCH32();
1198   CYCLES(CYCLES_MOV_IMM_REG);
1199}
1200
1201void i386_device::i386_mov_ebx_i32()       // Opcode 0xbb
1202{
1203   REG32(EBX) = FETCH32();
1204   CYCLES(CYCLES_MOV_IMM_REG);
1205}
1206
1207void i386_device::i386_mov_esp_i32()       // Opcode 0xbc
1208{
1209   REG32(ESP) = FETCH32();
1210   CYCLES(CYCLES_MOV_IMM_REG);
1211}
1212
1213void i386_device::i386_mov_ebp_i32()       // Opcode 0xbd
1214{
1215   REG32(EBP) = FETCH32();
1216   CYCLES(CYCLES_MOV_IMM_REG);
1217}
1218
1219void i386_device::i386_mov_esi_i32()       // Opcode 0xbe
1220{
1221   REG32(ESI) = FETCH32();
1222   CYCLES(CYCLES_MOV_IMM_REG);
1223}
1224
1225void i386_device::i386_mov_edi_i32()       // Opcode 0xbf
1226{
1227   REG32(EDI) = FETCH32();
1228   CYCLES(CYCLES_MOV_IMM_REG);
1229}
1230
1231void i386_device::i386_movsd()             // Opcode 0xa5
1232{
1233   UINT32 eas, ead, v;
1234   if( m_segment_prefix ) {
1235      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1236   } else {
1237      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1238   }
1239   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
1240   v = READ32(eas);
1241   WRITE32(ead, v);
1242   BUMP_SI(4);
1243   BUMP_DI(4);
1244   CYCLES(CYCLES_MOVS);
1245}
1246
1247void i386_device::i386_movsx_r32_rm8()     // Opcode 0x0f be
1248{
1249   UINT8 modrm = FETCH();
1250   if( modrm >= 0xc0 ) {
1251      INT32 src = (INT8)LOAD_RM8(modrm);
1252      STORE_REG32(modrm, src);
1253      CYCLES(CYCLES_MOVSX_REG_REG);
1254   } else {
1255      UINT32 ea = GetEA(modrm,0);
1256      INT32 src = (INT8)READ8(ea);
1257      STORE_REG32(modrm, src);
1258      CYCLES(CYCLES_MOVSX_MEM_REG);
1259   }
1260}
1261
1262void i386_device::i386_movsx_r32_rm16()    // Opcode 0x0f bf
1263{
1264   UINT8 modrm = FETCH();
1265   if( modrm >= 0xc0 ) {
1266      INT32 src = (INT16)LOAD_RM16(modrm);
1267      STORE_REG32(modrm, src);
1268      CYCLES(CYCLES_MOVSX_REG_REG);
1269   } else {
1270      UINT32 ea = GetEA(modrm,0);
1271      INT32 src = (INT16)READ16(ea);
1272      STORE_REG32(modrm, src);
1273      CYCLES(CYCLES_MOVSX_MEM_REG);
1274   }
1275}
1276
1277void i386_device::i386_movzx_r32_rm8()     // Opcode 0x0f b6
1278{
1279   UINT8 modrm = FETCH();
1280   if( modrm >= 0xc0 ) {
1281      UINT32 src = (UINT8)LOAD_RM8(modrm);
1282      STORE_REG32(modrm, src);
1283      CYCLES(CYCLES_MOVZX_REG_REG);
1284   } else {
1285      UINT32 ea = GetEA(modrm,0);
1286      UINT32 src = (UINT8)READ8(ea);
1287      STORE_REG32(modrm, src);
1288      CYCLES(CYCLES_MOVZX_MEM_REG);
1289   }
1290}
1291
1292void i386_device::i386_movzx_r32_rm16()    // Opcode 0x0f b7
1293{
1294   UINT8 modrm = FETCH();
1295   if( modrm >= 0xc0 ) {
1296      UINT32 src = (UINT16)LOAD_RM16(modrm);
1297      STORE_REG32(modrm, src);
1298      CYCLES(CYCLES_MOVZX_REG_REG);
1299   } else {
1300      UINT32 ea = GetEA(modrm,0);
1301      UINT32 src = (UINT16)READ16(ea);
1302      STORE_REG32(modrm, src);
1303      CYCLES(CYCLES_MOVZX_MEM_REG);
1304   }
1305}
1306
1307void i386_device::i386_or_rm32_r32()       // Opcode 0x09
1308{
1309   UINT32 src, dst;
1310   UINT8 modrm = FETCH();
1311   if( modrm >= 0xc0 ) {
1312      src = LOAD_REG32(modrm);
1313      dst = LOAD_RM32(modrm);
1314      dst = OR32(dst, src);
1315      STORE_RM32(modrm, dst);
1316      CYCLES(CYCLES_ALU_REG_REG);
1317   } else {
1318      UINT32 ea = GetEA(modrm,1);
1319      src = LOAD_REG32(modrm);
1320      dst = READ32(ea);
1321      dst = OR32(dst, src);
1322      WRITE32(ea, dst);
1323      CYCLES(CYCLES_ALU_REG_MEM);
1324   }
1325}
1326
1327void i386_device::i386_or_r32_rm32()       // Opcode 0x0b
1328{
1329   UINT32 src, dst;
1330   UINT8 modrm = FETCH();
1331   if( modrm >= 0xc0 ) {
1332      src = LOAD_RM32(modrm);
1333      dst = LOAD_REG32(modrm);
1334      dst = OR32(dst, src);
1335      STORE_REG32(modrm, dst);
1336      CYCLES(CYCLES_ALU_REG_REG);
1337   } else {
1338      UINT32 ea = GetEA(modrm,0);
1339      src = READ32(ea);
1340      dst = LOAD_REG32(modrm);
1341      dst = OR32(dst, src);
1342      STORE_REG32(modrm, dst);
1343      CYCLES(CYCLES_ALU_MEM_REG);
1344   }
1345}
1346
1347void i386_device::i386_or_eax_i32()        // Opcode 0x0d
1348{
1349   UINT32 src, dst;
1350   src = FETCH32();
1351   dst = REG32(EAX);
1352   dst = OR32(dst, src);
1353   REG32(EAX) = dst;
1354   CYCLES(CYCLES_ALU_IMM_ACC);
1355}
1356
1357void i386_device::i386_out_eax_i8()        // Opcode 0xe7
1358{
1359   UINT16 port = FETCH();
1360   UINT32 data = REG32(EAX);
1361   WRITEPORT32(port, data);
1362   CYCLES(CYCLES_OUT_VAR);
1363}
1364
1365void i386_device::i386_out_eax_dx()        // Opcode 0xef
1366{
1367   UINT16 port = REG16(DX);
1368   UINT32 data = REG32(EAX);
1369   WRITEPORT32(port, data);
1370   CYCLES(CYCLES_OUT);
1371}
1372
1373void i386_device::i386_pop_eax()           // Opcode 0x58
1374{
1375   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1376   if(i386_limit_check(SS,offset+3) == 0)
1377      REG32(EAX) = POP32();
1378   else
1379      FAULT(FAULT_SS,0)
1380   CYCLES(CYCLES_POP_REG_SHORT);
1381}
1382
1383void i386_device::i386_pop_ecx()           // Opcode 0x59
1384{
1385   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1386   if(i386_limit_check(SS,offset+3) == 0)
1387      REG32(ECX) = POP32();
1388   else
1389      FAULT(FAULT_SS,0)
1390   CYCLES(CYCLES_POP_REG_SHORT);
1391}
1392
1393void i386_device::i386_pop_edx()           // Opcode 0x5a
1394{
1395   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1396   if(i386_limit_check(SS,offset+3) == 0)
1397      REG32(EDX) = POP32();
1398   else
1399      FAULT(FAULT_SS,0)
1400   CYCLES(CYCLES_POP_REG_SHORT);
1401}
1402
1403void i386_device::i386_pop_ebx()           // Opcode 0x5b
1404{
1405   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1406   if(i386_limit_check(SS,offset+3) == 0)
1407      REG32(EBX) = POP32();
1408   else
1409      FAULT(FAULT_SS,0)
1410   CYCLES(CYCLES_POP_REG_SHORT);
1411}
1412
1413void i386_device::i386_pop_esp()           // Opcode 0x5c
1414{
1415   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1416   if(i386_limit_check(SS,offset+3) == 0)
1417      REG32(ESP) = POP32();
1418   else
1419      FAULT(FAULT_SS,0)
1420   CYCLES(CYCLES_POP_REG_SHORT);
1421}
1422
1423void i386_device::i386_pop_ebp()           // Opcode 0x5d
1424{
1425   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1426   if(i386_limit_check(SS,offset+3) == 0)
1427      REG32(EBP) = POP32();
1428   else
1429      FAULT(FAULT_SS,0)
1430   CYCLES(CYCLES_POP_REG_SHORT);
1431}
1432
1433void i386_device::i386_pop_esi()           // Opcode 0x5e
1434{
1435   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1436   if(i386_limit_check(SS,offset+3) == 0)
1437      REG32(ESI) = POP32();
1438   else
1439      FAULT(FAULT_SS,0)
1440   CYCLES(CYCLES_POP_REG_SHORT);
1441}
1442
1443void i386_device::i386_pop_edi()           // Opcode 0x5f
1444{
1445   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1446   if(i386_limit_check(SS,offset+3) == 0)
1447      REG32(EDI) = POP32();
1448   else
1449      FAULT(FAULT_SS,0)
1450   CYCLES(CYCLES_POP_REG_SHORT);
1451}
1452
1453bool i386_device::i386_pop_seg32(int segment)
1454{
1455   UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1456   UINT32 value;
1457   bool fault;
1458   if(i386_limit_check(SS,offset+3) == 0)
1459   {
1460      ea = i386_translate(SS, offset, 0);
1461      value = READ32(ea);
1462      i386_sreg_load(value, segment, &fault);
1463      if(fault) return false;
1464      if(STACK_32BIT)
1465         REG32(ESP) = offset + 4;
1466      else
1467         REG16(SP) = offset + 4;
1468   }
1469   else
1470   {
1471      m_ext = 1;
1472      i386_trap_with_error(FAULT_SS,0,0,0);
1473      return false;
1474   }
1475   CYCLES(CYCLES_POP_SREG);
1476   return true;
1477}
1478
1479void i386_device::i386_pop_ds32()          // Opcode 0x1f
1480{
1481   i386_pop_seg32(DS);
1482}
1483
1484void i386_device::i386_pop_es32()          // Opcode 0x07
1485{
1486   i386_pop_seg32(ES);
1487}
1488
1489void i386_device::i386_pop_fs32()          // Opcode 0x0f a1
1490{
1491   i386_pop_seg32(FS);
1492}
1493
1494void i386_device::i386_pop_gs32()          // Opcode 0x0f a9
1495{
1496   i386_pop_seg32(GS);
1497}
1498
1499void i386_device::i386_pop_ss32()          // Opcode 0x17
1500{
1501   if(!i386_pop_seg32(SS)) return;
1502   if(m_IF != 0) // if external interrupts are enabled
1503   {
1504      m_IF = 0;  // reset IF for the next instruction
1505      m_delayed_interrupt_enable = 1;
1506   }
1507}
1508
1509void i386_device::i386_pop_rm32()          // Opcode 0x8f
1510{
1511   UINT8 modrm = FETCH();
1512   UINT32 value;
1513   UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1514   if(i386_limit_check(SS,offset+3) == 0)
1515   {
1516      // be careful here, if the write references the esp register
1517      // it expects the post-pop value but esp must be wound back
1518      // if the write faults
1519      UINT32 temp_sp = REG32(ESP);
1520      value = POP32();
1521
1522      if( modrm >= 0xc0 ) {
1523         STORE_RM32(modrm, value);
1524      } else {
1525         ea = GetEA(modrm,1);
1526         try
1527         {
1528            WRITE32(ea, value);
1529         }
1530         catch(UINT64 e)
1531         {
1532            REG32(ESP) = temp_sp;
1533            throw e;
1534         }
1535      }
1536   }
1537   else
1538      FAULT(FAULT_SS,0)
1539   CYCLES(CYCLES_POP_RM);
1540}
1541
1542void i386_device::i386_popad()             // Opcode 0x61
1543{
1544   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1545   if(i386_limit_check(SS,offset+31) == 0)
1546   {
1547      REG32(EDI) = POP32();
1548      REG32(ESI) = POP32();
1549      REG32(EBP) = POP32();
1550      REG32(ESP) += 4;
1551      REG32(EBX) = POP32();
1552      REG32(EDX) = POP32();
1553      REG32(ECX) = POP32();
1554      REG32(EAX) = POP32();
1555   }
1556   else
1557      FAULT(FAULT_SS,0)
1558   CYCLES(CYCLES_POPA);
1559}
1560
1561void i386_device::i386_popfd()             // Opcode 0x9d
1562{
1563   UINT32 value;
1564   UINT32 current = get_flags();
1565   UINT8 IOPL = (current >> 12) & 0x03;
1566   UINT32 mask = 0x00257fd5;  // VM, VIP and VIF cannot be set by POPF/POPFD
1567   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1568
1569   // IOPL can only change if CPL is 0
1570   if(m_CPL != 0)
1571      mask &= ~0x00003000;
1572
1573   // IF can only change if CPL is at least as privileged as IOPL
1574   if(m_CPL > IOPL)
1575      mask &= ~0x00000200;
1576
1577   if(V8086_MODE)
1578   {
1579      if(IOPL < 3)
1580      {
1581         logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",m_pc);
1582         FAULT(FAULT_GP,0)  // #GP(0)
1583      }
1584      mask &= ~0x00003000;  // IOPL cannot be changed while in V8086 mode
1585   }
1586
1587   if(i386_limit_check(SS,offset+3) == 0)
1588   {
1589      value = POP32();
1590      value &= ~0x00010000;  // RF will always return zero
1591      set_flags((current & ~mask) | (value & mask));  // mask out reserved bits
1592   }
1593   else
1594      FAULT(FAULT_SS,0)
1595   CYCLES(CYCLES_POPF);
1596}
1597
1598void i386_device::i386_push_eax()          // Opcode 0x50
1599{
1600   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1601   if(i386_limit_check(SS,offset-4) == 0)
1602      PUSH32(REG32(EAX) );
1603   else
1604      FAULT(FAULT_SS,0)
1605   CYCLES(CYCLES_PUSH_REG_SHORT);
1606}
1607
1608void i386_device::i386_push_ecx()          // Opcode 0x51
1609{
1610   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1611   if(i386_limit_check(SS,offset-4) == 0)
1612      PUSH32(REG32(ECX) );
1613   else
1614      FAULT(FAULT_SS,0)
1615   CYCLES(CYCLES_PUSH_REG_SHORT);
1616}
1617
1618void i386_device::i386_push_edx()          // Opcode 0x52
1619{
1620   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1621   if(i386_limit_check(SS,offset-4) == 0)
1622      PUSH32(REG32(EDX) );
1623   else
1624      FAULT(FAULT_SS,0)
1625   CYCLES(CYCLES_PUSH_REG_SHORT);
1626}
1627
1628void i386_device::i386_push_ebx()          // Opcode 0x53
1629{
1630   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1631   if(i386_limit_check(SS,offset-4) == 0)
1632      PUSH32(REG32(EBX) );
1633   else
1634      FAULT(FAULT_SS,0)
1635   CYCLES(CYCLES_PUSH_REG_SHORT);
1636}
1637
1638void i386_device::i386_push_esp()          // Opcode 0x54
1639{
1640   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1641   if(i386_limit_check(SS,offset-4) == 0)
1642      PUSH32(REG32(ESP) );
1643   else
1644      FAULT(FAULT_SS,0)
1645   CYCLES(CYCLES_PUSH_REG_SHORT);
1646}
1647
1648void i386_device::i386_push_ebp()          // Opcode 0x55
1649{
1650   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1651   if(i386_limit_check(SS,offset-4) == 0)
1652      PUSH32(REG32(EBP) );
1653   else
1654      FAULT(FAULT_SS,0)
1655   CYCLES(CYCLES_PUSH_REG_SHORT);
1656}
1657
1658void i386_device::i386_push_esi()          // Opcode 0x56
1659{
1660   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1661   if(i386_limit_check(SS,offset-4) == 0)
1662      PUSH32(REG32(ESI) );
1663   else
1664      FAULT(FAULT_SS,0)
1665   CYCLES(CYCLES_PUSH_REG_SHORT);
1666}
1667
1668void i386_device::i386_push_edi()          // Opcode 0x57
1669{
1670   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1671   if(i386_limit_check(SS,offset-4) == 0)
1672      PUSH32(REG32(EDI) );
1673   else
1674      FAULT(FAULT_SS,0)
1675   CYCLES(CYCLES_PUSH_REG_SHORT);
1676}
1677
1678void i386_device::i386_push_cs32()         // Opcode 0x0e
1679{
1680   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1681   if(i386_limit_check(SS,offset-4) == 0)
1682      PUSH32(m_sreg[CS].selector );
1683   else
1684      FAULT(FAULT_SS,0)
1685   CYCLES(CYCLES_PUSH_SREG);
1686}
1687
1688void i386_device::i386_push_ds32()         // Opcode 0x1e
1689{
1690   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1691   if(i386_limit_check(SS,offset-4) == 0)
1692      PUSH32(m_sreg[DS].selector );
1693   else
1694      FAULT(FAULT_SS,0)
1695   CYCLES(CYCLES_PUSH_SREG);
1696}
1697
1698void i386_device::i386_push_es32()         // Opcode 0x06
1699{
1700   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1701   if(i386_limit_check(SS,offset-4) == 0)
1702      PUSH32(m_sreg[ES].selector );
1703   else
1704      FAULT(FAULT_SS,0)
1705   CYCLES(CYCLES_PUSH_SREG);
1706}
1707
1708void i386_device::i386_push_fs32()         // Opcode 0x0f a0
1709{
1710   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1711   if(i386_limit_check(SS,offset-4) == 0)
1712      PUSH32(m_sreg[FS].selector );
1713   else
1714      FAULT(FAULT_SS,0)
1715   CYCLES(CYCLES_PUSH_SREG);
1716}
1717
1718void i386_device::i386_push_gs32()         // Opcode 0x0f a8
1719{
1720   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1721   if(i386_limit_check(SS,offset-4) == 0)
1722      PUSH32(m_sreg[GS].selector );
1723   else
1724      FAULT(FAULT_SS,0)
1725   CYCLES(CYCLES_PUSH_SREG);
1726}
1727
1728void i386_device::i386_push_ss32()         // Opcode 0x16
1729{
1730   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1731   if(i386_limit_check(SS,offset-4) == 0)
1732      PUSH32(m_sreg[SS].selector );
1733   else
1734      FAULT(FAULT_SS,0)
1735   CYCLES(CYCLES_PUSH_SREG);
1736}
1737
1738void i386_device::i386_push_i32()          // Opcode 0x68
1739{
1740   UINT32 value = FETCH32();
1741   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1742   if(i386_limit_check(SS,offset-4) == 0)
1743      PUSH32(value);
1744   else
1745      FAULT(FAULT_SS,0)
1746   CYCLES(CYCLES_PUSH_IMM);
1747}
1748
1749void i386_device::i386_pushad()            // Opcode 0x60
1750{
1751   UINT32 temp = REG32(ESP);
1752   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1753   if(i386_limit_check(SS,offset-32) == 0)
1754   {
1755      PUSH32(REG32(EAX) );
1756      PUSH32(REG32(ECX) );
1757      PUSH32(REG32(EDX) );
1758      PUSH32(REG32(EBX) );
1759      PUSH32(temp );
1760      PUSH32(REG32(EBP) );
1761      PUSH32(REG32(ESI) );
1762      PUSH32(REG32(EDI) );
1763   }
1764   else
1765      FAULT(FAULT_SS,0)
1766   CYCLES(CYCLES_PUSHA);
1767}
1768
1769void i386_device::i386_pushfd()            // Opcode 0x9c
1770{
1771   if(!m_IOP1 && !m_IOP2 && V8086_MODE)
1772      FAULT(FAULT_GP,0)
1773   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1774   if(i386_limit_check(SS,offset-4) == 0)
1775      PUSH32(get_flags() & 0x00fcffff );
1776   else
1777      FAULT(FAULT_SS,0)
1778   CYCLES(CYCLES_PUSHF);
1779}
1780
1781void i386_device::i386_ret_near32_i16()    // Opcode 0xc2
1782{
1783   INT16 disp = FETCH16();
1784   m_eip = POP32();
1785   REG32(ESP) += disp;
1786   CHANGE_PC(m_eip);
1787   CYCLES(CYCLES_RET_IMM);        /* TODO: Timing = 10 + m */
1788}
1789
1790void i386_device::i386_ret_near32()        // Opcode 0xc3
1791{
1792   m_eip = POP32();
1793   CHANGE_PC(m_eip);
1794   CYCLES(CYCLES_RET);        /* TODO: Timing = 10 + m */
1795}
1796
1797void i386_device::i386_sbb_rm32_r32()      // Opcode 0x19
1798{
1799   UINT32 src, dst;
1800   UINT8 modrm = FETCH();
1801   if( modrm >= 0xc0 ) {
1802      src = LOAD_REG32(modrm);
1803      dst = LOAD_RM32(modrm);
1804      dst = SBB32(dst, src, m_CF);
1805      STORE_RM32(modrm, dst);
1806      CYCLES(CYCLES_ALU_REG_REG);
1807   } else {
1808      UINT32 ea = GetEA(modrm,1);
1809      src = LOAD_REG32(modrm);
1810      dst = READ32(ea);
1811      dst = SBB32(dst, src, m_CF);
1812      WRITE32(ea, dst);
1813      CYCLES(CYCLES_ALU_REG_MEM);
1814   }
1815}
1816
1817void i386_device::i386_sbb_r32_rm32()      // Opcode 0x1b
1818{
1819   UINT32 src, dst;
1820   UINT8 modrm = FETCH();
1821   if( modrm >= 0xc0 ) {
1822      src = LOAD_RM32(modrm);
1823      dst = LOAD_REG32(modrm);
1824      dst = SBB32(dst, src, m_CF);
1825      STORE_REG32(modrm, dst);
1826      CYCLES(CYCLES_ALU_REG_REG);
1827   } else {
1828      UINT32 ea = GetEA(modrm,0);
1829      src = READ32(ea);
1830      dst = LOAD_REG32(modrm);
1831      dst = SBB32(dst, src, m_CF);
1832      STORE_REG32(modrm, dst);
1833      CYCLES(CYCLES_ALU_MEM_REG);
1834   }
1835}
1836
1837void i386_device::i386_sbb_eax_i32()       // Opcode 0x1d
1838{
1839   UINT32 src, dst;
1840   src = FETCH32();
1841   dst = REG32(EAX);
1842   dst = SBB32(dst, src, m_CF);
1843   REG32(EAX) = dst;
1844   CYCLES(CYCLES_ALU_IMM_ACC);
1845}
1846
1847void i386_device::i386_scasd()             // Opcode 0xaf
1848{
1849   UINT32 eas, src, dst;
1850   eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
1851   src = READ32(eas);
1852   dst = REG32(EAX);
1853   SUB32(dst, src);
1854   BUMP_DI(4);
1855   CYCLES(CYCLES_SCAS);
1856}
1857
1858void i386_device::i386_shld32_i8()         // Opcode 0x0f a4
1859{
1860   UINT8 modrm = FETCH();
1861   if( modrm >= 0xc0 ) {
1862      UINT32 dst = LOAD_RM32(modrm);
1863      UINT32 upper = LOAD_REG32(modrm);
1864      UINT8 shift = FETCH();
1865      shift &= 31;
1866      if( shift == 0 ) {
1867      } else {
1868         m_CF = (dst & (1 << (32-shift))) ? 1 : 0;
1869         dst = (dst << shift) | (upper >> (32-shift));
1870         m_OF = m_CF ^ (dst >> 31);
1871         SetSZPF32(dst);
1872      }
1873      STORE_RM32(modrm, dst);
1874      CYCLES(CYCLES_SHLD_REG);
1875   } else {
1876      UINT32 ea = GetEA(modrm,1);
1877      UINT32 dst = READ32(ea);
1878      UINT32 upper = LOAD_REG32(modrm);
1879      UINT8 shift = FETCH();
1880      shift &= 31;
1881      if( shift == 0 ) {
1882      } else {
1883         m_CF = (dst & (1 << (32-shift))) ? 1 : 0;
1884         dst = (dst << shift) | (upper >> (32-shift));
1885         m_OF = m_CF ^ (dst >> 31);
1886         SetSZPF32(dst);
1887      }
1888      WRITE32(ea, dst);
1889      CYCLES(CYCLES_SHLD_MEM);
1890   }
1891}
1892
1893void i386_device::i386_shld32_cl()         // Opcode 0x0f a5
1894{
1895   UINT8 modrm = FETCH();
1896   if( modrm >= 0xc0 ) {
1897      UINT32 dst = LOAD_RM32(modrm);
1898      UINT32 upper = LOAD_REG32(modrm);
1899      UINT8 shift = REG8(CL);
1900      shift &= 31;
1901      if( shift == 0 ) {
1902      } else {
1903         m_CF = (dst & (1 << (32-shift))) ? 1 : 0;
1904         dst = (dst << shift) | (upper >> (32-shift));
1905         m_OF = m_CF ^ (dst >> 31);
1906         SetSZPF32(dst);
1907      }
1908      STORE_RM32(modrm, dst);
1909      CYCLES(CYCLES_SHLD_REG);
1910   } else {
1911      UINT32 ea = GetEA(modrm,1);
1912      UINT32 dst = READ32(ea);
1913      UINT32 upper = LOAD_REG32(modrm);
1914      UINT8 shift = REG8(CL);
1915      shift &= 31;
1916      if( shift == 0 ) {
1917      } else {
1918         m_CF = (dst & (1 << (32-shift))) ? 1 : 0;
1919         dst = (dst << shift) | (upper >> (32-shift));
1920         m_OF = m_CF ^ (dst >> 31);
1921         SetSZPF32(dst);
1922      }
1923      WRITE32(ea, dst);
1924      CYCLES(CYCLES_SHLD_MEM);
1925   }
1926}
1927
1928void i386_device::i386_shrd32_i8()         // Opcode 0x0f ac
1929{
1930   UINT8 modrm = FETCH();
1931   if( modrm >= 0xc0 ) {
1932      UINT32 dst = LOAD_RM32(modrm);
1933      UINT32 upper = LOAD_REG32(modrm);
1934      UINT8 shift = FETCH();
1935      shift &= 31;
1936      if( shift == 0 ) {
1937      } else {
1938         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
1939         dst = (dst >> shift) | (upper << (32-shift));
1940         m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
1941         SetSZPF32(dst);
1942      }
1943      STORE_RM32(modrm, dst);
1944      CYCLES(CYCLES_SHRD_REG);
1945   } else {
1946      UINT32 ea = GetEA(modrm,1);
1947      UINT32 dst = READ32(ea);
1948      UINT32 upper = LOAD_REG32(modrm);
1949      UINT8 shift = FETCH();
1950      shift &= 31;
1951      if( shift == 0 ) {
1952      } else {
1953         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
1954         dst = (dst >> shift) | (upper << (32-shift));
1955         m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
1956         SetSZPF32(dst);
1957      }
1958      WRITE32(ea, dst);
1959      CYCLES(CYCLES_SHRD_MEM);
1960   }
1961}
1962
1963void i386_device::i386_shrd32_cl()         // Opcode 0x0f ad
1964{
1965   UINT8 modrm = FETCH();
1966   if( modrm >= 0xc0 ) {
1967      UINT32 dst = LOAD_RM32(modrm);
1968      UINT32 upper = LOAD_REG32(modrm);
1969      UINT8 shift = REG8(CL);
1970      shift &= 31;
1971      if( shift == 0 ) {
1972      } else {
1973         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
1974         dst = (dst >> shift) | (upper << (32-shift));
1975         m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
1976         SetSZPF32(dst);
1977      }
1978      STORE_RM32(modrm, dst);
1979      CYCLES(CYCLES_SHRD_REG);
1980   } else {
1981      UINT32 ea = GetEA(modrm,1);
1982      UINT32 dst = READ32(ea);
1983      UINT32 upper = LOAD_REG32(modrm);
1984      UINT8 shift = REG8(CL);
1985      shift &= 31;
1986      if( shift == 0 ) {
1987      } else {
1988         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
1989         dst = (dst >> shift) | (upper << (32-shift));
1990         m_OF = ((dst >> 31) ^ (dst >> 30)) & 1;
1991         SetSZPF32(dst);
1992      }
1993      WRITE32(ea, dst);
1994      CYCLES(CYCLES_SHRD_MEM);
1995   }
1996}
1997
1998void i386_device::i386_stosd()             // Opcode 0xab
1999{
2000   UINT32 eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
2001   WRITE32(eas, REG32(EAX));
2002   BUMP_DI(4);
2003   CYCLES(CYCLES_STOS);
2004}
2005
2006void i386_device::i386_sub_rm32_r32()      // Opcode 0x29
2007{
2008   UINT32 src, dst;
2009   UINT8 modrm = FETCH();
2010   if( modrm >= 0xc0 ) {
2011      src = LOAD_REG32(modrm);
2012      dst = LOAD_RM32(modrm);
2013      dst = SUB32(dst, src);
2014      STORE_RM32(modrm, dst);
2015      CYCLES(CYCLES_ALU_REG_REG);
2016   } else {
2017      UINT32 ea = GetEA(modrm,1);
2018      src = LOAD_REG32(modrm);
2019      dst = READ32(ea);
2020      dst = SUB32(dst, src);
2021      WRITE32(ea, dst);
2022      CYCLES(CYCLES_ALU_REG_MEM);
2023   }
2024}
2025
2026void i386_device::i386_sub_r32_rm32()      // Opcode 0x2b
2027{
2028   UINT32 src, dst;
2029   UINT8 modrm = FETCH();
2030   if( modrm >= 0xc0 ) {
2031      src = LOAD_RM32(modrm);
2032      dst = LOAD_REG32(modrm);
2033      dst = SUB32(dst, src);
2034      STORE_REG32(modrm, dst);
2035      CYCLES(CYCLES_ALU_REG_REG);
2036   } else {
2037      UINT32 ea = GetEA(modrm,1);
2038      src = READ32(ea);
2039      dst = LOAD_REG32(modrm);
2040      dst = SUB32(dst, src);
2041      STORE_REG32(modrm, dst);
2042      CYCLES(CYCLES_ALU_MEM_REG);
2043   }
2044}
2045
2046void i386_device::i386_sub_eax_i32()       // Opcode 0x2d
2047{
2048   UINT32 src, dst;
2049   src = FETCH32();
2050   dst = REG32(EAX);
2051   dst = SUB32(dst, src);
2052   REG32(EAX) = dst;
2053   CYCLES(CYCLES_ALU_IMM_ACC);
2054}
2055
2056void i386_device::i386_test_eax_i32()      // Opcode 0xa9
2057{
2058   UINT32 src = FETCH32();
2059   UINT32 dst = REG32(EAX);
2060   dst = src & dst;
2061   SetSZPF32(dst);
2062   m_CF = 0;
2063   m_OF = 0;
2064   CYCLES(CYCLES_TEST_IMM_ACC);
2065}
2066
2067void i386_device::i386_test_rm32_r32()     // Opcode 0x85
2068{
2069   UINT32 src, dst;
2070   UINT8 modrm = FETCH();
2071   if( modrm >= 0xc0 ) {
2072      src = LOAD_REG32(modrm);
2073      dst = LOAD_RM32(modrm);
2074      dst = src & dst;
2075      SetSZPF32(dst);
2076      m_CF = 0;
2077      m_OF = 0;
2078      CYCLES(CYCLES_TEST_REG_REG);
2079   } else {
2080      UINT32 ea = GetEA(modrm,0);
2081      src = LOAD_REG32(modrm);
2082      dst = READ32(ea);
2083      dst = src & dst;
2084      SetSZPF32(dst);
2085      m_CF = 0;
2086      m_OF = 0;
2087      CYCLES(CYCLES_TEST_REG_MEM);
2088   }
2089}
2090
2091void i386_device::i386_xchg_eax_ecx()      // Opcode 0x91
2092{
2093   UINT32 temp;
2094   temp = REG32(EAX);
2095   REG32(EAX) = REG32(ECX);
2096   REG32(ECX) = temp;
2097   CYCLES(CYCLES_XCHG_REG_REG);
2098}
2099
2100void i386_device::i386_xchg_eax_edx()      // Opcode 0x92
2101{
2102   UINT32 temp;
2103   temp = REG32(EAX);
2104   REG32(EAX) = REG32(EDX);
2105   REG32(EDX) = temp;
2106   CYCLES(CYCLES_XCHG_REG_REG);
2107}
2108
2109void i386_device::i386_xchg_eax_ebx()      // Opcode 0x93
2110{
2111   UINT32 temp;
2112   temp = REG32(EAX);
2113   REG32(EAX) = REG32(EBX);
2114   REG32(EBX) = temp;
2115   CYCLES(CYCLES_XCHG_REG_REG);
2116}
2117
2118void i386_device::i386_xchg_eax_esp()      // Opcode 0x94
2119{
2120   UINT32 temp;
2121   temp = REG32(EAX);
2122   REG32(EAX) = REG32(ESP);
2123   REG32(ESP) = temp;
2124   CYCLES(CYCLES_XCHG_REG_REG);
2125}
2126
2127void i386_device::i386_xchg_eax_ebp()      // Opcode 0x95
2128{
2129   UINT32 temp;
2130   temp = REG32(EAX);
2131   REG32(EAX) = REG32(EBP);
2132   REG32(EBP) = temp;
2133   CYCLES(CYCLES_XCHG_REG_REG);
2134}
2135
2136void i386_device::i386_xchg_eax_esi()      // Opcode 0x96
2137{
2138   UINT32 temp;
2139   temp = REG32(EAX);
2140   REG32(EAX) = REG32(ESI);
2141   REG32(ESI) = temp;
2142   CYCLES(CYCLES_XCHG_REG_REG);
2143}
2144
2145void i386_device::i386_xchg_eax_edi()      // Opcode 0x97
2146{
2147   UINT32 temp;
2148   temp = REG32(EAX);
2149   REG32(EAX) = REG32(EDI);
2150   REG32(EDI) = temp;
2151   CYCLES(CYCLES_XCHG_REG_REG);
2152}
2153
2154void i386_device::i386_xchg_r32_rm32()     // Opcode 0x87
2155{
2156   UINT8 modrm = FETCH();
2157   if( modrm >= 0xc0 ) {
2158      UINT32 src = LOAD_RM32(modrm);
2159      UINT32 dst = LOAD_REG32(modrm);
2160      STORE_REG32(modrm, src);
2161      STORE_RM32(modrm, dst);
2162      CYCLES(CYCLES_XCHG_REG_REG);
2163   } else {
2164      UINT32 ea = GetEA(modrm,1);
2165      UINT32 src = READ32(ea);
2166      UINT32 dst = LOAD_REG32(modrm);
2167      WRITE32(ea, dst);
2168      STORE_REG32(modrm, src);
2169      CYCLES(CYCLES_XCHG_REG_MEM);
2170   }
2171}
2172
2173void i386_device::i386_xor_rm32_r32()      // Opcode 0x31
2174{
2175   UINT32 src, dst;
2176   UINT8 modrm = FETCH();
2177   if( modrm >= 0xc0 ) {
2178      src = LOAD_REG32(modrm);
2179      dst = LOAD_RM32(modrm);
2180      dst = XOR32(dst, src);
2181      STORE_RM32(modrm, dst);
2182      CYCLES(CYCLES_ALU_REG_REG);
2183   } else {
2184      UINT32 ea = GetEA(modrm,1);
2185      src = LOAD_REG32(modrm);
2186      dst = READ32(ea);
2187      dst = XOR32(dst, src);
2188      WRITE32(ea, dst);
2189      CYCLES(CYCLES_ALU_REG_MEM);
2190   }
2191}
2192
2193void i386_device::i386_xor_r32_rm32()      // Opcode 0x33
2194{
2195   UINT32 src, dst;
2196   UINT8 modrm = FETCH();
2197   if( modrm >= 0xc0 ) {
2198      src = LOAD_RM32(modrm);
2199      dst = LOAD_REG32(modrm);
2200      dst = XOR32(dst, src);
2201      STORE_REG32(modrm, dst);
2202      CYCLES(CYCLES_ALU_REG_REG);
2203   } else {
2204      UINT32 ea = GetEA(modrm,0);
2205      src = READ32(ea);
2206      dst = LOAD_REG32(modrm);
2207      dst = XOR32(dst, src);
2208      STORE_REG32(modrm, dst);
2209      CYCLES(CYCLES_ALU_MEM_REG);
2210   }
2211}
2212
2213void i386_device::i386_xor_eax_i32()       // Opcode 0x35
2214{
2215   UINT32 src, dst;
2216   src = FETCH32();
2217   dst = REG32(EAX);
2218   dst = XOR32(dst, src);
2219   REG32(EAX) = dst;
2220   CYCLES(CYCLES_ALU_IMM_ACC);
2221}
2222
2223
2224
2225void i386_device::i386_group81_32()        // Opcode 0x81
2226{
2227   UINT32 ea;
2228   UINT32 src, dst;
2229   UINT8 modrm = FETCH();
2230
2231   switch( (modrm >> 3) & 0x7 )
2232   {
2233      case 0:     // ADD Rm32, i32
2234         if( modrm >= 0xc0 ) {
2235            dst = LOAD_RM32(modrm);
2236            src = FETCH32();
2237            dst = ADD32(dst, src);
2238            STORE_RM32(modrm, dst);
2239            CYCLES(CYCLES_ALU_REG_REG);
2240         } else {
2241            ea = GetEA(modrm,1);
2242            dst = READ32(ea);
2243            src = FETCH32();
2244            dst = ADD32(dst, src);
2245            WRITE32(ea, dst);
2246            CYCLES(CYCLES_ALU_REG_MEM);
2247         }
2248         break;
2249      case 1:     // OR Rm32, i32
2250         if( modrm >= 0xc0 ) {
2251            dst = LOAD_RM32(modrm);
2252            src = FETCH32();
2253            dst = OR32(dst, src);
2254            STORE_RM32(modrm, dst);
2255            CYCLES(CYCLES_ALU_REG_REG);
2256         } else {
2257            ea = GetEA(modrm,1);
2258            dst = READ32(ea);
2259            src = FETCH32();
2260            dst = OR32(dst, src);
2261            WRITE32(ea, dst);
2262            CYCLES(CYCLES_ALU_REG_MEM);
2263         }
2264         break;
2265      case 2:     // ADC Rm32, i32
2266         if( modrm >= 0xc0 ) {
2267            dst = LOAD_RM32(modrm);
2268            src = FETCH32();
2269            dst = ADC32(dst, src, m_CF);
2270            STORE_RM32(modrm, dst);
2271            CYCLES(CYCLES_ALU_REG_REG);
2272         } else {
2273            ea = GetEA(modrm,1);
2274            dst = READ32(ea);
2275            src = FETCH32();
2276            dst = ADC32(dst, src, m_CF);
2277            WRITE32(ea, dst);
2278            CYCLES(CYCLES_ALU_REG_MEM);
2279         }
2280         break;
2281      case 3:     // SBB Rm32, i32
2282         if( modrm >= 0xc0 ) {
2283            dst = LOAD_RM32(modrm);
2284            src = FETCH32();
2285            dst = SBB32(dst, src, m_CF);
2286            STORE_RM32(modrm, dst);
2287            CYCLES(CYCLES_ALU_REG_REG);
2288         } else {
2289            ea = GetEA(modrm,1);
2290            dst = READ32(ea);
2291            src = FETCH32();
2292            dst = SBB32(dst, src, m_CF);
2293            WRITE32(ea, dst);
2294            CYCLES(CYCLES_ALU_REG_MEM);
2295         }
2296         break;
2297      case 4:     // AND Rm32, i32
2298         if( modrm >= 0xc0 ) {
2299            dst = LOAD_RM32(modrm);
2300            src = FETCH32();
2301            dst = AND32(dst, src);
2302            STORE_RM32(modrm, dst);
2303            CYCLES(CYCLES_ALU_REG_REG);
2304         } else {
2305            ea = GetEA(modrm,1);
2306            dst = READ32(ea);
2307            src = FETCH32();
2308            dst = AND32(dst, src);
2309            WRITE32(ea, dst);
2310            CYCLES(CYCLES_ALU_REG_MEM);
2311         }
2312         break;
2313      case 5:     // SUB Rm32, i32
2314         if( modrm >= 0xc0 ) {
2315            dst = LOAD_RM32(modrm);
2316            src = FETCH32();
2317            dst = SUB32(dst, src);
2318            STORE_RM32(modrm, dst);
2319            CYCLES(CYCLES_ALU_REG_REG);
2320         } else {
2321            ea = GetEA(modrm,1);
2322            dst = READ32(ea);
2323            src = FETCH32();
2324            dst = SUB32(dst, src);
2325            WRITE32(ea, dst);
2326            CYCLES(CYCLES_ALU_REG_MEM);
2327         }
2328         break;
2329      case 6:     // XOR Rm32, i32
2330         if( modrm >= 0xc0 ) {
2331            dst = LOAD_RM32(modrm);
2332            src = FETCH32();
2333            dst = XOR32(dst, src);
2334            STORE_RM32(modrm, dst);
2335            CYCLES(CYCLES_ALU_REG_REG);
2336         } else {
2337            ea = GetEA(modrm,1);
2338            dst = READ32(ea);
2339            src = FETCH32();
2340            dst = XOR32(dst, src);
2341            WRITE32(ea, dst);
2342            CYCLES(CYCLES_ALU_REG_MEM);
2343         }
2344         break;
2345      case 7:     // CMP Rm32, i32
2346         if( modrm >= 0xc0 ) {
2347            dst = LOAD_RM32(modrm);
2348            src = FETCH32();
2349            SUB32(dst, src);
2350            CYCLES(CYCLES_CMP_REG_REG);
2351         } else {
2352            ea = GetEA(modrm,0);
2353            dst = READ32(ea);
2354            src = FETCH32();
2355            SUB32(dst, src);
2356            CYCLES(CYCLES_CMP_REG_MEM);
2357         }
2358         break;
2359   }
2360}
2361
2362void i386_device::i386_group83_32()        // Opcode 0x83
2363{
2364   UINT32 ea;
2365   UINT32 src, dst;
2366   UINT8 modrm = FETCH();
2367
2368   switch( (modrm >> 3) & 0x7 )
2369   {
2370      case 0:     // ADD Rm32, i32
2371         if( modrm >= 0xc0 ) {
2372            dst = LOAD_RM32(modrm);
2373            src = (UINT32)(INT32)(INT8)FETCH();
2374            dst = ADD32(dst, src);
2375            STORE_RM32(modrm, dst);
2376            CYCLES(CYCLES_ALU_REG_REG);
2377         } else {
2378            ea = GetEA(modrm,1);
2379            dst = READ32(ea);
2380            src = (UINT32)(INT32)(INT8)FETCH();
2381            dst = ADD32(dst, src);
2382            WRITE32(ea, dst);
2383            CYCLES(CYCLES_ALU_REG_MEM);
2384         }
2385         break;
2386      case 1:     // OR Rm32, i32
2387         if( modrm >= 0xc0 ) {
2388            dst = LOAD_RM32(modrm);
2389            src = (UINT32)(INT32)(INT8)FETCH();
2390            dst = OR32(dst, src);
2391            STORE_RM32(modrm, dst);
2392            CYCLES(CYCLES_ALU_REG_REG);
2393         } else {
2394            ea = GetEA(modrm,1);
2395            dst = READ32(ea);
2396            src = (UINT32)(INT32)(INT8)FETCH();
2397            dst = OR32(dst, src);
2398            WRITE32(ea, dst);
2399            CYCLES(CYCLES_ALU_REG_MEM);
2400         }
2401         break;
2402      case 2:     // ADC Rm32, i32
2403         if( modrm >= 0xc0 ) {
2404            dst = LOAD_RM32(modrm);
2405            src = (UINT32)(INT32)(INT8)FETCH();
2406            dst = ADC32(dst, src, m_CF);
2407            STORE_RM32(modrm, dst);
2408            CYCLES(CYCLES_ALU_REG_REG);
2409         } else {
2410            ea = GetEA(modrm,1);
2411            dst = READ32(ea);
2412            src = (UINT32)(INT32)(INT8)FETCH();
2413            dst = ADC32(dst, src, m_CF);
2414            WRITE32(ea, dst);
2415            CYCLES(CYCLES_ALU_REG_MEM);
2416         }
2417         break;
2418      case 3:     // SBB Rm32, i32
2419         if( modrm >= 0xc0 ) {
2420            dst = LOAD_RM32(modrm);
2421            src = ((UINT32)(INT32)(INT8)FETCH());
2422            dst = SBB32(dst, src, m_CF);
2423            STORE_RM32(modrm, dst);
2424            CYCLES(CYCLES_ALU_REG_REG);
2425         } else {
2426            ea = GetEA(modrm,1);
2427            dst = READ32(ea);
2428            src = ((UINT32)(INT32)(INT8)FETCH());
2429            dst = SBB32(dst, src, m_CF);
2430            WRITE32(ea, dst);
2431            CYCLES(CYCLES_ALU_REG_MEM);
2432         }
2433         break;
2434      case 4:     // AND Rm32, i32
2435         if( modrm >= 0xc0 ) {
2436            dst = LOAD_RM32(modrm);
2437            src = (UINT32)(INT32)(INT8)FETCH();
2438            dst = AND32(dst, src);
2439            STORE_RM32(modrm, dst);
2440            CYCLES(CYCLES_ALU_REG_REG);
2441         } else {
2442            ea = GetEA(modrm,1);
2443            dst = READ32(ea);
2444            src = (UINT32)(INT32)(INT8)FETCH();
2445            dst = AND32(dst, src);
2446            WRITE32(ea, dst);
2447            CYCLES(CYCLES_ALU_REG_MEM);
2448         }
2449         break;
2450      case 5:     // SUB Rm32, i32
2451         if( modrm >= 0xc0 ) {
2452            dst = LOAD_RM32(modrm);
2453            src = (UINT32)(INT32)(INT8)FETCH();
2454            dst = SUB32(dst, src);
2455            STORE_RM32(modrm, dst);
2456            CYCLES(CYCLES_ALU_REG_REG);
2457         } else {
2458            ea = GetEA(modrm,1);
2459            dst = READ32(ea);
2460            src = (UINT32)(INT32)(INT8)FETCH();
2461            dst = SUB32(dst, src);
2462            WRITE32(ea, dst);
2463            CYCLES(CYCLES_ALU_REG_MEM);
2464         }
2465         break;
2466      case 6:     // XOR Rm32, i32
2467         if( modrm >= 0xc0 ) {
2468            dst = LOAD_RM32(modrm);
2469            src = (UINT32)(INT32)(INT8)FETCH();
2470            dst = XOR32(dst, src);
2471            STORE_RM32(modrm, dst);
2472            CYCLES(CYCLES_ALU_REG_REG);
2473         } else {
2474            ea = GetEA(modrm,1);
2475            dst = READ32(ea);
2476            src = (UINT32)(INT32)(INT8)FETCH();
2477            dst = XOR32(dst, src);
2478            WRITE32(ea, dst);
2479            CYCLES(CYCLES_ALU_REG_MEM);
2480         }
2481         break;
2482      case 7:     // CMP Rm32, i32
2483         if( modrm >= 0xc0 ) {
2484            dst = LOAD_RM32(modrm);
2485            src = (UINT32)(INT32)(INT8)FETCH();
2486            SUB32(dst, src);
2487            CYCLES(CYCLES_CMP_REG_REG);
2488         } else {
2489            ea = GetEA(modrm,0);
2490            dst = READ32(ea);
2491            src = (UINT32)(INT32)(INT8)FETCH();
2492            SUB32(dst, src);
2493            CYCLES(CYCLES_CMP_REG_MEM);
2494         }
2495         break;
2496   }
2497}
2498
2499void i386_device::i386_groupC1_32()        // Opcode 0xc1
2500{
2501   UINT32 dst;
2502   UINT8 modrm = FETCH();
2503   UINT8 shift;
2504
2505   if( modrm >= 0xc0 ) {
2506      dst = LOAD_RM32(modrm);
2507      shift = FETCH() & 0x1f;
2508      dst = i386_shift_rotate32(modrm, dst, shift);
2509      STORE_RM32(modrm, dst);
2510   } else {
2511      UINT32 ea = GetEA(modrm,1);
2512      dst = READ32(ea);
2513      shift = FETCH() & 0x1f;
2514      dst = i386_shift_rotate32(modrm, dst, shift);
2515      WRITE32(ea, dst);
2516   }
2517}
2518
2519void i386_device::i386_groupD1_32()        // Opcode 0xd1
2520{
2521   UINT32 dst;
2522   UINT8 modrm = FETCH();
2523
2524   if( modrm >= 0xc0 ) {
2525      dst = LOAD_RM32(modrm);
2526      dst = i386_shift_rotate32(modrm, dst, 1);
2527      STORE_RM32(modrm, dst);
2528   } else {
2529      UINT32 ea = GetEA(modrm,1);
2530      dst = READ32(ea);
2531      dst = i386_shift_rotate32(modrm, dst, 1);
2532      WRITE32(ea, dst);
2533   }
2534}
2535
2536void i386_device::i386_groupD3_32()        // Opcode 0xd3
2537{
2538   UINT32 dst;
2539   UINT8 modrm = FETCH();
2540
2541   if( modrm >= 0xc0 ) {
2542      dst = LOAD_RM32(modrm);
2543      dst = i386_shift_rotate32(modrm, dst, REG8(CL));
2544      STORE_RM32(modrm, dst);
2545   } else {
2546      UINT32 ea = GetEA(modrm,1);
2547      dst = READ32(ea);
2548      dst = i386_shift_rotate32(modrm, dst, REG8(CL));
2549      WRITE32(ea, dst);
2550   }
2551}
2552
2553void i386_device::i386_groupF7_32()        // Opcode 0xf7
2554{
2555   UINT8 modrm = FETCH();
2556
2557   switch( (modrm >> 3) & 0x7 )
2558   {
2559      case 0:         /* TEST Rm32, i32 */
2560         if( modrm >= 0xc0 ) {
2561            UINT32 dst = LOAD_RM32(modrm);
2562            UINT32 src = FETCH32();
2563            dst &= src;
2564            m_CF = m_OF = m_AF = 0;
2565            SetSZPF32(dst);
2566            CYCLES(CYCLES_TEST_IMM_REG);
2567         } else {
2568            UINT32 ea = GetEA(modrm,0);
2569            UINT32 dst = READ32(ea);
2570            UINT32 src = FETCH32();
2571            dst &= src;
2572            m_CF = m_OF = m_AF = 0;
2573            SetSZPF32(dst);
2574            CYCLES(CYCLES_TEST_IMM_MEM);
2575         }
2576         break;
2577      case 2:         /* NOT Rm32 */
2578         if( modrm >= 0xc0 ) {
2579            UINT32 dst = LOAD_RM32(modrm);
2580            dst = ~dst;
2581            STORE_RM32(modrm, dst);
2582            CYCLES(CYCLES_NOT_REG);
2583         } else {
2584            UINT32 ea = GetEA(modrm,1);
2585            UINT32 dst = READ32(ea);
2586            dst = ~dst;
2587            WRITE32(ea, dst);
2588            CYCLES(CYCLES_NOT_MEM);
2589         }
2590         break;
2591      case 3:         /* NEG Rm32 */
2592         if( modrm >= 0xc0 ) {
2593            UINT32 dst = LOAD_RM32(modrm);
2594            dst = SUB32(0, dst );
2595            STORE_RM32(modrm, dst);
2596            CYCLES(CYCLES_NEG_REG);
2597         } else {
2598            UINT32 ea = GetEA(modrm,1);
2599            UINT32 dst = READ32(ea);
2600            dst = SUB32(0, dst );
2601            WRITE32(ea, dst);
2602            CYCLES(CYCLES_NEG_MEM);
2603         }
2604         break;
2605      case 4:         /* MUL EAX, Rm32 */
2606         {
2607            UINT64 result;
2608            UINT32 src, dst;
2609            if( modrm >= 0xc0 ) {
2610               src = LOAD_RM32(modrm);
2611               CYCLES(CYCLES_MUL32_ACC_REG);      /* TODO: Correct multiply timing */
2612            } else {
2613               UINT32 ea = GetEA(modrm,0);
2614               src = READ32(ea);
2615               CYCLES(CYCLES_MUL32_ACC_MEM);      /* TODO: Correct multiply timing */
2616            }
2617
2618            dst = REG32(EAX);
2619            result = (UINT64)src * (UINT64)dst;
2620            REG32(EDX) = (UINT32)(result >> 32);
2621            REG32(EAX) = (UINT32)result;
2622
2623            m_CF = m_OF = (REG32(EDX) != 0);
2624         }
2625         break;
2626      case 5:         /* IMUL EAX, Rm32 */
2627         {
2628            INT64 result;
2629            INT64 src, dst;
2630            if( modrm >= 0xc0 ) {
2631               src = (INT64)(INT32)LOAD_RM32(modrm);
2632               CYCLES(CYCLES_IMUL32_ACC_REG);     /* TODO: Correct multiply timing */
2633            } else {
2634               UINT32 ea = GetEA(modrm,0);
2635               src = (INT64)(INT32)READ32(ea);
2636               CYCLES(CYCLES_IMUL32_ACC_MEM);     /* TODO: Correct multiply timing */
2637            }
2638
2639            dst = (INT64)(INT32)REG32(EAX);
2640            result = src * dst;
2641
2642            REG32(EDX) = (UINT32)(result >> 32);
2643            REG32(EAX) = (UINT32)result;
2644
2645            m_CF = m_OF = !(result == (INT64)(INT32)result);
2646         }
2647         break;
2648      case 6:         /* DIV EAX, Rm32 */
2649         {
2650            UINT64 quotient, remainder, result;
2651            UINT32 src;
2652            if( modrm >= 0xc0 ) {
2653               src = LOAD_RM32(modrm);
2654               CYCLES(CYCLES_DIV32_ACC_REG);
2655            } else {
2656               UINT32 ea = GetEA(modrm,0);
2657               src = READ32(ea);
2658               CYCLES(CYCLES_DIV32_ACC_MEM);
2659            }
2660
2661            quotient = ((UINT64)(REG32(EDX)) << 32) | (UINT64)(REG32(EAX));
2662            if( src ) {
2663               remainder = quotient % (UINT64)src;
2664               result = quotient / (UINT64)src;
2665               if( result > 0xffffffff ) {
2666                  /* TODO: Divide error */
2667               } else {
2668                  REG32(EDX) = (UINT32)remainder;
2669                  REG32(EAX) = (UINT32)result;
2670               }
2671            } else {
2672               i386_trap(0, 0, 0);
2673            }
2674         }
2675         break;
2676      case 7:         /* IDIV EAX, Rm32 */
2677         {
2678            INT64 quotient, remainder, result;
2679            UINT32 src;
2680            if( modrm >= 0xc0 ) {
2681               src = LOAD_RM32(modrm);
2682               CYCLES(CYCLES_IDIV32_ACC_REG);
2683            } else {
2684               UINT32 ea = GetEA(modrm,0);
2685               src = READ32(ea);
2686               CYCLES(CYCLES_IDIV32_ACC_MEM);
2687            }
2688
2689            quotient = (((INT64)REG32(EDX)) << 32) | ((UINT64)REG32(EAX));
2690            if( src ) {
2691               remainder = quotient % (INT64)(INT32)src;
2692               result = quotient / (INT64)(INT32)src;
2693               if( result > 0xffffffff ) {
2694                  /* TODO: Divide error */
2695               } else {
2696                  REG32(EDX) = (UINT32)remainder;
2697                  REG32(EAX) = (UINT32)result;
2698               }
2699            } else {
2700               i386_trap(0, 0, 0);
2701            }
2702         }
2703         break;
2704   }
2705}
2706
2707void i386_device::i386_groupFF_32()        // Opcode 0xff
2708{
2709   UINT8 modrm = FETCH();
2710
2711   switch( (modrm >> 3) & 0x7 )
2712   {
2713      case 0:         /* INC Rm32 */
2714         if( modrm >= 0xc0 ) {
2715            UINT32 dst = LOAD_RM32(modrm);
2716            dst = INC32(dst);
2717            STORE_RM32(modrm, dst);
2718            CYCLES(CYCLES_INC_REG);
2719         } else {
2720            UINT32 ea = GetEA(modrm,1);
2721            UINT32 dst = READ32(ea);
2722            dst = INC32(dst);
2723            WRITE32(ea, dst);
2724            CYCLES(CYCLES_INC_MEM);
2725         }
2726         break;
2727      case 1:         /* DEC Rm32 */
2728         if( modrm >= 0xc0 ) {
2729            UINT32 dst = LOAD_RM32(modrm);
2730            dst = DEC32(dst);
2731            STORE_RM32(modrm, dst);
2732            CYCLES(CYCLES_DEC_REG);
2733         } else {
2734            UINT32 ea = GetEA(modrm,1);
2735            UINT32 dst = READ32(ea);
2736            dst = DEC32(dst);
2737            WRITE32(ea, dst);
2738            CYCLES(CYCLES_DEC_MEM);
2739         }
2740         break;
2741      case 2:         /* CALL Rm32 */
2742         {
2743            UINT32 address;
2744            if( modrm >= 0xc0 ) {
2745               address = LOAD_RM32(modrm);
2746               CYCLES(CYCLES_CALL_REG);       /* TODO: Timing = 7 + m */
2747            } else {
2748               UINT32 ea = GetEA(modrm,0);
2749               address = READ32(ea);
2750               CYCLES(CYCLES_CALL_MEM);       /* TODO: Timing = 10 + m */
2751            }
2752            PUSH32(m_eip );
2753            m_eip = address;
2754            CHANGE_PC(m_eip);
2755         }
2756         break;
2757      case 3:         /* CALL FAR Rm32 */
2758         {
2759            UINT16 selector;
2760            UINT32 address;
2761
2762            if( modrm >= 0xc0 )
2763            {
2764               report_invalid_modrm("groupFF_32", modrm);
2765            }
2766            else
2767            {
2768               UINT32 ea = GetEA(modrm,0);
2769               address = READ32(ea + 0);
2770               selector = READ16(ea + 4);
2771               CYCLES(CYCLES_CALL_MEM_INTERSEG);      /* TODO: Timing = 10 + m */
2772               if(PROTECTED_MODE && !V8086_MODE)
2773               {
2774                  i386_protected_mode_call(selector,address,1,1);
2775               }
2776               else
2777               {
2778                  PUSH32(m_sreg[CS].selector );
2779                  PUSH32(m_eip );
2780                  m_sreg[CS].selector = selector;
2781                  m_performed_intersegment_jump = 1;
2782                  i386_load_segment_descriptor(CS );
2783                  m_eip = address;
2784                  CHANGE_PC(m_eip);
2785               }
2786            }
2787         }
2788         break;
2789      case 4:         /* JMP Rm32 */
2790         {
2791            UINT32 address;
2792            if( modrm >= 0xc0 ) {
2793               address = LOAD_RM32(modrm);
2794               CYCLES(CYCLES_JMP_REG);        /* TODO: Timing = 7 + m */
2795            } else {
2796               UINT32 ea = GetEA(modrm,0);
2797               address = READ32(ea);
2798               CYCLES(CYCLES_JMP_MEM);        /* TODO: Timing = 10 + m */
2799            }
2800            m_eip = address;
2801            CHANGE_PC(m_eip);
2802         }
2803         break;
2804      case 5:         /* JMP FAR Rm32 */
2805         {
2806            UINT16 selector;
2807            UINT32 address;
2808
2809            if( modrm >= 0xc0 )
2810            {
2811               report_invalid_modrm("groupFF_32", modrm);
2812            }
2813            else
2814            {
2815               UINT32 ea = GetEA(modrm,0);
2816               address = READ32(ea + 0);
2817               selector = READ16(ea + 4);
2818               CYCLES(CYCLES_JMP_MEM_INTERSEG);       /* TODO: Timing = 10 + m */
2819               if(PROTECTED_MODE && !V8086_MODE)
2820               {
2821                  i386_protected_mode_jump(selector,address,1,1);
2822               }
2823               else
2824               {
2825                  m_sreg[CS].selector = selector;
2826                  m_performed_intersegment_jump = 1;
2827                  i386_load_segment_descriptor(CS );
2828                  m_eip = address;
2829                  CHANGE_PC(m_eip);
2830               }
2831            }
2832         }
2833         break;
2834      case 6:         /* PUSH Rm32 */
2835         {
2836            UINT32 value;
2837            if( modrm >= 0xc0 ) {
2838               value = LOAD_RM32(modrm);
2839            } else {
2840               UINT32 ea = GetEA(modrm,0);
2841               value = READ32(ea);
2842            }
2843            PUSH32(value);
2844            CYCLES(CYCLES_PUSH_RM);
2845         }
2846         break;
2847      default:
2848         report_invalid_modrm("groupFF_32", modrm);
2849         break;
2850   }
2851}
2852
2853void i386_device::i386_group0F00_32()          // Opcode 0x0f 00
2854{
2855   UINT32 address, ea;
2856   UINT8 modrm = FETCH();
2857   I386_SREG seg;
2858   UINT8 result;
2859
2860   switch( (modrm >> 3) & 0x7 )
2861   {
2862      case 0:         /* SLDT */
2863         if ( PROTECTED_MODE && !V8086_MODE )
2864         {
2865            if( modrm >= 0xc0 ) {
2866               STORE_RM32(modrm, m_ldtr.segment);
2867               CYCLES(CYCLES_SLDT_REG);
2868            } else {
2869               ea = GetEA(modrm,1);
2870               WRITE16(ea, m_ldtr.segment);
2871               CYCLES(CYCLES_SLDT_MEM);
2872            }
2873         }
2874         else
2875         {
2876            i386_trap(6, 0, 0);
2877         }
2878         break;
2879      case 1:         /* STR */
2880         if ( PROTECTED_MODE && !V8086_MODE )
2881         {
2882            if( modrm >= 0xc0 ) {
2883               STORE_RM32(modrm, m_task.segment);
2884               CYCLES(CYCLES_STR_REG);
2885            } else {
2886               ea = GetEA(modrm,1);
2887               WRITE16(ea, m_task.segment);
2888               CYCLES(CYCLES_STR_MEM);
2889            }
2890         }
2891         else
2892         {
2893            i386_trap(6, 0, 0);
2894         }
2895         break;
2896      case 2:         /* LLDT */
2897         if ( PROTECTED_MODE && !V8086_MODE )
2898         {
2899            if(m_CPL)
2900               FAULT(FAULT_GP,0)
2901            if( modrm >= 0xc0 ) {
2902               address = LOAD_RM32(modrm);
2903               m_ldtr.segment = address;
2904               CYCLES(CYCLES_LLDT_REG);
2905            } else {
2906               ea = GetEA(modrm,0);
2907               m_ldtr.segment = READ32(ea);
2908               CYCLES(CYCLES_LLDT_MEM);
2909            }
2910            memset(&seg, 0, sizeof(seg));
2911            seg.selector = m_ldtr.segment;
2912            i386_load_protected_mode_segment(&seg,NULL);
2913            m_ldtr.limit = seg.limit;
2914            m_ldtr.base = seg.base;
2915            m_ldtr.flags = seg.flags;
2916         }
2917         else
2918         {
2919            i386_trap(6, 0, 0);
2920         }
2921         break;
2922
2923      case 3:         /* LTR */
2924         if ( PROTECTED_MODE && !V8086_MODE )
2925         {
2926            if(m_CPL)
2927               FAULT(FAULT_GP,0)
2928            if( modrm >= 0xc0 ) {
2929               address = LOAD_RM32(modrm);
2930               m_task.segment = address;
2931               CYCLES(CYCLES_LTR_REG);
2932            } else {
2933               ea = GetEA(modrm,0);
2934               m_task.segment = READ32(ea);
2935               CYCLES(CYCLES_LTR_MEM);
2936            }
2937            memset(&seg, 0, sizeof(seg));
2938            seg.selector = m_task.segment;
2939            i386_load_protected_mode_segment(&seg,NULL);
2940            m_task.limit = seg.limit;
2941            m_task.base = seg.base;
2942            m_task.flags = seg.flags;
2943         }
2944         else
2945         {
2946            i386_trap(6, 0, 0);
2947         }
2948         break;
2949
2950      case 4:  /* VERR */
2951         if ( PROTECTED_MODE && !V8086_MODE )
2952         {
2953            if( modrm >= 0xc0 ) {
2954               address = LOAD_RM32(modrm);
2955               CYCLES(CYCLES_VERR_REG);
2956            } else {
2957               ea = GetEA(modrm,0);
2958               address = READ32(ea);
2959               CYCLES(CYCLES_VERR_MEM);
2960            }
2961            memset(&seg, 0, sizeof(seg));
2962            seg.selector = address;
2963            result = i386_load_protected_mode_segment(&seg,NULL);
2964            // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
2965            if(!(seg.flags & 0x10))
2966               result = 0;
2967            // check that the segment is readable
2968            if(seg.flags & 0x10)  // is code or data segment
2969            {
2970               if(seg.flags & 0x08)  // is code segment, so check if it's readable
2971               {
2972                  if(!(seg.flags & 0x02))
2973                  {
2974                     result = 0;
2975                  }
2976                  else
2977                  {  // check if conforming, these are always readable, regardless of privilege
2978                     if(!(seg.flags & 0x04))
2979                     {
2980                        // if not conforming, then we must check privilege levels (TODO: current privilege level check)
2981                        if(((seg.flags >> 5) & 0x03) < (address & 0x03))
2982                           result = 0;
2983                     }
2984                  }
2985               }
2986            }
2987            // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
2988            SetZF(result);
2989         }
2990         else
2991         {
2992            i386_trap(6, 0, 0);
2993            logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n");
2994         }
2995         break;
2996
2997      case 5:  /* VERW */
2998         if ( PROTECTED_MODE && !V8086_MODE )
2999         {
3000            if( modrm >= 0xc0 ) {
3001               address = LOAD_RM16(modrm);
3002               CYCLES(CYCLES_VERW_REG);
3003            } else {
3004               ea = GetEA(modrm,0);
3005               address = READ16(ea);
3006               CYCLES(CYCLES_VERW_MEM);
3007            }
3008            memset(&seg, 0, sizeof(seg));
3009            seg.selector = address;
3010            result = i386_load_protected_mode_segment(&seg,NULL);
3011            // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3012            if(!(seg.flags & 0x10))
3013               result = 0;
3014            // check that the segment is writable
3015            if(seg.flags & 0x10)  // is code or data segment
3016            {
3017               if(seg.flags & 0x08)  // is code segment (and thus, not writable)
3018               {
3019                  result = 0;
3020               }
3021               else
3022               {  // is data segment
3023                  if(!(seg.flags & 0x02))
3024                     result = 0;
3025               }
3026            }
3027            // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3028            if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3029               result = 0;
3030            SetZF(result);
3031         }
3032         else
3033         {
3034            i386_trap(6, 0, 0);
3035            logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n");
3036         }
3037         break;
3038
3039      default:
3040         report_invalid_modrm("group0F00_32", modrm);
3041         break;
3042   }
3043}
3044
3045void i386_device::i386_group0F01_32()      // Opcode 0x0f 01
3046{
3047   UINT8 modrm = FETCH();
3048   UINT32 address, ea;
3049
3050   switch( (modrm >> 3) & 0x7 )
3051   {
3052      case 0:         /* SGDT */
3053         {
3054            if( modrm >= 0xc0 ) {
3055               address = LOAD_RM32(modrm);
3056               ea = i386_translate(CS, address, 1 );
3057            } else {
3058               ea = GetEA(modrm,1);
3059            }
3060            WRITE16(ea, m_gdtr.limit);
3061            WRITE32(ea + 2, m_gdtr.base);
3062            CYCLES(CYCLES_SGDT);
3063            break;
3064         }
3065      case 1:         /* SIDT */
3066         {
3067            if (modrm >= 0xc0)
3068            {
3069               address = LOAD_RM32(modrm);
3070               ea = i386_translate(CS, address, 1 );
3071            }
3072            else
3073            {
3074               ea = GetEA(modrm,1);
3075            }
3076            WRITE16(ea, m_idtr.limit);
3077            WRITE32(ea + 2, m_idtr.base);
3078            CYCLES(CYCLES_SIDT);
3079            break;
3080         }
3081      case 2:         /* LGDT */
3082         {
3083            if(PROTECTED_MODE && m_CPL)
3084               FAULT(FAULT_GP,0)
3085            if( modrm >= 0xc0 ) {
3086               address = LOAD_RM32(modrm);
3087               ea = i386_translate(CS, address, 0 );
3088            } else {
3089               ea = GetEA(modrm,0);
3090            }
3091            m_gdtr.limit = READ16(ea);
3092            m_gdtr.base = READ32(ea + 2);
3093            CYCLES(CYCLES_LGDT);
3094            break;
3095         }
3096      case 3:         /* LIDT */
3097         {
3098            if(PROTECTED_MODE && m_CPL)
3099               FAULT(FAULT_GP,0)
3100            if( modrm >= 0xc0 ) {
3101               address = LOAD_RM32(modrm);
3102               ea = i386_translate(CS, address, 0 );
3103            } else {
3104               ea = GetEA(modrm,0);
3105            }
3106            m_idtr.limit = READ16(ea);
3107            m_idtr.base = READ32(ea + 2);
3108            CYCLES(CYCLES_LIDT);
3109            break;
3110         }
3111      case 4:         /* SMSW */
3112         {
3113            if( modrm >= 0xc0 ) {
3114               // smsw stores all of cr0 into register
3115               STORE_RM32(modrm, m_cr[0]);
3116               CYCLES(CYCLES_SMSW_REG);
3117            } else {
3118               /* always 16-bit memory operand */
3119               ea = GetEA(modrm,1);
3120               WRITE16(ea, m_cr[0]);
3121               CYCLES(CYCLES_SMSW_MEM);
3122            }
3123            break;
3124         }
3125      case 6:         /* LMSW */
3126         {
3127            if(PROTECTED_MODE && m_CPL)
3128               FAULT(FAULT_GP,0)
3129            UINT16 b;
3130            if( modrm >= 0xc0 ) {
3131               b = LOAD_RM16(modrm);
3132               CYCLES(CYCLES_LMSW_REG);
3133            } else {
3134               ea = GetEA(modrm,0);
3135               CYCLES(CYCLES_LMSW_MEM);
3136            b = READ16(ea);
3137            }
3138            if(PROTECTED_MODE)
3139               b |= 0x0001;  // cannot return to real mode using this instruction.
3140            m_cr[0] &= ~0x0000000f;
3141            m_cr[0] |= b & 0x0000000f;
3142            break;
3143         }
3144      default:
3145         report_invalid_modrm("group0F01_32", modrm);
3146         break;
3147   }
3148}
3149
3150void i386_device::i386_group0FBA_32()      // Opcode 0x0f ba
3151{
3152   UINT8 modrm = FETCH();
3153
3154   switch( (modrm >> 3) & 0x7 )
3155   {
3156      case 4:         /* BT Rm32, i8 */
3157         if( modrm >= 0xc0 ) {
3158            UINT32 dst = LOAD_RM32(modrm);
3159            UINT8 bit = FETCH();
3160
3161            if( dst & (1 << bit) )
3162               m_CF = 1;
3163            else
3164               m_CF = 0;
3165
3166            CYCLES(CYCLES_BT_IMM_REG);
3167         } else {
3168            UINT32 ea = GetEA(modrm,0);
3169            UINT32 dst = READ32(ea);
3170            UINT8 bit = FETCH();
3171
3172            if( dst & (1 << bit) )
3173               m_CF = 1;
3174            else
3175               m_CF = 0;
3176
3177            CYCLES(CYCLES_BT_IMM_MEM);
3178         }
3179         break;
3180      case 5:         /* BTS Rm32, i8 */
3181         if( modrm >= 0xc0 ) {
3182            UINT32 dst = LOAD_RM32(modrm);
3183            UINT8 bit = FETCH();
3184
3185            if( dst & (1 << bit) )
3186               m_CF = 1;
3187            else
3188               m_CF = 0;
3189            dst |= (1 << bit);
3190
3191            STORE_RM32(modrm, dst);
3192            CYCLES(CYCLES_BTS_IMM_REG);
3193         } else {
3194            UINT32 ea = GetEA(modrm,1);
3195            UINT32 dst = READ32(ea);
3196            UINT8 bit = FETCH();
3197
3198            if( dst & (1 << bit) )
3199               m_CF = 1;
3200            else
3201               m_CF = 0;
3202            dst |= (1 << bit);
3203
3204            WRITE32(ea, dst);
3205            CYCLES(CYCLES_BTS_IMM_MEM);
3206         }
3207         break;
3208      case 6:         /* BTR Rm32, i8 */
3209         if( modrm >= 0xc0 ) {
3210            UINT32 dst = LOAD_RM32(modrm);
3211            UINT8 bit = FETCH();
3212
3213            if( dst & (1 << bit) )
3214               m_CF = 1;
3215            else
3216               m_CF = 0;
3217            dst &= ~(1 << bit);
3218
3219            STORE_RM32(modrm, dst);
3220            CYCLES(CYCLES_BTR_IMM_REG);
3221         } else {
3222            UINT32 ea = GetEA(modrm,1);
3223            UINT32 dst = READ32(ea);
3224            UINT8 bit = FETCH();
3225
3226            if( dst & (1 << bit) )
3227               m_CF = 1;
3228            else
3229               m_CF = 0;
3230            dst &= ~(1 << bit);
3231
3232            WRITE32(ea, dst);
3233            CYCLES(CYCLES_BTR_IMM_MEM);
3234         }
3235         break;
3236      case 7:         /* BTC Rm32, i8 */
3237         if( modrm >= 0xc0 ) {
3238            UINT32 dst = LOAD_RM32(modrm);
3239            UINT8 bit = FETCH();
3240
3241            if( dst & (1 << bit) )
3242               m_CF = 1;
3243            else
3244               m_CF = 0;
3245            dst ^= (1 << bit);
3246
3247            STORE_RM32(modrm, dst);
3248            CYCLES(CYCLES_BTC_IMM_REG);
3249         } else {
3250            UINT32 ea = GetEA(modrm,1);
3251            UINT32 dst = READ32(ea);
3252            UINT8 bit = FETCH();
3253
3254            if( dst & (1 << bit) )
3255               m_CF = 1;
3256            else
3257               m_CF = 0;
3258            dst ^= (1 << bit);
3259
3260            WRITE32(ea, dst);
3261            CYCLES(CYCLES_BTC_IMM_MEM);
3262         }
3263         break;
3264      default:
3265         report_invalid_modrm("group0FBA_32", modrm);
3266         break;
3267   }
3268}
3269
3270void i386_device::i386_lar_r32_rm32()  // Opcode 0x0f 0x02
3271{
3272   UINT8 modrm = FETCH();
3273   I386_SREG seg;
3274   UINT8 type;
3275
3276   if(PROTECTED_MODE && !V8086_MODE)
3277   {
3278      memset(&seg,0,sizeof(seg));
3279      if(modrm >= 0xc0)
3280      {
3281         seg.selector = LOAD_RM32(modrm);
3282         CYCLES(CYCLES_LAR_REG);
3283      }
3284      else
3285      {
3286         UINT32 ea = GetEA(modrm,0);
3287         seg.selector = READ32(ea);
3288         CYCLES(CYCLES_LAR_MEM);
3289      }
3290      if(seg.selector == 0)
3291      {
3292         SetZF(0);  // not a valid segment
3293      }
3294      else
3295      {
3296         UINT64 desc;
3297         if(!i386_load_protected_mode_segment(&seg,&desc))
3298         {
3299            SetZF(0);
3300            return;
3301         }
3302         UINT8 DPL = (seg.flags >> 5) & 3;
3303         if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3304         {
3305            SetZF(0);
3306            return;
3307         }
3308         if(!(seg.flags & 0x10))  // special segment
3309         {
3310            // check for invalid segment types
3311            type = seg.flags & 0x000f;
3312            if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d)
3313            {
3314               SetZF(0);  // invalid segment type
3315            }
3316            else
3317            {
3318               STORE_REG32(modrm,(desc>>32) & 0x00ffff00);
3319               SetZF(1);
3320            }
3321         }
3322         else
3323         {
3324            STORE_REG32(modrm,(desc>>32) & 0x00ffff00);
3325            SetZF(1);
3326         }
3327      }
3328   }
3329   else
3330   {
3331      // illegal opcode
3332      i386_trap(6,0, 0);
3333      logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n");
3334   }
3335}
3336
3337void i386_device::i386_lsl_r32_rm32()  // Opcode 0x0f 0x03
3338{
3339   UINT8 modrm = FETCH();
3340   UINT32 limit;
3341   I386_SREG seg;
3342
3343   if(PROTECTED_MODE && !V8086_MODE)
3344   {
3345      memset(&seg, 0, sizeof(seg));
3346      if(modrm >= 0xc0)
3347      {
3348         seg.selector = LOAD_RM32(modrm);
3349      }
3350      else
3351      {
3352         UINT32 ea = GetEA(modrm,0);
3353         seg.selector = READ32(ea);
3354      }
3355      if(seg.selector == 0)
3356      {
3357         SetZF(0);  // not a valid segment
3358      }
3359      else
3360      {
3361         UINT8 type;
3362         if(!i386_load_protected_mode_segment(&seg,NULL))
3363         {
3364            SetZF(0);
3365            return;
3366         }
3367         UINT8 DPL = (seg.flags >> 5) & 3;
3368         if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3369         {
3370            SetZF(0);
3371            return;
3372         }
3373         type = seg.flags & 0x1f;
3374         switch(type)
3375         {
3376         case 0:
3377         case 4:
3378         case 5:
3379         case 6:
3380         case 7:
3381         case 8:
3382         case 10:
3383         case 12:
3384         case 13:
3385         case 14:
3386         case 15:
3387            SetZF(0);
3388            return;
3389         default:
3390            limit = seg.limit;
3391            STORE_REG32(modrm,limit);
3392            SetZF(1);
3393         }
3394      }
3395   }
3396   else
3397      i386_trap(6, 0, 0);
3398}
3399
3400void i386_device::i386_bound_r32_m32_m32() // Opcode 0x62
3401{
3402   UINT8 modrm;
3403   INT32 val, low, high;
3404
3405   modrm = FETCH();
3406
3407   if (modrm >= 0xc0)
3408   {
3409      low = high = LOAD_RM32(modrm);
3410   }
3411   else
3412   {
3413      UINT32 ea = GetEA(modrm,0);
3414      low = READ32(ea + 0);
3415      high = READ32(ea + 4);
3416   }
3417   val = LOAD_REG32(modrm);
3418
3419   if ((val < low) || (val > high))
3420   {
3421      CYCLES(CYCLES_BOUND_OUT_RANGE);
3422      i386_trap(5, 0, 0);
3423   }
3424   else
3425   {
3426      CYCLES(CYCLES_BOUND_IN_RANGE);
3427   }
3428}
3429
3430void i386_device::i386_retf32()            // Opcode 0xcb
3431{
3432   if(PROTECTED_MODE && !V8086_MODE)
3433   {
3434      i386_protected_mode_retf(0,1);
3435   }
3436   else
3437   {
3438      m_eip = POP32();
3439      m_sreg[CS].selector = POP32();
3440      i386_load_segment_descriptor(CS );
3441      CHANGE_PC(m_eip);
3442   }
3443
3444   CYCLES(CYCLES_RET_INTERSEG);
3445}
3446
3447void i386_device::i386_retf_i32()          // Opcode 0xca
3448{
3449   UINT16 count = FETCH16();
3450
3451   if(PROTECTED_MODE && !V8086_MODE)
3452   {
3453      i386_protected_mode_retf(count,1);
3454   }
3455   else
3456   {
3457      m_eip = POP32();
3458      m_sreg[CS].selector = POP32();
3459      i386_load_segment_descriptor(CS );
3460      CHANGE_PC(m_eip);
3461      REG32(ESP) += count;
3462   }
3463
3464   CYCLES(CYCLES_RET_IMM_INTERSEG);
3465}
3466
3467void i386_device::i386_load_far_pointer32(int s)
3468{
3469   UINT8 modrm = FETCH();
3470   UINT16 selector;
3471
3472   if( modrm >= 0xc0 ) {
3473      report_invalid_modrm("load_far_pointer32", modrm);
3474   } else {
3475      UINT32 ea = GetEA(modrm,0);
3476      STORE_REG32(modrm, READ32(ea + 0));
3477      selector = READ16(ea + 4);
3478      i386_sreg_load(selector,s,NULL);
3479   }
3480}
3481
3482void i386_device::i386_lds32()             // Opcode 0xc5
3483{
3484   i386_load_far_pointer32(DS);
3485   CYCLES(CYCLES_LDS);
3486}
3487
3488void i386_device::i386_lss32()             // Opcode 0x0f 0xb2
3489{
3490   i386_load_far_pointer32(SS);
3491   CYCLES(CYCLES_LSS);
3492}
3493
3494void i386_device::i386_les32()             // Opcode 0xc4
3495{
3496   i386_load_far_pointer32(ES);
3497   CYCLES(CYCLES_LES);
3498}
3499
3500void i386_device::i386_lfs32()             // Opcode 0x0f 0xb4
3501{
3502   i386_load_far_pointer32(FS);
3503   CYCLES(CYCLES_LFS);
3504}
3505
3506void i386_device::i386_lgs32()             // Opcode 0x0f 0xb5
3507{
3508   i386_load_far_pointer32(GS);
3509   CYCLES(CYCLES_LGS);
3510}
Property changes on: trunk/src/emu/cpu/i386/i386op32.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/i386/i386op16.inc
r0r28739
1UINT16 i386_device::i386_shift_rotate16(UINT8 modrm, UINT32 value, UINT8 shift)
2{
3   UINT32 src = value & 0xffff;
4   UINT16 dst = value;
5
6   if( shift == 0 ) {
7      CYCLES_RM(modrm, 3, 7);
8   } else if( shift == 1 ) {
9      switch( (modrm >> 3) & 0x7 )
10      {
11         case 0:         /* ROL rm16, 1 */
12            m_CF = (src & 0x8000) ? 1 : 0;
13            dst = (src << 1) + m_CF;
14            m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
15            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
16            break;
17         case 1:         /* ROR rm16, 1 */
18            m_CF = (src & 0x1) ? 1 : 0;
19            dst = (m_CF << 15) | (src >> 1);
20            m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
21            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
22            break;
23         case 2:         /* RCL rm16, 1 */
24            dst = (src << 1) + m_CF;
25            m_CF = (src & 0x8000) ? 1 : 0;
26            m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
27            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
28            break;
29         case 3:         /* RCR rm16, 1 */
30            dst = (m_CF << 15) | (src >> 1);
31            m_CF = src & 0x1;
32            m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
33            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
34            break;
35         case 4:         /* SHL/SAL rm16, 1 */
36         case 6:
37            dst = src << 1;
38            m_CF = (src & 0x8000) ? 1 : 0;
39            m_OF = (((m_CF << 15) ^ dst) & 0x8000) ? 1 : 0;
40            SetSZPF16(dst);
41            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
42            break;
43         case 5:         /* SHR rm16, 1 */
44            dst = src >> 1;
45            m_CF = src & 0x1;
46            m_OF = (dst & 0x8000) ? 1 : 0;
47            SetSZPF16(dst);
48            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
49            break;
50         case 7:         /* SAR rm16, 1 */
51            dst = (INT16)(src) >> 1;
52            m_CF = src & 0x1;
53            m_OF = 0;
54            SetSZPF16(dst);
55            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
56            break;
57      }
58   } else {
59      switch( (modrm >> 3) & 0x7 )
60      {
61         case 0:         /* ROL rm16, i8 */
62            if(!(shift & 15))
63            {
64               if(shift & 16)
65               {
66                  m_CF = src & 1;
67                  m_OF = (src & 1) ^ ((src >> 15) & 1);
68               }
69               break;
70            }
71            shift &= 15;
72            dst = ((src & ((UINT16)0xffff >> shift)) << shift) |
73                  ((src & ((UINT16)0xffff << (16-shift))) >> (16-shift));
74            m_CF = dst & 0x1;
75            m_OF = (dst & 1) ^ (dst >> 15);
76            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
77            break;
78         case 1:         /* ROR rm16, i8 */
79            if(!(shift & 15))
80            {
81               if(shift & 16)
82               {
83                  m_CF = (src >> 15) & 1;
84                  m_OF = ((src >> 15) & 1) ^ ((src >> 14) & 1);
85               }
86               break;
87            }
88            shift &= 15;
89            dst = ((src & ((UINT16)0xffff << shift)) >> shift) |
90                  ((src & ((UINT16)0xffff >> (16-shift))) << (16-shift));
91            m_CF = (dst >> 15) & 1;
92            m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
93            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
94            break;
95         case 2:         /* RCL rm16, i8 */
96            shift %= 17;
97            dst = ((src & ((UINT16)0xffff >> shift)) << shift) |
98                  ((src & ((UINT16)0xffff << (17-shift))) >> (17-shift)) |
99                  (m_CF << (shift-1));
100            if(shift) m_CF = (src >> (16-shift)) & 0x1;
101            m_OF = m_CF ^ ((dst >> 15) & 1);
102            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
103            break;
104         case 3:         /* RCR rm16, i8 */
105            shift %= 17;
106            dst = ((src & ((UINT16)0xffff << shift)) >> shift) |
107                  ((src & ((UINT16)0xffff >> (16-shift))) << (17-shift)) |
108                  (m_CF << (16-shift));
109            if(shift) m_CF = (src >> (shift-1)) & 0x1;
110            m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
111            CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
112            break;
113         case 4:         /* SHL/SAL rm16, i8 */
114         case 6:
115            shift &= 31;
116            dst = src << shift;
117            m_CF = (shift <= 16) && (src & (1 << (16-shift)));
118            SetSZPF16(dst);
119            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
120            break;
121         case 5:         /* SHR rm16, i8 */
122            shift &= 31;
123            dst = src >> shift;
124            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
125            SetSZPF16(dst);
126            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
127            break;
128         case 7:         /* SAR rm16, i8 */
129            shift &= 31;
130            dst = (INT16)src >> shift;
131            m_CF = (src & (1 << (shift-1))) ? 1 : 0;
132            SetSZPF16(dst);
133            CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
134            break;
135      }
136
137   }
138   return dst;
139}
140
141
142
143void i386_device::i386_adc_rm16_r16()      // Opcode 0x11
144{
145   UINT16 src, dst;
146   UINT8 modrm = FETCH();
147   if( modrm >= 0xc0 ) {
148      src = LOAD_REG16(modrm);
149      dst = LOAD_RM16(modrm);
150      dst = ADC16(dst, src, m_CF);
151      STORE_RM16(modrm, dst);
152      CYCLES(CYCLES_ALU_REG_REG);
153   } else {
154      UINT32 ea = GetEA(modrm,1);
155      src = LOAD_REG16(modrm);
156      dst = READ16(ea);
157      dst = ADC16(dst, src, m_CF);
158      WRITE16(ea, dst);
159      CYCLES(CYCLES_ALU_REG_MEM);
160   }
161}
162
163void i386_device::i386_adc_r16_rm16()      // Opcode 0x13
164{
165   UINT16 src, dst;
166   UINT8 modrm = FETCH();
167   if( modrm >= 0xc0 ) {
168      src = LOAD_RM16(modrm);
169      dst = LOAD_REG16(modrm);
170      dst = ADC16(dst, src, m_CF);
171      STORE_REG16(modrm, dst);
172      CYCLES(CYCLES_ALU_REG_REG);
173   } else {
174      UINT32 ea = GetEA(modrm,0);
175      src = READ16(ea);
176      dst = LOAD_REG16(modrm);
177      dst = ADC16(dst, src, m_CF);
178      STORE_REG16(modrm, dst);
179      CYCLES(CYCLES_ALU_MEM_REG);
180   }
181}
182
183void i386_device::i386_adc_ax_i16()        // Opcode 0x15
184{
185   UINT16 src, dst;
186   src = FETCH16();
187   dst = REG16(AX);
188   dst = ADC16(dst, src, m_CF);
189   REG16(AX) = dst;
190   CYCLES(CYCLES_ALU_IMM_ACC);
191}
192
193void i386_device::i386_add_rm16_r16()      // Opcode 0x01
194{
195   UINT16 src, dst;
196   UINT8 modrm = FETCH();
197   if( modrm >= 0xc0 ) {
198      src = LOAD_REG16(modrm);
199      dst = LOAD_RM16(modrm);
200      dst = ADD16(dst, src);
201      STORE_RM16(modrm, dst);
202      CYCLES(CYCLES_ALU_REG_REG);
203   } else {
204      UINT32 ea = GetEA(modrm,1);
205      src = LOAD_REG16(modrm);
206      dst = READ16(ea);
207      dst = ADD16(dst, src);
208      WRITE16(ea, dst);
209      CYCLES(CYCLES_ALU_REG_MEM);
210   }
211}
212
213void i386_device::i386_add_r16_rm16()      // Opcode 0x03
214{
215   UINT16 src, dst;
216   UINT8 modrm = FETCH();
217   if( modrm >= 0xc0 ) {
218      src = LOAD_RM16(modrm);
219      dst = LOAD_REG16(modrm);
220      dst = ADD16(dst, src);
221      STORE_REG16(modrm, dst);
222      CYCLES(CYCLES_ALU_REG_REG);
223   } else {
224      UINT32 ea = GetEA(modrm,0);
225      src = READ16(ea);
226      dst = LOAD_REG16(modrm);
227      dst = ADD16(dst, src);
228      STORE_REG16(modrm, dst);
229      CYCLES(CYCLES_ALU_MEM_REG);
230   }
231}
232
233void i386_device::i386_add_ax_i16()        // Opcode 0x05
234{
235   UINT16 src, dst;
236   src = FETCH16();
237   dst = REG16(AX);
238   dst = ADD16(dst, src);
239   REG16(AX) = dst;
240   CYCLES(CYCLES_ALU_IMM_ACC);
241}
242
243void i386_device::i386_and_rm16_r16()      // Opcode 0x21
244{
245   UINT16 src, dst;
246   UINT8 modrm = FETCH();
247   if( modrm >= 0xc0 ) {
248      src = LOAD_REG16(modrm);
249      dst = LOAD_RM16(modrm);
250      dst = AND16(dst, src);
251      STORE_RM16(modrm, dst);
252      CYCLES(CYCLES_ALU_REG_REG);
253   } else {
254      UINT32 ea = GetEA(modrm,1);
255      src = LOAD_REG16(modrm);
256      dst = READ16(ea);
257      dst = AND16(dst, src);
258      WRITE16(ea, dst);
259      CYCLES(CYCLES_ALU_REG_MEM);
260   }
261}
262
263void i386_device::i386_and_r16_rm16()      // Opcode 0x23
264{
265   UINT16 src, dst;
266   UINT8 modrm = FETCH();
267   if( modrm >= 0xc0 ) {
268      src = LOAD_RM16(modrm);
269      dst = LOAD_REG16(modrm);
270      dst = AND16(dst, src);
271      STORE_REG16(modrm, dst);
272      CYCLES(CYCLES_ALU_REG_REG);
273   } else {
274      UINT32 ea = GetEA(modrm,0);
275      src = READ16(ea);
276      dst = LOAD_REG16(modrm);
277      dst = AND16(dst, src);
278      STORE_REG16(modrm, dst);
279      CYCLES(CYCLES_ALU_MEM_REG);
280   }
281}
282
283void i386_device::i386_and_ax_i16()        // Opcode 0x25
284{
285   UINT16 src, dst;
286   src = FETCH16();
287   dst = REG16(AX);
288   dst = AND16(dst, src);
289   REG16(AX) = dst;
290   CYCLES(CYCLES_ALU_IMM_ACC);
291}
292
293void i386_device::i386_bsf_r16_rm16()      // Opcode 0x0f bc
294{
295   UINT16 src, dst, temp;
296   UINT8 modrm = FETCH();
297
298   if( modrm >= 0xc0 ) {
299      src = LOAD_RM16(modrm);
300   } else {
301      UINT32 ea = GetEA(modrm,0);
302      src = READ16(ea);
303   }
304
305   dst = 0;
306
307   if( src == 0 ) {
308      m_ZF = 1;
309   } else {
310      m_ZF = 0;
311      temp = 0;
312      while( (src & (1 << temp)) == 0 ) {
313         temp++;
314         dst = temp;
315         CYCLES(CYCLES_BSF);
316      }
317      STORE_REG16(modrm, dst);
318   }
319   CYCLES(CYCLES_BSF_BASE);
320}
321
322void i386_device::i386_bsr_r16_rm16()      // Opcode 0x0f bd
323{
324   UINT16 src, dst, temp;
325   UINT8 modrm = FETCH();
326
327   if( modrm >= 0xc0 ) {
328      src = LOAD_RM16(modrm);
329   } else {
330      UINT32 ea = GetEA(modrm,0);
331      src = READ16(ea);
332   }
333
334   dst = 0;
335
336   if( src == 0 ) {
337      m_ZF = 1;
338   } else {
339      m_ZF = 0;
340      dst = temp = 15;
341      while( (src & (1 << temp)) == 0 ) {
342         temp--;
343         dst = temp;
344         CYCLES(CYCLES_BSR);
345      }
346      STORE_REG16(modrm, dst);
347   }
348   CYCLES(CYCLES_BSR_BASE);
349}
350
351
352void i386_device::i386_bt_rm16_r16()       // Opcode 0x0f a3
353{
354   UINT8 modrm = FETCH();
355   if( modrm >= 0xc0 ) {
356      UINT16 dst = LOAD_RM16(modrm);
357      UINT16 bit = LOAD_REG16(modrm);
358
359      if( dst & (1 << (bit & 0xf)) )
360         m_CF = 1;
361      else
362         m_CF = 0;
363
364      CYCLES(CYCLES_BT_REG_REG);
365   } else {
366      UINT8 segment;
367      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
368      UINT16 bit = LOAD_REG16(modrm);
369      ea += 2*(bit/16);
370      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),0);
371      bit %= 16;
372      UINT16 dst = READ16(ea);
373
374      if( dst & (1 << bit) )
375         m_CF = 1;
376      else
377         m_CF = 0;
378
379      CYCLES(CYCLES_BT_REG_MEM);
380   }
381}
382
383void i386_device::i386_btc_rm16_r16()      // Opcode 0x0f bb
384{
385   UINT8 modrm = FETCH();
386   if( modrm >= 0xc0 ) {
387      UINT16 dst = LOAD_RM16(modrm);
388      UINT16 bit = LOAD_REG16(modrm);
389
390      if( dst & (1 << (bit & 0xf)) )
391         m_CF = 1;
392      else
393         m_CF = 0;
394      dst ^= (1 << (bit & 0xf));
395
396      STORE_RM16(modrm, dst);
397      CYCLES(CYCLES_BTC_REG_REG);
398   } else {
399      UINT8 segment;
400      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
401      UINT16 bit = LOAD_REG16(modrm);
402      ea += 2*(bit/16);
403      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
404      bit %= 16;
405      UINT16 dst = READ16(ea);
406
407      if( dst & (1 << bit) )
408         m_CF = 1;
409      else
410         m_CF = 0;
411      dst ^= (1 << bit);
412
413      WRITE16(ea, dst);
414      CYCLES(CYCLES_BTC_REG_MEM);
415   }
416}
417
418void i386_device::i386_btr_rm16_r16()      // Opcode 0x0f b3
419{
420   UINT8 modrm = FETCH();
421   if( modrm >= 0xc0 ) {
422      UINT16 dst = LOAD_RM16(modrm);
423      UINT16 bit = LOAD_REG16(modrm);
424
425      if( dst & (1 << (bit & 0xf)) )
426         m_CF = 1;
427      else
428         m_CF = 0;
429      dst &= ~(1 << (bit & 0xf));
430
431      STORE_RM16(modrm, dst);
432      CYCLES(CYCLES_BTR_REG_REG);
433   } else {
434      UINT8 segment;
435      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
436      UINT16 bit = LOAD_REG16(modrm);
437      ea += 2*(bit/16);
438      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
439      bit %= 16;
440      UINT16 dst = READ16(ea);
441
442      if( dst & (1 << bit) )
443         m_CF = 1;
444      else
445         m_CF = 0;
446      dst &= ~(1 << bit);
447
448      WRITE16(ea, dst);
449      CYCLES(CYCLES_BTR_REG_MEM);
450   }
451}
452
453void i386_device::i386_bts_rm16_r16()      // Opcode 0x0f ab
454{
455   UINT8 modrm = FETCH();
456   if( modrm >= 0xc0 ) {
457      UINT16 dst = LOAD_RM16(modrm);
458      UINT16 bit = LOAD_REG16(modrm);
459
460      if( dst & (1 << (bit & 0xf)) )
461         m_CF = 1;
462      else
463         m_CF = 0;
464      dst |= (1 << (bit & 0xf));
465
466      STORE_RM16(modrm, dst);
467      CYCLES(CYCLES_BTS_REG_REG);
468   } else {
469      UINT8 segment;
470      UINT32 ea = GetNonTranslatedEA(modrm,&segment);
471      UINT16 bit = LOAD_REG16(modrm);
472      ea += 2*(bit/16);
473      ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
474      bit %= 16;
475      UINT16 dst = READ16(ea);
476
477      if( dst & (1 << bit) )
478         m_CF = 1;
479      else
480         m_CF = 0;
481      dst |= (1 << bit);
482
483      WRITE16(ea, dst);
484      CYCLES(CYCLES_BTS_REG_MEM);
485   }
486}
487
488void i386_device::i386_call_abs16()        // Opcode 0x9a
489{
490   UINT16 offset = FETCH16();
491   UINT16 ptr = FETCH16();
492
493   if( PROTECTED_MODE && !V8086_MODE)
494   {
495      i386_protected_mode_call(ptr,offset,0,0);
496   }
497   else
498   {
499      PUSH16(m_sreg[CS].selector );
500      PUSH16(m_eip );
501      m_sreg[CS].selector = ptr;
502      m_performed_intersegment_jump = 1;
503      m_eip = offset;
504      i386_load_segment_descriptor(CS);
505   }
506   CYCLES(CYCLES_CALL_INTERSEG);      /* TODO: Timing = 17 + m */
507   CHANGE_PC(m_eip);
508}
509
510void i386_device::i386_call_rel16()        // Opcode 0xe8
511{
512   INT16 disp = FETCH16();
513
514   PUSH16(m_eip );
515   if (m_sreg[CS].d)
516   {
517      m_eip += disp;
518   }
519   else
520   {
521      m_eip = (m_eip + disp) & 0xffff;
522   }
523   CHANGE_PC(m_eip);
524   CYCLES(CYCLES_CALL);       /* TODO: Timing = 7 + m */
525}
526
527void i386_device::i386_cbw()               // Opcode 0x98
528{
529   REG16(AX) = (INT16)((INT8)REG8(AL));
530   CYCLES(CYCLES_CBW);
531}
532
533void i386_device::i386_cmp_rm16_r16()      // Opcode 0x39
534{
535   UINT16 src, dst;
536   UINT8 modrm = FETCH();
537   if( modrm >= 0xc0 ) {
538      src = LOAD_REG16(modrm);
539      dst = LOAD_RM16(modrm);
540      SUB16(dst, src);
541      CYCLES(CYCLES_CMP_REG_REG);
542   } else {
543      UINT32 ea = GetEA(modrm,0);
544      src = LOAD_REG16(modrm);
545      dst = READ16(ea);
546      SUB16(dst, src);
547      CYCLES(CYCLES_CMP_REG_MEM);
548   }
549}
550
551void i386_device::i386_cmp_r16_rm16()      // Opcode 0x3b
552{
553   UINT16 src, dst;
554   UINT8 modrm = FETCH();
555   if( modrm >= 0xc0 ) {
556      src = LOAD_RM16(modrm);
557      dst = LOAD_REG16(modrm);
558      SUB16(dst, src);
559      CYCLES(CYCLES_CMP_REG_REG);
560   } else {
561      UINT32 ea = GetEA(modrm,0);
562      src = READ16(ea);
563      dst = LOAD_REG16(modrm);
564      SUB16(dst, src);
565      CYCLES(CYCLES_CMP_MEM_REG);
566   }
567}
568
569void i386_device::i386_cmp_ax_i16()        // Opcode 0x3d
570{
571   UINT16 src, dst;
572   src = FETCH16();
573   dst = REG16(AX);
574   SUB16(dst, src);
575   CYCLES(CYCLES_CMP_IMM_ACC);
576}
577
578void i386_device::i386_cmpsw()             // Opcode 0xa7
579{
580   UINT32 eas, ead;
581   UINT16 src, dst;
582   if( m_segment_prefix ) {
583      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
584   } else {
585      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
586   }
587   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
588   src = READ16(eas);
589   dst = READ16(ead);
590   SUB16(src,dst);
591   BUMP_SI(2);
592   BUMP_DI(2);
593   CYCLES(CYCLES_CMPS);
594}
595
596void i386_device::i386_cwd()               // Opcode 0x99
597{
598   if( REG16(AX) & 0x8000 ) {
599      REG16(DX) = 0xffff;
600   } else {
601      REG16(DX) = 0x0000;
602   }
603   CYCLES(CYCLES_CWD);
604}
605
606void i386_device::i386_dec_ax()            // Opcode 0x48
607{
608   REG16(AX) = DEC16(REG16(AX) );
609   CYCLES(CYCLES_DEC_REG);
610}
611
612void i386_device::i386_dec_cx()            // Opcode 0x49
613{
614   REG16(CX) = DEC16(REG16(CX) );
615   CYCLES(CYCLES_DEC_REG);
616}
617
618void i386_device::i386_dec_dx()            // Opcode 0x4a
619{
620   REG16(DX) = DEC16(REG16(DX) );
621   CYCLES(CYCLES_DEC_REG);
622}
623
624void i386_device::i386_dec_bx()            // Opcode 0x4b
625{
626   REG16(BX) = DEC16(REG16(BX) );
627   CYCLES(CYCLES_DEC_REG);
628}
629
630void i386_device::i386_dec_sp()            // Opcode 0x4c
631{
632   REG16(SP) = DEC16(REG16(SP) );
633   CYCLES(CYCLES_DEC_REG);
634}
635
636void i386_device::i386_dec_bp()            // Opcode 0x4d
637{
638   REG16(BP) = DEC16(REG16(BP) );
639   CYCLES(CYCLES_DEC_REG);
640}
641
642void i386_device::i386_dec_si()            // Opcode 0x4e
643{
644   REG16(SI) = DEC16(REG16(SI) );
645   CYCLES(CYCLES_DEC_REG);
646}
647
648void i386_device::i386_dec_di()            // Opcode 0x4f
649{
650   REG16(DI) = DEC16(REG16(DI) );
651   CYCLES(CYCLES_DEC_REG);
652}
653
654void i386_device::i386_imul_r16_rm16()     // Opcode 0x0f af
655{
656   UINT8 modrm = FETCH();
657   INT32 result;
658   INT32 src, dst;
659   if( modrm >= 0xc0 ) {
660      src = (INT32)(INT16)LOAD_RM16(modrm);
661      CYCLES(CYCLES_IMUL16_REG_REG);     /* TODO: Correct multiply timing */
662   } else {
663      UINT32 ea = GetEA(modrm,0);
664      src = (INT32)(INT16)READ16(ea);
665      CYCLES(CYCLES_IMUL16_REG_MEM);     /* TODO: Correct multiply timing */
666   }
667
668   dst = (INT32)(INT16)LOAD_REG16(modrm);
669   result = src * dst;
670
671   STORE_REG16(modrm, (UINT16)result);
672
673   m_CF = m_OF = !(result == (INT32)(INT16)result);
674}
675
676void i386_device::i386_imul_r16_rm16_i16() // Opcode 0x69
677{
678   UINT8 modrm = FETCH();
679   INT32 result;
680   INT32 src, dst;
681   if( modrm >= 0xc0 ) {
682      dst = (INT32)(INT16)LOAD_RM16(modrm);
683      CYCLES(CYCLES_IMUL16_REG_IMM_REG);     /* TODO: Correct multiply timing */
684   } else {
685      UINT32 ea = GetEA(modrm,0);
686      dst = (INT32)(INT16)READ16(ea);
687      CYCLES(CYCLES_IMUL16_MEM_IMM_REG);     /* TODO: Correct multiply timing */
688   }
689
690   src = (INT32)(INT16)FETCH16();
691   result = src * dst;
692
693   STORE_REG16(modrm, (UINT16)result);
694
695   m_CF = m_OF = !(result == (INT32)(INT16)result);
696}
697
698void i386_device::i386_imul_r16_rm16_i8()  // Opcode 0x6b
699{
700   UINT8 modrm = FETCH();
701   INT32 result;
702   INT32 src, dst;
703   if( modrm >= 0xc0 ) {
704      dst = (INT32)(INT16)LOAD_RM16(modrm);
705      CYCLES(CYCLES_IMUL16_REG_IMM_REG);     /* TODO: Correct multiply timing */
706   } else {
707      UINT32 ea = GetEA(modrm,0);
708      dst = (INT32)(INT16)READ16(ea);
709      CYCLES(CYCLES_IMUL16_MEM_IMM_REG);     /* TODO: Correct multiply timing */
710   }
711
712   src = (INT32)(INT8)FETCH();
713   result = src * dst;
714
715   STORE_REG16(modrm, (UINT16)result);
716
717   m_CF = m_OF = !(result == (INT32)(INT16)result);
718}
719
720void i386_device::i386_in_ax_i8()          // Opcode 0xe5
721{
722   UINT16 port = FETCH();
723   UINT16 data = READPORT16(port);
724   REG16(AX) = data;
725   CYCLES(CYCLES_IN_VAR);
726}
727
728void i386_device::i386_in_ax_dx()          // Opcode 0xed
729{
730   UINT16 port = REG16(DX);
731   UINT16 data = READPORT16(port);
732   REG16(AX) = data;
733   CYCLES(CYCLES_IN);
734}
735
736void i386_device::i386_inc_ax()            // Opcode 0x40
737{
738   REG16(AX) = INC16(REG16(AX) );
739   CYCLES(CYCLES_INC_REG);
740}
741
742void i386_device::i386_inc_cx()            // Opcode 0x41
743{
744   REG16(CX) = INC16(REG16(CX) );
745   CYCLES(CYCLES_INC_REG);
746}
747
748void i386_device::i386_inc_dx()            // Opcode 0x42
749{
750   REG16(DX) = INC16(REG16(DX) );
751   CYCLES(CYCLES_INC_REG);
752}
753
754void i386_device::i386_inc_bx()            // Opcode 0x43
755{
756   REG16(BX) = INC16(REG16(BX) );
757   CYCLES(CYCLES_INC_REG);
758}
759
760void i386_device::i386_inc_sp()            // Opcode 0x44
761{
762   REG16(SP) = INC16(REG16(SP) );
763   CYCLES(CYCLES_INC_REG);
764}
765
766void i386_device::i386_inc_bp()            // Opcode 0x45
767{
768   REG16(BP) = INC16(REG16(BP) );
769   CYCLES(CYCLES_INC_REG);
770}
771
772void i386_device::i386_inc_si()            // Opcode 0x46
773{
774   REG16(SI) = INC16(REG16(SI) );
775   CYCLES(CYCLES_INC_REG);
776}
777
778void i386_device::i386_inc_di()            // Opcode 0x47
779{
780   REG16(DI) = INC16(REG16(DI) );
781   CYCLES(CYCLES_INC_REG);
782}
783
784void i386_device::i386_iret16()            // Opcode 0xcf
785{
786   if( PROTECTED_MODE )
787   {
788      i386_protected_mode_iret(0);
789   }
790   else
791   {
792      /* TODO: #SS(0) exception */
793      /* TODO: #GP(0) exception */
794      m_eip = POP16();
795      m_sreg[CS].selector = POP16();
796      set_flags(POP16() );
797      i386_load_segment_descriptor(CS);
798      CHANGE_PC(m_eip);
799   }
800   CYCLES(CYCLES_IRET);
801}
802
803void i386_device::i386_ja_rel16()          // Opcode 0x0f 87
804{
805   INT16 disp = FETCH16();
806   if( m_CF == 0 && m_ZF == 0 ) {
807      if (m_sreg[CS].d)
808      {
809         m_eip += disp;
810      }
811      else
812      {
813         m_eip = (m_eip + disp) & 0xffff;
814      }
815      CHANGE_PC(m_eip);
816      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
817   } else {
818      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
819   }
820}
821
822void i386_device::i386_jbe_rel16()         // Opcode 0x0f 86
823{
824   INT16 disp = FETCH16();
825   if( m_CF != 0 || m_ZF != 0 ) {
826      if (m_sreg[CS].d)
827      {
828         m_eip += disp;
829      }
830      else
831      {
832         m_eip = (m_eip + disp) & 0xffff;
833      }
834      CHANGE_PC(m_eip);
835      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
836   } else {
837      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
838   }
839}
840
841void i386_device::i386_jc_rel16()          // Opcode 0x0f 82
842{
843   INT16 disp = FETCH16();
844   if( m_CF != 0 ) {
845      if (m_sreg[CS].d)
846      {
847         m_eip += disp;
848      }
849      else
850      {
851         m_eip = (m_eip + disp) & 0xffff;
852      }
853      CHANGE_PC(m_eip);
854      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
855   } else {
856      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
857   }
858}
859
860void i386_device::i386_jg_rel16()          // Opcode 0x0f 8f
861{
862   INT16 disp = FETCH16();
863   if( m_ZF == 0 && (m_SF == m_OF) ) {
864      if (m_sreg[CS].d)
865      {
866         m_eip += disp;
867      }
868      else
869      {
870         m_eip = (m_eip + disp) & 0xffff;
871      }
872      CHANGE_PC(m_eip);
873      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
874   } else {
875      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
876   }
877}
878
879void i386_device::i386_jge_rel16()         // Opcode 0x0f 8d
880{
881   INT16 disp = FETCH16();
882   if(m_SF == m_OF) {
883      if (m_sreg[CS].d)
884      {
885         m_eip += disp;
886      }
887      else
888      {
889         m_eip = (m_eip + disp) & 0xffff;
890      }
891      CHANGE_PC(m_eip);
892      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
893   } else {
894      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
895   }
896}
897
898void i386_device::i386_jl_rel16()          // Opcode 0x0f 8c
899{
900   INT16 disp = FETCH16();
901   if( (m_SF != m_OF) ) {
902      if (m_sreg[CS].d)
903      {
904         m_eip += disp;
905      }
906      else
907      {
908         m_eip = (m_eip + disp) & 0xffff;
909      }
910      CHANGE_PC(m_eip);
911      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
912   } else {
913      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
914   }
915}
916
917void i386_device::i386_jle_rel16()         // Opcode 0x0f 8e
918{
919   INT16 disp = FETCH16();
920   if( m_ZF != 0 || (m_SF != m_OF) ) {
921      if (m_sreg[CS].d)
922      {
923         m_eip += disp;
924      }
925      else
926      {
927         m_eip = (m_eip + disp) & 0xffff;
928      }
929      CHANGE_PC(m_eip);
930      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
931   } else {
932      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
933   }
934}
935
936void i386_device::i386_jnc_rel16()         // Opcode 0x0f 83
937{
938   INT16 disp = FETCH16();
939   if( m_CF == 0 ) {
940      if (m_sreg[CS].d)
941      {
942         m_eip += disp;
943      }
944      else
945      {
946         m_eip = (m_eip + disp) & 0xffff;
947      }
948      CHANGE_PC(m_eip);
949      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
950   } else {
951      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
952   }
953}
954
955void i386_device::i386_jno_rel16()         // Opcode 0x0f 81
956{
957   INT16 disp = FETCH16();
958   if( m_OF == 0 ) {
959      if (m_sreg[CS].d)
960      {
961         m_eip += disp;
962      }
963      else
964      {
965         m_eip = (m_eip + disp) & 0xffff;
966      }
967      CHANGE_PC(m_eip);
968      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
969   } else {
970      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
971   }
972}
973
974void i386_device::i386_jnp_rel16()         // Opcode 0x0f 8b
975{
976   INT16 disp = FETCH16();
977   if( m_PF == 0 ) {
978      if (m_sreg[CS].d)
979      {
980         m_eip += disp;
981      }
982      else
983      {
984         m_eip = (m_eip + disp) & 0xffff;
985      }
986      CHANGE_PC(m_eip);
987      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
988   } else {
989      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
990   }
991}
992
993void i386_device::i386_jns_rel16()         // Opcode 0x0f 89
994{
995   INT16 disp = FETCH16();
996   if( m_SF == 0 ) {
997      if (m_sreg[CS].d)
998      {
999         m_eip += disp;
1000      }
1001      else
1002      {
1003         m_eip = (m_eip + disp) & 0xffff;
1004      }
1005      CHANGE_PC(m_eip);
1006      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1007   } else {
1008      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1009   }
1010}
1011
1012void i386_device::i386_jnz_rel16()         // Opcode 0x0f 85
1013{
1014   INT16 disp = FETCH16();
1015   if( m_ZF == 0 ) {
1016      if (m_sreg[CS].d)
1017      {
1018         m_eip += disp;
1019      }
1020      else
1021      {
1022         m_eip = (m_eip + disp) & 0xffff;
1023      }
1024      CHANGE_PC(m_eip);
1025      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1026   } else {
1027      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1028   }
1029}
1030
1031void i386_device::i386_jo_rel16()          // Opcode 0x0f 80
1032{
1033   INT16 disp = FETCH16();
1034   if( m_OF != 0 ) {
1035      if (m_sreg[CS].d)
1036      {
1037         m_eip += disp;
1038      }
1039      else
1040      {
1041         m_eip = (m_eip + disp) & 0xffff;
1042      }
1043      CHANGE_PC(m_eip);
1044      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1045   } else {
1046      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1047   }
1048}
1049
1050void i386_device::i386_jp_rel16()          // Opcode 0x0f 8a
1051{
1052   INT16 disp = FETCH16();
1053   if( m_PF != 0 ) {
1054      if (m_sreg[CS].d)
1055      {
1056         m_eip += disp;
1057      }
1058      else
1059      {
1060         m_eip = (m_eip + disp) & 0xffff;
1061      }
1062      CHANGE_PC(m_eip);
1063      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1064   } else {
1065      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1066   }
1067}
1068
1069void i386_device::i386_js_rel16()          // Opcode 0x0f 88
1070{
1071   INT16 disp = FETCH16();
1072   if( m_SF != 0 ) {
1073      if (m_sreg[CS].d)
1074      {
1075         m_eip += disp;
1076      }
1077      else
1078      {
1079         m_eip = (m_eip + disp) & 0xffff;
1080      }
1081      CHANGE_PC(m_eip);
1082      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1083   } else {
1084      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1085   }
1086}
1087
1088void i386_device::i386_jz_rel16()          // Opcode 0x0f 84
1089{
1090   INT16 disp = FETCH16();
1091   if( m_ZF != 0 ) {
1092      if (m_sreg[CS].d)
1093      {
1094         m_eip += disp;
1095      }
1096      else
1097      {
1098         m_eip = (m_eip + disp) & 0xffff;
1099      }
1100      CHANGE_PC(m_eip);
1101      CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1102   } else {
1103      CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1104   }
1105}
1106
1107void i386_device::i386_jcxz16()            // Opcode 0xe3
1108{
1109   INT8 disp = FETCH();
1110   int val = (m_address_size)?(REG32(ECX) == 0):(REG16(CX) == 0);
1111   if( val ) {
1112      if (m_sreg[CS].d)
1113      {
1114         m_eip += disp;
1115      }
1116      else
1117      {
1118         m_eip = (m_eip + disp) & 0xffff;
1119      }
1120      CHANGE_PC(m_eip);
1121      CYCLES(CYCLES_JCXZ);       /* TODO: Timing = 9 + m */
1122   } else {
1123      CYCLES(CYCLES_JCXZ_NOBRANCH);
1124   }
1125}
1126
1127void i386_device::i386_jmp_rel16()         // Opcode 0xe9
1128{
1129   INT16 disp = FETCH16();
1130
1131   if (m_sreg[CS].d)
1132   {
1133      m_eip += disp;
1134   }
1135   else
1136   {
1137      m_eip = (m_eip + disp) & 0xffff;
1138   }
1139   CHANGE_PC(m_eip);
1140   CYCLES(CYCLES_JMP);        /* TODO: Timing = 7 + m */
1141}
1142
1143void i386_device::i386_jmp_abs16()         // Opcode 0xea
1144{
1145   UINT16 address = FETCH16();
1146   UINT16 segment = FETCH16();
1147
1148   if( PROTECTED_MODE && !V8086_MODE)
1149   {
1150      i386_protected_mode_jump(segment,address,0,0);
1151   }
1152   else
1153   {
1154      m_eip = address;
1155      m_sreg[CS].selector = segment;
1156      m_performed_intersegment_jump = 1;
1157      i386_load_segment_descriptor(CS);
1158      CHANGE_PC(m_eip);
1159   }
1160   CYCLES(CYCLES_JMP_INTERSEG);
1161}
1162
1163void i386_device::i386_lea16()             // Opcode 0x8d
1164{
1165   UINT8 modrm = FETCH();
1166   UINT32 ea = GetNonTranslatedEA(modrm,NULL);
1167   STORE_REG16(modrm, ea);
1168   CYCLES(CYCLES_LEA);
1169}
1170
1171void i386_device::i386_enter16()           // Opcode 0xc8
1172{
1173   UINT16 framesize = FETCH16();
1174   UINT8 level = FETCH() % 32;
1175   UINT8 x;
1176   UINT16 frameptr;
1177   PUSH16(REG16(BP));
1178
1179   if(!STACK_32BIT)
1180      frameptr = REG16(SP);
1181   else
1182      frameptr = REG32(ESP);
1183
1184   if(level > 0)
1185   {
1186      for(x=1;x<level-1;x++)
1187      {
1188         REG16(BP) -= 2;
1189         PUSH16(READ16(REG16(BP)));
1190      }
1191      PUSH16(frameptr);
1192   }
1193   REG16(BP) = frameptr;
1194   if(!STACK_32BIT)
1195      REG16(SP) -= framesize;
1196   else
1197      REG32(ESP) -= framesize;
1198   CYCLES(CYCLES_ENTER);
1199}
1200
1201void i386_device::i386_leave16()           // Opcode 0xc9
1202{
1203   if(!STACK_32BIT)
1204      REG16(SP) = REG16(BP);
1205   else
1206      REG32(ESP) = REG32(EBP);
1207   REG16(BP) = POP16();
1208   CYCLES(CYCLES_LEAVE);
1209}
1210
1211void i386_device::i386_lodsw()             // Opcode 0xad
1212{
1213   UINT32 eas;
1214   if( m_segment_prefix ) {
1215      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1216   } else {
1217      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1218   }
1219   REG16(AX) = READ16(eas);
1220   BUMP_SI(2);
1221   CYCLES(CYCLES_LODS);
1222}
1223
1224void i386_device::i386_loop16()            // Opcode 0xe2
1225{
1226   INT8 disp = FETCH();
1227   INT32 val = (m_address_size)?(--REG32(ECX)):(--REG16(CX));
1228   if( val != 0 ) {
1229      if (m_sreg[CS].d)
1230      {
1231         m_eip += disp;
1232      }
1233      else
1234      {
1235         m_eip = (m_eip + disp) & 0xffff;
1236      }
1237      CHANGE_PC(m_eip);
1238   }
1239   CYCLES(CYCLES_LOOP);       /* TODO: Timing = 11 + m */
1240}
1241
1242void i386_device::i386_loopne16()          // Opcode 0xe0
1243{
1244   INT8 disp = FETCH();
1245   INT32 val = (m_address_size)?(--REG32(ECX)):(--REG16(CX));
1246   if( val != 0 && m_ZF == 0 ) {
1247      if (m_sreg[CS].d)
1248      {
1249         m_eip += disp;
1250      }
1251      else
1252      {
1253         m_eip = (m_eip + disp) & 0xffff;
1254      }
1255      CHANGE_PC(m_eip);
1256   }
1257   CYCLES(CYCLES_LOOPNZ);     /* TODO: Timing = 11 + m */
1258}
1259
1260void i386_device::i386_loopz16()           // Opcode 0xe1
1261{
1262   INT8 disp = FETCH();
1263   INT32 val = (m_address_size)?(--REG32(ECX)):(--REG16(CX));
1264   if( val != 0 && m_ZF != 0 ) {
1265      if (m_sreg[CS].d)
1266      {
1267         m_eip += disp;
1268      }
1269      else
1270      {
1271         m_eip = (m_eip + disp) & 0xffff;
1272      }
1273      CHANGE_PC(m_eip);
1274   }
1275   CYCLES(CYCLES_LOOPZ);      /* TODO: Timing = 11 + m */
1276}
1277
1278void i386_device::i386_mov_rm16_r16()      // Opcode 0x89
1279{
1280   UINT16 src;
1281   UINT8 modrm = FETCH();
1282   if( modrm >= 0xc0 ) {
1283      src = LOAD_REG16(modrm);
1284      STORE_RM16(modrm, src);
1285      CYCLES(CYCLES_MOV_REG_REG);
1286   } else {
1287      UINT32 ea = GetEA(modrm,1);
1288      src = LOAD_REG16(modrm);
1289      WRITE16(ea, src);
1290      CYCLES(CYCLES_MOV_REG_MEM);
1291   }
1292}
1293
1294void i386_device::i386_mov_r16_rm16()      // Opcode 0x8b
1295{
1296   UINT16 src;
1297   UINT8 modrm = FETCH();
1298   if( modrm >= 0xc0 ) {
1299      src = LOAD_RM16(modrm);
1300      STORE_REG16(modrm, src);
1301      CYCLES(CYCLES_MOV_REG_REG);
1302   } else {
1303      UINT32 ea = GetEA(modrm,0);
1304      src = READ16(ea);
1305      STORE_REG16(modrm, src);
1306      CYCLES(CYCLES_MOV_MEM_REG);
1307   }
1308}
1309
1310void i386_device::i386_mov_rm16_i16()      // Opcode 0xc7
1311{
1312   UINT8 modrm = FETCH();
1313   if( modrm >= 0xc0 ) {
1314      UINT16 value = FETCH16();
1315      STORE_RM16(modrm, value);
1316      CYCLES(CYCLES_MOV_IMM_REG);
1317   } else {
1318      UINT32 ea = GetEA(modrm,1);
1319      UINT16 value = FETCH16();
1320      WRITE16(ea, value);
1321      CYCLES(CYCLES_MOV_IMM_MEM);
1322   }
1323}
1324
1325void i386_device::i386_mov_ax_m16()        // Opcode 0xa1
1326{
1327   UINT32 offset, ea;
1328   if( m_address_size ) {
1329      offset = FETCH32();
1330   } else {
1331      offset = FETCH16();
1332   }
1333   /* TODO: Not sure if this is correct... */
1334   if( m_segment_prefix ) {
1335      ea = i386_translate(m_segment_override, offset, 0 );
1336   } else {
1337      ea = i386_translate(DS, offset, 0 );
1338   }
1339   REG16(AX) = READ16(ea);
1340   CYCLES(CYCLES_MOV_MEM_ACC);
1341}
1342
1343void i386_device::i386_mov_m16_ax()        // Opcode 0xa3
1344{
1345   UINT32 offset, ea;
1346   if( m_address_size ) {
1347      offset = FETCH32();
1348   } else {
1349      offset = FETCH16();
1350   }
1351   /* TODO: Not sure if this is correct... */
1352   if( m_segment_prefix ) {
1353      ea = i386_translate(m_segment_override, offset, 1 );
1354   } else {
1355      ea = i386_translate(DS, offset, 1 );
1356   }
1357   WRITE16(ea, REG16(AX) );
1358   CYCLES(CYCLES_MOV_ACC_MEM);
1359}
1360
1361void i386_device::i386_mov_ax_i16()        // Opcode 0xb8
1362{
1363   REG16(AX) = FETCH16();
1364   CYCLES(CYCLES_MOV_IMM_REG);
1365}
1366
1367void i386_device::i386_mov_cx_i16()        // Opcode 0xb9
1368{
1369   REG16(CX) = FETCH16();
1370   CYCLES(CYCLES_MOV_IMM_REG);
1371}
1372
1373void i386_device::i386_mov_dx_i16()        // Opcode 0xba
1374{
1375   REG16(DX) = FETCH16();
1376   CYCLES(CYCLES_MOV_IMM_REG);
1377}
1378
1379void i386_device::i386_mov_bx_i16()        // Opcode 0xbb
1380{
1381   REG16(BX) = FETCH16();
1382   CYCLES(CYCLES_MOV_IMM_REG);
1383}
1384
1385void i386_device::i386_mov_sp_i16()        // Opcode 0xbc
1386{
1387   REG16(SP) = FETCH16();
1388   CYCLES(CYCLES_MOV_IMM_REG);
1389}
1390
1391void i386_device::i386_mov_bp_i16()        // Opcode 0xbd
1392{
1393   REG16(BP) = FETCH16();
1394   CYCLES(CYCLES_MOV_IMM_REG);
1395}
1396
1397void i386_device::i386_mov_si_i16()        // Opcode 0xbe
1398{
1399   REG16(SI) = FETCH16();
1400   CYCLES(CYCLES_MOV_IMM_REG);
1401}
1402
1403void i386_device::i386_mov_di_i16()        // Opcode 0xbf
1404{
1405   REG16(DI) = FETCH16();
1406   CYCLES(CYCLES_MOV_IMM_REG);
1407}
1408
1409void i386_device::i386_movsw()             // Opcode 0xa5
1410{
1411   UINT32 eas, ead;
1412   UINT16 v;
1413   if( m_segment_prefix ) {
1414      eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1415   } else {
1416      eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1417   }
1418   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
1419   v = READ16(eas);
1420   WRITE16(ead, v);
1421   BUMP_SI(2);
1422   BUMP_DI(2);
1423   CYCLES(CYCLES_MOVS);
1424}
1425
1426void i386_device::i386_movsx_r16_rm8()     // Opcode 0x0f be
1427{
1428   UINT8 modrm = FETCH();
1429   if( modrm >= 0xc0 ) {
1430      INT16 src = (INT8)LOAD_RM8(modrm);
1431      STORE_REG16(modrm, src);
1432      CYCLES(CYCLES_MOVSX_REG_REG);
1433   } else {
1434      UINT32 ea = GetEA(modrm,0);
1435      INT16 src = (INT8)READ8(ea);
1436      STORE_REG16(modrm, src);
1437      CYCLES(CYCLES_MOVSX_MEM_REG);
1438   }
1439}
1440
1441void i386_device::i386_movzx_r16_rm8()     // Opcode 0x0f b6
1442{
1443   UINT8 modrm = FETCH();
1444   if( modrm >= 0xc0 ) {
1445      UINT16 src = (UINT8)LOAD_RM8(modrm);
1446      STORE_REG16(modrm, src);
1447      CYCLES(CYCLES_MOVZX_REG_REG);
1448   } else {
1449      UINT32 ea = GetEA(modrm,0);
1450      UINT16 src = (UINT8)READ8(ea);
1451      STORE_REG16(modrm, src);
1452      CYCLES(CYCLES_MOVZX_MEM_REG);
1453   }
1454}
1455
1456void i386_device::i386_or_rm16_r16()       // Opcode 0x09
1457{
1458   UINT16 src, dst;
1459   UINT8 modrm = FETCH();
1460   if( modrm >= 0xc0 ) {
1461      src = LOAD_REG16(modrm);
1462      dst = LOAD_RM16(modrm);
1463      dst = OR16(dst, src);
1464      STORE_RM16(modrm, dst);
1465      CYCLES(CYCLES_ALU_REG_REG);
1466   } else {
1467      UINT32 ea = GetEA(modrm,1);
1468      src = LOAD_REG16(modrm);
1469      dst = READ16(ea);
1470      dst = OR16(dst, src);
1471      WRITE16(ea, dst);
1472      CYCLES(CYCLES_ALU_REG_MEM);
1473   }
1474}
1475
1476void i386_device::i386_or_r16_rm16()       // Opcode 0x0b
1477{
1478   UINT16 src, dst;
1479   UINT8 modrm = FETCH();
1480   if( modrm >= 0xc0 ) {
1481      src = LOAD_RM16(modrm);
1482      dst = LOAD_REG16(modrm);
1483      dst = OR16(dst, src);
1484      STORE_REG16(modrm, dst);
1485      CYCLES(CYCLES_ALU_REG_REG);
1486   } else {
1487      UINT32 ea = GetEA(modrm,0);
1488      src = READ16(ea);
1489      dst = LOAD_REG16(modrm);
1490      dst = OR16(dst, src);
1491      STORE_REG16(modrm, dst);
1492      CYCLES(CYCLES_ALU_MEM_REG);
1493   }
1494}
1495
1496void i386_device::i386_or_ax_i16()         // Opcode 0x0d
1497{
1498   UINT16 src, dst;
1499   src = FETCH16();
1500   dst = REG16(AX);
1501   dst = OR16(dst, src);
1502   REG16(AX) = dst;
1503   CYCLES(CYCLES_ALU_IMM_ACC);
1504}
1505
1506void i386_device::i386_out_ax_i8()         // Opcode 0xe7
1507{
1508   UINT16 port = FETCH();
1509   UINT16 data = REG16(AX);
1510   WRITEPORT16(port, data);
1511   CYCLES(CYCLES_OUT_VAR);
1512}
1513
1514void i386_device::i386_out_ax_dx()         // Opcode 0xef
1515{
1516   UINT16 port = REG16(DX);
1517   UINT16 data = REG16(AX);
1518   WRITEPORT16(port, data);
1519   CYCLES(CYCLES_OUT);
1520}
1521
1522void i386_device::i386_pop_ax()            // Opcode 0x58
1523{
1524   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1525   if(i386_limit_check(SS,offset+1) == 0)
1526      REG16(AX) = POP16();
1527   else
1528      FAULT(FAULT_SS,0)
1529   CYCLES(CYCLES_POP_REG_SHORT);
1530}
1531
1532void i386_device::i386_pop_cx()            // Opcode 0x59
1533{
1534   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1535   if(i386_limit_check(SS,offset+1) == 0)
1536      REG16(CX) = POP16();
1537   else
1538      FAULT(FAULT_SS,0)
1539   CYCLES(CYCLES_POP_REG_SHORT);
1540}
1541
1542void i386_device::i386_pop_dx()            // Opcode 0x5a
1543{
1544   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1545   if(i386_limit_check(SS,offset+1) == 0)
1546      REG16(DX) = POP16();
1547   else
1548      FAULT(FAULT_SS,0)
1549   CYCLES(CYCLES_POP_REG_SHORT);
1550}
1551
1552void i386_device::i386_pop_bx()            // Opcode 0x5b
1553{
1554   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1555   if(i386_limit_check(SS,offset+1) == 0)
1556      REG16(BX) = POP16();
1557   else
1558      FAULT(FAULT_SS,0)
1559   CYCLES(CYCLES_POP_REG_SHORT);
1560}
1561
1562void i386_device::i386_pop_sp()            // Opcode 0x5c
1563{
1564   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1565   if(i386_limit_check(SS,offset+1) == 0)
1566      REG16(SP) = POP16();
1567   else
1568      FAULT(FAULT_SS,0)
1569   CYCLES(CYCLES_POP_REG_SHORT);
1570}
1571
1572void i386_device::i386_pop_bp()            // Opcode 0x5d
1573{
1574   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1575   if(i386_limit_check(SS,offset+1) == 0)
1576      REG16(BP) = POP16();
1577   else
1578      FAULT(FAULT_SS,0)
1579   CYCLES(CYCLES_POP_REG_SHORT);
1580}
1581
1582void i386_device::i386_pop_si()            // Opcode 0x5e
1583{
1584   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1585   if(i386_limit_check(SS,offset+1) == 0)
1586      REG16(SI) = POP16();
1587   else
1588      FAULT(FAULT_SS,0)
1589   CYCLES(CYCLES_POP_REG_SHORT);
1590}
1591
1592void i386_device::i386_pop_di()            // Opcode 0x5f
1593{
1594   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1595   if(i386_limit_check(SS,offset+1) == 0)
1596      REG16(DI) = POP16();
1597   else
1598      FAULT(FAULT_SS,0)
1599   CYCLES(CYCLES_POP_REG_SHORT);
1600}
1601
1602bool i386_device::i386_pop_seg16(int segment)
1603{
1604   UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1605   UINT16 value;
1606   bool fault;
1607   if(i386_limit_check(SS,offset+1) == 0)
1608   {
1609      ea = i386_translate(SS, offset, 0);
1610      value = READ16(ea);
1611      i386_sreg_load(value, segment, &fault);
1612      if(fault) return false;
1613      if(STACK_32BIT)
1614         REG32(ESP) = offset + 2;
1615      else
1616         REG16(SP) = offset + 2;
1617   }
1618   else
1619   {
1620      m_ext = 1;
1621      i386_trap_with_error(FAULT_SS,0,0,0);
1622      return false;
1623   }
1624   CYCLES(CYCLES_POP_SREG);
1625   return true;
1626}
1627
1628void i386_device::i386_pop_ds16()          // Opcode 0x1f
1629{
1630   i386_pop_seg16(DS);
1631}
1632
1633void i386_device::i386_pop_es16()          // Opcode 0x07
1634{
1635   i386_pop_seg16(ES);
1636}
1637
1638void i386_device::i386_pop_fs16()          // Opcode 0x0f a1
1639{
1640   i386_pop_seg16(FS);
1641}
1642
1643void i386_device::i386_pop_gs16()          // Opcode 0x0f a9
1644{
1645   i386_pop_seg16(GS);
1646}
1647
1648void i386_device::i386_pop_ss16()          // Opcode 0x17
1649{
1650   if(!i386_pop_seg16(SS)) return;
1651   if(m_IF != 0) // if external interrupts are enabled
1652   {
1653      m_IF = 0;  // reset IF for the next instruction
1654      m_delayed_interrupt_enable = 1;
1655   }
1656}
1657
1658void i386_device::i386_pop_rm16()          // Opcode 0x8f
1659{
1660   UINT8 modrm = FETCH();
1661   UINT16 value;
1662   UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1663
1664   if(i386_limit_check(SS,offset+1) == 0)
1665   {
1666      UINT32 temp_sp = REG32(ESP);
1667      value = POP16();
1668
1669      if( modrm >= 0xc0 ) {
1670         STORE_RM16(modrm, value);
1671      } else {
1672         ea = GetEA(modrm,1);
1673         try
1674         {
1675            WRITE16(ea, value);
1676         }
1677         catch(UINT64 e)
1678         {
1679            REG32(ESP) = temp_sp;
1680            throw e;
1681         }
1682      }
1683   }
1684   else
1685      FAULT(FAULT_SS,0)
1686   CYCLES(CYCLES_POP_RM);
1687}
1688
1689void i386_device::i386_popa()              // Opcode 0x61
1690{
1691   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1692
1693   if(i386_limit_check(SS,offset+15) == 0)
1694   {
1695      REG16(DI) = POP16();
1696      REG16(SI) = POP16();
1697      REG16(BP) = POP16();
1698      REG16(SP) += 2;
1699      REG16(BX) = POP16();
1700      REG16(DX) = POP16();
1701      REG16(CX) = POP16();
1702      REG16(AX) = POP16();
1703   }
1704   else
1705      FAULT(FAULT_SS,0)
1706   CYCLES(CYCLES_POPA);
1707}
1708
1709void i386_device::i386_popf()              // Opcode 0x9d
1710{
1711   UINT32 value;
1712   UINT32 current = get_flags();
1713   UINT8 IOPL = (current >> 12) & 0x03;
1714   UINT32 mask = 0x7fd5;
1715   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1716
1717   // IOPL can only change if CPL is 0
1718   if(m_CPL != 0)
1719      mask &= ~0x00003000;
1720
1721   // IF can only change if CPL is at least as privileged as IOPL
1722   if(m_CPL > IOPL)
1723      mask &= ~0x00000200;
1724
1725   if(V8086_MODE)
1726   {
1727      if(IOPL < 3)
1728      {
1729         logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",m_pc);
1730         FAULT(FAULT_GP,0)  // #GP(0)
1731      }
1732      mask &= ~0x00003000;  // IOPL cannot be changed while in V8086 mode
1733   }
1734
1735   if(i386_limit_check(SS,offset+1) == 0)
1736   {
1737      value = POP16();
1738      set_flags((current & ~mask) | (value & mask));  // mask out reserved bits
1739   }
1740   else
1741      FAULT(FAULT_SS,0)
1742   CYCLES(CYCLES_POPF);
1743}
1744
1745void i386_device::i386_push_ax()           // Opcode 0x50
1746{
1747   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1748   if(i386_limit_check(SS,offset-2) == 0)
1749      PUSH16(REG16(AX) );
1750   else
1751      FAULT(FAULT_SS,0)
1752   CYCLES(CYCLES_PUSH_REG_SHORT);
1753}
1754
1755void i386_device::i386_push_cx()           // Opcode 0x51
1756{
1757   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1758   if(i386_limit_check(SS,offset-2) == 0)
1759      PUSH16(REG16(CX) );
1760   else
1761      FAULT(FAULT_SS,0)
1762   CYCLES(CYCLES_PUSH_REG_SHORT);
1763}
1764
1765void i386_device::i386_push_dx()           // Opcode 0x52
1766{
1767   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1768   if(i386_limit_check(SS,offset-2) == 0)
1769      PUSH16(REG16(DX) );
1770   else
1771      FAULT(FAULT_SS,0)
1772   CYCLES(CYCLES_PUSH_REG_SHORT);
1773}
1774
1775void i386_device::i386_push_bx()           // Opcode 0x53
1776{
1777   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1778   if(i386_limit_check(SS,offset-2) == 0)
1779      PUSH16(REG16(BX) );
1780   else
1781      FAULT(FAULT_SS,0)
1782   CYCLES(CYCLES_PUSH_REG_SHORT);
1783}
1784
1785void i386_device::i386_push_sp()           // Opcode 0x54
1786{
1787   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1788   if(i386_limit_check(SS,offset-2) == 0)
1789      PUSH16(REG16(SP) );
1790   else
1791      FAULT(FAULT_SS,0)
1792   CYCLES(CYCLES_PUSH_REG_SHORT);
1793}
1794
1795void i386_device::i386_push_bp()           // Opcode 0x55
1796{
1797   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1798   if(i386_limit_check(SS,offset-2) == 0)
1799      PUSH16(REG16(BP) );
1800   else
1801      FAULT(FAULT_SS,0)
1802   CYCLES(CYCLES_PUSH_REG_SHORT);
1803}
1804
1805void i386_device::i386_push_si()           // Opcode 0x56
1806{
1807   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1808   if(i386_limit_check(SS,offset-2) == 0)
1809      PUSH16(REG16(SI) );
1810   else
1811      FAULT(FAULT_SS,0)
1812   CYCLES(CYCLES_PUSH_REG_SHORT);
1813}
1814
1815void i386_device::i386_push_di()           // Opcode 0x57
1816{
1817   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1818   if(i386_limit_check(SS,offset-2) == 0)
1819      PUSH16(REG16(DI) );
1820   else
1821      FAULT(FAULT_SS,0)
1822   CYCLES(CYCLES_PUSH_REG_SHORT);
1823}
1824
1825void i386_device::i386_push_cs16()         // Opcode 0x0e
1826{
1827   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1828   if(i386_limit_check(SS,offset-2) == 0)
1829      PUSH16(m_sreg[CS].selector );
1830   else
1831      FAULT(FAULT_SS,0)
1832   CYCLES(CYCLES_PUSH_SREG);
1833}
1834
1835void i386_device::i386_push_ds16()         // Opcode 0x1e
1836{
1837   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1838   if(i386_limit_check(SS,offset-2) == 0)
1839      PUSH16(m_sreg[DS].selector );
1840   else
1841      FAULT(FAULT_SS,0)
1842   CYCLES(CYCLES_PUSH_SREG);
1843}
1844
1845void i386_device::i386_push_es16()         // Opcode 0x06
1846{
1847   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1848   if(i386_limit_check(SS,offset-2) == 0)
1849      PUSH16(m_sreg[ES].selector );
1850   else
1851      FAULT(FAULT_SS,0)
1852   CYCLES(CYCLES_PUSH_SREG);
1853}
1854
1855void i386_device::i386_push_fs16()         // Opcode 0x0f a0
1856{
1857   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1858   if(i386_limit_check(SS,offset-2) == 0)
1859      PUSH16(m_sreg[FS].selector );
1860   else
1861      FAULT(FAULT_SS,0)
1862   CYCLES(CYCLES_PUSH_SREG);
1863}
1864
1865void i386_device::i386_push_gs16()         // Opcode 0x0f a8
1866{
1867   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1868   if(i386_limit_check(SS,offset-2) == 0)
1869      PUSH16(m_sreg[GS].selector );
1870   else
1871      FAULT(FAULT_SS,0)
1872   CYCLES(CYCLES_PUSH_SREG);
1873}
1874
1875void i386_device::i386_push_ss16()         // Opcode 0x16
1876{
1877   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1878   if(i386_limit_check(SS,offset-2) == 0)
1879      PUSH16(m_sreg[SS].selector );
1880   else
1881      FAULT(FAULT_SS,0)
1882   CYCLES(CYCLES_PUSH_SREG);
1883}
1884
1885void i386_device::i386_push_i16()          // Opcode 0x68
1886{
1887   UINT16 value = FETCH16();
1888   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1889   if(i386_limit_check(SS,offset-2) == 0)
1890      PUSH16(value);
1891   else
1892      FAULT(FAULT_SS,0)
1893   CYCLES(CYCLES_PUSH_IMM);
1894}
1895
1896void i386_device::i386_pusha()             // Opcode 0x60
1897{
1898   UINT16 temp = REG16(SP);
1899   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1900   if(i386_limit_check(SS,offset-16) == 0)
1901   {
1902      PUSH16(REG16(AX) );
1903      PUSH16(REG16(CX) );
1904      PUSH16(REG16(DX) );
1905      PUSH16(REG16(BX) );
1906      PUSH16(temp );
1907      PUSH16(REG16(BP) );
1908      PUSH16(REG16(SI) );
1909      PUSH16(REG16(DI) );
1910   }
1911   else
1912      FAULT(FAULT_SS,0)
1913   CYCLES(CYCLES_PUSHA);
1914}
1915
1916void i386_device::i386_pushf()             // Opcode 0x9c
1917{
1918   UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1919   if(i386_limit_check(SS,offset-2) == 0)
1920      PUSH16(get_flags() & 0xffff );
1921   else
1922      FAULT(FAULT_SS,0)
1923   CYCLES(CYCLES_PUSHF);
1924}
1925
1926void i386_device::i386_ret_near16_i16()    // Opcode 0xc2
1927{
1928   INT16 disp = FETCH16();
1929   m_eip = POP16();
1930   REG16(SP) += disp;
1931   CHANGE_PC(m_eip);
1932   CYCLES(CYCLES_RET_IMM);        /* TODO: Timing = 10 + m */
1933}
1934
1935void i386_device::i386_ret_near16()        // Opcode 0xc3
1936{
1937   m_eip = POP16();
1938   CHANGE_PC(m_eip);
1939   CYCLES(CYCLES_RET);        /* TODO: Timing = 10 + m */
1940}
1941
1942void i386_device::i386_sbb_rm16_r16()      // Opcode 0x19
1943{
1944   UINT16 src, dst;
1945   UINT8 modrm = FETCH();
1946   if( modrm >= 0xc0 ) {
1947      src = LOAD_REG16(modrm);
1948      dst = LOAD_RM16(modrm);
1949      dst = SBB16(dst, src, m_CF);
1950      STORE_RM16(modrm, dst);
1951      CYCLES(CYCLES_ALU_REG_REG);
1952   } else {
1953      UINT32 ea = GetEA(modrm,1);
1954      src = LOAD_REG16(modrm);
1955      dst = READ16(ea);
1956      dst = SBB16(dst, src, m_CF);
1957      WRITE16(ea, dst);
1958      CYCLES(CYCLES_ALU_REG_MEM);
1959   }
1960}
1961
1962void i386_device::i386_sbb_r16_rm16()      // Opcode 0x1b
1963{
1964   UINT16 src, dst;
1965   UINT8 modrm = FETCH();
1966   if( modrm >= 0xc0 ) {
1967      src = LOAD_RM16(modrm);
1968      dst = LOAD_REG16(modrm);
1969      dst = SBB16(dst, src, m_CF);
1970      STORE_REG16(modrm, dst);
1971      CYCLES(CYCLES_ALU_REG_REG);
1972   } else {
1973      UINT32 ea = GetEA(modrm,0);
1974      src = READ16(ea);
1975      dst = LOAD_REG16(modrm);
1976      dst = SBB16(dst, src, m_CF);
1977      STORE_REG16(modrm, dst);
1978      CYCLES(CYCLES_ALU_MEM_REG);
1979   }
1980}
1981
1982void i386_device::i386_sbb_ax_i16()        // Opcode 0x1d
1983{
1984   UINT16 src, dst;
1985   src = FETCH16();
1986   dst = REG16(AX);
1987   dst = SBB16(dst, src, m_CF);
1988   REG16(AX) = dst;
1989   CYCLES(CYCLES_ALU_IMM_ACC);
1990}
1991
1992void i386_device::i386_scasw()             // Opcode 0xaf
1993{
1994   UINT32 eas;
1995   UINT16 src, dst;
1996   eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
1997   src = READ16(eas);
1998   dst = REG16(AX);
1999   SUB16(dst, src);
2000   BUMP_DI(2);
2001   CYCLES(CYCLES_SCAS);
2002}
2003
2004void i386_device::i386_shld16_i8()         // Opcode 0x0f a4
2005{
2006   UINT8 modrm = FETCH();
2007   if( modrm >= 0xc0 ) {
2008      UINT16 dst = LOAD_RM16(modrm);
2009      UINT16 upper = LOAD_REG16(modrm);
2010      UINT8 shift = FETCH();
2011      shift &= 31;
2012      if( shift == 0 ) {
2013      } else if( shift > 15 ) {
2014         m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2015         // ppro and above should be (dst >> (32-shift))
2016         dst = (upper << (shift-16)) | (upper >> (32-shift));
2017         m_OF = m_CF ^ (dst >> 15);
2018         SetSZPF16(dst);
2019      } else {
2020         m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2021         dst = (dst << shift) | (upper >> (16-shift));
2022         m_OF = m_CF ^ (dst >> 15);
2023         SetSZPF16(dst);
2024      }
2025      STORE_RM16(modrm, dst);
2026      CYCLES(CYCLES_SHLD_REG);
2027   } else {
2028      UINT32 ea = GetEA(modrm,1);
2029      UINT16 dst = READ16(ea);
2030      UINT16 upper = LOAD_REG16(modrm);
2031      UINT8 shift = FETCH();
2032      shift &= 31;
2033      if( shift == 0 ) {
2034      } else if( shift > 15 ) {
2035         m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2036         dst = (upper << (shift-16)) | (upper >> (32-shift));
2037         m_OF = m_CF ^ (dst >> 15);
2038         SetSZPF16(dst);
2039      } else {
2040         m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2041         dst = (dst << shift) | (upper >> (16-shift));
2042         m_OF = m_CF ^ (dst >> 15);
2043         SetSZPF16(dst);
2044      }
2045      WRITE16(ea, dst);
2046      CYCLES(CYCLES_SHLD_MEM);
2047   }
2048}
2049
2050void i386_device::i386_shld16_cl()         // Opcode 0x0f a5
2051{
2052   UINT8 modrm = FETCH();
2053   if( modrm >= 0xc0 ) {
2054      UINT16 dst = LOAD_RM16(modrm);
2055      UINT16 upper = LOAD_REG16(modrm);
2056      UINT8 shift = REG8(CL);
2057      shift &= 31;
2058      if( shift == 0 ) {
2059      } else if( shift > 15 ) {
2060         m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2061         dst = (upper << (shift-16)) | (upper >> (32-shift));
2062         m_OF = m_CF ^ (dst >> 15);
2063         SetSZPF16(dst);
2064      } else {
2065         m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2066         dst = (dst << shift) | (upper >> (16-shift));
2067         m_OF = m_CF ^ (dst >> 15);
2068         SetSZPF16(dst);
2069      }
2070      STORE_RM16(modrm, dst);
2071      CYCLES(CYCLES_SHLD_REG);
2072   } else {
2073      UINT32 ea = GetEA(modrm,1);
2074      UINT16 dst = READ16(ea);
2075      UINT16 upper = LOAD_REG16(modrm);
2076      UINT8 shift = REG8(CL);
2077      shift &= 31;
2078      if( shift == 0 ) {
2079      } else if( shift > 15 ) {
2080         m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2081         dst = (upper << (shift-16)) | (upper >> (32-shift));
2082         m_OF = m_CF ^ (dst >> 15);
2083         SetSZPF16(dst);
2084      } else {
2085         m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2086         dst = (dst << shift) | (upper >> (16-shift));
2087         m_OF = m_CF ^ (dst >> 15);
2088         SetSZPF16(dst);
2089      }
2090      WRITE16(ea, dst);
2091      CYCLES(CYCLES_SHLD_MEM);
2092   }
2093}
2094
2095void i386_device::i386_shrd16_i8()         // Opcode 0x0f ac
2096{
2097   UINT8 modrm = FETCH();
2098   if( modrm >= 0xc0 ) {
2099      UINT16 dst = LOAD_RM16(modrm);
2100      UINT16 upper = LOAD_REG16(modrm);
2101      UINT8 shift = FETCH();
2102      shift &= 31;
2103      if( shift == 0) {
2104      } else if( shift > 15 ) {
2105         m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2106         dst = (upper >> (shift-16)) | (upper << (32-shift));
2107         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2108         SetSZPF16(dst);
2109      } else {
2110         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2111         dst = (dst >> shift) | (upper << (16-shift));
2112         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2113         SetSZPF16(dst);
2114      }
2115      STORE_RM16(modrm, dst);
2116      CYCLES(CYCLES_SHRD_REG);
2117   } else {
2118      UINT32 ea = GetEA(modrm,1);
2119      UINT16 dst = READ16(ea);
2120      UINT16 upper = LOAD_REG16(modrm);
2121      UINT8 shift = FETCH();
2122      shift &= 31;
2123      if( shift == 0) {
2124      } else if( shift > 15 ) {
2125         m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2126         dst = (upper >> (shift-16)) | (upper << (32-shift));
2127         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2128         SetSZPF16(dst);
2129      } else {
2130         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2131         dst = (dst >> shift) | (upper << (16-shift));
2132         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2133         SetSZPF16(dst);
2134      }
2135      WRITE16(ea, dst);
2136      CYCLES(CYCLES_SHRD_MEM);
2137   }
2138}
2139
2140void i386_device::i386_shrd16_cl()         // Opcode 0x0f ad
2141{
2142   UINT8 modrm = FETCH();
2143   if( modrm >= 0xc0 ) {
2144      UINT16 dst = LOAD_RM16(modrm);
2145      UINT16 upper = LOAD_REG16(modrm);
2146      UINT8 shift = REG8(CL);
2147      shift &= 31;
2148      if( shift == 0) {
2149      } else if( shift > 15 ) {
2150         m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2151         dst = (upper >> (shift-16)) | (upper << (32-shift));
2152         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2153         SetSZPF16(dst);
2154      } else {
2155         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2156         dst = (dst >> shift) | (upper << (16-shift));
2157         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2158         SetSZPF16(dst);
2159      }
2160      STORE_RM16(modrm, dst);
2161      CYCLES(CYCLES_SHRD_REG);
2162   } else {
2163      UINT32 ea = GetEA(modrm,1);
2164      UINT16 dst = READ16(ea);
2165      UINT16 upper = LOAD_REG16(modrm);
2166      UINT8 shift = REG8(CL);
2167      shift &= 31;
2168      if( shift == 0) {
2169      } else if( shift > 15 ) {
2170         m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2171         dst = (upper >> (shift-16)) | (upper << (32-shift));
2172         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2173         SetSZPF16(dst);
2174      } else {
2175         m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2176         dst = (dst >> shift) | (upper << (16-shift));
2177         m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2178         SetSZPF16(dst);
2179      }
2180      WRITE16(ea, dst);
2181      CYCLES(CYCLES_SHRD_MEM);
2182   }
2183}
2184
2185void i386_device::i386_stosw()             // Opcode 0xab
2186{
2187   UINT32 ead;
2188   ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
2189   WRITE16(ead, REG16(AX));
2190   BUMP_DI(2);
2191   CYCLES(CYCLES_STOS);
2192}
2193
2194void i386_device::i386_sub_rm16_r16()      // Opcode 0x29
2195{
2196   UINT16 src, dst;
2197   UINT8 modrm = FETCH();
2198   if( modrm >= 0xc0 ) {
2199      src = LOAD_REG16(modrm);
2200      dst = LOAD_RM16(modrm);
2201      dst = SUB16(dst, src);
2202      STORE_RM16(modrm, dst);
2203      CYCLES(CYCLES_ALU_REG_REG);
2204   } else {
2205      UINT32 ea = GetEA(modrm,1);
2206      src = LOAD_REG16(modrm);
2207      dst = READ16(ea);
2208      dst = SUB16(dst, src);
2209      WRITE16(ea, dst);
2210      CYCLES(CYCLES_ALU_REG_MEM);
2211   }
2212}
2213
2214void i386_device::i386_sub_r16_rm16()      // Opcode 0x2b
2215{
2216   UINT16 src, dst;
2217   UINT8 modrm = FETCH();
2218   if( modrm >= 0xc0 ) {
2219      src = LOAD_RM16(modrm);
2220      dst = LOAD_REG16(modrm);
2221      dst = SUB16(dst, src);
2222      STORE_REG16(modrm, dst);
2223      CYCLES(CYCLES_ALU_REG_REG);
2224   } else {
2225      UINT32 ea = GetEA(modrm,0);
2226      src = READ16(ea);
2227      dst = LOAD_REG16(modrm);
2228      dst = SUB16(dst, src);
2229      STORE_REG16(modrm, dst);
2230      CYCLES(CYCLES_ALU_MEM_REG);
2231   }
2232}
2233
2234void i386_device::i386_sub_ax_i16()        // Opcode 0x2d
2235{
2236   UINT16 src, dst;
2237   src = FETCH16();
2238   dst = REG16(AX);
2239   dst = SUB16(dst, src);
2240   REG16(AX) = dst;
2241   CYCLES(CYCLES_ALU_IMM_ACC);
2242}
2243
2244void i386_device::i386_test_ax_i16()       // Opcode 0xa9
2245{
2246   UINT16 src = FETCH16();
2247   UINT16 dst = REG16(AX);
2248   dst = src & dst;
2249   SetSZPF16(dst);
2250   m_CF = 0;
2251   m_OF = 0;
2252   CYCLES(CYCLES_TEST_IMM_ACC);
2253}
2254
2255void i386_device::i386_test_rm16_r16()     // Opcode 0x85
2256{
2257   UINT16 src, dst;
2258   UINT8 modrm = FETCH();
2259   if( modrm >= 0xc0 ) {
2260      src = LOAD_REG16(modrm);
2261      dst = LOAD_RM16(modrm);
2262      dst = src & dst;
2263      SetSZPF16(dst);
2264      m_CF = 0;
2265      m_OF = 0;
2266      CYCLES(CYCLES_TEST_REG_REG);
2267   } else {
2268      UINT32 ea = GetEA(modrm,0);
2269      src = LOAD_REG16(modrm);
2270      dst = READ16(ea);
2271      dst = src & dst;
2272      SetSZPF16(dst);
2273      m_CF = 0;
2274      m_OF = 0;
2275      CYCLES(CYCLES_TEST_REG_MEM);
2276   }
2277}
2278
2279void i386_device::i386_xchg_ax_cx()        // Opcode 0x91
2280{
2281   UINT16 temp;
2282   temp = REG16(AX);
2283   REG16(AX) = REG16(CX);
2284   REG16(CX) = temp;
2285   CYCLES(CYCLES_XCHG_REG_REG);
2286}
2287
2288void i386_device::i386_xchg_ax_dx()        // Opcode 0x92
2289{
2290   UINT16 temp;
2291   temp = REG16(AX);
2292   REG16(AX) = REG16(DX);
2293   REG16(DX) = temp;
2294   CYCLES(CYCLES_XCHG_REG_REG);
2295}
2296
2297void i386_device::i386_xchg_ax_bx()        // Opcode 0x93
2298{
2299   UINT16 temp;
2300   temp = REG16(AX);
2301   REG16(AX) = REG16(BX);
2302   REG16(BX) = temp;
2303   CYCLES(CYCLES_XCHG_REG_REG);
2304}
2305
2306void i386_device::i386_xchg_ax_sp()        // Opcode 0x94
2307{
2308   UINT16 temp;
2309   temp = REG16(AX);
2310   REG16(AX) = REG16(SP);
2311   REG16(SP) = temp;
2312   CYCLES(CYCLES_XCHG_REG_REG);
2313}
2314
2315void i386_device::i386_xchg_ax_bp()        // Opcode 0x95
2316{
2317   UINT16 temp;
2318   temp = REG16(AX);
2319   REG16(AX) = REG16(BP);
2320   REG16(BP) = temp;
2321   CYCLES(CYCLES_XCHG_REG_REG);
2322}
2323
2324void i386_device::i386_xchg_ax_si()        // Opcode 0x96
2325{
2326   UINT16 temp;
2327   temp = REG16(AX);
2328   REG16(AX) = REG16(SI);
2329   REG16(SI) = temp;
2330   CYCLES(CYCLES_XCHG_REG_REG);
2331}
2332
2333void i386_device::i386_xchg_ax_di()        // Opcode 0x97
2334{
2335   UINT16 temp;
2336   temp = REG16(AX);
2337   REG16(AX) = REG16(DI);
2338   REG16(DI) = temp;
2339   CYCLES(CYCLES_XCHG_REG_REG);
2340}
2341
2342void i386_device::i386_xchg_r16_rm16()     // Opcode 0x87
2343{
2344   UINT8 modrm = FETCH();
2345   if( modrm >= 0xc0 ) {
2346      UINT16 src = LOAD_RM16(modrm);
2347      UINT16 dst = LOAD_REG16(modrm);
2348      STORE_REG16(modrm, src);
2349      STORE_RM16(modrm, dst);
2350      CYCLES(CYCLES_XCHG_REG_REG);
2351   } else {
2352      UINT32 ea = GetEA(modrm,1);
2353      UINT16 src = READ16(ea);
2354      UINT16 dst = LOAD_REG16(modrm);
2355      STORE_REG16(modrm, src);
2356      WRITE16(ea, dst);
2357      CYCLES(CYCLES_XCHG_REG_MEM);
2358   }
2359}
2360
2361void i386_device::i386_xor_rm16_r16()      // Opcode 0x31
2362{
2363   UINT16 src, dst;
2364   UINT8 modrm = FETCH();
2365   if( modrm >= 0xc0 ) {
2366      src = LOAD_REG16(modrm);
2367      dst = LOAD_RM16(modrm);
2368      dst = XOR16(dst, src);
2369      STORE_RM16(modrm, dst);
2370      CYCLES(CYCLES_ALU_REG_REG);
2371   } else {
2372      UINT32 ea = GetEA(modrm,1);
2373      src = LOAD_REG16(modrm);
2374      dst = READ16(ea);
2375      dst = XOR16(dst, src);
2376      WRITE16(ea, dst);
2377      CYCLES(CYCLES_ALU_REG_MEM);
2378   }
2379}
2380
2381void i386_device::i386_xor_r16_rm16()      // Opcode 0x33
2382{
2383   UINT16 src, dst;
2384   UINT8 modrm = FETCH();
2385   if( modrm >= 0xc0 ) {
2386      src = LOAD_RM16(modrm);
2387      dst = LOAD_REG16(modrm);
2388      dst = XOR16(dst, src);
2389      STORE_REG16(modrm, dst);
2390      CYCLES(CYCLES_ALU_REG_REG);
2391   } else {
2392      UINT32 ea = GetEA(modrm,0);
2393      src = READ16(ea);
2394      dst = LOAD_REG16(modrm);
2395      dst = XOR16(dst, src);
2396      STORE_REG16(modrm, dst);
2397      CYCLES(CYCLES_ALU_MEM_REG);
2398   }
2399}
2400
2401void i386_device::i386_xor_ax_i16()        // Opcode 0x35
2402{
2403   UINT16 src, dst;
2404   src = FETCH16();
2405   dst = REG16(AX);
2406   dst = XOR16(dst, src);
2407   REG16(AX) = dst;
2408   CYCLES(CYCLES_ALU_IMM_ACC);
2409}
2410
2411
2412
2413void i386_device::i386_group81_16()        // Opcode 0x81
2414{
2415   UINT32 ea;
2416   UINT16 src, dst;
2417   UINT8 modrm = FETCH();
2418
2419   switch( (modrm >> 3) & 0x7 )
2420   {
2421      case 0:     // ADD Rm16, i16
2422         if( modrm >= 0xc0 ) {
2423            dst = LOAD_RM16(modrm);
2424            src = FETCH16();
2425            dst = ADD16(dst, src);
2426            STORE_RM16(modrm, dst);
2427            CYCLES(CYCLES_ALU_REG_REG);
2428         } else {
2429            ea = GetEA(modrm,1);
2430            dst = READ16(ea);
2431            src = FETCH16();
2432            dst = ADD16(dst, src);
2433            WRITE16(ea, dst);
2434            CYCLES(CYCLES_ALU_REG_MEM);
2435         }
2436         break;
2437      case 1:     // OR Rm16, i16
2438         if( modrm >= 0xc0 ) {
2439            dst = LOAD_RM16(modrm);
2440            src = FETCH16();
2441            dst = OR16(dst, src);
2442            STORE_RM16(modrm, dst);
2443            CYCLES(CYCLES_ALU_REG_REG);
2444         } else {
2445            ea = GetEA(modrm,1);
2446            dst = READ16(ea);
2447            src = FETCH16();
2448            dst = OR16(dst, src);
2449            WRITE16(ea, dst);
2450            CYCLES(CYCLES_ALU_REG_MEM);
2451         }
2452         break;
2453      case 2:     // ADC Rm16, i16
2454         if( modrm >= 0xc0 ) {
2455            dst = LOAD_RM16(modrm);
2456            src = FETCH16();
2457            dst = ADC16(dst, src, m_CF);
2458            STORE_RM16(modrm, dst);
2459            CYCLES(CYCLES_ALU_REG_REG);
2460         } else {
2461            ea = GetEA(modrm,1);
2462            dst = READ16(ea);
2463            src = FETCH16();
2464            dst = ADC16(dst, src, m_CF);
2465            WRITE16(ea, dst);
2466            CYCLES(CYCLES_ALU_REG_MEM);
2467         }
2468         break;
2469      case 3:     // SBB Rm16, i16
2470         if( modrm >= 0xc0 ) {
2471            dst = LOAD_RM16(modrm);
2472            src = FETCH16();
2473            dst = SBB16(dst, src, m_CF);
2474            STORE_RM16(modrm, dst);
2475            CYCLES(CYCLES_ALU_REG_REG);
2476         } else {
2477            ea = GetEA(modrm,1);
2478            dst = READ16(ea);
2479            src = FETCH16();
2480            dst = SBB16(dst, src, m_CF);
2481            WRITE16(ea, dst);
2482            CYCLES(CYCLES_ALU_REG_MEM);
2483         }
2484         break;
2485      case 4:     // AND Rm16, i16
2486         if( modrm >= 0xc0 ) {
2487            dst = LOAD_RM16(modrm);
2488            src = FETCH16();
2489            dst = AND16(dst, src);
2490            STORE_RM16(modrm, dst);
2491            CYCLES(CYCLES_ALU_REG_REG);
2492         } else {
2493            ea = GetEA(modrm,1);
2494            dst = READ16(ea);
2495            src = FETCH16();
2496            dst = AND16(dst, src);
2497            WRITE16(ea, dst);
2498            CYCLES(CYCLES_ALU_REG_MEM);
2499         }
2500         break;
2501      case 5:     // SUB Rm16, i16
2502         if( modrm >= 0xc0 ) {
2503            dst = LOAD_RM16(modrm);
2504            src = FETCH16();
2505            dst = SUB16(dst, src);
2506            STORE_RM16(modrm, dst);
2507            CYCLES(CYCLES_ALU_REG_REG);
2508         } else {
2509            ea = GetEA(modrm,1);
2510            dst = READ16(ea);
2511            src = FETCH16();
2512            dst = SUB16(dst, src);
2513            WRITE16(ea, dst);
2514            CYCLES(CYCLES_ALU_REG_MEM);
2515         }
2516         break;
2517      case 6:     // XOR Rm16, i16
2518         if( modrm >= 0xc0 ) {
2519            dst = LOAD_RM16(modrm);
2520            src = FETCH16();
2521            dst = XOR16(dst, src);
2522            STORE_RM16(modrm, dst);
2523            CYCLES(CYCLES_ALU_REG_REG);
2524         } else {
2525            ea = GetEA(modrm,1);
2526            dst = READ16(ea);
2527            src = FETCH16();
2528            dst = XOR16(dst, src);
2529            WRITE16(ea, dst);
2530            CYCLES(CYCLES_ALU_REG_MEM);
2531         }
2532         break;
2533      case 7:     // CMP Rm16, i16
2534         if( modrm >= 0xc0 ) {
2535            dst = LOAD_RM16(modrm);
2536            src = FETCH16();
2537            SUB16(dst, src);
2538            CYCLES(CYCLES_CMP_REG_REG);
2539         } else {
2540            ea = GetEA(modrm,0);
2541            dst = READ16(ea);
2542            src = FETCH16();
2543            SUB16(dst, src);
2544            CYCLES(CYCLES_CMP_REG_MEM);
2545         }
2546         break;
2547   }
2548}
2549
2550void i386_device::i386_group83_16()        // Opcode 0x83
2551{
2552   UINT32 ea;
2553   UINT16 src, dst;
2554   UINT8 modrm = FETCH();
2555
2556   switch( (modrm >> 3) & 0x7 )
2557   {
2558      case 0:     // ADD Rm16, i16
2559         if( modrm >= 0xc0 ) {
2560            dst = LOAD_RM16(modrm);
2561            src = (UINT16)(INT16)(INT8)FETCH();
2562            dst = ADD16(dst, src);
2563            STORE_RM16(modrm, dst);
2564            CYCLES(CYCLES_ALU_REG_REG);
2565         } else {
2566            ea = GetEA(modrm,1);
2567            dst = READ16(ea);
2568            src = (UINT16)(INT16)(INT8)FETCH();
2569            dst = ADD16(dst, src);
2570            WRITE16(ea, dst);
2571            CYCLES(CYCLES_ALU_REG_MEM);
2572         }
2573         break;
2574      case 1:     // OR Rm16, i16
2575         if( modrm >= 0xc0 ) {
2576            dst = LOAD_RM16(modrm);
2577            src = (UINT16)(INT16)(INT8)FETCH();
2578            dst = OR16(dst, src);
2579            STORE_RM16(modrm, dst);
2580            CYCLES(CYCLES_ALU_REG_REG);
2581         } else {
2582            ea = GetEA(modrm,1);
2583            dst = READ16(ea);
2584            src = (UINT16)(INT16)(INT8)FETCH();
2585            dst = OR16(dst, src);
2586            WRITE16(ea, dst);
2587            CYCLES(CYCLES_ALU_REG_MEM);
2588         }
2589         break;
2590      case 2:     // ADC Rm16, i16
2591         if( modrm >= 0xc0 ) {
2592            dst = LOAD_RM16(modrm);
2593            src = (UINT16)(INT16)(INT8)FETCH();
2594            dst = ADC16(dst, src, m_CF);
2595            STORE_RM16(modrm, dst);
2596            CYCLES(CYCLES_ALU_REG_REG);
2597         } else {
2598            ea = GetEA(modrm,1);
2599            dst = READ16(ea);
2600            src = (UINT16)(INT16)(INT8)FETCH();
2601            dst = ADC16(dst, src, m_CF);
2602            WRITE16(ea, dst);
2603            CYCLES(CYCLES_ALU_REG_MEM);
2604         }
2605         break;
2606      case 3:     // SBB Rm16, i16
2607         if( modrm >= 0xc0 ) {
2608            dst = LOAD_RM16(modrm);
2609            src = ((UINT16)(INT16)(INT8)FETCH());
2610            dst = SBB16(dst, src, m_CF);
2611            STORE_RM16(modrm, dst);
2612            CYCLES(CYCLES_ALU_REG_REG);
2613         } else {
2614            ea = GetEA(modrm,1);
2615            dst = READ16(ea);
2616            src = ((UINT16)(INT16)(INT8)FETCH());
2617            dst = SBB16(dst, src, m_CF);
2618            WRITE16(ea, dst);
2619            CYCLES(CYCLES_ALU_REG_MEM);
2620         }
2621         break;
2622      case 4:     // AND Rm16, i16
2623         if( modrm >= 0xc0 ) {
2624            dst = LOAD_RM16(modrm);
2625            src = (UINT16)(INT16)(INT8)FETCH();
2626            dst = AND16(dst, src);
2627            STORE_RM16(modrm, dst);
2628            CYCLES(CYCLES_ALU_REG_REG);
2629         } else {
2630            ea = GetEA(modrm,1);
2631            dst = READ16(ea);
2632            src = (UINT16)(INT16)(INT8)FETCH();
2633            dst = AND16(dst, src);
2634            WRITE16(ea, dst);
2635            CYCLES(CYCLES_ALU_REG_MEM);
2636         }
2637         break;
2638      case 5:     // SUB Rm16, i16
2639         if( modrm >= 0xc0 ) {
2640            dst = LOAD_RM16(modrm);
2641            src = (UINT16)(INT16)(INT8)FETCH();
2642            dst = SUB16(dst, src);
2643            STORE_RM16(modrm, dst);
2644            CYCLES(CYCLES_ALU_REG_REG);
2645         } else {
2646            ea = GetEA(modrm,1);
2647            dst = READ16(ea);
2648            src = (UINT16)(INT16)(INT8)FETCH();
2649            dst = SUB16(dst, src);
2650            WRITE16(ea, dst);
2651            CYCLES(CYCLES_ALU_REG_MEM);
2652         }
2653         break;
2654      case 6:     // XOR Rm16, i16
2655         if( modrm >= 0xc0 ) {
2656            dst = LOAD_RM16(modrm);
2657            src = (UINT16)(INT16)(INT8)FETCH();
2658            dst = XOR16(dst, src);
2659            STORE_RM16(modrm, dst);
2660            CYCLES(CYCLES_ALU_REG_REG);
2661         } else {
2662            ea = GetEA(modrm,1);
2663            dst = READ16(ea);
2664            src = (UINT16)(INT16)(INT8)FETCH();
2665            dst = XOR16(dst, src);
2666            WRITE16(ea, dst);
2667            CYCLES(CYCLES_ALU_REG_MEM);
2668         }
2669         break;
2670      case 7:     // CMP Rm16, i16
2671         if( modrm >= 0xc0 ) {
2672            dst = LOAD_RM16(modrm);
2673            src = (UINT16)(INT16)(INT8)FETCH();
2674            SUB16(dst, src);
2675            CYCLES(CYCLES_CMP_REG_REG);
2676         } else {
2677            ea = GetEA(modrm,0);
2678            dst = READ16(ea);
2679            src = (UINT16)(INT16)(INT8)FETCH();
2680            SUB16(dst, src);
2681            CYCLES(CYCLES_CMP_REG_MEM);
2682         }
2683         break;
2684   }
2685}
2686
2687void i386_device::i386_groupC1_16()        // Opcode 0xc1
2688{
2689   UINT16 dst;
2690   UINT8 modrm = FETCH();
2691   UINT8 shift;
2692
2693   if( modrm >= 0xc0 ) {
2694      dst = LOAD_RM16(modrm);
2695      shift = FETCH() & 0x1f;
2696      dst = i386_shift_rotate16(modrm, dst, shift);
2697      STORE_RM16(modrm, dst);
2698   } else {
2699      UINT32 ea = GetEA(modrm,1);
2700      dst = READ16(ea);
2701      shift = FETCH() & 0x1f;
2702      dst = i386_shift_rotate16(modrm, dst, shift);
2703      WRITE16(ea, dst);
2704   }
2705}
2706
2707void i386_device::i386_groupD1_16()        // Opcode 0xd1
2708{
2709   UINT16 dst;
2710   UINT8 modrm = FETCH();
2711
2712   if( modrm >= 0xc0 ) {
2713      dst = LOAD_RM16(modrm);
2714      dst = i386_shift_rotate16(modrm, dst, 1);
2715      STORE_RM16(modrm, dst);
2716   } else {
2717      UINT32 ea = GetEA(modrm,1);
2718      dst = READ16(ea);
2719      dst = i386_shift_rotate16(modrm, dst, 1);
2720      WRITE16(ea, dst);
2721   }
2722}
2723
2724void i386_device::i386_groupD3_16()        // Opcode 0xd3
2725{
2726   UINT16 dst;
2727   UINT8 modrm = FETCH();
2728
2729   if( modrm >= 0xc0 ) {
2730      dst = LOAD_RM16(modrm);
2731      dst = i386_shift_rotate16(modrm, dst, REG8(CL));
2732      STORE_RM16(modrm, dst);
2733   } else {
2734      UINT32 ea = GetEA(modrm,1);
2735      dst = READ16(ea);
2736      dst = i386_shift_rotate16(modrm, dst, REG8(CL));
2737      WRITE16(ea, dst);
2738   }
2739}
2740
2741void i386_device::i386_groupF7_16()        // Opcode 0xf7
2742{
2743   UINT8 modrm = FETCH();
2744
2745   switch( (modrm >> 3) & 0x7 )
2746   {
2747      case 0:         /* TEST Rm16, i16 */
2748         if( modrm >= 0xc0 ) {
2749            UINT16 dst = LOAD_RM16(modrm);
2750            UINT16 src = FETCH16();
2751            dst &= src;
2752            m_CF = m_OF = m_AF = 0;
2753            SetSZPF16(dst);
2754            CYCLES(CYCLES_TEST_IMM_REG);
2755         } else {
2756            UINT32 ea = GetEA(modrm,0);
2757            UINT16 dst = READ16(ea);
2758            UINT16 src = FETCH16();
2759            dst &= src;
2760            m_CF = m_OF = m_AF = 0;
2761            SetSZPF16(dst);
2762            CYCLES(CYCLES_TEST_IMM_MEM);
2763         }
2764         break;
2765      case 2:         /* NOT Rm16 */
2766         if( modrm >= 0xc0 ) {
2767            UINT16 dst = LOAD_RM16(modrm);
2768            dst = ~dst;
2769            STORE_RM16(modrm, dst);
2770            CYCLES(CYCLES_NOT_REG);
2771         } else {
2772            UINT32 ea = GetEA(modrm,1);
2773            UINT16 dst = READ16(ea);
2774            dst = ~dst;
2775            WRITE16(ea, dst);
2776            CYCLES(CYCLES_NOT_MEM);
2777         }
2778         break;
2779      case 3:         /* NEG Rm16 */
2780         if( modrm >= 0xc0 ) {
2781            UINT16 dst = LOAD_RM16(modrm);
2782            dst = SUB16(0, dst );
2783            STORE_RM16(modrm, dst);
2784            CYCLES(CYCLES_NEG_REG);
2785         } else {
2786            UINT32 ea = GetEA(modrm,1);
2787            UINT16 dst = READ16(ea);
2788            dst = SUB16(0, dst );
2789            WRITE16(ea, dst);
2790            CYCLES(CYCLES_NEG_MEM);
2791         }
2792         break;
2793      case 4:         /* MUL AX, Rm16 */
2794         {
2795            UINT32 result;
2796            UINT16 src, dst;
2797            if( modrm >= 0xc0 ) {
2798               src = LOAD_RM16(modrm);
2799               CYCLES(CYCLES_MUL16_ACC_REG);      /* TODO: Correct multiply timing */
2800            } else {
2801               UINT32 ea = GetEA(modrm,0);
2802               src = READ16(ea);
2803               CYCLES(CYCLES_MUL16_ACC_MEM);      /* TODO: Correct multiply timing */
2804            }
2805
2806            dst = REG16(AX);
2807            result = (UINT32)src * (UINT32)dst;
2808            REG16(DX) = (UINT16)(result >> 16);
2809            REG16(AX) = (UINT16)result;
2810
2811            m_CF = m_OF = (REG16(DX) != 0);
2812         }
2813         break;
2814      case 5:         /* IMUL AX, Rm16 */
2815         {
2816            INT32 result;
2817            INT32 src, dst;
2818            if( modrm >= 0xc0 ) {
2819               src = (INT32)(INT16)LOAD_RM16(modrm);
2820               CYCLES(CYCLES_IMUL16_ACC_REG);     /* TODO: Correct multiply timing */
2821            } else {
2822               UINT32 ea = GetEA(modrm,0);
2823               src = (INT32)(INT16)READ16(ea);
2824               CYCLES(CYCLES_IMUL16_ACC_MEM);     /* TODO: Correct multiply timing */
2825            }
2826
2827            dst = (INT32)(INT16)REG16(AX);
2828            result = src * dst;
2829
2830            REG16(DX) = (UINT16)(result >> 16);
2831            REG16(AX) = (UINT16)result;
2832
2833            m_CF = m_OF = !(result == (INT32)(INT16)result);
2834         }
2835         break;
2836      case 6:         /* DIV AX, Rm16 */
2837         {
2838            UINT32 quotient, remainder, result;
2839            UINT16 src;
2840            if( modrm >= 0xc0 ) {
2841               src = LOAD_RM16(modrm);
2842               CYCLES(CYCLES_DIV16_ACC_REG);
2843            } else {
2844               UINT32 ea = GetEA(modrm,0);
2845               src = READ16(ea);
2846               CYCLES(CYCLES_DIV16_ACC_MEM);
2847            }
2848
2849            quotient = ((UINT32)(REG16(DX)) << 16) | (UINT32)(REG16(AX));
2850            if( src ) {
2851               remainder = quotient % (UINT32)src;
2852               result = quotient / (UINT32)src;
2853               if( result > 0xffff ) {
2854                  /* TODO: Divide error */
2855               } else {
2856                  REG16(DX) = (UINT16)remainder;
2857                  REG16(AX) = (UINT16)result;
2858
2859                  // this flag is actually undefined, enable on non-cyrix
2860                  if (m_cpuid_id0 != 0x69727943)
2861                     m_CF = 1;
2862               }
2863            } else {
2864               i386_trap(0, 0, 0);
2865            }
2866         }
2867         break;
2868      case 7:         /* IDIV AX, Rm16 */
2869         {
2870            INT32 quotient, remainder, result;
2871            UINT16 src;
2872            if( modrm >= 0xc0 ) {
2873               src = LOAD_RM16(modrm);
2874               CYCLES(CYCLES_IDIV16_ACC_REG);
2875            } else {
2876               UINT32 ea = GetEA(modrm,0);
2877               src = READ16(ea);
2878               CYCLES(CYCLES_IDIV16_ACC_MEM);
2879            }
2880
2881            quotient = (((INT32)REG16(DX)) << 16) | ((UINT32)REG16(AX));
2882            if( src ) {
2883               remainder = quotient % (INT32)(INT16)src;
2884               result = quotient / (INT32)(INT16)src;
2885               if( result > 0xffff ) {
2886                  /* TODO: Divide error */
2887               } else {
2888                  REG16(DX) = (UINT16)remainder;
2889                  REG16(AX) = (UINT16)result;
2890
2891                  // this flag is actually undefined, enable on non-cyrix
2892                  if (m_cpuid_id0 != 0x69727943)
2893                     m_CF = 1;
2894               }
2895            } else {
2896               i386_trap(0, 0, 0);
2897            }
2898         }
2899         break;
2900   }
2901}
2902
2903void i386_device::i386_groupFF_16()        // Opcode 0xff
2904{
2905   UINT8 modrm = FETCH();
2906
2907   switch( (modrm >> 3) & 0x7 )
2908   {
2909      case 0:         /* INC Rm16 */
2910         if( modrm >= 0xc0 ) {
2911            UINT16 dst = LOAD_RM16(modrm);
2912            dst = INC16(dst);
2913            STORE_RM16(modrm, dst);
2914            CYCLES(CYCLES_INC_REG);
2915         } else {
2916            UINT32 ea = GetEA(modrm,1);
2917            UINT16 dst = READ16(ea);
2918            dst = INC16(dst);
2919            WRITE16(ea, dst);
2920            CYCLES(CYCLES_INC_MEM);
2921         }
2922         break;
2923      case 1:         /* DEC Rm16 */
2924         if( modrm >= 0xc0 ) {
2925            UINT16 dst = LOAD_RM16(modrm);
2926            dst = DEC16(dst);
2927            STORE_RM16(modrm, dst);
2928            CYCLES(CYCLES_DEC_REG);
2929         } else {
2930            UINT32 ea = GetEA(modrm,1);
2931            UINT16 dst = READ16(ea);
2932            dst = DEC16(dst);
2933            WRITE16(ea, dst);
2934            CYCLES(CYCLES_DEC_MEM);
2935         }
2936         break;
2937      case 2:         /* CALL Rm16 */
2938         {
2939            UINT16 address;
2940            if( modrm >= 0xc0 ) {
2941               address = LOAD_RM16(modrm);
2942               CYCLES(CYCLES_CALL_REG);       /* TODO: Timing = 7 + m */
2943            } else {
2944               UINT32 ea = GetEA(modrm,0);
2945               address = READ16(ea);
2946               CYCLES(CYCLES_CALL_MEM);       /* TODO: Timing = 10 + m */
2947            }
2948            PUSH16(m_eip );
2949            m_eip = address;
2950            CHANGE_PC(m_eip);
2951         }
2952         break;
2953      case 3:         /* CALL FAR Rm16 */
2954         {
2955            UINT16 address, selector;
2956            if( modrm >= 0xc0 )
2957            {
2958               report_invalid_modrm("groupFF_16", modrm);
2959            }
2960            else
2961            {
2962               UINT32 ea = GetEA(modrm,0);
2963               address = READ16(ea + 0);
2964               selector = READ16(ea + 2);
2965               CYCLES(CYCLES_CALL_MEM_INTERSEG);      /* TODO: Timing = 10 + m */
2966
2967               if(PROTECTED_MODE && !V8086_MODE)
2968               {
2969                  i386_protected_mode_call(selector,address,1,0);
2970               }
2971               else
2972               {
2973                  PUSH16(m_sreg[CS].selector );
2974                  PUSH16(m_eip );
2975                  m_sreg[CS].selector = selector;
2976                  m_performed_intersegment_jump = 1;
2977                  i386_load_segment_descriptor(CS );
2978                  m_eip = address;
2979                  CHANGE_PC(m_eip);
2980               }
2981            }
2982         }
2983         break;
2984      case 4:         /* JMP Rm16 */
2985         {
2986            UINT16 address;
2987            if( modrm >= 0xc0 ) {
2988               address = LOAD_RM16(modrm);
2989               CYCLES(CYCLES_JMP_REG);        /* TODO: Timing = 7 + m */
2990            } else {
2991               UINT32 ea = GetEA(modrm,0);
2992               address = READ16(ea);
2993               CYCLES(CYCLES_JMP_MEM);        /* TODO: Timing = 10 + m */
2994            }
2995            m_eip = address;
2996            CHANGE_PC(m_eip);
2997         }
2998         break;
2999      case 5:         /* JMP FAR Rm16 */
3000         {
3001            UINT16 address, selector;
3002
3003            if( modrm >= 0xc0 )
3004            {
3005               report_invalid_modrm("groupFF_16", modrm);
3006            }
3007            else
3008            {
3009               UINT32 ea = GetEA(modrm,0);
3010               address = READ16(ea + 0);
3011               selector = READ16(ea + 2);
3012               CYCLES(CYCLES_JMP_MEM_INTERSEG);       /* TODO: Timing = 10 + m */
3013               if(PROTECTED_MODE && !V8086_MODE)
3014               {
3015                  i386_protected_mode_jump(selector,address,1,0);
3016               }
3017               else
3018               {
3019                  m_sreg[CS].selector = selector;
3020                  m_performed_intersegment_jump = 1;
3021                  i386_load_segment_descriptor(CS );
3022                  m_eip = address;
3023                  CHANGE_PC(m_eip);
3024               }
3025            }
3026         }
3027         break;
3028      case 6:         /* PUSH Rm16 */
3029         {
3030            UINT16 value;
3031            if( modrm >= 0xc0 ) {
3032               value = LOAD_RM16(modrm);
3033            } else {
3034               UINT32 ea = GetEA(modrm,0);
3035               value = READ16(ea);
3036            }
3037            PUSH16(value);
3038            CYCLES(CYCLES_PUSH_RM);
3039         }
3040         break;
3041      default:
3042         report_invalid_modrm("groupFF_16", modrm);
3043         break;
3044   }
3045}
3046
3047void i386_device::i386_group0F00_16()          // Opcode 0x0f 00
3048{
3049   UINT32 address, ea;
3050   UINT8 modrm = FETCH();
3051   I386_SREG seg;
3052   UINT8 result;
3053
3054   switch( (modrm >> 3) & 0x7 )
3055   {
3056      case 0:         /* SLDT */
3057         if ( PROTECTED_MODE && !V8086_MODE )
3058         {
3059            if( modrm >= 0xc0 ) {
3060               STORE_RM16(modrm, m_ldtr.segment);
3061               CYCLES(CYCLES_SLDT_REG);
3062            } else {
3063               ea = GetEA(modrm,1);
3064               WRITE16(ea, m_ldtr.segment);
3065               CYCLES(CYCLES_SLDT_MEM);
3066            }
3067         }
3068         else
3069         {
3070            i386_trap(6, 0, 0);
3071         }
3072         break;
3073      case 1:         /* STR */
3074         if ( PROTECTED_MODE && !V8086_MODE )
3075         {
3076            if( modrm >= 0xc0 ) {
3077               STORE_RM16(modrm, m_task.segment);
3078               CYCLES(CYCLES_STR_REG);
3079            } else {
3080               ea = GetEA(modrm,1);
3081               WRITE16(ea, m_task.segment);
3082               CYCLES(CYCLES_STR_MEM);
3083            }
3084         }
3085         else
3086         {
3087            i386_trap(6, 0, 0);
3088         }
3089         break;
3090      case 2:         /* LLDT */
3091         if ( PROTECTED_MODE && !V8086_MODE )
3092         {
3093            if(m_CPL)
3094               FAULT(FAULT_GP,0)
3095            if( modrm >= 0xc0 ) {
3096               address = LOAD_RM16(modrm);
3097               m_ldtr.segment = address;
3098               CYCLES(CYCLES_LLDT_REG);
3099            } else {
3100               ea = GetEA(modrm,0);
3101               m_ldtr.segment = READ16(ea);
3102               CYCLES(CYCLES_LLDT_MEM);
3103            }
3104            memset(&seg, 0, sizeof(seg));
3105            seg.selector = m_ldtr.segment;
3106            i386_load_protected_mode_segment(&seg,NULL);
3107            m_ldtr.limit = seg.limit;
3108            m_ldtr.base = seg.base;
3109            m_ldtr.flags = seg.flags;
3110         }
3111         else
3112         {
3113            i386_trap(6, 0, 0);
3114         }
3115         break;
3116
3117      case 3:         /* LTR */
3118         if ( PROTECTED_MODE && !V8086_MODE )
3119         {
3120            if(m_CPL)
3121               FAULT(FAULT_GP,0)
3122            if( modrm >= 0xc0 ) {
3123               address = LOAD_RM16(modrm);
3124               m_task.segment = address;
3125               CYCLES(CYCLES_LTR_REG);
3126            } else {
3127               ea = GetEA(modrm,0);
3128               m_task.segment = READ16(ea);
3129               CYCLES(CYCLES_LTR_MEM);
3130            }
3131            memset(&seg, 0, sizeof(seg));
3132            seg.selector = m_task.segment;
3133            i386_load_protected_mode_segment(&seg,NULL);
3134            m_task.limit = seg.limit;
3135            m_task.base = seg.base;
3136            m_task.flags = seg.flags;
3137         }
3138         else
3139         {
3140            i386_trap(6, 0, 0);
3141         }
3142         break;
3143
3144      case 4:  /* VERR */
3145         if ( PROTECTED_MODE && !V8086_MODE )
3146         {
3147            result = 1;
3148            if( modrm >= 0xc0 ) {
3149               address = LOAD_RM16(modrm);
3150               CYCLES(CYCLES_VERR_REG);
3151            } else {
3152               ea = GetEA(modrm,0);
3153               address = READ16(ea);
3154               CYCLES(CYCLES_VERR_MEM);
3155            }
3156            memset(&seg, 0, sizeof(seg));
3157            seg.selector = address;
3158            result = i386_load_protected_mode_segment(&seg,NULL);
3159            // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3160            if(!(seg.flags & 0x10))
3161               result = 0;
3162            // check that the segment is readable
3163            if(seg.flags & 0x10)  // is code or data segment
3164            {
3165               if(seg.flags & 0x08)  // is code segment, so check if it's readable
3166               {
3167                  if(!(seg.flags & 0x02))
3168                  {
3169                     result = 0;
3170                  }
3171                  else
3172                  {  // check if conforming, these are always readable, regardless of privilege
3173                     if(!(seg.flags & 0x04))
3174                     {
3175                        // if not conforming, then we must check privilege levels (TODO: current privilege level check)
3176                        if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3177                           result = 0;
3178                     }
3179                  }
3180               }
3181            }
3182            // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3183            SetZF(result);
3184         }
3185         else
3186         {
3187            i386_trap(6, 0, 0);
3188            logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n");
3189         }
3190         break;
3191
3192      case 5:  /* VERW */
3193         if ( PROTECTED_MODE && !V8086_MODE )
3194         {
3195            result = 1;
3196            if( modrm >= 0xc0 ) {
3197               address = LOAD_RM16(modrm);
3198               CYCLES(CYCLES_VERW_REG);
3199            } else {
3200               ea = GetEA(modrm,0);
3201               address = READ16(ea);
3202               CYCLES(CYCLES_VERW_MEM);
3203            }
3204            memset(&seg, 0, sizeof(seg));
3205            seg.selector = address;
3206            result = i386_load_protected_mode_segment(&seg,NULL);
3207            // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3208            if(!(seg.flags & 0x10))
3209               result = 0;
3210            // check that the segment is writable
3211            if(seg.flags & 0x10)  // is code or data segment
3212            {
3213               if(seg.flags & 0x08)  // is code segment (and thus, not writable)
3214               {
3215                  result = 0;
3216               }
3217               else
3218               {  // is data segment
3219                  if(!(seg.flags & 0x02))
3220                     result = 0;
3221               }
3222            }
3223            // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3224            if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3225               result = 0;
3226            SetZF(result);
3227         }
3228         else
3229         {
3230            i386_trap(6, 0, 0);
3231            logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n");
3232         }
3233         break;
3234
3235      default:
3236         report_invalid_modrm("group0F00_16", modrm);
3237         break;
3238   }
3239}
3240
3241void i386_device::i386_group0F01_16()      // Opcode 0x0f 01
3242{
3243   UINT8 modrm = FETCH();
3244   UINT16 address;
3245   UINT32 ea;
3246
3247   switch( (modrm >> 3) & 0x7 )
3248   {
3249      case 0:         /* SGDT */
3250         {
3251            if( modrm >= 0xc0 ) {
3252               address = LOAD_RM16(modrm);
3253               ea = i386_translate(CS, address, 1 );
3254            } else {
3255               ea = GetEA(modrm,1);
3256            }
3257            WRITE16(ea, m_gdtr.limit);
3258            WRITE32(ea + 2, m_gdtr.base & 0xffffff);
3259            CYCLES(CYCLES_SGDT);
3260            break;
3261         }
3262      case 1:         /* SIDT */
3263         {
3264            if (modrm >= 0xc0)
3265            {
3266               address = LOAD_RM16(modrm);
3267               ea = i386_translate(CS, address, 1 );
3268            }
3269            else
3270            {
3271               ea = GetEA(modrm,1);
3272            }
3273            WRITE16(ea, m_idtr.limit);
3274            WRITE32(ea + 2, m_idtr.base & 0xffffff);
3275            CYCLES(CYCLES_SIDT);
3276            break;
3277         }
3278      case 2:         /* LGDT */
3279         {
3280            if(PROTECTED_MODE && m_CPL)
3281               FAULT(FAULT_GP,0)
3282            if( modrm >= 0xc0 ) {
3283               address = LOAD_RM16(modrm);
3284               ea = i386_translate(CS, address, 0 );
3285            } else {
3286               ea = GetEA(modrm,0);
3287            }
3288            m_gdtr.limit = READ16(ea);
3289            m_gdtr.base = READ32(ea + 2) & 0xffffff;
3290            CYCLES(CYCLES_LGDT);
3291            break;
3292         }
3293      case 3:         /* LIDT */
3294         {
3295            if(PROTECTED_MODE && m_CPL)
3296               FAULT(FAULT_GP,0)
3297            if( modrm >= 0xc0 ) {
3298               address = LOAD_RM16(modrm);
3299               ea = i386_translate(CS, address, 0 );
3300            } else {
3301               ea = GetEA(modrm,0);
3302            }
3303            m_idtr.limit = READ16(ea);
3304            m_idtr.base = READ32(ea + 2) & 0xffffff;
3305            CYCLES(CYCLES_LIDT);
3306            break;
3307         }
3308      case 4:         /* SMSW */
3309         {
3310            if( modrm >= 0xc0 ) {
3311               STORE_RM16(modrm, m_cr[0]);
3312               CYCLES(CYCLES_SMSW_REG);
3313            } else {
3314               ea = GetEA(modrm,1);
3315               WRITE16(ea, m_cr[0]);
3316               CYCLES(CYCLES_SMSW_MEM);
3317            }
3318            break;
3319         }
3320      case 6:         /* LMSW */
3321         {
3322            if(PROTECTED_MODE && m_CPL)
3323               FAULT(FAULT_GP,0)
3324            UINT16 b;
3325            if( modrm >= 0xc0 ) {
3326               b = LOAD_RM16(modrm);
3327               CYCLES(CYCLES_LMSW_REG);
3328            } else {
3329               ea = GetEA(modrm,0);
3330               CYCLES(CYCLES_LMSW_MEM);
3331            b = READ16(ea);
3332            }
3333            if(PROTECTED_MODE)
3334               b |= 0x0001;  // cannot return to real mode using this instruction.
3335            m_cr[0] &= ~0x0000000f;
3336            m_cr[0] |= b & 0x0000000f;
3337            break;
3338         }
3339      default:
3340         report_invalid_modrm("group0F01_16", modrm);
3341         break;
3342   }
3343}
3344
3345void i386_device::i386_group0FBA_16()      // Opcode 0x0f ba
3346{
3347   UINT8 modrm = FETCH();
3348
3349   switch( (modrm >> 3) & 0x7 )
3350   {
3351      case 4:         /* BT Rm16, i8 */
3352         if( modrm >= 0xc0 ) {
3353            UINT16 dst = LOAD_RM16(modrm);
3354            UINT8 bit = FETCH();
3355
3356            if( dst & (1 << bit) )
3357               m_CF = 1;
3358            else
3359               m_CF = 0;
3360
3361            CYCLES(CYCLES_BT_IMM_REG);
3362         } else {
3363            UINT32 ea = GetEA(modrm,0);
3364            UINT16 dst = READ16(ea);
3365            UINT8 bit = FETCH();
3366
3367            if( dst & (1 << bit) )
3368               m_CF = 1;
3369            else
3370               m_CF = 0;
3371
3372            CYCLES(CYCLES_BT_IMM_MEM);
3373         }
3374         break;
3375      case 5:         /* BTS Rm16, i8 */
3376         if( modrm >= 0xc0 ) {
3377            UINT16 dst = LOAD_RM16(modrm);
3378            UINT8 bit = FETCH();
3379
3380            if( dst & (1 << bit) )
3381               m_CF = 1;
3382            else
3383               m_CF = 0;
3384            dst |= (1 << bit);
3385
3386            STORE_RM16(modrm, dst);
3387            CYCLES(CYCLES_BTS_IMM_REG);
3388         } else {
3389            UINT32 ea = GetEA(modrm,1);
3390            UINT16 dst = READ16(ea);
3391            UINT8 bit = FETCH();
3392
3393            if( dst & (1 << bit) )
3394               m_CF = 1;
3395            else
3396               m_CF = 0;
3397            dst |= (1 << bit);
3398
3399            WRITE16(ea, dst);
3400            CYCLES(CYCLES_BTS_IMM_MEM);
3401         }
3402         break;
3403      case 6:         /* BTR Rm16, i8 */
3404         if( modrm >= 0xc0 ) {
3405            UINT16 dst = LOAD_RM16(modrm);
3406            UINT8 bit = FETCH();
3407
3408            if( dst & (1 << bit) )
3409               m_CF = 1;
3410            else
3411               m_CF = 0;
3412            dst &= ~(1 << bit);
3413
3414            STORE_RM16(modrm, dst);
3415            CYCLES(CYCLES_BTR_IMM_REG);
3416         } else {
3417            UINT32 ea = GetEA(modrm,1);
3418            UINT16 dst = READ16(ea);
3419            UINT8 bit = FETCH();
3420
3421            if( dst & (1 << bit) )
3422               m_CF = 1;
3423            else
3424               m_CF = 0;
3425            dst &= ~(1 << bit);
3426
3427            WRITE16(ea, dst);
3428            CYCLES(CYCLES_BTR_IMM_MEM);
3429         }
3430         break;
3431      case 7:         /* BTC Rm16, i8 */
3432         if( modrm >= 0xc0 ) {
3433            UINT16 dst = LOAD_RM16(modrm);
3434            UINT8 bit = FETCH();
3435
3436            if( dst & (1 << bit) )
3437               m_CF = 1;
3438            else
3439               m_CF = 0;
3440            dst ^= (1 << bit);
3441
3442            STORE_RM16(modrm, dst);
3443            CYCLES(CYCLES_BTC_IMM_REG);
3444         } else {
3445            UINT32 ea = GetEA(modrm,1);
3446            UINT16 dst = READ16(ea);
3447            UINT8 bit = FETCH();
3448
3449            if( dst & (1 << bit) )
3450               m_CF = 1;
3451            else
3452               m_CF = 0;
3453            dst ^= (1 << bit);
3454
3455            WRITE16(ea, dst);
3456            CYCLES(CYCLES_BTC_IMM_MEM);
3457         }
3458         break;
3459      default:
3460         report_invalid_modrm("group0FBA_16", modrm);
3461         break;
3462   }
3463}
3464
3465void i386_device::i386_lar_r16_rm16()  // Opcode 0x0f 0x02
3466{
3467   UINT8 modrm = FETCH();
3468   I386_SREG seg;
3469   UINT8 type;
3470
3471   if(PROTECTED_MODE && !V8086_MODE)
3472   {
3473      memset(&seg,0,sizeof(seg));
3474      if(modrm >= 0xc0)
3475      {
3476         seg.selector = LOAD_RM16(modrm);
3477         CYCLES(CYCLES_LAR_REG);
3478      }
3479      else
3480      {
3481         UINT32 ea = GetEA(modrm,0);
3482         seg.selector = READ16(ea);
3483         CYCLES(CYCLES_LAR_MEM);
3484      }
3485      if(seg.selector == 0)
3486      {
3487         SetZF(0);  // not a valid segment
3488      //  logerror("i386 (%08x): LAR: Selector %04x is invalid type.\n",m_pc,seg.selector);
3489      }
3490      else
3491      {
3492         if(!i386_load_protected_mode_segment(&seg,NULL))
3493         {
3494            SetZF(0);
3495            return;
3496         }
3497         UINT8 DPL = (seg.flags >> 5) & 3;
3498         if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3499         {
3500            SetZF(0);
3501            return;
3502         }
3503         if(!(seg.flags & 0x10))  // special segment
3504         {
3505            // check for invalid segment types
3506            type = seg.flags & 0x000f;
3507            if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d)
3508            {
3509               SetZF(0);  // invalid segment type
3510            }
3511            else
3512            {
3513               STORE_REG16(modrm,(seg.flags << 8) & 0xff00);
3514               SetZF(1);
3515            }
3516         }
3517         else
3518         {  // data or code segment (both are valid for LAR)
3519            STORE_REG16(modrm,(seg.flags << 8) & 0xff00);
3520            SetZF(1);
3521         }
3522      }
3523   }
3524   else
3525   {
3526      // illegal opcode
3527      i386_trap(6,0, 0);
3528      logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n");
3529   }
3530}
3531
3532void i386_device::i386_lsl_r16_rm16()  // Opcode 0x0f 0x03
3533{
3534   UINT8 modrm = FETCH();
3535   UINT32 limit;
3536   I386_SREG seg;
3537
3538   if(PROTECTED_MODE && !V8086_MODE)
3539   {
3540      memset(&seg, 0, sizeof(seg));
3541      if(modrm >= 0xc0)
3542      {
3543         seg.selector = LOAD_RM16(modrm);
3544      }
3545      else
3546      {
3547         UINT32 ea = GetEA(modrm,0);
3548         seg.selector = READ16(ea);
3549      }
3550      if(seg.selector == 0)
3551      {
3552         SetZF(0);  // not a valid segment
3553      }
3554      else
3555      {
3556         UINT8 type;
3557         if(!i386_load_protected_mode_segment(&seg,NULL))
3558         {
3559            SetZF(0);
3560            return;
3561         }
3562         UINT8 DPL = (seg.flags >> 5) & 3;
3563         if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3564         {
3565            SetZF(0);
3566            return;
3567         }
3568         type = seg.flags & 0x1f;
3569         switch(type)
3570         {
3571         case 0:
3572         case 4:
3573         case 5:
3574         case 6:
3575         case 7:
3576         case 8:
3577         case 10:
3578         case 12:
3579         case 13:
3580         case 14:
3581         case 15:
3582            SetZF(0);
3583            return;
3584         default:
3585            limit = seg.limit;
3586            STORE_REG16(modrm,limit & 0x0000ffff);
3587            SetZF(1);
3588         }
3589      }
3590   }
3591   else
3592      i386_trap(6, 0, 0);
3593}
3594
3595void i386_device::i386_bound_r16_m16_m16() // Opcode 0x62
3596{
3597   UINT8 modrm;
3598   INT16 val, low, high;
3599
3600   modrm = FETCH();
3601
3602   if (modrm >= 0xc0)
3603   {
3604      low = high = LOAD_RM16(modrm);
3605   }
3606   else
3607   {
3608      UINT32 ea = GetEA(modrm,0);
3609      low = READ16(ea + 0);
3610      high = READ16(ea + 2);
3611   }
3612   val = LOAD_REG16(modrm);
3613
3614   if ((val < low) || (val > high))
3615   {
3616      CYCLES(CYCLES_BOUND_OUT_RANGE);
3617      i386_trap(5, 0, 0);
3618   }
3619   else
3620   {
3621      CYCLES(CYCLES_BOUND_IN_RANGE);
3622   }
3623}
3624
3625void i386_device::i386_retf16()            // Opcode 0xcb
3626{
3627   if(PROTECTED_MODE && !V8086_MODE)
3628   {
3629      i386_protected_mode_retf(0,0);
3630   }
3631   else
3632   {
3633      m_eip = POP16();
3634      m_sreg[CS].selector = POP16();
3635      i386_load_segment_descriptor(CS );
3636      CHANGE_PC(m_eip);
3637   }
3638
3639   CYCLES(CYCLES_RET_INTERSEG);
3640}
3641
3642void i386_device::i386_retf_i16()          // Opcode 0xca
3643{
3644   UINT16 count = FETCH16();
3645
3646   if(PROTECTED_MODE && !V8086_MODE)
3647   {
3648      i386_protected_mode_retf(count,0);
3649   }
3650   else
3651   {
3652      m_eip = POP16();
3653      m_sreg[CS].selector = POP16();
3654      i386_load_segment_descriptor(CS );
3655      CHANGE_PC(m_eip);
3656      REG16(SP) += count;
3657   }
3658
3659   CYCLES(CYCLES_RET_IMM_INTERSEG);
3660}
3661
3662bool i386_device::i386_load_far_pointer16(int s)
3663{
3664   UINT8 modrm = FETCH();
3665   UINT16 selector;
3666
3667   if( modrm >= 0xc0 ) {
3668      //logerror("i386: load_far_pointer16 NYI\n"); // don't log, NT will use this a lot
3669      i386_trap(6, 0, 0);
3670      return false;
3671   } else {
3672      UINT32 ea = GetEA(modrm,0);
3673      STORE_REG16(modrm, READ16(ea + 0));
3674      selector = READ16(ea + 2);
3675      i386_sreg_load(selector,s,NULL);
3676   }
3677   return true;
3678}
3679
3680void i386_device::i386_lds16()             // Opcode 0xc5
3681{
3682   if(i386_load_far_pointer16(DS))
3683      CYCLES(CYCLES_LDS);
3684}
3685
3686void i386_device::i386_lss16()             // Opcode 0x0f 0xb2
3687{
3688   if(i386_load_far_pointer16(SS))
3689      CYCLES(CYCLES_LSS);
3690}
3691
3692void i386_device::i386_les16()             // Opcode 0xc4
3693{
3694   if(i386_load_far_pointer16(ES))
3695      CYCLES(CYCLES_LES);
3696}
3697
3698void i386_device::i386_lfs16()             // Opcode 0x0f 0xb4
3699{
3700   if(i386_load_far_pointer16(FS))
3701      CYCLES(CYCLES_LFS);
3702}
3703
3704void i386_device::i386_lgs16()             // Opcode 0x0f 0xb5
3705{
3706   if(i386_load_far_pointer16(GS))
3707      CYCLES(CYCLES_LGS);
3708}
Property changes on: trunk/src/emu/cpu/i386/i386op16.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/i386/i386.c
r28738r28739
28322832}
28332833
28342834
2835#include "i386ops.c"
2836#include "i386op16.c"
2837#include "i386op32.c"
2838#include "i486ops.c"
2839#include "pentops.c"
2840#include "x87ops.c"
2835#include "i386ops.inc"
2836#include "i386op16.inc"
2837#include "i386op32.inc"
2838#include "i486ops.inc"
2839#include "pentops.inc"
2840#include "x87ops.inc"
28412841#include "i386ops.h"
28422842
28432843void i386_device::i386_decode_opcode()
trunk/src/emu/cpu/mc68hc11/hc11ops.c
r28738r28739
1#define SET_Z8(r)           (m_ccr |= ((UINT8)r == 0) ? CC_Z : 0)
2#define SET_Z16(r)          (m_ccr |= ((UINT16)r == 0) ? CC_Z : 0)
3#define SET_N8(r)           (m_ccr |= (r & 0x80) ? CC_N : 0)
4#define SET_N16(r)          (m_ccr |= (r & 0x8000) ? CC_N : 0)
5#define SET_V_ADD8(r,s,d)   (m_ccr |= (((r) ^ (s)) & ((r) ^ (d)) & 0x80) ? CC_V : 0)
6#define SET_V_SUB8(r,s,d)   (m_ccr |= (((d) ^ (s)) & ((d) ^ (r)) & 0x80) ? CC_V : 0)
7#define SET_V_ADD16(r,s,d)  (m_ccr |= (((r) ^ (s)) & ((r) ^ (d)) & 0x8000) ? CC_V : 0)
8#define SET_V_SUB16(r,s,d)  (m_ccr |= (((d) ^ (s)) & ((d) ^ (r)) & 0x8000) ? CC_V : 0)
9#define SET_H(r,s,d)        (m_ccr |= (((r) ^ (s) ^ (d)) & 0x10) ? CC_H : 0)
10#define SET_C8(x)           (m_ccr |= ((x) & 0x100) ? CC_C : 0)
11#define SET_C16(x)          (m_ccr |= ((x) & 0x10000) ? CC_C : 0)
12#define CLEAR_Z()           (m_ccr &= ~(CC_Z))
13#define CLEAR_C()           (m_ccr &= ~(CC_C))
14#define CLEAR_NZV()         (m_ccr &= ~(CC_N | CC_Z | CC_V))
15#define CLEAR_ZVC()         (m_ccr &= ~(CC_Z | CC_V | CC_C))
16#define CLEAR_NZVC()        (m_ccr &= ~(CC_N | CC_Z | CC_V | CC_C))
17#define CLEAR_HNZVC()       (m_ccr &= ~(CC_H | CC_N | CC_Z | CC_V | CC_C))
18
19#define SET_ZFLAG()         (m_ccr |= CC_Z)
20#define SET_NFLAG()         (m_ccr |= CC_N)
21#define SET_VFLAG()         (m_ccr |= CC_V)
22
23#define REG_A               m_d.d8.a
24#define REG_B               m_d.d8.b
25#define REG_D               m_d.d16
26
27void mc68hc11_cpu_device::CYCLES(int cycles)
28{
29   m_icount -= cycles;
30}
31
32void mc68hc11_cpu_device::SET_PC(int pc)
33{
34   m_pc = pc;
35}
36
37void mc68hc11_cpu_device::PUSH8(UINT8 value)
38{
39   WRITE8(m_sp--, value);
40}
41
42void mc68hc11_cpu_device::PUSH16(UINT16 value)
43{
44   WRITE8(m_sp--, (value >> 0) & 0xff);
45   WRITE8(m_sp--, (value >> 8) & 0xff);
46}
47
48UINT8 mc68hc11_cpu_device::POP8()
49{
50   return READ8(++m_sp);
51}
52
53UINT16 mc68hc11_cpu_device::POP16()
54{
55   UINT16 r = 0;
56   r |= (READ8(++m_sp) << 8);
57   r |= (READ8(++m_sp) << 0);
58   return r;
59}
60
61
62
63/*****************************************************************************/
64
65/* ABA              0x1B */
66void HC11OP(aba)()
67{
68   UINT16 r = REG_A + REG_B;
69   CLEAR_HNZVC();
70   SET_H(r, REG_B, REG_A);
71   SET_N8(r);
72   SET_Z8(r);
73   SET_V_ADD8(r, REG_B, REG_A);
74   SET_C8(r);
75   REG_A = (UINT8)r;
76   CYCLES(2);
77}
78
79
80/* ABX              0x3A */
81void HC11OP(abx)()
82{
83   m_ix += REG_B;
84   CYCLES(3);
85}
86
87
88/* ABY              0x18, 0x3A */
89void HC11OP(aby)()
90{
91   m_iy += REG_B;
92   CYCLES(4);
93}
94
95
96/* ADCA IMM         0x89 */
97void HC11OP(adca_imm)()
98{
99   UINT8 i = FETCH();
100   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
101   CLEAR_HNZVC();
102   SET_H(r, i, REG_A);
103   SET_N8(r);
104   SET_Z8(r);
105   SET_V_ADD8(r, i, REG_A);
106   SET_C8(r);
107   REG_A = (UINT8)r;
108   CYCLES(2);
109}
110
111/* ADCA DIR         0x99 */
112void HC11OP(adca_dir)()
113{
114   UINT8 d = FETCH();
115   UINT8 i = READ8(d);
116   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
117   CLEAR_HNZVC();
118   SET_H(r, i, REG_A);
119   SET_N8(r);
120   SET_Z8(r);
121   SET_V_ADD8(r, i, REG_A);
122   SET_C8(r);
123   REG_A = (UINT8)r;
124   CYCLES(3);
125}
126
127/* ADCA EXT         0xB9 */
128void HC11OP(adca_ext)()
129{
130   UINT16 adr = FETCH16();
131   UINT8 i = READ8(adr);
132   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
133   CLEAR_HNZVC();
134   SET_H(r, i, REG_A);
135   SET_N8(r);
136   SET_Z8(r);
137   SET_V_ADD8(r, i, REG_A);
138   SET_C8(r);
139   REG_A = (UINT8)r;
140   CYCLES(4);
141}
142
143/* ADCA IND, X      0xA9 */
144void HC11OP(adca_indx)()
145{
146   UINT8 offset = FETCH();
147   UINT8 i = READ8(m_ix + offset);
148   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
149   CLEAR_HNZVC();
150   SET_H(r, i, REG_A);
151   SET_N8(r);
152   SET_Z8(r);
153   SET_V_ADD8(r, i, REG_A);
154   SET_C8(r);
155   REG_A = (UINT8)r;
156   CYCLES(4);
157}
158
159/* ADCA IND, Y      0x18, 0xA9 */
160void HC11OP(adca_indy)()
161{
162   UINT8 offset = FETCH();
163   UINT8 i = READ8(m_iy + offset);
164   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
165   CLEAR_HNZVC();
166   SET_H(r, i, REG_A);
167   SET_N8(r);
168   SET_Z8(r);
169   SET_V_ADD8(r, i, REG_A);
170   SET_C8(r);
171   REG_A = (UINT8)r;
172   CYCLES(5);
173}
174
175
176/* ADCB IMM         0xC9 */
177void HC11OP(adcb_imm)()
178{
179   UINT8 i = FETCH();
180   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
181   CLEAR_HNZVC();
182   SET_H(r, i, REG_B);
183   SET_N8(r);
184   SET_Z8(r);
185   SET_V_ADD8(r, i, REG_B);
186   SET_C8(r);
187   REG_B = (UINT8)r;
188   CYCLES(2);
189}
190
191/* ADCB DIR         0xD9 */
192void HC11OP(adcb_dir)()
193{
194   UINT8 d = FETCH();
195   UINT8 i = READ8(d);
196   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
197   CLEAR_HNZVC();
198   SET_H(r, i, REG_B);
199   SET_N8(r);
200   SET_Z8(r);
201   SET_V_ADD8(r, i, REG_B);
202   SET_C8(r);
203   REG_B = (UINT8)r;
204   CYCLES(3);
205}
206
207/* ADCB EXT         0xF9 */
208void HC11OP(adcb_ext)()
209{
210   UINT16 adr = FETCH16();
211   UINT8 i = READ8(adr);
212   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
213   CLEAR_HNZVC();
214   SET_H(r, i, REG_B);
215   SET_N8(r);
216   SET_Z8(r);
217   SET_V_ADD8(r, i, REG_B);
218   SET_C8(r);
219   REG_B = (UINT8)r;
220   CYCLES(4);
221}
222
223/* ADCB IND, X      0xE9 */
224void HC11OP(adcb_indx)()
225{
226   UINT8 offset = FETCH();
227   UINT8 i = READ8(m_ix + offset);
228   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
229   CLEAR_HNZVC();
230   SET_H(r, i, REG_B);
231   SET_N8(r);
232   SET_Z8(r);
233   SET_V_ADD8(r, i, REG_B);
234   SET_C8(r);
235   REG_B = (UINT8)r;
236   CYCLES(4);
237}
238
239/* ADCB IND, Y      0x18, 0xE9 */
240void HC11OP(adcb_indy)()
241{
242   UINT8 offset = FETCH();
243   UINT8 i = READ8(m_iy + offset);
244   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
245   CLEAR_HNZVC();
246   SET_H(r, i, REG_B);
247   SET_N8(r);
248   SET_Z8(r);
249   SET_V_ADD8(r, i, REG_B);
250   SET_C8(r);
251   REG_B = (UINT8)r;
252   CYCLES(5);
253}
254
255
256/* ADDA IMM         0x8B */
257void HC11OP(adda_imm)()
258{
259   UINT8 i = FETCH();
260   UINT16 r = REG_A + i;
261   CLEAR_HNZVC();
262   SET_H(r, i, REG_A);
263   SET_N8(r);
264   SET_Z8(r);
265   SET_V_ADD8(r, i, REG_A);
266   SET_C8(r);
267   REG_A = (UINT8)r;
268   CYCLES(2);
269}
270
271/* ADDA DIR         0x9B */
272void HC11OP(adda_dir)()
273{
274   UINT8 d = FETCH();
275   UINT8 i = READ8(d);
276   UINT16 r = REG_A + i;
277   CLEAR_HNZVC();
278   SET_H(r, i, REG_A);
279   SET_N8(r);
280   SET_Z8(r);
281   SET_V_ADD8(r, i, REG_A);
282   SET_C8(r);
283   REG_A = (UINT8)r;
284   CYCLES(3);
285}
286
287/* ADDA EXT         0xBB */
288void HC11OP(adda_ext)()
289{
290   UINT16 adr = FETCH16();
291   UINT8 i = READ8(adr);
292   UINT16 r = REG_A + i;
293   CLEAR_HNZVC();
294   SET_H(r, i, REG_A);
295   SET_N8(r);
296   SET_Z8(r);
297   SET_V_ADD8(r, i, REG_A);
298   SET_C8(r);
299   REG_A = (UINT8)r;
300   CYCLES(4);
301}
302
303/* ADDA IND, X      0xAB */
304void HC11OP(adda_indx)()
305{
306   UINT8 offset = FETCH();
307   UINT8 i = READ8(m_ix + offset);
308   UINT16 r = REG_A + i;
309   CLEAR_HNZVC();
310   SET_H(r, i, REG_A);
311   SET_N8(r);
312   SET_Z8(r);
313   SET_V_ADD8(r, i, REG_A);
314   SET_C8(r);
315   REG_A = (UINT8)r;
316   CYCLES(4);
317}
318
319/* ADDA IND, Y      0x18, 0xAB */
320void HC11OP(adda_indy)()
321{
322   UINT8 offset = FETCH();
323   UINT8 i = READ8(m_iy + offset);
324   UINT16 r = REG_A + i;
325   CLEAR_HNZVC();
326   SET_H(r, i, REG_A);
327   SET_N8(r);
328   SET_Z8(r);
329   SET_V_ADD8(r, i, REG_A);
330   SET_C8(r);
331   REG_A = (UINT8)r;
332   CYCLES(5);
333}
334
335
336/* ADDB IMM         0xCB */
337void HC11OP(addb_imm)()
338{
339   UINT8 i = FETCH();
340   UINT16 r = REG_B + i;
341   CLEAR_HNZVC();
342   SET_H(r, i, REG_B);
343   SET_N8(r);
344   SET_Z8(r);
345   SET_V_ADD8(r, i, REG_B);
346   SET_C8(r);
347   REG_B = (UINT8)r;
348   CYCLES(2);
349}
350
351/* ADDB DIR         0xDB */
352void HC11OP(addb_dir)()
353{
354   UINT8 d = FETCH();
355   UINT8 i = READ8(d);
356   UINT16 r = REG_B + i;
357   CLEAR_HNZVC();
358   SET_H(r, i, REG_B);
359   SET_N8(r);
360   SET_Z8(r);
361   SET_V_ADD8(r, i, REG_B);
362   SET_C8(r);
363   REG_B = (UINT8)r;
364   CYCLES(3);
365}
366
367/* ADDB EXT         0xFB */
368void HC11OP(addb_ext)()
369{
370   UINT16 adr = FETCH16();
371   UINT8 i = READ8(adr);
372   UINT16 r = REG_B + i;
373   CLEAR_HNZVC();
374   SET_H(r, i, REG_B);
375   SET_N8(r);
376   SET_Z8(r);
377   SET_V_ADD8(r, i, REG_B);
378   SET_C8(r);
379   REG_B = (UINT8)r;
380   CYCLES(4);
381}
382
383/* ADDB IND, X      0xEB */
384void HC11OP(addb_indx)()
385{
386   UINT8 offset = FETCH();
387   UINT8 i = READ8(m_ix + offset);
388   UINT16 r = REG_B + i;
389   CLEAR_HNZVC();
390   SET_H(r, i, REG_B);
391   SET_N8(r);
392   SET_Z8(r);
393   SET_V_ADD8(r, i, REG_B);
394   SET_C8(r);
395   REG_B = (UINT8)r;
396   CYCLES(4);
397}
398
399/* ADDB IND, Y      0x18, 0xEB */
400void HC11OP(addb_indy)()
401{
402   UINT8 offset = FETCH();
403   UINT8 i = READ8(m_iy + offset);
404   UINT16 r = REG_B + i;
405   CLEAR_HNZVC();
406   SET_H(r, i, REG_B);
407   SET_N8(r);
408   SET_Z8(r);
409   SET_V_ADD8(r, i, REG_B);
410   SET_C8(r);
411   REG_B = (UINT8)r;
412   CYCLES(5);
413}
414
415
416/* ADDD IMM         0xC3 */
417void HC11OP(addd_imm)()
418{
419   UINT16 i = FETCH16();
420   UINT32 r = REG_D + i;
421   CLEAR_NZVC();
422   SET_N16(r);
423   SET_Z16(r);
424   SET_V_ADD16(r, i, REG_D);
425   SET_C16(r);
426   REG_D = (UINT16)r;
427   CYCLES(4);
428}
429
430/* ADDD DIR         0xD3 */
431void HC11OP(addd_dir)()
432{
433   UINT8 d = FETCH();
434   UINT16 i = READ16(d);
435   UINT32 r = REG_D + i;
436   CLEAR_NZVC();
437   SET_N16(r);
438   SET_Z16(r);
439   SET_V_ADD16(r, i, REG_D);
440   SET_C16(r);
441   REG_D = (UINT16)r;
442   CYCLES(5);
443}
444
445/* ADDD EXT         0xF3 */
446void HC11OP(addd_ext)()
447{
448   UINT16 adr = FETCH16();
449   UINT16 i = READ16(adr);
450   UINT32 r = REG_D + i;
451   CLEAR_NZVC();
452   SET_N16(r);
453   SET_Z16(r);
454   SET_V_ADD16(r, i, REG_D);
455   SET_C16(r);
456   REG_D = (UINT16)r;
457   CYCLES(6);
458}
459
460/* ADDD IND, X      0xE3 */
461void HC11OP(addd_indx)()
462{
463   UINT8 offset = FETCH();
464   UINT16 i = READ16(m_ix + offset);
465   UINT32 r = REG_D + i;
466   CLEAR_NZVC();
467   SET_N16(r);
468   SET_Z16(r);
469   SET_V_ADD16(r, i, REG_D);
470   SET_C16(r);
471   REG_D = (UINT16)r;
472   CYCLES(6);
473}
474
475/* ADDD IND, Y      0x18, 0xE3 */
476void HC11OP(addd_indy)()
477{
478   UINT8 offset = FETCH();
479   UINT16 i = READ16(m_iy + offset);
480   UINT32 r = REG_D + i;
481   CLEAR_NZVC();
482   SET_N16(r);
483   SET_Z16(r);
484   SET_V_ADD16(r, i, REG_D);
485   SET_C16(r);
486   REG_D = (UINT16)r;
487   CYCLES(7);
488}
489
490
491/* ANDA IMM         0x84 */
492void HC11OP(anda_imm)()
493{
494   UINT8 i = FETCH();
495   CLEAR_NZV();
496   REG_A &= i;
497   SET_N8(REG_A);
498   SET_Z8(REG_A);
499   CYCLES(2);
500}
501
502/* ANDA DIR         0x94 */
503void HC11OP(anda_dir)()
504{
505   UINT8 d = FETCH();
506   UINT8 i = READ8(d);
507   CLEAR_NZV();
508   REG_A &= i;
509   SET_N8(REG_A);
510   SET_Z8(REG_A);
511   CYCLES(3);
512}
513
514/* ANDA EXT         0xB4 */
515void HC11OP(anda_ext)()
516{
517   UINT16 adr = FETCH16();
518   UINT8 i = READ8(adr);
519   CLEAR_NZV();
520   REG_A &= i;
521   SET_N8(REG_A);
522   SET_Z8(REG_A);
523   CYCLES(4);
524}
525
526/* ANDA IND, X      0xA4 */
527void HC11OP(anda_indx)()
528{
529   UINT8 offset = FETCH();
530   UINT8 i = READ8(m_ix + offset);
531   CLEAR_NZV();
532   REG_A &= i;
533   SET_N8(REG_A);
534   SET_Z8(REG_A);
535   CYCLES(4);
536}
537
538/* ANDA IND, Y      0x18, 0xA4 */
539void HC11OP(anda_indy)()
540{
541   UINT8 offset = FETCH();
542   UINT8 i = READ8(m_iy + offset);
543   CLEAR_NZV();
544   REG_A &= i;
545   SET_N8(REG_A);
546   SET_Z8(REG_A);
547   CYCLES(5);
548}
549
550
551/* ANDB IMM         0xC4 */
552void HC11OP(andb_imm)()
553{
554   UINT8 i = FETCH();
555   CLEAR_NZV();
556   REG_B &= i;
557   SET_N8(REG_B);
558   SET_Z8(REG_B);
559   CYCLES(2);
560}
561
562/* ANDB DIR         0xD4 */
563void HC11OP(andb_dir)()
564{
565   UINT8 d = FETCH();
566   UINT8 i = READ8(d);
567   CLEAR_NZV();
568   REG_B &= i;
569   SET_N8(REG_B);
570   SET_Z8(REG_B);
571   CYCLES(3);
572}
573
574/* ANDB EXT         0xF4 */
575void HC11OP(andb_ext)()
576{
577   UINT16 adr = FETCH16();
578   UINT8 i = READ8(adr);
579   CLEAR_NZV();
580   REG_B &= i;
581   SET_N8(REG_B);
582   SET_Z8(REG_B);
583   CYCLES(4);
584}
585
586/* ANDB IND, X      0xE4 */
587void HC11OP(andb_indx)()
588{
589   UINT8 offset = FETCH();
590   UINT8 i = READ8(m_ix + offset);
591   CLEAR_NZV();
592   REG_B &= i;
593   SET_N8(REG_B);
594   SET_Z8(REG_B);
595   CYCLES(4);
596}
597
598/* ANDB IND, Y      0x18, 0xE4 */
599void HC11OP(andb_indy)()
600{
601   UINT8 offset = FETCH();
602   UINT8 i = READ8(m_iy + offset);
603   CLEAR_NZV();
604   REG_B &= i;
605   SET_N8(REG_B);
606   SET_Z8(REG_B);
607   CYCLES(5);
608}
609
610/* ASLA             0x48 */
611void HC11OP(asla)()
612{
613   UINT16 r = REG_A << 1;
614   CLEAR_NZVC();
615   SET_C8(r);
616   REG_A = (UINT16)(r);
617   SET_N8(REG_A);
618   SET_Z8(REG_A);
619
620   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
621      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
622   {
623      m_ccr |= CC_V;
624   }
625
626   CYCLES(2);
627}
628
629/* ASLB             0x58 */
630void HC11OP(aslb)()
631{
632   UINT16 r = REG_B << 1;
633   CLEAR_NZVC();
634   SET_C8(r);
635   REG_B = (UINT16)(r);
636   SET_N8(REG_B);
637   SET_Z8(REG_B);
638
639   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
640      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
641   {
642      m_ccr |= CC_V;
643   }
644
645   CYCLES(2);
646}
647
648/* ASL EXT             0x78 */
649void HC11OP(asl_ext)()
650{
651   UINT16 adr = FETCH16();
652   UINT8 i = READ8(adr);
653   UINT16 r = i << 1;
654   CLEAR_NZVC();
655   SET_C8(r);
656   WRITE8(adr, r);
657   SET_N8(r);
658   SET_Z8(r);
659
660   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
661      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
662   {
663      m_ccr |= CC_V;
664   }
665
666   CYCLES(6);
667}
668
669/* BITA IMM         0x85 */
670void HC11OP(bita_imm)()
671{
672   UINT8 i = FETCH();
673   UINT8 r = REG_A & i;
674   CLEAR_NZV();
675   SET_N8(r);
676   SET_Z8(r);
677   CYCLES(2);
678}
679
680/* BITA DIR         0x95 */
681void HC11OP(bita_dir)()
682{
683   UINT8 d = FETCH();
684   UINT8 i = READ8(d);
685   UINT8 r = REG_A & i;
686   CLEAR_NZV();
687   SET_N8(r);
688   SET_Z8(r);
689   CYCLES(3);
690}
691
692/* BITA EXT         0xB5 */
693void HC11OP(bita_ext)()
694{
695   UINT16 adr = FETCH16();
696   UINT8 i = READ8(adr);
697   UINT8 r = REG_A & i;
698   CLEAR_NZV();
699   SET_N8(r);
700   SET_Z8(r);
701   CYCLES(4);
702}
703
704/* BITA IND, X      0xA5 */
705void HC11OP(bita_indx)()
706{
707   UINT8 offset = FETCH();
708   UINT8 i = READ8(m_ix + offset);
709   UINT8 r = REG_A & i;
710   CLEAR_NZV();
711   SET_N8(r);
712   SET_Z8(r);
713   CYCLES(4);
714}
715
716/* BITA IND, Y      0x18, 0xA5 */
717void HC11OP(bita_indy)()
718{
719   UINT8 offset = FETCH();
720   UINT8 i = READ8(m_iy + offset);
721   UINT8 r = REG_A & i;
722   CLEAR_NZV();
723   SET_N8(r);
724   SET_Z8(r);
725   CYCLES(5);
726}
727
728
729/* BITB IMM         0xC5 */
730void HC11OP(bitb_imm)()
731{
732   UINT8 i = FETCH();
733   UINT8 r = REG_B & i;
734   CLEAR_NZV();
735   SET_N8(r);
736   SET_Z8(r);
737   CYCLES(2);
738}
739
740/* BITB DIR         0xD5 */
741void HC11OP(bitb_dir)()
742{
743   UINT8 d = FETCH();
744   UINT8 i = READ8(d);
745   UINT8 r = REG_B & i;
746   CLEAR_NZV();
747   SET_N8(r);
748   SET_Z8(r);
749   CYCLES(3);
750}
751
752/* BITB EXT         0xF5 */
753void HC11OP(bitb_ext)()
754{
755   UINT16 adr = FETCH16();
756   UINT8 i = READ8(adr);
757   UINT8 r = REG_B & i;
758   CLEAR_NZV();
759   SET_N8(r);
760   SET_Z8(r);
761   CYCLES(4);
762}
763
764/* BITB IND, X      0xE5 */
765void HC11OP(bitb_indx)()
766{
767   UINT8 offset = FETCH();
768   UINT8 i = READ8(m_ix + offset);
769   UINT8 r = REG_B & i;
770   CLEAR_NZV();
771   SET_N8(r);
772   SET_Z8(r);
773   CYCLES(4);
774}
775
776/* BITB IND, Y      0x18, 0xE5 */
777void HC11OP(bitb_indy)()
778{
779   UINT8 offset = FETCH();
780   UINT8 i = READ8(m_iy + offset);
781   UINT8 r = REG_B & i;
782   CLEAR_NZV();
783   SET_N8(r);
784   SET_Z8(r);
785   CYCLES(5);
786}
787
788/* BCC              0x24 */
789void HC11OP(bcc)()
790{
791   INT8 rel = FETCH();
792   if ((m_ccr & CC_C) == 0)    /* Branch if C flag clear */
793   {
794      SET_PC(m_ppc + rel + 2);
795   }
796   CYCLES(3);
797}
798
799/* BCLR DIR       0x15 */
800void HC11OP(bclr_dir)()
801{
802   UINT8 d = FETCH();
803   UINT8 mask = FETCH();
804   UINT8 r = READ8(d) & ~mask;
805   WRITE8(d, r);
806   CLEAR_NZV();
807   SET_N8(r);
808   SET_Z8(r);
809   CYCLES(6);
810}
811
812/* BCLR INDX       0x1d */
813void HC11OP(bclr_indx)()
814{
815   UINT8 offset = FETCH();
816   UINT8 mask = FETCH();
817   UINT8 r = READ8(m_ix + offset) & ~mask;
818   WRITE8(m_ix + offset, r);
819   CLEAR_NZV();
820   SET_N8(r);
821   SET_Z8(r);
822
823   CYCLES(7);
824}
825
826/* BCS              0x25 */
827void HC11OP(bcs)()
828{
829   INT8 rel = FETCH();
830   if (m_ccr & CC_C)           /* Branch if C flag set */
831   {
832      SET_PC(m_ppc + rel + 2);
833   }
834   CYCLES(3);
835}
836
837
838/* BEQ              0x27 */
839void HC11OP(beq)()
840{
841   INT8 rel = FETCH();
842   if (m_ccr & CC_Z)           /* Branch if Z flag set */
843   {
844      SET_PC(m_ppc + rel + 2);
845   }
846   CYCLES(3);
847}
848
849
850/* BHI              0x22 */
851void HC11OP(bhi)()
852{
853   INT8 rel = FETCH();
854   if (((m_ccr & CC_C) == 0) && ((m_ccr & CC_Z) == 0)) /* Branch if C and Z flag clear */
855   {
856      SET_PC(m_ppc + rel + 2);
857   }
858   CYCLES(3);
859}
860
861
862/* BNE              0x26 */
863void HC11OP(bne)()
864{
865   INT8 rel = FETCH();
866   if ((m_ccr & CC_Z) == 0)        /* Branch if Z flag clear */
867   {
868      SET_PC(m_ppc + rel + 2);
869   }
870   CYCLES(3);
871}
872
873
874/* BLE              0x2F */
875void HC11OP(ble)()
876{
877   UINT8 n = (m_ccr & CC_N) ? 1 : 0;
878   UINT8 v = (m_ccr & CC_V) ? 1 : 0;
879   INT8 rel = FETCH();
880   if ((m_ccr & CC_Z) || (n ^ v))  /* Branch if Z flag set or (N ^ V) */
881   {
882      SET_PC(m_ppc + rel + 2);
883   }
884   CYCLES(3);
885}
886
887/* BLS              0x23 */
888void HC11OP(bls)()
889{
890   INT8 rel = FETCH();
891   if (m_ccr & CC_C || m_ccr & CC_Z)   /* Branch if C or Z flag set */
892   {
893      SET_PC(m_ppc + rel + 2);
894   }
895   CYCLES(3);
896}
897
898/* BMI              0x2B */
899void HC11OP(bmi)()
900{
901   INT8 rel = FETCH();
902   if (m_ccr & CC_N)       /* Branch if N flag set */
903   {
904      SET_PC(m_ppc + rel + 2);
905   }
906   CYCLES(3);
907}
908
909/* BPL              0x2A */
910void HC11OP(bpl)()
911{
912   INT8 rel = FETCH();
913   if ((m_ccr & CC_N) == 0)        /* Branch if N flag clear */
914   {
915      SET_PC(m_ppc + rel + 2);
916   }
917   CYCLES(3);
918}
919
920
921/* BRA              0x20 */
922void HC11OP(bra)()
923{
924   INT8 rel = FETCH();
925   SET_PC(m_ppc + rel + 2);
926   CYCLES(3);
927}
928
929/* BRCLR DIR       0x13 */
930void HC11OP(brclr_dir)()
931{
932   UINT8 d = FETCH();
933   UINT8 mask = FETCH();
934   INT8 rel = FETCH();
935   UINT8 i = READ8(d);
936
937   if ((i & mask) == 0)
938   {
939      SET_PC(m_ppc + rel + 4);
940   }
941
942   CYCLES(6);
943}
944
945
946/* BRCLR INDX       0x1F */
947void HC11OP(brclr_indx)()
948{
949   UINT8 offset = FETCH();
950   UINT8 mask = FETCH();
951   INT8 rel = FETCH();
952   UINT8 i = READ8(m_ix + offset);
953
954   if ((i & mask) == 0)
955   {
956      SET_PC(m_ppc + rel + 4);
957   }
958
959   CYCLES(7);
960}
961
962/* BRSET DIR       0x12 */
963void HC11OP(brset_dir)()
964{
965   UINT8 d = FETCH();
966   UINT8 mask = FETCH();
967   INT8 rel = FETCH();
968   UINT8 i = READ8(d);
969
970   if(i & mask)
971   {
972      SET_PC(m_ppc + rel + 4);
973   }
974
975   CYCLES(6);
976}
977
978
979/* BRSET INDX       0x1E */
980void HC11OP(brset_indx)()
981{
982   UINT8 offset = FETCH();
983   UINT8 mask = FETCH();
984   INT8 rel = FETCH();
985   UINT8 i = READ8(m_ix + offset);
986
987   if ((~i & mask) == 0)
988   {
989      SET_PC(m_ppc + rel + 4);
990   }
991
992   CYCLES(7);
993}
994
995
996/* BRN              0x21 */
997void HC11OP(brn)()
998{
999   /* with this opcode the branch condition is always false. */
1000   SET_PC(m_ppc + 2);
1001   CYCLES(3);
1002}
1003
1004/* BSET DIR       0x14 */
1005void HC11OP(bset_dir)()
1006{
1007   UINT8 d = FETCH();
1008   UINT8 mask = FETCH();
1009   UINT8 r = READ8(d) | mask;
1010   WRITE8(d, r);
1011   CLEAR_NZV();
1012   SET_N8(r);
1013   SET_Z8(r);
1014   CYCLES(6);
1015}
1016
1017/* BSET INDX       0x1c */
1018void HC11OP(bset_indx)()
1019{
1020   UINT8 offset = FETCH();
1021   UINT8 mask = FETCH();
1022   UINT8 r = READ8(m_ix + offset) | mask;
1023   WRITE8(m_ix + offset, r);
1024   CLEAR_NZV();
1025   SET_N8(r);
1026   SET_Z8(r);
1027
1028   CYCLES(7);
1029}
1030
1031/* BSR              0x8D */
1032void HC11OP(bsr)()
1033{
1034   INT8 rel = FETCH();
1035   UINT16 rt_adr = m_pc;
1036   PUSH16(rt_adr);
1037   SET_PC(m_ppc + rel + 2);
1038   CYCLES(6);
1039}
1040
1041/* BVC              0x28 */
1042void HC11OP(bvc)()
1043{
1044   INT8 rel = FETCH();
1045   if ((m_ccr & CC_V) == 0)    /* Branch if V flag clear */
1046   {
1047      SET_PC(m_ppc + rel + 2);
1048   }
1049   CYCLES(3);
1050}
1051
1052/* BVS              0x29 */
1053void HC11OP(bvs)()
1054{
1055   INT8 rel = FETCH();
1056   if (m_ccr & CC_V)   /* Branch if V flag set */
1057   {
1058      SET_PC(m_ppc + rel + 2);
1059   }
1060   CYCLES(3);
1061}
1062
1063/* CBA              0x11 */
1064void HC11OP(cba)()
1065{
1066   UINT16 r = REG_A - REG_B;
1067   CLEAR_NZVC();
1068   SET_N8(r);
1069   SET_Z8(r);
1070   SET_V_SUB8(r, REG_B, REG_A);
1071   SET_C8(r);
1072   CYCLES(2);
1073}
1074
1075/* CLC              0x0C */
1076void HC11OP(clc)()
1077{
1078   m_ccr &= ~CC_C;
1079   CYCLES(2);
1080}
1081
1082
1083/* CLI              0x0E */
1084void HC11OP(cli)()
1085{
1086   m_ccr &= ~CC_I;
1087   CYCLES(2);
1088}
1089
1090
1091/* CLRA             0x4F */
1092void HC11OP(clra)()
1093{
1094   REG_A = 0;
1095   CLEAR_NZVC();
1096   SET_ZFLAG();
1097   CYCLES(2);
1098}
1099
1100/* CLRB             0x5F */
1101void HC11OP(clrb)()
1102{
1103   REG_B = 0;
1104   CLEAR_NZVC();
1105   SET_ZFLAG();
1106   CYCLES(2);
1107}
1108
1109/* CLR EXT          0x7F */
1110void HC11OP(clr_ext)()
1111{
1112   UINT16 adr = FETCH16();
1113   WRITE8(adr, 0);
1114   CLEAR_NZVC();
1115   SET_ZFLAG();
1116   CYCLES(6);
1117}
1118
1119/* CLR IND, X       0x6F */
1120void HC11OP(clr_indx)()
1121{
1122   UINT8 offset = FETCH();
1123   WRITE8(m_ix + offset, 0);
1124   CLEAR_NZVC();
1125   SET_ZFLAG();
1126   CYCLES(6);
1127}
1128
1129/* CLR IND, Y       0x18, 0x6F */
1130void HC11OP(clr_indy)()
1131{
1132   UINT8 offset = FETCH();
1133   WRITE8(m_iy + offset, 0);
1134   CLEAR_NZVC();
1135   SET_ZFLAG();
1136   CYCLES(7);
1137}
1138
1139
1140/* CLV              0x0A */
1141void HC11OP(clv)()
1142{
1143   m_ccr &= ~CC_V;
1144   CYCLES(2);
1145}
1146
1147
1148/* CMPA IMM         0x81 */
1149void HC11OP(cmpa_imm)()
1150{
1151   UINT8 i = FETCH();
1152   UINT16 r = REG_A - i;
1153   CLEAR_NZVC();
1154   SET_N8(r);
1155   SET_Z8(r);
1156   SET_V_SUB8(r, i, REG_A);
1157   SET_C8(r);
1158   CYCLES(2);
1159}
1160
1161/* CMPA DIR         0x91 */
1162void HC11OP(cmpa_dir)()
1163{
1164   UINT8 d = FETCH();
1165   UINT8 i = READ8(d);
1166   UINT16 r = REG_A - i;
1167   CLEAR_NZVC();
1168   SET_N8(r);
1169   SET_Z8(r);
1170   SET_V_SUB8(r, i, REG_A);
1171   SET_C8(r);
1172   CYCLES(3);
1173}
1174
1175/* CMPA EXT         0xB1 */
1176void HC11OP(cmpa_ext)()
1177{
1178   UINT16 adr = FETCH16();
1179   UINT8 i = READ8(adr);
1180   UINT16 r = REG_A - i;
1181   CLEAR_NZVC();
1182   SET_N8(r);
1183   SET_Z8(r);
1184   SET_V_SUB8(r, i, REG_A);
1185   SET_C8(r);
1186   CYCLES(4);
1187}
1188
1189/* CMPA IND, X      0xA1 */
1190void HC11OP(cmpa_indx)()
1191{
1192   UINT8 offset = FETCH();
1193   UINT8 i = READ8(m_ix + offset);
1194   UINT16 r = REG_A - i;
1195   CLEAR_NZVC();
1196   SET_N8(r);
1197   SET_Z8(r);
1198   SET_V_SUB8(r, i, REG_A);
1199   SET_C8(r);
1200   CYCLES(4);
1201}
1202
1203/* CMPA IND, Y      0x18, 0xA1 */
1204void HC11OP(cmpa_indy)()
1205{
1206   UINT8 offset = FETCH();
1207   UINT8 i = READ8(m_iy + offset);
1208   UINT16 r = REG_A - i;
1209   CLEAR_NZVC();
1210   SET_N8(r);
1211   SET_Z8(r);
1212   SET_V_SUB8(r, i, REG_A);
1213   SET_C8(r);
1214   CYCLES(5);
1215}
1216
1217
1218/* CMPB IMM         0xC1 */
1219void HC11OP(cmpb_imm)()
1220{
1221   UINT8 i = FETCH();
1222   UINT16 r = REG_B - i;
1223   CLEAR_NZVC();
1224   SET_N8(r);
1225   SET_Z8(r);
1226   SET_V_SUB8(r, i, REG_B);
1227   SET_C8(r);
1228   CYCLES(2);
1229}
1230
1231/* CMPB DIR         0xD1 */
1232void HC11OP(cmpb_dir)()
1233{
1234   UINT8 d = FETCH();
1235   UINT8 i = READ8(d);
1236   UINT16 r = REG_B - i;
1237   CLEAR_NZVC();
1238   SET_N8(r);
1239   SET_Z8(r);
1240   SET_V_SUB8(r, i, REG_B);
1241   SET_C8(r);
1242   CYCLES(3);
1243}
1244
1245/* CMPB EXT         0xF1 */
1246void HC11OP(cmpb_ext)()
1247{
1248   UINT16 adr = FETCH16();
1249   UINT8 i = READ8(adr);
1250   UINT16 r = REG_B - i;
1251   CLEAR_NZVC();
1252   SET_N8(r);
1253   SET_Z8(r);
1254   SET_V_SUB8(r, i, REG_B);
1255   SET_C8(r);
1256   CYCLES(4);
1257}
1258
1259/* CMPB IND, X      0xE1 */
1260void HC11OP(cmpb_indx)()
1261{
1262   UINT8 offset = FETCH();
1263   UINT8 i = READ8(m_ix + offset);
1264   UINT16 r = REG_B - i;
1265   CLEAR_NZVC();
1266   SET_N8(r);
1267   SET_Z8(r);
1268   SET_V_SUB8(r, i, REG_B);
1269   SET_C8(r);
1270   CYCLES(4);
1271}
1272
1273/* CMPB IND, Y      0x18, 0xE1 */
1274void HC11OP(cmpb_indy)()
1275{
1276   UINT8 offset = FETCH();
1277   UINT8 i = READ8(m_iy + offset);
1278   UINT16 r = REG_B - i;
1279   CLEAR_NZVC();
1280   SET_N8(r);
1281   SET_Z8(r);
1282   SET_V_SUB8(r, i, REG_B);
1283   SET_C8(r);
1284   CYCLES(5);
1285}
1286
1287
1288/* COMA              , 0x43 */
1289void HC11OP(coma)()
1290{
1291   UINT16 r = 0xff - REG_A;
1292   CLEAR_NZVC();
1293   SET_N8(r);
1294   SET_Z8(r);
1295   m_ccr |= CC_C; //always set for M6800 compatibility
1296   REG_A = r;
1297   CYCLES(2);
1298}
1299
1300
1301/* COMB              , 0x53 */
1302void HC11OP(comb)()
1303{
1304   UINT16 r = 0xff - REG_B;
1305   CLEAR_NZVC();
1306   SET_N8(r);
1307   SET_Z8(r);
1308   m_ccr |= CC_C; //always set for M6800 compatibility
1309   REG_B = r;
1310   CYCLES(2);
1311}
1312
1313
1314/* CPD IMM          0x1A, 0x83 */
1315void HC11OP(cpd_imm)()
1316{
1317   UINT16 i = FETCH16();
1318   UINT32 r = REG_D - i;
1319   CLEAR_NZVC();
1320   SET_N16(r);
1321   SET_Z16(r);
1322   SET_V_SUB16(r, i, REG_D);
1323   SET_C16(r);
1324   CYCLES(5);
1325}
1326
1327/* CPD DIR          0x1A, 0x93 */
1328void HC11OP(cpd_dir)()
1329{
1330   UINT8 d = FETCH();
1331   UINT16 i = READ16(d);
1332   UINT32 r = REG_D - i;
1333   CLEAR_NZVC();
1334   SET_N16(r);
1335   SET_Z16(r);
1336   SET_V_SUB16(r, i, REG_D);
1337   SET_C16(r);
1338   CYCLES(6);
1339}
1340
1341/* CPD EXT          0x1A, 0xB3 */
1342void HC11OP(cpd_ext)()
1343{
1344   UINT16 adr = FETCH16();
1345   UINT16 i = READ16(adr);
1346   UINT32 r = REG_D - i;
1347   CLEAR_NZVC();
1348   SET_N16(r);
1349   SET_Z16(r);
1350   SET_V_SUB16(r, i, REG_D);
1351   SET_C16(r);
1352   CYCLES(7);
1353}
1354
1355/* CPD IND, X       0x1A, 0xA3 */
1356void HC11OP(cpd_indx)()
1357{
1358   UINT8 offset = FETCH();
1359   UINT16 i = READ16(m_ix + offset);
1360   UINT32 r = REG_D - i;
1361   CLEAR_NZVC();
1362   SET_N16(r);
1363   SET_Z16(r);
1364   SET_V_SUB16(r, i, REG_D);
1365   SET_C16(r);
1366   CYCLES(7);
1367}
1368
1369/* CPD IND, Y       0xCD, 0xA3 */
1370void HC11OP(cpd_indy)()
1371{
1372   UINT8 offset = FETCH();
1373   UINT16 i = READ16(m_iy + offset);
1374   UINT32 r = REG_D - i;
1375   CLEAR_NZVC();
1376   SET_N16(r);
1377   SET_Z16(r);
1378   SET_V_SUB16(r, i, REG_D);
1379   SET_C16(r);
1380   CYCLES(7);
1381}
1382
1383
1384/* CPX IMM          0x8C */
1385void HC11OP(cpx_imm)()
1386{
1387   UINT16 i = FETCH16();
1388   UINT32 r = m_ix - i;
1389   CLEAR_NZVC();
1390   SET_N16(r);
1391   SET_Z16(r);
1392   SET_V_SUB16(r, i, m_ix);
1393   SET_C16(r);
1394   CYCLES(4);
1395}
1396
1397/* CPX DIR          0x9C */
1398void HC11OP(cpx_dir)()
1399{
1400   UINT8 d = FETCH();
1401   UINT16 i = READ16(d);
1402   UINT32 r = m_ix - i;
1403   CLEAR_NZVC();
1404   SET_N16(r);
1405   SET_Z16(r);
1406   SET_V_SUB16(r, i, m_ix);
1407   SET_C16(r);
1408   CYCLES(5);
1409}
1410
1411/* CPX EXT          0xBC */
1412void HC11OP(cpx_ext)()
1413{
1414   UINT16 adr = FETCH16();
1415   UINT16 i = READ16(adr);
1416   UINT32 r = m_ix - i;
1417   CLEAR_NZVC();
1418   SET_N16(r);
1419   SET_Z16(r);
1420   SET_V_SUB16(r, i, m_ix);
1421   SET_C16(r);
1422   CYCLES(6);
1423}
1424
1425/* CPX IND, X       0xAC */
1426void HC11OP(cpx_indx)()
1427{
1428   UINT8 offset = FETCH();
1429   UINT16 i = READ16(m_ix + offset);
1430   UINT32 r = m_ix - i;
1431   CLEAR_NZVC();
1432   SET_N16(r);
1433   SET_Z16(r);
1434   SET_V_SUB16(r, i, m_ix);
1435   SET_C16(r);
1436   CYCLES(6);
1437}
1438
1439/* CPX IND, Y       0xCD, 0xAC */
1440void HC11OP(cpx_indy)()
1441{
1442   UINT8 offset = FETCH();
1443   UINT16 i = READ16(m_iy + offset);
1444   UINT32 r = m_ix - i;
1445   CLEAR_NZVC();
1446   SET_N16(r);
1447   SET_Z16(r);
1448   SET_V_SUB16(r, i, m_ix);
1449   SET_C16(r);
1450   CYCLES(7);
1451}
1452
1453/* CPY IMM          0x18, 0x8C */
1454void HC11OP(cpy_imm)()
1455{
1456   UINT16 i = FETCH16();
1457   UINT32 r = m_iy - i;
1458   CLEAR_NZVC();
1459   SET_N16(r);
1460   SET_Z16(r);
1461   SET_V_SUB16(r, i, m_iy);
1462   SET_C16(r);
1463   CYCLES(5);
1464}
1465
1466/* CPY DIR          0x18 0x9C */
1467void HC11OP(cpy_dir)()
1468{
1469   UINT8 d = FETCH();
1470   UINT16 i = READ16(d);
1471   UINT32 r = m_iy - i;
1472   CLEAR_NZVC();
1473   SET_N16(r);
1474   SET_Z16(r);
1475   SET_V_SUB16(r, i, m_iy);
1476   SET_C16(r);
1477   CYCLES(6);
1478}
1479
1480/* CPY EXT          0x18 0xBC */
1481void HC11OP(cpy_ext)()
1482{
1483   UINT16 adr = FETCH16();
1484   UINT16 i = READ16(adr);
1485   UINT32 r = m_iy - i;
1486   CLEAR_NZVC();
1487   SET_N16(r);
1488   SET_Z16(r);
1489   SET_V_SUB16(r, i, m_iy);
1490   SET_C16(r);
1491   CYCLES(7);
1492}
1493
1494/* CPY IND, X       0x1A 0xAC */
1495void HC11OP(cpy_indx)()
1496{
1497   UINT8 offset = FETCH();
1498   UINT16 i = READ16(m_ix + offset);
1499   UINT32 r = m_iy - i;
1500   CLEAR_NZVC();
1501   SET_N16(r);
1502   SET_Z16(r);
1503   SET_V_SUB16(r, i, m_iy);
1504   SET_C16(r);
1505   CYCLES(7);
1506}
1507
1508/* CPY IND, Y       0x18 0xAC */
1509void HC11OP(cpy_indy)()
1510{
1511   UINT8 offset = FETCH();
1512   UINT16 i = READ16(m_iy + offset);
1513   UINT32 r = m_iy - i;
1514   CLEAR_NZVC();
1515   SET_N16(r);
1516   SET_Z16(r);
1517   SET_V_SUB16(r, i, m_iy);
1518   SET_C16(r);
1519   CYCLES(7);
1520}
1521
1522/* DECA             0x4A */
1523void HC11OP(deca)()
1524{
1525   CLEAR_NZV();
1526   if (REG_A == 0x80)
1527      SET_VFLAG();
1528   REG_A--;
1529   SET_N8(REG_A);
1530   SET_Z8(REG_A);
1531   CYCLES(2);
1532}
1533
1534/* DECB             0x5A */
1535void HC11OP(decb)()
1536{
1537   CLEAR_NZV();
1538   if (REG_B == 0x80)
1539      SET_VFLAG();
1540   REG_B--;
1541   SET_N8(REG_B);
1542   SET_Z8(REG_B);
1543   CYCLES(2);
1544}
1545
1546/* DEC EXT          0x7A */
1547void HC11OP(dec_ext)()
1548{
1549   UINT16 adr = FETCH16();
1550   UINT8 i = READ8(adr);
1551
1552   CLEAR_NZV();
1553   if (i == 0x80)
1554      SET_VFLAG();
1555   i--;
1556   SET_N8(i);
1557   SET_Z8(i);
1558   WRITE8(adr, i);
1559   CYCLES(6);
1560}
1561
1562/* DEC INDX          0x6A */
1563void HC11OP(dec_indx)()
1564{
1565   UINT8 offset = FETCH();
1566   UINT8 i = READ8(m_ix + offset);
1567
1568   CLEAR_NZV();
1569   if (i == 0x80)
1570      SET_VFLAG();
1571   i--;
1572   SET_N8(i);
1573   SET_Z8(i);
1574   WRITE8(m_ix + offset, i);
1575   CYCLES(6);
1576}
1577
1578/* DEC INDY          0x18 0x6A */
1579void HC11OP(dec_indy)()
1580{
1581   UINT8 offset = FETCH();
1582   UINT8 i = READ8(m_iy + offset);
1583
1584   CLEAR_NZV();
1585   if (i == 0x80)
1586      SET_VFLAG();
1587   i--;
1588   SET_N8(i);
1589   SET_Z8(i);
1590   WRITE8(m_iy + offset, i);
1591   CYCLES(7);
1592}
1593
1594/* DEX              0x09 */
1595void HC11OP(dex)()
1596{
1597   CLEAR_Z();
1598   m_ix--;
1599   SET_Z16(m_ix);
1600   CYCLES(3);
1601}
1602
1603
1604/* DEY              0x18, 0x09 */
1605void HC11OP(dey)()
1606{
1607   CLEAR_Z();
1608   m_iy--;
1609   SET_Z16(m_iy);
1610   CYCLES(4);
1611}
1612
1613
1614/* EORA IMM         0x88 */
1615void HC11OP(eora_imm)()
1616{
1617   UINT8 i = FETCH();
1618   CLEAR_NZV();
1619   REG_A ^= i;
1620   SET_N8(REG_A);
1621   SET_Z8(REG_A);
1622   CYCLES(2);
1623}
1624
1625/* EORA DIR         0x98 */
1626void HC11OP(eora_dir)()
1627{
1628   UINT8 d = FETCH();
1629   UINT8 i = READ8(d);
1630   CLEAR_NZV();
1631   REG_A ^= i;
1632   SET_N8(REG_A);
1633   SET_Z8(REG_A);
1634   CYCLES(3);
1635}
1636
1637/* EORA EXT         0xB8 */
1638void HC11OP(eora_ext)()
1639{
1640   UINT16 adr = FETCH16();
1641   UINT8 i = READ8(adr);
1642   CLEAR_NZV();
1643   REG_A ^= i;
1644   SET_N8(REG_A);
1645   SET_Z8(REG_A);
1646   CYCLES(4);
1647}
1648
1649/* EORA IND, X      0xA8 */
1650void HC11OP(eora_indx)()
1651{
1652   UINT8 offset = FETCH();
1653   UINT8 i = READ8(m_ix + offset);
1654   CLEAR_NZV();
1655   REG_A ^= i;
1656   SET_N8(REG_A);
1657   SET_Z8(REG_A);
1658   CYCLES(4);
1659}
1660
1661/* EORA IND, Y      0x18, 0xA8 */
1662void HC11OP(eora_indy)()
1663{
1664   UINT8 offset = FETCH();
1665   UINT8 i = READ8(m_iy + offset);
1666   CLEAR_NZV();
1667   REG_A ^= i;
1668   SET_N8(REG_A);
1669   SET_Z8(REG_A);
1670   CYCLES(5);
1671}
1672
1673
1674/* EORB IMM         0xC8 */
1675void HC11OP(eorb_imm)()
1676{
1677   UINT8 i = FETCH();
1678   CLEAR_NZV();
1679   REG_B ^= i;
1680   SET_N8(REG_B);
1681   SET_Z8(REG_B);
1682   CYCLES(2);
1683}
1684
1685/* EORB DIR         0xD8 */
1686void HC11OP(eorb_dir)()
1687{
1688   UINT8 d = FETCH();
1689   UINT8 i = READ8(d);
1690   CLEAR_NZV();
1691   REG_B ^= i;
1692   SET_N8(REG_B);
1693   SET_Z8(REG_B);
1694   CYCLES(3);
1695}
1696
1697/* EORB EXT         0xF8 */
1698void HC11OP(eorb_ext)()
1699{
1700   UINT16 adr = FETCH16();
1701   UINT8 i = READ8(adr);
1702   CLEAR_NZV();
1703   REG_B ^= i;
1704   SET_N8(REG_B);
1705   SET_Z8(REG_B);
1706   CYCLES(4);
1707}
1708
1709/* EORB IND, X      0xE8 */
1710void HC11OP(eorb_indx)()
1711{
1712   UINT8 offset = FETCH();
1713   UINT8 i = READ8(m_ix + offset);
1714   CLEAR_NZV();
1715   REG_B ^= i;
1716   SET_N8(REG_B);
1717   SET_Z8(REG_B);
1718   CYCLES(4);
1719}
1720
1721/* EORB IND, Y      0x18, 0xE8 */
1722void HC11OP(eorb_indy)()
1723{
1724   UINT8 offset = FETCH();
1725   UINT8 i = READ8(m_iy + offset);
1726   CLEAR_NZV();
1727   REG_B ^= i;
1728   SET_N8(REG_B);
1729   SET_Z8(REG_B);
1730   CYCLES(5);
1731}
1732
1733/* IDIV             0x02 */
1734void HC11OP(idiv)()
1735{
1736   UINT16 numerator = REG_D;
1737   UINT16 denominator = m_ix;
1738   UINT16 remainder;
1739   UINT16 result;
1740
1741   CLEAR_ZVC();
1742   if(denominator == 0) // divide by zero behaviour
1743   {
1744      remainder = 0xffff; // TODO: undefined behaviour according to the docs
1745      result = 0xffff;
1746      logerror("HC11: divide by zero at PC=%04x\n",m_pc-1);
1747      m_ccr |= CC_C;
1748   }
1749   else
1750   {
1751      remainder = numerator % denominator;
1752      result = numerator / denominator;
1753   }
1754   m_ix = result;
1755   REG_D = remainder;
1756   SET_Z16(result);
1757
1758   CYCLES(41);
1759}
1760
1761/* INCA             0x4C */
1762void HC11OP(inca)()
1763{
1764   CLEAR_NZV();
1765   if (REG_A == 0x7f)
1766      SET_VFLAG();
1767   REG_A++;
1768   SET_N8(REG_A);
1769   SET_Z8(REG_A);
1770   CYCLES(2);
1771}
1772
1773/* INCB             0x5C */
1774void HC11OP(incb)()
1775{
1776   CLEAR_NZV();
1777   if (REG_B == 0x7f)
1778      SET_VFLAG();
1779   REG_B++;
1780   SET_N8(REG_B);
1781   SET_Z8(REG_B);
1782   CYCLES(2);
1783}
1784
1785/* INC EXT          0x7C */
1786void HC11OP(inc_ext)()
1787{
1788   UINT16 adr = FETCH16();
1789   UINT8 i = READ8(adr);
1790
1791   CLEAR_NZV();
1792   if (i == 0x7f)
1793      SET_VFLAG();
1794   i++;
1795   SET_N8(i);
1796   SET_Z8(i);
1797   WRITE8(adr, i);
1798   CYCLES(6);
1799}
1800
1801/* INC INDX          0x6C */
1802void HC11OP(inc_indx)()
1803{
1804   UINT8 offset = FETCH();
1805   UINT8 i = READ8(m_ix + offset);
1806
1807   CLEAR_NZV();
1808   if (i == 0x7f)
1809      SET_VFLAG();
1810   i++;
1811   SET_N8(i);
1812   SET_Z8(i);
1813   WRITE8(m_ix + offset, i);
1814   CYCLES(6);
1815}
1816
1817
1818/* INC INDY          0x18 0x6C */
1819void HC11OP(inc_indy)()
1820{
1821   UINT8 offset = FETCH();
1822   UINT8 i = READ8(m_iy + offset);
1823
1824   CLEAR_NZV();
1825   if (i == 0x7f)
1826      SET_VFLAG();
1827   i++;
1828   SET_N8(i);
1829   SET_Z8(i);
1830   WRITE8(m_iy + offset, i);
1831   CYCLES(7);
1832}
1833
1834
1835/* INX              0x08 */
1836void HC11OP(inx)()
1837{
1838   CLEAR_Z();
1839   m_ix++;
1840   SET_Z16(m_ix);
1841   CYCLES(3);
1842}
1843
1844/* INY              0x18, 0x08 */
1845void HC11OP(iny)()
1846{
1847   CLEAR_Z();
1848   m_iy++;
1849   SET_Z16(m_iy);
1850   CYCLES(4);
1851}
1852
1853/* JMP IND X        0x6E */
1854void HC11OP(jmp_indx)()
1855{
1856   UINT16 adr = FETCH();
1857   SET_PC(m_ix + adr);
1858   CYCLES(3);
1859}
1860
1861/* JMP IND Y        0x18 0x6E */
1862void HC11OP(jmp_indy)()
1863{
1864   UINT16 adr = FETCH();
1865   SET_PC(m_iy + adr);
1866   CYCLES(4);
1867}
1868
1869/* JMP EXT          0x7E */
1870void HC11OP(jmp_ext)()
1871{
1872   UINT16 adr = FETCH16();
1873   SET_PC(adr);
1874   CYCLES(3);
1875}
1876
1877
1878/* JSR DIR          0x9D */
1879void HC11OP(jsr_dir)()
1880{
1881   UINT8 i = FETCH();
1882   UINT16 rt_adr = m_pc;
1883   PUSH16(rt_adr);
1884   SET_PC(i);
1885   CYCLES(5);
1886}
1887
1888/* JSR EXT          0xBD */
1889void HC11OP(jsr_ext)()
1890{
1891   UINT16 adr = FETCH16();
1892   UINT16 rt_adr = m_pc;
1893   PUSH16(rt_adr);
1894   SET_PC(adr);
1895   CYCLES(6);
1896}
1897
1898/* JSR IND, X       0xAD */
1899void HC11OP(jsr_indx)()
1900{
1901   UINT8 offset = FETCH();
1902   UINT16 rt_adr = m_pc;
1903   PUSH16(rt_adr);
1904   SET_PC(m_ix + offset);
1905   CYCLES(6);
1906}
1907
1908/* JSR IND, Y       0x18, 0xAD */
1909void HC11OP(jsr_indy)()
1910{
1911   UINT8 offset = FETCH();
1912   UINT16 rt_adr = m_pc;
1913   PUSH16(rt_adr);
1914   SET_PC(m_iy + offset);
1915   CYCLES(6);
1916}
1917
1918
1919/* LDAA IMM         0x86 */
1920void HC11OP(ldaa_imm)()
1921{
1922   CLEAR_NZV();
1923   REG_A = FETCH();
1924   SET_N8(REG_A);
1925   SET_Z8(REG_A);
1926   CYCLES(2);
1927}
1928
1929/* LDAA DIR         0x96 */
1930void HC11OP(ldaa_dir)()
1931{
1932   UINT8 d = FETCH();
1933   CLEAR_NZV();
1934   REG_A = READ8(d);
1935   SET_N8(REG_A);
1936   SET_Z8(REG_A);
1937   CYCLES(3);
1938}
1939
1940/* LDAA EXT         0xB6 */
1941void HC11OP(ldaa_ext)()
1942{
1943   UINT16 adr = FETCH16();
1944   CLEAR_NZV();
1945   REG_A = READ8(adr);
1946   SET_N8(REG_A);
1947   SET_Z8(REG_A);
1948   CYCLES(4);
1949}
1950
1951/* LDAA IND, X      0xA6 */
1952void HC11OP(ldaa_indx)()
1953{
1954   UINT8 offset = FETCH();
1955   CLEAR_NZV();
1956   REG_A = READ8(m_ix + offset);
1957   SET_N8(REG_A);
1958   SET_Z8(REG_A);
1959   CYCLES(4);
1960}
1961
1962/* LDAA IND, Y      0x18, 0xA6 */
1963void HC11OP(ldaa_indy)()
1964{
1965   UINT8 offset = FETCH();
1966   CLEAR_NZV();
1967   REG_A = READ8(m_iy + offset);
1968   SET_N8(REG_A);
1969   SET_Z8(REG_A);
1970   CYCLES(5);
1971}
1972
1973/* LDAB IMM         0xC6 */
1974void HC11OP(ldab_imm)()
1975{
1976   CLEAR_NZV();
1977   REG_B = FETCH();
1978   SET_N8(REG_B);
1979   SET_Z8(REG_B);
1980   CYCLES(2);
1981}
1982
1983/* LDAB DIR         0xD6 */
1984void HC11OP(ldab_dir)()
1985{
1986   UINT8 d = FETCH();
1987   CLEAR_NZV();
1988   REG_B = READ8(d);
1989   SET_N8(REG_B);
1990   SET_Z8(REG_B);
1991   CYCLES(3);
1992}
1993
1994/* LDAB EXT         0xF6 */
1995void HC11OP(ldab_ext)()
1996{
1997   UINT16 adr = FETCH16();
1998   CLEAR_NZV();
1999   REG_B = READ8(adr);
2000   SET_N8(REG_B);
2001   SET_Z8(REG_B);
2002   CYCLES(4);
2003}
2004
2005/* LDAB IND, X      0xE6 */
2006void HC11OP(ldab_indx)()
2007{
2008   UINT8 offset = FETCH();
2009   CLEAR_NZV();
2010   REG_B = READ8(m_ix + offset);
2011   SET_N8(REG_B);
2012   SET_Z8(REG_B);
2013   CYCLES(4);
2014}
2015
2016/* LDAB IND, Y      0x18, 0xE6 */
2017void HC11OP(ldab_indy)()
2018{
2019   UINT8 offset = FETCH();
2020   CLEAR_NZV();
2021   REG_B = READ8(m_iy + offset);
2022   SET_N8(REG_B);
2023   SET_Z8(REG_B);
2024   CYCLES(5);
2025}
2026
2027
2028/* LDD IMM          0xCC */
2029void HC11OP(ldd_imm)()
2030{
2031   CLEAR_NZV();
2032   REG_D = FETCH16();
2033   SET_N16(REG_D);
2034   SET_Z16(REG_D);
2035   CYCLES(3);
2036}
2037
2038/* LDD DIR          0xDC */
2039void HC11OP(ldd_dir)()
2040{
2041   UINT8 d = FETCH();
2042   CLEAR_NZV();
2043   REG_D = READ16(d);
2044   SET_N16(REG_D);
2045   SET_Z16(REG_D);
2046   CYCLES(4);
2047}
2048
2049/* LDD EXT          0xFC */
2050void HC11OP(ldd_ext)()
2051{
2052   UINT16 adr = FETCH16();
2053   CLEAR_NZV();
2054   REG_D = READ16(adr);
2055   SET_N16(REG_D);
2056   SET_Z16(REG_D);
2057   CYCLES(5);
2058}
2059
2060/* LDD IND, X       0xEC */
2061void HC11OP(ldd_indx)()
2062{
2063   UINT8 offset = FETCH();
2064   CLEAR_NZV();
2065   REG_D = READ16(m_ix + offset);
2066   SET_N16(REG_D);
2067   SET_Z16(REG_D);
2068   CYCLES(5);
2069}
2070
2071/* LDD IND, Y       0x18, 0xEC */
2072void HC11OP(ldd_indy)()
2073{
2074   UINT8 offset = FETCH();
2075   CLEAR_NZV();
2076   REG_D = READ16(m_iy + offset);
2077   SET_N16(REG_D);
2078   SET_Z16(REG_D);
2079   CYCLES(6);
2080}
2081
2082
2083/* LDS IMM          0x8E */
2084void HC11OP(lds_imm)()
2085{
2086   CLEAR_NZV();
2087   m_sp = FETCH16();
2088   SET_N16(m_sp);
2089   SET_Z16(m_sp);
2090   CYCLES(3);
2091}
2092
2093/* LDS DIR          0x9E */
2094void HC11OP(lds_dir)()
2095{
2096   UINT8 i = FETCH();
2097   CLEAR_NZV();
2098   m_sp = READ16(i);
2099   SET_N16(m_sp);
2100   SET_Z16(m_sp);
2101   CYCLES(4);
2102}
2103
2104/* LDS EXT          0xBE */
2105void HC11OP(lds_ext)()
2106{
2107   UINT16 adr = FETCH16();
2108   CLEAR_NZV();
2109   m_sp = READ16(adr);
2110   SET_N16(m_sp);
2111   SET_Z16(m_sp);
2112   CYCLES(5);
2113}
2114
2115/* LDS IND, X       0xAE */
2116void HC11OP(lds_indx)()
2117{
2118   UINT8 offset = FETCH();
2119   CLEAR_NZV();
2120   m_sp = READ16(m_ix + offset);
2121   SET_N16(m_sp);
2122   SET_Z16(m_sp);
2123   CYCLES(5);
2124}
2125
2126/* LDS IND, Y       0x18, 0xAE */
2127void HC11OP(lds_indy)()
2128{
2129   UINT8 offset = FETCH();
2130   CLEAR_NZV();
2131   m_sp = READ16(m_iy + offset);
2132   SET_N16(m_sp);
2133   SET_Z16(m_sp);
2134   CYCLES(6);
2135}
2136
2137
2138/* LDX IMM          0xCE */
2139void HC11OP(ldx_imm)()
2140{
2141   CLEAR_NZV();
2142   m_ix = FETCH16();
2143   SET_N16(m_ix);
2144   SET_Z16(m_ix);
2145   CYCLES(3);
2146}
2147
2148/* LDX DIR          0xDE */
2149void HC11OP(ldx_dir)()
2150{
2151   UINT8 d = FETCH();
2152   CLEAR_NZV();
2153   m_ix = READ16(d);
2154   SET_N16(m_ix);
2155   SET_Z16(m_ix);
2156   CYCLES(4);
2157}
2158
2159/* LDX EXT          0xFE */
2160void HC11OP(ldx_ext)()
2161{
2162   UINT16 adr = FETCH16();
2163   CLEAR_NZV();
2164   m_ix = READ16(adr);
2165   SET_N16(m_ix);
2166   SET_Z16(m_ix);
2167   CYCLES(5);
2168}
2169
2170/* LDX IND, X       0xEE */
2171void HC11OP(ldx_indx)()
2172{
2173   UINT8 offset = FETCH();
2174   CLEAR_NZV();
2175   m_ix = READ16(m_ix + offset);
2176   SET_N16(m_ix);
2177   SET_Z16(m_ix);
2178   CYCLES(5);
2179}
2180
2181/* LDX IND, Y       0xCD, 0xEE */
2182void HC11OP(ldx_indy)()
2183{
2184   UINT8 offset = FETCH();
2185   CLEAR_NZV();
2186   m_ix = READ16(m_iy + offset);
2187   SET_N16(m_ix);
2188   SET_Z16(m_ix);
2189   CYCLES(6);
2190}
2191
2192
2193/* LDY IMM          0x18, 0xCE */
2194void HC11OP(ldy_imm)()
2195{
2196   CLEAR_NZV();
2197   m_iy = FETCH16();
2198   SET_N16(m_iy);
2199   SET_Z16(m_iy);
2200   CYCLES(4);
2201}
2202
2203/* LDY DIR          0x18, 0xDE */
2204void HC11OP(ldy_dir)()
2205{
2206   UINT8 d = FETCH();
2207   CLEAR_NZV();
2208   m_iy = READ16(d);
2209   SET_N16(m_iy);
2210   SET_Z16(m_iy);
2211   CYCLES(5);
2212}
2213
2214/* LDY EXT          0x18, 0xFE */
2215void HC11OP(ldy_ext)()
2216{
2217   UINT16 adr = FETCH16();
2218   CLEAR_NZV();
2219   m_iy = READ16(adr);
2220   SET_N16(m_iy);
2221   SET_Z16(m_iy);
2222   CYCLES(6);
2223}
2224
2225/* LDY IND, X       0x1A, 0xEE */
2226void HC11OP(ldy_indx)()
2227{
2228   UINT8 offset = FETCH();
2229   CLEAR_NZV();
2230   m_iy = READ16(m_ix + offset);
2231   SET_N16(m_iy);
2232   SET_Z16(m_iy);
2233   CYCLES(6);
2234}
2235
2236/* LDY IND, Y       0x18, 0xEE */
2237void HC11OP(ldy_indy)()
2238{
2239   UINT8 offset = FETCH();
2240   CLEAR_NZV();
2241   m_iy = READ16(m_iy + offset);
2242   SET_N16(m_iy);
2243   SET_Z16(m_iy);
2244   CYCLES(6);
2245}
2246
2247/* LSLD             0x05 */
2248void HC11OP(lsld)()
2249{
2250   UINT32 r = REG_D << 1;
2251   CLEAR_NZVC();
2252   SET_C16(r);
2253   REG_D = (UINT16)(r);
2254   SET_N16(REG_D);
2255   SET_Z16(REG_D);
2256
2257   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2258      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2259   {
2260      m_ccr |= CC_V;
2261   }
2262
2263   CYCLES(3);
2264}
2265
2266/* LSRA              0x44 */
2267void HC11OP(lsra)()
2268{
2269   UINT16 r = REG_A >> 1;
2270   CLEAR_NZVC();
2271   m_ccr |= (REG_A & 1) ? CC_C : 0;
2272   REG_A = (UINT8)(r);
2273   m_ccr |= ((m_ccr & CC_C)) ? CC_V : 0;
2274   SET_Z8(REG_A);
2275
2276   CYCLES(2);
2277}
2278
2279/* LSRB              0x54 */
2280void HC11OP(lsrb)()
2281{
2282   UINT16 r = REG_B >> 1;
2283   CLEAR_NZVC();
2284   m_ccr |= (REG_B & 1) ? CC_C : 0;
2285   REG_B = (UINT8)(r);
2286   m_ccr |= ((m_ccr & CC_C)) ? CC_V : 0;
2287   SET_Z8(REG_B);
2288
2289   CYCLES(2);
2290}
2291
2292/* LSRD             0x04 */
2293void HC11OP(lsrd)()
2294{
2295   UINT32 r = REG_D >> 1;
2296   CLEAR_NZVC();
2297   m_ccr |= (REG_D & 1) ? CC_C : 0;
2298   REG_D = (UINT16)(r);
2299   m_ccr |= ((m_ccr & CC_C)) ? CC_V : 0;
2300
2301   SET_N16(REG_D);
2302   SET_Z16(REG_D);
2303
2304   CYCLES(3);
2305}
2306
2307/* MUL              0x3d */
2308void HC11OP(mul)()
2309{
2310   REG_D = REG_A * REG_B;
2311   CLEAR_C();
2312   m_ccr |= (REG_B & 0x80) ? CC_C : 0;
2313   CYCLES(10);
2314}
2315
2316/* NEGA              0x40 */
2317void HC11OP(nega)()
2318{
2319   REG_A = 0x00 - REG_A;
2320   CLEAR_NZVC();
2321   SET_N8(REG_A);
2322   SET_Z8(REG_A);
2323   m_ccr |= (REG_A == 0x80) ? CC_V : 0;
2324   m_ccr |= (REG_A != 0x00) ? CC_C : 0;
2325   CYCLES(2);
2326}
2327
2328/* NEGB              0x50 */
2329void HC11OP(negb)()
2330{
2331   REG_B = 0x00 - REG_B;
2332   CLEAR_NZVC();
2333   SET_N8(REG_B);
2334   SET_Z8(REG_B);
2335   m_ccr |= (REG_B == 0x80) ? CC_V : 0;
2336   m_ccr |= (REG_B != 0x00) ? CC_C : 0;
2337   CYCLES(2);
2338}
2339
2340
2341/* NEG EXT           0x70 */
2342void HC11OP(neg_ext)()
2343{
2344   UINT16 adr = FETCH16();
2345   UINT8 i = 0x00 - READ8(adr);
2346   CLEAR_NZVC();
2347   SET_N8(i);
2348   SET_Z8(i);
2349   m_ccr |= (i == 0x80) ? CC_V : 0;
2350   m_ccr |= (i != 0x00) ? CC_C : 0;
2351   WRITE8(adr, i);
2352   CYCLES(6);
2353}
2354
2355
2356/* NEG INDX           0x60 */
2357void HC11OP(neg_indx)()
2358{
2359   UINT16 offset = FETCH();
2360   UINT8 i = 0x00 - READ8(m_ix + offset);
2361   CLEAR_NZVC();
2362   SET_N8(i);
2363   SET_Z8(i);
2364   m_ccr |= (i == 0x80) ? CC_V : 0;
2365   m_ccr |= (i != 0x00) ? CC_C : 0;
2366   WRITE8(m_ix + offset, i);
2367   CYCLES(6);
2368}
2369
2370
2371/* NEG INDY           0x18 0x60 */
2372void HC11OP(neg_indy)()
2373{
2374   UINT16 offset = FETCH();
2375   UINT8 i = 0x00 - READ8(m_iy + offset);
2376   CLEAR_NZVC();
2377   SET_N8(i);
2378   SET_Z8(i);
2379   m_ccr |= (i == 0x80) ? CC_V : 0;
2380   m_ccr |= (i != 0x00) ? CC_C : 0;
2381   WRITE8(m_iy + offset, i);
2382   CYCLES(7);
2383}
2384
2385
2386/* NOP              0x01 */
2387void HC11OP(nop)()
2388{
2389   CYCLES(2);
2390}
2391
2392/* PSHA             0x36 */
2393void HC11OP(psha)()
2394{
2395   PUSH8(REG_A);
2396   CYCLES(3);
2397}
2398
2399/* ORAA IMM         0x8A */
2400void HC11OP(oraa_imm)()
2401{
2402   UINT8 i = FETCH();
2403   CLEAR_NZV();
2404   REG_A |= i;
2405   SET_N8(REG_A);
2406   SET_Z8(REG_A);
2407   CYCLES(2);
2408}
2409
2410/* ORAA DIR         0x9A */
2411void HC11OP(oraa_dir)()
2412{
2413   UINT8 d = FETCH();
2414   UINT8 i = READ8(d);
2415   CLEAR_NZV();
2416   REG_A |= i;
2417   SET_N8(REG_A);
2418   SET_Z8(REG_A);
2419   CYCLES(3);
2420}
2421
2422/* ORAA EXT         0xBA */
2423void HC11OP(oraa_ext)()
2424{
2425   UINT16 adr = FETCH16();
2426   UINT8 i = READ8(adr);
2427   CLEAR_NZV();
2428   REG_A |= i;
2429   SET_N8(REG_A);
2430   SET_Z8(REG_A);
2431   CYCLES(4);
2432}
2433
2434/* ORAA IND, X      0xAA */
2435void HC11OP(oraa_indx)()
2436{
2437   UINT8 offset = FETCH();
2438   UINT8 i = READ8(m_ix + offset);
2439   CLEAR_NZV();
2440   REG_A |= i;
2441   SET_N8(REG_A);
2442   SET_Z8(REG_A);
2443   CYCLES(4);
2444}
2445
2446/* ORAA IND, Y      0x18, 0xAA */
2447void HC11OP(oraa_indy)()
2448{
2449   UINT8 offset = FETCH();
2450   UINT8 i = READ8(m_iy + offset);
2451   CLEAR_NZV();
2452   REG_A |= i;
2453   SET_N8(REG_A);
2454   SET_Z8(REG_A);
2455   CYCLES(5);
2456}
2457
2458
2459/* ORAB IMM         0xCA */
2460void HC11OP(orab_imm)()
2461{
2462   UINT8 i = FETCH();
2463   CLEAR_NZV();
2464   REG_B |= i;
2465   SET_N8(REG_B);
2466   SET_Z8(REG_B);
2467   CYCLES(2);
2468}
2469
2470/* ORAB DIR         0xDA */
2471void HC11OP(orab_dir)()
2472{
2473   UINT8 d = FETCH();
2474   UINT8 i = READ8(d);
2475   CLEAR_NZV();
2476   REG_B |= i;
2477   SET_N8(REG_B);
2478   SET_Z8(REG_B);
2479   CYCLES(3);
2480}
2481
2482/* ORAB EXT         0xFA */
2483void HC11OP(orab_ext)()
2484{
2485   UINT16 adr = FETCH16();
2486   UINT8 i = READ8(adr);
2487   CLEAR_NZV();
2488   REG_B |= i;
2489   SET_N8(REG_B);
2490   SET_Z8(REG_B);
2491   CYCLES(4);
2492}
2493
2494/* ORAB IND, X      0xEA */
2495void HC11OP(orab_indx)()
2496{
2497   UINT8 offset = FETCH();
2498   UINT8 i = READ8(m_ix + offset);
2499   CLEAR_NZV();
2500   REG_B |= i;
2501   SET_N8(REG_B);
2502   SET_Z8(REG_B);
2503   CYCLES(4);
2504}
2505
2506/* ORAB IND, Y      0x18, 0xEA */
2507void HC11OP(orab_indy)()
2508{
2509   UINT8 offset = FETCH();
2510   UINT8 i = READ8(m_iy + offset);
2511   CLEAR_NZV();
2512   REG_B |= i;
2513   SET_N8(REG_B);
2514   SET_Z8(REG_B);
2515   CYCLES(5);
2516}
2517
2518
2519/* PSHB             0x37 */
2520void HC11OP(pshb)()
2521{
2522   PUSH8(REG_B);
2523   CYCLES(3);
2524}
2525
2526
2527/* PSHX             0x3C */
2528void HC11OP(pshx)()
2529{
2530   PUSH16(m_ix);
2531   CYCLES(4);
2532}
2533
2534
2535/* PSHY             0x18, 0x3C */
2536void HC11OP(pshy)()
2537{
2538   PUSH16(m_iy);
2539   CYCLES(5);
2540}
2541
2542
2543/* PULA             0x32 */
2544void HC11OP(pula)()
2545{
2546   REG_A = POP8();
2547   CYCLES(4);
2548}
2549
2550
2551/* PULB             0x33 */
2552void HC11OP(pulb)()
2553{
2554   REG_B = POP8();
2555   CYCLES(4);
2556}
2557
2558
2559/* PULX             0x38 */
2560void HC11OP(pulx)()
2561{
2562   m_ix = POP16();
2563   CYCLES(5);
2564}
2565
2566
2567/* PULY             0x18, 0x38 */
2568void HC11OP(puly)()
2569{
2570   m_iy = POP16();
2571   CYCLES(6);
2572}
2573
2574/* ROLA             0x49 */
2575void HC11OP(rola)()
2576{
2577   UINT16 r = ((REG_A & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2578   CLEAR_NZVC();
2579   m_ccr |= (REG_A & 0x80) ? CC_C : 0;
2580   REG_A = (UINT8)(r);
2581   SET_N8(REG_A);
2582   SET_Z8(REG_A);
2583
2584   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2585      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2586   {
2587      m_ccr |= CC_V;
2588   }
2589
2590   CYCLES(2);
2591}
2592
2593/* ROLB             0x59 */
2594void HC11OP(rolb)()
2595{
2596   UINT16 r = ((REG_B & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2597   CLEAR_NZVC();
2598   m_ccr |= (REG_B & 0x80) ? CC_C : 0;
2599   REG_B = (UINT8)(r);
2600   SET_N8(REG_B);
2601   SET_Z8(REG_B);
2602
2603   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2604      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2605   {
2606      m_ccr |= CC_V;
2607   }
2608
2609   CYCLES(2);
2610}
2611
2612/* ROL EXT           0x79 */
2613void HC11OP(rol_ext)()
2614{
2615   UINT16 adr = FETCH16();
2616   UINT8 r = READ8(adr);
2617   UINT8 c = (r & 0x80);
2618   r = ((r & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2619   CLEAR_NZVC();
2620   m_ccr |= (c & 0x80) ? CC_C : 0;
2621   SET_N8(r);
2622   SET_Z8(r);
2623   WRITE8(adr, r);
2624
2625   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2626      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2627   {
2628      m_ccr |= CC_V;
2629   }
2630
2631   CYCLES(6);
2632}
2633
2634/* ROL INDX           0x69 */
2635void HC11OP(rol_indx)()
2636{
2637   UINT8 offset = FETCH();
2638   UINT8 i = READ8(m_ix + offset);
2639   UINT8 c = (i & 0x80);
2640   i = ((i & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2641   CLEAR_NZVC();
2642   m_ccr |= (c & 0x80) ? CC_C : 0;
2643   SET_N8(i);
2644   SET_Z8(i);
2645   WRITE8(m_ix + offset, i);
2646
2647   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2648      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2649   {
2650      m_ccr |= CC_V;
2651   }
2652
2653   CYCLES(6);
2654}
2655
2656/* ROL INDY           0x18 0x69 */
2657void HC11OP(rol_indy)()
2658{
2659   UINT8 offset = FETCH();
2660   UINT8 i = READ8(m_iy + offset);
2661   UINT8 c = (i & 0x80);
2662   i = ((i & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2663   CLEAR_NZVC();
2664   m_ccr |= (c & 0x80) ? CC_C : 0;
2665   SET_N8(i);
2666   SET_Z8(i);
2667   WRITE8(m_iy + offset, i);
2668
2669   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2670      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2671   {
2672      m_ccr |= CC_V;
2673   }
2674
2675   CYCLES(6);
2676}
2677
2678
2679/* RORA             0x46 */
2680void HC11OP(rora)()
2681{
2682   UINT16 r = ((REG_A & 0xfe) >> 1) | ((m_ccr & CC_C) ? 0x80 : 0);
2683   CLEAR_NZVC();
2684   m_ccr |= (REG_A & 1) ? CC_C : 0;
2685   REG_A = (UINT8)(r);
2686   SET_N8(REG_A);
2687   SET_Z8(REG_A);
2688
2689   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2690      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2691   {
2692      m_ccr |= CC_V;
2693   }
2694
2695   CYCLES(2);
2696}
2697
2698/* RORB             0x56 */
2699void HC11OP(rorb)()
2700{
2701   UINT16 r = ((REG_B & 0xfe) >> 1) | ((m_ccr & CC_C) ? 0x80 : 0);
2702   CLEAR_NZVC();
2703   m_ccr |= (REG_B & 1) ? CC_C : 0;
2704   REG_B = (UINT8)(r);
2705   SET_N8(REG_B);
2706   SET_Z8(REG_B);
2707
2708   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2709      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2710   {
2711      m_ccr |= CC_V;
2712   }
2713
2714   CYCLES(2);
2715}
2716
2717/* RTI              0x3B */
2718void HC11OP(rti)()
2719{
2720   UINT16 rt_adr;
2721   UINT8 x_flag = m_ccr & CC_X;
2722   m_ccr = POP8();
2723   if(x_flag == 0 && m_ccr & CC_X) //X flag cannot do a 0->1 transition with this instruction.
2724      m_ccr &= ~CC_X;
2725   REG_B = POP8();
2726   REG_A = POP8();
2727   m_ix = POP16();
2728   m_iy = POP16();
2729   rt_adr = POP16();
2730   SET_PC(rt_adr);
2731   CYCLES(12);
2732}
2733
2734/* RTS              0x39 */
2735void HC11OP(rts)()
2736{
2737   UINT16 rt_adr = POP16();
2738   SET_PC(rt_adr);
2739   CYCLES(5);
2740}
2741
2742
2743/* SBA              0x10 */
2744void HC11OP(sba)()
2745{
2746   UINT16 r = REG_A - REG_B;
2747   CLEAR_NZVC();
2748   SET_N8(r);
2749   SET_Z8(r);
2750   SET_V_SUB8(r, REG_B, REG_A);
2751   SET_C8(r);
2752   REG_A = (UINT8)r;
2753   CYCLES(2);
2754}
2755
2756
2757/* SBCA IMM         0x82 */
2758void HC11OP(sbca_imm)()
2759{
2760   UINT8 i = FETCH();
2761   UINT16 r = (REG_A - i) - ((m_ccr & CC_C) ? 1 : 0);
2762   CLEAR_NZVC();
2763   SET_N8(r);
2764   SET_Z8(r);
2765   SET_V_SUB8(r, i, REG_A);
2766   SET_C8(r);
2767   REG_A = (UINT8)r;
2768   CYCLES(2);
2769}
2770
2771/* SBCA IND, X      0xA2 */
2772void HC11OP(sbca_indx)()
2773{
2774   UINT8 offset = FETCH();
2775   UINT8 i = READ8(m_ix + offset);
2776   UINT16 r = (REG_A - i) - ((m_ccr & CC_C) ? 1 : 0);
2777   CLEAR_NZVC();
2778   SET_N8(r);
2779   SET_Z8(r);
2780   SET_V_SUB8(r, i, REG_A);
2781   SET_C8(r);
2782   REG_A = (UINT8)r;
2783   CYCLES(4);
2784}
2785
2786/* SBCA IND, Y      0x18, 0xA2 */
2787void HC11OP(sbca_indy)()
2788{
2789   UINT8 offset = FETCH();
2790   UINT8 i = READ8(m_iy + offset);
2791   UINT16 r = (REG_A - i) - ((m_ccr & CC_C) ? 1 : 0);
2792   CLEAR_NZVC();
2793   SET_N8(r);
2794   SET_Z8(r);
2795   SET_V_SUB8(r, i, REG_A);
2796   SET_C8(r);
2797   REG_A = (UINT8)r;
2798   CYCLES(5);
2799}
2800
2801/* SBCB IMM         0xC2 */
2802void HC11OP(sbcb_imm)()
2803{
2804   UINT8 i = FETCH();
2805   UINT16 r = (REG_B - i) - ((m_ccr & CC_C) ? 1 : 0);
2806   CLEAR_NZVC();
2807   SET_N8(r);
2808   SET_Z8(r);
2809   SET_V_SUB8(r, i, REG_B);
2810   SET_C8(r);
2811   REG_B = (UINT8)r;
2812   CYCLES(2);
2813}
2814
2815/* SBCB IND, X      0xE2 */
2816void HC11OP(sbcb_indx)()
2817{
2818   UINT8 offset = FETCH();
2819   UINT8 i = READ8(m_ix + offset);
2820   UINT16 r = (REG_B - i) - ((m_ccr & CC_C) ? 1 : 0);
2821   CLEAR_NZVC();
2822   SET_N8(r);
2823   SET_Z8(r);
2824   SET_V_SUB8(r, i, REG_B);
2825   SET_C8(r);
2826   REG_B = (UINT8)r;
2827   CYCLES(4);
2828}
2829
2830/* SBCB IND, Y      0x18, 0xE2 */
2831void HC11OP(sbcb_indy)()
2832{
2833   UINT8 offset = FETCH();
2834   UINT8 i = READ8(m_iy + offset);
2835   UINT16 r = (REG_B - i) - ((m_ccr & CC_C) ? 1 : 0);
2836   CLEAR_NZVC();
2837   SET_N8(r);
2838   SET_Z8(r);
2839   SET_V_SUB8(r, i, REG_B);
2840   SET_C8(r);
2841   REG_B = (UINT8)r;
2842   CYCLES(5);
2843}
2844
2845/* SEC              0x0D */
2846void HC11OP(sec)()
2847{
2848   m_ccr |= CC_C;
2849   CYCLES(2);
2850}
2851
2852/* SEI              0x0F */
2853void HC11OP(sei)()
2854{
2855   m_ccr |= CC_I;
2856   CYCLES(2);
2857}
2858
2859/* SEV              0x0B */
2860void HC11OP(sev)()
2861{
2862   m_ccr |= CC_V;
2863   CYCLES(2);
2864}
2865
2866/* STAA DIR         0x97 */
2867void HC11OP(staa_dir)()
2868{
2869   UINT8 d = FETCH();
2870   CLEAR_NZV();
2871   SET_N8(REG_A);
2872   SET_Z8(REG_A);
2873   WRITE8(d, REG_A);
2874   CYCLES(3);
2875}
2876
2877/* STAA EXT         0xB7 */
2878void HC11OP(staa_ext)()
2879{
2880   UINT16 adr = FETCH16();
2881   CLEAR_NZV();
2882   SET_N8(REG_A);
2883   SET_Z8(REG_A);
2884   WRITE8(adr, REG_A);
2885   CYCLES(4);
2886}
2887
2888/* STAA IND, X      0xA7 */
2889void HC11OP(staa_indx)()
2890{
2891   UINT8 offset = FETCH();
2892   CLEAR_NZV();
2893   SET_N8(REG_A);
2894   SET_Z8(REG_A);
2895   WRITE8(m_ix + offset, REG_A);
2896   CYCLES(4);
2897}
2898
2899/* STAA IND, Y      0x18, 0xA7 */
2900void HC11OP(staa_indy)()
2901{
2902   UINT8 offset = FETCH();
2903   CLEAR_NZV();
2904   SET_N8(REG_A);
2905   SET_Z8(REG_A);
2906   WRITE8(m_iy + offset, REG_A);
2907   CYCLES(5);
2908}
2909
2910/* STAB DIR         0xD7 */
2911void HC11OP(stab_dir)()
2912{
2913   UINT8 d = FETCH();
2914   CLEAR_NZV();
2915   SET_N8(REG_B);
2916   SET_Z8(REG_B);
2917   WRITE8(d, REG_B);
2918   CYCLES(3);
2919}
2920
2921/* STAB EXT         0xF7 */
2922void HC11OP(stab_ext)()
2923{
2924   UINT16 adr = FETCH16();
2925   CLEAR_NZV();
2926   SET_N8(REG_B);
2927   SET_Z8(REG_B);
2928   WRITE8(adr, REG_B);
2929   CYCLES(4);
2930}
2931
2932/* STAB IND, X      0xE7 */
2933void HC11OP(stab_indx)()
2934{
2935   UINT8 offset = FETCH();
2936   CLEAR_NZV();
2937   SET_N8(REG_B);
2938   SET_Z8(REG_B);
2939   WRITE8(m_ix + offset, REG_B);
2940   CYCLES(4);
2941}
2942
2943/* STAB IND, Y      0x18, 0xE7 */
2944void HC11OP(stab_indy)()
2945{
2946   UINT8 offset = FETCH();
2947   CLEAR_NZV();
2948   SET_N8(REG_B);
2949   SET_Z8(REG_B);
2950   WRITE8(m_iy + offset, REG_B);
2951   CYCLES(5);
2952}
2953
2954
2955/* STD DIR          0xDD */
2956void HC11OP(std_dir)()
2957{
2958   UINT8 d = FETCH();
2959   CLEAR_NZV();
2960   WRITE16(d, REG_D);
2961   SET_N16(REG_D);
2962   SET_Z16(REG_D);
2963   CYCLES(4);
2964}
2965
2966/* STD EXT          0xFD */
2967void HC11OP(std_ext)()
2968{
2969   UINT16 adr = FETCH16();
2970   CLEAR_NZV();
2971   WRITE16(adr, REG_D);
2972   SET_N16(REG_D);
2973   SET_Z16(REG_D);
2974   CYCLES(5);
2975}
2976
2977/* STD IND, X       0xED */
2978void HC11OP(std_indx)()
2979{
2980   UINT8 offset = FETCH();
2981   CLEAR_NZV();
2982   WRITE16(m_ix + offset, REG_D);
2983   SET_N16(REG_D);
2984   SET_Z16(REG_D);
2985   CYCLES(5);
2986}
2987
2988/* STD IND, Y       0x18, 0xED */
2989void HC11OP(std_indy)()
2990{
2991   UINT8 offset = FETCH();
2992   CLEAR_NZV();
2993   WRITE16(m_iy + offset, REG_D);
2994   SET_N16(REG_D);
2995   SET_Z16(REG_D);
2996   CYCLES(6);
2997}
2998
2999/* STS DIR          0x9F */
3000void HC11OP(sts_dir)()
3001{
3002   UINT8 d = FETCH();
3003   UINT16 r = m_sp;
3004   CLEAR_NZV();
3005   WRITE8(d, (r & 0xff00) >> 8);
3006   WRITE8(d + 1, (r & 0xff));
3007   SET_N16(r);
3008   SET_Z16(r);
3009   CYCLES(4);
3010}
3011
3012
3013/* STX DIR          0xDF */
3014void HC11OP(stx_dir)()
3015{
3016   UINT8 adr = FETCH();
3017   UINT16 r = m_ix;
3018   CLEAR_NZV();
3019   WRITE8(adr, (r & 0xff00) >> 8);
3020   WRITE8(adr + 1, (r & 0xff));
3021   SET_N16(r);
3022   SET_Z16(r);
3023   CYCLES(4);
3024}
3025
3026/* STX EXT          0xFF */
3027void HC11OP(stx_ext)()
3028{
3029   UINT16 adr = FETCH16();
3030   UINT16 r = m_ix;
3031   CLEAR_NZV();
3032   WRITE8(adr, (r & 0xff00) >> 8);
3033   WRITE8(adr + 1, (r & 0xff));
3034   SET_N16(r);
3035   SET_Z16(r);
3036   CYCLES(5);
3037}
3038
3039
3040/* STX INDX         0xEF */
3041void HC11OP(stx_indx)()
3042{
3043   UINT16 adr = FETCH();
3044   UINT16 r = m_ix;
3045   CLEAR_NZV();
3046   WRITE8(m_ix + adr, (r & 0xff00) >> 8);
3047   WRITE8(m_ix + adr + 1, (r & 0xff));
3048   SET_N16(r);
3049   SET_Z16(r);
3050   CYCLES(5);
3051}
3052
3053
3054/* STX INDY         0xCD 0xEF */
3055void HC11OP(stx_indy)()
3056{
3057   UINT16 adr = FETCH();
3058   UINT16 r = m_ix;
3059   CLEAR_NZV();
3060   WRITE8(m_iy + adr, (r & 0xff00) >> 8);
3061   WRITE8(m_iy + adr + 1, (r & 0xff));
3062   SET_N16(r);
3063   SET_Z16(r);
3064   CYCLES(6);
3065}
3066
3067/* STY DIR          0x18 0xDF */
3068void HC11OP(sty_dir)()
3069{
3070   UINT8 adr = FETCH();
3071   UINT16 r = m_iy;
3072   CLEAR_NZV();
3073   WRITE8(adr, (r & 0xff00) >> 8);
3074   WRITE8(adr + 1, (r & 0xff));
3075   SET_N16(r);
3076   SET_Z16(r);
3077   CYCLES(5);
3078}
3079
3080
3081/* STY EXT          0x18 0xFF */
3082void HC11OP(sty_ext)()
3083{
3084   UINT16 adr = FETCH16();
3085   UINT16 r = m_iy;
3086   CLEAR_NZV();
3087   WRITE8(adr, (r & 0xff00) >> 8);
3088   WRITE8(adr + 1, (r & 0xff));
3089   SET_N16(r);
3090   SET_Z16(r);
3091   CYCLES(6);
3092}
3093
3094/* STY INDX         0x1A 0xEF */
3095void HC11OP(sty_indx)()
3096{
3097   UINT16 adr = FETCH();
3098   UINT16 r = m_iy;
3099   CLEAR_NZV();
3100   WRITE8(m_ix + adr, (r & 0xff00) >> 8);
3101   WRITE8(m_ix + adr + 1, (r & 0xff));
3102   SET_N16(r);
3103   SET_Z16(r);
3104   CYCLES(6);
3105}
3106
3107/* STY INDY         0x18 0xEF */
3108void HC11OP(sty_indy)()
3109{
3110   UINT16 adr = FETCH();
3111   UINT16 r = m_iy;
3112   CLEAR_NZV();
3113   WRITE8(m_iy + adr, (r & 0xff00) >> 8);
3114   WRITE8(m_iy + adr + 1, (r & 0xff));
3115   SET_N16(r);
3116   SET_Z16(r);
3117   CYCLES(6);
3118}
3119
3120/* STOP              0xCF */
3121void HC11OP(stop)()
3122{
3123   if(m_stop_state == 0 && ((m_ccr & CC_S) == 0))
3124   {
3125      m_stop_state = 1;
3126   }
3127
3128   if(m_stop_state == 1)
3129   {
3130      SET_PC(m_ppc); // wait for an exception
3131   }
3132
3133   if(m_stop_state == 2)
3134   {
3135      m_stop_state = 0;
3136   }
3137
3138   CYCLES(2);
3139}
3140
3141
3142/* SUBA IMM         0x80 */
3143void HC11OP(suba_imm)()
3144{
3145   UINT8 i = FETCH();
3146   UINT16 r = REG_A - i;
3147   CLEAR_NZVC();
3148   SET_N8(r);
3149   SET_Z8(r);
3150   SET_V_SUB8(r, i, REG_A);
3151   SET_C8(r);
3152   REG_A = (UINT8)r;
3153   CYCLES(2);
3154}
3155
3156
3157/* SUBA DIR         0xd0 */
3158void HC11OP(suba_dir)()
3159{
3160   UINT8 d = FETCH();
3161   UINT8 i = READ8(d);
3162   UINT16 r = REG_A - i;
3163   CLEAR_NZVC();
3164   SET_N8(r);
3165   SET_Z8(r);
3166   SET_V_SUB8(r, i, REG_A);
3167   SET_C8(r);
3168   REG_A = (UINT8)r;
3169   CYCLES(3);
3170}
3171
3172
3173/* SUBA EXT         0xE0 */
3174void HC11OP(suba_ext)()
3175{
3176   UINT16 adr = FETCH16();
3177   UINT8 i = READ8(adr);
3178   UINT16 r = REG_A - i;
3179   CLEAR_NZVC();
3180   SET_N8(r);
3181   SET_Z8(r);
3182   SET_V_SUB8(r, i, REG_A);
3183   SET_C8(r);
3184   REG_A = (UINT8)r;
3185   CYCLES(4);
3186}
3187
3188
3189/* SUBA INDX        0xA0 */
3190void HC11OP(suba_indx)()
3191{
3192   UINT16 adr = FETCH();
3193   UINT8 i = READ8(m_ix + adr);
3194   UINT16 r = REG_A - i;
3195   CLEAR_NZVC();
3196   SET_N8(r);
3197   SET_Z8(r);
3198   SET_V_SUB8(r, i, REG_A);
3199   SET_C8(r);
3200   REG_A = (UINT8)r;
3201   CYCLES(4);
3202}
3203
3204
3205/* SUBA INDY        0x18 0xA0 */
3206void HC11OP(suba_indy)()
3207{
3208   UINT16 adr = FETCH();
3209   UINT8 i = READ8(m_iy + adr);
3210   UINT16 r = REG_A - i;
3211   CLEAR_NZVC();
3212   SET_N8(r);
3213   SET_Z8(r);
3214   SET_V_SUB8(r, i, REG_A);
3215   SET_C8(r);
3216   REG_A = (UINT8)r;
3217   CYCLES(5);
3218}
3219
3220
3221/* SUBB IMM         0xC0 */
3222void HC11OP(subb_imm)()
3223{
3224   UINT8 i = FETCH();
3225   UINT16 r = REG_B - i;
3226   CLEAR_NZVC();
3227   SET_N8(r);
3228   SET_Z8(r);
3229   SET_V_SUB8(r, i, REG_B);
3230   SET_C8(r);
3231   REG_B = (UINT8)r;
3232   CYCLES(2);
3233}
3234
3235
3236/* SUBB DIR         0xD0 */
3237void HC11OP(subb_dir)()
3238{
3239   UINT8 d = FETCH();
3240   UINT8 i = READ8(d);
3241   UINT16 r = REG_B - i;
3242   CLEAR_NZVC();
3243   SET_N8(r);
3244   SET_Z8(r);
3245   SET_V_SUB8(r, i, REG_B);
3246   SET_C8(r);
3247   REG_B = (UINT8)r;
3248   CYCLES(3);
3249}
3250
3251
3252/* SUBB EXT         0xF0 */
3253void HC11OP(subb_ext)()
3254{
3255   UINT16 adr = FETCH16();
3256   UINT8 i = READ8(adr);
3257   UINT16 r = REG_B - i;
3258   CLEAR_NZVC();
3259   SET_N8(r);
3260   SET_Z8(r);
3261   SET_V_SUB8(r, i, REG_B);
3262   SET_C8(r);
3263   REG_B = (UINT8)r;
3264   CYCLES(4);
3265}
3266
3267
3268/* SUBB INDX        0xE0 */
3269void HC11OP(subb_indx)()
3270{
3271   UINT16 adr = FETCH();
3272   UINT8 i = READ8(m_ix + adr);
3273   UINT16 r = REG_B - i;
3274   CLEAR_NZVC();
3275   SET_N8(r);
3276   SET_Z8(r);
3277   SET_V_SUB8(r, i, REG_B);
3278   SET_C8(r);
3279   REG_B = (UINT8)r;
3280   CYCLES(4);
3281}
3282
3283/* SUBB INDY        0x18 0xE0 */
3284void HC11OP(subb_indy)()
3285{
3286   UINT16 adr = FETCH();
3287   UINT8 i = READ8(m_iy + adr);
3288   UINT16 r = REG_B - i;
3289   CLEAR_NZVC();
3290   SET_N8(r);
3291   SET_Z8(r);
3292   SET_V_SUB8(r, i, REG_B);
3293   SET_C8(r);
3294   REG_B = (UINT8)r;
3295   CYCLES(5);
3296}
3297
3298/* SUBD IMM         0x83 */
3299void HC11OP(subd_imm)()
3300{
3301   UINT16 i = FETCH16();
3302   UINT32 r = REG_D - i;
3303   CLEAR_NZVC();
3304   SET_N16(r);
3305   SET_Z16(r);
3306   SET_V_SUB16(r, i, REG_D);
3307   SET_C16(r);
3308   REG_D = (UINT16)r;
3309   CYCLES(4);
3310}
3311
3312/* SUBD DIR        0x93 */
3313void HC11OP(subd_dir)()
3314{
3315   UINT8 d = FETCH();
3316   UINT16 i = READ16(d);
3317   UINT32 r = REG_D - i;
3318   CLEAR_NZVC();
3319   SET_N16(r);
3320   SET_Z16(r);
3321   SET_V_SUB16(r, i, REG_D);
3322   SET_C16(r);
3323   REG_D = (UINT16)r;
3324   CYCLES(5);
3325}
3326
3327/* SUBD EXT        0xB3 */
3328void HC11OP(subd_ext)()
3329{
3330   UINT16 addr = FETCH16();
3331   UINT16 i = READ16(addr);
3332   UINT32 r = REG_D - i;
3333   CLEAR_NZVC();
3334   SET_N16(r);
3335   SET_Z16(r);
3336   SET_V_SUB16(r, i, REG_D);
3337   SET_C16(r);
3338   REG_D = (UINT16)r;
3339   CYCLES(6);
3340}
3341
3342/* SUBD INDX        0xA3 */
3343void HC11OP(subd_indx)()
3344{
3345   UINT8 offset = FETCH();
3346   UINT16 i = READ16(m_ix + offset);
3347   UINT32 r = REG_D - i;
3348   CLEAR_NZVC();
3349   SET_N16(r);
3350   SET_Z16(r);
3351   SET_V_SUB16(r, i, REG_D);
3352   SET_C16(r);
3353   REG_D = (UINT16)r;
3354   CYCLES(6);
3355}
3356
3357/* SUBD INDY        0x18 0xA3 */
3358void HC11OP(subd_indy)()
3359{
3360   UINT8 offset = FETCH();
3361   UINT16 i = READ16(m_iy + offset);
3362   UINT32 r = REG_D - i;
3363   CLEAR_NZVC();
3364   SET_N16(r);
3365   SET_Z16(r);
3366   SET_V_SUB16(r, i, REG_D);
3367   SET_C16(r);
3368   REG_D = (UINT16)r;
3369   CYCLES(7);
3370}
3371
3372/* SWI              0x3F */
3373void HC11OP(swi)()
3374{
3375   UINT16 pc_vector;
3376   //m_pc++;
3377   PUSH16(m_pc);
3378   PUSH16(m_iy);
3379   PUSH16(m_ix);
3380   PUSH8(REG_A);
3381   PUSH8(REG_B);
3382   PUSH8(m_ccr);
3383   pc_vector = READ16(0xfff6);
3384   SET_PC(pc_vector);
3385   m_ccr |= CC_I; //irq taken, mask the flag
3386   CYCLES(14);
3387}
3388
3389/* TAB              0x16 */
3390void HC11OP(tab)()
3391{
3392   CLEAR_NZV();
3393   REG_B = REG_A;
3394   SET_N8(REG_B);
3395   SET_Z8(REG_B);
3396   CYCLES(2);
3397}
3398
3399/* TAP              0x06 */
3400void HC11OP(tap)()
3401{
3402   UINT8 x_flag = m_ccr & CC_X;
3403   m_ccr = REG_A;
3404   if(x_flag == 0 && m_ccr & CC_X) //X flag cannot do a 0->1 transition with this instruction.
3405      m_ccr &= ~CC_X;
3406
3407   CYCLES(2);
3408}
3409
3410/* TBA              0x17 */
3411void HC11OP(tba)()
3412{
3413   CLEAR_NZV();
3414   REG_A = REG_B;
3415   SET_N8(REG_A);
3416   SET_Z8(REG_A);
3417   CYCLES(2);
3418}
3419
3420/* TEST              0x00 */
3421void HC11OP(test)()
3422{
3423//  if(m_test_mode)
3424      SET_PC(m_ppc); // Note: docs says "incremented" but the behaviour makes me think that's actually "decremented".
3425//  else
3426//  {
3427//      TODO: execute an illegal opcode exception here (NMI)
3428//  }
3429
3430   CYCLES(1);
3431}
3432
3433/* TPA              0x07 */
3434void HC11OP(tpa)()
3435{
3436   REG_A = m_ccr;
3437   CYCLES(2);
3438}
3439
3440
3441/* TSTA             0x4D */
3442void HC11OP(tsta)()
3443{
3444   CLEAR_NZVC();
3445   SET_N8(REG_A);
3446   SET_Z8(REG_A);
3447   CYCLES(2);
3448}
3449
3450/* TSTB             0x5D */
3451void HC11OP(tstb)()
3452{
3453   CLEAR_NZVC();
3454   SET_N8(REG_B);
3455   SET_Z8(REG_B);
3456   CYCLES(2);
3457}
3458
3459/* TST EXT          0x7D */
3460void HC11OP(tst_ext)()
3461{
3462   UINT16 adr = FETCH16();
3463   UINT8 i = READ8(adr);
3464   CLEAR_NZVC();
3465   SET_N8(i);
3466   SET_Z8(i);
3467   CYCLES(6);
3468}
3469
3470/* TST IND, X       0x6D */
3471void HC11OP(tst_indx)()
3472{
3473   UINT8 offset = FETCH();
3474   UINT8 i = READ8(m_ix + offset);
3475   CLEAR_NZVC();
3476   SET_N8(i);
3477   SET_Z8(i);
3478   CYCLES(6);
3479}
3480
3481/* TST IND, Y       0x18, 0x6D */
3482void HC11OP(tst_indy)()
3483{
3484   UINT8 offset = FETCH();
3485   UINT8 i = READ8(m_iy + offset);
3486   CLEAR_NZVC();
3487   SET_N8(i);
3488   SET_Z8(i);
3489   CYCLES(6);
3490}
3491
3492/* TSX              0x30 */
3493void HC11OP(tsx)()
3494{
3495   m_ix = m_sp + 1;
3496   CYCLES(3);
3497}
3498
3499/* TSY              0x18 0x30 */
3500void HC11OP(tsy)()
3501{
3502   m_iy = m_sp + 1;
3503   CYCLES(4);
3504}
3505
3506/* TXS              0x35 */
3507void HC11OP(txs)()
3508{
3509   m_sp = m_ix - 1;
3510   CYCLES(3);
3511}
3512
3513/* TYS              0x18 0x35 */
3514void HC11OP(tys)()
3515{
3516   m_sp = m_iy - 1;
3517   CYCLES(4);
3518}
3519
3520/* WAI              0x3E */
3521void HC11OP(wai)()
3522{
3523   if(m_wait_state == 0)
3524   {
3525      /* TODO: the following is bogus, pushes regs HERE in an instruction that wants an irq to go out? */
3526      PUSH16(m_pc);
3527      PUSH16(m_iy);
3528      PUSH16(m_ix);
3529      PUSH8(REG_A);
3530      PUSH8(REG_B);
3531      PUSH8(m_ccr);
3532      CYCLES(14);
3533      m_wait_state = 1;
3534   }
3535   if(m_wait_state == 1)
3536   {
3537      SET_PC(m_ppc); // wait for an exception
3538      CYCLES(1);
3539   }
3540   if(m_wait_state == 2)
3541   {
3542      m_wait_state = 0;
3543      CYCLES(1);
3544   }
3545}
3546
3547/* XGDX             0x8F */
3548void HC11OP(xgdx)()
3549{
3550   UINT16 tmp = REG_D;
3551   REG_D = m_ix;
3552   m_ix = tmp;
3553   CYCLES(3);
3554}
3555
3556
3557/* XGDY             0x18, 0x8F */
3558void HC11OP(xgdy)()
3559{
3560   UINT16 tmp = REG_D;
3561   REG_D = m_iy;
3562   m_iy = tmp;
3563   CYCLES(4);
3564}
3565
3566/*****************************************************************************/
3567
3568void HC11OP(page2)()
3569{
3570   UINT8 op2 = FETCH();
3571   (this->*hc11_optable_page2[op2])();
3572}
3573
3574void HC11OP(page3)()
3575{
3576   UINT8 op2 = FETCH();
3577   (this->*hc11_optable_page3[op2])();
3578}
3579
3580void HC11OP(page4)()
3581{
3582   UINT8 op2 = FETCH();
3583   (this->*hc11_optable_page4[op2])();
3584}
3585
3586void HC11OP(invalid)()
3587{
3588   fatalerror("HC11: Invalid opcode 0x%02X at %04X\n", READ8(m_pc-1), m_pc-1);
3589}
trunk/src/emu/cpu/mc68hc11/hc11ops.inc
r0r28739
1#define SET_Z8(r)           (m_ccr |= ((UINT8)r == 0) ? CC_Z : 0)
2#define SET_Z16(r)          (m_ccr |= ((UINT16)r == 0) ? CC_Z : 0)
3#define SET_N8(r)           (m_ccr |= (r & 0x80) ? CC_N : 0)
4#define SET_N16(r)          (m_ccr |= (r & 0x8000) ? CC_N : 0)
5#define SET_V_ADD8(r,s,d)   (m_ccr |= (((r) ^ (s)) & ((r) ^ (d)) & 0x80) ? CC_V : 0)
6#define SET_V_SUB8(r,s,d)   (m_ccr |= (((d) ^ (s)) & ((d) ^ (r)) & 0x80) ? CC_V : 0)
7#define SET_V_ADD16(r,s,d)  (m_ccr |= (((r) ^ (s)) & ((r) ^ (d)) & 0x8000) ? CC_V : 0)
8#define SET_V_SUB16(r,s,d)  (m_ccr |= (((d) ^ (s)) & ((d) ^ (r)) & 0x8000) ? CC_V : 0)
9#define SET_H(r,s,d)        (m_ccr |= (((r) ^ (s) ^ (d)) & 0x10) ? CC_H : 0)
10#define SET_C8(x)           (m_ccr |= ((x) & 0x100) ? CC_C : 0)
11#define SET_C16(x)          (m_ccr |= ((x) & 0x10000) ? CC_C : 0)
12#define CLEAR_Z()           (m_ccr &= ~(CC_Z))
13#define CLEAR_C()           (m_ccr &= ~(CC_C))
14#define CLEAR_NZV()         (m_ccr &= ~(CC_N | CC_Z | CC_V))
15#define CLEAR_ZVC()         (m_ccr &= ~(CC_Z | CC_V | CC_C))
16#define CLEAR_NZVC()        (m_ccr &= ~(CC_N | CC_Z | CC_V | CC_C))
17#define CLEAR_HNZVC()       (m_ccr &= ~(CC_H | CC_N | CC_Z | CC_V | CC_C))
18
19#define SET_ZFLAG()         (m_ccr |= CC_Z)
20#define SET_NFLAG()         (m_ccr |= CC_N)
21#define SET_VFLAG()         (m_ccr |= CC_V)
22
23#define REG_A               m_d.d8.a
24#define REG_B               m_d.d8.b
25#define REG_D               m_d.d16
26
27void mc68hc11_cpu_device::CYCLES(int cycles)
28{
29   m_icount -= cycles;
30}
31
32void mc68hc11_cpu_device::SET_PC(int pc)
33{
34   m_pc = pc;
35}
36
37void mc68hc11_cpu_device::PUSH8(UINT8 value)
38{
39   WRITE8(m_sp--, value);
40}
41
42void mc68hc11_cpu_device::PUSH16(UINT16 value)
43{
44   WRITE8(m_sp--, (value >> 0) & 0xff);
45   WRITE8(m_sp--, (value >> 8) & 0xff);
46}
47
48UINT8 mc68hc11_cpu_device::POP8()
49{
50   return READ8(++m_sp);
51}
52
53UINT16 mc68hc11_cpu_device::POP16()
54{
55   UINT16 r = 0;
56   r |= (READ8(++m_sp) << 8);
57   r |= (READ8(++m_sp) << 0);
58   return r;
59}
60
61
62
63/*****************************************************************************/
64
65/* ABA              0x1B */
66void HC11OP(aba)()
67{
68   UINT16 r = REG_A + REG_B;
69   CLEAR_HNZVC();
70   SET_H(r, REG_B, REG_A);
71   SET_N8(r);
72   SET_Z8(r);
73   SET_V_ADD8(r, REG_B, REG_A);
74   SET_C8(r);
75   REG_A = (UINT8)r;
76   CYCLES(2);
77}
78
79
80/* ABX              0x3A */
81void HC11OP(abx)()
82{
83   m_ix += REG_B;
84   CYCLES(3);
85}
86
87
88/* ABY              0x18, 0x3A */
89void HC11OP(aby)()
90{
91   m_iy += REG_B;
92   CYCLES(4);
93}
94
95
96/* ADCA IMM         0x89 */
97void HC11OP(adca_imm)()
98{
99   UINT8 i = FETCH();
100   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
101   CLEAR_HNZVC();
102   SET_H(r, i, REG_A);
103   SET_N8(r);
104   SET_Z8(r);
105   SET_V_ADD8(r, i, REG_A);
106   SET_C8(r);
107   REG_A = (UINT8)r;
108   CYCLES(2);
109}
110
111/* ADCA DIR         0x99 */
112void HC11OP(adca_dir)()
113{
114   UINT8 d = FETCH();
115   UINT8 i = READ8(d);
116   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
117   CLEAR_HNZVC();
118   SET_H(r, i, REG_A);
119   SET_N8(r);
120   SET_Z8(r);
121   SET_V_ADD8(r, i, REG_A);
122   SET_C8(r);
123   REG_A = (UINT8)r;
124   CYCLES(3);
125}
126
127/* ADCA EXT         0xB9 */
128void HC11OP(adca_ext)()
129{
130   UINT16 adr = FETCH16();
131   UINT8 i = READ8(adr);
132   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
133   CLEAR_HNZVC();
134   SET_H(r, i, REG_A);
135   SET_N8(r);
136   SET_Z8(r);
137   SET_V_ADD8(r, i, REG_A);
138   SET_C8(r);
139   REG_A = (UINT8)r;
140   CYCLES(4);
141}
142
143/* ADCA IND, X      0xA9 */
144void HC11OP(adca_indx)()
145{
146   UINT8 offset = FETCH();
147   UINT8 i = READ8(m_ix + offset);
148   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
149   CLEAR_HNZVC();
150   SET_H(r, i, REG_A);
151   SET_N8(r);
152   SET_Z8(r);
153   SET_V_ADD8(r, i, REG_A);
154   SET_C8(r);
155   REG_A = (UINT8)r;
156   CYCLES(4);
157}
158
159/* ADCA IND, Y      0x18, 0xA9 */
160void HC11OP(adca_indy)()
161{
162   UINT8 offset = FETCH();
163   UINT8 i = READ8(m_iy + offset);
164   UINT16 r = REG_A + i + ((m_ccr & CC_C) ? 1 : 0);
165   CLEAR_HNZVC();
166   SET_H(r, i, REG_A);
167   SET_N8(r);
168   SET_Z8(r);
169   SET_V_ADD8(r, i, REG_A);
170   SET_C8(r);
171   REG_A = (UINT8)r;
172   CYCLES(5);
173}
174
175
176/* ADCB IMM         0xC9 */
177void HC11OP(adcb_imm)()
178{
179   UINT8 i = FETCH();
180   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
181   CLEAR_HNZVC();
182   SET_H(r, i, REG_B);
183   SET_N8(r);
184   SET_Z8(r);
185   SET_V_ADD8(r, i, REG_B);
186   SET_C8(r);
187   REG_B = (UINT8)r;
188   CYCLES(2);
189}
190
191/* ADCB DIR         0xD9 */
192void HC11OP(adcb_dir)()
193{
194   UINT8 d = FETCH();
195   UINT8 i = READ8(d);
196   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
197   CLEAR_HNZVC();
198   SET_H(r, i, REG_B);
199   SET_N8(r);
200   SET_Z8(r);
201   SET_V_ADD8(r, i, REG_B);
202   SET_C8(r);
203   REG_B = (UINT8)r;
204   CYCLES(3);
205}
206
207/* ADCB EXT         0xF9 */
208void HC11OP(adcb_ext)()
209{
210   UINT16 adr = FETCH16();
211   UINT8 i = READ8(adr);
212   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
213   CLEAR_HNZVC();
214   SET_H(r, i, REG_B);
215   SET_N8(r);
216   SET_Z8(r);
217   SET_V_ADD8(r, i, REG_B);
218   SET_C8(r);
219   REG_B = (UINT8)r;
220   CYCLES(4);
221}
222
223/* ADCB IND, X      0xE9 */
224void HC11OP(adcb_indx)()
225{
226   UINT8 offset = FETCH();
227   UINT8 i = READ8(m_ix + offset);
228   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
229   CLEAR_HNZVC();
230   SET_H(r, i, REG_B);
231   SET_N8(r);
232   SET_Z8(r);
233   SET_V_ADD8(r, i, REG_B);
234   SET_C8(r);
235   REG_B = (UINT8)r;
236   CYCLES(4);
237}
238
239/* ADCB IND, Y      0x18, 0xE9 */
240void HC11OP(adcb_indy)()
241{
242   UINT8 offset = FETCH();
243   UINT8 i = READ8(m_iy + offset);
244   UINT16 r = REG_B + i + ((m_ccr & CC_C) ? 1 : 0);
245   CLEAR_HNZVC();
246   SET_H(r, i, REG_B);
247   SET_N8(r);
248   SET_Z8(r);
249   SET_V_ADD8(r, i, REG_B);
250   SET_C8(r);
251   REG_B = (UINT8)r;
252   CYCLES(5);
253}
254
255
256/* ADDA IMM         0x8B */
257void HC11OP(adda_imm)()
258{
259   UINT8 i = FETCH();
260   UINT16 r = REG_A + i;
261   CLEAR_HNZVC();
262   SET_H(r, i, REG_A);
263   SET_N8(r);
264   SET_Z8(r);
265   SET_V_ADD8(r, i, REG_A);
266   SET_C8(r);
267   REG_A = (UINT8)r;
268   CYCLES(2);
269}
270
271/* ADDA DIR         0x9B */
272void HC11OP(adda_dir)()
273{
274   UINT8 d = FETCH();
275   UINT8 i = READ8(d);
276   UINT16 r = REG_A + i;
277   CLEAR_HNZVC();
278   SET_H(r, i, REG_A);
279   SET_N8(r);
280   SET_Z8(r);
281   SET_V_ADD8(r, i, REG_A);
282   SET_C8(r);
283   REG_A = (UINT8)r;
284   CYCLES(3);
285}
286
287/* ADDA EXT         0xBB */
288void HC11OP(adda_ext)()
289{
290   UINT16 adr = FETCH16();
291   UINT8 i = READ8(adr);
292   UINT16 r = REG_A + i;
293   CLEAR_HNZVC();
294   SET_H(r, i, REG_A);
295   SET_N8(r);
296   SET_Z8(r);
297   SET_V_ADD8(r, i, REG_A);
298   SET_C8(r);
299   REG_A = (UINT8)r;
300   CYCLES(4);
301}
302
303/* ADDA IND, X      0xAB */
304void HC11OP(adda_indx)()
305{
306   UINT8 offset = FETCH();
307   UINT8 i = READ8(m_ix + offset);
308   UINT16 r = REG_A + i;
309   CLEAR_HNZVC();
310   SET_H(r, i, REG_A);
311   SET_N8(r);
312   SET_Z8(r);
313   SET_V_ADD8(r, i, REG_A);
314   SET_C8(r);
315   REG_A = (UINT8)r;
316   CYCLES(4);
317}
318
319/* ADDA IND, Y      0x18, 0xAB */
320void HC11OP(adda_indy)()
321{
322   UINT8 offset = FETCH();
323   UINT8 i = READ8(m_iy + offset);
324   UINT16 r = REG_A + i;
325   CLEAR_HNZVC();
326   SET_H(r, i, REG_A);
327   SET_N8(r);
328   SET_Z8(r);
329   SET_V_ADD8(r, i, REG_A);
330   SET_C8(r);
331   REG_A = (UINT8)r;
332   CYCLES(5);
333}
334
335
336/* ADDB IMM         0xCB */
337void HC11OP(addb_imm)()
338{
339   UINT8 i = FETCH();
340   UINT16 r = REG_B + i;
341   CLEAR_HNZVC();
342   SET_H(r, i, REG_B);
343   SET_N8(r);
344   SET_Z8(r);
345   SET_V_ADD8(r, i, REG_B);
346   SET_C8(r);
347   REG_B = (UINT8)r;
348   CYCLES(2);
349}
350
351/* ADDB DIR         0xDB */
352void HC11OP(addb_dir)()
353{
354   UINT8 d = FETCH();
355   UINT8 i = READ8(d);
356   UINT16 r = REG_B + i;
357   CLEAR_HNZVC();
358   SET_H(r, i, REG_B);
359   SET_N8(r);
360   SET_Z8(r);
361   SET_V_ADD8(r, i, REG_B);
362   SET_C8(r);
363   REG_B = (UINT8)r;
364   CYCLES(3);
365}
366
367/* ADDB EXT         0xFB */
368void HC11OP(addb_ext)()
369{
370   UINT16 adr = FETCH16();
371   UINT8 i = READ8(adr);
372   UINT16 r = REG_B + i;
373   CLEAR_HNZVC();
374   SET_H(r, i, REG_B);
375   SET_N8(r);
376   SET_Z8(r);
377   SET_V_ADD8(r, i, REG_B);
378   SET_C8(r);
379   REG_B = (UINT8)r;
380   CYCLES(4);
381}
382
383/* ADDB IND, X      0xEB */
384void HC11OP(addb_indx)()
385{
386   UINT8 offset = FETCH();
387   UINT8 i = READ8(m_ix + offset);
388   UINT16 r = REG_B + i;
389   CLEAR_HNZVC();
390   SET_H(r, i, REG_B);
391   SET_N8(r);
392   SET_Z8(r);
393   SET_V_ADD8(r, i, REG_B);
394   SET_C8(r);
395   REG_B = (UINT8)r;
396   CYCLES(4);
397}
398
399/* ADDB IND, Y      0x18, 0xEB */
400void HC11OP(addb_indy)()
401{
402   UINT8 offset = FETCH();
403   UINT8 i = READ8(m_iy + offset);
404   UINT16 r = REG_B + i;
405   CLEAR_HNZVC();
406   SET_H(r, i, REG_B);
407   SET_N8(r);
408   SET_Z8(r);
409   SET_V_ADD8(r, i, REG_B);
410   SET_C8(r);
411   REG_B = (UINT8)r;
412   CYCLES(5);
413}
414
415
416/* ADDD IMM         0xC3 */
417void HC11OP(addd_imm)()
418{
419   UINT16 i = FETCH16();
420   UINT32 r = REG_D + i;
421   CLEAR_NZVC();
422   SET_N16(r);
423   SET_Z16(r);
424   SET_V_ADD16(r, i, REG_D);
425   SET_C16(r);
426   REG_D = (UINT16)r;
427   CYCLES(4);
428}
429
430/* ADDD DIR         0xD3 */
431void HC11OP(addd_dir)()
432{
433   UINT8 d = FETCH();
434   UINT16 i = READ16(d);
435   UINT32 r = REG_D + i;
436   CLEAR_NZVC();
437   SET_N16(r);
438   SET_Z16(r);
439   SET_V_ADD16(r, i, REG_D);
440   SET_C16(r);
441   REG_D = (UINT16)r;
442   CYCLES(5);
443}
444
445/* ADDD EXT         0xF3 */
446void HC11OP(addd_ext)()
447{
448   UINT16 adr = FETCH16();
449   UINT16 i = READ16(adr);
450   UINT32 r = REG_D + i;
451   CLEAR_NZVC();
452   SET_N16(r);
453   SET_Z16(r);
454   SET_V_ADD16(r, i, REG_D);
455   SET_C16(r);
456   REG_D = (UINT16)r;
457   CYCLES(6);
458}
459
460/* ADDD IND, X      0xE3 */
461void HC11OP(addd_indx)()
462{
463   UINT8 offset = FETCH();
464   UINT16 i = READ16(m_ix + offset);
465   UINT32 r = REG_D + i;
466   CLEAR_NZVC();
467   SET_N16(r);
468   SET_Z16(r);
469   SET_V_ADD16(r, i, REG_D);
470   SET_C16(r);
471   REG_D = (UINT16)r;
472   CYCLES(6);
473}
474
475/* ADDD IND, Y      0x18, 0xE3 */
476void HC11OP(addd_indy)()
477{
478   UINT8 offset = FETCH();
479   UINT16 i = READ16(m_iy + offset);
480   UINT32 r = REG_D + i;
481   CLEAR_NZVC();
482   SET_N16(r);
483   SET_Z16(r);
484   SET_V_ADD16(r, i, REG_D);
485   SET_C16(r);
486   REG_D = (UINT16)r;
487   CYCLES(7);
488}
489
490
491/* ANDA IMM         0x84 */
492void HC11OP(anda_imm)()
493{
494   UINT8 i = FETCH();
495   CLEAR_NZV();
496   REG_A &= i;
497   SET_N8(REG_A);
498   SET_Z8(REG_A);
499   CYCLES(2);
500}
501
502/* ANDA DIR         0x94 */
503void HC11OP(anda_dir)()
504{
505   UINT8 d = FETCH();
506   UINT8 i = READ8(d);
507   CLEAR_NZV();
508   REG_A &= i;
509   SET_N8(REG_A);
510   SET_Z8(REG_A);
511   CYCLES(3);
512}
513
514/* ANDA EXT         0xB4 */
515void HC11OP(anda_ext)()
516{
517   UINT16 adr = FETCH16();
518   UINT8 i = READ8(adr);
519   CLEAR_NZV();
520   REG_A &= i;
521   SET_N8(REG_A);
522   SET_Z8(REG_A);
523   CYCLES(4);
524}
525
526/* ANDA IND, X      0xA4 */
527void HC11OP(anda_indx)()
528{
529   UINT8 offset = FETCH();
530   UINT8 i = READ8(m_ix + offset);
531   CLEAR_NZV();
532   REG_A &= i;
533   SET_N8(REG_A);
534   SET_Z8(REG_A);
535   CYCLES(4);
536}
537
538/* ANDA IND, Y      0x18, 0xA4 */
539void HC11OP(anda_indy)()
540{
541   UINT8 offset = FETCH();
542   UINT8 i = READ8(m_iy + offset);
543   CLEAR_NZV();
544   REG_A &= i;
545   SET_N8(REG_A);
546   SET_Z8(REG_A);
547   CYCLES(5);
548}
549
550
551/* ANDB IMM         0xC4 */
552void HC11OP(andb_imm)()
553{
554   UINT8 i = FETCH();
555   CLEAR_NZV();
556   REG_B &= i;
557   SET_N8(REG_B);
558   SET_Z8(REG_B);
559   CYCLES(2);
560}
561
562/* ANDB DIR         0xD4 */
563void HC11OP(andb_dir)()
564{
565   UINT8 d = FETCH();
566   UINT8 i = READ8(d);
567   CLEAR_NZV();
568   REG_B &= i;
569   SET_N8(REG_B);
570   SET_Z8(REG_B);
571   CYCLES(3);
572}
573
574/* ANDB EXT         0xF4 */
575void HC11OP(andb_ext)()
576{
577   UINT16 adr = FETCH16();
578   UINT8 i = READ8(adr);
579   CLEAR_NZV();
580   REG_B &= i;
581   SET_N8(REG_B);
582   SET_Z8(REG_B);
583   CYCLES(4);
584}
585
586/* ANDB IND, X      0xE4 */
587void HC11OP(andb_indx)()
588{
589   UINT8 offset = FETCH();
590   UINT8 i = READ8(m_ix + offset);
591   CLEAR_NZV();
592   REG_B &= i;
593   SET_N8(REG_B);
594   SET_Z8(REG_B);
595   CYCLES(4);
596}
597
598/* ANDB IND, Y      0x18, 0xE4 */
599void HC11OP(andb_indy)()
600{
601   UINT8 offset = FETCH();
602   UINT8 i = READ8(m_iy + offset);
603   CLEAR_NZV();
604   REG_B &= i;
605   SET_N8(REG_B);
606   SET_Z8(REG_B);
607   CYCLES(5);
608}
609
610/* ASLA             0x48 */
611void HC11OP(asla)()
612{
613   UINT16 r = REG_A << 1;
614   CLEAR_NZVC();
615   SET_C8(r);
616   REG_A = (UINT16)(r);
617   SET_N8(REG_A);
618   SET_Z8(REG_A);
619
620   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
621      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
622   {
623      m_ccr |= CC_V;
624   }
625
626   CYCLES(2);
627}
628
629/* ASLB             0x58 */
630void HC11OP(aslb)()
631{
632   UINT16 r = REG_B << 1;
633   CLEAR_NZVC();
634   SET_C8(r);
635   REG_B = (UINT16)(r);
636   SET_N8(REG_B);
637   SET_Z8(REG_B);
638
639   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
640      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
641   {
642      m_ccr |= CC_V;
643   }
644
645   CYCLES(2);
646}
647
648/* ASL EXT             0x78 */
649void HC11OP(asl_ext)()
650{
651   UINT16 adr = FETCH16();
652   UINT8 i = READ8(adr);
653   UINT16 r = i << 1;
654   CLEAR_NZVC();
655   SET_C8(r);
656   WRITE8(adr, r);
657   SET_N8(r);
658   SET_Z8(r);
659
660   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
661      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
662   {
663      m_ccr |= CC_V;
664   }
665
666   CYCLES(6);
667}
668
669/* BITA IMM         0x85 */
670void HC11OP(bita_imm)()
671{
672   UINT8 i = FETCH();
673   UINT8 r = REG_A & i;
674   CLEAR_NZV();
675   SET_N8(r);
676   SET_Z8(r);
677   CYCLES(2);
678}
679
680/* BITA DIR         0x95 */
681void HC11OP(bita_dir)()
682{
683   UINT8 d = FETCH();
684   UINT8 i = READ8(d);
685   UINT8 r = REG_A & i;
686   CLEAR_NZV();
687   SET_N8(r);
688   SET_Z8(r);
689   CYCLES(3);
690}
691
692/* BITA EXT         0xB5 */
693void HC11OP(bita_ext)()
694{
695   UINT16 adr = FETCH16();
696   UINT8 i = READ8(adr);
697   UINT8 r = REG_A & i;
698   CLEAR_NZV();
699   SET_N8(r);
700   SET_Z8(r);
701   CYCLES(4);
702}
703
704/* BITA IND, X      0xA5 */
705void HC11OP(bita_indx)()
706{
707   UINT8 offset = FETCH();
708   UINT8 i = READ8(m_ix + offset);
709   UINT8 r = REG_A & i;
710   CLEAR_NZV();
711   SET_N8(r);
712   SET_Z8(r);
713   CYCLES(4);
714}
715
716/* BITA IND, Y      0x18, 0xA5 */
717void HC11OP(bita_indy)()
718{
719   UINT8 offset = FETCH();
720   UINT8 i = READ8(m_iy + offset);
721   UINT8 r = REG_A & i;
722   CLEAR_NZV();
723   SET_N8(r);
724   SET_Z8(r);
725   CYCLES(5);
726}
727
728
729/* BITB IMM         0xC5 */
730void HC11OP(bitb_imm)()
731{
732   UINT8 i = FETCH();
733   UINT8 r = REG_B & i;
734   CLEAR_NZV();
735   SET_N8(r);
736   SET_Z8(r);
737   CYCLES(2);
738}
739
740/* BITB DIR         0xD5 */
741void HC11OP(bitb_dir)()
742{
743   UINT8 d = FETCH();
744   UINT8 i = READ8(d);
745   UINT8 r = REG_B & i;
746   CLEAR_NZV();
747   SET_N8(r);
748   SET_Z8(r);
749   CYCLES(3);
750}
751
752/* BITB EXT         0xF5 */
753void HC11OP(bitb_ext)()
754{
755   UINT16 adr = FETCH16();
756   UINT8 i = READ8(adr);
757   UINT8 r = REG_B & i;
758   CLEAR_NZV();
759   SET_N8(r);
760   SET_Z8(r);
761   CYCLES(4);
762}
763
764/* BITB IND, X      0xE5 */
765void HC11OP(bitb_indx)()
766{
767   UINT8 offset = FETCH();
768   UINT8 i = READ8(m_ix + offset);
769   UINT8 r = REG_B & i;
770   CLEAR_NZV();
771   SET_N8(r);
772   SET_Z8(r);
773   CYCLES(4);
774}
775
776/* BITB IND, Y      0x18, 0xE5 */
777void HC11OP(bitb_indy)()
778{
779   UINT8 offset = FETCH();
780   UINT8 i = READ8(m_iy + offset);
781   UINT8 r = REG_B & i;
782   CLEAR_NZV();
783   SET_N8(r);
784   SET_Z8(r);
785   CYCLES(5);
786}
787
788/* BCC              0x24 */
789void HC11OP(bcc)()
790{
791   INT8 rel = FETCH();
792   if ((m_ccr & CC_C) == 0)    /* Branch if C flag clear */
793   {
794      SET_PC(m_ppc + rel + 2);
795   }
796   CYCLES(3);
797}
798
799/* BCLR DIR       0x15 */
800void HC11OP(bclr_dir)()
801{
802   UINT8 d = FETCH();
803   UINT8 mask = FETCH();
804   UINT8 r = READ8(d) & ~mask;
805   WRITE8(d, r);
806   CLEAR_NZV();
807   SET_N8(r);
808   SET_Z8(r);
809   CYCLES(6);
810}
811
812/* BCLR INDX       0x1d */
813void HC11OP(bclr_indx)()
814{
815   UINT8 offset = FETCH();
816   UINT8 mask = FETCH();
817   UINT8 r = READ8(m_ix + offset) & ~mask;
818   WRITE8(m_ix + offset, r);
819   CLEAR_NZV();
820   SET_N8(r);
821   SET_Z8(r);
822
823   CYCLES(7);
824}
825
826/* BCS              0x25 */
827void HC11OP(bcs)()
828{
829   INT8 rel = FETCH();
830   if (m_ccr & CC_C)           /* Branch if C flag set */
831   {
832      SET_PC(m_ppc + rel + 2);
833   }
834   CYCLES(3);
835}
836
837
838/* BEQ              0x27 */
839void HC11OP(beq)()
840{
841   INT8 rel = FETCH();
842   if (m_ccr & CC_Z)           /* Branch if Z flag set */
843   {
844      SET_PC(m_ppc + rel + 2);
845   }
846   CYCLES(3);
847}
848
849
850/* BHI              0x22 */
851void HC11OP(bhi)()
852{
853   INT8 rel = FETCH();
854   if (((m_ccr & CC_C) == 0) && ((m_ccr & CC_Z) == 0)) /* Branch if C and Z flag clear */
855   {
856      SET_PC(m_ppc + rel + 2);
857   }
858   CYCLES(3);
859}
860
861
862/* BNE              0x26 */
863void HC11OP(bne)()
864{
865   INT8 rel = FETCH();
866   if ((m_ccr & CC_Z) == 0)        /* Branch if Z flag clear */
867   {
868      SET_PC(m_ppc + rel + 2);
869   }
870   CYCLES(3);
871}
872
873
874/* BLE              0x2F */
875void HC11OP(ble)()
876{
877   UINT8 n = (m_ccr & CC_N) ? 1 : 0;
878   UINT8 v = (m_ccr & CC_V) ? 1 : 0;
879   INT8 rel = FETCH();
880   if ((m_ccr & CC_Z) || (n ^ v))  /* Branch if Z flag set or (N ^ V) */
881   {
882      SET_PC(m_ppc + rel + 2);
883   }
884   CYCLES(3);
885}
886
887/* BLS              0x23 */
888void HC11OP(bls)()
889{
890   INT8 rel = FETCH();
891   if (m_ccr & CC_C || m_ccr & CC_Z)   /* Branch if C or Z flag set */
892   {
893      SET_PC(m_ppc + rel + 2);
894   }
895   CYCLES(3);
896}
897
898/* BMI              0x2B */
899void HC11OP(bmi)()
900{
901   INT8 rel = FETCH();
902   if (m_ccr & CC_N)       /* Branch if N flag set */
903   {
904      SET_PC(m_ppc + rel + 2);
905   }
906   CYCLES(3);
907}
908
909/* BPL              0x2A */
910void HC11OP(bpl)()
911{
912   INT8 rel = FETCH();
913   if ((m_ccr & CC_N) == 0)        /* Branch if N flag clear */
914   {
915      SET_PC(m_ppc + rel + 2);
916   }
917   CYCLES(3);
918}
919
920
921/* BRA              0x20 */
922void HC11OP(bra)()
923{
924   INT8 rel = FETCH();
925   SET_PC(m_ppc + rel + 2);
926   CYCLES(3);
927}
928
929/* BRCLR DIR       0x13 */
930void HC11OP(brclr_dir)()
931{
932   UINT8 d = FETCH();
933   UINT8 mask = FETCH();
934   INT8 rel = FETCH();
935   UINT8 i = READ8(d);
936
937   if ((i & mask) == 0)
938   {
939      SET_PC(m_ppc + rel + 4);
940   }
941
942   CYCLES(6);
943}
944
945
946/* BRCLR INDX       0x1F */
947void HC11OP(brclr_indx)()
948{
949   UINT8 offset = FETCH();
950   UINT8 mask = FETCH();
951   INT8 rel = FETCH();
952   UINT8 i = READ8(m_ix + offset);
953
954   if ((i & mask) == 0)
955   {
956      SET_PC(m_ppc + rel + 4);
957   }
958
959   CYCLES(7);
960}
961
962/* BRSET DIR       0x12 */
963void HC11OP(brset_dir)()
964{
965   UINT8 d = FETCH();
966   UINT8 mask = FETCH();
967   INT8 rel = FETCH();
968   UINT8 i = READ8(d);
969
970   if(i & mask)
971   {
972      SET_PC(m_ppc + rel + 4);
973   }
974
975   CYCLES(6);
976}
977
978
979/* BRSET INDX       0x1E */
980void HC11OP(brset_indx)()
981{
982   UINT8 offset = FETCH();
983   UINT8 mask = FETCH();
984   INT8 rel = FETCH();
985   UINT8 i = READ8(m_ix + offset);
986
987   if ((~i & mask) == 0)
988   {
989      SET_PC(m_ppc + rel + 4);
990   }
991
992   CYCLES(7);
993}
994
995
996/* BRN              0x21 */
997void HC11OP(brn)()
998{
999   /* with this opcode the branch condition is always false. */
1000   SET_PC(m_ppc + 2);
1001   CYCLES(3);
1002}
1003
1004/* BSET DIR       0x14 */
1005void HC11OP(bset_dir)()
1006{
1007   UINT8 d = FETCH();
1008   UINT8 mask = FETCH();
1009   UINT8 r = READ8(d) | mask;
1010   WRITE8(d, r);
1011   CLEAR_NZV();
1012   SET_N8(r);
1013   SET_Z8(r);
1014   CYCLES(6);
1015}
1016
1017/* BSET INDX       0x1c */
1018void HC11OP(bset_indx)()
1019{
1020   UINT8 offset = FETCH();
1021   UINT8 mask = FETCH();
1022   UINT8 r = READ8(m_ix + offset) | mask;
1023   WRITE8(m_ix + offset, r);
1024   CLEAR_NZV();
1025   SET_N8(r);
1026   SET_Z8(r);
1027
1028   CYCLES(7);
1029}
1030
1031/* BSR              0x8D */
1032void HC11OP(bsr)()
1033{
1034   INT8 rel = FETCH();
1035   UINT16 rt_adr = m_pc;
1036   PUSH16(rt_adr);
1037   SET_PC(m_ppc + rel + 2);
1038   CYCLES(6);
1039}
1040
1041/* BVC              0x28 */
1042void HC11OP(bvc)()
1043{
1044   INT8 rel = FETCH();
1045   if ((m_ccr & CC_V) == 0)    /* Branch if V flag clear */
1046   {
1047      SET_PC(m_ppc + rel + 2);
1048   }
1049   CYCLES(3);
1050}
1051
1052/* BVS              0x29 */
1053void HC11OP(bvs)()
1054{
1055   INT8 rel = FETCH();
1056   if (m_ccr & CC_V)   /* Branch if V flag set */
1057   {
1058      SET_PC(m_ppc + rel + 2);
1059   }
1060   CYCLES(3);
1061}
1062
1063/* CBA              0x11 */
1064void HC11OP(cba)()
1065{
1066   UINT16 r = REG_A - REG_B;
1067   CLEAR_NZVC();
1068   SET_N8(r);
1069   SET_Z8(r);
1070   SET_V_SUB8(r, REG_B, REG_A);
1071   SET_C8(r);
1072   CYCLES(2);
1073}
1074
1075/* CLC              0x0C */
1076void HC11OP(clc)()
1077{
1078   m_ccr &= ~CC_C;
1079   CYCLES(2);
1080}
1081
1082
1083/* CLI              0x0E */
1084void HC11OP(cli)()
1085{
1086   m_ccr &= ~CC_I;
1087   CYCLES(2);
1088}
1089
1090
1091/* CLRA             0x4F */
1092void HC11OP(clra)()
1093{
1094   REG_A = 0;
1095   CLEAR_NZVC();
1096   SET_ZFLAG();
1097   CYCLES(2);
1098}
1099
1100/* CLRB             0x5F */
1101void HC11OP(clrb)()
1102{
1103   REG_B = 0;
1104   CLEAR_NZVC();
1105   SET_ZFLAG();
1106   CYCLES(2);
1107}
1108
1109/* CLR EXT          0x7F */
1110void HC11OP(clr_ext)()
1111{
1112   UINT16 adr = FETCH16();
1113   WRITE8(adr, 0);
1114   CLEAR_NZVC();
1115   SET_ZFLAG();
1116   CYCLES(6);
1117}
1118
1119/* CLR IND, X       0x6F */
1120void HC11OP(clr_indx)()
1121{
1122   UINT8 offset = FETCH();
1123   WRITE8(m_ix + offset, 0);
1124   CLEAR_NZVC();
1125   SET_ZFLAG();
1126   CYCLES(6);
1127}
1128
1129/* CLR IND, Y       0x18, 0x6F */
1130void HC11OP(clr_indy)()
1131{
1132   UINT8 offset = FETCH();
1133   WRITE8(m_iy + offset, 0);
1134   CLEAR_NZVC();
1135   SET_ZFLAG();
1136   CYCLES(7);
1137}
1138
1139
1140/* CLV              0x0A */
1141void HC11OP(clv)()
1142{
1143   m_ccr &= ~CC_V;
1144   CYCLES(2);
1145}
1146
1147
1148/* CMPA IMM         0x81 */
1149void HC11OP(cmpa_imm)()
1150{
1151   UINT8 i = FETCH();
1152   UINT16 r = REG_A - i;
1153   CLEAR_NZVC();
1154   SET_N8(r);
1155   SET_Z8(r);
1156   SET_V_SUB8(r, i, REG_A);
1157   SET_C8(r);
1158   CYCLES(2);
1159}
1160
1161/* CMPA DIR         0x91 */
1162void HC11OP(cmpa_dir)()
1163{
1164   UINT8 d = FETCH();
1165   UINT8 i = READ8(d);
1166   UINT16 r = REG_A - i;
1167   CLEAR_NZVC();
1168   SET_N8(r);
1169   SET_Z8(r);
1170   SET_V_SUB8(r, i, REG_A);
1171   SET_C8(r);
1172   CYCLES(3);
1173}
1174
1175/* CMPA EXT         0xB1 */
1176void HC11OP(cmpa_ext)()
1177{
1178   UINT16 adr = FETCH16();
1179   UINT8 i = READ8(adr);
1180   UINT16 r = REG_A - i;
1181   CLEAR_NZVC();
1182   SET_N8(r);
1183   SET_Z8(r);
1184   SET_V_SUB8(r, i, REG_A);
1185   SET_C8(r);
1186   CYCLES(4);
1187}
1188
1189/* CMPA IND, X      0xA1 */
1190void HC11OP(cmpa_indx)()
1191{
1192   UINT8 offset = FETCH();
1193   UINT8 i = READ8(m_ix + offset);
1194   UINT16 r = REG_A - i;
1195   CLEAR_NZVC();
1196   SET_N8(r);
1197   SET_Z8(r);
1198   SET_V_SUB8(r, i, REG_A);
1199   SET_C8(r);
1200   CYCLES(4);
1201}
1202
1203/* CMPA IND, Y      0x18, 0xA1 */
1204void HC11OP(cmpa_indy)()
1205{
1206   UINT8 offset = FETCH();
1207   UINT8 i = READ8(m_iy + offset);
1208   UINT16 r = REG_A - i;
1209   CLEAR_NZVC();
1210   SET_N8(r);
1211   SET_Z8(r);
1212   SET_V_SUB8(r, i, REG_A);
1213   SET_C8(r);
1214   CYCLES(5);
1215}
1216
1217
1218/* CMPB IMM         0xC1 */
1219void HC11OP(cmpb_imm)()
1220{
1221   UINT8 i = FETCH();
1222   UINT16 r = REG_B - i;
1223   CLEAR_NZVC();
1224   SET_N8(r);
1225   SET_Z8(r);
1226   SET_V_SUB8(r, i, REG_B);
1227   SET_C8(r);
1228   CYCLES(2);
1229}
1230
1231/* CMPB DIR         0xD1 */
1232void HC11OP(cmpb_dir)()
1233{
1234   UINT8 d = FETCH();
1235   UINT8 i = READ8(d);
1236   UINT16 r = REG_B - i;
1237   CLEAR_NZVC();
1238   SET_N8(r);
1239   SET_Z8(r);
1240   SET_V_SUB8(r, i, REG_B);
1241   SET_C8(r);
1242   CYCLES(3);
1243}
1244
1245/* CMPB EXT         0xF1 */
1246void HC11OP(cmpb_ext)()
1247{
1248   UINT16 adr = FETCH16();
1249   UINT8 i = READ8(adr);
1250   UINT16 r = REG_B - i;
1251   CLEAR_NZVC();
1252   SET_N8(r);
1253   SET_Z8(r);
1254   SET_V_SUB8(r, i, REG_B);
1255   SET_C8(r);
1256   CYCLES(4);
1257}
1258
1259/* CMPB IND, X      0xE1 */
1260void HC11OP(cmpb_indx)()
1261{
1262   UINT8 offset = FETCH();
1263   UINT8 i = READ8(m_ix + offset);
1264   UINT16 r = REG_B - i;
1265   CLEAR_NZVC();
1266   SET_N8(r);
1267   SET_Z8(r);
1268   SET_V_SUB8(r, i, REG_B);
1269   SET_C8(r);
1270   CYCLES(4);
1271}
1272
1273/* CMPB IND, Y      0x18, 0xE1 */
1274void HC11OP(cmpb_indy)()
1275{
1276   UINT8 offset = FETCH();
1277   UINT8 i = READ8(m_iy + offset);
1278   UINT16 r = REG_B - i;
1279   CLEAR_NZVC();
1280   SET_N8(r);
1281   SET_Z8(r);
1282   SET_V_SUB8(r, i, REG_B);
1283   SET_C8(r);
1284   CYCLES(5);
1285}
1286
1287
1288/* COMA              , 0x43 */
1289void HC11OP(coma)()
1290{
1291   UINT16 r = 0xff - REG_A;
1292   CLEAR_NZVC();
1293   SET_N8(r);
1294   SET_Z8(r);
1295   m_ccr |= CC_C; //always set for M6800 compatibility
1296   REG_A = r;
1297   CYCLES(2);
1298}
1299
1300
1301/* COMB              , 0x53 */
1302void HC11OP(comb)()
1303{
1304   UINT16 r = 0xff - REG_B;
1305   CLEAR_NZVC();
1306   SET_N8(r);
1307   SET_Z8(r);
1308   m_ccr |= CC_C; //always set for M6800 compatibility
1309   REG_B = r;
1310   CYCLES(2);
1311}
1312
1313
1314/* CPD IMM          0x1A, 0x83 */
1315void HC11OP(cpd_imm)()
1316{
1317   UINT16 i = FETCH16();
1318   UINT32 r = REG_D - i;
1319   CLEAR_NZVC();
1320   SET_N16(r);
1321   SET_Z16(r);
1322   SET_V_SUB16(r, i, REG_D);
1323   SET_C16(r);
1324   CYCLES(5);
1325}
1326
1327/* CPD DIR          0x1A, 0x93 */
1328void HC11OP(cpd_dir)()
1329{
1330   UINT8 d = FETCH();
1331   UINT16 i = READ16(d);
1332   UINT32 r = REG_D - i;
1333   CLEAR_NZVC();
1334   SET_N16(r);
1335   SET_Z16(r);
1336   SET_V_SUB16(r, i, REG_D);
1337   SET_C16(r);
1338   CYCLES(6);
1339}
1340
1341/* CPD EXT          0x1A, 0xB3 */
1342void HC11OP(cpd_ext)()
1343{
1344   UINT16 adr = FETCH16();
1345   UINT16 i = READ16(adr);
1346   UINT32 r = REG_D - i;
1347   CLEAR_NZVC();
1348   SET_N16(r);
1349   SET_Z16(r);
1350   SET_V_SUB16(r, i, REG_D);
1351   SET_C16(r);
1352   CYCLES(7);
1353}
1354
1355/* CPD IND, X       0x1A, 0xA3 */
1356void HC11OP(cpd_indx)()
1357{
1358   UINT8 offset = FETCH();
1359   UINT16 i = READ16(m_ix + offset);
1360   UINT32 r = REG_D - i;
1361   CLEAR_NZVC();
1362   SET_N16(r);
1363   SET_Z16(r);
1364   SET_V_SUB16(r, i, REG_D);
1365   SET_C16(r);
1366   CYCLES(7);
1367}
1368
1369/* CPD IND, Y       0xCD, 0xA3 */
1370void HC11OP(cpd_indy)()
1371{
1372   UINT8 offset = FETCH();
1373   UINT16 i = READ16(m_iy + offset);
1374   UINT32 r = REG_D - i;
1375   CLEAR_NZVC();
1376   SET_N16(r);
1377   SET_Z16(r);
1378   SET_V_SUB16(r, i, REG_D);
1379   SET_C16(r);
1380   CYCLES(7);
1381}
1382
1383
1384/* CPX IMM          0x8C */
1385void HC11OP(cpx_imm)()
1386{
1387   UINT16 i = FETCH16();
1388   UINT32 r = m_ix - i;
1389   CLEAR_NZVC();
1390   SET_N16(r);
1391   SET_Z16(r);
1392   SET_V_SUB16(r, i, m_ix);
1393   SET_C16(r);
1394   CYCLES(4);
1395}
1396
1397/* CPX DIR          0x9C */
1398void HC11OP(cpx_dir)()
1399{
1400   UINT8 d = FETCH();
1401   UINT16 i = READ16(d);
1402   UINT32 r = m_ix - i;
1403   CLEAR_NZVC();
1404   SET_N16(r);
1405   SET_Z16(r);
1406   SET_V_SUB16(r, i, m_ix);
1407   SET_C16(r);
1408   CYCLES(5);
1409}
1410
1411/* CPX EXT          0xBC */
1412void HC11OP(cpx_ext)()
1413{
1414   UINT16 adr = FETCH16();
1415   UINT16 i = READ16(adr);
1416   UINT32 r = m_ix - i;
1417   CLEAR_NZVC();
1418   SET_N16(r);
1419   SET_Z16(r);
1420   SET_V_SUB16(r, i, m_ix);
1421   SET_C16(r);
1422   CYCLES(6);
1423}
1424
1425/* CPX IND, X       0xAC */
1426void HC11OP(cpx_indx)()
1427{
1428   UINT8 offset = FETCH();
1429   UINT16 i = READ16(m_ix + offset);
1430   UINT32 r = m_ix - i;
1431   CLEAR_NZVC();
1432   SET_N16(r);
1433   SET_Z16(r);
1434   SET_V_SUB16(r, i, m_ix);
1435   SET_C16(r);
1436   CYCLES(6);
1437}
1438
1439/* CPX IND, Y       0xCD, 0xAC */
1440void HC11OP(cpx_indy)()
1441{
1442   UINT8 offset = FETCH();
1443   UINT16 i = READ16(m_iy + offset);
1444   UINT32 r = m_ix - i;
1445   CLEAR_NZVC();
1446   SET_N16(r);
1447   SET_Z16(r);
1448   SET_V_SUB16(r, i, m_ix);
1449   SET_C16(r);
1450   CYCLES(7);
1451}
1452
1453/* CPY IMM          0x18, 0x8C */
1454void HC11OP(cpy_imm)()
1455{
1456   UINT16 i = FETCH16();
1457   UINT32 r = m_iy - i;
1458   CLEAR_NZVC();
1459   SET_N16(r);
1460   SET_Z16(r);
1461   SET_V_SUB16(r, i, m_iy);
1462   SET_C16(r);
1463   CYCLES(5);
1464}
1465
1466/* CPY DIR          0x18 0x9C */
1467void HC11OP(cpy_dir)()
1468{
1469   UINT8 d = FETCH();
1470   UINT16 i = READ16(d);
1471   UINT32 r = m_iy - i;
1472   CLEAR_NZVC();
1473   SET_N16(r);
1474   SET_Z16(r);
1475   SET_V_SUB16(r, i, m_iy);
1476   SET_C16(r);
1477   CYCLES(6);
1478}
1479
1480/* CPY EXT          0x18 0xBC */
1481void HC11OP(cpy_ext)()
1482{
1483   UINT16 adr = FETCH16();
1484   UINT16 i = READ16(adr);
1485   UINT32 r = m_iy - i;
1486   CLEAR_NZVC();
1487   SET_N16(r);
1488   SET_Z16(r);
1489   SET_V_SUB16(r, i, m_iy);
1490   SET_C16(r);
1491   CYCLES(7);
1492}
1493
1494/* CPY IND, X       0x1A 0xAC */
1495void HC11OP(cpy_indx)()
1496{
1497   UINT8 offset = FETCH();
1498   UINT16 i = READ16(m_ix + offset);
1499   UINT32 r = m_iy - i;
1500   CLEAR_NZVC();
1501   SET_N16(r);
1502   SET_Z16(r);
1503   SET_V_SUB16(r, i, m_iy);
1504   SET_C16(r);
1505   CYCLES(7);
1506}
1507
1508/* CPY IND, Y       0x18 0xAC */
1509void HC11OP(cpy_indy)()
1510{
1511   UINT8 offset = FETCH();
1512   UINT16 i = READ16(m_iy + offset);
1513   UINT32 r = m_iy - i;
1514   CLEAR_NZVC();
1515   SET_N16(r);
1516   SET_Z16(r);
1517   SET_V_SUB16(r, i, m_iy);
1518   SET_C16(r);
1519   CYCLES(7);
1520}
1521
1522/* DECA             0x4A */
1523void HC11OP(deca)()
1524{
1525   CLEAR_NZV();
1526   if (REG_A == 0x80)
1527      SET_VFLAG();
1528   REG_A--;
1529   SET_N8(REG_A);
1530   SET_Z8(REG_A);
1531   CYCLES(2);
1532}
1533
1534/* DECB             0x5A */
1535void HC11OP(decb)()
1536{
1537   CLEAR_NZV();
1538   if (REG_B == 0x80)
1539      SET_VFLAG();
1540   REG_B--;
1541   SET_N8(REG_B);
1542   SET_Z8(REG_B);
1543   CYCLES(2);
1544}
1545
1546/* DEC EXT          0x7A */
1547void HC11OP(dec_ext)()
1548{
1549   UINT16 adr = FETCH16();
1550   UINT8 i = READ8(adr);
1551
1552   CLEAR_NZV();
1553   if (i == 0x80)
1554      SET_VFLAG();
1555   i--;
1556   SET_N8(i);
1557   SET_Z8(i);
1558   WRITE8(adr, i);
1559   CYCLES(6);
1560}
1561
1562/* DEC INDX          0x6A */
1563void HC11OP(dec_indx)()
1564{
1565   UINT8 offset = FETCH();
1566   UINT8 i = READ8(m_ix + offset);
1567
1568   CLEAR_NZV();
1569   if (i == 0x80)
1570      SET_VFLAG();
1571   i--;
1572   SET_N8(i);
1573   SET_Z8(i);
1574   WRITE8(m_ix + offset, i);
1575   CYCLES(6);
1576}
1577
1578/* DEC INDY          0x18 0x6A */
1579void HC11OP(dec_indy)()
1580{
1581   UINT8 offset = FETCH();
1582   UINT8 i = READ8(m_iy + offset);
1583
1584   CLEAR_NZV();
1585   if (i == 0x80)
1586      SET_VFLAG();
1587   i--;
1588   SET_N8(i);
1589   SET_Z8(i);
1590   WRITE8(m_iy + offset, i);
1591   CYCLES(7);
1592}
1593
1594/* DEX              0x09 */
1595void HC11OP(dex)()
1596{
1597   CLEAR_Z();
1598   m_ix--;
1599   SET_Z16(m_ix);
1600   CYCLES(3);
1601}
1602
1603
1604/* DEY              0x18, 0x09 */
1605void HC11OP(dey)()
1606{
1607   CLEAR_Z();
1608   m_iy--;
1609   SET_Z16(m_iy);
1610   CYCLES(4);
1611}
1612
1613
1614/* EORA IMM         0x88 */
1615void HC11OP(eora_imm)()
1616{
1617   UINT8 i = FETCH();
1618   CLEAR_NZV();
1619   REG_A ^= i;
1620   SET_N8(REG_A);
1621   SET_Z8(REG_A);
1622   CYCLES(2);
1623}
1624
1625/* EORA DIR         0x98 */
1626void HC11OP(eora_dir)()
1627{
1628   UINT8 d = FETCH();
1629   UINT8 i = READ8(d);
1630   CLEAR_NZV();
1631   REG_A ^= i;
1632   SET_N8(REG_A);
1633   SET_Z8(REG_A);
1634   CYCLES(3);
1635}
1636
1637/* EORA EXT         0xB8 */
1638void HC11OP(eora_ext)()
1639{
1640   UINT16 adr = FETCH16();
1641   UINT8 i = READ8(adr);
1642   CLEAR_NZV();
1643   REG_A ^= i;
1644   SET_N8(REG_A);
1645   SET_Z8(REG_A);
1646   CYCLES(4);
1647}
1648
1649/* EORA IND, X      0xA8 */
1650void HC11OP(eora_indx)()
1651{
1652   UINT8 offset = FETCH();
1653   UINT8 i = READ8(m_ix + offset);
1654   CLEAR_NZV();
1655   REG_A ^= i;
1656   SET_N8(REG_A);
1657   SET_Z8(REG_A);
1658   CYCLES(4);
1659}
1660
1661/* EORA IND, Y      0x18, 0xA8 */
1662void HC11OP(eora_indy)()
1663{
1664   UINT8 offset = FETCH();
1665   UINT8 i = READ8(m_iy + offset);
1666   CLEAR_NZV();
1667   REG_A ^= i;
1668   SET_N8(REG_A);
1669   SET_Z8(REG_A);
1670   CYCLES(5);
1671}
1672
1673
1674/* EORB IMM         0xC8 */
1675void HC11OP(eorb_imm)()
1676{
1677   UINT8 i = FETCH();
1678   CLEAR_NZV();
1679   REG_B ^= i;
1680   SET_N8(REG_B);
1681   SET_Z8(REG_B);
1682   CYCLES(2);
1683}
1684
1685/* EORB DIR         0xD8 */
1686void HC11OP(eorb_dir)()
1687{
1688   UINT8 d = FETCH();
1689   UINT8 i = READ8(d);
1690   CLEAR_NZV();
1691   REG_B ^= i;
1692   SET_N8(REG_B);
1693   SET_Z8(REG_B);
1694   CYCLES(3);
1695}
1696
1697/* EORB EXT         0xF8 */
1698void HC11OP(eorb_ext)()
1699{
1700   UINT16 adr = FETCH16();
1701   UINT8 i = READ8(adr);
1702   CLEAR_NZV();
1703   REG_B ^= i;
1704   SET_N8(REG_B);
1705   SET_Z8(REG_B);
1706   CYCLES(4);
1707}
1708
1709/* EORB IND, X      0xE8 */
1710void HC11OP(eorb_indx)()
1711{
1712   UINT8 offset = FETCH();
1713   UINT8 i = READ8(m_ix + offset);
1714   CLEAR_NZV();
1715   REG_B ^= i;
1716   SET_N8(REG_B);
1717   SET_Z8(REG_B);
1718   CYCLES(4);
1719}
1720
1721/* EORB IND, Y      0x18, 0xE8 */
1722void HC11OP(eorb_indy)()
1723{
1724   UINT8 offset = FETCH();
1725   UINT8 i = READ8(m_iy + offset);
1726   CLEAR_NZV();
1727   REG_B ^= i;
1728   SET_N8(REG_B);
1729   SET_Z8(REG_B);
1730   CYCLES(5);
1731}
1732
1733/* IDIV             0x02 */
1734void HC11OP(idiv)()
1735{
1736   UINT16 numerator = REG_D;
1737   UINT16 denominator = m_ix;
1738   UINT16 remainder;
1739   UINT16 result;
1740
1741   CLEAR_ZVC();
1742   if(denominator == 0) // divide by zero behaviour
1743   {
1744      remainder = 0xffff; // TODO: undefined behaviour according to the docs
1745      result = 0xffff;
1746      logerror("HC11: divide by zero at PC=%04x\n",m_pc-1);
1747      m_ccr |= CC_C;
1748   }
1749   else
1750   {
1751      remainder = numerator % denominator;
1752      result = numerator / denominator;
1753   }
1754   m_ix = result;
1755   REG_D = remainder;
1756   SET_Z16(result);
1757
1758   CYCLES(41);
1759}
1760
1761/* INCA             0x4C */
1762void HC11OP(inca)()
1763{
1764   CLEAR_NZV();
1765   if (REG_A == 0x7f)
1766      SET_VFLAG();
1767   REG_A++;
1768   SET_N8(REG_A);
1769   SET_Z8(REG_A);
1770   CYCLES(2);
1771}
1772
1773/* INCB             0x5C */
1774void HC11OP(incb)()
1775{
1776   CLEAR_NZV();
1777   if (REG_B == 0x7f)
1778      SET_VFLAG();
1779   REG_B++;
1780   SET_N8(REG_B);
1781   SET_Z8(REG_B);
1782   CYCLES(2);
1783}
1784
1785/* INC EXT          0x7C */
1786void HC11OP(inc_ext)()
1787{
1788   UINT16 adr = FETCH16();
1789   UINT8 i = READ8(adr);
1790
1791   CLEAR_NZV();
1792   if (i == 0x7f)
1793      SET_VFLAG();
1794   i++;
1795   SET_N8(i);
1796   SET_Z8(i);
1797   WRITE8(adr, i);
1798   CYCLES(6);
1799}
1800
1801/* INC INDX          0x6C */
1802void HC11OP(inc_indx)()
1803{
1804   UINT8 offset = FETCH();
1805   UINT8 i = READ8(m_ix + offset);
1806
1807   CLEAR_NZV();
1808   if (i == 0x7f)
1809      SET_VFLAG();
1810   i++;
1811   SET_N8(i);
1812   SET_Z8(i);
1813   WRITE8(m_ix + offset, i);
1814   CYCLES(6);
1815}
1816
1817
1818/* INC INDY          0x18 0x6C */
1819void HC11OP(inc_indy)()
1820{
1821   UINT8 offset = FETCH();
1822   UINT8 i = READ8(m_iy + offset);
1823
1824   CLEAR_NZV();
1825   if (i == 0x7f)
1826      SET_VFLAG();
1827   i++;
1828   SET_N8(i);
1829   SET_Z8(i);
1830   WRITE8(m_iy + offset, i);
1831   CYCLES(7);
1832}
1833
1834
1835/* INX              0x08 */
1836void HC11OP(inx)()
1837{
1838   CLEAR_Z();
1839   m_ix++;
1840   SET_Z16(m_ix);
1841   CYCLES(3);
1842}
1843
1844/* INY              0x18, 0x08 */
1845void HC11OP(iny)()
1846{
1847   CLEAR_Z();
1848   m_iy++;
1849   SET_Z16(m_iy);
1850   CYCLES(4);
1851}
1852
1853/* JMP IND X        0x6E */
1854void HC11OP(jmp_indx)()
1855{
1856   UINT16 adr = FETCH();
1857   SET_PC(m_ix + adr);
1858   CYCLES(3);
1859}
1860
1861/* JMP IND Y        0x18 0x6E */
1862void HC11OP(jmp_indy)()
1863{
1864   UINT16 adr = FETCH();
1865   SET_PC(m_iy + adr);
1866   CYCLES(4);
1867}
1868
1869/* JMP EXT          0x7E */
1870void HC11OP(jmp_ext)()
1871{
1872   UINT16 adr = FETCH16();
1873   SET_PC(adr);
1874   CYCLES(3);
1875}
1876
1877
1878/* JSR DIR          0x9D */
1879void HC11OP(jsr_dir)()
1880{
1881   UINT8 i = FETCH();
1882   UINT16 rt_adr = m_pc;
1883   PUSH16(rt_adr);
1884   SET_PC(i);
1885   CYCLES(5);
1886}
1887
1888/* JSR EXT          0xBD */
1889void HC11OP(jsr_ext)()
1890{
1891   UINT16 adr = FETCH16();
1892   UINT16 rt_adr = m_pc;
1893   PUSH16(rt_adr);
1894   SET_PC(adr);
1895   CYCLES(6);
1896}
1897
1898/* JSR IND, X       0xAD */
1899void HC11OP(jsr_indx)()
1900{
1901   UINT8 offset = FETCH();
1902   UINT16 rt_adr = m_pc;
1903   PUSH16(rt_adr);
1904   SET_PC(m_ix + offset);
1905   CYCLES(6);
1906}
1907
1908/* JSR IND, Y       0x18, 0xAD */
1909void HC11OP(jsr_indy)()
1910{
1911   UINT8 offset = FETCH();
1912   UINT16 rt_adr = m_pc;
1913   PUSH16(rt_adr);
1914   SET_PC(m_iy + offset);
1915   CYCLES(6);
1916}
1917
1918
1919/* LDAA IMM         0x86 */
1920void HC11OP(ldaa_imm)()
1921{
1922   CLEAR_NZV();
1923   REG_A = FETCH();
1924   SET_N8(REG_A);
1925   SET_Z8(REG_A);
1926   CYCLES(2);
1927}
1928
1929/* LDAA DIR         0x96 */
1930void HC11OP(ldaa_dir)()
1931{
1932   UINT8 d = FETCH();
1933   CLEAR_NZV();
1934   REG_A = READ8(d);
1935   SET_N8(REG_A);
1936   SET_Z8(REG_A);
1937   CYCLES(3);
1938}
1939
1940/* LDAA EXT         0xB6 */
1941void HC11OP(ldaa_ext)()
1942{
1943   UINT16 adr = FETCH16();
1944   CLEAR_NZV();
1945   REG_A = READ8(adr);
1946   SET_N8(REG_A);
1947   SET_Z8(REG_A);
1948   CYCLES(4);
1949}
1950
1951/* LDAA IND, X      0xA6 */
1952void HC11OP(ldaa_indx)()
1953{
1954   UINT8 offset = FETCH();
1955   CLEAR_NZV();
1956   REG_A = READ8(m_ix + offset);
1957   SET_N8(REG_A);
1958   SET_Z8(REG_A);
1959   CYCLES(4);
1960}
1961
1962/* LDAA IND, Y      0x18, 0xA6 */
1963void HC11OP(ldaa_indy)()
1964{
1965   UINT8 offset = FETCH();
1966   CLEAR_NZV();
1967   REG_A = READ8(m_iy + offset);
1968   SET_N8(REG_A);
1969   SET_Z8(REG_A);
1970   CYCLES(5);
1971}
1972
1973/* LDAB IMM         0xC6 */
1974void HC11OP(ldab_imm)()
1975{
1976   CLEAR_NZV();
1977   REG_B = FETCH();
1978   SET_N8(REG_B);
1979   SET_Z8(REG_B);
1980   CYCLES(2);
1981}
1982
1983/* LDAB DIR         0xD6 */
1984void HC11OP(ldab_dir)()
1985{
1986   UINT8 d = FETCH();
1987   CLEAR_NZV();
1988   REG_B = READ8(d);
1989   SET_N8(REG_B);
1990   SET_Z8(REG_B);
1991   CYCLES(3);
1992}
1993
1994/* LDAB EXT         0xF6 */
1995void HC11OP(ldab_ext)()
1996{
1997   UINT16 adr = FETCH16();
1998   CLEAR_NZV();
1999   REG_B = READ8(adr);
2000   SET_N8(REG_B);
2001   SET_Z8(REG_B);
2002   CYCLES(4);
2003}
2004
2005/* LDAB IND, X      0xE6 */
2006void HC11OP(ldab_indx)()
2007{
2008   UINT8 offset = FETCH();
2009   CLEAR_NZV();
2010   REG_B = READ8(m_ix + offset);
2011   SET_N8(REG_B);
2012   SET_Z8(REG_B);
2013   CYCLES(4);
2014}
2015
2016/* LDAB IND, Y      0x18, 0xE6 */
2017void HC11OP(ldab_indy)()
2018{
2019   UINT8 offset = FETCH();
2020   CLEAR_NZV();
2021   REG_B = READ8(m_iy + offset);
2022   SET_N8(REG_B);
2023   SET_Z8(REG_B);
2024   CYCLES(5);
2025}
2026
2027
2028/* LDD IMM          0xCC */
2029void HC11OP(ldd_imm)()
2030{
2031   CLEAR_NZV();
2032   REG_D = FETCH16();
2033   SET_N16(REG_D);
2034   SET_Z16(REG_D);
2035   CYCLES(3);
2036}
2037
2038/* LDD DIR          0xDC */
2039void HC11OP(ldd_dir)()
2040{
2041   UINT8 d = FETCH();
2042   CLEAR_NZV();
2043   REG_D = READ16(d);
2044   SET_N16(REG_D);
2045   SET_Z16(REG_D);
2046   CYCLES(4);
2047}
2048
2049/* LDD EXT          0xFC */
2050void HC11OP(ldd_ext)()
2051{
2052   UINT16 adr = FETCH16();
2053   CLEAR_NZV();
2054   REG_D = READ16(adr);
2055   SET_N16(REG_D);
2056   SET_Z16(REG_D);
2057   CYCLES(5);
2058}
2059
2060/* LDD IND, X       0xEC */
2061void HC11OP(ldd_indx)()
2062{
2063   UINT8 offset = FETCH();
2064   CLEAR_NZV();
2065   REG_D = READ16(m_ix + offset);
2066   SET_N16(REG_D);
2067   SET_Z16(REG_D);
2068   CYCLES(5);
2069}
2070
2071/* LDD IND, Y       0x18, 0xEC */
2072void HC11OP(ldd_indy)()
2073{
2074   UINT8 offset = FETCH();
2075   CLEAR_NZV();
2076   REG_D = READ16(m_iy + offset);
2077   SET_N16(REG_D);
2078   SET_Z16(REG_D);
2079   CYCLES(6);
2080}
2081
2082
2083/* LDS IMM          0x8E */
2084void HC11OP(lds_imm)()
2085{
2086   CLEAR_NZV();
2087   m_sp = FETCH16();
2088   SET_N16(m_sp);
2089   SET_Z16(m_sp);
2090   CYCLES(3);
2091}
2092
2093/* LDS DIR          0x9E */
2094void HC11OP(lds_dir)()
2095{
2096   UINT8 i = FETCH();
2097   CLEAR_NZV();
2098   m_sp = READ16(i);
2099   SET_N16(m_sp);
2100   SET_Z16(m_sp);
2101   CYCLES(4);
2102}
2103
2104/* LDS EXT          0xBE */
2105void HC11OP(lds_ext)()
2106{
2107   UINT16 adr = FETCH16();
2108   CLEAR_NZV();
2109   m_sp = READ16(adr);
2110   SET_N16(m_sp);
2111   SET_Z16(m_sp);
2112   CYCLES(5);
2113}
2114
2115/* LDS IND, X       0xAE */
2116void HC11OP(lds_indx)()
2117{
2118   UINT8 offset = FETCH();
2119   CLEAR_NZV();
2120   m_sp = READ16(m_ix + offset);
2121   SET_N16(m_sp);
2122   SET_Z16(m_sp);
2123   CYCLES(5);
2124}
2125
2126/* LDS IND, Y       0x18, 0xAE */
2127void HC11OP(lds_indy)()
2128{
2129   UINT8 offset = FETCH();
2130   CLEAR_NZV();
2131   m_sp = READ16(m_iy + offset);
2132   SET_N16(m_sp);
2133   SET_Z16(m_sp);
2134   CYCLES(6);
2135}
2136
2137
2138/* LDX IMM          0xCE */
2139void HC11OP(ldx_imm)()
2140{
2141   CLEAR_NZV();
2142   m_ix = FETCH16();
2143   SET_N16(m_ix);
2144   SET_Z16(m_ix);
2145   CYCLES(3);
2146}
2147
2148/* LDX DIR          0xDE */
2149void HC11OP(ldx_dir)()
2150{
2151   UINT8 d = FETCH();
2152   CLEAR_NZV();
2153   m_ix = READ16(d);
2154   SET_N16(m_ix);
2155   SET_Z16(m_ix);
2156   CYCLES(4);
2157}
2158
2159/* LDX EXT          0xFE */
2160void HC11OP(ldx_ext)()
2161{
2162   UINT16 adr = FETCH16();
2163   CLEAR_NZV();
2164   m_ix = READ16(adr);
2165   SET_N16(m_ix);
2166   SET_Z16(m_ix);
2167   CYCLES(5);
2168}
2169
2170/* LDX IND, X       0xEE */
2171void HC11OP(ldx_indx)()
2172{
2173   UINT8 offset = FETCH();
2174   CLEAR_NZV();
2175   m_ix = READ16(m_ix + offset);
2176   SET_N16(m_ix);
2177   SET_Z16(m_ix);
2178   CYCLES(5);
2179}
2180
2181/* LDX IND, Y       0xCD, 0xEE */
2182void HC11OP(ldx_indy)()
2183{
2184   UINT8 offset = FETCH();
2185   CLEAR_NZV();
2186   m_ix = READ16(m_iy + offset);
2187   SET_N16(m_ix);
2188   SET_Z16(m_ix);
2189   CYCLES(6);
2190}
2191
2192
2193/* LDY IMM          0x18, 0xCE */
2194void HC11OP(ldy_imm)()
2195{
2196   CLEAR_NZV();
2197   m_iy = FETCH16();
2198   SET_N16(m_iy);
2199   SET_Z16(m_iy);
2200   CYCLES(4);
2201}
2202
2203/* LDY DIR          0x18, 0xDE */
2204void HC11OP(ldy_dir)()
2205{
2206   UINT8 d = FETCH();
2207   CLEAR_NZV();
2208   m_iy = READ16(d);
2209   SET_N16(m_iy);
2210   SET_Z16(m_iy);
2211   CYCLES(5);
2212}
2213
2214/* LDY EXT          0x18, 0xFE */
2215void HC11OP(ldy_ext)()
2216{
2217   UINT16 adr = FETCH16();
2218   CLEAR_NZV();
2219   m_iy = READ16(adr);
2220   SET_N16(m_iy);
2221   SET_Z16(m_iy);
2222   CYCLES(6);
2223}
2224
2225/* LDY IND, X       0x1A, 0xEE */
2226void HC11OP(ldy_indx)()
2227{
2228   UINT8 offset = FETCH();
2229   CLEAR_NZV();
2230   m_iy = READ16(m_ix + offset);
2231   SET_N16(m_iy);
2232   SET_Z16(m_iy);
2233   CYCLES(6);
2234}
2235
2236/* LDY IND, Y       0x18, 0xEE */
2237void HC11OP(ldy_indy)()
2238{
2239   UINT8 offset = FETCH();
2240   CLEAR_NZV();
2241   m_iy = READ16(m_iy + offset);
2242   SET_N16(m_iy);
2243   SET_Z16(m_iy);
2244   CYCLES(6);
2245}
2246
2247/* LSLD             0x05 */
2248void HC11OP(lsld)()
2249{
2250   UINT32 r = REG_D << 1;
2251   CLEAR_NZVC();
2252   SET_C16(r);
2253   REG_D = (UINT16)(r);
2254   SET_N16(REG_D);
2255   SET_Z16(REG_D);
2256
2257   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2258      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2259   {
2260      m_ccr |= CC_V;
2261   }
2262
2263   CYCLES(3);
2264}
2265
2266/* LSRA              0x44 */
2267void HC11OP(lsra)()
2268{
2269   UINT16 r = REG_A >> 1;
2270   CLEAR_NZVC();
2271   m_ccr |= (REG_A & 1) ? CC_C : 0;
2272   REG_A = (UINT8)(r);
2273   m_ccr |= ((m_ccr & CC_C)) ? CC_V : 0;
2274   SET_Z8(REG_A);
2275
2276   CYCLES(2);
2277}
2278
2279/* LSRB              0x54 */
2280void HC11OP(lsrb)()
2281{
2282   UINT16 r = REG_B >> 1;
2283   CLEAR_NZVC();
2284   m_ccr |= (REG_B & 1) ? CC_C : 0;
2285   REG_B = (UINT8)(r);
2286   m_ccr |= ((m_ccr & CC_C)) ? CC_V : 0;
2287   SET_Z8(REG_B);
2288
2289   CYCLES(2);
2290}
2291
2292/* LSRD             0x04 */
2293void HC11OP(lsrd)()
2294{
2295   UINT32 r = REG_D >> 1;
2296   CLEAR_NZVC();
2297   m_ccr |= (REG_D & 1) ? CC_C : 0;
2298   REG_D = (UINT16)(r);
2299   m_ccr |= ((m_ccr & CC_C)) ? CC_V : 0;
2300
2301   SET_N16(REG_D);
2302   SET_Z16(REG_D);
2303
2304   CYCLES(3);
2305}
2306
2307/* MUL              0x3d */
2308void HC11OP(mul)()
2309{
2310   REG_D = REG_A * REG_B;
2311   CLEAR_C();
2312   m_ccr |= (REG_B & 0x80) ? CC_C : 0;
2313   CYCLES(10);
2314}
2315
2316/* NEGA              0x40 */
2317void HC11OP(nega)()
2318{
2319   REG_A = 0x00 - REG_A;
2320   CLEAR_NZVC();
2321   SET_N8(REG_A);
2322   SET_Z8(REG_A);
2323   m_ccr |= (REG_A == 0x80) ? CC_V : 0;
2324   m_ccr |= (REG_A != 0x00) ? CC_C : 0;
2325   CYCLES(2);
2326}
2327
2328/* NEGB              0x50 */
2329void HC11OP(negb)()
2330{
2331   REG_B = 0x00 - REG_B;
2332   CLEAR_NZVC();
2333   SET_N8(REG_B);
2334   SET_Z8(REG_B);
2335   m_ccr |= (REG_B == 0x80) ? CC_V : 0;
2336   m_ccr |= (REG_B != 0x00) ? CC_C : 0;
2337   CYCLES(2);
2338}
2339
2340
2341/* NEG EXT           0x70 */
2342void HC11OP(neg_ext)()
2343{
2344   UINT16 adr = FETCH16();
2345   UINT8 i = 0x00 - READ8(adr);
2346   CLEAR_NZVC();
2347   SET_N8(i);
2348   SET_Z8(i);
2349   m_ccr |= (i == 0x80) ? CC_V : 0;
2350   m_ccr |= (i != 0x00) ? CC_C : 0;
2351   WRITE8(adr, i);
2352   CYCLES(6);
2353}
2354
2355
2356/* NEG INDX           0x60 */
2357void HC11OP(neg_indx)()
2358{
2359   UINT16 offset = FETCH();
2360   UINT8 i = 0x00 - READ8(m_ix + offset);
2361   CLEAR_NZVC();
2362   SET_N8(i);
2363   SET_Z8(i);
2364   m_ccr |= (i == 0x80) ? CC_V : 0;
2365   m_ccr |= (i != 0x00) ? CC_C : 0;
2366   WRITE8(m_ix + offset, i);
2367   CYCLES(6);
2368}
2369
2370
2371/* NEG INDY           0x18 0x60 */
2372void HC11OP(neg_indy)()
2373{
2374   UINT16 offset = FETCH();
2375   UINT8 i = 0x00 - READ8(m_iy + offset);
2376   CLEAR_NZVC();
2377   SET_N8(i);
2378   SET_Z8(i);
2379   m_ccr |= (i == 0x80) ? CC_V : 0;
2380   m_ccr |= (i != 0x00) ? CC_C : 0;
2381   WRITE8(m_iy + offset, i);
2382   CYCLES(7);
2383}
2384
2385
2386/* NOP              0x01 */
2387void HC11OP(nop)()
2388{
2389   CYCLES(2);
2390}
2391
2392/* PSHA             0x36 */
2393void HC11OP(psha)()
2394{
2395   PUSH8(REG_A);
2396   CYCLES(3);
2397}
2398
2399/* ORAA IMM         0x8A */
2400void HC11OP(oraa_imm)()
2401{
2402   UINT8 i = FETCH();
2403   CLEAR_NZV();
2404   REG_A |= i;
2405   SET_N8(REG_A);
2406   SET_Z8(REG_A);
2407   CYCLES(2);
2408}
2409
2410/* ORAA DIR         0x9A */
2411void HC11OP(oraa_dir)()
2412{
2413   UINT8 d = FETCH();
2414   UINT8 i = READ8(d);
2415   CLEAR_NZV();
2416   REG_A |= i;
2417   SET_N8(REG_A);
2418   SET_Z8(REG_A);
2419   CYCLES(3);
2420}
2421
2422/* ORAA EXT         0xBA */
2423void HC11OP(oraa_ext)()
2424{
2425   UINT16 adr = FETCH16();
2426   UINT8 i = READ8(adr);
2427   CLEAR_NZV();
2428   REG_A |= i;
2429   SET_N8(REG_A);
2430   SET_Z8(REG_A);
2431   CYCLES(4);
2432}
2433
2434/* ORAA IND, X      0xAA */
2435void HC11OP(oraa_indx)()
2436{
2437   UINT8 offset = FETCH();
2438   UINT8 i = READ8(m_ix + offset);
2439   CLEAR_NZV();
2440   REG_A |= i;
2441   SET_N8(REG_A);
2442   SET_Z8(REG_A);
2443   CYCLES(4);
2444}
2445
2446/* ORAA IND, Y      0x18, 0xAA */
2447void HC11OP(oraa_indy)()
2448{
2449   UINT8 offset = FETCH();
2450   UINT8 i = READ8(m_iy + offset);
2451   CLEAR_NZV();
2452   REG_A |= i;
2453   SET_N8(REG_A);
2454   SET_Z8(REG_A);
2455   CYCLES(5);
2456}
2457
2458
2459/* ORAB IMM         0xCA */
2460void HC11OP(orab_imm)()
2461{
2462   UINT8 i = FETCH();
2463   CLEAR_NZV();
2464   REG_B |= i;
2465   SET_N8(REG_B);
2466   SET_Z8(REG_B);
2467   CYCLES(2);
2468}
2469
2470/* ORAB DIR         0xDA */
2471void HC11OP(orab_dir)()
2472{
2473   UINT8 d = FETCH();
2474   UINT8 i = READ8(d);
2475   CLEAR_NZV();
2476   REG_B |= i;
2477   SET_N8(REG_B);
2478   SET_Z8(REG_B);
2479   CYCLES(3);
2480}
2481
2482/* ORAB EXT         0xFA */
2483void HC11OP(orab_ext)()
2484{
2485   UINT16 adr = FETCH16();
2486   UINT8 i = READ8(adr);
2487   CLEAR_NZV();
2488   REG_B |= i;
2489   SET_N8(REG_B);
2490   SET_Z8(REG_B);
2491   CYCLES(4);
2492}
2493
2494/* ORAB IND, X      0xEA */
2495void HC11OP(orab_indx)()
2496{
2497   UINT8 offset = FETCH();
2498   UINT8 i = READ8(m_ix + offset);
2499   CLEAR_NZV();
2500   REG_B |= i;
2501   SET_N8(REG_B);
2502   SET_Z8(REG_B);
2503   CYCLES(4);
2504}
2505
2506/* ORAB IND, Y      0x18, 0xEA */
2507void HC11OP(orab_indy)()
2508{
2509   UINT8 offset = FETCH();
2510   UINT8 i = READ8(m_iy + offset);
2511   CLEAR_NZV();
2512   REG_B |= i;
2513   SET_N8(REG_B);
2514   SET_Z8(REG_B);
2515   CYCLES(5);
2516}
2517
2518
2519/* PSHB             0x37 */
2520void HC11OP(pshb)()
2521{
2522   PUSH8(REG_B);
2523   CYCLES(3);
2524}
2525
2526
2527/* PSHX             0x3C */
2528void HC11OP(pshx)()
2529{
2530   PUSH16(m_ix);
2531   CYCLES(4);
2532}
2533
2534
2535/* PSHY             0x18, 0x3C */
2536void HC11OP(pshy)()
2537{
2538   PUSH16(m_iy);
2539   CYCLES(5);
2540}
2541
2542
2543/* PULA             0x32 */
2544void HC11OP(pula)()
2545{
2546   REG_A = POP8();
2547   CYCLES(4);
2548}
2549
2550
2551/* PULB             0x33 */
2552void HC11OP(pulb)()
2553{
2554   REG_B = POP8();
2555   CYCLES(4);
2556}
2557
2558
2559/* PULX             0x38 */
2560void HC11OP(pulx)()
2561{
2562   m_ix = POP16();
2563   CYCLES(5);
2564}
2565
2566
2567/* PULY             0x18, 0x38 */
2568void HC11OP(puly)()
2569{
2570   m_iy = POP16();
2571   CYCLES(6);
2572}
2573
2574/* ROLA             0x49 */
2575void HC11OP(rola)()
2576{
2577   UINT16 r = ((REG_A & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2578   CLEAR_NZVC();
2579   m_ccr |= (REG_A & 0x80) ? CC_C : 0;
2580   REG_A = (UINT8)(r);
2581   SET_N8(REG_A);
2582   SET_Z8(REG_A);
2583
2584   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2585      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2586   {
2587      m_ccr |= CC_V;
2588   }
2589
2590   CYCLES(2);
2591}
2592
2593/* ROLB             0x59 */
2594void HC11OP(rolb)()
2595{
2596   UINT16 r = ((REG_B & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2597   CLEAR_NZVC();
2598   m_ccr |= (REG_B & 0x80) ? CC_C : 0;
2599   REG_B = (UINT8)(r);
2600   SET_N8(REG_B);
2601   SET_Z8(REG_B);
2602
2603   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2604      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2605   {
2606      m_ccr |= CC_V;
2607   }
2608
2609   CYCLES(2);
2610}
2611
2612/* ROL EXT           0x79 */
2613void HC11OP(rol_ext)()
2614{
2615   UINT16 adr = FETCH16();
2616   UINT8 r = READ8(adr);
2617   UINT8 c = (r & 0x80);
2618   r = ((r & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2619   CLEAR_NZVC();
2620   m_ccr |= (c & 0x80) ? CC_C : 0;
2621   SET_N8(r);
2622   SET_Z8(r);
2623   WRITE8(adr, r);
2624
2625   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2626      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2627   {
2628      m_ccr |= CC_V;
2629   }
2630
2631   CYCLES(6);
2632}
2633
2634/* ROL INDX           0x69 */
2635void HC11OP(rol_indx)()
2636{
2637   UINT8 offset = FETCH();
2638   UINT8 i = READ8(m_ix + offset);
2639   UINT8 c = (i & 0x80);
2640   i = ((i & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2641   CLEAR_NZVC();
2642   m_ccr |= (c & 0x80) ? CC_C : 0;
2643   SET_N8(i);
2644   SET_Z8(i);
2645   WRITE8(m_ix + offset, i);
2646
2647   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2648      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2649   {
2650      m_ccr |= CC_V;
2651   }
2652
2653   CYCLES(6);
2654}
2655
2656/* ROL INDY           0x18 0x69 */
2657void HC11OP(rol_indy)()
2658{
2659   UINT8 offset = FETCH();
2660   UINT8 i = READ8(m_iy + offset);
2661   UINT8 c = (i & 0x80);
2662   i = ((i & 0x7f) << 1) | ((m_ccr & CC_C) ? 1 : 0);
2663   CLEAR_NZVC();
2664   m_ccr |= (c & 0x80) ? CC_C : 0;
2665   SET_N8(i);
2666   SET_Z8(i);
2667   WRITE8(m_iy + offset, i);
2668
2669   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2670      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2671   {
2672      m_ccr |= CC_V;
2673   }
2674
2675   CYCLES(6);
2676}
2677
2678
2679/* RORA             0x46 */
2680void HC11OP(rora)()
2681{
2682   UINT16 r = ((REG_A & 0xfe) >> 1) | ((m_ccr & CC_C) ? 0x80 : 0);
2683   CLEAR_NZVC();
2684   m_ccr |= (REG_A & 1) ? CC_C : 0;
2685   REG_A = (UINT8)(r);
2686   SET_N8(REG_A);
2687   SET_Z8(REG_A);
2688
2689   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2690      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2691   {
2692      m_ccr |= CC_V;
2693   }
2694
2695   CYCLES(2);
2696}
2697
2698/* RORB             0x56 */
2699void HC11OP(rorb)()
2700{
2701   UINT16 r = ((REG_B & 0xfe) >> 1) | ((m_ccr & CC_C) ? 0x80 : 0);
2702   CLEAR_NZVC();
2703   m_ccr |= (REG_B & 1) ? CC_C : 0;
2704   REG_B = (UINT8)(r);
2705   SET_N8(REG_B);
2706   SET_Z8(REG_B);
2707
2708   if (((m_ccr & CC_N) && (m_ccr & CC_C) == 0) ||
2709      ((m_ccr & CC_N) == 0 && (m_ccr & CC_C)))
2710   {
2711      m_ccr |= CC_V;
2712   }
2713
2714   CYCLES(2);
2715}
2716
2717/* RTI              0x3B */
2718void HC11OP(rti)()
2719{
2720   UINT16 rt_adr;
2721   UINT8 x_flag = m_ccr & CC_X;
2722   m_ccr = POP8();
2723   if(x_flag == 0 && m_ccr & CC_X) //X flag cannot do a 0->1 transition with this instruction.
2724      m_ccr &= ~CC_X;
2725   REG_B = POP8();
2726   REG_A = POP8();
2727   m_ix = POP16();
2728   m_iy = POP16();
2729   rt_adr = POP16();
2730   SET_PC(rt_adr);
2731   CYCLES(12);
2732}
2733
2734/* RTS              0x39 */
2735void HC11OP(rts)()
2736{
2737   UINT16 rt_adr = POP16();
2738   SET_PC(rt_adr);
2739   CYCLES(5);
2740}
2741
2742
2743/* SBA              0x10 */
2744void HC11OP(sba)()
2745{
2746   UINT16 r = REG_A - REG_B;
2747   CLEAR_NZVC();
2748   SET_N8(r);
2749   SET_Z8(r);
2750   SET_V_SUB8(r, REG_B, REG_A);
2751   SET_C8(r);
2752   REG_A = (UINT8)r;
2753   CYCLES(2);
2754}
2755
2756
2757/* SBCA IMM         0x82 */
2758void HC11OP(sbca_imm)()
2759{
2760   UINT8 i = FETCH();
2761   UINT16 r = (REG_A - i) - ((m_ccr & CC_C) ? 1 : 0);
2762   CLEAR_NZVC();
2763   SET_N8(r);
2764   SET_Z8(r);
2765   SET_V_SUB8(r, i, REG_A);
2766   SET_C8(r);
2767   REG_A = (UINT8)r;
2768   CYCLES(2);
2769}
2770
2771/* SBCA IND, X      0xA2 */
2772void HC11OP(sbca_indx)()
2773{
2774   UINT8 offset = FETCH();
2775   UINT8 i = READ8(m_ix + offset);
2776   UINT16 r = (REG_A - i) - ((m_ccr & CC_C) ? 1 : 0);
2777   CLEAR_NZVC();
2778   SET_N8(r);
2779   SET_Z8(r);
2780   SET_V_SUB8(r, i, REG_A);
2781   SET_C8(r);
2782   REG_A = (UINT8)r;
2783   CYCLES(4);
2784}
2785
2786/* SBCA IND, Y      0x18, 0xA2 */
2787void HC11OP(sbca_indy)()
2788{
2789   UINT8 offset = FETCH();
2790   UINT8 i = READ8(m_iy + offset);
2791   UINT16 r = (REG_A - i) - ((m_ccr & CC_C) ? 1 : 0);
2792   CLEAR_NZVC();
2793   SET_N8(r);
2794   SET_Z8(r);
2795   SET_V_SUB8(r, i, REG_A);
2796   SET_C8(r);
2797   REG_A = (UINT8)r;
2798   CYCLES(5);
2799}
2800
2801/* SBCB IMM         0xC2 */
2802void HC11OP(sbcb_imm)()
2803{
2804   UINT8 i = FETCH();
2805   UINT16 r = (REG_B - i) - ((m_ccr & CC_C) ? 1 : 0);
2806   CLEAR_NZVC();
2807   SET_N8(r);
2808   SET_Z8(r);
2809   SET_V_SUB8(r, i, REG_B);
2810   SET_C8(r);
2811   REG_B = (UINT8)r;
2812   CYCLES(2);
2813}
2814
2815/* SBCB IND, X      0xE2 */
2816void HC11OP(sbcb_indx)()
2817{
2818   UINT8 offset = FETCH();
2819   UINT8 i = READ8(m_ix + offset);
2820   UINT16 r = (REG_B - i) - ((m_ccr & CC_C) ? 1 : 0);
2821   CLEAR_NZVC();
2822   SET_N8(r);
2823   SET_Z8(r);
2824   SET_V_SUB8(r, i, REG_B);
2825   SET_C8(r);
2826   REG_B = (UINT8)r;
2827   CYCLES(4);
2828}
2829
2830/* SBCB IND, Y      0x18, 0xE2 */
2831void HC11OP(sbcb_indy)()
2832{
2833   UINT8 offset = FETCH();
2834   UINT8 i = READ8(m_iy + offset);
2835   UINT16 r = (REG_B - i) - ((m_ccr & CC_C) ? 1 : 0);
2836   CLEAR_NZVC();
2837   SET_N8(r);
2838   SET_Z8(r);
2839   SET_V_SUB8(r, i, REG_B);
2840   SET_C8(r);
2841   REG_B = (UINT8)r;
2842   CYCLES(5);
2843}
2844
2845/* SEC              0x0D */
2846void HC11OP(sec)()
2847{
2848   m_ccr |= CC_C;
2849   CYCLES(2);
2850}
2851
2852/* SEI              0x0F */
2853void HC11OP(sei)()
2854{
2855   m_ccr |= CC_I;
2856   CYCLES(2);
2857}
2858
2859/* SEV              0x0B */
2860void HC11OP(sev)()
2861{
2862   m_ccr |= CC_V;
2863   CYCLES(2);
2864}
2865
2866/* STAA DIR         0x97 */
2867void HC11OP(staa_dir)()
2868{
2869   UINT8 d = FETCH();
2870   CLEAR_NZV();
2871   SET_N8(REG_A);
2872   SET_Z8(REG_A);
2873   WRITE8(d, REG_A);
2874   CYCLES(3);
2875}
2876
2877/* STAA EXT         0xB7 */
2878void HC11OP(staa_ext)()
2879{
2880   UINT16 adr = FETCH16();
2881   CLEAR_NZV();
2882   SET_N8(REG_A);
2883   SET_Z8(REG_A);
2884   WRITE8(adr, REG_A);
2885   CYCLES(4);
2886}
2887
2888/* STAA IND, X      0xA7 */
2889void HC11OP(staa_indx)()
2890{
2891   UINT8 offset = FETCH();
2892   CLEAR_NZV();
2893   SET_N8(REG_A);
2894   SET_Z8(REG_A);
2895   WRITE8(m_ix + offset, REG_A);
2896   CYCLES(4);
2897}
2898
2899/* STAA IND, Y      0x18, 0xA7 */
2900void HC11OP(staa_indy)()
2901{
2902   UINT8 offset = FETCH();
2903   CLEAR_NZV();
2904   SET_N8(REG_A);
2905   SET_Z8(REG_A);
2906   WRITE8(m_iy + offset, REG_A);
2907   CYCLES(5);
2908}
2909
2910/* STAB DIR         0xD7 */
2911void HC11OP(stab_dir)()
2912{
2913   UINT8 d = FETCH();
2914   CLEAR_NZV();
2915   SET_N8(REG_B);
2916   SET_Z8(REG_B);
2917   WRITE8(d, REG_B);
2918   CYCLES(3);
2919}
2920
2921/* STAB EXT         0xF7 */
2922void HC11OP(stab_ext)()
2923{
2924   UINT16 adr = FETCH16();
2925   CLEAR_NZV();
2926   SET_N8(REG_B);
2927   SET_Z8(REG_B);
2928   WRITE8(adr, REG_B);
2929   CYCLES(4);
2930}
2931
2932/* STAB IND, X      0xE7 */
2933void HC11OP(stab_indx)()
2934{
2935   UINT8 offset = FETCH();
2936   CLEAR_NZV();
2937   SET_N8(REG_B);
2938   SET_Z8(REG_B);
2939   WRITE8(m_ix + offset, REG_B);
2940   CYCLES(4);
2941}
2942
2943/* STAB IND, Y      0x18, 0xE7 */
2944void HC11OP(stab_indy)()
2945{
2946   UINT8 offset = FETCH();
2947   CLEAR_NZV();
2948   SET_N8(REG_B);
2949   SET_Z8(REG_B);
2950   WRITE8(m_iy + offset, REG_B);
2951   CYCLES(5);
2952}
2953
2954
2955/* STD DIR          0xDD */
2956void HC11OP(std_dir)()
2957{
2958   UINT8 d = FETCH();
2959   CLEAR_NZV();
2960   WRITE16(d, REG_D);
2961   SET_N16(REG_D);
2962   SET_Z16(REG_D);
2963   CYCLES(4);
2964}
2965
2966/* STD EXT          0xFD */
2967void HC11OP(std_ext)()
2968{
2969   UINT16 adr = FETCH16();
2970   CLEAR_NZV();
2971   WRITE16(adr, REG_D);
2972   SET_N16(REG_D);
2973   SET_Z16(REG_D);
2974   CYCLES(5);
2975}
2976
2977/* STD IND, X       0xED */
2978void HC11OP(std_indx)()
2979{
2980   UINT8 offset = FETCH();
2981   CLEAR_NZV();
2982   WRITE16(m_ix + offset, REG_D);
2983   SET_N16(REG_D);
2984   SET_Z16(REG_D);
2985   CYCLES(5);
2986}
2987
2988/* STD IND, Y       0x18, 0xED */
2989void HC11OP(std_indy)()
2990{
2991   UINT8 offset = FETCH();
2992   CLEAR_NZV();
2993   WRITE16(m_iy + offset, REG_D);
2994   SET_N16(REG_D);
2995   SET_Z16(REG_D);
2996   CYCLES(6);
2997}
2998
2999/* STS DIR          0x9F */
3000void HC11OP(sts_dir)()
3001{
3002   UINT8 d = FETCH();
3003   UINT16 r = m_sp;
3004   CLEAR_NZV();
3005   WRITE8(d, (r & 0xff00) >> 8);
3006   WRITE8(d + 1, (r & 0xff));
3007   SET_N16(r);
3008   SET_Z16(r);
3009   CYCLES(4);
3010}
3011
3012
3013/* STX DIR          0xDF */
3014void HC11OP(stx_dir)()
3015{
3016   UINT8 adr = FETCH();
3017   UINT16 r = m_ix;
3018   CLEAR_NZV();
3019   WRITE8(adr, (r & 0xff00) >> 8);
3020   WRITE8(adr + 1, (r & 0xff));
3021   SET_N16(r);
3022   SET_Z16(r);
3023   CYCLES(4);
3024}
3025
3026/* STX EXT          0xFF */
3027void HC11OP(stx_ext)()
3028{
3029   UINT16 adr = FETCH16();
3030   UINT16 r = m_ix;
3031   CLEAR_NZV();
3032   WRITE8(adr, (r & 0xff00) >> 8);
3033   WRITE8(adr + 1, (r & 0xff));
3034   SET_N16(r);
3035   SET_Z16(r);
3036   CYCLES(5);
3037}
3038
3039
3040/* STX INDX         0xEF */
3041void HC11OP(stx_indx)()
3042{
3043   UINT16 adr = FETCH();
3044   UINT16 r = m_ix;
3045   CLEAR_NZV();
3046   WRITE8(m_ix + adr, (r & 0xff00) >> 8);
3047   WRITE8(m_ix + adr + 1, (r & 0xff));
3048   SET_N16(r);
3049   SET_Z16(r);
3050   CYCLES(5);
3051}
3052
3053
3054/* STX INDY         0xCD 0xEF */
3055void HC11OP(stx_indy)()
3056{
3057   UINT16 adr = FETCH();
3058   UINT16 r = m_ix;
3059   CLEAR_NZV();
3060   WRITE8(m_iy + adr, (r & 0xff00) >> 8);
3061   WRITE8(m_iy + adr + 1, (r & 0xff));
3062   SET_N16(r);
3063   SET_Z16(r);
3064   CYCLES(6);
3065}
3066
3067/* STY DIR          0x18 0xDF */
3068void HC11OP(sty_dir)()
3069{
3070   UINT8 adr = FETCH();
3071   UINT16 r = m_iy;
3072   CLEAR_NZV();
3073   WRITE8(adr, (r & 0xff00) >> 8);
3074   WRITE8(adr + 1, (r & 0xff));
3075   SET_N16(r);
3076   SET_Z16(r);
3077   CYCLES(5);
3078}
3079
3080
3081/* STY EXT          0x18 0xFF */
3082void HC11OP(sty_ext)()
3083{
3084   UINT16 adr = FETCH16();
3085   UINT16 r = m_iy;
3086   CLEAR_NZV();
3087   WRITE8(adr, (r & 0xff00) >> 8);
3088   WRITE8(adr + 1, (r & 0xff));
3089   SET_N16(r);
3090   SET_Z16(r);
3091   CYCLES(6);
3092}
3093
3094/* STY INDX         0x1A 0xEF */
3095void HC11OP(sty_indx)()
3096{
3097   UINT16 adr = FETCH();
3098   UINT16 r = m_iy;
3099   CLEAR_NZV();
3100   WRITE8(m_ix + adr, (r & 0xff00) >> 8);
3101   WRITE8(m_ix + adr + 1, (r & 0xff));
3102   SET_N16(r);
3103   SET_Z16(r);
3104   CYCLES(6);
3105}
3106
3107/* STY INDY         0x18 0xEF */
3108void HC11OP(sty_indy)()
3109{
3110   UINT16 adr = FETCH();
3111   UINT16 r = m_iy;
3112   CLEAR_NZV();
3113   WRITE8(m_iy + adr, (r & 0xff00) >> 8);
3114   WRITE8(m_iy + adr + 1, (r & 0xff));
3115   SET_N16(r);
3116   SET_Z16(r);
3117   CYCLES(6);
3118}
3119
3120/* STOP              0xCF */
3121void HC11OP(stop)()
3122{
3123   if(m_stop_state == 0 && ((m_ccr & CC_S) == 0))
3124   {
3125      m_stop_state = 1;
3126   }
3127
3128   if(m_stop_state == 1)
3129   {
3130      SET_PC(m_ppc); // wait for an exception
3131   }
3132
3133   if(m_stop_state == 2)
3134   {
3135      m_stop_state = 0;
3136   }
3137
3138   CYCLES(2);
3139}
3140
3141
3142/* SUBA IMM         0x80 */
3143void HC11OP(suba_imm)()
3144{
3145   UINT8 i = FETCH();
3146   UINT16 r = REG_A - i;
3147   CLEAR_NZVC();
3148   SET_N8(r);
3149   SET_Z8(r);
3150   SET_V_SUB8(r, i, REG_A);
3151   SET_C8(r);
3152   REG_A = (UINT8)r;
3153   CYCLES(2);
3154}
3155
3156
3157/* SUBA DIR         0xd0 */
3158void HC11OP(suba_dir)()
3159{
3160   UINT8 d = FETCH();
3161   UINT8 i = READ8(d);
3162   UINT16 r = REG_A - i;
3163   CLEAR_NZVC();
3164   SET_N8(r);
3165   SET_Z8(r);
3166   SET_V_SUB8(r, i, REG_A);
3167   SET_C8(r);
3168   REG_A = (UINT8)r;
3169   CYCLES(3);
3170}
3171
3172
3173/* SUBA EXT         0xE0 */
3174void HC11OP(suba_ext)()
3175{
3176   UINT16 adr = FETCH16();
3177   UINT8 i = READ8(adr);
3178   UINT16 r = REG_A - i;
3179   CLEAR_NZVC();
3180   SET_N8(r);
3181   SET_Z8(r);
3182   SET_V_SUB8(r, i, REG_A);
3183   SET_C8(r);
3184   REG_A = (UINT8)r;
3185   CYCLES(4);
3186}
3187
3188
3189/* SUBA INDX        0xA0 */
3190void HC11OP(suba_indx)()
3191{
3192   UINT16 adr = FETCH();
3193   UINT8 i = READ8(m_ix + adr);
3194   UINT16 r = REG_A - i;
3195   CLEAR_NZVC();
3196   SET_N8(r);
3197   SET_Z8(r);
3198   SET_V_SUB8(r, i, REG_A);
3199   SET_C8(r);
3200   REG_A = (UINT8)r;
3201   CYCLES(4);
3202}
3203
3204
3205/* SUBA INDY        0x18 0xA0 */
3206void HC11OP(suba_indy)()
3207{
3208   UINT16 adr = FETCH();
3209   UINT8 i = READ8(m_iy + adr);
3210   UINT16 r = REG_A - i;
3211   CLEAR_NZVC();
3212   SET_N8(r);
3213   SET_Z8(r);
3214   SET_V_SUB8(r, i, REG_A);
3215   SET_C8(r);
3216   REG_A = (UINT8)r;
3217   CYCLES(5);
3218}
3219
3220
3221/* SUBB IMM         0xC0 */
3222void HC11OP(subb_imm)()
3223{
3224   UINT8 i = FETCH();
3225   UINT16 r = REG_B - i;
3226   CLEAR_NZVC();
3227   SET_N8(r);
3228   SET_Z8(r);
3229   SET_V_SUB8(r, i, REG_B);
3230   SET_C8(r);
3231   REG_B = (UINT8)r;
3232   CYCLES(2);
3233}
3234
3235
3236/* SUBB DIR         0xD0 */
3237void HC11OP(subb_dir)()
3238{
3239   UINT8 d = FETCH();
3240   UINT8 i = READ8(d);
3241   UINT16 r = REG_B - i;
3242   CLEAR_NZVC();
3243   SET_N8(r);
3244   SET_Z8(r);
3245   SET_V_SUB8(r, i, REG_B);
3246   SET_C8(r);
3247   REG_B = (UINT8)r;
3248   CYCLES(3);
3249}
3250
3251
3252/* SUBB EXT         0xF0 */
3253void HC11OP(subb_ext)()
3254{
3255   UINT16 adr = FETCH16();
3256   UINT8 i = READ8(adr);
3257   UINT16 r = REG_B - i;
3258   CLEAR_NZVC();
3259   SET_N8(r);
3260   SET_Z8(r);
3261   SET_V_SUB8(r, i, REG_B);
3262   SET_C8(r);
3263   REG_B = (UINT8)r;
3264   CYCLES(4);
3265}
3266
3267
3268/* SUBB INDX        0xE0 */
3269void HC11OP(subb_indx)()
3270{
3271   UINT16 adr = FETCH();
3272   UINT8 i = READ8(m_ix + adr);
3273   UINT16 r = REG_B - i;
3274   CLEAR_NZVC();
3275   SET_N8(r);
3276   SET_Z8(r);
3277   SET_V_SUB8(r, i, REG_B);
3278   SET_C8(r);
3279   REG_B = (UINT8)r;
3280   CYCLES(4);
3281}
3282
3283/* SUBB INDY        0x18 0xE0 */
3284void HC11OP(subb_indy)()
3285{
3286   UINT16 adr = FETCH();
3287   UINT8 i = READ8(m_iy + adr);
3288   UINT16 r = REG_B - i;
3289   CLEAR_NZVC();
3290   SET_N8(r);
3291   SET_Z8(r);
3292   SET_V_SUB8(r, i, REG_B);
3293   SET_C8(r);
3294   REG_B = (UINT8)r;
3295   CYCLES(5);
3296}
3297
3298/* SUBD IMM         0x83 */
3299void HC11OP(subd_imm)()
3300{
3301   UINT16 i = FETCH16();
3302   UINT32 r = REG_D - i;
3303   CLEAR_NZVC();
3304   SET_N16(r);
3305   SET_Z16(r);
3306   SET_V_SUB16(r, i, REG_D);
3307   SET_C16(r);
3308   REG_D = (UINT16)r;
3309   CYCLES(4);
3310}
3311
3312/* SUBD DIR        0x93 */
3313void HC11OP(subd_dir)()
3314{
3315   UINT8 d = FETCH();
3316   UINT16 i = READ16(d);
3317   UINT32 r = REG_D - i;
3318   CLEAR_NZVC();
3319   SET_N16(r);
3320   SET_Z16(r);
3321   SET_V_SUB16(r, i, REG_D);
3322   SET_C16(r);
3323   REG_D = (UINT16)r;
3324   CYCLES(5);
3325}
3326
3327/* SUBD EXT        0xB3 */
3328void HC11OP(subd_ext)()
3329{
3330   UINT16 addr = FETCH16();
3331   UINT16 i = READ16(addr);
3332   UINT32 r = REG_D - i;
3333   CLEAR_NZVC();
3334   SET_N16(r);
3335   SET_Z16(r);
3336   SET_V_SUB16(r, i, REG_D);
3337   SET_C16(r);
3338   REG_D = (UINT16)r;
3339   CYCLES(6);
3340}
3341
3342/* SUBD INDX        0xA3 */
3343void HC11OP(subd_indx)()
3344{
3345   UINT8 offset = FETCH();
3346   UINT16 i = READ16(m_ix + offset);
3347   UINT32 r = REG_D - i;
3348   CLEAR_NZVC();
3349   SET_N16(r);
3350   SET_Z16(r);
3351   SET_V_SUB16(r, i, REG_D);
3352   SET_C16(r);
3353   REG_D = (UINT16)r;
3354   CYCLES(6);
3355}
3356
3357/* SUBD INDY        0x18 0xA3 */
3358void HC11OP(subd_indy)()
3359{
3360   UINT8 offset = FETCH();
3361   UINT16 i = READ16(m_iy + offset);
3362   UINT32 r = REG_D - i;
3363   CLEAR_NZVC();
3364   SET_N16(r);
3365   SET_Z16(r);
3366   SET_V_SUB16(r, i, REG_D);
3367   SET_C16(r);
3368   REG_D = (UINT16)r;
3369   CYCLES(7);
3370}
3371
3372/* SWI              0x3F */
3373void HC11OP(swi)()
3374{
3375   UINT16 pc_vector;
3376   //m_pc++;
3377   PUSH16(m_pc);
3378   PUSH16(m_iy);
3379   PUSH16(m_ix);
3380   PUSH8(REG_A);
3381   PUSH8(REG_B);
3382   PUSH8(m_ccr);
3383   pc_vector = READ16(0xfff6);
3384   SET_PC(pc_vector);
3385   m_ccr |= CC_I; //irq taken, mask the flag
3386   CYCLES(14);
3387}
3388
3389/* TAB              0x16 */
3390void HC11OP(tab)()
3391{
3392   CLEAR_NZV();
3393   REG_B = REG_A;
3394   SET_N8(REG_B);
3395   SET_Z8(REG_B);
3396   CYCLES(2);
3397}
3398
3399/* TAP              0x06 */
3400void HC11OP(tap)()
3401{
3402   UINT8 x_flag = m_ccr & CC_X;
3403   m_ccr = REG_A;
3404   if(x_flag == 0 && m_ccr & CC_X) //X flag cannot do a 0->1 transition with this instruction.
3405      m_ccr &= ~CC_X;
3406
3407   CYCLES(2);
3408}
3409
3410/* TBA              0x17 */
3411void HC11OP(tba)()
3412{
3413   CLEAR_NZV();
3414   REG_A = REG_B;
3415   SET_N8(REG_A);
3416   SET_Z8(REG_A);
3417   CYCLES(2);
3418}
3419
3420/* TEST              0x00 */
3421void HC11OP(test)()
3422{
3423//  if(m_test_mode)
3424      SET_PC(m_ppc); // Note: docs says "incremented" but the behaviour makes me think that's actually "decremented".
3425//  else
3426//  {
3427//      TODO: execute an illegal opcode exception here (NMI)
3428//  }
3429
3430   CYCLES(1);
3431}
3432
3433/* TPA              0x07 */
3434void HC11OP(tpa)()
3435{
3436   REG_A = m_ccr;
3437   CYCLES(2);
3438}
3439
3440
3441/* TSTA             0x4D */
3442void HC11OP(tsta)()
3443{
3444   CLEAR_NZVC();
3445   SET_N8(REG_A);
3446   SET_Z8(REG_A);
3447   CYCLES(2);
3448}
3449
3450/* TSTB             0x5D */
3451void HC11OP(tstb)()
3452{
3453   CLEAR_NZVC();
3454   SET_N8(REG_B);
3455   SET_Z8(REG_B);
3456   CYCLES(2);
3457}
3458
3459/* TST EXT          0x7D */
3460void HC11OP(tst_ext)()
3461{
3462   UINT16 adr = FETCH16();
3463   UINT8 i = READ8(adr);
3464   CLEAR_NZVC();
3465   SET_N8(i);
3466   SET_Z8(i);
3467   CYCLES(6);
3468}
3469
3470/* TST IND, X       0x6D */
3471void HC11OP(tst_indx)()
3472{
3473   UINT8 offset = FETCH();
3474   UINT8 i = READ8(m_ix + offset);
3475   CLEAR_NZVC();
3476   SET_N8(i);
3477   SET_Z8(i);
3478   CYCLES(6);
3479}
3480
3481/* TST IND, Y       0x18, 0x6D */
3482void HC11OP(tst_indy)()
3483{
3484   UINT8 offset = FETCH();
3485   UINT8 i = READ8(m_iy + offset);
3486   CLEAR_NZVC();
3487   SET_N8(i);
3488   SET_Z8(i);
3489   CYCLES(6);
3490}
3491
3492/* TSX              0x30 */
3493void HC11OP(tsx)()
3494{
3495   m_ix = m_sp + 1;
3496   CYCLES(3);
3497}
3498
3499/* TSY              0x18 0x30 */
3500void HC11OP(tsy)()
3501{
3502   m_iy = m_sp + 1;
3503   CYCLES(4);
3504}
3505
3506/* TXS              0x35 */
3507void HC11OP(txs)()
3508{
3509   m_sp = m_ix - 1;
3510   CYCLES(3);
3511}
3512
3513/* TYS              0x18 0x35 */
3514void HC11OP(tys)()
3515{
3516   m_sp = m_iy - 1;
3517   CYCLES(4);
3518}
3519
3520/* WAI              0x3E */
3521void HC11OP(wai)()
3522{
3523   if(m_wait_state == 0)
3524   {
3525      /* TODO: the following is bogus, pushes regs HERE in an instruction that wants an irq to go out? */
3526      PUSH16(m_pc);
3527      PUSH16(m_iy);
3528      PUSH16(m_ix);
3529      PUSH8(REG_A);
3530      PUSH8(REG_B);
3531      PUSH8(m_ccr);
3532      CYCLES(14);
3533      m_wait_state = 1;
3534   }
3535   if(m_wait_state == 1)
3536   {
3537      SET_PC(m_ppc); // wait for an exception
3538      CYCLES(1);
3539   }
3540   if(m_wait_state == 2)
3541   {
3542      m_wait_state = 0;
3543      CYCLES(1);
3544   }
3545}
3546
3547/* XGDX             0x8F */
3548void HC11OP(xgdx)()
3549{
3550   UINT16 tmp = REG_D;
3551   REG_D = m_ix;
3552   m_ix = tmp;
3553   CYCLES(3);
3554}
3555
3556
3557/* XGDY             0x18, 0x8F */
3558void HC11OP(xgdy)()
3559{
3560   UINT16 tmp = REG_D;
3561   REG_D = m_iy;
3562   m_iy = tmp;
3563   CYCLES(4);
3564}
3565
3566/*****************************************************************************/
3567
3568void HC11OP(page2)()
3569{
3570   UINT8 op2 = FETCH();
3571   (this->*hc11_optable_page2[op2])();
3572}
3573
3574void HC11OP(page3)()
3575{
3576   UINT8 op2 = FETCH();
3577   (this->*hc11_optable_page3[op2])();
3578}
3579
3580void HC11OP(page4)()
3581{
3582   UINT8 op2 = FETCH();
3583   (this->*hc11_optable_page4[op2])();
3584}
3585
3586void HC11OP(invalid)()
3587{
3588   fatalerror("HC11: Invalid opcode 0x%02X at %04X\n", READ8(m_pc-1), m_pc-1);
3589}
Property changes on: trunk/src/emu/cpu/mc68hc11/hc11ops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/mc68hc11/mc68hc11.c
r28738r28739
353353/*****************************************************************************/
354354
355355
356#include "hc11ops.c"
356#include "hc11ops.inc"
357357#include "hc11ops.h"
358358
359359void mc68hc11_cpu_device::device_start()
trunk/src/emu/cpu/cpu.mak
r28738r28739
240240
241241$(CPUOBJ)/dsp32/dsp32.o:    $(CPUSRC)/dsp32/dsp32.c \
242242                     $(CPUSRC)/dsp32/dsp32.h \
243                     $(CPUSRC)/dsp32/dsp32ops.c
243                     $(CPUSRC)/dsp32/dsp32ops.inc
244244
245245
246246
r28738r28739
652652
653653$(CPUOBJ)/e132xs/e132xs.o:  $(CPUSRC)/e132xs/e132xs.c \
654654                     $(CPUSRC)/e132xs/e132xs.h \
655                     $(CPUSRC)/e132xs/e132xsop.c
655                     $(CPUSRC)/e132xs/e132xsop.inc
656656
657657
658658
r28738r28739
780780
781781$(CPUOBJ)/mcs51/mcs51.o:    $(CPUSRC)/mcs51/mcs51.c \
782782                     $(CPUSRC)/mcs51/mcs51.h \
783                     $(CPUSRC)/mcs51/mcs51ops.c
783                     $(CPUSRC)/mcs51/mcs51ops.inc
784784
785785#-------------------------------------------------
786786# Intel MCS-96
r28738r28739
858858$(CPUOBJ)/i386/i386.o:  $(CPUSRC)/i386/i386.c \
859859                  $(CPUSRC)/i386/i386.h \
860860                  $(CPUSRC)/i386/i386priv.h \
861                  $(CPUSRC)/i386/i386op16.c \
862                  $(CPUSRC)/i386/i386op32.c \
863                  $(CPUSRC)/i386/i386ops.c \
864                  $(CPUSRC)/i386/i486ops.c \
865                  $(CPUSRC)/i386/pentops.c \
866                  $(CPUSRC)/i386/x87ops.c \
861                  $(CPUSRC)/i386/i386op16.inc \
862                  $(CPUSRC)/i386/i386op32.inc \
863                  $(CPUSRC)/i386/i386ops.inc \
864                  $(CPUSRC)/i386/i486ops.inc \
865                  $(CPUSRC)/i386/pentops.inc \
866                  $(CPUSRC)/i386/x87ops.inc \
867867                  $(CPUSRC)/i386/i386ops.h \
868868                  $(CPUSRC)/i386/cycles.h
869869
r28738r28739
882882
883883$(CPUOBJ)/i860/i860.o:  $(CPUSRC)/i860/i860.c \
884884                                    $(CPUSRC)/i860/i860.h \
885                                    $(CPUSRC)/i860/i860dec.c
885                                    $(CPUSRC)/i860/i860dec.inc
886886
887887#-------------------------------------------------
888888# Intel i960
r28738r28739
912912endif
913913
914914$(CPUOBJ)/lh5801/lh5801.o:  $(CPUSRC)/lh5801/lh5801.c \
915                     $(CPUSRC)/lh5801/5801tbl.c \
915                     $(CPUSRC)/lh5801/5801tbl.inc \
916916                     $(CPUSRC)/lh5801/lh5801.h
917917
918918
r28738r28739
12881288
12891289$(CPUOBJ)/m6800/m6800.o:    $(CPUSRC)/m6800/m6800.c \
12901290                     $(CPUSRC)/m6800/m6800.h \
1291                     $(CPUSRC)/m6800/6800ops.c \
1292                     $(CPUSRC)/m6800/6800tbl.c
1291                     $(CPUSRC)/m6800/6800ops.inc \
1292                     $(CPUSRC)/m6800/6800tbl.inc
12931293
12941294
12951295
r28738r28739
13061306
13071307$(CPUOBJ)/m6805/m6805.o:    $(CPUSRC)/m6805/m6805.c \
13081308                     $(CPUSRC)/m6805/m6805.h \
1309                     $(CPUSRC)/m6805/6805ops.c
1309                     $(CPUSRC)/m6805/6805ops.inc
13101310
13111311
13121312
r28738r28739
13671367endif
13681368
13691369$(CPUOBJ)/mc68hc11/mc68hc11.o:  $(CPUSRC)/mc68hc11/mc68hc11.c \
1370                        $(CPUSRC)/mc68hc11/hc11ops.c
1370                        $(CPUSRC)/mc68hc11/mc68hc11.h \
1371                        $(CPUSRC)/mc68hc11/hc11ops.inc \
1372                        $(CPUSRC)/mc68hc11/hc11ops.h
13711373
13721374
13731375
r28738r28739
14131415
14141416# rule to ensure we build the header before building the core CPU file
14151417$(CPUOBJ)/m68000/m68kcpu.o:     $(CPUOBJ)/m68000/m68kops.c \
1416                        $(CPUSRC)/m68000/m68kcpu.h $(CPUSRC)/m68000/m68kfpu.c $(CPUSRC)/m68000/m68kmmu.h
1418                        $(CPUSRC)/m68000/m68kcpu.h $(CPUSRC)/m68000/m68kfpu.inc $(CPUSRC)/m68000/m68kmmu.h
14171419
14181420# m68kcpu.h now includes m68kops.h; m68kops.h won't exist until m68kops.c has been made
14191421$(CPUSRC)/m68000/m68kcpu.h: $(CPUOBJ)/m68000/m68kops.c
r28738r28739
14441446                        $(CPUSRC)/dsp56k/dsp56pcu.h
14451447
14461448$(CPUOBJ)/dsp56k/dsp56k.o:  $(CPUSRC)/dsp56k/dsp56k.c \
1447                     $(CPUSRC)/dsp56k/dsp56k.h
1449                     $(CPUSRC)/dsp56k/dsp56k.h \
1450                     $(CPUSRC)/dsp56k/dsp56ops.inc
14481451
14491452$(CPUOBJ)/dsp56k/opcode.o:  $(CPUSRC)/dsp56k/opcode.c \
14501453                     $(CPUSRC)/dsp56k/opcode.h
r28738r28739
15421545$(CPUOBJ)/nec/nec.o:    $(CPUSRC)/nec/nec.c \
15431546                  $(CPUSRC)/nec/nec.h \
15441547                  $(CPUSRC)/nec/necea.h \
1545                  $(CPUSRC)/nec/necinstr.c \
1548                  $(CPUSRC)/nec/necinstr.inc \
15461549                  $(CPUSRC)/nec/necinstr.h \
15471550                  $(CPUSRC)/nec/necmacro.h \
15481551                  $(CPUSRC)/nec/necmodrm.h \
r28738r28739
15511554$(CPUOBJ)/nec/v25.o:    $(CPUSRC)/nec/v25.c \
15521555                  $(CPUSRC)/nec/nec.h \
15531556                  $(CPUSRC)/nec/necea.h \
1554                  $(CPUSRC)/nec/necinstr.c \
1555                  $(CPUSRC)/nec/v25instr.c \
1557                  $(CPUSRC)/nec/necinstr.inc \
1558                  $(CPUSRC)/nec/v25instr.inc \
15561559                  $(CPUSRC)/nec/v25instr.h \
15571560                  $(CPUSRC)/nec/necmacro.h \
15581561                  $(CPUSRC)/nec/necmodrm.h \
trunk/src/emu/cpu/lh5801/5801tbl.c
r28738r28739
1/* assumed
2   res=left+right+c
3   sbc is like adc with inverted carry and right side
4   (decrement, compare the same)
5   (like in the m6502 processors)
6*/
7UINT8 lh5801_cpu_device::lh5801_add_generic(int left, int right, int carry)
8{
9   int res=left+right+carry;
10   int v,c;
11
12   m_t&=~(H|V|Z|C);
13
14   if (!(res&0xff)) m_t|=Z;
15   c=res&0x100;
16   if (c) m_t|=C;
17   if (((left&0xf)+(right&0xf)+carry)&0x10) m_t|=H;
18   v=((left&0x7f)+(right&0x7f)+carry)&0x80;
19   if ( (c&&!v)||(!c&&v) ) m_t|=V;
20
21   return res;
22}
23
24UINT16 lh5801_cpu_device::lh5801_readop_word()
25{
26   UINT16 r;
27   r=m_direct->read_decrypted_byte(P++)<<8;
28   r|=m_direct->read_decrypted_byte(P++);
29   return r;
30}
31
32
33void lh5801_cpu_device::lh5801_adc(UINT8 data)
34{
35   m_a=lh5801_add_generic(m_a,data,m_t&C);
36}
37
38void lh5801_cpu_device::lh5801_add_mem(address_space &space, int addr, UINT8 data)
39{
40   int v=lh5801_add_generic(space.read_byte(addr),data,0);
41   space.write_byte(addr,v);
42}
43
44void lh5801_cpu_device::lh5801_adr(PAIR *reg)
45{
46   reg->b.l=lh5801_add_generic(reg->b.l,m_a,0);
47   if (m_t&C) {
48      reg->b.h++;
49   }
50}
51
52void lh5801_cpu_device::lh5801_sbc(UINT8 data)
53{
54   m_a=lh5801_add_generic(m_a,data^0xff,m_t&C);
55}
56
57void lh5801_cpu_device::lh5801_cpa(UINT8 a, UINT8 b)
58{
59   lh5801_add_generic(a, b^0xff, 1);
60}
61
62UINT8 lh5801_cpu_device::lh5801_decimaladd_generic(int left, int right, int carry)
63{
64   int res=lh5801_add_generic(left, right, carry);
65   UINT8 da;
66
67   //DA values taken from official documentation
68   if (!(m_t&C) && !(m_t&H))
69      da = 0x9a;
70   else if (!(m_t&C) &&  (m_t&H))
71      da = 0xa0;
72   else if ((m_t&C) && !(m_t&H))
73      da = 0xfa;
74   else    //if ((m_t&C) && (m_t&H))
75      da = 0x00;
76
77   return res + da;
78}
79
80void lh5801_cpu_device::lh5801_dca(UINT8 data)
81{
82   m_a += 0x66;    //taken from official documentation
83   m_a=lh5801_decimaladd_generic(m_a, data, m_t&C);
84}
85
86void lh5801_cpu_device::lh5801_dcs(UINT8 data)
87{
88   m_a=lh5801_decimaladd_generic(m_a, data^0xff, m_t&C);
89}
90
91void lh5801_cpu_device::lh5801_and(UINT8 data)
92{
93   m_a&=data;
94   m_t&=~Z;
95   if (!m_a) m_t|=Z;
96}
97
98void lh5801_cpu_device::lh5801_and_mem(address_space &space, int addr, UINT8 data)
99{
100   data&=space.read_byte(addr);
101   m_t&=~Z;
102   if (!data) m_t|=Z;
103   space.write_byte(addr,data);
104}
105
106void lh5801_cpu_device::lh5801_bit(UINT8 a, UINT8 b)
107{
108   m_t&=~Z;
109   if (!(a&b)) m_t|=Z;
110}
111
112void lh5801_cpu_device::lh5801_eor(UINT8 data)
113{
114   m_a^=data;
115   m_t&=~Z;
116   if (!m_a) m_t|=Z;
117}
118
119void lh5801_cpu_device::lh5801_ora(UINT8 data)
120{
121   m_a|=data;
122   m_t&=~Z;
123   if (!m_a) m_t|=Z;
124}
125
126void lh5801_cpu_device::lh5801_ora_mem(address_space &space, int addr, UINT8 data)
127{
128   data|=space.read_byte(addr);
129   m_t&=~Z;
130   if (!data) m_t|=Z;
131   space.write_byte(addr,data);
132}
133
134void lh5801_cpu_device::lh5801_lda(UINT8 data)
135{
136   m_a=data;
137   m_t&=~Z;
138   if (!m_a) m_t|=Z;
139}
140
141void lh5801_cpu_device::lh5801_lde(PAIR *reg)
142{
143   // or z flag depends on reg
144   m_a=m_program->read_byte(reg->w.l--);
145   m_t&=~Z;
146   if (!m_a) m_t|=Z;
147}
148
149void lh5801_cpu_device::lh5801_sde(PAIR *reg)
150{
151   m_program->write_byte(reg->w.l--, m_a);
152}
153
154void lh5801_cpu_device::lh5801_lin(PAIR *reg)
155{
156   // or z flag depends on reg
157   m_a=m_program->read_byte(reg->w.l++);
158   m_t&=~Z;
159   if (!m_a) m_t|=Z;
160}
161
162void lh5801_cpu_device::lh5801_sin(PAIR *reg)
163{
164   m_program->write_byte(reg->w.l++, m_a);
165}
166
167void lh5801_cpu_device::lh5801_dec(UINT8 *adr)
168{
169   *adr=lh5801_add_generic(*adr,0xff,0);
170}
171
172void lh5801_cpu_device::lh5801_inc(UINT8 *adr)
173{
174   *adr=lh5801_add_generic(*adr,1,0);
175}
176
177void lh5801_cpu_device::lh5801_pop()
178{
179   m_a=m_program->read_byte(++S);
180   m_t&=~Z;
181   if (!m_a) m_t|=Z;
182}
183
184void lh5801_cpu_device::lh5801_pop_word(PAIR *reg)
185{
186   reg->b.h=m_program->read_byte(++S);
187   reg->b.l=m_program->read_byte(++S);
188   // z flag?
189}
190
191void lh5801_cpu_device::lh5801_rtn()
192{
193   P=m_program->read_byte(++S)<<8;
194   P|=m_program->read_byte(++S);
195}
196
197void lh5801_cpu_device::lh5801_rti()
198{
199   P=m_program->read_byte(++S)<<8;
200   P|=m_program->read_byte(++S);
201   m_t=m_program->read_byte(++S);
202}
203
204void lh5801_cpu_device::lh5801_push(UINT8 data)
205{
206   m_program->write_byte(S--, data);
207}
208
209void lh5801_cpu_device::lh5801_push_word(UINT16 data)
210{
211   m_program->write_byte(S--, data&0xff);
212   m_program->write_byte(S--, data>>8);
213}
214
215void lh5801_cpu_device::lh5801_jmp(UINT16 adr)
216{
217   P=adr;
218}
219
220void lh5801_cpu_device::lh5801_branch_plus(int doit)
221{
222   UINT8 t=m_direct->read_decrypted_byte(P++);
223   if (doit) {
224      m_icount-=3;
225      P+=t;
226   }
227}
228
229void lh5801_cpu_device::lh5801_branch_minus(int doit)
230{
231   UINT8 t=m_direct->read_decrypted_byte(P++);
232   if (doit) {
233      m_icount-=3;
234      P-=t;
235   }
236}
237
238void lh5801_cpu_device::lh5801_lop()
239{
240   UINT8 t=m_direct->read_decrypted_byte(P++);
241   m_icount-=8;
242   if (UL--) {
243      m_icount-=3;
244      P-=t;
245   }
246}
247
248void lh5801_cpu_device::lh5801_sjp()
249{
250   UINT16 n=lh5801_readop_word();
251   lh5801_push_word(P);
252   P=n;
253}
254
255void lh5801_cpu_device::lh5801_vector(int doit, int nr)
256{
257   if (doit) {
258      lh5801_push_word(P);
259      P=m_program->read_byte(0xff00+nr)<<8;
260      P|=m_program->read_byte(0xff00+nr+1);
261      m_icount-=21-8;
262   }
263   m_t&=~Z; // after the jump!?
264}
265
266void lh5801_cpu_device::lh5801_aex()
267{
268   UINT8 t=m_a;
269   m_a=(t<<4)|(t>>4);
270   // flags?
271}
272
273void lh5801_cpu_device::lh5801_drl(address_space &space, int adr)
274{
275   UINT16 t=m_a|(space.read_byte(adr)<<8);
276
277   m_a=t>>8;
278   space.write_byte(adr,t>>4);
279}
280
281void lh5801_cpu_device::lh5801_drr(address_space &space, int adr)
282{
283   UINT16 t=space.read_byte(adr)|(m_a<<8);
284
285   m_a=t;
286   space.write_byte(adr,t>>4);
287}
288
289void lh5801_cpu_device::lh5801_rol()
290{
291   // maybe use of the adder
292   int n = m_a;
293   m_a = (n<<1) | (m_t&C);
294   // flags cvhz
295   m_t&=~(H|V|Z|C);
296   if (n&0x80) m_t|=C;
297   if (!m_a) m_t|=Z;
298   if (m_a & 0x10) m_t|=H;
299   if ((BIT(n,6) && !BIT(n,7)) || (!BIT(n,6) && BIT(n,7))) m_t|=V;
300}
301
302void lh5801_cpu_device::lh5801_ror()
303{
304   int n = m_a;
305   m_a=(n | ((m_t&C)<<8))>>1;
306   // flags cvhz
307   m_t&=~(H|V|Z|C);
308   if (n&0x01) m_t|=C;
309   if (!m_a) m_t|=Z;
310   if (m_a & 0x08) m_t|=H;
311   if ((BIT(n,0) && BIT(m_a,1)) || (BIT(m_a,0) && BIT(n,1))) m_t|=V;
312}
313
314void lh5801_cpu_device::lh5801_shl()
315{
316   int n = m_a;
317   m_a<<=1;
318   // flags cvhz
319   m_t&=~(H|V|Z|C);
320   if (n&0x80) m_t|=C;
321   if (!m_a) m_t|=Z;
322   if (m_a & 0x10) m_t|=H;
323   if ((BIT(n,6) && !BIT(n,7)) || (!BIT(n,6) && BIT(n,7))) m_t|=V;
324}
325
326void lh5801_cpu_device::lh5801_shr()
327{
328   int n = m_a;
329   m_a>>=1;
330   // flags cvhz
331   m_t&=~(H|V|Z|C);
332   if (n & 0x01) m_t|=C;
333   if (!m_a) m_t|=Z;
334   if (m_a & 0x08) m_t|=H;
335   if ((BIT(n,0) && BIT(m_a,1)) || (BIT(m_a,0) && BIT(n,1))) m_t|=V;
336}
337
338void lh5801_cpu_device::lh5801_am(int value)
339{
340   m_tm=value;
341   // jfkas?jfkl?jkd?
342}
343
344void lh5801_cpu_device::lh5801_ita()
345{
346   m_a=m_in_func();
347   m_t&=~Z;
348   if (!m_a) m_t|=Z;
349}
350
351void lh5801_cpu_device::lh5801_instruction_fd()
352{
353   int oper;
354   int adr;
355
356   oper=m_direct->read_decrypted_byte(P++);
357   switch (oper) {
358   case 0x01: lh5801_sbc(m_io->read_byte(X)); m_icount-=11;break;
359   case 0x03: lh5801_adc(m_io->read_byte(X)); m_icount-=11;break;
360   case 0x05: lh5801_lda(m_io->read_byte(X)); m_icount-=10;break;
361   case 0x07: lh5801_cpa(m_a, m_io->read_byte(X)); m_icount-=11;break;
362   case 0x08: X=X;m_icount-=11;break; //!!!
363   case 0x09: lh5801_and(m_io->read_byte(X)); m_icount-=11;break;
364   case 0x0a: lh5801_pop_word(&m_x); m_icount-=15;break;
365   case 0x0b: lh5801_ora(m_io->read_byte(X)); m_icount-=11;break;
366   case 0x0c: lh5801_dcs(m_io->read_byte(X)); m_icount-=17; break;
367   case 0x0d: lh5801_eor(m_io->read_byte(X)); m_icount-=11;break;
368   case 0x0e: m_io->write_byte(X,m_a); m_icount-=10;break;
369   case 0x0f: lh5801_bit(m_io->read_byte(X),m_a); m_icount-=11;break;
370   case 0x11: lh5801_sbc(m_io->read_byte(Y)); m_icount-=11;break;
371   case 0x13: lh5801_adc(m_io->read_byte(Y)); m_icount-=11;break;
372   case 0x15: lh5801_lda(m_io->read_byte(Y)); m_icount-=10;break;
373   case 0x17: lh5801_cpa(m_a, m_io->read_byte(Y)); m_icount-=11;break;
374   case 0x18: X=Y;m_icount-=11;break;
375   case 0x19: lh5801_and(m_io->read_byte(Y)); m_icount-=11;break;
376   case 0x1a: lh5801_pop_word(&m_y); m_icount-=15;break;
377   case 0x1b: lh5801_ora(m_io->read_byte(Y)); m_icount-=11;break;
378   case 0x1c: lh5801_dcs(m_io->read_byte(Y)); m_icount-=17; break;
379   case 0x1d: lh5801_eor(m_io->read_byte(Y)); m_icount-=11;break;
380   case 0x1e: m_io->write_byte(Y,m_a); m_icount-=10;break;
381   case 0x1f: lh5801_bit(m_io->read_byte(Y),m_a); m_icount-=11;break;
382   case 0x21: lh5801_sbc(m_io->read_byte(U)); m_icount-=11;break;
383   case 0x23: lh5801_adc(m_io->read_byte(U)); m_icount-=11;break;
384   case 0x25: lh5801_lda(m_io->read_byte(U)); m_icount-=10;break;
385   case 0x27: lh5801_cpa(m_a, m_io->read_byte(U)); m_icount-=11;break;
386   case 0x28: X=U;m_icount-=11;break;
387   case 0x29: lh5801_and(m_io->read_byte(U)); m_icount-=11;break;
388   case 0x2a: lh5801_pop_word(&m_u); m_icount-=15;break;
389   case 0x2b: lh5801_ora(m_io->read_byte(U)); m_icount-=11;break;
390   case 0x2c: lh5801_dcs(m_io->read_byte(U)); m_icount-=17; break;
391   case 0x2d: lh5801_eor(m_io->read_byte(U)); m_icount-=11;break;
392   case 0x2e: m_io->write_byte(U,m_a); m_icount-=10;break;
393   case 0x2f: lh5801_bit(m_io->read_byte(U),m_a); m_icount-=11;break;
394   case 0x40: lh5801_inc(&XH);m_icount-=9;break;
395   case 0x42: lh5801_dec(&XH);m_icount-=9;break;
396   case 0x48: X=S;m_icount-=11;break;
397   case 0x49: lh5801_and_mem(*m_io, X, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
398   case 0x4a: X=X;m_icount-=11;break; //!!!
399   case 0x4b: lh5801_ora_mem(*m_io, X, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
400   case 0x4c: m_bf=0;/*off !*/ m_icount-=8;break;
401   case 0x4d: lh5801_bit(m_io->read_byte(X), m_direct->read_decrypted_byte(P++));m_icount-=14;break;
402   case 0x4e: S=X;m_icount-=11;break;
403   case 0x4f: lh5801_add_mem(*m_io, X, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
404   case 0x50: lh5801_inc(&YH);m_icount-=9;break;
405   case 0x52: lh5801_dec(&YH);m_icount-=9;break;
406   case 0x58: X=P;m_icount-=11;break;
407   case 0x59: lh5801_and_mem(*m_io, Y, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
408   case 0x5a: Y=X;m_icount-=11;break;
409   case 0x5b: lh5801_ora_mem(*m_io, Y, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
410   case 0x5d: lh5801_bit(m_io->read_byte(Y), m_direct->read_decrypted_byte(P++));m_icount-=14;break;
411   case 0x5e: lh5801_jmp(X);m_icount-=11;break; // P=X
412   case 0x5f: lh5801_add_mem(*m_io, Y, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
413   case 0x60: lh5801_inc(&UH);m_icount-=9;break;
414   case 0x62: lh5801_dec(&UH);m_icount-=9;break;
415   case 0x69: lh5801_and_mem(*m_io, U, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
416   case 0x6a: U=X;m_icount-=11;break;
417   case 0x6b: lh5801_ora_mem(*m_io, U, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
418   case 0x6d: lh5801_bit(m_io->read_byte(X), m_direct->read_decrypted_byte(P++));m_icount-=14;break;
419   case 0x6f: lh5801_add_mem(*m_io, U, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
420   case 0x81: m_t|=IE; /*sie !*/m_icount-=8;break;
421   case 0x88: lh5801_push_word(X); m_icount-=14;break;
422   case 0x8a: lh5801_pop(); m_icount-=12; break;
423   case 0x8c: lh5801_dca(m_io->read_byte(X)); m_icount-=19; break;
424   case 0x8e: /*cdv clears internal devider*/m_icount-=8;break;
425   case 0x98: lh5801_push_word(Y); m_icount-=14;break;
426   case 0x9c: lh5801_dca(m_io->read_byte(Y)); m_icount-=19; break;
427   case 0xa1: lh5801_sbc(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
428   case 0xa3: lh5801_adc(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
429   case 0xa5: lh5801_lda(m_io->read_byte(lh5801_readop_word())); m_icount-=16;break;
430   case 0xa7: lh5801_cpa(m_a, m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
431   case 0xa8: lh5801_push_word(U); m_icount-=14;break;
432   case 0xa9: lh5801_and(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
433   case 0xaa: lh5801_lda(m_t); m_icount-=9;break;
434   case 0xab: lh5801_ora(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
435   case 0xac: lh5801_dca(m_io->read_byte(U)); m_icount-=19; break;
436   case 0xad: lh5801_eor(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
437   case 0xae: m_io->write_byte(lh5801_readop_word(),m_a); m_icount-=16;break;
438   case 0xaf: lh5801_bit(m_io->read_byte(lh5801_readop_word()),m_a); m_icount-=17;break;
439   case 0xb1: /*hlt*/m_icount-=8;break;
440   case 0xba: lh5801_ita();m_icount-=9;break;
441   case 0xbe: m_t&=~IE; /*rie !*/m_icount-=8;break;
442   case 0xc0: m_dp=0; /*rdp !*/m_icount-=8;break;
443   case 0xc1: m_dp=1; /*sdp !*/m_icount-=8;break;
444   case 0xc8: lh5801_push(m_a); m_icount-=11;break;
445   case 0xca: lh5801_adr(&m_x);m_icount-=11;break;
446   case 0xcc: /*atp sends a to data bus*/m_icount-=9;break;
447   case 0xce: lh5801_am(m_a); m_icount-=9; break;
448   case 0xd3: lh5801_drr(*m_io, X); m_icount-=16; break;
449   case 0xd7: lh5801_drl(*m_io, X); m_icount-=16; break;
450   case 0xda: lh5801_adr(&m_y);m_icount-=11;break;
451   case 0xde: lh5801_am(m_a|0x100); m_icount-=9; break;
452   case 0xea: lh5801_adr(&m_u);m_icount-=11;break;
453   case 0xe9:
454      adr=lh5801_readop_word();
455      lh5801_and_mem(*m_io, adr, m_direct->read_decrypted_byte(P++)); m_icount-=23;
456      break;
457   case 0xeb:
458      adr=lh5801_readop_word();
459      lh5801_ora_mem(*m_io, adr, m_direct->read_decrypted_byte(P++)); m_icount-=23;
460      break;
461   case 0xec: m_t=m_a; m_icount-=9;break;
462   case 0xed:
463      adr=lh5801_readop_word();
464      lh5801_bit(m_io->read_byte(adr), m_direct->read_decrypted_byte(P++));
465      m_icount-=20;break;
466   case 0xef:
467      adr=lh5801_readop_word();
468      lh5801_add_mem(*m_io, adr, m_direct->read_decrypted_byte(P++)); m_icount-=23;
469      break;
470
471   default:
472      logerror("lh5801 illegal opcode at %.4x fd%.2x\n",P-2, oper);
473   }
474}
475
476void lh5801_cpu_device::lh5801_instruction()
477{
478   int oper;
479   int adr;
480
481   oper=m_direct->read_decrypted_byte(P++);
482   switch (oper) {
483   case 0x00: lh5801_sbc(XL); m_icount-=6;break;
484   case 0x01: lh5801_sbc(m_program->read_byte(X)); m_icount-=7;break;
485   case 0x02: lh5801_adc(XL); m_icount-=6;break;
486   case 0x03: lh5801_adc(m_program->read_byte(X)); m_icount-=7;break;
487   case 0x04: lh5801_lda(XL); m_icount-=5;break;
488   case 0x05: lh5801_lda(m_program->read_byte(X)); m_icount-=6;break;
489   case 0x06: lh5801_cpa(m_a, XL); m_icount-=6;break;
490   case 0x07: lh5801_cpa(m_a, m_program->read_byte(X)); m_icount-=7;break;
491   case 0x08: XH=m_a; m_icount-=5; break;
492   case 0x09: lh5801_and(m_program->read_byte(X)); m_icount-=7;break;
493   case 0x0a: XL=m_a; m_icount-=5; break;
494   case 0x0b: lh5801_ora(m_program->read_byte(X)); m_icount-=7;break;
495   case 0x0c: lh5801_dcs(m_program->read_byte(X)); m_icount-=13; break;
496   case 0x0d: lh5801_eor(m_program->read_byte(X)); m_icount-=7;break;
497   case 0x0e: m_program->write_byte(X,m_a); m_icount-=6;break;
498   case 0x0f: lh5801_bit(m_program->read_byte(X),m_a); m_icount-=7;break;
499   case 0x10: lh5801_sbc(YL); m_icount-=6;break;
500   case 0x11: lh5801_sbc(m_program->read_byte(Y)); m_icount-=7;break;
501   case 0x12: lh5801_adc(YL); m_icount-=6;break;
502   case 0x13: lh5801_adc(m_program->read_byte(Y)); m_icount-=7;break;
503   case 0x14: lh5801_lda(YL); m_icount-=5;break;
504   case 0x15: lh5801_lda(m_program->read_byte(Y)); m_icount-=6;break;
505   case 0x16: lh5801_cpa(m_a, YL); m_icount-=6;break;
506   case 0x17: lh5801_cpa(m_a, m_program->read_byte(Y)); m_icount-=7;break;
507   case 0x18: YH=m_a; m_icount-=5; break;
508   case 0x19: lh5801_and(m_program->read_byte(Y)); m_icount-=7;break;
509   case 0x1a: YL=m_a; m_icount-=5; break;
510   case 0x1b: lh5801_ora(m_program->read_byte(Y)); m_icount-=7;break;
511   case 0x1c: lh5801_dcs(m_program->read_byte(Y)); m_icount-=13; break;
512   case 0x1d: lh5801_eor(m_program->read_byte(Y)); m_icount-=7;break;
513   case 0x1e: m_program->write_byte(Y,m_a); m_icount-=6;break;
514   case 0x1f: lh5801_bit(m_program->read_byte(Y),m_a); m_icount-=7;break;
515   case 0x20: lh5801_sbc(UL); m_icount-=6;break;
516   case 0x21: lh5801_sbc(m_program->read_byte(U)); m_icount-=7;break;
517   case 0x22: lh5801_adc(UL); m_icount-=6;break;
518   case 0x23: lh5801_adc(m_program->read_byte(U)); m_icount-=7;break;
519   case 0x24: lh5801_lda(UL); m_icount-=5;break;
520   case 0x25: lh5801_lda(m_program->read_byte(U)); m_icount-=6;break;
521   case 0x26: lh5801_cpa(m_a, UL); m_icount-=6;break;
522   case 0x27: lh5801_cpa(m_a, m_program->read_byte(U)); m_icount-=7;break;
523   case 0x28: UH=m_a; m_icount-=5; break;
524   case 0x29: lh5801_and(m_program->read_byte(U)); m_icount-=7;break;
525   case 0x2a: UL=m_a; m_icount-=5; break;
526   case 0x2b: lh5801_ora(m_program->read_byte(U)); m_icount-=7;break;
527   case 0x2c: lh5801_dcs(m_program->read_byte(U)); m_icount-=13; break;
528   case 0x2d: lh5801_eor(m_program->read_byte(U)); m_icount-=7;break;
529   case 0x2e: m_program->write_byte(U,m_a); m_icount-=6;break;
530   case 0x2f: lh5801_bit(m_program->read_byte(U),m_a); m_icount-=7;break;
531   case 0x38: /*nop*/m_icount-=5;break;
532   case 0x40: lh5801_inc(&XL);m_icount-=5;break;
533   case 0x41: lh5801_sin(&m_x); m_icount-=6;break;
534   case 0x42: lh5801_dec(&XL);m_icount-=5;break;
535   case 0x43: lh5801_sde(&m_x); m_icount-=6;break;
536   case 0x44: X++;m_icount-=5;break;
537   case 0x45: lh5801_lin(&m_x);m_icount-=6;break;
538   case 0x46: X--;m_icount-=5;break;
539   case 0x47: lh5801_lde(&m_x);m_icount-=6;break;
540   case 0x48: XH=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
541   case 0x49: lh5801_and_mem(*m_program, X, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
542   case 0x4a: XL=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
543   case 0x4b: lh5801_ora_mem(*m_program, X, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
544   case 0x4c: lh5801_cpa(XH, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
545   case 0x4d: lh5801_bit(m_program->read_byte(X), m_direct->read_decrypted_byte(P++));m_icount-=10;break;
546   case 0x4e: lh5801_cpa(XL, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
547   case 0x4f: lh5801_add_mem(*m_program, X, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
548   case 0x50: lh5801_inc(&YL);m_icount-=5;break;
549   case 0x51: lh5801_sin(&m_y); m_icount-=6;break;
550   case 0x52: lh5801_dec(&YL);m_icount-=5;break;
551   case 0x53: lh5801_sde(&m_y); m_icount-=6;break;
552   case 0x54: Y++;m_icount-=5;break;
553   case 0x55: lh5801_lin(&m_y);m_icount-=6;break;
554   case 0x56: Y--;m_icount-=5;break;
555   case 0x57: lh5801_lde(&m_y);m_icount-=6;break;
556   case 0x58: YH=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
557   case 0x59: lh5801_and_mem(*m_program, Y, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
558   case 0x5a: YL=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
559   case 0x5b: lh5801_ora_mem(*m_program, Y, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
560   case 0x5c: lh5801_cpa(YH, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
561   case 0x5d: lh5801_bit(m_program->read_byte(Y), m_direct->read_decrypted_byte(P++));m_icount-=10;break;
562   case 0x5e: lh5801_cpa(YL, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
563   case 0x5f: lh5801_add_mem(*m_program, Y, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
564   case 0x60: lh5801_inc(&UL);m_icount-=5;break;
565   case 0x61: lh5801_sin(&m_u); m_icount-=6;break;
566   case 0x62: lh5801_dec(&UL);m_icount-=5;break;
567   case 0x63: lh5801_sde(&m_u); m_icount-=6;break;
568   case 0x64: U++;m_icount-=5;break;
569   case 0x65: lh5801_lin(&m_u);m_icount-=6;break;
570   case 0x66: U--;m_icount-=5;break;
571   case 0x67: lh5801_lde(&m_u);m_icount-=6;break;
572   case 0x68: UH=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
573   case 0x69: lh5801_and_mem(*m_program, U, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
574   case 0x6a: UL=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
575   case 0x6b: lh5801_ora_mem(*m_program, U, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
576   case 0x6c: lh5801_cpa(UH, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
577   case 0x6d: lh5801_bit(m_program->read_byte(U), m_direct->read_decrypted_byte(P++));m_icount-=10;break;
578   case 0x6e: lh5801_cpa(UL, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
579   case 0x6f: lh5801_add_mem(*m_program, U, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
580   case 0x80: lh5801_sbc(XH); m_icount-=6;break;
581   case 0x81: lh5801_branch_plus(!(m_t&C)); m_icount-=8; break;
582   case 0x82: lh5801_adc(XH); m_icount-=6;break;
583   case 0x83: lh5801_branch_plus(m_t&C); m_icount-=8; break;
584   case 0x84: lh5801_lda(XH); m_icount-=5;break;
585   case 0x85: lh5801_branch_plus(!(m_t&H)); m_icount-=8; break;
586   case 0x86: lh5801_cpa(m_a, XH); m_icount-=6;break;
587   case 0x87: lh5801_branch_plus(m_t&H); m_icount-=8; break;
588   case 0x88: lh5801_lop(); break;
589   case 0x89: lh5801_branch_plus(!(m_t&Z)); m_icount-=8; break;
590   case 0x8a: lh5801_rti(); m_icount-=14; break;
591   case 0x8b: lh5801_branch_plus(m_t&Z); m_icount-=8; break;
592   case 0x8c: lh5801_dca(m_program->read_byte(X)); m_icount-=15; break;
593   case 0x8d: lh5801_branch_plus(!(m_t&V)); m_icount-=8; break;
594   case 0x8e: lh5801_branch_plus(1); m_icount-=5; break;
595   case 0x8f: lh5801_branch_plus(m_t&V); m_icount-=8; break;
596   case 0x90: lh5801_sbc(YH); m_icount-=6;break;
597   case 0x91: lh5801_branch_minus(!(m_t&C)); m_icount-=8; break;
598   case 0x92: lh5801_adc(YH); m_icount-=6;break;
599   case 0x93: lh5801_branch_minus(m_t&C); m_icount-=8; break;
600   case 0x94: lh5801_lda(YH); m_icount-=5;break;
601   case 0x95: lh5801_branch_minus(!(m_t&H)); m_icount-=8; break;
602   case 0x96: lh5801_cpa(m_a, YH); m_icount-=6;break;
603   case 0x97: lh5801_branch_minus(m_t&H); m_icount-=8; break;
604   case 0x99: lh5801_branch_minus(!(m_t&Z)); m_icount-=8; break;
605   case 0x9a: lh5801_rtn(); m_icount-=11; break;
606   case 0x9b: lh5801_branch_minus(m_t&Z); m_icount-=8; break;
607   case 0x9c: lh5801_dca(m_program->read_byte(Y)); m_icount-=15; break;
608   case 0x9d: lh5801_branch_minus(!(m_t&V)); m_icount-=8; break;
609   case 0x9e: lh5801_branch_minus(1); m_icount-=6; break;
610   case 0x9f: lh5801_branch_minus(m_t&V); m_icount-=8; break;
611   case 0xa0: lh5801_sbc(UH); m_icount-=6;break;
612   case 0xa2: lh5801_adc(UH); m_icount-=6;break;
613   case 0xa1: lh5801_sbc(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
614   case 0xa3: lh5801_adc(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
615   case 0xa4: lh5801_lda(UH); m_icount-=5;break;
616   case 0xa5: lh5801_lda(m_program->read_byte(lh5801_readop_word())); m_icount-=12;break;
617   case 0xa6: lh5801_cpa(m_a, UH); m_icount-=6;break;
618   case 0xa7: lh5801_cpa(m_a, m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
619   case 0xa8: m_pv=1;/*spv!*/ m_icount-=4; break;
620   case 0xa9: lh5801_and(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
621   case 0xaa: S=lh5801_readop_word();m_icount-=6;break;
622   case 0xab: lh5801_ora(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
623   case 0xac: lh5801_dca(m_program->read_byte(U)); m_icount-=15; break;
624   case 0xad: lh5801_eor(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
625   case 0xae: m_program->write_byte(lh5801_readop_word(),m_a); m_icount-=12;break;
626   case 0xaf: lh5801_bit(m_program->read_byte(lh5801_readop_word()),m_a); m_icount-=13;break;
627   case 0xb1: lh5801_sbc(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
628   case 0xb3: lh5801_adc(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
629   case 0xb5: lh5801_lda(m_direct->read_decrypted_byte(P++)); m_icount-=6;break;
630   case 0xb7: lh5801_cpa(m_a, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
631   case 0xb8: m_pv=0;/*rpv!*/ m_icount-=4; break;
632   case 0xb9: lh5801_and(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
633   case 0xba: lh5801_jmp(lh5801_readop_word()); m_icount-=12;break;
634   case 0xbb: lh5801_ora(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
635   case 0xbd: lh5801_eor(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
636   case 0xbe: lh5801_sjp(); m_icount-=19; break;
637   case 0xbf: lh5801_bit(m_a, m_direct->read_decrypted_byte(P++));m_icount-=7;break;
638   case 0xc1: lh5801_vector(!(m_t&C), m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
639   case 0xc3: lh5801_vector(m_t&C, m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
640   case 0xc5: lh5801_vector(!(m_t&H), m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
641   case 0xc7: lh5801_vector(m_t&H, m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
642   case 0xc9: lh5801_vector(!(m_t&Z), m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
643   case 0xcb: lh5801_vector(m_t&Z, m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
644   case 0xcd: lh5801_vector(1, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
645   case 0xcf: lh5801_vector(m_t&V, m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
646   case 0xd1: lh5801_ror(); m_icount-=6; break;
647   case 0xd3: lh5801_drr(*m_program, X); m_icount-=12; break;
648   case 0xd5: lh5801_shr(); m_icount-=6; break;
649   case 0xd7: lh5801_drl(*m_program, X); m_icount-=12; break;
650   case 0xd9: lh5801_shl(); m_icount-=6; break;
651   case 0xdb: lh5801_rol(); m_icount-=6; break;
652   case 0xdd: lh5801_inc(&m_a);m_icount-=5;break;
653   case 0xdf: lh5801_dec(&m_a);m_icount-=5;break;
654   case 0xe1: m_pu=1;/*spu!*/ m_icount-=4; break;
655   case 0xe3: m_pu=0;/*rpu!*/ m_icount-=4; break;
656   case 0xe9:
657      adr=lh5801_readop_word();lh5801_and_mem(*m_program, adr, m_direct->read_decrypted_byte(P++));
658      m_icount-=19;break;
659   case 0xeb:
660      adr=lh5801_readop_word();lh5801_ora_mem(*m_program, adr, m_direct->read_decrypted_byte(P++));
661      m_icount-=19;break;
662   case 0xed:
663      adr=lh5801_readop_word();lh5801_bit(m_program->read_byte(adr), m_direct->read_decrypted_byte(P++));
664      m_icount-=16;break;
665   case 0xef:
666      adr=lh5801_readop_word();
667      lh5801_add_mem(*m_program, adr, m_direct->read_decrypted_byte(P++)); m_icount-=19;
668      break;
669   case 0xf1: lh5801_aex(); m_icount-=6; break;
670   case 0xf5: m_program->write_byte(Y++, m_program->read_byte(X++)); m_icount-=7; break; //tin
671   case 0xf7: lh5801_cpa(m_a, m_program->read_byte(X++));m_icount-=7; break; //cin
672   case 0xf9: m_t&=~C;m_icount-=4;break;
673   case 0xfb: m_t|=C;m_icount-=4;break;
674   case 0xfd: lh5801_instruction_fd();break;
675   case 0xc0: case 0xc2: case 0xc4: case 0xc6:
676   case 0xc8: case 0xca: case 0xcc: case 0xce:
677   case 0xd0: case 0xd2: case 0xd4: case 0xd6:
678   case 0xd8: case 0xda: case 0xdc: case 0xde:
679   case 0xe0: case 0xe2: case 0xe4: case 0xe6:
680   case 0xe8: case 0xea: case 0xec: case 0xee:
681   case 0xf0: case 0xf2: case 0xf4: case 0xf6:
682      lh5801_vector(1, oper);m_icount-=4;break;
683   default:
684      logerror("lh5801 illegal opcode at %.4x %.2x\n",P-1, oper);
685   }
686
687}
trunk/src/emu/cpu/lh5801/lh5801.c
r28738r28739
8989/***************************************************************
9090 * include the opcode macros, functions and tables
9191 ***************************************************************/
92#include "5801tbl.c"
92#include "5801tbl.inc"
9393
9494void lh5801_cpu_device::device_start()
9595{
trunk/src/emu/cpu/lh5801/5801tbl.inc
r0r28739
1/* assumed
2   res=left+right+c
3   sbc is like adc with inverted carry and right side
4   (decrement, compare the same)
5   (like in the m6502 processors)
6*/
7UINT8 lh5801_cpu_device::lh5801_add_generic(int left, int right, int carry)
8{
9   int res=left+right+carry;
10   int v,c;
11
12   m_t&=~(H|V|Z|C);
13
14   if (!(res&0xff)) m_t|=Z;
15   c=res&0x100;
16   if (c) m_t|=C;
17   if (((left&0xf)+(right&0xf)+carry)&0x10) m_t|=H;
18   v=((left&0x7f)+(right&0x7f)+carry)&0x80;
19   if ( (c&&!v)||(!c&&v) ) m_t|=V;
20
21   return res;
22}
23
24UINT16 lh5801_cpu_device::lh5801_readop_word()
25{
26   UINT16 r;
27   r=m_direct->read_decrypted_byte(P++)<<8;
28   r|=m_direct->read_decrypted_byte(P++);
29   return r;
30}
31
32
33void lh5801_cpu_device::lh5801_adc(UINT8 data)
34{
35   m_a=lh5801_add_generic(m_a,data,m_t&C);
36}
37
38void lh5801_cpu_device::lh5801_add_mem(address_space &space, int addr, UINT8 data)
39{
40   int v=lh5801_add_generic(space.read_byte(addr),data,0);
41   space.write_byte(addr,v);
42}
43
44void lh5801_cpu_device::lh5801_adr(PAIR *reg)
45{
46   reg->b.l=lh5801_add_generic(reg->b.l,m_a,0);
47   if (m_t&C) {
48      reg->b.h++;
49   }
50}
51
52void lh5801_cpu_device::lh5801_sbc(UINT8 data)
53{
54   m_a=lh5801_add_generic(m_a,data^0xff,m_t&C);
55}
56
57void lh5801_cpu_device::lh5801_cpa(UINT8 a, UINT8 b)
58{
59   lh5801_add_generic(a, b^0xff, 1);
60}
61
62UINT8 lh5801_cpu_device::lh5801_decimaladd_generic(int left, int right, int carry)
63{
64   int res=lh5801_add_generic(left, right, carry);
65   UINT8 da;
66
67   //DA values taken from official documentation
68   if (!(m_t&C) && !(m_t&H))
69      da = 0x9a;
70   else if (!(m_t&C) &&  (m_t&H))
71      da = 0xa0;
72   else if ((m_t&C) && !(m_t&H))
73      da = 0xfa;
74   else    //if ((m_t&C) && (m_t&H))
75      da = 0x00;
76
77   return res + da;
78}
79
80void lh5801_cpu_device::lh5801_dca(UINT8 data)
81{
82   m_a += 0x66;    //taken from official documentation
83   m_a=lh5801_decimaladd_generic(m_a, data, m_t&C);
84}
85
86void lh5801_cpu_device::lh5801_dcs(UINT8 data)
87{
88   m_a=lh5801_decimaladd_generic(m_a, data^0xff, m_t&C);
89}
90
91void lh5801_cpu_device::lh5801_and(UINT8 data)
92{
93   m_a&=data;
94   m_t&=~Z;
95   if (!m_a) m_t|=Z;
96}
97
98void lh5801_cpu_device::lh5801_and_mem(address_space &space, int addr, UINT8 data)
99{
100   data&=space.read_byte(addr);
101   m_t&=~Z;
102   if (!data) m_t|=Z;
103   space.write_byte(addr,data);
104}
105
106void lh5801_cpu_device::lh5801_bit(UINT8 a, UINT8 b)
107{
108   m_t&=~Z;
109   if (!(a&b)) m_t|=Z;
110}
111
112void lh5801_cpu_device::lh5801_eor(UINT8 data)
113{
114   m_a^=data;
115   m_t&=~Z;
116   if (!m_a) m_t|=Z;
117}
118
119void lh5801_cpu_device::lh5801_ora(UINT8 data)
120{
121   m_a|=data;
122   m_t&=~Z;
123   if (!m_a) m_t|=Z;
124}
125
126void lh5801_cpu_device::lh5801_ora_mem(address_space &space, int addr, UINT8 data)
127{
128   data|=space.read_byte(addr);
129   m_t&=~Z;
130   if (!data) m_t|=Z;
131   space.write_byte(addr,data);
132}
133
134void lh5801_cpu_device::lh5801_lda(UINT8 data)
135{
136   m_a=data;
137   m_t&=~Z;
138   if (!m_a) m_t|=Z;
139}
140
141void lh5801_cpu_device::lh5801_lde(PAIR *reg)
142{
143   // or z flag depends on reg
144   m_a=m_program->read_byte(reg->w.l--);
145   m_t&=~Z;
146   if (!m_a) m_t|=Z;
147}
148
149void lh5801_cpu_device::lh5801_sde(PAIR *reg)
150{
151   m_program->write_byte(reg->w.l--, m_a);
152}
153
154void lh5801_cpu_device::lh5801_lin(PAIR *reg)
155{
156   // or z flag depends on reg
157   m_a=m_program->read_byte(reg->w.l++);
158   m_t&=~Z;
159   if (!m_a) m_t|=Z;
160}
161
162void lh5801_cpu_device::lh5801_sin(PAIR *reg)
163{
164   m_program->write_byte(reg->w.l++, m_a);
165}
166
167void lh5801_cpu_device::lh5801_dec(UINT8 *adr)
168{
169   *adr=lh5801_add_generic(*adr,0xff,0);
170}
171
172void lh5801_cpu_device::lh5801_inc(UINT8 *adr)
173{
174   *adr=lh5801_add_generic(*adr,1,0);
175}
176
177void lh5801_cpu_device::lh5801_pop()
178{
179   m_a=m_program->read_byte(++S);
180   m_t&=~Z;
181   if (!m_a) m_t|=Z;
182}
183
184void lh5801_cpu_device::lh5801_pop_word(PAIR *reg)
185{
186   reg->b.h=m_program->read_byte(++S);
187   reg->b.l=m_program->read_byte(++S);
188   // z flag?
189}
190
191void lh5801_cpu_device::lh5801_rtn()
192{
193   P=m_program->read_byte(++S)<<8;
194   P|=m_program->read_byte(++S);
195}
196
197void lh5801_cpu_device::lh5801_rti()
198{
199   P=m_program->read_byte(++S)<<8;
200   P|=m_program->read_byte(++S);
201   m_t=m_program->read_byte(++S);
202}
203
204void lh5801_cpu_device::lh5801_push(UINT8 data)
205{
206   m_program->write_byte(S--, data);
207}
208
209void lh5801_cpu_device::lh5801_push_word(UINT16 data)
210{
211   m_program->write_byte(S--, data&0xff);
212   m_program->write_byte(S--, data>>8);
213}
214
215void lh5801_cpu_device::lh5801_jmp(UINT16 adr)
216{
217   P=adr;
218}
219
220void lh5801_cpu_device::lh5801_branch_plus(int doit)
221{
222   UINT8 t=m_direct->read_decrypted_byte(P++);
223   if (doit) {
224      m_icount-=3;
225      P+=t;
226   }
227}
228
229void lh5801_cpu_device::lh5801_branch_minus(int doit)
230{
231   UINT8 t=m_direct->read_decrypted_byte(P++);
232   if (doit) {
233      m_icount-=3;
234      P-=t;
235   }
236}
237
238void lh5801_cpu_device::lh5801_lop()
239{
240   UINT8 t=m_direct->read_decrypted_byte(P++);
241   m_icount-=8;
242   if (UL--) {
243      m_icount-=3;
244      P-=t;
245   }
246}
247
248void lh5801_cpu_device::lh5801_sjp()
249{
250   UINT16 n=lh5801_readop_word();
251   lh5801_push_word(P);
252   P=n;
253}
254
255void lh5801_cpu_device::lh5801_vector(int doit, int nr)
256{
257   if (doit) {
258      lh5801_push_word(P);
259      P=m_program->read_byte(0xff00+nr)<<8;
260      P|=m_program->read_byte(0xff00+nr+1);
261      m_icount-=21-8;
262   }
263   m_t&=~Z; // after the jump!?
264}
265
266void lh5801_cpu_device::lh5801_aex()
267{
268   UINT8 t=m_a;
269   m_a=(t<<4)|(t>>4);
270   // flags?
271}
272
273void lh5801_cpu_device::lh5801_drl(address_space &space, int adr)
274{
275   UINT16 t=m_a|(space.read_byte(adr)<<8);
276
277   m_a=t>>8;
278   space.write_byte(adr,t>>4);
279}
280
281void lh5801_cpu_device::lh5801_drr(address_space &space, int adr)
282{
283   UINT16 t=space.read_byte(adr)|(m_a<<8);
284
285   m_a=t;
286   space.write_byte(adr,t>>4);
287}
288
289void lh5801_cpu_device::lh5801_rol()
290{
291   // maybe use of the adder
292   int n = m_a;
293   m_a = (n<<1) | (m_t&C);
294   // flags cvhz
295   m_t&=~(H|V|Z|C);
296   if (n&0x80) m_t|=C;
297   if (!m_a) m_t|=Z;
298   if (m_a & 0x10) m_t|=H;
299   if ((BIT(n,6) && !BIT(n,7)) || (!BIT(n,6) && BIT(n,7))) m_t|=V;
300}
301
302void lh5801_cpu_device::lh5801_ror()
303{
304   int n = m_a;
305   m_a=(n | ((m_t&C)<<8))>>1;
306   // flags cvhz
307   m_t&=~(H|V|Z|C);
308   if (n&0x01) m_t|=C;
309   if (!m_a) m_t|=Z;
310   if (m_a & 0x08) m_t|=H;
311   if ((BIT(n,0) && BIT(m_a,1)) || (BIT(m_a,0) && BIT(n,1))) m_t|=V;
312}
313
314void lh5801_cpu_device::lh5801_shl()
315{
316   int n = m_a;
317   m_a<<=1;
318   // flags cvhz
319   m_t&=~(H|V|Z|C);
320   if (n&0x80) m_t|=C;
321   if (!m_a) m_t|=Z;
322   if (m_a & 0x10) m_t|=H;
323   if ((BIT(n,6) && !BIT(n,7)) || (!BIT(n,6) && BIT(n,7))) m_t|=V;
324}
325
326void lh5801_cpu_device::lh5801_shr()
327{
328   int n = m_a;
329   m_a>>=1;
330   // flags cvhz
331   m_t&=~(H|V|Z|C);
332   if (n & 0x01) m_t|=C;
333   if (!m_a) m_t|=Z;
334   if (m_a & 0x08) m_t|=H;
335   if ((BIT(n,0) && BIT(m_a,1)) || (BIT(m_a,0) && BIT(n,1))) m_t|=V;
336}
337
338void lh5801_cpu_device::lh5801_am(int value)
339{
340   m_tm=value;
341   // jfkas?jfkl?jkd?
342}
343
344void lh5801_cpu_device::lh5801_ita()
345{
346   m_a=m_in_func();
347   m_t&=~Z;
348   if (!m_a) m_t|=Z;
349}
350
351void lh5801_cpu_device::lh5801_instruction_fd()
352{
353   int oper;
354   int adr;
355
356   oper=m_direct->read_decrypted_byte(P++);
357   switch (oper) {
358   case 0x01: lh5801_sbc(m_io->read_byte(X)); m_icount-=11;break;
359   case 0x03: lh5801_adc(m_io->read_byte(X)); m_icount-=11;break;
360   case 0x05: lh5801_lda(m_io->read_byte(X)); m_icount-=10;break;
361   case 0x07: lh5801_cpa(m_a, m_io->read_byte(X)); m_icount-=11;break;
362   case 0x08: X=X;m_icount-=11;break; //!!!
363   case 0x09: lh5801_and(m_io->read_byte(X)); m_icount-=11;break;
364   case 0x0a: lh5801_pop_word(&m_x); m_icount-=15;break;
365   case 0x0b: lh5801_ora(m_io->read_byte(X)); m_icount-=11;break;
366   case 0x0c: lh5801_dcs(m_io->read_byte(X)); m_icount-=17; break;
367   case 0x0d: lh5801_eor(m_io->read_byte(X)); m_icount-=11;break;
368   case 0x0e: m_io->write_byte(X,m_a); m_icount-=10;break;
369   case 0x0f: lh5801_bit(m_io->read_byte(X),m_a); m_icount-=11;break;
370   case 0x11: lh5801_sbc(m_io->read_byte(Y)); m_icount-=11;break;
371   case 0x13: lh5801_adc(m_io->read_byte(Y)); m_icount-=11;break;
372   case 0x15: lh5801_lda(m_io->read_byte(Y)); m_icount-=10;break;
373   case 0x17: lh5801_cpa(m_a, m_io->read_byte(Y)); m_icount-=11;break;
374   case 0x18: X=Y;m_icount-=11;break;
375   case 0x19: lh5801_and(m_io->read_byte(Y)); m_icount-=11;break;
376   case 0x1a: lh5801_pop_word(&m_y); m_icount-=15;break;
377   case 0x1b: lh5801_ora(m_io->read_byte(Y)); m_icount-=11;break;
378   case 0x1c: lh5801_dcs(m_io->read_byte(Y)); m_icount-=17; break;
379   case 0x1d: lh5801_eor(m_io->read_byte(Y)); m_icount-=11;break;
380   case 0x1e: m_io->write_byte(Y,m_a); m_icount-=10;break;
381   case 0x1f: lh5801_bit(m_io->read_byte(Y),m_a); m_icount-=11;break;
382   case 0x21: lh5801_sbc(m_io->read_byte(U)); m_icount-=11;break;
383   case 0x23: lh5801_adc(m_io->read_byte(U)); m_icount-=11;break;
384   case 0x25: lh5801_lda(m_io->read_byte(U)); m_icount-=10;break;
385   case 0x27: lh5801_cpa(m_a, m_io->read_byte(U)); m_icount-=11;break;
386   case 0x28: X=U;m_icount-=11;break;
387   case 0x29: lh5801_and(m_io->read_byte(U)); m_icount-=11;break;
388   case 0x2a: lh5801_pop_word(&m_u); m_icount-=15;break;
389   case 0x2b: lh5801_ora(m_io->read_byte(U)); m_icount-=11;break;
390   case 0x2c: lh5801_dcs(m_io->read_byte(U)); m_icount-=17; break;
391   case 0x2d: lh5801_eor(m_io->read_byte(U)); m_icount-=11;break;
392   case 0x2e: m_io->write_byte(U,m_a); m_icount-=10;break;
393   case 0x2f: lh5801_bit(m_io->read_byte(U),m_a); m_icount-=11;break;
394   case 0x40: lh5801_inc(&XH);m_icount-=9;break;
395   case 0x42: lh5801_dec(&XH);m_icount-=9;break;
396   case 0x48: X=S;m_icount-=11;break;
397   case 0x49: lh5801_and_mem(*m_io, X, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
398   case 0x4a: X=X;m_icount-=11;break; //!!!
399   case 0x4b: lh5801_ora_mem(*m_io, X, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
400   case 0x4c: m_bf=0;/*off !*/ m_icount-=8;break;
401   case 0x4d: lh5801_bit(m_io->read_byte(X), m_direct->read_decrypted_byte(P++));m_icount-=14;break;
402   case 0x4e: S=X;m_icount-=11;break;
403   case 0x4f: lh5801_add_mem(*m_io, X, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
404   case 0x50: lh5801_inc(&YH);m_icount-=9;break;
405   case 0x52: lh5801_dec(&YH);m_icount-=9;break;
406   case 0x58: X=P;m_icount-=11;break;
407   case 0x59: lh5801_and_mem(*m_io, Y, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
408   case 0x5a: Y=X;m_icount-=11;break;
409   case 0x5b: lh5801_ora_mem(*m_io, Y, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
410   case 0x5d: lh5801_bit(m_io->read_byte(Y), m_direct->read_decrypted_byte(P++));m_icount-=14;break;
411   case 0x5e: lh5801_jmp(X);m_icount-=11;break; // P=X
412   case 0x5f: lh5801_add_mem(*m_io, Y, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
413   case 0x60: lh5801_inc(&UH);m_icount-=9;break;
414   case 0x62: lh5801_dec(&UH);m_icount-=9;break;
415   case 0x69: lh5801_and_mem(*m_io, U, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
416   case 0x6a: U=X;m_icount-=11;break;
417   case 0x6b: lh5801_ora_mem(*m_io, U, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
418   case 0x6d: lh5801_bit(m_io->read_byte(X), m_direct->read_decrypted_byte(P++));m_icount-=14;break;
419   case 0x6f: lh5801_add_mem(*m_io, U, m_direct->read_decrypted_byte(P++)); m_icount-=17;break;
420   case 0x81: m_t|=IE; /*sie !*/m_icount-=8;break;
421   case 0x88: lh5801_push_word(X); m_icount-=14;break;
422   case 0x8a: lh5801_pop(); m_icount-=12; break;
423   case 0x8c: lh5801_dca(m_io->read_byte(X)); m_icount-=19; break;
424   case 0x8e: /*cdv clears internal devider*/m_icount-=8;break;
425   case 0x98: lh5801_push_word(Y); m_icount-=14;break;
426   case 0x9c: lh5801_dca(m_io->read_byte(Y)); m_icount-=19; break;
427   case 0xa1: lh5801_sbc(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
428   case 0xa3: lh5801_adc(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
429   case 0xa5: lh5801_lda(m_io->read_byte(lh5801_readop_word())); m_icount-=16;break;
430   case 0xa7: lh5801_cpa(m_a, m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
431   case 0xa8: lh5801_push_word(U); m_icount-=14;break;
432   case 0xa9: lh5801_and(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
433   case 0xaa: lh5801_lda(m_t); m_icount-=9;break;
434   case 0xab: lh5801_ora(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
435   case 0xac: lh5801_dca(m_io->read_byte(U)); m_icount-=19; break;
436   case 0xad: lh5801_eor(m_io->read_byte(lh5801_readop_word())); m_icount-=17;break;
437   case 0xae: m_io->write_byte(lh5801_readop_word(),m_a); m_icount-=16;break;
438   case 0xaf: lh5801_bit(m_io->read_byte(lh5801_readop_word()),m_a); m_icount-=17;break;
439   case 0xb1: /*hlt*/m_icount-=8;break;
440   case 0xba: lh5801_ita();m_icount-=9;break;
441   case 0xbe: m_t&=~IE; /*rie !*/m_icount-=8;break;
442   case 0xc0: m_dp=0; /*rdp !*/m_icount-=8;break;
443   case 0xc1: m_dp=1; /*sdp !*/m_icount-=8;break;
444   case 0xc8: lh5801_push(m_a); m_icount-=11;break;
445   case 0xca: lh5801_adr(&m_x);m_icount-=11;break;
446   case 0xcc: /*atp sends a to data bus*/m_icount-=9;break;
447   case 0xce: lh5801_am(m_a); m_icount-=9; break;
448   case 0xd3: lh5801_drr(*m_io, X); m_icount-=16; break;
449   case 0xd7: lh5801_drl(*m_io, X); m_icount-=16; break;
450   case 0xda: lh5801_adr(&m_y);m_icount-=11;break;
451   case 0xde: lh5801_am(m_a|0x100); m_icount-=9; break;
452   case 0xea: lh5801_adr(&m_u);m_icount-=11;break;
453   case 0xe9:
454      adr=lh5801_readop_word();
455      lh5801_and_mem(*m_io, adr, m_direct->read_decrypted_byte(P++)); m_icount-=23;
456      break;
457   case 0xeb:
458      adr=lh5801_readop_word();
459      lh5801_ora_mem(*m_io, adr, m_direct->read_decrypted_byte(P++)); m_icount-=23;
460      break;
461   case 0xec: m_t=m_a; m_icount-=9;break;
462   case 0xed:
463      adr=lh5801_readop_word();
464      lh5801_bit(m_io->read_byte(adr), m_direct->read_decrypted_byte(P++));
465      m_icount-=20;break;
466   case 0xef:
467      adr=lh5801_readop_word();
468      lh5801_add_mem(*m_io, adr, m_direct->read_decrypted_byte(P++)); m_icount-=23;
469      break;
470
471   default:
472      logerror("lh5801 illegal opcode at %.4x fd%.2x\n",P-2, oper);
473   }
474}
475
476void lh5801_cpu_device::lh5801_instruction()
477{
478   int oper;
479   int adr;
480
481   oper=m_direct->read_decrypted_byte(P++);
482   switch (oper) {
483   case 0x00: lh5801_sbc(XL); m_icount-=6;break;
484   case 0x01: lh5801_sbc(m_program->read_byte(X)); m_icount-=7;break;
485   case 0x02: lh5801_adc(XL); m_icount-=6;break;
486   case 0x03: lh5801_adc(m_program->read_byte(X)); m_icount-=7;break;
487   case 0x04: lh5801_lda(XL); m_icount-=5;break;
488   case 0x05: lh5801_lda(m_program->read_byte(X)); m_icount-=6;break;
489   case 0x06: lh5801_cpa(m_a, XL); m_icount-=6;break;
490   case 0x07: lh5801_cpa(m_a, m_program->read_byte(X)); m_icount-=7;break;
491   case 0x08: XH=m_a; m_icount-=5; break;
492   case 0x09: lh5801_and(m_program->read_byte(X)); m_icount-=7;break;
493   case 0x0a: XL=m_a; m_icount-=5; break;
494   case 0x0b: lh5801_ora(m_program->read_byte(X)); m_icount-=7;break;
495   case 0x0c: lh5801_dcs(m_program->read_byte(X)); m_icount-=13; break;
496   case 0x0d: lh5801_eor(m_program->read_byte(X)); m_icount-=7;break;
497   case 0x0e: m_program->write_byte(X,m_a); m_icount-=6;break;
498   case 0x0f: lh5801_bit(m_program->read_byte(X),m_a); m_icount-=7;break;
499   case 0x10: lh5801_sbc(YL); m_icount-=6;break;
500   case 0x11: lh5801_sbc(m_program->read_byte(Y)); m_icount-=7;break;
501   case 0x12: lh5801_adc(YL); m_icount-=6;break;
502   case 0x13: lh5801_adc(m_program->read_byte(Y)); m_icount-=7;break;
503   case 0x14: lh5801_lda(YL); m_icount-=5;break;
504   case 0x15: lh5801_lda(m_program->read_byte(Y)); m_icount-=6;break;
505   case 0x16: lh5801_cpa(m_a, YL); m_icount-=6;break;
506   case 0x17: lh5801_cpa(m_a, m_program->read_byte(Y)); m_icount-=7;break;
507   case 0x18: YH=m_a; m_icount-=5; break;
508   case 0x19: lh5801_and(m_program->read_byte(Y)); m_icount-=7;break;
509   case 0x1a: YL=m_a; m_icount-=5; break;
510   case 0x1b: lh5801_ora(m_program->read_byte(Y)); m_icount-=7;break;
511   case 0x1c: lh5801_dcs(m_program->read_byte(Y)); m_icount-=13; break;
512   case 0x1d: lh5801_eor(m_program->read_byte(Y)); m_icount-=7;break;
513   case 0x1e: m_program->write_byte(Y,m_a); m_icount-=6;break;
514   case 0x1f: lh5801_bit(m_program->read_byte(Y),m_a); m_icount-=7;break;
515   case 0x20: lh5801_sbc(UL); m_icount-=6;break;
516   case 0x21: lh5801_sbc(m_program->read_byte(U)); m_icount-=7;break;
517   case 0x22: lh5801_adc(UL); m_icount-=6;break;
518   case 0x23: lh5801_adc(m_program->read_byte(U)); m_icount-=7;break;
519   case 0x24: lh5801_lda(UL); m_icount-=5;break;
520   case 0x25: lh5801_lda(m_program->read_byte(U)); m_icount-=6;break;
521   case 0x26: lh5801_cpa(m_a, UL); m_icount-=6;break;
522   case 0x27: lh5801_cpa(m_a, m_program->read_byte(U)); m_icount-=7;break;
523   case 0x28: UH=m_a; m_icount-=5; break;
524   case 0x29: lh5801_and(m_program->read_byte(U)); m_icount-=7;break;
525   case 0x2a: UL=m_a; m_icount-=5; break;
526   case 0x2b: lh5801_ora(m_program->read_byte(U)); m_icount-=7;break;
527   case 0x2c: lh5801_dcs(m_program->read_byte(U)); m_icount-=13; break;
528   case 0x2d: lh5801_eor(m_program->read_byte(U)); m_icount-=7;break;
529   case 0x2e: m_program->write_byte(U,m_a); m_icount-=6;break;
530   case 0x2f: lh5801_bit(m_program->read_byte(U),m_a); m_icount-=7;break;
531   case 0x38: /*nop*/m_icount-=5;break;
532   case 0x40: lh5801_inc(&XL);m_icount-=5;break;
533   case 0x41: lh5801_sin(&m_x); m_icount-=6;break;
534   case 0x42: lh5801_dec(&XL);m_icount-=5;break;
535   case 0x43: lh5801_sde(&m_x); m_icount-=6;break;
536   case 0x44: X++;m_icount-=5;break;
537   case 0x45: lh5801_lin(&m_x);m_icount-=6;break;
538   case 0x46: X--;m_icount-=5;break;
539   case 0x47: lh5801_lde(&m_x);m_icount-=6;break;
540   case 0x48: XH=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
541   case 0x49: lh5801_and_mem(*m_program, X, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
542   case 0x4a: XL=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
543   case 0x4b: lh5801_ora_mem(*m_program, X, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
544   case 0x4c: lh5801_cpa(XH, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
545   case 0x4d: lh5801_bit(m_program->read_byte(X), m_direct->read_decrypted_byte(P++));m_icount-=10;break;
546   case 0x4e: lh5801_cpa(XL, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
547   case 0x4f: lh5801_add_mem(*m_program, X, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
548   case 0x50: lh5801_inc(&YL);m_icount-=5;break;
549   case 0x51: lh5801_sin(&m_y); m_icount-=6;break;
550   case 0x52: lh5801_dec(&YL);m_icount-=5;break;
551   case 0x53: lh5801_sde(&m_y); m_icount-=6;break;
552   case 0x54: Y++;m_icount-=5;break;
553   case 0x55: lh5801_lin(&m_y);m_icount-=6;break;
554   case 0x56: Y--;m_icount-=5;break;
555   case 0x57: lh5801_lde(&m_y);m_icount-=6;break;
556   case 0x58: YH=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
557   case 0x59: lh5801_and_mem(*m_program, Y, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
558   case 0x5a: YL=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
559   case 0x5b: lh5801_ora_mem(*m_program, Y, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
560   case 0x5c: lh5801_cpa(YH, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
561   case 0x5d: lh5801_bit(m_program->read_byte(Y), m_direct->read_decrypted_byte(P++));m_icount-=10;break;
562   case 0x5e: lh5801_cpa(YL, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
563   case 0x5f: lh5801_add_mem(*m_program, Y, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
564   case 0x60: lh5801_inc(&UL);m_icount-=5;break;
565   case 0x61: lh5801_sin(&m_u); m_icount-=6;break;
566   case 0x62: lh5801_dec(&UL);m_icount-=5;break;
567   case 0x63: lh5801_sde(&m_u); m_icount-=6;break;
568   case 0x64: U++;m_icount-=5;break;
569   case 0x65: lh5801_lin(&m_u);m_icount-=6;break;
570   case 0x66: U--;m_icount-=5;break;
571   case 0x67: lh5801_lde(&m_u);m_icount-=6;break;
572   case 0x68: UH=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
573   case 0x69: lh5801_and_mem(*m_program, U, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
574   case 0x6a: UL=m_direct->read_decrypted_byte(P++);m_icount-=6;break;
575   case 0x6b: lh5801_ora_mem(*m_program, U, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
576   case 0x6c: lh5801_cpa(UH, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
577   case 0x6d: lh5801_bit(m_program->read_byte(U), m_direct->read_decrypted_byte(P++));m_icount-=10;break;
578   case 0x6e: lh5801_cpa(UL, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
579   case 0x6f: lh5801_add_mem(*m_program, U, m_direct->read_decrypted_byte(P++)); m_icount-=13;break;
580   case 0x80: lh5801_sbc(XH); m_icount-=6;break;
581   case 0x81: lh5801_branch_plus(!(m_t&C)); m_icount-=8; break;
582   case 0x82: lh5801_adc(XH); m_icount-=6;break;
583   case 0x83: lh5801_branch_plus(m_t&C); m_icount-=8; break;
584   case 0x84: lh5801_lda(XH); m_icount-=5;break;
585   case 0x85: lh5801_branch_plus(!(m_t&H)); m_icount-=8; break;
586   case 0x86: lh5801_cpa(m_a, XH); m_icount-=6;break;
587   case 0x87: lh5801_branch_plus(m_t&H); m_icount-=8; break;
588   case 0x88: lh5801_lop(); break;
589   case 0x89: lh5801_branch_plus(!(m_t&Z)); m_icount-=8; break;
590   case 0x8a: lh5801_rti(); m_icount-=14; break;
591   case 0x8b: lh5801_branch_plus(m_t&Z); m_icount-=8; break;
592   case 0x8c: lh5801_dca(m_program->read_byte(X)); m_icount-=15; break;
593   case 0x8d: lh5801_branch_plus(!(m_t&V)); m_icount-=8; break;
594   case 0x8e: lh5801_branch_plus(1); m_icount-=5; break;
595   case 0x8f: lh5801_branch_plus(m_t&V); m_icount-=8; break;
596   case 0x90: lh5801_sbc(YH); m_icount-=6;break;
597   case 0x91: lh5801_branch_minus(!(m_t&C)); m_icount-=8; break;
598   case 0x92: lh5801_adc(YH); m_icount-=6;break;
599   case 0x93: lh5801_branch_minus(m_t&C); m_icount-=8; break;
600   case 0x94: lh5801_lda(YH); m_icount-=5;break;
601   case 0x95: lh5801_branch_minus(!(m_t&H)); m_icount-=8; break;
602   case 0x96: lh5801_cpa(m_a, YH); m_icount-=6;break;
603   case 0x97: lh5801_branch_minus(m_t&H); m_icount-=8; break;
604   case 0x99: lh5801_branch_minus(!(m_t&Z)); m_icount-=8; break;
605   case 0x9a: lh5801_rtn(); m_icount-=11; break;
606   case 0x9b: lh5801_branch_minus(m_t&Z); m_icount-=8; break;
607   case 0x9c: lh5801_dca(m_program->read_byte(Y)); m_icount-=15; break;
608   case 0x9d: lh5801_branch_minus(!(m_t&V)); m_icount-=8; break;
609   case 0x9e: lh5801_branch_minus(1); m_icount-=6; break;
610   case 0x9f: lh5801_branch_minus(m_t&V); m_icount-=8; break;
611   case 0xa0: lh5801_sbc(UH); m_icount-=6;break;
612   case 0xa2: lh5801_adc(UH); m_icount-=6;break;
613   case 0xa1: lh5801_sbc(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
614   case 0xa3: lh5801_adc(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
615   case 0xa4: lh5801_lda(UH); m_icount-=5;break;
616   case 0xa5: lh5801_lda(m_program->read_byte(lh5801_readop_word())); m_icount-=12;break;
617   case 0xa6: lh5801_cpa(m_a, UH); m_icount-=6;break;
618   case 0xa7: lh5801_cpa(m_a, m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
619   case 0xa8: m_pv=1;/*spv!*/ m_icount-=4; break;
620   case 0xa9: lh5801_and(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
621   case 0xaa: S=lh5801_readop_word();m_icount-=6;break;
622   case 0xab: lh5801_ora(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
623   case 0xac: lh5801_dca(m_program->read_byte(U)); m_icount-=15; break;
624   case 0xad: lh5801_eor(m_program->read_byte(lh5801_readop_word())); m_icount-=13;break;
625   case 0xae: m_program->write_byte(lh5801_readop_word(),m_a); m_icount-=12;break;
626   case 0xaf: lh5801_bit(m_program->read_byte(lh5801_readop_word()),m_a); m_icount-=13;break;
627   case 0xb1: lh5801_sbc(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
628   case 0xb3: lh5801_adc(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
629   case 0xb5: lh5801_lda(m_direct->read_decrypted_byte(P++)); m_icount-=6;break;
630   case 0xb7: lh5801_cpa(m_a, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
631   case 0xb8: m_pv=0;/*rpv!*/ m_icount-=4; break;
632   case 0xb9: lh5801_and(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
633   case 0xba: lh5801_jmp(lh5801_readop_word()); m_icount-=12;break;
634   case 0xbb: lh5801_ora(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
635   case 0xbd: lh5801_eor(m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
636   case 0xbe: lh5801_sjp(); m_icount-=19; break;
637   case 0xbf: lh5801_bit(m_a, m_direct->read_decrypted_byte(P++));m_icount-=7;break;
638   case 0xc1: lh5801_vector(!(m_t&C), m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
639   case 0xc3: lh5801_vector(m_t&C, m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
640   case 0xc5: lh5801_vector(!(m_t&H), m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
641   case 0xc7: lh5801_vector(m_t&H, m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
642   case 0xc9: lh5801_vector(!(m_t&Z), m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
643   case 0xcb: lh5801_vector(m_t&Z, m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
644   case 0xcd: lh5801_vector(1, m_direct->read_decrypted_byte(P++)); m_icount-=7;break;
645   case 0xcf: lh5801_vector(m_t&V, m_direct->read_decrypted_byte(P++)); m_icount-=8;break;
646   case 0xd1: lh5801_ror(); m_icount-=6; break;
647   case 0xd3: lh5801_drr(*m_program, X); m_icount-=12; break;
648   case 0xd5: lh5801_shr(); m_icount-=6; break;
649   case 0xd7: lh5801_drl(*m_program, X); m_icount-=12; break;
650   case 0xd9: lh5801_shl(); m_icount-=6; break;
651   case 0xdb: lh5801_rol(); m_icount-=6; break;
652   case 0xdd: lh5801_inc(&m_a);m_icount-=5;break;
653   case 0xdf: lh5801_dec(&m_a);m_icount-=5;break;
654   case 0xe1: m_pu=1;/*spu!*/ m_icount-=4; break;
655   case 0xe3: m_pu=0;/*rpu!*/ m_icount-=4; break;
656   case 0xe9:
657      adr=lh5801_readop_word();lh5801_and_mem(*m_program, adr, m_direct->read_decrypted_byte(P++));
658      m_icount-=19;break;
659   case 0xeb:
660      adr=lh5801_readop_word();lh5801_ora_mem(*m_program, adr, m_direct->read_decrypted_byte(P++));
661      m_icount-=19;break;
662   case 0xed:
663      adr=lh5801_readop_word();lh5801_bit(m_program->read_byte(adr), m_direct->read_decrypted_byte(P++));
664      m_icount-=16;break;
665   case 0xef:
666      adr=lh5801_readop_word();
667      lh5801_add_mem(*m_program, adr, m_direct->read_decrypted_byte(P++)); m_icount-=19;
668      break;
669   case 0xf1: lh5801_aex(); m_icount-=6; break;
670   case 0xf5: m_program->write_byte(Y++, m_program->read_byte(X++)); m_icount-=7; break; //tin
671   case 0xf7: lh5801_cpa(m_a, m_program->read_byte(X++));m_icount-=7; break; //cin
672   case 0xf9: m_t&=~C;m_icount-=4;break;
673   case 0xfb: m_t|=C;m_icount-=4;break;
674   case 0xfd: lh5801_instruction_fd();break;
675   case 0xc0: case 0xc2: case 0xc4: case 0xc6:
676   case 0xc8: case 0xca: case 0xcc: case 0xce:
677   case 0xd0: case 0xd2: case 0xd4: case 0xd6:
678   case 0xd8: case 0xda: case 0xdc: case 0xde:
679   case 0xe0: case 0xe2: case 0xe4: case 0xe6:
680   case 0xe8: case 0xea: case 0xec: case 0xee:
681   case 0xf0: case 0xf2: case 0xf4: case 0xf6:
682      lh5801_vector(1, oper);m_icount-=4;break;
683   default:
684      logerror("lh5801 illegal opcode at %.4x %.2x\n",P-1, oper);
685   }
686
687}
Property changes on: trunk/src/emu/cpu/lh5801/5801tbl.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/m68000/m68kfpu.c
r28738r28739
1#include <math.h>
2
3#define FPCC_N          0x08000000
4#define FPCC_Z          0x04000000
5#define FPCC_I          0x02000000
6#define FPCC_NAN        0x01000000
7
8#define FPES_OE         0x00002000
9#define FPAE_IOP        0x00000080
10
11#define DOUBLE_INFINITY                 U64(0x7ff0000000000000)
12#define DOUBLE_EXPONENT                 U64(0x7ff0000000000000)
13#define DOUBLE_MANTISSA                 U64(0x000fffffffffffff)
14
15extern flag floatx80_is_nan( floatx80 a );
16
17// masks for packed dwords, positive k-factor
18static const UINT32 pkmask2[18] =
19{
20   0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
21   0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
22   0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
23   0xffffffff, 0xffffffff, 0xffffffff
24};
25
26static const UINT32 pkmask3[18] =
27{
28   0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29   0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
30   0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
31};
32
33INLINE double fx80_to_double(floatx80 fx)
34{
35   UINT64 d;
36   double *foo;
37
38   foo = (double *)&d;
39
40   d = floatx80_to_float64(fx);
41
42   return *foo;
43}
44
45INLINE floatx80 double_to_fx80(double in)
46{
47   UINT64 *d;
48
49   d = (UINT64 *)&in;
50
51   return float64_to_floatx80(*d);
52}
53
54INLINE floatx80 load_extended_float80(m68000_base_device *m68k, UINT32 ea)
55{
56   UINT32 d1,d2;
57   UINT16 d3;
58   floatx80 fp;
59
60   d3 = m68ki_read_16(m68k, ea);
61   d1 = m68ki_read_32(m68k, ea+4);
62   d2 = m68ki_read_32(m68k, ea+8);
63
64   fp.high = d3;
65   fp.low = ((UINT64)d1<<32) | (d2 & 0xffffffff);
66
67   return fp;
68}
69
70INLINE void store_extended_float80(m68000_base_device *m68k, UINT32 ea, floatx80 fpr)
71{
72   m68ki_write_16(m68k, ea+0, fpr.high);
73   m68ki_write_16(m68k, ea+2, 0);
74   m68ki_write_32(m68k, ea+4, (fpr.low>>32)&0xffffffff);
75   m68ki_write_32(m68k, ea+8, fpr.low&0xffffffff);
76}
77
78INLINE floatx80 load_pack_float80(m68000_base_device *m68k, UINT32 ea)
79{
80   UINT32 dw1, dw2, dw3;
81   floatx80 result;
82   double tmp;
83   char str[128], *ch;
84
85   dw1 = m68ki_read_32(m68k, ea);
86   dw2 = m68ki_read_32(m68k, ea+4);
87   dw3 = m68ki_read_32(m68k, ea+8);
88
89   ch = &str[0];
90   if (dw1 & 0x80000000)   // mantissa sign
91   {
92      *ch++ = '-';
93   }
94   *ch++ = (char)((dw1 & 0xf) + '0');
95   *ch++ = '.';
96   *ch++ = (char)(((dw2 >> 28) & 0xf) + '0');
97   *ch++ = (char)(((dw2 >> 24) & 0xf) + '0');
98   *ch++ = (char)(((dw2 >> 20) & 0xf) + '0');
99   *ch++ = (char)(((dw2 >> 16) & 0xf) + '0');
100   *ch++ = (char)(((dw2 >> 12) & 0xf) + '0');
101   *ch++ = (char)(((dw2 >> 8)  & 0xf) + '0');
102   *ch++ = (char)(((dw2 >> 4)  & 0xf) + '0');
103   *ch++ = (char)(((dw2 >> 0)  & 0xf) + '0');
104   *ch++ = (char)(((dw3 >> 28) & 0xf) + '0');
105   *ch++ = (char)(((dw3 >> 24) & 0xf) + '0');
106   *ch++ = (char)(((dw3 >> 20) & 0xf) + '0');
107   *ch++ = (char)(((dw3 >> 16) & 0xf) + '0');
108   *ch++ = (char)(((dw3 >> 12) & 0xf) + '0');
109   *ch++ = (char)(((dw3 >> 8)  & 0xf) + '0');
110   *ch++ = (char)(((dw3 >> 4)  & 0xf) + '0');
111   *ch++ = (char)(((dw3 >> 0)  & 0xf) + '0');
112   *ch++ = 'E';
113   if (dw1 & 0x40000000)   // exponent sign
114   {
115      *ch++ = '-';
116   }
117   *ch++ = (char)(((dw1 >> 24) & 0xf) + '0');
118   *ch++ = (char)(((dw1 >> 20) & 0xf) + '0');
119   *ch++ = (char)(((dw1 >> 16) & 0xf) + '0');
120   *ch = '\0';
121
122   sscanf(str, "%le", &tmp);
123
124   result = double_to_fx80(tmp);
125
126   return result;
127}
128
129INLINE void store_pack_float80(m68000_base_device *m68k, UINT32 ea, int k, floatx80 fpr)
130{
131   UINT32 dw1, dw2, dw3;
132   char str[128], *ch;
133   int i, j, exp;
134
135   dw1 = dw2 = dw3 = 0;
136   ch = &str[0];
137
138   sprintf(str, "%.16e", fx80_to_double(fpr));
139
140   if (*ch == '-')
141   {
142      ch++;
143      dw1 = 0x80000000;
144   }
145
146   if (*ch == '+')
147   {
148      ch++;
149   }
150
151   dw1 |= (*ch++ - '0');
152
153   if (*ch == '.')
154   {
155      ch++;
156   }
157
158   // handle negative k-factor here
159   if ((k <= 0) && (k >= -13))
160   {
161      exp = 0;
162      for (i = 0; i < 3; i++)
163      {
164         if (ch[18+i] >= '0' && ch[18+i] <= '9')
165         {
166            exp = (exp << 4) | (ch[18+i] - '0');
167         }
168      }
169
170      if (ch[17] == '-')
171      {
172         exp = -exp;
173      }
174
175      k = -k;
176      // last digit is (k + exponent - 1)
177      k += (exp - 1);
178
179      // round up the last significant mantissa digit
180      if (ch[k+1] >= '5')
181      {
182         ch[k]++;
183      }
184
185      // zero out the rest of the mantissa digits
186      for (j = (k+1); j < 16; j++)
187      {
188         ch[j] = '0';
189      }
190
191      // now zero out K to avoid tripping the positive K detection below
192      k = 0;
193   }
194
195   // crack 8 digits of the mantissa
196   for (i = 0; i < 8; i++)
197   {
198      dw2 <<= 4;
199      if (*ch >= '0' && *ch <= '9')
200      {
201         dw2 |= *ch++ - '0';
202      }
203   }
204
205   // next 8 digits of the mantissa
206   for (i = 0; i < 8; i++)
207   {
208      dw3 <<= 4;
209      if (*ch >= '0' && *ch <= '9')
210      dw3 |= *ch++ - '0';
211   }
212
213   // handle masking if k is positive
214   if (k >= 1)
215   {
216      if (k <= 17)
217      {
218         dw2 &= pkmask2[k];
219         dw3 &= pkmask3[k];
220      }
221      else
222      {
223         dw2 &= pkmask2[17];
224         dw3 &= pkmask3[17];
225//          m68k->fpcr |=  (need to set OPERR bit)
226      }
227   }
228
229   // finally, crack the exponent
230   if (*ch == 'e' || *ch == 'E')
231   {
232      ch++;
233      if (*ch == '-')
234      {
235         ch++;
236         dw1 |= 0x40000000;
237      }
238
239      if (*ch == '+')
240      {
241         ch++;
242      }
243
244      j = 0;
245      for (i = 0; i < 3; i++)
246      {
247         if (*ch >= '0' && *ch <= '9')
248         {
249            j = (j << 4) | (*ch++ - '0');
250         }
251      }
252
253      dw1 |= (j << 16);
254   }
255
256   m68ki_write_32(m68k, ea, dw1);
257   m68ki_write_32(m68k, ea+4, dw2);
258   m68ki_write_32(m68k, ea+8, dw3);
259}
260
261INLINE void SET_CONDITION_CODES(m68000_base_device *m68k, floatx80 reg)
262{
263//  UINT64 *regi;
264
265//  regi = (UINT64 *)&reg;
266
267   REG_FPSR(m68k) &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
268
269   // sign flag
270   if (reg.high & 0x8000)
271   {
272      REG_FPSR(m68k) |= FPCC_N;
273   }
274
275   // zero flag
276   if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
277   {
278      REG_FPSR(m68k) |= FPCC_Z;
279   }
280
281   // infinity flag
282   if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
283   {
284      REG_FPSR(m68k) |= FPCC_I;
285   }
286
287   // NaN flag
288   if (floatx80_is_nan(reg))
289   {
290      REG_FPSR(m68k) |= FPCC_NAN;
291   }
292}
293
294INLINE int TEST_CONDITION(m68000_base_device *m68k, int condition)
295{
296   int n = (REG_FPSR(m68k) & FPCC_N) != 0;
297   int z = (REG_FPSR(m68k) & FPCC_Z) != 0;
298   int nan = (REG_FPSR(m68k) & FPCC_NAN) != 0;
299   int r = 0;
300   switch (condition)
301   {
302      case 0x10:
303      case 0x00:      return 0;                   // False
304
305      case 0x11:
306      case 0x01:      return (z);                 // Equal
307
308      case 0x12:
309      case 0x02:      return (!(nan || z || n));          // Greater Than
310
311      case 0x13:
312      case 0x03:      return (z || !(nan || n));          // Greater or Equal
313
314      case 0x14:
315      case 0x04:      return (n && !(nan || z));          // Less Than
316
317      case 0x15:
318      case 0x05:      return (z || (n && !nan));          // Less Than or Equal
319
320      case 0x16:
321      case 0x06:      return !nan && !z;
322
323      case 0x17:
324      case 0x07:      return !nan;
325
326      case 0x18:
327      case 0x08:      return nan;
328
329      case 0x19:
330      case 0x09:      return nan || z;
331
332      case 0x1a:
333      case 0x0a:      return (nan || !(n || z));          // Not Less Than or Equal
334
335      case 0x1b:
336      case 0x0b:      return (nan || z || !n);            // Not Less Than
337
338      case 0x1c:
339      case 0x0c:      return (nan || (n && !z));          // Not Greater or Equal Than
340
341      case 0x1d:
342      case 0x0d:      return (nan || z || n);             // Not Greater Than
343
344      case 0x1e:
345      case 0x0e:      return (!z);                    // Not Equal
346
347      case 0x1f:
348      case 0x0f:      return 1;                   // True
349
350      default:        fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
351   }
352
353   return r;
354}
355
356static UINT8 READ_EA_8(m68000_base_device *m68k, int ea)
357{
358   int mode = (ea >> 3) & 0x7;
359   int reg = (ea & 0x7);
360
361   switch (mode)
362   {
363      case 0:     // Dn
364      {
365         return REG_D(m68k)[reg];
366      }
367      case 2:     // (An)
368      {
369         UINT32 ea = REG_A(m68k)[reg];
370         return m68ki_read_8(m68k, ea);
371      }
372      case 3:     // (An)+
373      {
374         UINT32 ea = EA_AY_PI_8(m68k);
375         return m68ki_read_8(m68k, ea);
376      }
377      case 4:     // -(An)
378      {
379         UINT32 ea = EA_AY_PD_8(m68k);
380         return m68ki_read_8(m68k, ea);
381      }
382      case 5:     // (d16, An)
383      {
384         UINT32 ea = EA_AY_DI_8(m68k);
385         return m68ki_read_8(m68k, ea);
386      }
387      case 6:     // (An) + (Xn) + d8
388      {
389         UINT32 ea = EA_AY_IX_8(m68k);
390         return m68ki_read_8(m68k, ea);
391      }
392      case 7:
393      {
394         switch (reg)
395         {
396            case 0:     // (xxx).W
397            {
398               UINT32 ea = (UINT32)OPER_I_16(m68k);
399               return m68ki_read_8(m68k, ea);
400            }
401            case 1:     // (xxx).L
402            {
403               UINT32 d1 = OPER_I_16(m68k);
404               UINT32 d2 = OPER_I_16(m68k);
405               UINT32 ea = (d1 << 16) | d2;
406               return m68ki_read_8(m68k, ea);
407            }
408            case 2:     // (d16, PC)
409            {
410               UINT32 ea = EA_PCDI_8(m68k);
411               return m68ki_read_8(m68k, ea);
412            }
413            case 3:     // (PC) + (Xn) + d8
414            {
415               UINT32 ea =  EA_PCIX_8(m68k);
416               return m68ki_read_8(m68k, ea);
417            }
418            case 4:     // #<data>
419            {
420               return  OPER_I_8(m68k);
421            }
422            default:    fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
423         }
424         break;
425      }
426      default:    fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
427   }
428
429   return 0;
430}
431
432static UINT16 READ_EA_16(m68000_base_device *m68k, int ea)
433{
434   int mode = (ea >> 3) & 0x7;
435   int reg = (ea & 0x7);
436
437   switch (mode)
438   {
439      case 0:     // Dn
440      {
441         return (UINT16)(REG_D(m68k)[reg]);
442      }
443      case 2:     // (An)
444      {
445         UINT32 ea = REG_A(m68k)[reg];
446         return m68ki_read_16(m68k, ea);
447      }
448      case 3:     // (An)+
449      {
450         UINT32 ea = EA_AY_PI_16(m68k);
451         return m68ki_read_16(m68k, ea);
452      }
453      case 4:     // -(An)
454      {
455         UINT32 ea = EA_AY_PD_16(m68k);
456         return m68ki_read_16(m68k, ea);
457      }
458      case 5:     // (d16, An)
459      {
460         UINT32 ea = EA_AY_DI_16(m68k);
461         return m68ki_read_16(m68k, ea);
462      }
463      case 6:     // (An) + (Xn) + d8
464      {
465         UINT32 ea = EA_AY_IX_16(m68k);
466         return m68ki_read_16(m68k, ea);
467      }
468      case 7:
469      {
470         switch (reg)
471         {
472            case 0:     // (xxx).W
473            {
474               UINT32 ea = (UINT32)OPER_I_16(m68k);
475               return m68ki_read_16(m68k, ea);
476            }
477            case 1:     // (xxx).L
478            {
479               UINT32 d1 = OPER_I_16(m68k);
480               UINT32 d2 = OPER_I_16(m68k);
481               UINT32 ea = (d1 << 16) | d2;
482               return m68ki_read_16(m68k, ea);
483            }
484            case 2:     // (d16, PC)
485            {
486               UINT32 ea = EA_PCDI_16(m68k);
487               return m68ki_read_16(m68k, ea);
488            }
489            case 3:     // (PC) + (Xn) + d8
490            {
491               UINT32 ea =  EA_PCIX_16(m68k);
492               return m68ki_read_16(m68k, ea);
493            }
494            case 4:     // #<data>
495            {
496               return OPER_I_16(m68k);
497            }
498
499            default:    fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
500         }
501         break;
502      }
503      default:    fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
504   }
505
506   return 0;
507}
508
509static UINT32 READ_EA_32(m68000_base_device *m68k, int ea)
510{
511   int mode = (ea >> 3) & 0x7;
512   int reg = (ea & 0x7);
513
514   switch (mode)
515   {
516      case 0:     // Dn
517      {
518         return REG_D(m68k)[reg];
519      }
520      case 2:     // (An)
521      {
522         UINT32 ea = REG_A(m68k)[reg];
523         return m68ki_read_32(m68k, ea);
524      }
525      case 3:     // (An)+
526      {
527         UINT32 ea = EA_AY_PI_32(m68k);
528         return m68ki_read_32(m68k, ea);
529      }
530      case 4:     // -(An)
531      {
532         UINT32 ea = EA_AY_PD_32(m68k);
533         return m68ki_read_32(m68k, ea);
534      }
535      case 5:     // (d16, An)
536      {
537         UINT32 ea = EA_AY_DI_32(m68k);
538         return m68ki_read_32(m68k, ea);
539      }
540      case 6:     // (An) + (Xn) + d8
541      {
542         UINT32 ea = EA_AY_IX_32(m68k);
543         return m68ki_read_32(m68k, ea);
544      }
545      case 7:
546      {
547         switch (reg)
548         {
549            case 0:     // (xxx).W
550            {
551               UINT32 ea = (UINT32)OPER_I_16(m68k);
552               return m68ki_read_32(m68k, ea);
553            }
554            case 1:     // (xxx).L
555            {
556               UINT32 d1 = OPER_I_16(m68k);
557               UINT32 d2 = OPER_I_16(m68k);
558               UINT32 ea = (d1 << 16) | d2;
559               return m68ki_read_32(m68k, ea);
560            }
561            case 2:     // (d16, PC)
562            {
563               UINT32 ea = EA_PCDI_32(m68k);
564               return m68ki_read_32(m68k, ea);
565            }
566            case 3:     // (PC) + (Xn) + d8
567            {
568               UINT32 ea =  EA_PCIX_32(m68k);
569               return m68ki_read_32(m68k, ea);
570            }
571            case 4:     // #<data>
572            {
573               return  OPER_I_32(m68k);
574            }
575            default:    fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
576         }
577         break;
578      }
579      default:    fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
580   }
581   return 0;
582}
583
584static UINT64 READ_EA_64(m68000_base_device *m68k, int ea)
585{
586   int mode = (ea >> 3) & 0x7;
587   int reg = (ea & 0x7);
588   UINT32 h1, h2;
589
590   switch (mode)
591   {
592      case 2:     // (An)
593      {
594         UINT32 ea = REG_A(m68k)[reg];
595         h1 = m68ki_read_32(m68k, ea+0);
596         h2 = m68ki_read_32(m68k, ea+4);
597         return  (UINT64)(h1) << 32 | (UINT64)(h2);
598      }
599      case 3:     // (An)+
600      {
601         UINT32 ea = REG_A(m68k)[reg];
602         REG_A(m68k)[reg] += 8;
603         h1 = m68ki_read_32(m68k, ea+0);
604         h2 = m68ki_read_32(m68k, ea+4);
605         return  (UINT64)(h1) << 32 | (UINT64)(h2);
606      }
607      case 4:     // -(An)
608      {
609         UINT32 ea = REG_A(m68k)[reg]-8;
610         REG_A(m68k)[reg] -= 8;
611         h1 = m68ki_read_32(m68k, ea+0);
612         h2 = m68ki_read_32(m68k, ea+4);
613         return  (UINT64)(h1) << 32 | (UINT64)(h2);
614      }
615      case 5:     // (d16, An)
616      {
617         UINT32 ea = EA_AY_DI_32(m68k);
618         h1 = m68ki_read_32(m68k, ea+0);
619         h2 = m68ki_read_32(m68k, ea+4);
620         return  (UINT64)(h1) << 32 | (UINT64)(h2);
621      }
622      case 6:     // (An) + (Xn) + d8
623      {
624         UINT32 ea = EA_AY_IX_32(m68k);
625         h1 = m68ki_read_32(m68k, ea+0);
626         h2 = m68ki_read_32(m68k, ea+4);
627         return  (UINT64)(h1) << 32 | (UINT64)(h2);
628      }
629      case 7:
630      {
631         switch (reg)
632         {
633            case 1:     // (xxx).L
634            {
635               UINT32 d1 = OPER_I_16(m68k);
636               UINT32 d2 = OPER_I_16(m68k);
637               UINT32 ea = (d1 << 16) | d2;
638               return (UINT64)(m68ki_read_32(m68k, ea)) << 32 | (UINT64)(m68ki_read_32(m68k, ea+4));
639            }
640            case 3:     // (PC) + (Xn) + d8
641            {
642               UINT32 ea =  EA_PCIX_32(m68k);
643               h1 = m68ki_read_32(m68k, ea+0);
644               h2 = m68ki_read_32(m68k, ea+4);
645               return  (UINT64)(h1) << 32 | (UINT64)(h2);
646            }
647            case 4:     // #<data>
648            {
649               h1 = OPER_I_32(m68k);
650               h2 = OPER_I_32(m68k);
651               return  (UINT64)(h1) << 32 | (UINT64)(h2);
652            }
653            case 2:     // (d16, PC)
654            {
655               UINT32 ea = EA_PCDI_32(m68k);
656               h1 = m68ki_read_32(m68k, ea+0);
657               h2 = m68ki_read_32(m68k, ea+4);
658               return  (UINT64)(h1) << 32 | (UINT64)(h2);
659            }
660            default:    fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
661         }
662         break;
663      }
664      default:    fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
665   }
666
667   return 0;
668}
669
670
671static floatx80 READ_EA_FPE(m68000_base_device *m68k, int ea)
672{
673   floatx80 fpr;
674   int mode = (ea >> 3) & 0x7;
675   int reg = (ea & 0x7);
676
677   switch (mode)
678   {
679      case 2:     // (An)
680      {
681         UINT32 ea = REG_A(m68k)[reg];
682         fpr = load_extended_float80(m68k, ea);
683         break;
684      }
685
686      case 3:     // (An)+
687      {
688         UINT32 ea = REG_A(m68k)[reg];
689         REG_A(m68k)[reg] += 12;
690         fpr = load_extended_float80(m68k, ea);
691         break;
692      }
693      case 4:     // -(An)
694      {
695         UINT32 ea = REG_A(m68k)[reg]-12;
696         REG_A(m68k)[reg] -= 12;
697         fpr = load_extended_float80(m68k, ea);
698         break;
699      }
700      case 5:     // (d16, An)
701      {
702         // FIXME: will fail for fmovem
703         UINT32 ea = EA_AY_DI_32(m68k);
704         fpr = load_extended_float80(m68k, ea);
705         break;
706      }
707      case 6:     // (An) + (Xn) + d8
708      {
709         // FIXME: will fail for fmovem
710         UINT32 ea = EA_AY_IX_32(m68k);
711         fpr = load_extended_float80(m68k, ea);
712         break;
713      }
714
715      case 7: // extended modes
716      {
717         switch (reg)
718         {
719            case 2: // (d16, PC)
720               {
721                  UINT32 ea = EA_PCDI_32(m68k);
722                  fpr = load_extended_float80(m68k, ea);
723               }
724               break;
725
726            case 3: // (d16,PC,Dx.w)
727               {
728                  UINT32 ea = EA_PCIX_32(m68k);
729                  fpr = load_extended_float80(m68k, ea);
730               }
731               break;
732
733            default:
734               fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
735               break;
736         }
737      }
738      break;
739
740      default:    fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k)); break;
741   }
742
743   return fpr;
744}
745
746static floatx80 READ_EA_PACK(m68000_base_device *m68k, int ea)
747{
748   floatx80 fpr;
749   int mode = (ea >> 3) & 0x7;
750   int reg = (ea & 0x7);
751
752   switch (mode)
753   {
754      case 2:     // (An)
755      {
756         UINT32 ea = REG_A(m68k)[reg];
757         fpr = load_pack_float80(m68k, ea);
758         break;
759      }
760
761      case 3:     // (An)+
762      {
763         UINT32 ea = REG_A(m68k)[reg];
764         REG_A(m68k)[reg] += 12;
765         fpr = load_pack_float80(m68k, ea);
766         break;
767      }
768
769      case 7: // extended modes
770      {
771         switch (reg)
772         {
773            case 3: // (d16,PC,Dx.w)
774               {
775                  UINT32 ea = EA_PCIX_32(m68k);
776                  fpr = load_pack_float80(m68k, ea);
777               }
778               break;
779
780            default:
781               fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
782               break;
783         }
784      }
785      break;
786
787      default:    fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k)); break;
788   }
789
790   return fpr;
791}
792
793static void WRITE_EA_8(m68000_base_device *m68k, int ea, UINT8 data)
794{
795   int mode = (ea >> 3) & 0x7;
796   int reg = (ea & 0x7);
797
798   switch (mode)
799   {
800      case 0:     // Dn
801      {
802         REG_D(m68k)[reg] = data;
803         break;
804      }
805      case 2:     // (An)
806      {
807         UINT32 ea = REG_A(m68k)[reg];
808         m68ki_write_8(m68k, ea, data);
809         break;
810      }
811      case 3:     // (An)+
812      {
813         UINT32 ea = EA_AY_PI_8(m68k);
814         m68ki_write_8(m68k, ea, data);
815         break;
816      }
817      case 4:     // -(An)
818      {
819         UINT32 ea = EA_AY_PD_8(m68k);
820         m68ki_write_8(m68k, ea, data);
821         break;
822      }
823      case 5:     // (d16, An)
824      {
825         UINT32 ea = EA_AY_DI_8(m68k);
826         m68ki_write_8(m68k, ea, data);
827         break;
828      }
829      case 6:     // (An) + (Xn) + d8
830      {
831         UINT32 ea = EA_AY_IX_8(m68k);
832         m68ki_write_8(m68k, ea, data);
833         break;
834      }
835      case 7:
836      {
837         switch (reg)
838         {
839            case 1:     // (xxx).B
840            {
841               UINT32 d1 = OPER_I_16(m68k);
842               UINT32 d2 = OPER_I_16(m68k);
843               UINT32 ea = (d1 << 16) | d2;
844               m68ki_write_8(m68k, ea, data);
845               break;
846            }
847            case 2:     // (d16, PC)
848            {
849               UINT32 ea = EA_PCDI_16(m68k);
850               m68ki_write_8(m68k, ea, data);
851               break;
852            }
853            default:    fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
854         }
855         break;
856      }
857      default:    fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC(m68k));
858   }
859}
860
861static void WRITE_EA_16(m68000_base_device *m68k, int ea, UINT16 data)
862{
863   int mode = (ea >> 3) & 0x7;
864   int reg = (ea & 0x7);
865
866   switch (mode)
867   {
868      case 0:     // Dn
869      {
870         REG_D(m68k)[reg] = data;
871         break;
872      }
873      case 2:     // (An)
874      {
875         UINT32 ea = REG_A(m68k)[reg];
876         m68ki_write_16(m68k, ea, data);
877         break;
878      }
879      case 3:     // (An)+
880      {
881         UINT32 ea = EA_AY_PI_16(m68k);
882         m68ki_write_16(m68k, ea, data);
883         break;
884      }
885      case 4:     // -(An)
886      {
887         UINT32 ea = EA_AY_PD_16(m68k);
888         m68ki_write_16(m68k, ea, data);
889         break;
890      }
891      case 5:     // (d16, An)
892      {
893         UINT32 ea = EA_AY_DI_16(m68k);
894         m68ki_write_16(m68k, ea, data);
895         break;
896      }
897      case 6:     // (An) + (Xn) + d8
898      {
899         UINT32 ea = EA_AY_IX_16(m68k);
900         m68ki_write_16(m68k, ea, data);
901         break;
902      }
903      case 7:
904      {
905         switch (reg)
906         {
907            case 1:     // (xxx).W
908            {
909               UINT32 d1 = OPER_I_16(m68k);
910               UINT32 d2 = OPER_I_16(m68k);
911               UINT32 ea = (d1 << 16) | d2;
912               m68ki_write_16(m68k, ea, data);
913               break;
914            }
915            case 2:     // (d16, PC)
916            {
917               UINT32 ea = EA_PCDI_16(m68k);
918               m68ki_write_16(m68k, ea, data);
919               break;
920            }
921            default:    fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
922         }
923         break;
924      }
925      default:    fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC(m68k));
926   }
927}
928
929static void WRITE_EA_32(m68000_base_device *m68k, int ea, UINT32 data)
930{
931   int mode = (ea >> 3) & 0x7;
932   int reg = (ea & 0x7);
933
934   switch (mode)
935   {
936      case 0:     // Dn
937      {
938         REG_D(m68k)[reg] = data;
939         break;
940      }
941      case 1:     // An
942      {
943         REG_A(m68k)[reg] = data;
944         break;
945      }
946      case 2:     // (An)
947      {
948         UINT32 ea = REG_A(m68k)[reg];
949         m68ki_write_32(m68k, ea, data);
950         break;
951      }
952      case 3:     // (An)+
953      {
954         UINT32 ea = EA_AY_PI_32(m68k);
955         m68ki_write_32(m68k, ea, data);
956         break;
957      }
958      case 4:     // -(An)
959      {
960         UINT32 ea = EA_AY_PD_32(m68k);
961         m68ki_write_32(m68k, ea, data);
962         break;
963      }
964      case 5:     // (d16, An)
965      {
966         UINT32 ea = EA_AY_DI_32(m68k);
967         m68ki_write_32(m68k, ea, data);
968         break;
969      }
970      case 6:     // (An) + (Xn) + d8
971      {
972         UINT32 ea = EA_AY_IX_32(m68k);
973         m68ki_write_32(m68k, ea, data);
974         break;
975      }
976      case 7:
977      {
978         switch (reg)
979         {
980            case 1:     // (xxx).L
981            {
982               UINT32 d1 = OPER_I_16(m68k);
983               UINT32 d2 = OPER_I_16(m68k);
984               UINT32 ea = (d1 << 16) | d2;
985               m68ki_write_32(m68k, ea, data);
986               break;
987            }
988            case 2:     // (d16, PC)
989            {
990               UINT32 ea = EA_PCDI_32(m68k);
991               m68ki_write_32(m68k, ea, data);
992               break;
993            }
994            default:    fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
995         }
996         break;
997      }
998      default:    fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC(m68k));
999   }
1000}
1001
1002static void WRITE_EA_64(m68000_base_device *m68k, int ea, UINT64 data)
1003{
1004   int mode = (ea >> 3) & 0x7;
1005   int reg = (ea & 0x7);
1006
1007   switch (mode)
1008   {
1009      case 2:     // (An)
1010      {
1011         UINT32 ea = REG_A(m68k)[reg];
1012         m68ki_write_32(m68k, ea, (UINT32)(data >> 32));
1013         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1014         break;
1015      }
1016      case 3:     // (An)+
1017      {
1018         UINT32 ea = REG_A(m68k)[reg];
1019         REG_A(m68k)[reg] += 8;
1020         m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1021         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1022         break;
1023      }
1024      case 4:     // -(An)
1025      {
1026         UINT32 ea;
1027         REG_A(m68k)[reg] -= 8;
1028         ea = REG_A(m68k)[reg];
1029         m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1030         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1031         break;
1032      }
1033      case 5:     // (d16, An)
1034      {
1035         UINT32 ea = EA_AY_DI_32(m68k);
1036         m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1037         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1038         break;
1039      }
1040      case 6:     // (An) + (Xn) + d8
1041      {
1042         UINT32 ea = EA_AY_IX_32(m68k);
1043         m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1044         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1045         break;
1046      }
1047      case 7:
1048      {
1049         switch (reg)
1050         {
1051            case 1:     // (xxx).L
1052            {
1053               UINT32 d1 = OPER_I_16(m68k);
1054               UINT32 d2 = OPER_I_16(m68k);
1055               UINT32 ea = (d1 << 16) | d2;
1056               m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1057               m68ki_write_32(m68k, ea+4, (UINT32)(data));
1058               break;
1059            }
1060            case 2:     // (d16, PC)
1061            {
1062               UINT32 ea = EA_PCDI_32(m68k);
1063               m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1064               m68ki_write_32(m68k, ea+4, (UINT32)(data));
1065               break;
1066            }
1067            default:    fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
1068         }
1069         break;
1070      }
1071      default:    fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (UINT32)(data >> 32), (UINT32)(data), REG_PC(m68k));
1072   }
1073}
1074
1075static void WRITE_EA_FPE(m68000_base_device *m68k, int ea, floatx80 fpr)
1076{
1077   int mode = (ea >> 3) & 0x7;
1078   int reg = (ea & 0x7);
1079
1080   switch (mode)
1081   {
1082      case 2:     // (An)
1083      {
1084         UINT32 ea;
1085         ea = REG_A(m68k)[reg];
1086         store_extended_float80(m68k, ea, fpr);
1087         break;
1088      }
1089
1090      case 3:     // (An)+
1091      {
1092         UINT32 ea;
1093         ea = REG_A(m68k)[reg];
1094         store_extended_float80(m68k, ea, fpr);
1095         REG_A(m68k)[reg] += 12;
1096         break;
1097      }
1098
1099      case 4:     // -(An)
1100      {
1101         UINT32 ea;
1102         REG_A(m68k)[reg] -= 12;
1103         ea = REG_A(m68k)[reg];
1104         store_extended_float80(m68k, ea, fpr);
1105         break;
1106      }
1107
1108      case 7:
1109      {
1110         switch (reg)
1111         {
1112            default:    fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
1113         }
1114      }
1115      default:    fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
1116   }
1117}
1118
1119static void WRITE_EA_PACK(m68000_base_device *m68k, int ea, int k, floatx80 fpr)
1120{
1121   int mode = (ea >> 3) & 0x7;
1122   int reg = (ea & 0x7);
1123
1124   switch (mode)
1125   {
1126      case 2:     // (An)
1127      {
1128         UINT32 ea;
1129         ea = REG_A(m68k)[reg];
1130         store_pack_float80(m68k, ea, k, fpr);
1131         break;
1132      }
1133
1134      case 3:     // (An)+
1135      {
1136         UINT32 ea;
1137         ea = REG_A(m68k)[reg];
1138         store_pack_float80(m68k, ea, k, fpr);
1139         REG_A(m68k)[reg] += 12;
1140         break;
1141      }
1142
1143      case 4:     // -(An)
1144      {
1145         UINT32 ea;
1146         REG_A(m68k)[reg] -= 12;
1147         ea = REG_A(m68k)[reg];
1148         store_pack_float80(m68k, ea, k, fpr);
1149         break;
1150      }
1151
1152      case 7:
1153      {
1154         switch (reg)
1155         {
1156            default:    fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
1157         }
1158      }
1159      default:    fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
1160   }
1161}
1162
1163static void fpgen_rm_reg(m68000_base_device *m68k, UINT16 w2)
1164{
1165   int ea = m68k->ir & 0x3f;
1166   int rm = (w2 >> 14) & 0x1;
1167   int src = (w2 >> 10) & 0x7;
1168   int dst = (w2 >>  7) & 0x7;
1169   int opmode = w2 & 0x7f;
1170   floatx80 source;
1171
1172   // fmovecr #$f, fp0 f200 5c0f
1173
1174   if (rm)
1175   {
1176      switch (src)
1177      {
1178         case 0:     // Long-Word Integer
1179         {
1180            INT32 d = READ_EA_32(m68k, ea);
1181            source = int32_to_floatx80(d);
1182            break;
1183         }
1184         case 1:     // Single-precision Real
1185         {
1186            UINT32 d = READ_EA_32(m68k, ea);
1187            source = float32_to_floatx80(d);
1188            break;
1189         }
1190         case 2:     // Extended-precision Real
1191         {
1192            source = READ_EA_FPE(m68k, ea);
1193            break;
1194         }
1195         case 3:     // Packed-decimal Real
1196         {
1197            source = READ_EA_PACK(m68k, ea);
1198            break;
1199         }
1200         case 4:     // Word Integer
1201         {
1202            INT16 d = READ_EA_16(m68k, ea);
1203            source = int32_to_floatx80((INT32)d);
1204            break;
1205         }
1206         case 5:     // Double-precision Real
1207         {
1208            UINT64 d = READ_EA_64(m68k, ea);
1209
1210            source = float64_to_floatx80(d);
1211            break;
1212         }
1213         case 6:     // Byte Integer
1214         {
1215            INT8 d = READ_EA_8(m68k, ea);
1216            source = int32_to_floatx80((INT32)d);
1217            break;
1218         }
1219         case 7:     // FMOVECR load from constant ROM
1220         {
1221            switch (w2 & 0x7f)
1222            {
1223               case 0x0:   // Pi
1224                  source.high = 0x4000;
1225                  source.low = U64(0xc90fdaa22168c235);
1226                  break;
1227
1228               case 0xb:   // log10(2)
1229                  source.high = 0x3ffd;
1230                  source.low = U64(0x9a209a84fbcff798);
1231                  break;
1232
1233               case 0xc:   // e
1234                  source.high = 0x4000;
1235                  source.low = U64(0xadf85458a2bb4a9b);
1236                  break;
1237
1238               case 0xd:   // log2(e)
1239                  source.high = 0x3fff;
1240                  source.low = U64(0xb8aa3b295c17f0bc);
1241                  break;
1242
1243               case 0xe:   // log10(e)
1244                  source.high = 0x3ffd;
1245                  source.low = U64(0xde5bd8a937287195);
1246                  break;
1247
1248               case 0xf:   // 0.0
1249                  source = int32_to_floatx80((INT32)0);
1250                  break;
1251
1252               case 0x30:  // ln(2)
1253                  source.high = 0x3ffe;
1254                  source.low = U64(0xb17217f7d1cf79ac);
1255                  break;
1256
1257               case 0x31:  // ln(10)
1258                  source.high = 0x4000;
1259                  source.low = U64(0x935d8dddaaa8ac17);
1260                  break;
1261
1262               case 0x32:  // 1 (or 100?  manuals are unclear, but 1 would make more sense)
1263                  source = int32_to_floatx80((INT32)1);
1264                  break;
1265
1266               case 0x33:  // 10^1
1267                  source = int32_to_floatx80((INT32)10);
1268                  break;
1269
1270               case 0x34:  // 10^2
1271                  source = int32_to_floatx80((INT32)10*10);
1272                  break;
1273
1274               case 0x35:  // 10^4
1275                  source = int32_to_floatx80((INT32)1000*10);
1276                  break;
1277
1278               case 0x36:  // 1.0e8
1279                  source = int32_to_floatx80((INT32)10000000*10);
1280                  break;
1281
1282               case 0x37:  // 1.0e16 - can't get the right precision from INT32 so go "direct" with constants from h/w
1283                  source.high = 0x4034;
1284                  source.low = U64(0x8e1bc9bf04000000);
1285                  break;
1286
1287               case 0x38:  // 1.0e32
1288                  source.high = 0x4069;
1289                  source.low = U64(0x9dc5ada82b70b59e);
1290                  break;
1291
1292               case 0x39:  // 1.0e64
1293                  source.high = 0x40d3;
1294                  source.low = U64(0xc2781f49ffcfa6d5);
1295                  break;
1296
1297               case 0x3a:  // 1.0e128
1298                  source.high = 0x41a8;
1299                  source.low = U64(0x93ba47c980e98ce0);
1300                  break;
1301
1302               case 0x3b:  // 1.0e256
1303                  source.high = 0x4351;
1304                  source.low = U64(0xaa7eebfb9df9de8e);
1305                  break;
1306
1307               case 0x3c:  // 1.0e512
1308                  source.high = 0x46a3;
1309                  source.low = U64(0xe319a0aea60e91c7);
1310                  break;
1311
1312               case 0x3d:  // 1.0e1024
1313                  source.high = 0x4d48;
1314                  source.low = U64(0xc976758681750c17);
1315                  break;
1316
1317               case 0x3e:  // 1.0e2048
1318                  source.high = 0x5a92;
1319                  source.low = U64(0x9e8b3b5dc53d5de5);
1320                  break;
1321
1322               case 0x3f:  // 1.0e4096
1323                  source.high = 0x7525;
1324                  source.low = U64(0xc46052028a20979b);
1325                  break;
1326
1327               default:
1328                  fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC(m68k)-4);
1329                  break;
1330            }
1331
1332            // handle it right here, the usual opmode bits aren't valid in the FMOVECR case
1333            REG_FP(m68k)[dst] = source;
1334            m68k->remaining_cycles -= 4;
1335            return;
1336         }
1337         default:    fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC(m68k)-4);
1338      }
1339   }
1340   else
1341   {
1342      source = REG_FP(m68k)[src];
1343   }
1344
1345
1346
1347   switch (opmode)
1348   {
1349      case 0x00:      // FMOVE
1350      {
1351         REG_FP(m68k)[dst] = source;
1352         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1353         m68k->remaining_cycles -= 4;
1354         break;
1355      }
1356      case 0x01:      // FINT
1357      {
1358         INT32 temp;
1359         temp = floatx80_to_int32(source);
1360         REG_FP(m68k)[dst] = int32_to_floatx80(temp);
1361         break;
1362      }
1363      case 0x03:      // FINTRZ
1364      {
1365         INT32 temp;
1366         temp = floatx80_to_int32_round_to_zero(source);
1367         REG_FP(m68k)[dst] = int32_to_floatx80(temp);
1368         break;
1369      }
1370      case 0x04:      // FSQRT
1371      {
1372         REG_FP(m68k)[dst] = floatx80_sqrt(source);
1373         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1374         m68k->remaining_cycles -= 109;
1375         break;
1376      }
1377      case 0x06:      // FLOGNP1
1378      {
1379         REG_FP(m68k)[dst] = floatx80_flognp1 (source);
1380         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1381         m68k->remaining_cycles -= 594; // for MC68881
1382         break;
1383      }
1384      case 0x0e:      // FSIN
1385      {
1386         REG_FP(m68k)[dst] = source;
1387         floatx80_fsin(REG_FP(m68k)[dst]);
1388         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1389         m68k->remaining_cycles -= 75;
1390         break;
1391      }
1392      case 0x0f:      // FTAN
1393      {
1394         REG_FP(m68k)[dst] = source;
1395         floatx80_ftan(REG_FP(m68k)[dst]);
1396         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1397         m68k->remaining_cycles -= 75;
1398         break;
1399      }
1400      case 0x14:      // FLOGN
1401      {
1402         REG_FP(m68k)[dst] = floatx80_flogn (source);
1403         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1404         m68k->remaining_cycles -= 548; // for MC68881
1405         break;
1406      }
1407      case 0x15:      // FLOG10
1408      {
1409         REG_FP(m68k)[dst] = floatx80_flog10 (source);
1410         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1411         m68k->remaining_cycles -= 604; // for MC68881
1412         break;
1413      }
1414      case 0x16:      // FLOG2
1415      {
1416         REG_FP(m68k)[dst] = floatx80_flog2 (source);
1417         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1418         m68k->remaining_cycles -= 604; // for MC68881
1419         break;
1420      }
1421      case 0x18:      // FABS
1422      {
1423         REG_FP(m68k)[dst] = source;
1424         REG_FP(m68k)[dst].high &= 0x7fff;
1425         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1426         m68k->remaining_cycles -= 3;
1427         break;
1428      }
1429      case 0x1a:      // FNEG
1430      {
1431         REG_FP(m68k)[dst] = source;
1432         REG_FP(m68k)[dst].high ^= 0x8000;
1433         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1434         m68k->remaining_cycles -= 3;
1435         break;
1436      }
1437      case 0x1d:      // FCOS
1438      {
1439         REG_FP(m68k)[dst] = source;
1440         floatx80_fcos(REG_FP(m68k)[dst]);
1441         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1442         m68k->remaining_cycles -= 75;
1443         break;
1444      }
1445      case 0x1e:      // FGETEXP
1446      {
1447         INT16 temp2;
1448
1449         temp2 = source.high;    // get the exponent
1450         temp2 -= 0x3fff;    // take off the bias
1451         REG_FP(m68k)[dst] = double_to_fx80((double)temp2);
1452         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1453         m68k->remaining_cycles -= 6;
1454         break;
1455      }
1456      case 0x20:      // FDIV
1457      {
1458         REG_FP(m68k)[dst] = floatx80_div(REG_FP(m68k)[dst], source);
1459         m68k->remaining_cycles -= 43;
1460         break;
1461      }
1462      case 0x22:      // FADD
1463      {
1464         REG_FP(m68k)[dst] = floatx80_add(REG_FP(m68k)[dst], source);
1465         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1466         m68k->remaining_cycles -= 9;
1467         break;
1468      }
1469      case 0x23:      // FMUL
1470      {
1471         REG_FP(m68k)[dst] = floatx80_mul(REG_FP(m68k)[dst], source);
1472         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1473         m68k->remaining_cycles -= 11;
1474         break;
1475      }
1476      case 0x24:      // FSGLDIV
1477      {
1478         float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
1479         float32 b = floatx80_to_float32( source );
1480         REG_FP(m68k)[dst] = float32_to_floatx80( float32_div(a, b) );
1481         m68k->remaining_cycles -= 43; //  // ? (value is from FDIV)
1482         break;
1483      }
1484      case 0x25:      // FREM
1485      {
1486         REG_FP(m68k)[dst] = floatx80_rem(REG_FP(m68k)[dst], source);
1487         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1488         m68k->remaining_cycles -= 43;   // guess
1489         break;
1490      }
1491      case 0x26:      // FSCALE
1492      {
1493         REG_FP(m68k)[dst] = floatx80_scale(REG_FP(m68k)[dst], source);
1494         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1495         m68k->remaining_cycles -= 46;   // (better?) guess
1496         break;
1497      }
1498      case 0x27:      // FSGLMUL
1499      {
1500         float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
1501         float32 b = floatx80_to_float32( source );
1502         REG_FP(m68k)[dst] = float32_to_floatx80( float32_mul(a, b) );
1503         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1504         m68k->remaining_cycles -= 11; // ? (value is from FMUL)
1505         break;
1506      }
1507      case 0x28:      // FSUB
1508      {
1509         REG_FP(m68k)[dst] = floatx80_sub(REG_FP(m68k)[dst], source);
1510         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1511         m68k->remaining_cycles -= 9;
1512         break;
1513      }
1514      case 0x38:      // FCMP
1515      {
1516         floatx80 res;
1517         res = floatx80_sub(REG_FP(m68k)[dst], source);
1518         SET_CONDITION_CODES(m68k, res);
1519         m68k->remaining_cycles -= 7;
1520         break;
1521      }
1522      case 0x3a:      // FTST
1523      {
1524         floatx80 res;
1525         res = source;
1526         SET_CONDITION_CODES(m68k, res);
1527         m68k->remaining_cycles -= 7;
1528         break;
1529      }
1530
1531      default:    fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PPC(m68k));
1532   }
1533}
1534
1535static void fmove_reg_mem(m68000_base_device *m68k, UINT16 w2)
1536{
1537   int ea = m68k->ir & 0x3f;
1538   int src = (w2 >>  7) & 0x7;
1539   int dst = (w2 >> 10) & 0x7;
1540   int k = (w2 & 0x7f);
1541
1542   switch (dst)
1543   {
1544      case 0:     // Long-Word Integer
1545      {
1546         INT32 d = (INT32)floatx80_to_int32(REG_FP(m68k)[src]);
1547         WRITE_EA_32(m68k, ea, d);
1548         break;
1549      }
1550      case 1:     // Single-precision Real
1551      {
1552         UINT32 d = floatx80_to_float32(REG_FP(m68k)[src]);
1553         WRITE_EA_32(m68k, ea, d);
1554         break;
1555      }
1556      case 2:     // Extended-precision Real
1557      {
1558         WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[src]);
1559         break;
1560      }
1561      case 3:     // Packed-decimal Real with Static K-factor
1562      {
1563         // sign-extend k
1564         k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
1565         WRITE_EA_PACK(m68k, ea, k, REG_FP(m68k)[src]);
1566         break;
1567      }
1568      case 4:     // Word Integer
1569      {
1570         int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
1571         if (value > 0x7fff || value < -0x8000 )
1572         {
1573            REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
1574         }
1575         WRITE_EA_16(m68k, ea, (INT16)value);
1576         break;
1577      }
1578      case 5:     // Double-precision Real
1579      {
1580         UINT64 d;
1581
1582         d = floatx80_to_float64(REG_FP(m68k)[src]);
1583
1584         WRITE_EA_64(m68k, ea, d);
1585         break;
1586      }
1587      case 6:     // Byte Integer
1588      {
1589         int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
1590         if (value > 127 || value < -128)
1591         {
1592            REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
1593         }
1594         WRITE_EA_8(m68k, ea, (INT8) value);
1595         break;
1596      }
1597      case 7:     // Packed-decimal Real with Dynamic K-factor
1598      {
1599         WRITE_EA_PACK(m68k, ea, REG_D(m68k)[k>>4], REG_FP(m68k)[src]);
1600         break;
1601      }
1602   }
1603
1604   m68k->remaining_cycles -= 12;
1605}
1606
1607static void fmove_fpcr(m68000_base_device *m68k, UINT16 w2)
1608{
1609   int ea = m68k->ir & 0x3f;
1610   int dir = (w2 >> 13) & 0x1;
1611   int regsel = (w2 >> 10) & 0x7;
1612   int mode = (ea >> 3) & 0x7;
1613
1614   if ((mode == 5) || (mode == 6))
1615   {
1616      UINT32 address = 0xffffffff;    // force a bus error if this doesn't get assigned
1617
1618      if (mode == 5)
1619      {
1620         address = EA_AY_DI_32(m68k);
1621      }
1622      else if (mode == 6)
1623      {
1624         address = EA_AY_IX_32(m68k);
1625      }
1626
1627      if (dir)    // From system control reg to <ea>
1628      {
1629         if (regsel & 4) { m68ki_write_32(m68k, address, REG_FPCR(m68k)); address += 4; }
1630         if (regsel & 2) { m68ki_write_32(m68k, address, REG_FPSR(m68k)); address += 4; }
1631         if (regsel & 1) { m68ki_write_32(m68k, address, REG_FPIAR(m68k)); address += 4; }
1632      }
1633      else        // From <ea> to system control reg
1634      {
1635         if (regsel & 4) { REG_FPCR(m68k) = m68ki_read_32(m68k, address); address += 4; }
1636         if (regsel & 2) { REG_FPSR(m68k) = m68ki_read_32(m68k, address); address += 4; }
1637         if (regsel & 1) { REG_FPIAR(m68k) = m68ki_read_32(m68k, address); address += 4; }
1638      }
1639   }
1640   else
1641   {
1642      if (dir)    // From system control reg to <ea>
1643      {
1644         if (regsel & 4) WRITE_EA_32(m68k, ea, REG_FPCR(m68k));
1645         if (regsel & 2) WRITE_EA_32(m68k, ea, REG_FPSR(m68k));
1646         if (regsel & 1) WRITE_EA_32(m68k, ea, REG_FPIAR(m68k));
1647      }
1648      else        // From <ea> to system control reg
1649      {
1650         if (regsel & 4) REG_FPCR(m68k) = READ_EA_32(m68k, ea);
1651         if (regsel & 2) REG_FPSR(m68k) = READ_EA_32(m68k, ea);
1652         if (regsel & 1) REG_FPIAR(m68k) = READ_EA_32(m68k, ea);
1653      }
1654   }
1655
1656#if 0
1657   // FIXME: (2011-12-18 ost)
1658   // rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
1659   // but:  with this code on Apollo the following programs in /systest/fptest will fail:
1660   // 1. Single Precision Whetstone will return wrong results never the less
1661   // 2. Vector Test will fault with 00040004: reference to illegal address
1662
1663   if ((regsel & 4) && dir == 0)
1664   {
1665      int rnd = (REG_FPCR(m68k) >> 4) & 3;
1666      int prec = (REG_FPCR(m68k) >> 6) & 3;
1667
1668      logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", REG_FPCR(m68k), prec, rnd);
1669
1670#ifdef FLOATX80
1671      switch (prec)
1672      {
1673      case 0: // Extend (X)
1674         floatx80_rounding_precision = 80;
1675         break;
1676      case 1: // Single (S)
1677         floatx80_rounding_precision = 32;
1678         break;
1679      case 2: // Double (D)
1680         floatx80_rounding_precision = 64;
1681         break;
1682      case 3: // Undefined
1683         floatx80_rounding_precision = 80;
1684         break;
1685      }
1686#endif
1687
1688      switch (rnd)
1689      {
1690      case 0: // To Nearest (RN)
1691         float_rounding_mode = float_round_nearest_even;
1692         break;
1693      case 1: // To Zero (RZ)
1694         float_rounding_mode = float_round_to_zero;
1695         break;
1696      case 2: // To Minus Infinitiy (RM)
1697         float_rounding_mode = float_round_down;
1698         break;
1699      case 3: // To Plus Infinitiy (RP)
1700         float_rounding_mode = float_round_up;
1701         break;
1702      }
1703   }
1704#endif
1705
1706   m68k->remaining_cycles -= 10;
1707}
1708
1709static void fmovem(m68000_base_device *m68k, UINT16 w2)
1710{
1711   int i;
1712   int ea = m68k->ir & 0x3f;
1713   int dir = (w2 >> 13) & 0x1;
1714   int mode = (w2 >> 11) & 0x3;
1715   int reglist = w2 & 0xff;
1716
1717   UINT32 mem_addr = 0;
1718   switch (ea >> 3)
1719   {
1720      case 5:     // (d16, An)
1721         mem_addr= EA_AY_DI_32(m68k);
1722         break;
1723      case 6:     // (An) + (Xn) + d8
1724         mem_addr= EA_AY_IX_32(m68k);
1725         break;
1726   }
1727
1728   if (dir)    // From FP regs to mem
1729   {
1730      switch (mode)
1731      {
1732         case 1: // Dynamic register list, postincrement or control addressing mode.
1733            // FIXME: not really tested, but seems to work
1734            reglist = REG_D(m68k)[(reglist >> 4) & 7];
1735
1736         case 0:     // Static register list, predecrement or control addressing mode
1737         {
1738            for (i=0; i < 8; i++)
1739            {
1740               if (reglist & (1 << i))
1741               {
1742                  switch (ea >> 3)
1743                  {
1744                     case 5:     // (d16, An)
1745                     case 6:     // (An) + (Xn) + d8
1746                        store_extended_float80(m68k, mem_addr, REG_FP(m68k)[i]);
1747                        mem_addr += 12;
1748                        break;
1749                     default:
1750                        WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[i]);
1751                        break;
1752                  }
1753
1754                  m68k->remaining_cycles -= 2;
1755               }
1756            }
1757            break;
1758         }
1759
1760         case 2:     // Static register list, postdecrement or control addressing mode
1761         {
1762            for (i=0; i < 8; i++)
1763            {
1764               if (reglist & (1 << i))
1765               {
1766                  switch (ea >> 3)
1767                  {
1768                     case 5:     // (d16, An)
1769                     case 6:     // (An) + (Xn) + d8
1770                        store_extended_float80(m68k, mem_addr, REG_FP(m68k)[7-i]);
1771                        mem_addr += 12;
1772                        break;
1773                     default:
1774                        WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[7-i]);
1775                        break;
1776                  }
1777
1778                  m68k->remaining_cycles -= 2;
1779               }
1780            }
1781            break;
1782         }
1783
1784         default:    fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC(m68k)-4);
1785      }
1786   }
1787   else        // From mem to FP regs
1788   {
1789      switch (mode)
1790      {
1791         case 3: // Dynamic register list, predecrement addressing mode.
1792            // FIXME: not really tested, but seems to work
1793            reglist = REG_D(m68k)[(reglist >> 4) & 7];
1794
1795         case 2:     // Static register list, postincrement or control addressing mode
1796         {
1797            for (i=0; i < 8; i++)
1798            {
1799               if (reglist & (1 << i))
1800               {
1801                  switch (ea >> 3)
1802                  {
1803                     case 5:     // (d16, An)
1804                     case 6:     // (An) + (Xn) + d8
1805                        REG_FP(m68k)[7-i] = load_extended_float80(m68k, mem_addr);
1806                        mem_addr += 12;
1807                        break;
1808                     default:
1809                        REG_FP(m68k)[7-i] = READ_EA_FPE(m68k, ea);
1810                        break;
1811                  }
1812                  m68k->remaining_cycles -= 2;
1813               }
1814            }
1815            break;
1816         }
1817
1818         default:    fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC(m68k)-4);
1819      }
1820   }
1821}
1822
1823static void fscc(m68000_base_device *m68k)
1824{
1825   int ea = m68k->ir & 0x3f;
1826   int condition = (INT16)(OPER_I_16(m68k));
1827
1828   WRITE_EA_8(m68k, ea, TEST_CONDITION(m68k, condition) ? 0xff : 0);
1829   m68k->remaining_cycles -= 7; // ???
1830}
1831
1832static void fbcc16(m68000_base_device *m68k)
1833{
1834   INT32 offset;
1835   int condition = m68k->ir & 0x3f;
1836
1837   offset = (INT16)(OPER_I_16(m68k));
1838
1839   // TODO: condition and jump!!!
1840   if (TEST_CONDITION(m68k, condition))
1841   {
1842      m68ki_trace_t0(m68k);              /* auto-disable (see m68kcpu.h) */
1843      m68ki_branch_16(m68k, offset-2);
1844   }
1845
1846   m68k->remaining_cycles -= 7;
1847}
1848
1849static void fbcc32(m68000_base_device *m68k)
1850{
1851   INT32 offset;
1852   int condition = m68k->ir & 0x3f;
1853
1854   offset = OPER_I_32(m68k);
1855
1856   // TODO: condition and jump!!!
1857   if (TEST_CONDITION(m68k, condition))
1858   {
1859      m68ki_trace_t0(m68k);              /* auto-disable (see m68kcpu.h) */
1860      m68ki_branch_32(m68k, offset-4);
1861   }
1862
1863   m68k->remaining_cycles -= 7;
1864}
1865
1866
1867void m68040_fpu_op0(m68000_base_device *m68k)
1868{
1869   m68k->fpu_just_reset = 0;
1870
1871   switch ((m68k->ir >> 6) & 0x3)
1872   {
1873      case 0:
1874      {
1875         UINT16 w2 = OPER_I_16(m68k);
1876         switch ((w2 >> 13) & 0x7)
1877         {
1878            case 0x0:   // FPU ALU FP, FP
1879            case 0x2:   // FPU ALU ea, FP
1880            {
1881               fpgen_rm_reg(m68k, w2);
1882               break;
1883            }
1884
1885            case 0x3:   // FMOVE FP, ea
1886            {
1887               fmove_reg_mem(m68k, w2);
1888               break;
1889            }
1890
1891            case 0x4:   // FMOVEM ea, FPCR
1892            case 0x5:   // FMOVEM FPCR, ea
1893            {
1894               fmove_fpcr(m68k, w2);
1895               break;
1896            }
1897
1898            case 0x6:   // FMOVEM ea, list
1899            case 0x7:   // FMOVEM list, ea
1900            {
1901               fmovem(m68k, w2);
1902               break;
1903            }
1904
1905            default:    fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC(m68k)-4);
1906         }
1907         break;
1908      }
1909
1910      case 1:     // FBcc disp16
1911      {
1912         switch ((m68k->ir >> 3) & 0x7) {
1913         case 1: // FDBcc
1914            // TODO:
1915            break;
1916         default: // FScc (?)
1917            fscc(m68k);
1918            return;
1919         }
1920         fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (m68k->ir >> 6) & 0x3, (m68k->ir >> 3) & 0x7, REG_PPC(m68k));
1921      }
1922
1923      case 2:     // FBcc disp16
1924      {
1925         fbcc16(m68k);
1926         break;
1927      }
1928      case 3:     // FBcc disp32
1929      {
1930         fbcc32(m68k);
1931         break;
1932      }
1933
1934      default:    fatalerror("M68kFPU: unimplemented main op %d\n", (m68k->ir >> 6)   & 0x3);
1935   }
1936}
1937
1938static int perform_fsave(m68000_base_device *m68k, UINT32 addr, int inc)
1939{
1940   if(m68k->cpu_type & CPU_TYPE_040)
1941   {
1942      if(inc)
1943      {
1944         m68ki_write_32(m68k, addr, 0x41000000);
1945         return 4;
1946      }
1947      else
1948      {
1949         m68ki_write_32(m68k, addr-4, 0x41000000);
1950         return -4;
1951      }
1952   }
1953
1954   if (inc)
1955   {
1956      // 68881 IDLE, version 0x1f
1957      m68ki_write_32(m68k, addr, 0x1f180000);
1958      m68ki_write_32(m68k, addr+4, 0);
1959      m68ki_write_32(m68k, addr+8, 0);
1960      m68ki_write_32(m68k, addr+12, 0);
1961      m68ki_write_32(m68k, addr+16, 0);
1962      m68ki_write_32(m68k, addr+20, 0);
1963      m68ki_write_32(m68k, addr+24, 0x70000000);
1964      return 7*4;
1965   }
1966   else
1967   {
1968      m68ki_write_32(m68k, addr-4, 0x70000000);
1969      m68ki_write_32(m68k, addr-8, 0);
1970      m68ki_write_32(m68k, addr-12, 0);
1971      m68ki_write_32(m68k, addr-16, 0);
1972      m68ki_write_32(m68k, addr-20, 0);
1973      m68ki_write_32(m68k, addr-24, 0);
1974      m68ki_write_32(m68k, addr-28, 0x1f180000);
1975      return -7*4;
1976   }
1977}
1978
1979// FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
1980static void do_frestore_null(m68000_base_device *m68k)
1981{
1982   int i;
1983
1984   REG_FPCR(m68k) = 0;
1985   REG_FPSR(m68k) = 0;
1986   REG_FPIAR(m68k) = 0;
1987   for (i = 0; i < 8; i++)
1988   {
1989      REG_FP(m68k)[i].high = 0x7fff;
1990      REG_FP(m68k)[i].low = U64(0xffffffffffffffff);
1991   }
1992
1993   // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL
1994   // The PRM says it's possible to generate a NULL frame, but not how/when/why.  (need the 68881/68882 manual!)
1995   m68k->fpu_just_reset = 1;
1996}
1997
1998static void m68040_do_fsave(m68000_base_device *m68k, UINT32 addr, int reg, int inc)
1999{
2000   if (m68k->fpu_just_reset)
2001   {
2002         m68ki_write_32(m68k, addr, 0);
2003   }
2004   else
2005   {
2006      // we normally generate an IDLE frame
2007      int delta = perform_fsave(m68k, addr, inc);
2008      if(reg != -1)
2009         REG_A(m68k)[reg] += delta;
2010   }
2011}
2012
2013static void m68040_do_frestore(m68000_base_device *m68k, UINT32 addr, int reg)
2014{
2015   bool m40 = m68k->cpu_type & CPU_TYPE_040;
2016   UINT32 temp = m68ki_read_32(m68k, addr);
2017
2018   // check for NULL frame
2019   if (temp & 0xff000000)
2020   {
2021      // we don't handle non-NULL frames
2022      m68k->fpu_just_reset = 0;
2023
2024      if (reg != -1)
2025      {
2026         // how about an IDLE frame?
2027         if (!m40 && ((temp & 0x00ff0000) == 0x00180000))
2028         {
2029            REG_A(m68k)[reg] += 7*4;
2030         }
2031         else if (m40 && ((temp & 0xffff0000) == 0x41000000))
2032         {
2033            REG_A(m68k)[reg] += 4;
2034         } // check UNIMP
2035         else if ((temp & 0x00ff0000) == 0x00380000)
2036         {
2037            REG_A(m68k)[reg] += 14*4;
2038         } // check BUSY
2039         else if ((temp & 0x00ff0000) == 0x00b40000)
2040         {
2041            REG_A(m68k)[reg] += 45*4;
2042         }
2043      }
2044   }
2045   else
2046   {
2047      do_frestore_null(m68k);
2048   }
2049}
2050
2051void m68040_fpu_op1(m68000_base_device *m68k)
2052{
2053   int ea = m68k->ir & 0x3f;
2054   int mode = (ea >> 3) & 0x7;
2055   int reg = (ea & 0x7);
2056   UINT32 addr;
2057
2058   switch ((m68k->ir >> 6) & 0x3)
2059   {
2060      case 0:     // FSAVE <ea>
2061      {
2062         switch (mode)
2063         {
2064         case 2: // (An)
2065            addr = REG_A(m68k)[reg];
2066            m68040_do_fsave(m68k, addr, -1, 1);
2067            break;
2068
2069         case 3: // (An)+
2070            addr = EA_AY_PI_32(m68k);
2071            m68040_do_fsave(m68k, addr, reg, 1);
2072            break;
2073
2074         case 4: // -(An)
2075            addr = EA_AY_PD_32(m68k);
2076            m68040_do_fsave(m68k, addr, reg, 0);
2077            break;
2078
2079         case 5: // (D16, An)
2080            addr = EA_AY_DI_16(m68k);
2081            m68040_do_fsave(m68k, addr, -1, 1);
2082            break;
2083
2084         case 7: //
2085            switch (reg)
2086            {
2087               case 1:     // (abs32)
2088               {
2089                  addr = EA_AL_32(m68k);
2090                  m68040_do_fsave(m68k, addr, -1, 1);
2091                  break;
2092               }
2093               case 2:     // (d16, PC)
2094               {
2095                  addr = EA_PCDI_16(m68k);
2096                  m68040_do_fsave(m68k, addr, -1, 1);
2097                  break;
2098               }
2099               default:
2100                  fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC(m68k));
2101            }
2102
2103            break;
2104
2105         default:
2106            fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC(m68k));
2107         }
2108         break;
2109      }
2110      break;
2111
2112      case 1:     // FRESTORE <ea>
2113      {
2114         switch (mode)
2115         {
2116         case 2: // (An)
2117            addr = REG_A(m68k)[reg];
2118            m68040_do_frestore(m68k, addr, -1);
2119            break;
2120
2121         case 3: // (An)+
2122            addr = EA_AY_PI_32(m68k);
2123            m68040_do_frestore(m68k, addr, reg);
2124            break;
2125
2126         case 5: // (D16, An)
2127            addr = EA_AY_DI_16(m68k);
2128            m68040_do_frestore(m68k, addr, -1);
2129            break;
2130
2131         case 7: //
2132            switch (reg)
2133            {
2134               case 1:     // (abs32)
2135               {
2136                  addr = EA_AL_32(m68k);
2137                  m68040_do_frestore(m68k, addr, -1);
2138                  break;
2139               }
2140               case 2:     // (d16, PC)
2141               {
2142                  addr = EA_PCDI_16(m68k);
2143                  m68040_do_frestore(m68k, addr, -1);
2144                  break;
2145               }
2146               default:
2147                  fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC(m68k));
2148            }
2149
2150            break;
2151
2152         default:
2153            fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC(m68k));
2154         }
2155         break;
2156      }
2157      break;
2158
2159      default:    fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (m68k->ir >> 6) & 0x3, REG_PC(m68k)-2);
2160   }
2161}
trunk/src/emu/cpu/m68000/m68kfpu.inc
r0r28739
1#include <math.h>
2
3#define FPCC_N          0x08000000
4#define FPCC_Z          0x04000000
5#define FPCC_I          0x02000000
6#define FPCC_NAN        0x01000000
7
8#define FPES_OE         0x00002000
9#define FPAE_IOP        0x00000080
10
11#define DOUBLE_INFINITY                 U64(0x7ff0000000000000)
12#define DOUBLE_EXPONENT                 U64(0x7ff0000000000000)
13#define DOUBLE_MANTISSA                 U64(0x000fffffffffffff)
14
15extern flag floatx80_is_nan( floatx80 a );
16
17// masks for packed dwords, positive k-factor
18static const UINT32 pkmask2[18] =
19{
20   0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
21   0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
22   0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
23   0xffffffff, 0xffffffff, 0xffffffff
24};
25
26static const UINT32 pkmask3[18] =
27{
28   0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29   0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
30   0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
31};
32
33INLINE double fx80_to_double(floatx80 fx)
34{
35   UINT64 d;
36   double *foo;
37
38   foo = (double *)&d;
39
40   d = floatx80_to_float64(fx);
41
42   return *foo;
43}
44
45INLINE floatx80 double_to_fx80(double in)
46{
47   UINT64 *d;
48
49   d = (UINT64 *)&in;
50
51   return float64_to_floatx80(*d);
52}
53
54INLINE floatx80 load_extended_float80(m68000_base_device *m68k, UINT32 ea)
55{
56   UINT32 d1,d2;
57   UINT16 d3;
58   floatx80 fp;
59
60   d3 = m68ki_read_16(m68k, ea);
61   d1 = m68ki_read_32(m68k, ea+4);
62   d2 = m68ki_read_32(m68k, ea+8);
63
64   fp.high = d3;
65   fp.low = ((UINT64)d1<<32) | (d2 & 0xffffffff);
66
67   return fp;
68}
69
70INLINE void store_extended_float80(m68000_base_device *m68k, UINT32 ea, floatx80 fpr)
71{
72   m68ki_write_16(m68k, ea+0, fpr.high);
73   m68ki_write_16(m68k, ea+2, 0);
74   m68ki_write_32(m68k, ea+4, (fpr.low>>32)&0xffffffff);
75   m68ki_write_32(m68k, ea+8, fpr.low&0xffffffff);
76}
77
78INLINE floatx80 load_pack_float80(m68000_base_device *m68k, UINT32 ea)
79{
80   UINT32 dw1, dw2, dw3;
81   floatx80 result;
82   double tmp;
83   char str[128], *ch;
84
85   dw1 = m68ki_read_32(m68k, ea);
86   dw2 = m68ki_read_32(m68k, ea+4);
87   dw3 = m68ki_read_32(m68k, ea+8);
88
89   ch = &str[0];
90   if (dw1 & 0x80000000)   // mantissa sign
91   {
92      *ch++ = '-';
93   }
94   *ch++ = (char)((dw1 & 0xf) + '0');
95   *ch++ = '.';
96   *ch++ = (char)(((dw2 >> 28) & 0xf) + '0');
97   *ch++ = (char)(((dw2 >> 24) & 0xf) + '0');
98   *ch++ = (char)(((dw2 >> 20) & 0xf) + '0');
99   *ch++ = (char)(((dw2 >> 16) & 0xf) + '0');
100   *ch++ = (char)(((dw2 >> 12) & 0xf) + '0');
101   *ch++ = (char)(((dw2 >> 8)  & 0xf) + '0');
102   *ch++ = (char)(((dw2 >> 4)  & 0xf) + '0');
103   *ch++ = (char)(((dw2 >> 0)  & 0xf) + '0');
104   *ch++ = (char)(((dw3 >> 28) & 0xf) + '0');
105   *ch++ = (char)(((dw3 >> 24) & 0xf) + '0');
106   *ch++ = (char)(((dw3 >> 20) & 0xf) + '0');
107   *ch++ = (char)(((dw3 >> 16) & 0xf) + '0');
108   *ch++ = (char)(((dw3 >> 12) & 0xf) + '0');
109   *ch++ = (char)(((dw3 >> 8)  & 0xf) + '0');
110   *ch++ = (char)(((dw3 >> 4)  & 0xf) + '0');
111   *ch++ = (char)(((dw3 >> 0)  & 0xf) + '0');
112   *ch++ = 'E';
113   if (dw1 & 0x40000000)   // exponent sign
114   {
115      *ch++ = '-';
116   }
117   *ch++ = (char)(((dw1 >> 24) & 0xf) + '0');
118   *ch++ = (char)(((dw1 >> 20) & 0xf) + '0');
119   *ch++ = (char)(((dw1 >> 16) & 0xf) + '0');
120   *ch = '\0';
121
122   sscanf(str, "%le", &tmp);
123
124   result = double_to_fx80(tmp);
125
126   return result;
127}
128
129INLINE void store_pack_float80(m68000_base_device *m68k, UINT32 ea, int k, floatx80 fpr)
130{
131   UINT32 dw1, dw2, dw3;
132   char str[128], *ch;
133   int i, j, exp;
134
135   dw1 = dw2 = dw3 = 0;
136   ch = &str[0];
137
138   sprintf(str, "%.16e", fx80_to_double(fpr));
139
140   if (*ch == '-')
141   {
142      ch++;
143      dw1 = 0x80000000;
144   }
145
146   if (*ch == '+')
147   {
148      ch++;
149   }
150
151   dw1 |= (*ch++ - '0');
152
153   if (*ch == '.')
154   {
155      ch++;
156   }
157
158   // handle negative k-factor here
159   if ((k <= 0) && (k >= -13))
160   {
161      exp = 0;
162      for (i = 0; i < 3; i++)
163      {
164         if (ch[18+i] >= '0' && ch[18+i] <= '9')
165         {
166            exp = (exp << 4) | (ch[18+i] - '0');
167         }
168      }
169
170      if (ch[17] == '-')
171      {
172         exp = -exp;
173      }
174
175      k = -k;
176      // last digit is (k + exponent - 1)
177      k += (exp - 1);
178
179      // round up the last significant mantissa digit
180      if (ch[k+1] >= '5')
181      {
182         ch[k]++;
183      }
184
185      // zero out the rest of the mantissa digits
186      for (j = (k+1); j < 16; j++)
187      {
188         ch[j] = '0';
189      }
190
191      // now zero out K to avoid tripping the positive K detection below
192      k = 0;
193   }
194
195   // crack 8 digits of the mantissa
196   for (i = 0; i < 8; i++)
197   {
198      dw2 <<= 4;
199      if (*ch >= '0' && *ch <= '9')
200      {
201         dw2 |= *ch++ - '0';
202      }
203   }
204
205   // next 8 digits of the mantissa
206   for (i = 0; i < 8; i++)
207   {
208      dw3 <<= 4;
209      if (*ch >= '0' && *ch <= '9')
210      dw3 |= *ch++ - '0';
211   }
212
213   // handle masking if k is positive
214   if (k >= 1)
215   {
216      if (k <= 17)
217      {
218         dw2 &= pkmask2[k];
219         dw3 &= pkmask3[k];
220      }
221      else
222      {
223         dw2 &= pkmask2[17];
224         dw3 &= pkmask3[17];
225//          m68k->fpcr |=  (need to set OPERR bit)
226      }
227   }
228
229   // finally, crack the exponent
230   if (*ch == 'e' || *ch == 'E')
231   {
232      ch++;
233      if (*ch == '-')
234      {
235         ch++;
236         dw1 |= 0x40000000;
237      }
238
239      if (*ch == '+')
240      {
241         ch++;
242      }
243
244      j = 0;
245      for (i = 0; i < 3; i++)
246      {
247         if (*ch >= '0' && *ch <= '9')
248         {
249            j = (j << 4) | (*ch++ - '0');
250         }
251      }
252
253      dw1 |= (j << 16);
254   }
255
256   m68ki_write_32(m68k, ea, dw1);
257   m68ki_write_32(m68k, ea+4, dw2);
258   m68ki_write_32(m68k, ea+8, dw3);
259}
260
261INLINE void SET_CONDITION_CODES(m68000_base_device *m68k, floatx80 reg)
262{
263//  UINT64 *regi;
264
265//  regi = (UINT64 *)&reg;
266
267   REG_FPSR(m68k) &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
268
269   // sign flag
270   if (reg.high & 0x8000)
271   {
272      REG_FPSR(m68k) |= FPCC_N;
273   }
274
275   // zero flag
276   if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
277   {
278      REG_FPSR(m68k) |= FPCC_Z;
279   }
280
281   // infinity flag
282   if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
283   {
284      REG_FPSR(m68k) |= FPCC_I;
285   }
286
287   // NaN flag
288   if (floatx80_is_nan(reg))
289   {
290      REG_FPSR(m68k) |= FPCC_NAN;
291   }
292}
293
294INLINE int TEST_CONDITION(m68000_base_device *m68k, int condition)
295{
296   int n = (REG_FPSR(m68k) & FPCC_N) != 0;
297   int z = (REG_FPSR(m68k) & FPCC_Z) != 0;
298   int nan = (REG_FPSR(m68k) & FPCC_NAN) != 0;
299   int r = 0;
300   switch (condition)
301   {
302      case 0x10:
303      case 0x00:      return 0;                   // False
304
305      case 0x11:
306      case 0x01:      return (z);                 // Equal
307
308      case 0x12:
309      case 0x02:      return (!(nan || z || n));          // Greater Than
310
311      case 0x13:
312      case 0x03:      return (z || !(nan || n));          // Greater or Equal
313
314      case 0x14:
315      case 0x04:      return (n && !(nan || z));          // Less Than
316
317      case 0x15:
318      case 0x05:      return (z || (n && !nan));          // Less Than or Equal
319
320      case 0x16:
321      case 0x06:      return !nan && !z;
322
323      case 0x17:
324      case 0x07:      return !nan;
325
326      case 0x18:
327      case 0x08:      return nan;
328
329      case 0x19:
330      case 0x09:      return nan || z;
331
332      case 0x1a:
333      case 0x0a:      return (nan || !(n || z));          // Not Less Than or Equal
334
335      case 0x1b:
336      case 0x0b:      return (nan || z || !n);            // Not Less Than
337
338      case 0x1c:
339      case 0x0c:      return (nan || (n && !z));          // Not Greater or Equal Than
340
341      case 0x1d:
342      case 0x0d:      return (nan || z || n);             // Not Greater Than
343
344      case 0x1e:
345      case 0x0e:      return (!z);                    // Not Equal
346
347      case 0x1f:
348      case 0x0f:      return 1;                   // True
349
350      default:        fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
351   }
352
353   return r;
354}
355
356static UINT8 READ_EA_8(m68000_base_device *m68k, int ea)
357{
358   int mode = (ea >> 3) & 0x7;
359   int reg = (ea & 0x7);
360
361   switch (mode)
362   {
363      case 0:     // Dn
364      {
365         return REG_D(m68k)[reg];
366      }
367      case 2:     // (An)
368      {
369         UINT32 ea = REG_A(m68k)[reg];
370         return m68ki_read_8(m68k, ea);
371      }
372      case 3:     // (An)+
373      {
374         UINT32 ea = EA_AY_PI_8(m68k);
375         return m68ki_read_8(m68k, ea);
376      }
377      case 4:     // -(An)
378      {
379         UINT32 ea = EA_AY_PD_8(m68k);
380         return m68ki_read_8(m68k, ea);
381      }
382      case 5:     // (d16, An)
383      {
384         UINT32 ea = EA_AY_DI_8(m68k);
385         return m68ki_read_8(m68k, ea);
386      }
387      case 6:     // (An) + (Xn) + d8
388      {
389         UINT32 ea = EA_AY_IX_8(m68k);
390         return m68ki_read_8(m68k, ea);
391      }
392      case 7:
393      {
394         switch (reg)
395         {
396            case 0:     // (xxx).W
397            {
398               UINT32 ea = (UINT32)OPER_I_16(m68k);
399               return m68ki_read_8(m68k, ea);
400            }
401            case 1:     // (xxx).L
402            {
403               UINT32 d1 = OPER_I_16(m68k);
404               UINT32 d2 = OPER_I_16(m68k);
405               UINT32 ea = (d1 << 16) | d2;
406               return m68ki_read_8(m68k, ea);
407            }
408            case 2:     // (d16, PC)
409            {
410               UINT32 ea = EA_PCDI_8(m68k);
411               return m68ki_read_8(m68k, ea);
412            }
413            case 3:     // (PC) + (Xn) + d8
414            {
415               UINT32 ea =  EA_PCIX_8(m68k);
416               return m68ki_read_8(m68k, ea);
417            }
418            case 4:     // #<data>
419            {
420               return  OPER_I_8(m68k);
421            }
422            default:    fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
423         }
424         break;
425      }
426      default:    fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
427   }
428
429   return 0;
430}
431
432static UINT16 READ_EA_16(m68000_base_device *m68k, int ea)
433{
434   int mode = (ea >> 3) & 0x7;
435   int reg = (ea & 0x7);
436
437   switch (mode)
438   {
439      case 0:     // Dn
440      {
441         return (UINT16)(REG_D(m68k)[reg]);
442      }
443      case 2:     // (An)
444      {
445         UINT32 ea = REG_A(m68k)[reg];
446         return m68ki_read_16(m68k, ea);
447      }
448      case 3:     // (An)+
449      {
450         UINT32 ea = EA_AY_PI_16(m68k);
451         return m68ki_read_16(m68k, ea);
452      }
453      case 4:     // -(An)
454      {
455         UINT32 ea = EA_AY_PD_16(m68k);
456         return m68ki_read_16(m68k, ea);
457      }
458      case 5:     // (d16, An)
459      {
460         UINT32 ea = EA_AY_DI_16(m68k);
461         return m68ki_read_16(m68k, ea);
462      }
463      case 6:     // (An) + (Xn) + d8
464      {
465         UINT32 ea = EA_AY_IX_16(m68k);
466         return m68ki_read_16(m68k, ea);
467      }
468      case 7:
469      {
470         switch (reg)
471         {
472            case 0:     // (xxx).W
473            {
474               UINT32 ea = (UINT32)OPER_I_16(m68k);
475               return m68ki_read_16(m68k, ea);
476            }
477            case 1:     // (xxx).L
478            {
479               UINT32 d1 = OPER_I_16(m68k);
480               UINT32 d2 = OPER_I_16(m68k);
481               UINT32 ea = (d1 << 16) | d2;
482               return m68ki_read_16(m68k, ea);
483            }
484            case 2:     // (d16, PC)
485            {
486               UINT32 ea = EA_PCDI_16(m68k);
487               return m68ki_read_16(m68k, ea);
488            }
489            case 3:     // (PC) + (Xn) + d8
490            {
491               UINT32 ea =  EA_PCIX_16(m68k);
492               return m68ki_read_16(m68k, ea);
493            }
494            case 4:     // #<data>
495            {
496               return OPER_I_16(m68k);
497            }
498
499            default:    fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
500         }
501         break;
502      }
503      default:    fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
504   }
505
506   return 0;
507}
508
509static UINT32 READ_EA_32(m68000_base_device *m68k, int ea)
510{
511   int mode = (ea >> 3) & 0x7;
512   int reg = (ea & 0x7);
513
514   switch (mode)
515   {
516      case 0:     // Dn
517      {
518         return REG_D(m68k)[reg];
519      }
520      case 2:     // (An)
521      {
522         UINT32 ea = REG_A(m68k)[reg];
523         return m68ki_read_32(m68k, ea);
524      }
525      case 3:     // (An)+
526      {
527         UINT32 ea = EA_AY_PI_32(m68k);
528         return m68ki_read_32(m68k, ea);
529      }
530      case 4:     // -(An)
531      {
532         UINT32 ea = EA_AY_PD_32(m68k);
533         return m68ki_read_32(m68k, ea);
534      }
535      case 5:     // (d16, An)
536      {
537         UINT32 ea = EA_AY_DI_32(m68k);
538         return m68ki_read_32(m68k, ea);
539      }
540      case 6:     // (An) + (Xn) + d8
541      {
542         UINT32 ea = EA_AY_IX_32(m68k);
543         return m68ki_read_32(m68k, ea);
544      }
545      case 7:
546      {
547         switch (reg)
548         {
549            case 0:     // (xxx).W
550            {
551               UINT32 ea = (UINT32)OPER_I_16(m68k);
552               return m68ki_read_32(m68k, ea);
553            }
554            case 1:     // (xxx).L
555            {
556               UINT32 d1 = OPER_I_16(m68k);
557               UINT32 d2 = OPER_I_16(m68k);
558               UINT32 ea = (d1 << 16) | d2;
559               return m68ki_read_32(m68k, ea);
560            }
561            case 2:     // (d16, PC)
562            {
563               UINT32 ea = EA_PCDI_32(m68k);
564               return m68ki_read_32(m68k, ea);
565            }
566            case 3:     // (PC) + (Xn) + d8
567            {
568               UINT32 ea =  EA_PCIX_32(m68k);
569               return m68ki_read_32(m68k, ea);
570            }
571            case 4:     // #<data>
572            {
573               return  OPER_I_32(m68k);
574            }
575            default:    fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
576         }
577         break;
578      }
579      default:    fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
580   }
581   return 0;
582}
583
584static UINT64 READ_EA_64(m68000_base_device *m68k, int ea)
585{
586   int mode = (ea >> 3) & 0x7;
587   int reg = (ea & 0x7);
588   UINT32 h1, h2;
589
590   switch (mode)
591   {
592      case 2:     // (An)
593      {
594         UINT32 ea = REG_A(m68k)[reg];
595         h1 = m68ki_read_32(m68k, ea+0);
596         h2 = m68ki_read_32(m68k, ea+4);
597         return  (UINT64)(h1) << 32 | (UINT64)(h2);
598      }
599      case 3:     // (An)+
600      {
601         UINT32 ea = REG_A(m68k)[reg];
602         REG_A(m68k)[reg] += 8;
603         h1 = m68ki_read_32(m68k, ea+0);
604         h2 = m68ki_read_32(m68k, ea+4);
605         return  (UINT64)(h1) << 32 | (UINT64)(h2);
606      }
607      case 4:     // -(An)
608      {
609         UINT32 ea = REG_A(m68k)[reg]-8;
610         REG_A(m68k)[reg] -= 8;
611         h1 = m68ki_read_32(m68k, ea+0);
612         h2 = m68ki_read_32(m68k, ea+4);
613         return  (UINT64)(h1) << 32 | (UINT64)(h2);
614      }
615      case 5:     // (d16, An)
616      {
617         UINT32 ea = EA_AY_DI_32(m68k);
618         h1 = m68ki_read_32(m68k, ea+0);
619         h2 = m68ki_read_32(m68k, ea+4);
620         return  (UINT64)(h1) << 32 | (UINT64)(h2);
621      }
622      case 6:     // (An) + (Xn) + d8
623      {
624         UINT32 ea = EA_AY_IX_32(m68k);
625         h1 = m68ki_read_32(m68k, ea+0);
626         h2 = m68ki_read_32(m68k, ea+4);
627         return  (UINT64)(h1) << 32 | (UINT64)(h2);
628      }
629      case 7:
630      {
631         switch (reg)
632         {
633            case 1:     // (xxx).L
634            {
635               UINT32 d1 = OPER_I_16(m68k);
636               UINT32 d2 = OPER_I_16(m68k);
637               UINT32 ea = (d1 << 16) | d2;
638               return (UINT64)(m68ki_read_32(m68k, ea)) << 32 | (UINT64)(m68ki_read_32(m68k, ea+4));
639            }
640            case 3:     // (PC) + (Xn) + d8
641            {
642               UINT32 ea =  EA_PCIX_32(m68k);
643               h1 = m68ki_read_32(m68k, ea+0);
644               h2 = m68ki_read_32(m68k, ea+4);
645               return  (UINT64)(h1) << 32 | (UINT64)(h2);
646            }
647            case 4:     // #<data>
648            {
649               h1 = OPER_I_32(m68k);
650               h2 = OPER_I_32(m68k);
651               return  (UINT64)(h1) << 32 | (UINT64)(h2);
652            }
653            case 2:     // (d16, PC)
654            {
655               UINT32 ea = EA_PCDI_32(m68k);
656               h1 = m68ki_read_32(m68k, ea+0);
657               h2 = m68ki_read_32(m68k, ea+4);
658               return  (UINT64)(h1) << 32 | (UINT64)(h2);
659            }
660            default:    fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
661         }
662         break;
663      }
664      default:    fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
665   }
666
667   return 0;
668}
669
670
671static floatx80 READ_EA_FPE(m68000_base_device *m68k, int ea)
672{
673   floatx80 fpr;
674   int mode = (ea >> 3) & 0x7;
675   int reg = (ea & 0x7);
676
677   switch (mode)
678   {
679      case 2:     // (An)
680      {
681         UINT32 ea = REG_A(m68k)[reg];
682         fpr = load_extended_float80(m68k, ea);
683         break;
684      }
685
686      case 3:     // (An)+
687      {
688         UINT32 ea = REG_A(m68k)[reg];
689         REG_A(m68k)[reg] += 12;
690         fpr = load_extended_float80(m68k, ea);
691         break;
692      }
693      case 4:     // -(An)
694      {
695         UINT32 ea = REG_A(m68k)[reg]-12;
696         REG_A(m68k)[reg] -= 12;
697         fpr = load_extended_float80(m68k, ea);
698         break;
699      }
700      case 5:     // (d16, An)
701      {
702         // FIXME: will fail for fmovem
703         UINT32 ea = EA_AY_DI_32(m68k);
704         fpr = load_extended_float80(m68k, ea);
705         break;
706      }
707      case 6:     // (An) + (Xn) + d8
708      {
709         // FIXME: will fail for fmovem
710         UINT32 ea = EA_AY_IX_32(m68k);
711         fpr = load_extended_float80(m68k, ea);
712         break;
713      }
714
715      case 7: // extended modes
716      {
717         switch (reg)
718         {
719            case 2: // (d16, PC)
720               {
721                  UINT32 ea = EA_PCDI_32(m68k);
722                  fpr = load_extended_float80(m68k, ea);
723               }
724               break;
725
726            case 3: // (d16,PC,Dx.w)
727               {
728                  UINT32 ea = EA_PCIX_32(m68k);
729                  fpr = load_extended_float80(m68k, ea);
730               }
731               break;
732
733            default:
734               fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
735               break;
736         }
737      }
738      break;
739
740      default:    fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k)); break;
741   }
742
743   return fpr;
744}
745
746static floatx80 READ_EA_PACK(m68000_base_device *m68k, int ea)
747{
748   floatx80 fpr;
749   int mode = (ea >> 3) & 0x7;
750   int reg = (ea & 0x7);
751
752   switch (mode)
753   {
754      case 2:     // (An)
755      {
756         UINT32 ea = REG_A(m68k)[reg];
757         fpr = load_pack_float80(m68k, ea);
758         break;
759      }
760
761      case 3:     // (An)+
762      {
763         UINT32 ea = REG_A(m68k)[reg];
764         REG_A(m68k)[reg] += 12;
765         fpr = load_pack_float80(m68k, ea);
766         break;
767      }
768
769      case 7: // extended modes
770      {
771         switch (reg)
772         {
773            case 3: // (d16,PC,Dx.w)
774               {
775                  UINT32 ea = EA_PCIX_32(m68k);
776                  fpr = load_pack_float80(m68k, ea);
777               }
778               break;
779
780            default:
781               fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
782               break;
783         }
784      }
785      break;
786
787      default:    fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k)); break;
788   }
789
790   return fpr;
791}
792
793static void WRITE_EA_8(m68000_base_device *m68k, int ea, UINT8 data)
794{
795   int mode = (ea >> 3) & 0x7;
796   int reg = (ea & 0x7);
797
798   switch (mode)
799   {
800      case 0:     // Dn
801      {
802         REG_D(m68k)[reg] = data;
803         break;
804      }
805      case 2:     // (An)
806      {
807         UINT32 ea = REG_A(m68k)[reg];
808         m68ki_write_8(m68k, ea, data);
809         break;
810      }
811      case 3:     // (An)+
812      {
813         UINT32 ea = EA_AY_PI_8(m68k);
814         m68ki_write_8(m68k, ea, data);
815         break;
816      }
817      case 4:     // -(An)
818      {
819         UINT32 ea = EA_AY_PD_8(m68k);
820         m68ki_write_8(m68k, ea, data);
821         break;
822      }
823      case 5:     // (d16, An)
824      {
825         UINT32 ea = EA_AY_DI_8(m68k);
826         m68ki_write_8(m68k, ea, data);
827         break;
828      }
829      case 6:     // (An) + (Xn) + d8
830      {
831         UINT32 ea = EA_AY_IX_8(m68k);
832         m68ki_write_8(m68k, ea, data);
833         break;
834      }
835      case 7:
836      {
837         switch (reg)
838         {
839            case 1:     // (xxx).B
840            {
841               UINT32 d1 = OPER_I_16(m68k);
842               UINT32 d2 = OPER_I_16(m68k);
843               UINT32 ea = (d1 << 16) | d2;
844               m68ki_write_8(m68k, ea, data);
845               break;
846            }
847            case 2:     // (d16, PC)
848            {
849               UINT32 ea = EA_PCDI_16(m68k);
850               m68ki_write_8(m68k, ea, data);
851               break;
852            }
853            default:    fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
854         }
855         break;
856      }
857      default:    fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC(m68k));
858   }
859}
860
861static void WRITE_EA_16(m68000_base_device *m68k, int ea, UINT16 data)
862{
863   int mode = (ea >> 3) & 0x7;
864   int reg = (ea & 0x7);
865
866   switch (mode)
867   {
868      case 0:     // Dn
869      {
870         REG_D(m68k)[reg] = data;
871         break;
872      }
873      case 2:     // (An)
874      {
875         UINT32 ea = REG_A(m68k)[reg];
876         m68ki_write_16(m68k, ea, data);
877         break;
878      }
879      case 3:     // (An)+
880      {
881         UINT32 ea = EA_AY_PI_16(m68k);
882         m68ki_write_16(m68k, ea, data);
883         break;
884      }
885      case 4:     // -(An)
886      {
887         UINT32 ea = EA_AY_PD_16(m68k);
888         m68ki_write_16(m68k, ea, data);
889         break;
890      }
891      case 5:     // (d16, An)
892      {
893         UINT32 ea = EA_AY_DI_16(m68k);
894         m68ki_write_16(m68k, ea, data);
895         break;
896      }
897      case 6:     // (An) + (Xn) + d8
898      {
899         UINT32 ea = EA_AY_IX_16(m68k);
900         m68ki_write_16(m68k, ea, data);
901         break;
902      }
903      case 7:
904      {
905         switch (reg)
906         {
907            case 1:     // (xxx).W
908            {
909               UINT32 d1 = OPER_I_16(m68k);
910               UINT32 d2 = OPER_I_16(m68k);
911               UINT32 ea = (d1 << 16) | d2;
912               m68ki_write_16(m68k, ea, data);
913               break;
914            }
915            case 2:     // (d16, PC)
916            {
917               UINT32 ea = EA_PCDI_16(m68k);
918               m68ki_write_16(m68k, ea, data);
919               break;
920            }
921            default:    fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
922         }
923         break;
924      }
925      default:    fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC(m68k));
926   }
927}
928
929static void WRITE_EA_32(m68000_base_device *m68k, int ea, UINT32 data)
930{
931   int mode = (ea >> 3) & 0x7;
932   int reg = (ea & 0x7);
933
934   switch (mode)
935   {
936      case 0:     // Dn
937      {
938         REG_D(m68k)[reg] = data;
939         break;
940      }
941      case 1:     // An
942      {
943         REG_A(m68k)[reg] = data;
944         break;
945      }
946      case 2:     // (An)
947      {
948         UINT32 ea = REG_A(m68k)[reg];
949         m68ki_write_32(m68k, ea, data);
950         break;
951      }
952      case 3:     // (An)+
953      {
954         UINT32 ea = EA_AY_PI_32(m68k);
955         m68ki_write_32(m68k, ea, data);
956         break;
957      }
958      case 4:     // -(An)
959      {
960         UINT32 ea = EA_AY_PD_32(m68k);
961         m68ki_write_32(m68k, ea, data);
962         break;
963      }
964      case 5:     // (d16, An)
965      {
966         UINT32 ea = EA_AY_DI_32(m68k);
967         m68ki_write_32(m68k, ea, data);
968         break;
969      }
970      case 6:     // (An) + (Xn) + d8
971      {
972         UINT32 ea = EA_AY_IX_32(m68k);
973         m68ki_write_32(m68k, ea, data);
974         break;
975      }
976      case 7:
977      {
978         switch (reg)
979         {
980            case 1:     // (xxx).L
981            {
982               UINT32 d1 = OPER_I_16(m68k);
983               UINT32 d2 = OPER_I_16(m68k);
984               UINT32 ea = (d1 << 16) | d2;
985               m68ki_write_32(m68k, ea, data);
986               break;
987            }
988            case 2:     // (d16, PC)
989            {
990               UINT32 ea = EA_PCDI_32(m68k);
991               m68ki_write_32(m68k, ea, data);
992               break;
993            }
994            default:    fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
995         }
996         break;
997      }
998      default:    fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC(m68k));
999   }
1000}
1001
1002static void WRITE_EA_64(m68000_base_device *m68k, int ea, UINT64 data)
1003{
1004   int mode = (ea >> 3) & 0x7;
1005   int reg = (ea & 0x7);
1006
1007   switch (mode)
1008   {
1009      case 2:     // (An)
1010      {
1011         UINT32 ea = REG_A(m68k)[reg];
1012         m68ki_write_32(m68k, ea, (UINT32)(data >> 32));
1013         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1014         break;
1015      }
1016      case 3:     // (An)+
1017      {
1018         UINT32 ea = REG_A(m68k)[reg];
1019         REG_A(m68k)[reg] += 8;
1020         m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1021         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1022         break;
1023      }
1024      case 4:     // -(An)
1025      {
1026         UINT32 ea;
1027         REG_A(m68k)[reg] -= 8;
1028         ea = REG_A(m68k)[reg];
1029         m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1030         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1031         break;
1032      }
1033      case 5:     // (d16, An)
1034      {
1035         UINT32 ea = EA_AY_DI_32(m68k);
1036         m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1037         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1038         break;
1039      }
1040      case 6:     // (An) + (Xn) + d8
1041      {
1042         UINT32 ea = EA_AY_IX_32(m68k);
1043         m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1044         m68ki_write_32(m68k, ea+4, (UINT32)(data));
1045         break;
1046      }
1047      case 7:
1048      {
1049         switch (reg)
1050         {
1051            case 1:     // (xxx).L
1052            {
1053               UINT32 d1 = OPER_I_16(m68k);
1054               UINT32 d2 = OPER_I_16(m68k);
1055               UINT32 ea = (d1 << 16) | d2;
1056               m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1057               m68ki_write_32(m68k, ea+4, (UINT32)(data));
1058               break;
1059            }
1060            case 2:     // (d16, PC)
1061            {
1062               UINT32 ea = EA_PCDI_32(m68k);
1063               m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
1064               m68ki_write_32(m68k, ea+4, (UINT32)(data));
1065               break;
1066            }
1067            default:    fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
1068         }
1069         break;
1070      }
1071      default:    fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (UINT32)(data >> 32), (UINT32)(data), REG_PC(m68k));
1072   }
1073}
1074
1075static void WRITE_EA_FPE(m68000_base_device *m68k, int ea, floatx80 fpr)
1076{
1077   int mode = (ea >> 3) & 0x7;
1078   int reg = (ea & 0x7);
1079
1080   switch (mode)
1081   {
1082      case 2:     // (An)
1083      {
1084         UINT32 ea;
1085         ea = REG_A(m68k)[reg];
1086         store_extended_float80(m68k, ea, fpr);
1087         break;
1088      }
1089
1090      case 3:     // (An)+
1091      {
1092         UINT32 ea;
1093         ea = REG_A(m68k)[reg];
1094         store_extended_float80(m68k, ea, fpr);
1095         REG_A(m68k)[reg] += 12;
1096         break;
1097      }
1098
1099      case 4:     // -(An)
1100      {
1101         UINT32 ea;
1102         REG_A(m68k)[reg] -= 12;
1103         ea = REG_A(m68k)[reg];
1104         store_extended_float80(m68k, ea, fpr);
1105         break;
1106      }
1107
1108      case 7:
1109      {
1110         switch (reg)
1111         {
1112            default:    fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
1113         }
1114      }
1115      default:    fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
1116   }
1117}
1118
1119static void WRITE_EA_PACK(m68000_base_device *m68k, int ea, int k, floatx80 fpr)
1120{
1121   int mode = (ea >> 3) & 0x7;
1122   int reg = (ea & 0x7);
1123
1124   switch (mode)
1125   {
1126      case 2:     // (An)
1127      {
1128         UINT32 ea;
1129         ea = REG_A(m68k)[reg];
1130         store_pack_float80(m68k, ea, k, fpr);
1131         break;
1132      }
1133
1134      case 3:     // (An)+
1135      {
1136         UINT32 ea;
1137         ea = REG_A(m68k)[reg];
1138         store_pack_float80(m68k, ea, k, fpr);
1139         REG_A(m68k)[reg] += 12;
1140         break;
1141      }
1142
1143      case 4:     // -(An)
1144      {
1145         UINT32 ea;
1146         REG_A(m68k)[reg] -= 12;
1147         ea = REG_A(m68k)[reg];
1148         store_pack_float80(m68k, ea, k, fpr);
1149         break;
1150      }
1151
1152      case 7:
1153      {
1154         switch (reg)
1155         {
1156            default:    fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
1157         }
1158      }
1159      default:    fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
1160   }
1161}
1162
1163static void fpgen_rm_reg(m68000_base_device *m68k, UINT16 w2)
1164{
1165   int ea = m68k->ir & 0x3f;
1166   int rm = (w2 >> 14) & 0x1;
1167   int src = (w2 >> 10) & 0x7;
1168   int dst = (w2 >>  7) & 0x7;
1169   int opmode = w2 & 0x7f;
1170   floatx80 source;
1171
1172   // fmovecr #$f, fp0 f200 5c0f
1173
1174   if (rm)
1175   {
1176      switch (src)
1177      {
1178         case 0:     // Long-Word Integer
1179         {
1180            INT32 d = READ_EA_32(m68k, ea);
1181            source = int32_to_floatx80(d);
1182            break;
1183         }
1184         case 1:     // Single-precision Real
1185         {
1186            UINT32 d = READ_EA_32(m68k, ea);
1187            source = float32_to_floatx80(d);
1188            break;
1189         }
1190         case 2:     // Extended-precision Real
1191         {
1192            source = READ_EA_FPE(m68k, ea);
1193            break;
1194         }
1195         case 3:     // Packed-decimal Real
1196         {
1197            source = READ_EA_PACK(m68k, ea);
1198            break;
1199         }
1200         case 4:     // Word Integer
1201         {
1202            INT16 d = READ_EA_16(m68k, ea);
1203            source = int32_to_floatx80((INT32)d);
1204            break;
1205         }
1206         case 5:     // Double-precision Real
1207         {
1208            UINT64 d = READ_EA_64(m68k, ea);
1209
1210            source = float64_to_floatx80(d);
1211            break;
1212         }
1213         case 6:     // Byte Integer
1214         {
1215            INT8 d = READ_EA_8(m68k, ea);
1216            source = int32_to_floatx80((INT32)d);
1217            break;
1218         }
1219         case 7:     // FMOVECR load from constant ROM
1220         {
1221            switch (w2 & 0x7f)
1222            {
1223               case 0x0:   // Pi
1224                  source.high = 0x4000;
1225                  source.low = U64(0xc90fdaa22168c235);
1226                  break;
1227
1228               case 0xb:   // log10(2)
1229                  source.high = 0x3ffd;
1230                  source.low = U64(0x9a209a84fbcff798);
1231                  break;
1232
1233               case 0xc:   // e
1234                  source.high = 0x4000;
1235                  source.low = U64(0xadf85458a2bb4a9b);
1236                  break;
1237
1238               case 0xd:   // log2(e)
1239                  source.high = 0x3fff;
1240                  source.low = U64(0xb8aa3b295c17f0bc);
1241                  break;
1242
1243               case 0xe:   // log10(e)
1244                  source.high = 0x3ffd;
1245                  source.low = U64(0xde5bd8a937287195);
1246                  break;
1247
1248               case 0xf:   // 0.0
1249                  source = int32_to_floatx80((INT32)0);
1250                  break;
1251
1252               case 0x30:  // ln(2)
1253                  source.high = 0x3ffe;
1254                  source.low = U64(0xb17217f7d1cf79ac);
1255                  break;
1256
1257               case 0x31:  // ln(10)
1258                  source.high = 0x4000;
1259                  source.low = U64(0x935d8dddaaa8ac17);
1260                  break;
1261
1262               case 0x32:  // 1 (or 100?  manuals are unclear, but 1 would make more sense)
1263                  source = int32_to_floatx80((INT32)1);
1264                  break;
1265
1266               case 0x33:  // 10^1
1267                  source = int32_to_floatx80((INT32)10);
1268                  break;
1269
1270               case 0x34:  // 10^2
1271                  source = int32_to_floatx80((INT32)10*10);
1272                  break;
1273
1274               case 0x35:  // 10^4
1275                  source = int32_to_floatx80((INT32)1000*10);
1276                  break;
1277
1278               case 0x36:  // 1.0e8
1279                  source = int32_to_floatx80((INT32)10000000*10);
1280                  break;
1281
1282               case 0x37:  // 1.0e16 - can't get the right precision from INT32 so go "direct" with constants from h/w
1283                  source.high = 0x4034;
1284                  source.low = U64(0x8e1bc9bf04000000);
1285                  break;
1286
1287               case 0x38:  // 1.0e32
1288                  source.high = 0x4069;
1289                  source.low = U64(0x9dc5ada82b70b59e);
1290                  break;
1291
1292               case 0x39:  // 1.0e64
1293                  source.high = 0x40d3;
1294                  source.low = U64(0xc2781f49ffcfa6d5);
1295                  break;
1296
1297               case 0x3a:  // 1.0e128
1298                  source.high = 0x41a8;
1299                  source.low = U64(0x93ba47c980e98ce0);
1300                  break;
1301
1302               case 0x3b:  // 1.0e256
1303                  source.high = 0x4351;
1304                  source.low = U64(0xaa7eebfb9df9de8e);
1305                  break;
1306
1307               case 0x3c:  // 1.0e512
1308                  source.high = 0x46a3;
1309                  source.low = U64(0xe319a0aea60e91c7);
1310                  break;
1311
1312               case 0x3d:  // 1.0e1024
1313                  source.high = 0x4d48;
1314                  source.low = U64(0xc976758681750c17);
1315                  break;
1316
1317               case 0x3e:  // 1.0e2048
1318                  source.high = 0x5a92;
1319                  source.low = U64(0x9e8b3b5dc53d5de5);
1320                  break;
1321
1322               case 0x3f:  // 1.0e4096
1323                  source.high = 0x7525;
1324                  source.low = U64(0xc46052028a20979b);
1325                  break;
1326
1327               default:
1328                  fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC(m68k)-4);
1329                  break;
1330            }
1331
1332            // handle it right here, the usual opmode bits aren't valid in the FMOVECR case
1333            REG_FP(m68k)[dst] = source;
1334            m68k->remaining_cycles -= 4;
1335            return;
1336         }
1337         default:    fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC(m68k)-4);
1338      }
1339   }
1340   else
1341   {
1342      source = REG_FP(m68k)[src];
1343   }
1344
1345
1346
1347   switch (opmode)
1348   {
1349      case 0x00:      // FMOVE
1350      {
1351         REG_FP(m68k)[dst] = source;
1352         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1353         m68k->remaining_cycles -= 4;
1354         break;
1355      }
1356      case 0x01:      // FINT
1357      {
1358         INT32 temp;
1359         temp = floatx80_to_int32(source);
1360         REG_FP(m68k)[dst] = int32_to_floatx80(temp);
1361         break;
1362      }
1363      case 0x03:      // FINTRZ
1364      {
1365         INT32 temp;
1366         temp = floatx80_to_int32_round_to_zero(source);
1367         REG_FP(m68k)[dst] = int32_to_floatx80(temp);
1368         break;
1369      }
1370      case 0x04:      // FSQRT
1371      {
1372         REG_FP(m68k)[dst] = floatx80_sqrt(source);
1373         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1374         m68k->remaining_cycles -= 109;
1375         break;
1376      }
1377      case 0x06:      // FLOGNP1
1378      {
1379         REG_FP(m68k)[dst] = floatx80_flognp1 (source);
1380         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1381         m68k->remaining_cycles -= 594; // for MC68881
1382         break;
1383      }
1384      case 0x0e:      // FSIN
1385      {
1386         REG_FP(m68k)[dst] = source;
1387         floatx80_fsin(REG_FP(m68k)[dst]);
1388         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1389         m68k->remaining_cycles -= 75;
1390         break;
1391      }
1392      case 0x0f:      // FTAN
1393      {
1394         REG_FP(m68k)[dst] = source;
1395         floatx80_ftan(REG_FP(m68k)[dst]);
1396         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1397         m68k->remaining_cycles -= 75;
1398         break;
1399      }
1400      case 0x14:      // FLOGN
1401      {
1402         REG_FP(m68k)[dst] = floatx80_flogn (source);
1403         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1404         m68k->remaining_cycles -= 548; // for MC68881
1405         break;
1406      }
1407      case 0x15:      // FLOG10
1408      {
1409         REG_FP(m68k)[dst] = floatx80_flog10 (source);
1410         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1411         m68k->remaining_cycles -= 604; // for MC68881
1412         break;
1413      }
1414      case 0x16:      // FLOG2
1415      {
1416         REG_FP(m68k)[dst] = floatx80_flog2 (source);
1417         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1418         m68k->remaining_cycles -= 604; // for MC68881
1419         break;
1420      }
1421      case 0x18:      // FABS
1422      {
1423         REG_FP(m68k)[dst] = source;
1424         REG_FP(m68k)[dst].high &= 0x7fff;
1425         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1426         m68k->remaining_cycles -= 3;
1427         break;
1428      }
1429      case 0x1a:      // FNEG
1430      {
1431         REG_FP(m68k)[dst] = source;
1432         REG_FP(m68k)[dst].high ^= 0x8000;
1433         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1434         m68k->remaining_cycles -= 3;
1435         break;
1436      }
1437      case 0x1d:      // FCOS
1438      {
1439         REG_FP(m68k)[dst] = source;
1440         floatx80_fcos(REG_FP(m68k)[dst]);
1441         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1442         m68k->remaining_cycles -= 75;
1443         break;
1444      }
1445      case 0x1e:      // FGETEXP
1446      {
1447         INT16 temp2;
1448
1449         temp2 = source.high;    // get the exponent
1450         temp2 -= 0x3fff;    // take off the bias
1451         REG_FP(m68k)[dst] = double_to_fx80((double)temp2);
1452         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1453         m68k->remaining_cycles -= 6;
1454         break;
1455      }
1456      case 0x20:      // FDIV
1457      {
1458         REG_FP(m68k)[dst] = floatx80_div(REG_FP(m68k)[dst], source);
1459         m68k->remaining_cycles -= 43;
1460         break;
1461      }
1462      case 0x22:      // FADD
1463      {
1464         REG_FP(m68k)[dst] = floatx80_add(REG_FP(m68k)[dst], source);
1465         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1466         m68k->remaining_cycles -= 9;
1467         break;
1468      }
1469      case 0x23:      // FMUL
1470      {
1471         REG_FP(m68k)[dst] = floatx80_mul(REG_FP(m68k)[dst], source);
1472         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1473         m68k->remaining_cycles -= 11;
1474         break;
1475      }
1476      case 0x24:      // FSGLDIV
1477      {
1478         float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
1479         float32 b = floatx80_to_float32( source );
1480         REG_FP(m68k)[dst] = float32_to_floatx80( float32_div(a, b) );
1481         m68k->remaining_cycles -= 43; //  // ? (value is from FDIV)
1482         break;
1483      }
1484      case 0x25:      // FREM
1485      {
1486         REG_FP(m68k)[dst] = floatx80_rem(REG_FP(m68k)[dst], source);
1487         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1488         m68k->remaining_cycles -= 43;   // guess
1489         break;
1490      }
1491      case 0x26:      // FSCALE
1492      {
1493         REG_FP(m68k)[dst] = floatx80_scale(REG_FP(m68k)[dst], source);
1494         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1495         m68k->remaining_cycles -= 46;   // (better?) guess
1496         break;
1497      }
1498      case 0x27:      // FSGLMUL
1499      {
1500         float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
1501         float32 b = floatx80_to_float32( source );
1502         REG_FP(m68k)[dst] = float32_to_floatx80( float32_mul(a, b) );
1503         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1504         m68k->remaining_cycles -= 11; // ? (value is from FMUL)
1505         break;
1506      }
1507      case 0x28:      // FSUB
1508      {
1509         REG_FP(m68k)[dst] = floatx80_sub(REG_FP(m68k)[dst], source);
1510         SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1511         m68k->remaining_cycles -= 9;
1512         break;
1513      }
1514      case 0x38:      // FCMP
1515      {
1516         floatx80 res;
1517         res = floatx80_sub(REG_FP(m68k)[dst], source);
1518         SET_CONDITION_CODES(m68k, res);
1519         m68k->remaining_cycles -= 7;
1520         break;
1521      }
1522      case 0x3a:      // FTST
1523      {
1524         floatx80 res;
1525         res = source;
1526         SET_CONDITION_CODES(m68k, res);
1527         m68k->remaining_cycles -= 7;
1528         break;
1529      }
1530
1531      default:    fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PPC(m68k));
1532   }
1533}
1534
1535static void fmove_reg_mem(m68000_base_device *m68k, UINT16 w2)
1536{
1537   int ea = m68k->ir & 0x3f;
1538   int src = (w2 >>  7) & 0x7;
1539   int dst = (w2 >> 10) & 0x7;
1540   int k = (w2 & 0x7f);
1541
1542   switch (dst)
1543   {
1544      case 0:     // Long-Word Integer
1545      {
1546         INT32 d = (INT32)floatx80_to_int32(REG_FP(m68k)[src]);
1547         WRITE_EA_32(m68k, ea, d);
1548         break;
1549      }
1550      case 1:     // Single-precision Real
1551      {
1552         UINT32 d = floatx80_to_float32(REG_FP(m68k)[src]);
1553         WRITE_EA_32(m68k, ea, d);
1554         break;
1555      }
1556      case 2:     // Extended-precision Real
1557      {
1558         WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[src]);
1559         break;
1560      }
1561      case 3:     // Packed-decimal Real with Static K-factor
1562      {
1563         // sign-extend k
1564         k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
1565         WRITE_EA_PACK(m68k, ea, k, REG_FP(m68k)[src]);
1566         break;
1567      }
1568      case 4:     // Word Integer
1569      {
1570         int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
1571         if (value > 0x7fff || value < -0x8000 )
1572         {
1573            REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
1574         }
1575         WRITE_EA_16(m68k, ea, (INT16)value);
1576         break;
1577      }
1578      case 5:     // Double-precision Real
1579      {
1580         UINT64 d;
1581
1582         d = floatx80_to_float64(REG_FP(m68k)[src]);
1583
1584         WRITE_EA_64(m68k, ea, d);
1585         break;
1586      }
1587      case 6:     // Byte Integer
1588      {
1589         int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
1590         if (value > 127 || value < -128)
1591         {
1592            REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
1593         }
1594         WRITE_EA_8(m68k, ea, (INT8) value);
1595         break;
1596      }
1597      case 7:     // Packed-decimal Real with Dynamic K-factor
1598      {
1599         WRITE_EA_PACK(m68k, ea, REG_D(m68k)[k>>4], REG_FP(m68k)[src]);
1600         break;
1601      }
1602   }
1603
1604   m68k->remaining_cycles -= 12;
1605}
1606
1607static void fmove_fpcr(m68000_base_device *m68k, UINT16 w2)
1608{
1609   int ea = m68k->ir & 0x3f;
1610   int dir = (w2 >> 13) & 0x1;
1611   int regsel = (w2 >> 10) & 0x7;
1612   int mode = (ea >> 3) & 0x7;
1613
1614   if ((mode == 5) || (mode == 6))
1615   {
1616      UINT32 address = 0xffffffff;    // force a bus error if this doesn't get assigned
1617
1618      if (mode == 5)
1619      {
1620         address = EA_AY_DI_32(m68k);
1621      }
1622      else if (mode == 6)
1623      {
1624         address = EA_AY_IX_32(m68k);
1625      }
1626
1627      if (dir)    // From system control reg to <ea>
1628      {
1629         if (regsel & 4) { m68ki_write_32(m68k, address, REG_FPCR(m68k)); address += 4; }
1630         if (regsel & 2) { m68ki_write_32(m68k, address, REG_FPSR(m68k)); address += 4; }
1631         if (regsel & 1) { m68ki_write_32(m68k, address, REG_FPIAR(m68k)); address += 4; }
1632      }
1633      else        // From <ea> to system control reg
1634      {
1635         if (regsel & 4) { REG_FPCR(m68k) = m68ki_read_32(m68k, address); address += 4; }
1636         if (regsel & 2) { REG_FPSR(m68k) = m68ki_read_32(m68k, address); address += 4; }
1637         if (regsel & 1) { REG_FPIAR(m68k) = m68ki_read_32(m68k, address); address += 4; }
1638      }
1639   }
1640   else
1641   {
1642      if (dir)    // From system control reg to <ea>
1643      {
1644         if (regsel & 4) WRITE_EA_32(m68k, ea, REG_FPCR(m68k));
1645         if (regsel & 2) WRITE_EA_32(m68k, ea, REG_FPSR(m68k));
1646         if (regsel & 1) WRITE_EA_32(m68k, ea, REG_FPIAR(m68k));
1647      }
1648      else        // From <ea> to system control reg
1649      {
1650         if (regsel & 4) REG_FPCR(m68k) = READ_EA_32(m68k, ea);
1651         if (regsel & 2) REG_FPSR(m68k) = READ_EA_32(m68k, ea);
1652         if (regsel & 1) REG_FPIAR(m68k) = READ_EA_32(m68k, ea);
1653      }
1654   }
1655
1656#if 0
1657   // FIXME: (2011-12-18 ost)
1658   // rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
1659   // but:  with this code on Apollo the following programs in /systest/fptest will fail:
1660   // 1. Single Precision Whetstone will return wrong results never the less
1661   // 2. Vector Test will fault with 00040004: reference to illegal address
1662
1663   if ((regsel & 4) && dir == 0)
1664   {
1665      int rnd = (REG_FPCR(m68k) >> 4) & 3;
1666      int prec = (REG_FPCR(m68k) >> 6) & 3;
1667
1668      logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", REG_FPCR(m68k), prec, rnd);
1669
1670#ifdef FLOATX80
1671      switch (prec)
1672      {
1673      case 0: // Extend (X)
1674         floatx80_rounding_precision = 80;
1675         break;
1676      case 1: // Single (S)
1677         floatx80_rounding_precision = 32;
1678         break;
1679      case 2: // Double (D)
1680         floatx80_rounding_precision = 64;
1681         break;
1682      case 3: // Undefined
1683         floatx80_rounding_precision = 80;
1684         break;
1685      }
1686#endif
1687
1688      switch (rnd)
1689      {
1690      case 0: // To Nearest (RN)
1691         float_rounding_mode = float_round_nearest_even;
1692         break;
1693      case 1: // To Zero (RZ)
1694         float_rounding_mode = float_round_to_zero;
1695         break;
1696      case 2: // To Minus Infinitiy (RM)
1697         float_rounding_mode = float_round_down;
1698         break;
1699      case 3: // To Plus Infinitiy (RP)
1700         float_rounding_mode = float_round_up;
1701         break;
1702      }
1703   }
1704#endif
1705
1706   m68k->remaining_cycles -= 10;
1707}
1708
1709static void fmovem(m68000_base_device *m68k, UINT16 w2)
1710{
1711   int i;
1712   int ea = m68k->ir & 0x3f;
1713   int dir = (w2 >> 13) & 0x1;
1714   int mode = (w2 >> 11) & 0x3;
1715   int reglist = w2 & 0xff;
1716
1717   UINT32 mem_addr = 0;
1718   switch (ea >> 3)
1719   {
1720      case 5:     // (d16, An)
1721         mem_addr= EA_AY_DI_32(m68k);
1722         break;
1723      case 6:     // (An) + (Xn) + d8
1724         mem_addr= EA_AY_IX_32(m68k);
1725         break;
1726   }
1727
1728   if (dir)    // From FP regs to mem
1729   {
1730      switch (mode)
1731      {
1732         case 1: // Dynamic register list, postincrement or control addressing mode.
1733            // FIXME: not really tested, but seems to work
1734            reglist = REG_D(m68k)[(reglist >> 4) & 7];
1735
1736         case 0:     // Static register list, predecrement or control addressing mode
1737         {
1738            for (i=0; i < 8; i++)
1739            {
1740               if (reglist & (1 << i))
1741               {
1742                  switch (ea >> 3)
1743                  {
1744                     case 5:     // (d16, An)
1745                     case 6:     // (An) + (Xn) + d8
1746                        store_extended_float80(m68k, mem_addr, REG_FP(m68k)[i]);
1747                        mem_addr += 12;
1748                        break;
1749                     default:
1750                        WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[i]);
1751                        break;
1752                  }
1753
1754                  m68k->remaining_cycles -= 2;
1755               }
1756            }
1757            break;
1758         }
1759
1760         case 2:     // Static register list, postdecrement or control addressing mode
1761         {
1762            for (i=0; i < 8; i++)
1763            {
1764               if (reglist & (1 << i))
1765               {
1766                  switch (ea >> 3)
1767                  {
1768                     case 5:     // (d16, An)
1769                     case 6:     // (An) + (Xn) + d8
1770                        store_extended_float80(m68k, mem_addr, REG_FP(m68k)[7-i]);
1771                        mem_addr += 12;
1772                        break;
1773                     default:
1774                        WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[7-i]);
1775                        break;
1776                  }
1777
1778                  m68k->remaining_cycles -= 2;
1779               }
1780            }
1781            break;
1782         }
1783
1784         default:    fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC(m68k)-4);
1785      }
1786   }
1787   else        // From mem to FP regs
1788   {
1789      switch (mode)
1790      {
1791         case 3: // Dynamic register list, predecrement addressing mode.
1792            // FIXME: not really tested, but seems to work
1793            reglist = REG_D(m68k)[(reglist >> 4) & 7];
1794
1795         case 2:     // Static register list, postincrement or control addressing mode
1796         {
1797            for (i=0; i < 8; i++)
1798            {
1799               if (reglist & (1 << i))
1800               {
1801                  switch (ea >> 3)
1802                  {
1803                     case 5:     // (d16, An)
1804                     case 6:     // (An) + (Xn) + d8
1805                        REG_FP(m68k)[7-i] = load_extended_float80(m68k, mem_addr);
1806                        mem_addr += 12;
1807                        break;
1808                     default:
1809                        REG_FP(m68k)[7-i] = READ_EA_FPE(m68k, ea);
1810                        break;
1811                  }
1812                  m68k->remaining_cycles -= 2;
1813               }
1814            }
1815            break;
1816         }
1817
1818         default:    fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC(m68k)-4);
1819      }
1820   }
1821}
1822
1823static void fscc(m68000_base_device *m68k)
1824{
1825   int ea = m68k->ir & 0x3f;
1826   int condition = (INT16)(OPER_I_16(m68k));
1827
1828   WRITE_EA_8(m68k, ea, TEST_CONDITION(m68k, condition) ? 0xff : 0);
1829   m68k->remaining_cycles -= 7; // ???
1830}
1831
1832static void fbcc16(m68000_base_device *m68k)
1833{
1834   INT32 offset;
1835   int condition = m68k->ir & 0x3f;
1836
1837   offset = (INT16)(OPER_I_16(m68k));
1838
1839   // TODO: condition and jump!!!
1840   if (TEST_CONDITION(m68k, condition))
1841   {
1842      m68ki_trace_t0(m68k);              /* auto-disable (see m68kcpu.h) */
1843      m68ki_branch_16(m68k, offset-2);
1844   }
1845
1846   m68k->remaining_cycles -= 7;
1847}
1848
1849static void fbcc32(m68000_base_device *m68k)
1850{
1851   INT32 offset;
1852   int condition = m68k->ir & 0x3f;
1853
1854   offset = OPER_I_32(m68k);
1855
1856   // TODO: condition and jump!!!
1857   if (TEST_CONDITION(m68k, condition))
1858   {
1859      m68ki_trace_t0(m68k);              /* auto-disable (see m68kcpu.h) */
1860      m68ki_branch_32(m68k, offset-4);
1861   }
1862
1863   m68k->remaining_cycles -= 7;
1864}
1865
1866
1867void m68040_fpu_op0(m68000_base_device *m68k)
1868{
1869   m68k->fpu_just_reset = 0;
1870
1871   switch ((m68k->ir >> 6) & 0x3)
1872   {
1873      case 0:
1874      {
1875         UINT16 w2 = OPER_I_16(m68k);
1876         switch ((w2 >> 13) & 0x7)
1877         {
1878            case 0x0:   // FPU ALU FP, FP
1879            case 0x2:   // FPU ALU ea, FP
1880            {
1881               fpgen_rm_reg(m68k, w2);
1882               break;
1883            }
1884
1885            case 0x3:   // FMOVE FP, ea
1886            {
1887               fmove_reg_mem(m68k, w2);
1888               break;
1889            }
1890
1891            case 0x4:   // FMOVEM ea, FPCR
1892            case 0x5:   // FMOVEM FPCR, ea
1893            {
1894               fmove_fpcr(m68k, w2);
1895               break;
1896            }
1897
1898            case 0x6:   // FMOVEM ea, list
1899            case 0x7:   // FMOVEM list, ea
1900            {
1901               fmovem(m68k, w2);
1902               break;
1903            }
1904
1905            default:    fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC(m68k)-4);
1906         }
1907         break;
1908      }
1909
1910      case 1:     // FBcc disp16
1911      {
1912         switch ((m68k->ir >> 3) & 0x7) {
1913         case 1: // FDBcc
1914            // TODO:
1915            break;
1916         default: // FScc (?)
1917            fscc(m68k);
1918            return;
1919         }
1920         fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (m68k->ir >> 6) & 0x3, (m68k->ir >> 3) & 0x7, REG_PPC(m68k));
1921      }
1922
1923      case 2:     // FBcc disp16
1924      {
1925         fbcc16(m68k);
1926         break;
1927      }
1928      case 3:     // FBcc disp32
1929      {
1930         fbcc32(m68k);
1931         break;
1932      }
1933
1934      default:    fatalerror("M68kFPU: unimplemented main op %d\n", (m68k->ir >> 6)   & 0x3);
1935   }
1936}
1937
1938static int perform_fsave(m68000_base_device *m68k, UINT32 addr, int inc)
1939{
1940   if(m68k->cpu_type & CPU_TYPE_040)
1941   {
1942      if(inc)
1943      {
1944         m68ki_write_32(m68k, addr, 0x41000000);
1945         return 4;
1946      }
1947      else
1948      {
1949         m68ki_write_32(m68k, addr-4, 0x41000000);
1950         return -4;
1951      }
1952   }
1953
1954   if (inc)
1955   {
1956      // 68881 IDLE, version 0x1f
1957      m68ki_write_32(m68k, addr, 0x1f180000);
1958      m68ki_write_32(m68k, addr+4, 0);
1959      m68ki_write_32(m68k, addr+8, 0);
1960      m68ki_write_32(m68k, addr+12, 0);
1961      m68ki_write_32(m68k, addr+16, 0);
1962      m68ki_write_32(m68k, addr+20, 0);
1963      m68ki_write_32(m68k, addr+24, 0x70000000);
1964      return 7*4;
1965   }
1966   else
1967   {
1968      m68ki_write_32(m68k, addr-4, 0x70000000);
1969      m68ki_write_32(m68k, addr-8, 0);
1970      m68ki_write_32(m68k, addr-12, 0);
1971      m68ki_write_32(m68k, addr-16, 0);
1972      m68ki_write_32(m68k, addr-20, 0);
1973      m68ki_write_32(m68k, addr-24, 0);
1974      m68ki_write_32(m68k, addr-28, 0x1f180000);
1975      return -7*4;
1976   }
1977}
1978
1979// FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
1980static void do_frestore_null(m68000_base_device *m68k)
1981{
1982   int i;
1983
1984   REG_FPCR(m68k) = 0;
1985   REG_FPSR(m68k) = 0;
1986   REG_FPIAR(m68k) = 0;
1987   for (i = 0; i < 8; i++)
1988   {
1989      REG_FP(m68k)[i].high = 0x7fff;
1990      REG_FP(m68k)[i].low = U64(0xffffffffffffffff);
1991   }
1992
1993   // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL
1994   // The PRM says it's possible to generate a NULL frame, but not how/when/why.  (need the 68881/68882 manual!)
1995   m68k->fpu_just_reset = 1;
1996}
1997
1998static void m68040_do_fsave(m68000_base_device *m68k, UINT32 addr, int reg, int inc)
1999{
2000   if (m68k->fpu_just_reset)
2001   {
2002         m68ki_write_32(m68k, addr, 0);
2003   }
2004   else
2005   {
2006      // we normally generate an IDLE frame
2007      int delta = perform_fsave(m68k, addr, inc);
2008      if(reg != -1)
2009         REG_A(m68k)[reg] += delta;
2010   }
2011}
2012
2013static void m68040_do_frestore(m68000_base_device *m68k, UINT32 addr, int reg)
2014{
2015   bool m40 = m68k->cpu_type & CPU_TYPE_040;
2016   UINT32 temp = m68ki_read_32(m68k, addr);
2017
2018   // check for NULL frame
2019   if (temp & 0xff000000)
2020   {
2021      // we don't handle non-NULL frames
2022      m68k->fpu_just_reset = 0;
2023
2024      if (reg != -1)
2025      {
2026         // how about an IDLE frame?
2027         if (!m40 && ((temp & 0x00ff0000) == 0x00180000))
2028         {
2029            REG_A(m68k)[reg] += 7*4;
2030         }
2031         else if (m40 && ((temp & 0xffff0000) == 0x41000000))
2032         {
2033            REG_A(m68k)[reg] += 4;
2034         } // check UNIMP
2035         else if ((temp & 0x00ff0000) == 0x00380000)
2036         {
2037            REG_A(m68k)[reg] += 14*4;
2038         } // check BUSY
2039         else if ((temp & 0x00ff0000) == 0x00b40000)
2040         {
2041            REG_A(m68k)[reg] += 45*4;
2042         }
2043      }
2044   }
2045   else
2046   {
2047      do_frestore_null(m68k);
2048   }
2049}
2050
2051void m68040_fpu_op1(m68000_base_device *m68k)
2052{
2053   int ea = m68k->ir & 0x3f;
2054   int mode = (ea >> 3) & 0x7;
2055   int reg = (ea & 0x7);
2056   UINT32 addr;
2057
2058   switch ((m68k->ir >> 6) & 0x3)
2059   {
2060      case 0:     // FSAVE <ea>
2061      {
2062         switch (mode)
2063         {
2064         case 2: // (An)
2065            addr = REG_A(m68k)[reg];
2066            m68040_do_fsave(m68k, addr, -1, 1);
2067            break;
2068
2069         case 3: // (An)+
2070            addr = EA_AY_PI_32(m68k);
2071            m68040_do_fsave(m68k, addr, reg, 1);
2072            break;
2073
2074         case 4: // -(An)
2075            addr = EA_AY_PD_32(m68k);
2076            m68040_do_fsave(m68k, addr, reg, 0);
2077            break;
2078
2079         case 5: // (D16, An)
2080            addr = EA_AY_DI_16(m68k);
2081            m68040_do_fsave(m68k, addr, -1, 1);
2082            break;
2083
2084         case 7: //
2085            switch (reg)
2086            {
2087               case 1:     // (abs32)
2088               {
2089                  addr = EA_AL_32(m68k);
2090                  m68040_do_fsave(m68k, addr, -1, 1);
2091                  break;
2092               }
2093               case 2:     // (d16, PC)
2094               {
2095                  addr = EA_PCDI_16(m68k);
2096                  m68040_do_fsave(m68k, addr, -1, 1);
2097                  break;
2098               }
2099               default:
2100                  fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC(m68k));
2101            }
2102
2103            break;
2104
2105         default:
2106            fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC(m68k));
2107         }
2108         break;
2109      }
2110      break;
2111
2112      case 1:     // FRESTORE <ea>
2113      {
2114         switch (mode)
2115         {
2116         case 2: // (An)
2117            addr = REG_A(m68k)[reg];
2118            m68040_do_frestore(m68k, addr, -1);
2119            break;
2120
2121         case 3: // (An)+
2122            addr = EA_AY_PI_32(m68k);
2123            m68040_do_frestore(m68k, addr, reg);
2124            break;
2125
2126         case 5: // (D16, An)
2127            addr = EA_AY_DI_16(m68k);
2128            m68040_do_frestore(m68k, addr, -1);
2129            break;
2130
2131         case 7: //
2132            switch (reg)
2133            {
2134               case 1:     // (abs32)
2135               {
2136                  addr = EA_AL_32(m68k);
2137                  m68040_do_frestore(m68k, addr, -1);
2138                  break;
2139               }
2140               case 2:     // (d16, PC)
2141               {
2142                  addr = EA_PCDI_16(m68k);
2143                  m68040_do_frestore(m68k, addr, -1);
2144                  break;
2145               }
2146               default:
2147                  fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC(m68k));
2148            }
2149
2150            break;
2151
2152         default:
2153            fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC(m68k));
2154         }
2155         break;
2156      }
2157      break;
2158
2159      default:    fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (m68k->ir >> 6) & 0x3, REG_PC(m68k)-2);
2160   }
2161}
Property changes on: trunk/src/emu/cpu/m68000/m68kfpu.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/m68000/m68kcpu.c
r28738r28739
3737#include "m68kcpu.h"
3838#include "m68kops.h"
3939
40#include "m68kfpu.c"
40#include "m68kfpu.inc"
4141#include "m68kmmu.h"
4242
4343extern void m68040_fpu_op0(m68000_base_device *m68k);
trunk/src/emu/cpu/m6800/6800ops.c
r28738r28739
1
2/*
3
4HNZVC
5
6? = undefined
7* = affected
8- = unaffected
90 = cleared
101 = set
11# = ccr directly affected by instruction
12@ = special - carry set if bit 7 is set
13
14*/
15
16#define OP_HANDLER(_name) void m6800_cpu_device::_name ()
17
18//OP_HANDLER( illegal )
19OP_HANDLER( illegal )
20{
21   logerror("m6800: illegal opcode: address %04X, op %02X\n",PC-1,(int) M_RDOP_ARG(PC-1)&0xFF);
22}
23
24/* HD63701 only */
25//OP_HANDLER( trap )
26OP_HANDLER( trap )
27{
28   logerror("m6800: illegal opcode: address %04X, op %02X\n",PC-1,(int) M_RDOP_ARG(PC-1)&0xFF);
29   TAKE_TRAP;
30}
31
32/* $00 ILLEGAL */
33
34/* $01 NOP */
35OP_HANDLER( nop )
36{
37}
38
39/* $02 ILLEGAL */
40
41/* $03 ILLEGAL */
42
43/* $04 LSRD inherent -0*-* */
44OP_HANDLER( lsrd )
45{
46   UINT16 t;
47   CLR_NZC; t = D; CC|=(t&0x0001);
48   t>>=1; SET_Z16(t); D=t;
49}
50
51/* $05 ASLD inherent ?**** */
52OP_HANDLER( asld )
53{
54   int r;
55   UINT16 t;
56   t = D; r=t<<1;
57   CLR_NZVC; SET_FLAGS16(t,t,r);
58   D=r;
59}
60
61/* $06 TAP inherent ##### */
62OP_HANDLER( tap )
63{
64   CC=A;
65   ONE_MORE_INSN();
66   CHECK_IRQ_LINES(); /* HJB 990417 */
67}
68
69/* $07 TPA inherent ----- */
70OP_HANDLER( tpa )
71{
72   A=CC;
73}
74
75/* $08 INX inherent --*-- */
76OP_HANDLER( inx )
77{
78   ++X;
79   CLR_Z; SET_Z16(X);
80}
81
82/* $09 DEX inherent --*-- */
83OP_HANDLER( dex )
84{
85   --X;
86   CLR_Z; SET_Z16(X);
87}
88
89/* $0a CLV */
90OP_HANDLER( clv )
91{
92   CLV;
93}
94
95/* $0b SEV */
96OP_HANDLER( sev )
97{
98   SEV;
99}
100
101/* $0c CLC */
102OP_HANDLER( clc )
103{
104   CLC;
105}
106
107/* $0d SEC */
108OP_HANDLER( sec )
109{
110   SEC;
111}
112
113/* $0e CLI */
114OP_HANDLER( cli )
115{
116   CLI;
117   ONE_MORE_INSN();
118   CHECK_IRQ_LINES(); /* HJB 990417 */
119}
120
121/* $0f SEI */
122OP_HANDLER( sei )
123{
124   SEI;
125   ONE_MORE_INSN();
126   CHECK_IRQ_LINES(); /* HJB 990417 */
127}
128
129/* $10 SBA inherent -**** */
130OP_HANDLER( sba )
131{
132   UINT16 t;
133   t=A-B;
134   CLR_NZVC; SET_FLAGS8(A,B,t);
135   A=t;
136}
137
138/* $11 CBA inherent -**** */
139OP_HANDLER( cba )
140{
141   UINT16 t;
142   t=A-B;
143   CLR_NZVC; SET_FLAGS8(A,B,t);
144}
145
146/* $12 ILLEGAL */
147OP_HANDLER( undoc1 )
148{
149   X += RM( S + 1 );
150}
151
152/* $13 ILLEGAL */
153OP_HANDLER( undoc2 )
154{
155   X += RM( S + 1 );
156}
157
158
159/* $14 ILLEGAL */
160
161/* $15 ILLEGAL */
162
163/* $16 TAB inherent -**0- */
164OP_HANDLER( tab )
165{
166   B=A;
167   CLR_NZV; SET_NZ8(B);
168}
169
170/* $17 TBA inherent -**0- */
171OP_HANDLER( tba )
172{
173   A=B;
174   CLR_NZV; SET_NZ8(A);
175}
176
177/* $18 XGDX inherent ----- */ /* HD63701YO only */
178OP_HANDLER( xgdx )
179{
180   UINT16 t = X;
181   X = D;
182   D=t;
183}
184
185/* $19 DAA inherent (A) -**0* */
186OP_HANDLER( daa )
187{
188   UINT8 msn, lsn;
189   UINT16 t, cf = 0;
190   msn=A & 0xf0; lsn=A & 0x0f;
191   if( lsn>0x09 || CC&0x20 ) cf |= 0x06;
192   if( msn>0x80 && lsn>0x09 ) cf |= 0x60;
193   if( msn>0x90 || CC&0x01 ) cf |= 0x60;
194   t = cf + A;
195   CLR_NZV; /* keep carry from previous operation */
196   SET_NZ8((UINT8)t); SET_C8(t);
197   A = t;
198}
199
200/* $1a ILLEGAL */
201
202/* $1a SLP */ /* HD63701YO only */
203OP_HANDLER( slp )
204{
205   /* wait for next IRQ (same as waiting of wai) */
206   m_wai_state |= M6800_SLP;
207   EAT_CYCLES;
208}
209
210/* $1b ABA inherent ***** */
211OP_HANDLER( aba )
212{
213   UINT16 t;
214   t=A+B;
215   CLR_HNZVC; SET_FLAGS8(A,B,t); SET_H(A,B,t);
216   A=t;
217}
218
219/* $1c ILLEGAL */
220
221/* $1d ILLEGAL */
222
223/* $1e ILLEGAL */
224
225/* $1f ILLEGAL */
226
227/* $20 BRA relative ----- */
228OP_HANDLER( bra )
229{
230   UINT8 t;
231   IMMBYTE(t);
232   PC+=SIGNED(t);
233}
234
235/* $21 BRN relative ----- */
236static UINT8 m6800_brn_t; // hack around GCC 4.6 error because we need the side effects of IMMBYTE
237OP_HANDLER( brn )
238{
239   IMMBYTE(m6800_brn_t);
240}
241
242/* $22 BHI relative ----- */
243OP_HANDLER( bhi )
244{
245   UINT8 t;
246   BRANCH(!(CC&0x05));
247}
248
249/* $23 BLS relative ----- */
250OP_HANDLER( bls )
251{
252   UINT8 t;
253   BRANCH(CC&0x05);
254}
255
256/* $24 BCC relative ----- */
257OP_HANDLER( bcc )
258{
259   UINT8 t;
260   BRANCH(!(CC&0x01));
261}
262
263/* $25 BCS relative ----- */
264OP_HANDLER( bcs )
265{
266   UINT8 t;
267   BRANCH(CC&0x01);
268}
269
270/* $26 BNE relative ----- */
271OP_HANDLER( bne )
272{
273   UINT8 t;
274   BRANCH(!(CC&0x04));
275}
276
277/* $27 BEQ relative ----- */
278OP_HANDLER( beq )
279{
280   UINT8 t;
281   BRANCH(CC&0x04);
282}
283
284/* $28 BVC relative ----- */
285OP_HANDLER( bvc )
286{
287   UINT8 t;
288   BRANCH(!(CC&0x02));
289}
290
291/* $29 BVS relative ----- */
292OP_HANDLER( bvs )
293{
294   UINT8 t;
295   BRANCH(CC&0x02);
296}
297
298/* $2a BPL relative ----- */
299OP_HANDLER( bpl )
300{
301   UINT8 t;
302   BRANCH(!(CC&0x08));
303}
304
305/* $2b BMI relative ----- */
306OP_HANDLER( bmi )
307{
308   UINT8 t;
309   BRANCH(CC&0x08);
310}
311
312/* $2c BGE relative ----- */
313OP_HANDLER( bge )
314{
315   UINT8 t;
316   BRANCH(!NXORV);
317}
318
319/* $2d BLT relative ----- */
320OP_HANDLER( blt )
321{
322   UINT8 t;
323   BRANCH(NXORV);
324}
325
326/* $2e BGT relative ----- */
327OP_HANDLER( bgt )
328{
329   UINT8 t;
330   BRANCH(!(NXORV||CC&0x04));
331}
332
333/* $2f BLE relative ----- */
334OP_HANDLER( ble )
335{
336   UINT8 t;
337   BRANCH(NXORV||CC&0x04);
338}
339
340/* $30 TSX inherent ----- */
341OP_HANDLER( tsx )
342{
343   X = ( S + 1 );
344}
345
346/* $31 INS inherent ----- */
347OP_HANDLER( ins )
348{
349   ++S;
350}
351
352/* $32 PULA inherent ----- */
353OP_HANDLER( pula )
354{
355   PULLBYTE(m_d.b.h);
356}
357
358/* $33 PULB inherent ----- */
359OP_HANDLER( pulb )
360{
361   PULLBYTE(m_d.b.l);
362}
363
364/* $34 DES inherent ----- */
365OP_HANDLER( des )
366{
367   --S;
368}
369
370/* $35 TXS inherent ----- */
371OP_HANDLER( txs )
372{
373   S = ( X - 1 );
374}
375
376/* $36 PSHA inherent ----- */
377OP_HANDLER( psha )
378{
379   PUSHBYTE(m_d.b.h);
380}
381
382/* $37 PSHB inherent ----- */
383OP_HANDLER( pshb )
384{
385   PUSHBYTE(m_d.b.l);
386}
387
388/* $38 PULX inherent ----- */
389OP_HANDLER( pulx )
390{
391   PULLWORD(pX);
392}
393
394/* $39 RTS inherent ----- */
395OP_HANDLER( rts )
396{
397   PULLWORD(pPC);
398}
399
400/* $3a ABX inherent ----- */
401OP_HANDLER( abx )
402{
403   X += B;
404}
405
406/* $3b RTI inherent ##### */
407OP_HANDLER( rti )
408{
409   PULLBYTE(CC);
410   PULLBYTE(B);
411   PULLBYTE(A);
412   PULLWORD(pX);
413   PULLWORD(pPC);
414   CHECK_IRQ_LINES(); /* HJB 990417 */
415}
416
417/* $3c PSHX inherent ----- */
418OP_HANDLER( pshx )
419{
420   PUSHWORD(pX);
421}
422
423/* $3d MUL inherent --*-@ */
424OP_HANDLER( mul )
425{
426   UINT16 t;
427   t=A*B;
428   CLR_C;
429   if(t&0x80) SEC;
430   D=t;
431}
432
433/* $3e WAI inherent ----- */
434OP_HANDLER( wai )
435{
436   /*
437    * WAI stacks the entire machine state on the
438    * hardware stack, then waits for an interrupt.
439    */
440   m_wai_state |= M6800_WAI;
441   PUSHWORD(pPC);
442   PUSHWORD(pX);
443   PUSHBYTE(A);
444   PUSHBYTE(B);
445   PUSHBYTE(CC);
446   CHECK_IRQ_LINES();
447   if (m_wai_state & M6800_WAI) EAT_CYCLES;
448}
449
450/* $3f SWI absolute indirect ----- */
451OP_HANDLER( swi )
452{
453   PUSHWORD(pPC);
454   PUSHWORD(pX);
455   PUSHBYTE(A);
456   PUSHBYTE(B);
457   PUSHBYTE(CC);
458   SEI;
459   PCD = RM16(0xfffa);
460}
461
462/* $40 NEGA inherent ?**** */
463OP_HANDLER( nega )
464{
465   UINT16 r;
466   r=-A;
467   CLR_NZVC; SET_FLAGS8(0,A,r);
468   A=r;
469}
470
471/* $41 ILLEGAL */
472
473/* $42 ILLEGAL */
474
475/* $43 COMA inherent -**01 */
476OP_HANDLER( coma )
477{
478   A = ~A;
479   CLR_NZV; SET_NZ8(A); SEC;
480}
481
482/* $44 LSRA inherent -0*-* */
483OP_HANDLER( lsra )
484{
485   CLR_NZC; CC|=(A&0x01);
486   A>>=1; SET_Z8(A);
487}
488
489/* $45 ILLEGAL */
490
491/* $46 RORA inherent -**-* */
492OP_HANDLER( rora )
493{
494   UINT8 r;
495   r=(CC&0x01)<<7;
496   CLR_NZC; CC|=(A&0x01);
497   r |= A>>1; SET_NZ8(r);
498   A=r;
499}
500
501/* $47 ASRA inherent ?**-* */
502OP_HANDLER( asra )
503{
504   CLR_NZC; CC|=(A&0x01);
505   A>>=1; A|=((A&0x40)<<1);
506   SET_NZ8(A);
507}
508
509/* $48 ASLA inherent ?**** */
510OP_HANDLER( asla )
511{
512   UINT16 r;
513   r=A<<1;
514   CLR_NZVC; SET_FLAGS8(A,A,r);
515   A=r;
516}
517
518/* $49 ROLA inherent -**** */
519OP_HANDLER( rola )
520{
521   UINT16 t,r;
522   t = A; r = CC&0x01; r |= t<<1;
523   CLR_NZVC; SET_FLAGS8(t,t,r);
524   A=r;
525}
526
527/* $4a DECA inherent -***- */
528OP_HANDLER( deca )
529{
530   --A;
531   CLR_NZV; SET_FLAGS8D(A);
532}
533
534/* $4b ILLEGAL */
535
536/* $4c INCA inherent -***- */
537OP_HANDLER( inca )
538{
539   ++A;
540   CLR_NZV; SET_FLAGS8I(A);
541}
542
543/* $4d TSTA inherent -**0- */
544OP_HANDLER( tsta )
545{
546   CLR_NZVC; SET_NZ8(A);
547}
548
549/* $4e ILLEGAL */
550
551/* $4f CLRA inherent -0100 */
552OP_HANDLER( clra )
553{
554   A=0;
555   CLR_NZVC; SEZ;
556}
557
558/* $50 NEGB inherent ?**** */
559OP_HANDLER( negb )
560{
561   UINT16 r;
562   r=-B;
563   CLR_NZVC; SET_FLAGS8(0,B,r);
564   B=r;
565}
566
567/* $51 ILLEGAL */
568
569/* $52 ILLEGAL */
570
571/* $53 COMB inherent -**01 */
572OP_HANDLER( comb )
573{
574   B = ~B;
575   CLR_NZV; SET_NZ8(B); SEC;
576}
577
578/* $54 LSRB inherent -0*-* */
579OP_HANDLER( lsrb )
580{
581   CLR_NZC; CC|=(B&0x01);
582   B>>=1; SET_Z8(B);
583}
584
585/* $55 ILLEGAL */
586
587/* $56 RORB inherent -**-* */
588OP_HANDLER( rorb )
589{
590   UINT8 r;
591   r=(CC&0x01)<<7;
592   CLR_NZC; CC|=(B&0x01);
593   r |= B>>1; SET_NZ8(r);
594   B=r;
595}
596
597/* $57 ASRB inherent ?**-* */
598OP_HANDLER( asrb )
599{
600   CLR_NZC; CC|=(B&0x01);
601   B>>=1; B|=((B&0x40)<<1);
602   SET_NZ8(B);
603}
604
605/* $58 ASLB inherent ?**** */
606OP_HANDLER( aslb )
607{
608   UINT16 r;
609   r=B<<1;
610   CLR_NZVC; SET_FLAGS8(B,B,r);
611   B=r;
612}
613
614/* $59 ROLB inherent -**** */
615OP_HANDLER( rolb )
616{
617   UINT16 t,r;
618   t = B; r = CC&0x01; r |= t<<1;
619   CLR_NZVC; SET_FLAGS8(t,t,r);
620   B=r;
621}
622
623/* $5a DECB inherent -***- */
624OP_HANDLER( decb )
625{
626   --B;
627   CLR_NZV; SET_FLAGS8D(B);
628}
629
630/* $5b ILLEGAL */
631
632/* $5c INCB inherent -***- */
633OP_HANDLER( incb )
634{
635   ++B;
636   CLR_NZV; SET_FLAGS8I(B);
637}
638
639/* $5d TSTB inherent -**0- */
640OP_HANDLER( tstb )
641{
642   CLR_NZVC; SET_NZ8(B);
643}
644
645/* $5e ILLEGAL */
646
647/* $5f CLRB inherent -0100 */
648OP_HANDLER( clrb )
649{
650   B=0;
651   CLR_NZVC; SEZ;
652}
653
654/* $60 NEG indexed ?**** */
655OP_HANDLER( neg_ix )
656{
657   UINT16 r,t;
658   IDXBYTE(t); r=-t;
659   CLR_NZVC; SET_FLAGS8(0,t,r);
660   WM(EAD,r);
661}
662
663/* $61 AIM --**0- */ /* HD63701YO only */
664OP_HANDLER( aim_ix )
665{
666   UINT8 t, r;
667   IMMBYTE(t);
668   IDXBYTE(r);
669   r &= t;
670   CLR_NZV; SET_NZ8(r);
671   WM(EAD,r);
672}
673
674/* $62 OIM --**0- */ /* HD63701YO only */
675OP_HANDLER( oim_ix )
676{
677   UINT8 t, r;
678   IMMBYTE(t);
679   IDXBYTE(r);
680   r |= t;
681   CLR_NZV; SET_NZ8(r);
682   WM(EAD,r);
683}
684
685/* $63 COM indexed -**01 */
686OP_HANDLER( com_ix )
687{
688   UINT8 t;
689   IDXBYTE(t); t = ~t;
690   CLR_NZV; SET_NZ8(t); SEC;
691   WM(EAD,t);
692}
693
694/* $64 LSR indexed -0*-* */
695OP_HANDLER( lsr_ix )
696{
697   UINT8 t;
698   IDXBYTE(t); CLR_NZC; CC|=(t&0x01);
699   t>>=1; SET_Z8(t);
700   WM(EAD,t);
701}
702
703/* $65 EIM --**0- */ /* HD63701YO only */
704OP_HANDLER( eim_ix )
705{
706   UINT8 t, r;
707   IMMBYTE(t);
708   IDXBYTE(r);
709   r ^= t;
710   CLR_NZV; SET_NZ8(r);
711   WM(EAD,r);
712}
713
714/* $66 ROR indexed -**-* */
715OP_HANDLER( ror_ix )
716{
717   UINT8 t,r;
718   IDXBYTE(t); r=(CC&0x01)<<7;
719   CLR_NZC; CC|=(t&0x01);
720   r |= t>>1; SET_NZ8(r);
721   WM(EAD,r);
722}
723
724/* $67 ASR indexed ?**-* */
725OP_HANDLER( asr_ix )
726{
727   UINT8 t;
728   IDXBYTE(t); CLR_NZC; CC|=(t&0x01);
729   t>>=1; t|=((t&0x40)<<1);
730   SET_NZ8(t);
731   WM(EAD,t);
732}
733
734/* $68 ASL indexed ?**** */
735OP_HANDLER( asl_ix )
736{
737   UINT16 t,r;
738   IDXBYTE(t); r=t<<1;
739   CLR_NZVC; SET_FLAGS8(t,t,r);
740   WM(EAD,r);
741}
742
743/* $69 ROL indexed -**** */
744OP_HANDLER( rol_ix )
745{
746   UINT16 t,r;
747   IDXBYTE(t); r = CC&0x01; r |= t<<1;
748   CLR_NZVC; SET_FLAGS8(t,t,r);
749   WM(EAD,r);
750}
751
752/* $6a DEC indexed -***- */
753OP_HANDLER( dec_ix )
754{
755   UINT8 t;
756   IDXBYTE(t); --t;
757   CLR_NZV; SET_FLAGS8D(t);
758   WM(EAD,t);
759}
760
761/* $6b TIM --**0- */ /* HD63701YO only */
762OP_HANDLER( tim_ix )
763{
764   UINT8 t, r;
765   IMMBYTE(t);
766   IDXBYTE(r);
767   r &= t;
768   CLR_NZV; SET_NZ8(r);
769}
770
771/* $6c INC indexed -***- */
772OP_HANDLER( inc_ix )
773{
774   UINT8 t;
775   IDXBYTE(t); ++t;
776   CLR_NZV; SET_FLAGS8I(t);
777   WM(EAD,t);
778}
779
780/* $6d TST indexed -**0- */
781OP_HANDLER( tst_ix )
782{
783   UINT8 t;
784   IDXBYTE(t); CLR_NZVC; SET_NZ8(t);
785}
786
787/* $6e JMP indexed ----- */
788OP_HANDLER( jmp_ix )
789{
790   INDEXED; PC=EA;
791}
792
793/* $6f CLR indexed -0100 */
794OP_HANDLER( clr_ix )
795{
796   INDEXED; WM(EAD,0);
797   CLR_NZVC; SEZ;
798}
799
800/* $70 NEG extended ?**** */
801OP_HANDLER( neg_ex )
802{
803   UINT16 r,t;
804   EXTBYTE(t); r=-t;
805   CLR_NZVC; SET_FLAGS8(0,t,r);
806   WM(EAD,r);
807}
808
809/* $71 AIM --**0- */ /* HD63701YO only */
810OP_HANDLER( aim_di )
811{
812   UINT8 t, r;
813   IMMBYTE(t);
814   DIRBYTE(r);
815   r &= t;
816   CLR_NZV; SET_NZ8(r);
817   WM(EAD,r);
818}
819
820/* $72 OIM --**0- */ /* HD63701YO only */
821OP_HANDLER( oim_di )
822{
823   UINT8 t, r;
824   IMMBYTE(t);
825   DIRBYTE(r);
826   r |= t;
827   CLR_NZV; SET_NZ8(r);
828   WM(EAD,r);
829}
830
831/* $73 COM extended -**01 */
832OP_HANDLER( com_ex )
833{
834   UINT8 t;
835   EXTBYTE(t); t = ~t;
836   CLR_NZV; SET_NZ8(t); SEC;
837   WM(EAD,t);
838}
839
840/* $74 LSR extended -0*-* */
841OP_HANDLER( lsr_ex )
842{
843   UINT8 t;
844   EXTBYTE(t);
845   CLR_NZC;
846   CC|=(t&0x01);
847   t>>=1;
848   SET_Z8(t);
849   WM(EAD,t);
850}
851
852/* $75 EIM --**0- */ /* HD63701YO only */
853OP_HANDLER( eim_di )
854{
855   UINT8 t, r;
856   IMMBYTE(t);
857   DIRBYTE(r);
858   r ^= t;
859   CLR_NZV; SET_NZ8(r);
860   WM(EAD,r);
861}
862
863/* $76 ROR extended -**-* */
864OP_HANDLER( ror_ex )
865{
866   UINT8 t,r;
867   EXTBYTE(t); r=(CC&0x01)<<7;
868   CLR_NZC; CC|=(t&0x01);
869   r |= t>>1; SET_NZ8(r);
870   WM(EAD,r);
871}
872
873/* $77 ASR extended ?**-* */
874OP_HANDLER( asr_ex )
875{
876   UINT8 t;
877   EXTBYTE(t); CLR_NZC; CC|=(t&0x01);
878   t>>=1; t|=((t&0x40)<<1);
879   SET_NZ8(t);
880   WM(EAD,t);
881}
882
883/* $78 ASL extended ?**** */
884OP_HANDLER( asl_ex )
885{
886   UINT16 t,r;
887   EXTBYTE(t); r=t<<1;
888   CLR_NZVC; SET_FLAGS8(t,t,r);
889   WM(EAD,r);
890}
891
892/* $79 ROL extended -**** */
893OP_HANDLER( rol_ex )
894{
895   UINT16 t,r;
896   EXTBYTE(t); r = CC&0x01; r |= t<<1;
897   CLR_NZVC; SET_FLAGS8(t,t,r);
898   WM(EAD,r);
899}
900
901/* $7a DEC extended -***- */
902OP_HANDLER( dec_ex )
903{
904   UINT8 t;
905   EXTBYTE(t); --t;
906   CLR_NZV; SET_FLAGS8D(t);
907   WM(EAD,t);
908}
909
910/* $7b TIM --**0- */ /* HD63701YO only */
911OP_HANDLER( tim_di )
912{
913   UINT8 t, r;
914   IMMBYTE(t);
915   DIRBYTE(r);
916   r &= t;
917   CLR_NZV; SET_NZ8(r);
918}
919
920/* $7c INC extended -***- */
921OP_HANDLER( inc_ex )
922{
923   UINT8 t;
924   EXTBYTE(t); ++t;
925   CLR_NZV; SET_FLAGS8I(t);
926   WM(EAD,t);
927}
928
929/* $7d TST extended -**0- */
930OP_HANDLER( tst_ex )
931{
932   UINT8 t;
933   EXTBYTE(t); CLR_NZVC; SET_NZ8(t);
934}
935
936/* $7e JMP extended ----- */
937OP_HANDLER( jmp_ex )
938{
939   EXTENDED; PC=EA;
940}
941
942/* $7f CLR extended -0100 */
943OP_HANDLER( clr_ex )
944{
945   EXTENDED; WM(EAD,0);
946   CLR_NZVC; SEZ;
947}
948
949/* $80 SUBA immediate ?**** */
950OP_HANDLER( suba_im )
951{
952   UINT16    t,r;
953   IMMBYTE(t); r = A-t;
954   CLR_NZVC; SET_FLAGS8(A,t,r);
955   A = r;
956}
957
958/* $81 CMPA immediate ?**** */
959OP_HANDLER( cmpa_im )
960{
961   UINT16    t,r;
962   IMMBYTE(t); r = A-t;
963   CLR_NZVC; SET_FLAGS8(A,t,r);
964}
965
966/* $82 SBCA immediate ?**** */
967OP_HANDLER( sbca_im )
968{
969   UINT16    t,r;
970   IMMBYTE(t); r = A-t-(CC&0x01);
971   CLR_NZVC; SET_FLAGS8(A,t,r);
972   A = r;
973}
974
975/* $83 SUBD immediate -**** */
976OP_HANDLER( subd_im )
977{
978   UINT32 r,d;
979   PAIR b;
980   IMMWORD(b);
981   d = D;
982   r = d - b.d;
983   CLR_NZVC;
984   SET_FLAGS16(d,b.d,r);
985   D = r;
986}
987
988/* $84 ANDA immediate -**0- */
989OP_HANDLER( anda_im )
990{
991   UINT8 t;
992   IMMBYTE(t); A &= t;
993   CLR_NZV; SET_NZ8(A);
994}
995
996/* $85 BITA immediate -**0- */
997OP_HANDLER( bita_im )
998{
999   UINT8 t,r;
1000   IMMBYTE(t); r = A&t;
1001   CLR_NZV; SET_NZ8(r);
1002}
1003
1004/* $86 LDA immediate -**0- */
1005OP_HANDLER( lda_im )
1006{
1007   IMMBYTE(A);
1008   CLR_NZV; SET_NZ8(A);
1009}
1010
1011/* is this a legal instruction? */
1012/* $87 STA immediate -**0- */
1013OP_HANDLER( sta_im )
1014{
1015   CLR_NZV; SET_NZ8(A);
1016   IMM8; WM(EAD,A);
1017}
1018
1019/* $88 EORA immediate -**0- */
1020OP_HANDLER( eora_im )
1021{
1022   UINT8 t;
1023   IMMBYTE(t); A ^= t;
1024   CLR_NZV; SET_NZ8(A);
1025}
1026
1027/* $89 ADCA immediate ***** */
1028OP_HANDLER( adca_im )
1029{
1030   UINT16 t,r;
1031   IMMBYTE(t); r = A+t+(CC&0x01);
1032   CLR_HNZVC; SET_FLAGS8(A,t,r); SET_H(A,t,r);
1033   A = r;
1034}
1035
1036/* $8a ORA immediate -**0- */
1037OP_HANDLER( ora_im )
1038{
1039   UINT8 t;
1040   IMMBYTE(t); A |= t;
1041   CLR_NZV; SET_NZ8(A);
1042}
1043
1044/* $8b ADDA immediate ***** */
1045OP_HANDLER( adda_im )
1046{
1047   UINT16 t,r;
1048   IMMBYTE(t); r = A+t;
1049   CLR_HNZVC; SET_FLAGS8(A,t,r); SET_H(A,t,r);
1050   A = r;
1051}
1052
1053/* $8c CMPX immediate -***- */
1054OP_HANDLER( cmpx_im )
1055{
1056   UINT32 r,d;
1057   PAIR b;
1058   IMMWORD(b);
1059   d = X;
1060   r = d - b.d;
1061   CLR_NZV;
1062   SET_NZ16(r); SET_V16(d,b.d,r);
1063}
1064
1065/* $8c CPX immediate -**** (6803) */
1066OP_HANDLER( cpx_im )
1067{
1068   UINT32 r,d;
1069   PAIR b;
1070   IMMWORD(b);
1071   d = X;
1072   r = d - b.d;
1073   CLR_NZVC; SET_FLAGS16(d,b.d,r);
1074}
1075
1076
1077/* $8d BSR ----- */
1078OP_HANDLER( bsr )
1079{
1080   UINT8 t;
1081   IMMBYTE(t);
1082   PUSHWORD(pPC);
1083   PC += SIGNED(t);
1084}
1085
1086/* $8e LDS immediate -**0- */
1087OP_HANDLER( lds_im )
1088{
1089   IMMWORD(m_s);
1090   CLR_NZV;
1091   SET_NZ16(S);
1092}
1093
1094/* $8f STS immediate -**0- */
1095OP_HANDLER( sts_im )
1096{
1097   CLR_NZV;
1098   SET_NZ16(S);
1099   IMM16;
1100   WM16(EAD,&m_s);
1101}
1102
1103/* $90 SUBA direct ?**** */
1104OP_HANDLER( suba_di )
1105{
1106   UINT16    t,r;
1107   DIRBYTE(t); r = A-t;
1108   CLR_NZVC; SET_FLAGS8(A,t,r);
1109   A = r;
1110}
1111
1112/* $91 CMPA direct ?**** */
1113OP_HANDLER( cmpa_di )
1114{
1115   UINT16    t,r;
1116   DIRBYTE(t); r = A-t;
1117   CLR_NZVC; SET_FLAGS8(A,t,r);
1118}
1119
1120/* $92 SBCA direct ?**** */
1121OP_HANDLER( sbca_di )
1122{
1123   UINT16    t,r;
1124   DIRBYTE(t); r = A-t-(CC&0x01);
1125   CLR_NZVC; SET_FLAGS8(A,t,r);
1126   A = r;
1127}
1128
1129/* $93 SUBD direct -**** */
1130OP_HANDLER( subd_di )
1131{
1132   UINT32 r,d;
1133   PAIR b;
1134   DIRWORD(b);
1135   d = D;
1136   r = d - b.d;
1137   CLR_NZVC;
1138   SET_FLAGS16(d,b.d,r);
1139   D=r;
1140}
1141
1142/* $94 ANDA direct -**0- */
1143OP_HANDLER( anda_di )
1144{
1145   UINT8 t;
1146   DIRBYTE(t); A &= t;
1147   CLR_NZV; SET_NZ8(A);
1148}
1149
1150/* $95 BITA direct -**0- */
1151OP_HANDLER( bita_di )
1152{
1153   UINT8 t,r;
1154   DIRBYTE(t); r = A&t;
1155   CLR_NZV; SET_NZ8(r);
1156}
1157
1158/* $96 LDA direct -**0- */
1159OP_HANDLER( lda_di )
1160{
1161   DIRBYTE(A);
1162   CLR_NZV;
1163   SET_NZ8(A);
1164}
1165
1166/* $97 STA direct -**0- */
1167OP_HANDLER( sta_di )
1168{
1169   CLR_NZV;
1170   SET_NZ8(A);
1171   DIRECT;
1172   WM(EAD,A);
1173}
1174
1175/* $98 EORA direct -**0- */
1176OP_HANDLER( eora_di )
1177{
1178   UINT8 t;
1179   DIRBYTE(t);
1180   A ^= t;
1181   CLR_NZV;
1182   SET_NZ8(A);
1183}
1184
1185/* $99 ADCA direct ***** */
1186OP_HANDLER( adca_di )
1187{
1188   UINT16 t,r;
1189   DIRBYTE(t);
1190   r = A+t+(CC&0x01);
1191   CLR_HNZVC;
1192   SET_FLAGS8(A,t,r);
1193   SET_H(A,t,r);
1194   A = r;
1195}
1196
1197/* $9a ORA direct -**0- */
1198OP_HANDLER( ora_di )
1199{
1200   UINT8 t;
1201   DIRBYTE(t);
1202   A |= t;
1203   CLR_NZV;
1204   SET_NZ8(A);
1205}
1206
1207/* $9b ADDA direct ***** */
1208OP_HANDLER( adda_di )
1209{
1210   UINT16 t,r;
1211   DIRBYTE(t);
1212   r = A + t;
1213   CLR_HNZVC;
1214   SET_FLAGS8(A,t,r);
1215   SET_H(A,t,r);
1216   A = r;
1217}
1218
1219/* $9c CMPX direct -***- */
1220OP_HANDLER( cmpx_di )
1221{
1222   UINT32 r,d;
1223   PAIR b;
1224   DIRWORD(b);
1225   d = X;
1226   r = d - b.d;
1227   CLR_NZV;
1228   SET_NZ16(r);
1229   SET_V16(d,b.d,r);
1230}
1231
1232/* $9c CPX direct -**** (6803) */
1233OP_HANDLER( cpx_di )
1234{
1235   UINT32 r,d;
1236   PAIR b;
1237   DIRWORD(b);
1238   d = X;
1239   r = d - b.d;
1240   CLR_NZVC;
1241   SET_FLAGS16(d,b.d,r);
1242}
1243
1244/* $9d JSR direct ----- */
1245OP_HANDLER( jsr_di )
1246{
1247   DIRECT;
1248   PUSHWORD(pPC);
1249   PC = EA;
1250}
1251
1252/* $9e LDS direct -**0- */
1253OP_HANDLER( lds_di )
1254{
1255   DIRWORD(m_s);
1256   CLR_NZV;
1257   SET_NZ16(S);
1258}
1259
1260/* $9f STS direct -**0- */
1261OP_HANDLER( sts_di )
1262{
1263   CLR_NZV;
1264   SET_NZ16(S);
1265   DIRECT;
1266   WM16(EAD,&m_s);
1267}
1268
1269/* $a0 SUBA indexed ?**** */
1270OP_HANDLER( suba_ix )
1271{
1272   UINT16    t,r;
1273   IDXBYTE(t);
1274   r = A - t;
1275   CLR_NZVC;
1276   SET_FLAGS8(A,t,r);
1277   A = r;
1278}
1279
1280/* $a1 CMPA indexed ?**** */
1281OP_HANDLER( cmpa_ix )
1282{
1283   UINT16    t,r;
1284   IDXBYTE(t);
1285   r = A - t;
1286   CLR_NZVC;
1287   SET_FLAGS8(A,t,r);
1288}
1289
1290/* $a2 SBCA indexed ?**** */
1291OP_HANDLER( sbca_ix )
1292{
1293   UINT16    t,r;
1294   IDXBYTE(t);
1295   r = A - t - (CC&0x01);
1296   CLR_NZVC;
1297   SET_FLAGS8(A,t,r);
1298   A = r;
1299}
1300
1301/* $a3 SUBD indexed -**** */
1302OP_HANDLER( subd_ix )
1303{
1304   UINT32 r,d;
1305   PAIR b;
1306   IDXWORD(b);
1307   d = D;
1308   r = d - b.d;
1309   CLR_NZVC;
1310   SET_FLAGS16(d,b.d,r);
1311   D = r;
1312}
1313
1314/* $a4 ANDA indexed -**0- */
1315OP_HANDLER( anda_ix )
1316{
1317   UINT8 t;
1318   IDXBYTE(t); A &= t;
1319   CLR_NZV;
1320   SET_NZ8(A);
1321}
1322
1323/* $a5 BITA indexed -**0- */
1324OP_HANDLER( bita_ix )
1325{
1326   UINT8 t,r;
1327   IDXBYTE(t); r = A&t;
1328   CLR_NZV;
1329   SET_NZ8(r);
1330}
1331
1332/* $a6 LDA indexed -**0- */
1333OP_HANDLER( lda_ix )
1334{
1335   IDXBYTE(A);
1336   CLR_NZV;
1337   SET_NZ8(A);
1338}
1339
1340/* $a7 STA indexed -**0- */
1341OP_HANDLER( sta_ix )
1342{
1343   CLR_NZV;
1344   SET_NZ8(A);
1345   INDEXED;
1346   WM(EAD,A);
1347}
1348
1349/* $a8 EORA indexed -**0- */
1350OP_HANDLER( eora_ix )
1351{
1352   UINT8 t;
1353   IDXBYTE(t);
1354   A ^= t;
1355   CLR_NZV;
1356   SET_NZ8(A);
1357}
1358
1359/* $a9 ADCA indexed ***** */
1360OP_HANDLER( adca_ix )
1361{
1362   UINT16 t,r;
1363   IDXBYTE(t);
1364   r = A + t + (CC&0x01);
1365   CLR_HNZVC;
1366   SET_FLAGS8(A,t,r);
1367   SET_H(A,t,r);
1368   A = r;
1369}
1370
1371/* $aa ORA indexed -**0- */
1372OP_HANDLER( ora_ix )
1373{
1374   UINT8 t;
1375   IDXBYTE(t);
1376   A |= t;
1377   CLR_NZV;
1378   SET_NZ8(A);
1379}
1380
1381/* $ab ADDA indexed ***** */
1382OP_HANDLER( adda_ix )
1383{
1384   UINT16 t,r;
1385   IDXBYTE(t);
1386   r = A+t;
1387   CLR_HNZVC;
1388   SET_FLAGS8(A,t,r);
1389   SET_H(A,t,r);
1390   A = r;
1391}
1392
1393/* $ac CMPX indexed -***- */
1394OP_HANDLER( cmpx_ix )
1395{
1396   UINT32 r,d;
1397   PAIR b;
1398   IDXWORD(b);
1399   d = X;
1400   r = d - b.d;
1401   CLR_NZV;
1402   SET_NZ16(r);
1403   SET_V16(d,b.d,r);
1404}
1405
1406/* $ac CPX indexed -**** (6803)*/
1407OP_HANDLER( cpx_ix )
1408{
1409   UINT32 r,d;
1410   PAIR b;
1411   IDXWORD(b);
1412   d = X;
1413   r = d - b.d;
1414   CLR_NZVC;
1415   SET_FLAGS16(d,b.d,r);
1416}
1417
1418/* $ad JSR indexed ----- */
1419OP_HANDLER( jsr_ix )
1420{
1421   INDEXED;
1422   PUSHWORD(pPC);
1423   PC = EA;
1424}
1425
1426/* $ae LDS indexed -**0- */
1427OP_HANDLER( lds_ix )
1428{
1429   IDXWORD(m_s);
1430   CLR_NZV;
1431   SET_NZ16(S);
1432}
1433
1434/* $af STS indexed -**0- */
1435OP_HANDLER( sts_ix )
1436{
1437   CLR_NZV;
1438   SET_NZ16(S);
1439   INDEXED;
1440   WM16(EAD,&m_s);
1441}
1442
1443/* $b0 SUBA extended ?**** */
1444OP_HANDLER( suba_ex )
1445{
1446   UINT16    t,r;
1447   EXTBYTE(t);
1448   r = A - t;
1449   CLR_NZVC;
1450   SET_FLAGS8(A,t,r);
1451   A = r;
1452}
1453
1454/* $b1 CMPA extended ?**** */
1455OP_HANDLER( cmpa_ex )
1456{
1457   UINT16    t,r;
1458   EXTBYTE(t);
1459   r = A-t;
1460   CLR_NZVC;
1461   SET_FLAGS8(A,t,r);
1462}
1463
1464/* $b2 SBCA extended ?**** */
1465OP_HANDLER( sbca_ex )
1466{
1467   UINT16    t,r;
1468   EXTBYTE(t);
1469   r = A-t-(CC&0x01);
1470   CLR_NZVC;
1471   SET_FLAGS8(A,t,r);
1472   A = r;
1473}
1474
1475/* $b3 SUBD extended -**** */
1476OP_HANDLER( subd_ex )
1477{
1478   UINT32 r,d;
1479   PAIR b;
1480   EXTWORD(b);
1481   d = D;
1482   r = d - b.d;
1483   CLR_NZVC;
1484   SET_FLAGS16(d,b.d,r);
1485   D=r;
1486}
1487
1488/* $b4 ANDA extended -**0- */
1489OP_HANDLER( anda_ex )
1490{
1491   UINT8 t;
1492   EXTBYTE(t);
1493   A &= t;
1494   CLR_NZV;
1495   SET_NZ8(A);
1496}
1497
1498/* $b5 BITA extended -**0- */
1499OP_HANDLER( bita_ex )
1500{
1501   UINT8 t,r;
1502   EXTBYTE(t);
1503   r = A&t;
1504   CLR_NZV;
1505   SET_NZ8(r);
1506}
1507
1508/* $b6 LDA extended -**0- */
1509OP_HANDLER( lda_ex )
1510{
1511   EXTBYTE(A);
1512   CLR_NZV;
1513   SET_NZ8(A);
1514}
1515
1516/* $b7 STA extended -**0- */
1517OP_HANDLER( sta_ex )
1518{
1519   CLR_NZV;
1520   SET_NZ8(A);
1521   EXTENDED;
1522   WM(EAD,A);
1523}
1524
1525/* $b8 EORA extended -**0- */
1526OP_HANDLER( eora_ex )
1527{
1528   UINT8 t;
1529   EXTBYTE(t);
1530   A ^= t;
1531   CLR_NZV;
1532   SET_NZ8(A);
1533}
1534
1535/* $b9 ADCA extended ***** */
1536OP_HANDLER( adca_ex )
1537{
1538   UINT16 t,r;
1539   EXTBYTE(t);
1540   r = A+t+(CC&0x01);
1541   CLR_HNZVC;
1542   SET_FLAGS8(A,t,r);
1543   SET_H(A,t,r);
1544   A = r;
1545}
1546
1547/* $ba ORA extended -**0- */
1548OP_HANDLER( ora_ex )
1549{
1550   UINT8 t;
1551   EXTBYTE(t);
1552   A |= t;
1553   CLR_NZV;
1554   SET_NZ8(A);
1555}
1556
1557/* $bb ADDA extended ***** */
1558OP_HANDLER( adda_ex )
1559{
1560   UINT16 t,r;
1561   EXTBYTE(t);
1562   r = A+t;
1563   CLR_HNZVC;
1564   SET_FLAGS8(A,t,r);
1565   SET_H(A,t,r);
1566   A = r;
1567}
1568
1569/* $bc CMPX extended -***- */
1570OP_HANDLER( cmpx_ex )
1571{
1572   UINT32 r,d;
1573   PAIR b;
1574   EXTWORD(b);
1575   d = X;
1576   r = d - b.d;
1577   CLR_NZV;
1578   SET_NZ16(r);
1579   SET_V16(d,b.d,r);
1580}
1581
1582/* $bc CPX extended -**** (6803) */
1583OP_HANDLER( cpx_ex )
1584{
1585   UINT32 r,d;
1586   PAIR b;
1587   EXTWORD(b);
1588   d = X;
1589   r = d - b.d;
1590   CLR_NZVC;
1591   SET_FLAGS16(d,b.d,r);
1592}
1593
1594/* $bd JSR extended ----- */
1595OP_HANDLER( jsr_ex )
1596{
1597   EXTENDED;
1598   PUSHWORD(pPC);
1599   PC = EA;
1600}
1601
1602/* $be LDS extended -**0- */
1603OP_HANDLER( lds_ex )
1604{
1605   EXTWORD(m_s);
1606   CLR_NZV;
1607   SET_NZ16(S);
1608}
1609
1610/* $bf STS extended -**0- */
1611OP_HANDLER( sts_ex )
1612{
1613   CLR_NZV;
1614   SET_NZ16(S);
1615   EXTENDED;
1616   WM16(EAD,&m_s);
1617}
1618
1619/* $c0 SUBB immediate ?**** */
1620OP_HANDLER( subb_im )
1621{
1622   UINT16    t,r;
1623   IMMBYTE(t);
1624   r = B-t;
1625   CLR_NZVC;
1626   SET_FLAGS8(B,t,r);
1627   B = r;
1628}
1629
1630/* $c1 CMPB immediate ?**** */
1631OP_HANDLER( cmpb_im )
1632{
1633   UINT16    t,r;
1634   IMMBYTE(t);
1635   r = B-t;
1636   CLR_NZVC;
1637   SET_FLAGS8(B,t,r);
1638}
1639
1640/* $c2 SBCB immediate ?**** */
1641OP_HANDLER( sbcb_im )
1642{
1643   UINT16    t,r;
1644   IMMBYTE(t);
1645   r = B-t-(CC&0x01);
1646   CLR_NZVC;
1647   SET_FLAGS8(B,t,r);
1648   B = r;
1649}
1650
1651/* $c3 ADDD immediate -**** */
1652OP_HANDLER( addd_im )
1653{
1654   UINT32 r,d;
1655   PAIR b;
1656   IMMWORD(b);
1657   d = D;
1658   r = d + b.d;
1659   CLR_NZVC;
1660   SET_FLAGS16(d,b.d,r);
1661   D = r;
1662}
1663
1664/* $c4 ANDB immediate -**0- */
1665OP_HANDLER( andb_im )
1666{
1667   UINT8 t;
1668   IMMBYTE(t);
1669   B &= t;
1670   CLR_NZV;
1671   SET_NZ8(B);
1672}
1673
1674/* $c5 BITB immediate -**0- */
1675OP_HANDLER( bitb_im )
1676{
1677   UINT8 t,r;
1678   IMMBYTE(t);
1679   r = B&t;
1680   CLR_NZV;
1681   SET_NZ8(r);
1682}
1683
1684/* $c6 LDB immediate -**0- */
1685OP_HANDLER( ldb_im )
1686{
1687   IMMBYTE(B);
1688   CLR_NZV;
1689   SET_NZ8(B);
1690}
1691
1692/* is this a legal instruction? */
1693/* $c7 STB immediate -**0- */
1694OP_HANDLER( stb_im )
1695{
1696   CLR_NZV;
1697   SET_NZ8(B);
1698   IMM8;
1699   WM(EAD,B);
1700}
1701
1702/* $c8 EORB immediate -**0- */
1703OP_HANDLER( eorb_im )
1704{
1705   UINT8 t;
1706   IMMBYTE(t);
1707   B ^= t;
1708   CLR_NZV;
1709   SET_NZ8(B);
1710}
1711
1712/* $c9 ADCB immediate ***** */
1713OP_HANDLER( adcb_im )
1714{
1715   UINT16 t,r;
1716   IMMBYTE(t);
1717   r = B+t+(CC&0x01);
1718   CLR_HNZVC;
1719   SET_FLAGS8(B,t,r);
1720   SET_H(B,t,r);
1721   B = r;
1722}
1723
1724/* $ca ORB immediate -**0- */
1725OP_HANDLER( orb_im )
1726{
1727   UINT8 t;
1728   IMMBYTE(t);
1729   B |= t;
1730   CLR_NZV;
1731   SET_NZ8(B);
1732}
1733
1734/* $cb ADDB immediate ***** */
1735OP_HANDLER( addb_im )
1736{
1737   UINT16 t,r;
1738   IMMBYTE(t);
1739   r = B+t;
1740   CLR_HNZVC;
1741   SET_FLAGS8(B,t,r);
1742   SET_H(B,t,r);
1743   B = r;
1744}
1745
1746/* $CC LDD immediate -**0- */
1747OP_HANDLER( ldd_im )
1748{
1749   IMMWORD(m_d);
1750   CLR_NZV;
1751   SET_NZ16(D);
1752}
1753
1754/* is this a legal instruction? */
1755/* $cd STD immediate -**0- */
1756OP_HANDLER( std_im )
1757{
1758   IMM16;
1759   CLR_NZV;
1760   SET_NZ16(D);
1761   WM16(EAD,&m_d);
1762}
1763
1764/* $ce LDX immediate -**0- */
1765OP_HANDLER( ldx_im )
1766{
1767   IMMWORD(m_x);
1768   CLR_NZV;
1769   SET_NZ16(X);
1770}
1771
1772/* $cf STX immediate -**0- */
1773OP_HANDLER( stx_im )
1774{
1775   CLR_NZV;
1776   SET_NZ16(X);
1777   IMM16;
1778   WM16(EAD,&m_x);
1779}
1780
1781/* $d0 SUBB direct ?**** */
1782OP_HANDLER( subb_di )
1783{
1784   UINT16    t,r;
1785   DIRBYTE(t);
1786   r = B-t;
1787   CLR_NZVC;
1788   SET_FLAGS8(B,t,r);
1789   B = r;
1790}
1791
1792/* $d1 CMPB direct ?**** */
1793OP_HANDLER( cmpb_di )
1794{
1795   UINT16    t,r;
1796   DIRBYTE(t);
1797   r = B-t;
1798   CLR_NZVC;
1799   SET_FLAGS8(B,t,r);
1800}
1801
1802/* $d2 SBCB direct ?**** */
1803OP_HANDLER( sbcb_di )
1804{
1805   UINT16    t,r;
1806   DIRBYTE(t);
1807   r = B-t-(CC&0x01);
1808   CLR_NZVC;
1809   SET_FLAGS8(B,t,r);
1810   B = r;
1811}
1812
1813/* $d3 ADDD direct -**** */
1814OP_HANDLER( addd_di )
1815{
1816   UINT32 r,d;
1817   PAIR b;
1818   DIRWORD(b);
1819   d = D;
1820   r = d + b.d;
1821   CLR_NZVC;
1822   SET_FLAGS16(d,b.d,r);
1823   D = r;
1824}
1825
1826/* $d4 ANDB direct -**0- */
1827OP_HANDLER( andb_di )
1828{
1829   UINT8 t;
1830   DIRBYTE(t);
1831   B &= t;
1832   CLR_NZV;
1833   SET_NZ8(B);
1834}
1835
1836/* $d5 BITB direct -**0- */
1837OP_HANDLER( bitb_di )
1838{
1839   UINT8 t,r;
1840   DIRBYTE(t);
1841   r = B&t;
1842   CLR_NZV;
1843   SET_NZ8(r);
1844}
1845
1846/* $d6 LDB direct -**0- */
1847OP_HANDLER( ldb_di )
1848{
1849   DIRBYTE(B);
1850   CLR_NZV;
1851   SET_NZ8(B);
1852}
1853
1854/* $d7 STB direct -**0- */
1855OP_HANDLER( stb_di )
1856{
1857   CLR_NZV;
1858   SET_NZ8(B);
1859   DIRECT;
1860   WM(EAD,B);
1861}
1862
1863/* $d8 EORB direct -**0- */
1864OP_HANDLER( eorb_di )
1865{
1866   UINT8 t;
1867   DIRBYTE(t);
1868   B ^= t;
1869   CLR_NZV;
1870   SET_NZ8(B);
1871}
1872
1873/* $d9 ADCB direct ***** */
1874OP_HANDLER( adcb_di )
1875{
1876   UINT16 t,r;
1877   DIRBYTE(t);
1878   r = B+t+(CC&0x01);
1879   CLR_HNZVC;
1880   SET_FLAGS8(B,t,r);
1881   SET_H(B,t,r);
1882   B = r;
1883}
1884
1885/* $da ORB direct -**0- */
1886OP_HANDLER( orb_di )
1887{
1888   UINT8 t;
1889   DIRBYTE(t);
1890   B |= t;
1891   CLR_NZV;
1892   SET_NZ8(B);
1893}
1894
1895/* $db ADDB direct ***** */
1896OP_HANDLER( addb_di )
1897{
1898   UINT16 t,r;
1899   DIRBYTE(t);
1900   r = B+t;
1901   CLR_HNZVC;
1902   SET_FLAGS8(B,t,r);
1903   SET_H(B,t,r);
1904   B = r;
1905}
1906
1907/* $dc LDD direct -**0- */
1908OP_HANDLER( ldd_di )
1909{
1910   DIRWORD(m_d);
1911   CLR_NZV;
1912   SET_NZ16(D);
1913}
1914
1915/* $dd STD direct -**0- */
1916OP_HANDLER( std_di )
1917{
1918   DIRECT;
1919   CLR_NZV;
1920   SET_NZ16(D);
1921   WM16(EAD,&m_d);
1922}
1923
1924/* $de LDX direct -**0- */
1925OP_HANDLER( ldx_di )
1926{
1927   DIRWORD(m_x);
1928   CLR_NZV;
1929   SET_NZ16(X);
1930}
1931
1932/* $dF STX direct -**0- */
1933OP_HANDLER( stx_di )
1934{
1935   CLR_NZV;
1936   SET_NZ16(X);
1937   DIRECT;
1938   WM16(EAD,&m_x);
1939}
1940
1941/* $e0 SUBB indexed ?**** */
1942OP_HANDLER( subb_ix )
1943{
1944   UINT16    t,r;
1945   IDXBYTE(t);
1946   r = B-t;
1947   CLR_NZVC;
1948   SET_FLAGS8(B,t,r);
1949   B = r;
1950}
1951
1952/* $e1 CMPB indexed ?**** */
1953OP_HANDLER( cmpb_ix )
1954{
1955   UINT16    t,r;
1956   IDXBYTE(t);
1957   r = B-t;
1958   CLR_NZVC;
1959   SET_FLAGS8(B,t,r);
1960}
1961
1962/* $e2 SBCB indexed ?**** */
1963OP_HANDLER( sbcb_ix )
1964{
1965   UINT16    t,r;
1966   IDXBYTE(t);
1967   r = B-t-(CC&0x01);
1968   CLR_NZVC;
1969   SET_FLAGS8(B,t,r);
1970   B = r;
1971}
1972
1973/* $e3 ADDD indexed -**** */
1974OP_HANDLER( addd_ix )
1975{
1976   UINT32 r,d;
1977   PAIR b;
1978   IDXWORD(b);
1979   d = D;
1980   r = d + b.d;
1981   CLR_NZVC;
1982   SET_FLAGS16(d,b.d,r);
1983   D = r;
1984}
1985
1986/* $e4 ANDB indexed -**0- */
1987OP_HANDLER( andb_ix )
1988{
1989   UINT8 t;
1990   IDXBYTE(t);
1991   B &= t;
1992   CLR_NZV;
1993   SET_NZ8(B);
1994}
1995
1996/* $e5 BITB indexed -**0- */
1997OP_HANDLER( bitb_ix )
1998{
1999   UINT8 t,r;
2000   IDXBYTE(t);
2001   r = B&t;
2002   CLR_NZV;
2003   SET_NZ8(r);
2004}
2005
2006/* $e6 LDB indexed -**0- */
2007OP_HANDLER( ldb_ix )
2008{
2009   IDXBYTE(B);
2010   CLR_NZV;
2011   SET_NZ8(B);
2012}
2013
2014/* $e7 STB indexed -**0- */
2015OP_HANDLER( stb_ix )
2016{
2017   CLR_NZV;
2018   SET_NZ8(B);
2019   INDEXED;
2020   WM(EAD,B);
2021}
2022
2023/* $e8 EORB indexed -**0- */
2024OP_HANDLER( eorb_ix )
2025{
2026   UINT8 t;
2027   IDXBYTE(t);
2028   B ^= t;
2029   CLR_NZV;
2030   SET_NZ8(B);
2031}
2032
2033/* $e9 ADCB indexed ***** */
2034OP_HANDLER( adcb_ix )
2035{
2036   UINT16 t,r;
2037   IDXBYTE(t);
2038   r = B+t+(CC&0x01);
2039   CLR_HNZVC;
2040   SET_FLAGS8(B,t,r);
2041   SET_H(B,t,r);
2042   B = r;
2043}
2044
2045/* $ea ORB indexed -**0- */
2046OP_HANDLER( orb_ix )
2047{
2048   UINT8 t;
2049   IDXBYTE(t);
2050   B |= t;
2051   CLR_NZV;
2052   SET_NZ8(B);
2053}
2054
2055/* $eb ADDB indexed ***** */
2056OP_HANDLER( addb_ix )
2057{
2058   UINT16 t,r;
2059   IDXBYTE(t);
2060   r = B+t;
2061   CLR_HNZVC;
2062   SET_FLAGS8(B,t,r);
2063   SET_H(B,t,r);
2064   B = r;
2065}
2066
2067/* $ec LDD indexed -**0- */
2068OP_HANDLER( ldd_ix )
2069{
2070   IDXWORD(m_d);
2071   CLR_NZV;
2072   SET_NZ16(D);
2073}
2074
2075/* $ec ADCX immediate -****    NSC8105 only.  Flags are a guess - copied from addb_im() */
2076OP_HANDLER( adcx_im )
2077{
2078   UINT16 t,r;
2079   IMMBYTE(t);
2080   r = X+t+(CC&0x01);
2081   CLR_HNZVC;
2082   SET_FLAGS8(X,t,r);
2083   SET_H(X,t,r);
2084   X = r;
2085}
2086
2087/* $ed STD indexed -**0- */
2088OP_HANDLER( std_ix )
2089{
2090   INDEXED;
2091   CLR_NZV;
2092   SET_NZ16(D);
2093   WM16(EAD,&m_d);
2094}
2095
2096/* $ee LDX indexed -**0- */
2097OP_HANDLER( ldx_ix )
2098{
2099   IDXWORD(m_x);
2100   CLR_NZV;
2101   SET_NZ16(X);
2102}
2103
2104/* $ef STX indexed -**0- */
2105OP_HANDLER( stx_ix )
2106{
2107   CLR_NZV;
2108   SET_NZ16(X);
2109   INDEXED;
2110   WM16(EAD,&m_x);
2111}
2112
2113/* $f0 SUBB extended ?**** */
2114OP_HANDLER( subb_ex )
2115{
2116   UINT16    t,r;
2117   EXTBYTE(t);
2118   r = B-t;
2119   CLR_NZVC;
2120   SET_FLAGS8(B,t,r);
2121   B = r;
2122}
2123
2124/* $f1 CMPB extended ?**** */
2125OP_HANDLER( cmpb_ex )
2126{
2127   UINT16    t,r;
2128   EXTBYTE(t);
2129   r = B-t;
2130   CLR_NZVC;
2131   SET_FLAGS8(B,t,r);
2132}
2133
2134/* $f2 SBCB extended ?**** */
2135OP_HANDLER( sbcb_ex )
2136{
2137   UINT16    t,r;
2138   EXTBYTE(t);
2139   r = B-t-(CC&0x01);
2140   CLR_NZVC;
2141   SET_FLAGS8(B,t,r);
2142   B = r;
2143}
2144
2145/* $f3 ADDD extended -**** */
2146OP_HANDLER( addd_ex )
2147{
2148   UINT32 r,d;
2149   PAIR b;
2150   EXTWORD(b);
2151   d = D;
2152   r = d + b.d;
2153   CLR_NZVC;
2154   SET_FLAGS16(d,b.d,r);
2155   D = r;
2156}
2157
2158/* $f4 ANDB extended -**0- */
2159OP_HANDLER( andb_ex )
2160{
2161   UINT8 t;
2162   EXTBYTE(t);
2163   B &= t;
2164   CLR_NZV;
2165   SET_NZ8(B);
2166}
2167
2168/* $f5 BITB extended -**0- */
2169OP_HANDLER( bitb_ex )
2170{
2171   UINT8 t,r;
2172   EXTBYTE(t);
2173   r = B & t;
2174   CLR_NZV;
2175   SET_NZ8(r);
2176}
2177
2178/* $f6 LDB extended -**0- */
2179OP_HANDLER( ldb_ex )
2180{
2181   EXTBYTE(B);
2182   CLR_NZV;
2183   SET_NZ8(B);
2184}
2185
2186/* $f7 STB extended -**0- */
2187OP_HANDLER( stb_ex )
2188{
2189   CLR_NZV;
2190   SET_NZ8(B);
2191   EXTENDED;
2192   WM(EAD,B);
2193}
2194
2195/* $f8 EORB extended -**0- */
2196OP_HANDLER( eorb_ex )
2197{
2198   UINT8 t;
2199   EXTBYTE(t);
2200   B ^= t;
2201   CLR_NZV;
2202   SET_NZ8(B);
2203}
2204
2205/* $f9 ADCB extended ***** */
2206OP_HANDLER( adcb_ex )
2207{
2208   UINT16 t,r;
2209   EXTBYTE(t);
2210   r = B+t+(CC&0x01);
2211   CLR_HNZVC;
2212   SET_FLAGS8(B,t,r);
2213   SET_H(B,t,r);
2214   B = r;
2215}
2216
2217/* $fa ORB extended -**0- */
2218OP_HANDLER( orb_ex )
2219{
2220   UINT8 t;
2221   EXTBYTE(t);
2222   B |= t;
2223   CLR_NZV;
2224   SET_NZ8(B);
2225}
2226
2227/* $fb ADDB extended ***** */
2228OP_HANDLER( addb_ex )
2229{
2230   UINT16 t,r;
2231   EXTBYTE(t);
2232   r = B+t;
2233   CLR_HNZVC;
2234   SET_FLAGS8(B,t,r);
2235   SET_H(B,t,r);
2236   B = r;
2237}
2238
2239/* $fc LDD extended -**0- */
2240OP_HANDLER( ldd_ex )
2241{
2242   EXTWORD(m_d);
2243   CLR_NZV;
2244   SET_NZ16(D);
2245}
2246
2247/* $fc ADDX extended -****    NSC8105 only.  Flags are a guess */
2248OP_HANDLER( addx_ex )
2249{
2250   UINT32 r,d;
2251   PAIR b;
2252   EXTWORD(b);
2253   d = X;
2254   r = d + b.d;
2255   CLR_NZVC;
2256   SET_FLAGS16(d,b.d,r);
2257   X = r;
2258}
2259
2260/* $fd STD extended -**0- */
2261OP_HANDLER( std_ex )
2262{
2263   EXTENDED;
2264   CLR_NZV;
2265   SET_NZ16(D);
2266   WM16(EAD,&m_d);
2267}
2268
2269/* $fe LDX extended -**0- */
2270OP_HANDLER( ldx_ex )
2271{
2272   EXTWORD(m_x);
2273   CLR_NZV;
2274   SET_NZ16(X);
2275}
2276
2277/* $ff STX extended -**0- */
2278OP_HANDLER( stx_ex )
2279{
2280   CLR_NZV;
2281   SET_NZ16(X);
2282   EXTENDED;
2283   WM16(EAD,&m_x);
2284}
trunk/src/emu/cpu/m6800/6800tbl.c
r28738r28739
1
2const m6800_cpu_device::op_func m6800_cpu_device::m6800_insn[0x100] = {
3&m6800_cpu_device::illegal,&m6800_cpu_device::nop,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tap,    &m6800_cpu_device::tpa,
4&m6800_cpu_device::inx,    &m6800_cpu_device::dex,    &m6800_cpu_device::clv,    &m6800_cpu_device::sev,    &m6800_cpu_device::clc,    &m6800_cpu_device::sec,    &m6800_cpu_device::cli,    &m6800_cpu_device::sei,
5&m6800_cpu_device::sba,    &m6800_cpu_device::cba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tab,    &m6800_cpu_device::tba,
6&m6800_cpu_device::illegal,&m6800_cpu_device::daa,    &m6800_cpu_device::illegal,&m6800_cpu_device::aba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,
7&m6800_cpu_device::bra,    &m6800_cpu_device::brn,    &m6800_cpu_device::bhi,    &m6800_cpu_device::bls,    &m6800_cpu_device::bcc,    &m6800_cpu_device::bcs,    &m6800_cpu_device::bne,    &m6800_cpu_device::beq,
8&m6800_cpu_device::bvc,    &m6800_cpu_device::bvs,    &m6800_cpu_device::bpl,    &m6800_cpu_device::bmi,    &m6800_cpu_device::bge,    &m6800_cpu_device::blt,    &m6800_cpu_device::bgt,    &m6800_cpu_device::ble,
9&m6800_cpu_device::tsx,    &m6800_cpu_device::ins,    &m6800_cpu_device::pula,   &m6800_cpu_device::pulb,   &m6800_cpu_device::des,    &m6800_cpu_device::txs,    &m6800_cpu_device::psha,   &m6800_cpu_device::pshb,
10&m6800_cpu_device::illegal,&m6800_cpu_device::rts,    &m6800_cpu_device::illegal,&m6800_cpu_device::rti,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::wai,    &m6800_cpu_device::swi,
11&m6800_cpu_device::nega,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::coma,   &m6800_cpu_device::lsra,   &m6800_cpu_device::illegal,&m6800_cpu_device::rora,   &m6800_cpu_device::asra,
12&m6800_cpu_device::asla,   &m6800_cpu_device::rola,   &m6800_cpu_device::deca,   &m6800_cpu_device::illegal,&m6800_cpu_device::inca,   &m6800_cpu_device::tsta,   &m6800_cpu_device::illegal,&m6800_cpu_device::clra,
13&m6800_cpu_device::negb,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::comb,   &m6800_cpu_device::lsrb,   &m6800_cpu_device::illegal,&m6800_cpu_device::rorb,   &m6800_cpu_device::asrb,
14&m6800_cpu_device::aslb,   &m6800_cpu_device::rolb,   &m6800_cpu_device::decb,   &m6800_cpu_device::illegal,&m6800_cpu_device::incb,   &m6800_cpu_device::tstb,   &m6800_cpu_device::illegal,&m6800_cpu_device::clrb,
15&m6800_cpu_device::neg_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::ror_ix, &m6800_cpu_device::asr_ix,
16&m6800_cpu_device::asl_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::clr_ix,
17&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::ror_ex, &m6800_cpu_device::asr_ex,
18&m6800_cpu_device::asl_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::clr_ex,
19&m6800_cpu_device::suba_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_im,&m6800_cpu_device::bita_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::sta_im,
20&m6800_cpu_device::eora_im,&m6800_cpu_device::adca_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adda_im,&m6800_cpu_device::cmpx_im,&m6800_cpu_device::bsr,    &m6800_cpu_device::lds_im, &m6800_cpu_device::sts_im,
21&m6800_cpu_device::suba_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_di,&m6800_cpu_device::bita_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::sta_di,
22&m6800_cpu_device::eora_di,&m6800_cpu_device::adca_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adda_di,&m6800_cpu_device::cmpx_di,&m6800_cpu_device::jsr_di, &m6800_cpu_device::lds_di, &m6800_cpu_device::sts_di,
23&m6800_cpu_device::suba_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ix,&m6800_cpu_device::bita_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::sta_ix,
24&m6800_cpu_device::eora_ix,&m6800_cpu_device::adca_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adda_ix,&m6800_cpu_device::cmpx_ix,&m6800_cpu_device::jsr_ix, &m6800_cpu_device::lds_ix, &m6800_cpu_device::sts_ix,
25&m6800_cpu_device::suba_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ex,&m6800_cpu_device::bita_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::sta_ex,
26&m6800_cpu_device::eora_ex,&m6800_cpu_device::adca_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adda_ex,&m6800_cpu_device::cmpx_ex,&m6800_cpu_device::jsr_ex, &m6800_cpu_device::lds_ex, &m6800_cpu_device::sts_ex,
27&m6800_cpu_device::subb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_im,&m6800_cpu_device::bitb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::stb_im,
28&m6800_cpu_device::eorb_im,&m6800_cpu_device::adcb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::addb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_im, &m6800_cpu_device::stx_im,
29&m6800_cpu_device::subb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_di,&m6800_cpu_device::bitb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::stb_di,
30&m6800_cpu_device::eorb_di,&m6800_cpu_device::adcb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::addb_di,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_di, &m6800_cpu_device::stx_di,
31&m6800_cpu_device::subb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_ix,&m6800_cpu_device::bitb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::stb_ix,
32&m6800_cpu_device::eorb_ix,&m6800_cpu_device::adcb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::addb_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_ix, &m6800_cpu_device::stx_ix,
33&m6800_cpu_device::subb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_ex,&m6800_cpu_device::bitb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::stb_ex,
34&m6800_cpu_device::eorb_ex,&m6800_cpu_device::adcb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::addb_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_ex, &m6800_cpu_device::stx_ex
35};
36
37const m6800_cpu_device::op_func m6800_cpu_device::m6803_insn[0x100] = {
38&m6800_cpu_device::illegal,&m6800_cpu_device::nop,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::lsrd,   &m6800_cpu_device::asld,   &m6800_cpu_device::tap,    &m6800_cpu_device::tpa,
39&m6800_cpu_device::inx,    &m6800_cpu_device::dex,    &m6800_cpu_device::clv,    &m6800_cpu_device::sev,    &m6800_cpu_device::clc,    &m6800_cpu_device::sec,    &m6800_cpu_device::cli,    &m6800_cpu_device::sei,
40&m6800_cpu_device::sba,    &m6800_cpu_device::cba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tab,    &m6800_cpu_device::tba,
41&m6800_cpu_device::illegal,&m6800_cpu_device::daa,    &m6800_cpu_device::illegal,&m6800_cpu_device::aba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,
42&m6800_cpu_device::bra,    &m6800_cpu_device::brn,    &m6800_cpu_device::bhi,    &m6800_cpu_device::bls,    &m6800_cpu_device::bcc,    &m6800_cpu_device::bcs,    &m6800_cpu_device::bne,    &m6800_cpu_device::beq,
43&m6800_cpu_device::bvc,    &m6800_cpu_device::bvs,    &m6800_cpu_device::bpl,    &m6800_cpu_device::bmi,    &m6800_cpu_device::bge,    &m6800_cpu_device::blt,    &m6800_cpu_device::bgt,    &m6800_cpu_device::ble,
44&m6800_cpu_device::tsx,    &m6800_cpu_device::ins,    &m6800_cpu_device::pula,   &m6800_cpu_device::pulb,   &m6800_cpu_device::des,    &m6800_cpu_device::txs,    &m6800_cpu_device::psha,   &m6800_cpu_device::pshb,
45&m6800_cpu_device::pulx,   &m6800_cpu_device::rts,    &m6800_cpu_device::abx,    &m6800_cpu_device::rti,    &m6800_cpu_device::pshx,   &m6800_cpu_device::mul,    &m6800_cpu_device::wai,    &m6800_cpu_device::swi,
46&m6800_cpu_device::nega,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::coma,   &m6800_cpu_device::lsra,   &m6800_cpu_device::illegal,&m6800_cpu_device::rora,   &m6800_cpu_device::asra,
47&m6800_cpu_device::asla,   &m6800_cpu_device::rola,   &m6800_cpu_device::deca,   &m6800_cpu_device::illegal,&m6800_cpu_device::inca,   &m6800_cpu_device::tsta,   &m6800_cpu_device::illegal,&m6800_cpu_device::clra,
48&m6800_cpu_device::negb,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::comb,   &m6800_cpu_device::lsrb,   &m6800_cpu_device::illegal,&m6800_cpu_device::rorb,   &m6800_cpu_device::asrb,
49&m6800_cpu_device::aslb,   &m6800_cpu_device::rolb,   &m6800_cpu_device::decb,   &m6800_cpu_device::illegal,&m6800_cpu_device::incb,   &m6800_cpu_device::tstb,   &m6800_cpu_device::illegal,&m6800_cpu_device::clrb,
50&m6800_cpu_device::neg_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::ror_ix, &m6800_cpu_device::asr_ix,
51&m6800_cpu_device::asl_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::clr_ix,
52&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::ror_ex, &m6800_cpu_device::asr_ex,
53&m6800_cpu_device::asl_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::clr_ex,
54&m6800_cpu_device::suba_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::subd_im,&m6800_cpu_device::anda_im,&m6800_cpu_device::bita_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::sta_im,
55&m6800_cpu_device::eora_im,&m6800_cpu_device::adca_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adda_im,&m6800_cpu_device::cpx_im ,&m6800_cpu_device::bsr,    &m6800_cpu_device::lds_im, &m6800_cpu_device::sts_im,
56&m6800_cpu_device::suba_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::subd_di,&m6800_cpu_device::anda_di,&m6800_cpu_device::bita_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::sta_di,
57&m6800_cpu_device::eora_di,&m6800_cpu_device::adca_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adda_di,&m6800_cpu_device::cpx_di ,&m6800_cpu_device::jsr_di, &m6800_cpu_device::lds_di, &m6800_cpu_device::sts_di,
58&m6800_cpu_device::suba_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::subd_ix,&m6800_cpu_device::anda_ix,&m6800_cpu_device::bita_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::sta_ix,
59&m6800_cpu_device::eora_ix,&m6800_cpu_device::adca_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adda_ix,&m6800_cpu_device::cpx_ix ,&m6800_cpu_device::jsr_ix, &m6800_cpu_device::lds_ix, &m6800_cpu_device::sts_ix,
60&m6800_cpu_device::suba_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::subd_ex,&m6800_cpu_device::anda_ex,&m6800_cpu_device::bita_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::sta_ex,
61&m6800_cpu_device::eora_ex,&m6800_cpu_device::adca_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adda_ex,&m6800_cpu_device::cpx_ex ,&m6800_cpu_device::jsr_ex, &m6800_cpu_device::lds_ex, &m6800_cpu_device::sts_ex,
62&m6800_cpu_device::subb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::addd_im,&m6800_cpu_device::andb_im,&m6800_cpu_device::bitb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::stb_im,
63&m6800_cpu_device::eorb_im,&m6800_cpu_device::adcb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::addb_im,&m6800_cpu_device::ldd_im, &m6800_cpu_device::std_im, &m6800_cpu_device::ldx_im, &m6800_cpu_device::stx_im,
64&m6800_cpu_device::subb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::addd_di,&m6800_cpu_device::andb_di,&m6800_cpu_device::bitb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::stb_di,
65&m6800_cpu_device::eorb_di,&m6800_cpu_device::adcb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::addb_di,&m6800_cpu_device::ldd_di, &m6800_cpu_device::std_di, &m6800_cpu_device::ldx_di, &m6800_cpu_device::stx_di,
66&m6800_cpu_device::subb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::addd_ix,&m6800_cpu_device::andb_ix,&m6800_cpu_device::bitb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::stb_ix,
67&m6800_cpu_device::eorb_ix,&m6800_cpu_device::adcb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::addb_ix,&m6800_cpu_device::ldd_ix, &m6800_cpu_device::std_ix, &m6800_cpu_device::ldx_ix, &m6800_cpu_device::stx_ix,
68&m6800_cpu_device::subb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::addd_ex,&m6800_cpu_device::andb_ex,&m6800_cpu_device::bitb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::stb_ex,
69&m6800_cpu_device::eorb_ex,&m6800_cpu_device::adcb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::addb_ex,&m6800_cpu_device::ldd_ex, &m6800_cpu_device::std_ex, &m6800_cpu_device::ldx_ex, &m6800_cpu_device::stx_ex
70};
71
72const m6800_cpu_device::op_func m6800_cpu_device::hd63701_insn[0x100] = {
73&m6800_cpu_device::trap,   &m6800_cpu_device::nop,    &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::lsrd,   &m6800_cpu_device::asld,   &m6800_cpu_device::tap,    &m6800_cpu_device::tpa,
74&m6800_cpu_device::inx,    &m6800_cpu_device::dex,    &m6800_cpu_device::clv,    &m6800_cpu_device::sev,    &m6800_cpu_device::clc,    &m6800_cpu_device::sec,    &m6800_cpu_device::cli,    &m6800_cpu_device::sei,
75&m6800_cpu_device::sba,    &m6800_cpu_device::cba,    &m6800_cpu_device::undoc1, &m6800_cpu_device::undoc2, &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::tab,    &m6800_cpu_device::tba,
76&m6800_cpu_device::xgdx,   &m6800_cpu_device::daa,    &m6800_cpu_device::slp,    &m6800_cpu_device::aba,    &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::trap,
77&m6800_cpu_device::bra,    &m6800_cpu_device::brn,    &m6800_cpu_device::bhi,    &m6800_cpu_device::bls,    &m6800_cpu_device::bcc,    &m6800_cpu_device::bcs,    &m6800_cpu_device::bne,    &m6800_cpu_device::beq,
78&m6800_cpu_device::bvc,    &m6800_cpu_device::bvs,    &m6800_cpu_device::bpl,    &m6800_cpu_device::bmi,    &m6800_cpu_device::bge,    &m6800_cpu_device::blt,    &m6800_cpu_device::bgt,    &m6800_cpu_device::ble,
79&m6800_cpu_device::tsx,    &m6800_cpu_device::ins,    &m6800_cpu_device::pula,   &m6800_cpu_device::pulb,   &m6800_cpu_device::des,    &m6800_cpu_device::txs,    &m6800_cpu_device::psha,   &m6800_cpu_device::pshb,
80&m6800_cpu_device::pulx,   &m6800_cpu_device::rts,    &m6800_cpu_device::abx,    &m6800_cpu_device::rti,    &m6800_cpu_device::pshx,   &m6800_cpu_device::mul,    &m6800_cpu_device::wai,    &m6800_cpu_device::swi,
81&m6800_cpu_device::nega,   &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::coma,   &m6800_cpu_device::lsra,   &m6800_cpu_device::trap,   &m6800_cpu_device::rora,   &m6800_cpu_device::asra,
82&m6800_cpu_device::asla,   &m6800_cpu_device::rola,   &m6800_cpu_device::deca,   &m6800_cpu_device::trap,   &m6800_cpu_device::inca,   &m6800_cpu_device::tsta,   &m6800_cpu_device::trap,   &m6800_cpu_device::clra,
83&m6800_cpu_device::negb,   &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::comb,   &m6800_cpu_device::lsrb,   &m6800_cpu_device::trap,   &m6800_cpu_device::rorb,   &m6800_cpu_device::asrb,
84&m6800_cpu_device::aslb,   &m6800_cpu_device::rolb,   &m6800_cpu_device::decb,   &m6800_cpu_device::trap,   &m6800_cpu_device::incb,   &m6800_cpu_device::tstb,   &m6800_cpu_device::trap,   &m6800_cpu_device::clrb,
85&m6800_cpu_device::neg_ix, &m6800_cpu_device::aim_ix, &m6800_cpu_device::oim_ix, &m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::eim_ix, &m6800_cpu_device::ror_ix, &m6800_cpu_device::asr_ix,
86&m6800_cpu_device::asl_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::tim_ix, &m6800_cpu_device::inc_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::clr_ix,
87&m6800_cpu_device::neg_ex, &m6800_cpu_device::aim_di, &m6800_cpu_device::oim_di, &m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::eim_di, &m6800_cpu_device::ror_ex, &m6800_cpu_device::asr_ex,
88&m6800_cpu_device::asl_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::tim_di, &m6800_cpu_device::inc_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::clr_ex,
89&m6800_cpu_device::suba_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::subd_im,&m6800_cpu_device::anda_im,&m6800_cpu_device::bita_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::sta_im,
90&m6800_cpu_device::eora_im,&m6800_cpu_device::adca_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adda_im,&m6800_cpu_device::cpx_im ,&m6800_cpu_device::bsr,    &m6800_cpu_device::lds_im, &m6800_cpu_device::sts_im,
91&m6800_cpu_device::suba_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::subd_di,&m6800_cpu_device::anda_di,&m6800_cpu_device::bita_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::sta_di,
92&m6800_cpu_device::eora_di,&m6800_cpu_device::adca_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adda_di,&m6800_cpu_device::cpx_di ,&m6800_cpu_device::jsr_di, &m6800_cpu_device::lds_di, &m6800_cpu_device::sts_di,
93&m6800_cpu_device::suba_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::subd_ix,&m6800_cpu_device::anda_ix,&m6800_cpu_device::bita_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::sta_ix,
94&m6800_cpu_device::eora_ix,&m6800_cpu_device::adca_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adda_ix,&m6800_cpu_device::cpx_ix ,&m6800_cpu_device::jsr_ix, &m6800_cpu_device::lds_ix, &m6800_cpu_device::sts_ix,
95&m6800_cpu_device::suba_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::subd_ex,&m6800_cpu_device::anda_ex,&m6800_cpu_device::bita_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::sta_ex,
96&m6800_cpu_device::eora_ex,&m6800_cpu_device::adca_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adda_ex,&m6800_cpu_device::cpx_ex ,&m6800_cpu_device::jsr_ex, &m6800_cpu_device::lds_ex, &m6800_cpu_device::sts_ex,
97&m6800_cpu_device::subb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::addd_im,&m6800_cpu_device::andb_im,&m6800_cpu_device::bitb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::stb_im,
98&m6800_cpu_device::eorb_im,&m6800_cpu_device::adcb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::addb_im,&m6800_cpu_device::ldd_im, &m6800_cpu_device::std_im, &m6800_cpu_device::ldx_im, &m6800_cpu_device::stx_im,
99&m6800_cpu_device::subb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::addd_di,&m6800_cpu_device::andb_di,&m6800_cpu_device::bitb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::stb_di,
100&m6800_cpu_device::eorb_di,&m6800_cpu_device::adcb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::addb_di,&m6800_cpu_device::ldd_di, &m6800_cpu_device::std_di, &m6800_cpu_device::ldx_di, &m6800_cpu_device::stx_di,
101&m6800_cpu_device::subb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::addd_ix,&m6800_cpu_device::andb_ix,&m6800_cpu_device::bitb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::stb_ix,
102&m6800_cpu_device::eorb_ix,&m6800_cpu_device::adcb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::addb_ix,&m6800_cpu_device::ldd_ix, &m6800_cpu_device::std_ix, &m6800_cpu_device::ldx_ix, &m6800_cpu_device::stx_ix,
103&m6800_cpu_device::subb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::addd_ex,&m6800_cpu_device::andb_ex,&m6800_cpu_device::bitb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::stb_ex,
104&m6800_cpu_device::eorb_ex,&m6800_cpu_device::adcb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::addb_ex,&m6800_cpu_device::ldd_ex, &m6800_cpu_device::std_ex, &m6800_cpu_device::ldx_ex, &m6800_cpu_device::stx_ex
105};
106
107const m6800_cpu_device::op_func m6800_cpu_device::nsc8105_insn[0x100] = {
108&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::nop,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tap,    &m6800_cpu_device::illegal,&m6800_cpu_device::tpa,
109&m6800_cpu_device::inx,    &m6800_cpu_device::clv,    &m6800_cpu_device::dex,    &m6800_cpu_device::sev,    &m6800_cpu_device::clc,    &m6800_cpu_device::cli,    &m6800_cpu_device::sec,    &m6800_cpu_device::sei,
110&m6800_cpu_device::sba,    &m6800_cpu_device::illegal,&m6800_cpu_device::cba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tab,    &m6800_cpu_device::illegal,&m6800_cpu_device::tba,
111&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::daa,    &m6800_cpu_device::aba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,
112&m6800_cpu_device::bra,    &m6800_cpu_device::bhi,    &m6800_cpu_device::brn,    &m6800_cpu_device::bls,    &m6800_cpu_device::bcc,    &m6800_cpu_device::bne,    &m6800_cpu_device::bcs,    &m6800_cpu_device::beq,
113&m6800_cpu_device::bvc,    &m6800_cpu_device::bpl,    &m6800_cpu_device::bvs,    &m6800_cpu_device::bmi,    &m6800_cpu_device::bge,    &m6800_cpu_device::bgt,    &m6800_cpu_device::blt,    &m6800_cpu_device::ble,
114&m6800_cpu_device::tsx,    &m6800_cpu_device::pula,   &m6800_cpu_device::ins,    &m6800_cpu_device::pulb,   &m6800_cpu_device::des,    &m6800_cpu_device::psha,   &m6800_cpu_device::txs,    &m6800_cpu_device::pshb,
115&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::rts,    &m6800_cpu_device::rti,    &m6800_cpu_device::illegal,&m6800_cpu_device::wai,    &m6800_cpu_device::illegal,&m6800_cpu_device::swi,
116&m6800_cpu_device::suba_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::bita_im,&m6800_cpu_device::sta_im,
117&m6800_cpu_device::eora_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adca_im,&m6800_cpu_device::adda_im,&m6800_cpu_device::cmpx_im,&m6800_cpu_device::lds_im, &m6800_cpu_device::bsr,    &m6800_cpu_device::sts_im,
118&m6800_cpu_device::suba_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::bita_di,&m6800_cpu_device::sta_di,
119&m6800_cpu_device::eora_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adca_di,&m6800_cpu_device::adda_di,&m6800_cpu_device::cmpx_di,&m6800_cpu_device::lds_di, &m6800_cpu_device::jsr_di, &m6800_cpu_device::sts_di,
120&m6800_cpu_device::suba_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::bita_ix,&m6800_cpu_device::sta_ix,
121&m6800_cpu_device::eora_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adca_ix,&m6800_cpu_device::adda_ix,&m6800_cpu_device::cmpx_ix,&m6800_cpu_device::lds_ix, &m6800_cpu_device::jsr_ix, &m6800_cpu_device::sts_ix,
122&m6800_cpu_device::suba_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::bita_ex,&m6800_cpu_device::sta_ex,
123&m6800_cpu_device::eora_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adca_ex,&m6800_cpu_device::adda_ex,&m6800_cpu_device::cmpx_ex,&m6800_cpu_device::lds_ex, &m6800_cpu_device::jsr_ex, &m6800_cpu_device::sts_ex,
124&m6800_cpu_device::nega,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::coma,   &m6800_cpu_device::lsra,   &m6800_cpu_device::rora,   &m6800_cpu_device::illegal,&m6800_cpu_device::asra,
125&m6800_cpu_device::asla,   &m6800_cpu_device::deca,   &m6800_cpu_device::rola,   &m6800_cpu_device::illegal,&m6800_cpu_device::inca,   &m6800_cpu_device::illegal,&m6800_cpu_device::tsta,   &m6800_cpu_device::clra,
126&m6800_cpu_device::negb,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::comb,   &m6800_cpu_device::lsrb,   &m6800_cpu_device::rorb,   &m6800_cpu_device::illegal,&m6800_cpu_device::asrb,
127&m6800_cpu_device::aslb,   &m6800_cpu_device::decb,   &m6800_cpu_device::rolb,   &m6800_cpu_device::illegal,&m6800_cpu_device::incb,   &m6800_cpu_device::illegal,&m6800_cpu_device::tstb,   &m6800_cpu_device::clrb,
128&m6800_cpu_device::neg_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::ror_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::asr_ix,
129&m6800_cpu_device::asl_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::clr_ix,
130&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::ror_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::asr_ex,
131&m6800_cpu_device::asl_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::clr_ex,
132&m6800_cpu_device::subb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::bitb_im,&m6800_cpu_device::stb_im,
133&m6800_cpu_device::eorb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::adcb_im,&m6800_cpu_device::addb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_im, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_im,
134&m6800_cpu_device::subb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::bitb_di,&m6800_cpu_device::stb_di,
135&m6800_cpu_device::eorb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::adcb_di,&m6800_cpu_device::addb_di,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_di, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_di,
136&m6800_cpu_device::subb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::bitb_ix,&m6800_cpu_device::stb_ix,
137&m6800_cpu_device::eorb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::adcb_ix,&m6800_cpu_device::addb_ix,&m6800_cpu_device::adcx_im,&m6800_cpu_device::ldx_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_ix,
138&m6800_cpu_device::subb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::bitb_ex,&m6800_cpu_device::stb_ex,
139&m6800_cpu_device::eorb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::adcb_ex,&m6800_cpu_device::addb_ex,&m6800_cpu_device::addx_ex,&m6800_cpu_device::ldx_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_ex
140};
trunk/src/emu/cpu/m6800/6800ops.inc
r0r28739
1
2/*
3
4HNZVC
5
6? = undefined
7* = affected
8- = unaffected
90 = cleared
101 = set
11# = ccr directly affected by instruction
12@ = special - carry set if bit 7 is set
13
14*/
15
16#define OP_HANDLER(_name) void m6800_cpu_device::_name ()
17
18//OP_HANDLER( illegal )
19OP_HANDLER( illegal )
20{
21   logerror("m6800: illegal opcode: address %04X, op %02X\n",PC-1,(int) M_RDOP_ARG(PC-1)&0xFF);
22}
23
24/* HD63701 only */
25//OP_HANDLER( trap )
26OP_HANDLER( trap )
27{
28   logerror("m6800: illegal opcode: address %04X, op %02X\n",PC-1,(int) M_RDOP_ARG(PC-1)&0xFF);
29   TAKE_TRAP;
30}
31
32/* $00 ILLEGAL */
33
34/* $01 NOP */
35OP_HANDLER( nop )
36{
37}
38
39/* $02 ILLEGAL */
40
41/* $03 ILLEGAL */
42
43/* $04 LSRD inherent -0*-* */
44OP_HANDLER( lsrd )
45{
46   UINT16 t;
47   CLR_NZC; t = D; CC|=(t&0x0001);
48   t>>=1; SET_Z16(t); D=t;
49}
50
51/* $05 ASLD inherent ?**** */
52OP_HANDLER( asld )
53{
54   int r;
55   UINT16 t;
56   t = D; r=t<<1;
57   CLR_NZVC; SET_FLAGS16(t,t,r);
58   D=r;
59}
60
61/* $06 TAP inherent ##### */
62OP_HANDLER( tap )
63{
64   CC=A;
65   ONE_MORE_INSN();
66   CHECK_IRQ_LINES(); /* HJB 990417 */
67}
68
69/* $07 TPA inherent ----- */
70OP_HANDLER( tpa )
71{
72   A=CC;
73}
74
75/* $08 INX inherent --*-- */
76OP_HANDLER( inx )
77{
78   ++X;
79   CLR_Z; SET_Z16(X);
80}
81
82/* $09 DEX inherent --*-- */
83OP_HANDLER( dex )
84{
85   --X;
86   CLR_Z; SET_Z16(X);
87}
88
89/* $0a CLV */
90OP_HANDLER( clv )
91{
92   CLV;
93}
94
95/* $0b SEV */
96OP_HANDLER( sev )
97{
98   SEV;
99}
100
101/* $0c CLC */
102OP_HANDLER( clc )
103{
104   CLC;
105}
106
107/* $0d SEC */
108OP_HANDLER( sec )
109{
110   SEC;
111}
112
113/* $0e CLI */
114OP_HANDLER( cli )
115{
116   CLI;
117   ONE_MORE_INSN();
118   CHECK_IRQ_LINES(); /* HJB 990417 */
119}
120
121/* $0f SEI */
122OP_HANDLER( sei )
123{
124   SEI;
125   ONE_MORE_INSN();
126   CHECK_IRQ_LINES(); /* HJB 990417 */
127}
128
129/* $10 SBA inherent -**** */
130OP_HANDLER( sba )
131{
132   UINT16 t;
133   t=A-B;
134   CLR_NZVC; SET_FLAGS8(A,B,t);
135   A=t;
136}
137
138/* $11 CBA inherent -**** */
139OP_HANDLER( cba )
140{
141   UINT16 t;
142   t=A-B;
143   CLR_NZVC; SET_FLAGS8(A,B,t);
144}
145
146/* $12 ILLEGAL */
147OP_HANDLER( undoc1 )
148{
149   X += RM( S + 1 );
150}
151
152/* $13 ILLEGAL */
153OP_HANDLER( undoc2 )
154{
155   X += RM( S + 1 );
156}
157
158
159/* $14 ILLEGAL */
160
161/* $15 ILLEGAL */
162
163/* $16 TAB inherent -**0- */
164OP_HANDLER( tab )
165{
166   B=A;
167   CLR_NZV; SET_NZ8(B);
168}
169
170/* $17 TBA inherent -**0- */
171OP_HANDLER( tba )
172{
173   A=B;
174   CLR_NZV; SET_NZ8(A);
175}
176
177/* $18 XGDX inherent ----- */ /* HD63701YO only */
178OP_HANDLER( xgdx )
179{
180   UINT16 t = X;
181   X = D;
182   D=t;
183}
184
185/* $19 DAA inherent (A) -**0* */
186OP_HANDLER( daa )
187{
188   UINT8 msn, lsn;
189   UINT16 t, cf = 0;
190   msn=A & 0xf0; lsn=A & 0x0f;
191   if( lsn>0x09 || CC&0x20 ) cf |= 0x06;
192   if( msn>0x80 && lsn>0x09 ) cf |= 0x60;
193   if( msn>0x90 || CC&0x01 ) cf |= 0x60;
194   t = cf + A;
195   CLR_NZV; /* keep carry from previous operation */
196   SET_NZ8((UINT8)t); SET_C8(t);
197   A = t;
198}
199
200/* $1a ILLEGAL */
201
202/* $1a SLP */ /* HD63701YO only */
203OP_HANDLER( slp )
204{
205   /* wait for next IRQ (same as waiting of wai) */
206   m_wai_state |= M6800_SLP;
207   EAT_CYCLES;
208}
209
210/* $1b ABA inherent ***** */
211OP_HANDLER( aba )
212{
213   UINT16 t;
214   t=A+B;
215   CLR_HNZVC; SET_FLAGS8(A,B,t); SET_H(A,B,t);
216   A=t;
217}
218
219/* $1c ILLEGAL */
220
221/* $1d ILLEGAL */
222
223/* $1e ILLEGAL */
224
225/* $1f ILLEGAL */
226
227/* $20 BRA relative ----- */
228OP_HANDLER( bra )
229{
230   UINT8 t;
231   IMMBYTE(t);
232   PC+=SIGNED(t);
233}
234
235/* $21 BRN relative ----- */
236static UINT8 m6800_brn_t; // hack around GCC 4.6 error because we need the side effects of IMMBYTE
237OP_HANDLER( brn )
238{
239   IMMBYTE(m6800_brn_t);
240}
241
242/* $22 BHI relative ----- */
243OP_HANDLER( bhi )
244{
245   UINT8 t;
246   BRANCH(!(CC&0x05));
247}
248
249/* $23 BLS relative ----- */
250OP_HANDLER( bls )
251{
252   UINT8 t;
253   BRANCH(CC&0x05);
254}
255
256/* $24 BCC relative ----- */
257OP_HANDLER( bcc )
258{
259   UINT8 t;
260   BRANCH(!(CC&0x01));
261}
262
263/* $25 BCS relative ----- */
264OP_HANDLER( bcs )
265{
266   UINT8 t;
267   BRANCH(CC&0x01);
268}
269
270/* $26 BNE relative ----- */
271OP_HANDLER( bne )
272{
273   UINT8 t;
274   BRANCH(!(CC&0x04));
275}
276
277/* $27 BEQ relative ----- */
278OP_HANDLER( beq )
279{
280   UINT8 t;
281   BRANCH(CC&0x04);
282}
283
284/* $28 BVC relative ----- */
285OP_HANDLER( bvc )
286{
287   UINT8 t;
288   BRANCH(!(CC&0x02));
289}
290
291/* $29 BVS relative ----- */
292OP_HANDLER( bvs )
293{
294   UINT8 t;
295   BRANCH(CC&0x02);
296}
297
298/* $2a BPL relative ----- */
299OP_HANDLER( bpl )
300{
301   UINT8 t;
302   BRANCH(!(CC&0x08));
303}
304
305/* $2b BMI relative ----- */
306OP_HANDLER( bmi )
307{
308   UINT8 t;
309   BRANCH(CC&0x08);
310}
311
312/* $2c BGE relative ----- */
313OP_HANDLER( bge )
314{
315   UINT8 t;
316   BRANCH(!NXORV);
317}
318
319/* $2d BLT relative ----- */
320OP_HANDLER( blt )
321{
322   UINT8 t;
323   BRANCH(NXORV);
324}
325
326/* $2e BGT relative ----- */
327OP_HANDLER( bgt )
328{
329   UINT8 t;
330   BRANCH(!(NXORV||CC&0x04));
331}
332
333/* $2f BLE relative ----- */
334OP_HANDLER( ble )
335{
336   UINT8 t;
337   BRANCH(NXORV||CC&0x04);
338}
339
340/* $30 TSX inherent ----- */
341OP_HANDLER( tsx )
342{
343   X = ( S + 1 );
344}
345
346/* $31 INS inherent ----- */
347OP_HANDLER( ins )
348{
349   ++S;
350}
351
352/* $32 PULA inherent ----- */
353OP_HANDLER( pula )
354{
355   PULLBYTE(m_d.b.h);
356}
357
358/* $33 PULB inherent ----- */
359OP_HANDLER( pulb )
360{
361   PULLBYTE(m_d.b.l);
362}
363
364/* $34 DES inherent ----- */
365OP_HANDLER( des )
366{
367   --S;
368}
369
370/* $35 TXS inherent ----- */
371OP_HANDLER( txs )
372{
373   S = ( X - 1 );
374}
375
376/* $36 PSHA inherent ----- */
377OP_HANDLER( psha )
378{
379   PUSHBYTE(m_d.b.h);
380}
381
382/* $37 PSHB inherent ----- */
383OP_HANDLER( pshb )
384{
385   PUSHBYTE(m_d.b.l);
386}
387
388/* $38 PULX inherent ----- */
389OP_HANDLER( pulx )
390{
391   PULLWORD(pX);
392}
393
394/* $39 RTS inherent ----- */
395OP_HANDLER( rts )
396{
397   PULLWORD(pPC);
398}
399
400/* $3a ABX inherent ----- */
401OP_HANDLER( abx )
402{
403   X += B;
404}
405
406/* $3b RTI inherent ##### */
407OP_HANDLER( rti )
408{
409   PULLBYTE(CC);
410   PULLBYTE(B);
411   PULLBYTE(A);
412   PULLWORD(pX);
413   PULLWORD(pPC);
414   CHECK_IRQ_LINES(); /* HJB 990417 */
415}
416
417/* $3c PSHX inherent ----- */
418OP_HANDLER( pshx )
419{
420   PUSHWORD(pX);
421}
422
423/* $3d MUL inherent --*-@ */
424OP_HANDLER( mul )
425{
426   UINT16 t;
427   t=A*B;
428   CLR_C;
429   if(t&0x80) SEC;
430   D=t;
431}
432
433/* $3e WAI inherent ----- */
434OP_HANDLER( wai )
435{
436   /*
437    * WAI stacks the entire machine state on the
438    * hardware stack, then waits for an interrupt.
439    */
440   m_wai_state |= M6800_WAI;
441   PUSHWORD(pPC);
442   PUSHWORD(pX);
443   PUSHBYTE(A);
444   PUSHBYTE(B);
445   PUSHBYTE(CC);
446   CHECK_IRQ_LINES();
447   if (m_wai_state & M6800_WAI) EAT_CYCLES;
448}
449
450/* $3f SWI absolute indirect ----- */
451OP_HANDLER( swi )
452{
453   PUSHWORD(pPC);
454   PUSHWORD(pX);
455   PUSHBYTE(A);
456   PUSHBYTE(B);
457   PUSHBYTE(CC);
458   SEI;
459   PCD = RM16(0xfffa);
460}
461
462/* $40 NEGA inherent ?**** */
463OP_HANDLER( nega )
464{
465   UINT16 r;
466   r=-A;
467   CLR_NZVC; SET_FLAGS8(0,A,r);
468   A=r;
469}
470
471/* $41 ILLEGAL */
472
473/* $42 ILLEGAL */
474
475/* $43 COMA inherent -**01 */
476OP_HANDLER( coma )
477{
478   A = ~A;
479   CLR_NZV; SET_NZ8(A); SEC;
480}
481
482/* $44 LSRA inherent -0*-* */
483OP_HANDLER( lsra )
484{
485   CLR_NZC; CC|=(A&0x01);
486   A>>=1; SET_Z8(A);
487}
488
489/* $45 ILLEGAL */
490
491/* $46 RORA inherent -**-* */
492OP_HANDLER( rora )
493{
494   UINT8 r;
495   r=(CC&0x01)<<7;
496   CLR_NZC; CC|=(A&0x01);
497   r |= A>>1; SET_NZ8(r);
498   A=r;
499}
500
501/* $47 ASRA inherent ?**-* */
502OP_HANDLER( asra )
503{
504   CLR_NZC; CC|=(A&0x01);
505   A>>=1; A|=((A&0x40)<<1);
506   SET_NZ8(A);
507}
508
509/* $48 ASLA inherent ?**** */
510OP_HANDLER( asla )
511{
512   UINT16 r;
513   r=A<<1;
514   CLR_NZVC; SET_FLAGS8(A,A,r);
515   A=r;
516}
517
518/* $49 ROLA inherent -**** */
519OP_HANDLER( rola )
520{
521   UINT16 t,r;
522   t = A; r = CC&0x01; r |= t<<1;
523   CLR_NZVC; SET_FLAGS8(t,t,r);
524   A=r;
525}
526
527/* $4a DECA inherent -***- */
528OP_HANDLER( deca )
529{
530   --A;
531   CLR_NZV; SET_FLAGS8D(A);
532}
533
534/* $4b ILLEGAL */
535
536/* $4c INCA inherent -***- */
537OP_HANDLER( inca )
538{
539   ++A;
540   CLR_NZV; SET_FLAGS8I(A);
541}
542
543/* $4d TSTA inherent -**0- */
544OP_HANDLER( tsta )
545{
546   CLR_NZVC; SET_NZ8(A);
547}
548
549/* $4e ILLEGAL */
550
551/* $4f CLRA inherent -0100 */
552OP_HANDLER( clra )
553{
554   A=0;
555   CLR_NZVC; SEZ;
556}
557
558/* $50 NEGB inherent ?**** */
559OP_HANDLER( negb )
560{
561   UINT16 r;
562   r=-B;
563   CLR_NZVC; SET_FLAGS8(0,B,r);
564   B=r;
565}
566
567/* $51 ILLEGAL */
568
569/* $52 ILLEGAL */
570
571/* $53 COMB inherent -**01 */
572OP_HANDLER( comb )
573{
574   B = ~B;
575   CLR_NZV; SET_NZ8(B); SEC;
576}
577
578/* $54 LSRB inherent -0*-* */
579OP_HANDLER( lsrb )
580{
581   CLR_NZC; CC|=(B&0x01);
582   B>>=1; SET_Z8(B);
583}
584
585/* $55 ILLEGAL */
586
587/* $56 RORB inherent -**-* */
588OP_HANDLER( rorb )
589{
590   UINT8 r;
591   r=(CC&0x01)<<7;
592   CLR_NZC; CC|=(B&0x01);
593   r |= B>>1; SET_NZ8(r);
594   B=r;
595}
596
597/* $57 ASRB inherent ?**-* */
598OP_HANDLER( asrb )
599{
600   CLR_NZC; CC|=(B&0x01);
601   B>>=1; B|=((B&0x40)<<1);
602   SET_NZ8(B);
603}
604
605/* $58 ASLB inherent ?**** */
606OP_HANDLER( aslb )
607{
608   UINT16 r;
609   r=B<<1;
610   CLR_NZVC; SET_FLAGS8(B,B,r);
611   B=r;
612}
613
614/* $59 ROLB inherent -**** */
615OP_HANDLER( rolb )
616{
617   UINT16 t,r;
618   t = B; r = CC&0x01; r |= t<<1;
619   CLR_NZVC; SET_FLAGS8(t,t,r);
620   B=r;
621}
622
623/* $5a DECB inherent -***- */
624OP_HANDLER( decb )
625{
626   --B;
627   CLR_NZV; SET_FLAGS8D(B);
628}
629
630/* $5b ILLEGAL */
631
632/* $5c INCB inherent -***- */
633OP_HANDLER( incb )
634{
635   ++B;
636   CLR_NZV; SET_FLAGS8I(B);
637}
638
639/* $5d TSTB inherent -**0- */
640OP_HANDLER( tstb )
641{
642   CLR_NZVC; SET_NZ8(B);
643}
644
645/* $5e ILLEGAL */
646
647/* $5f CLRB inherent -0100 */
648OP_HANDLER( clrb )
649{
650   B=0;
651   CLR_NZVC; SEZ;
652}
653
654/* $60 NEG indexed ?**** */
655OP_HANDLER( neg_ix )
656{
657   UINT16 r,t;
658   IDXBYTE(t); r=-t;
659   CLR_NZVC; SET_FLAGS8(0,t,r);
660   WM(EAD,r);
661}
662
663/* $61 AIM --**0- */ /* HD63701YO only */
664OP_HANDLER( aim_ix )
665{
666   UINT8 t, r;
667   IMMBYTE(t);
668   IDXBYTE(r);
669   r &= t;
670   CLR_NZV; SET_NZ8(r);
671   WM(EAD,r);
672}
673
674/* $62 OIM --**0- */ /* HD63701YO only */
675OP_HANDLER( oim_ix )
676{
677   UINT8 t, r;
678   IMMBYTE(t);
679   IDXBYTE(r);
680   r |= t;
681   CLR_NZV; SET_NZ8(r);
682   WM(EAD,r);
683}
684
685/* $63 COM indexed -**01 */
686OP_HANDLER( com_ix )
687{
688   UINT8 t;
689   IDXBYTE(t); t = ~t;
690   CLR_NZV; SET_NZ8(t); SEC;
691   WM(EAD,t);
692}
693
694/* $64 LSR indexed -0*-* */
695OP_HANDLER( lsr_ix )
696{
697   UINT8 t;
698   IDXBYTE(t); CLR_NZC; CC|=(t&0x01);
699   t>>=1; SET_Z8(t);
700   WM(EAD,t);
701}
702
703/* $65 EIM --**0- */ /* HD63701YO only */
704OP_HANDLER( eim_ix )
705{
706   UINT8 t, r;
707   IMMBYTE(t);
708   IDXBYTE(r);
709   r ^= t;
710   CLR_NZV; SET_NZ8(r);
711   WM(EAD,r);
712}
713
714/* $66 ROR indexed -**-* */
715OP_HANDLER( ror_ix )
716{
717   UINT8 t,r;
718   IDXBYTE(t); r=(CC&0x01)<<7;
719   CLR_NZC; CC|=(t&0x01);
720   r |= t>>1; SET_NZ8(r);
721   WM(EAD,r);
722}
723
724/* $67 ASR indexed ?**-* */
725OP_HANDLER( asr_ix )
726{
727   UINT8 t;
728   IDXBYTE(t); CLR_NZC; CC|=(t&0x01);
729   t>>=1; t|=((t&0x40)<<1);
730   SET_NZ8(t);
731   WM(EAD,t);
732}
733
734/* $68 ASL indexed ?**** */
735OP_HANDLER( asl_ix )
736{
737   UINT16 t,r;
738   IDXBYTE(t); r=t<<1;
739   CLR_NZVC; SET_FLAGS8(t,t,r);
740   WM(EAD,r);
741}
742
743/* $69 ROL indexed -**** */
744OP_HANDLER( rol_ix )
745{
746   UINT16 t,r;
747   IDXBYTE(t); r = CC&0x01; r |= t<<1;
748   CLR_NZVC; SET_FLAGS8(t,t,r);
749   WM(EAD,r);
750}
751
752/* $6a DEC indexed -***- */
753OP_HANDLER( dec_ix )
754{
755   UINT8 t;
756   IDXBYTE(t); --t;
757   CLR_NZV; SET_FLAGS8D(t);
758   WM(EAD,t);
759}
760
761/* $6b TIM --**0- */ /* HD63701YO only */
762OP_HANDLER( tim_ix )
763{
764   UINT8 t, r;
765   IMMBYTE(t);
766   IDXBYTE(r);
767   r &= t;
768   CLR_NZV; SET_NZ8(r);
769}
770
771/* $6c INC indexed -***- */
772OP_HANDLER( inc_ix )
773{
774   UINT8 t;
775   IDXBYTE(t); ++t;
776   CLR_NZV; SET_FLAGS8I(t);
777   WM(EAD,t);
778}
779
780/* $6d TST indexed -**0- */
781OP_HANDLER( tst_ix )
782{
783   UINT8 t;
784   IDXBYTE(t); CLR_NZVC; SET_NZ8(t);
785}
786
787/* $6e JMP indexed ----- */
788OP_HANDLER( jmp_ix )
789{
790   INDEXED; PC=EA;
791}
792
793/* $6f CLR indexed -0100 */
794OP_HANDLER( clr_ix )
795{
796   INDEXED; WM(EAD,0);
797   CLR_NZVC; SEZ;
798}
799
800/* $70 NEG extended ?**** */
801OP_HANDLER( neg_ex )
802{
803   UINT16 r,t;
804   EXTBYTE(t); r=-t;
805   CLR_NZVC; SET_FLAGS8(0,t,r);
806   WM(EAD,r);
807}
808
809/* $71 AIM --**0- */ /* HD63701YO only */
810OP_HANDLER( aim_di )
811{
812   UINT8 t, r;
813   IMMBYTE(t);
814   DIRBYTE(r);
815   r &= t;
816   CLR_NZV; SET_NZ8(r);
817   WM(EAD,r);
818}
819
820/* $72 OIM --**0- */ /* HD63701YO only */
821OP_HANDLER( oim_di )
822{
823   UINT8 t, r;
824   IMMBYTE(t);
825   DIRBYTE(r);
826   r |= t;
827   CLR_NZV; SET_NZ8(r);
828   WM(EAD,r);
829}
830
831/* $73 COM extended -**01 */
832OP_HANDLER( com_ex )
833{
834   UINT8 t;
835   EXTBYTE(t); t = ~t;
836   CLR_NZV; SET_NZ8(t); SEC;
837   WM(EAD,t);
838}
839
840/* $74 LSR extended -0*-* */
841OP_HANDLER( lsr_ex )
842{
843   UINT8 t;
844   EXTBYTE(t);
845   CLR_NZC;
846   CC|=(t&0x01);
847   t>>=1;
848   SET_Z8(t);
849   WM(EAD,t);
850}
851
852/* $75 EIM --**0- */ /* HD63701YO only */
853OP_HANDLER( eim_di )
854{
855   UINT8 t, r;
856   IMMBYTE(t);
857   DIRBYTE(r);
858   r ^= t;
859   CLR_NZV; SET_NZ8(r);
860   WM(EAD,r);
861}
862
863/* $76 ROR extended -**-* */
864OP_HANDLER( ror_ex )
865{
866   UINT8 t,r;
867   EXTBYTE(t); r=(CC&0x01)<<7;
868   CLR_NZC; CC|=(t&0x01);
869   r |= t>>1; SET_NZ8(r);
870   WM(EAD,r);
871}
872
873/* $77 ASR extended ?**-* */
874OP_HANDLER( asr_ex )
875{
876   UINT8 t;
877   EXTBYTE(t); CLR_NZC; CC|=(t&0x01);
878   t>>=1; t|=((t&0x40)<<1);
879   SET_NZ8(t);
880   WM(EAD,t);
881}
882
883/* $78 ASL extended ?**** */
884OP_HANDLER( asl_ex )
885{
886   UINT16 t,r;
887   EXTBYTE(t); r=t<<1;
888   CLR_NZVC; SET_FLAGS8(t,t,r);
889   WM(EAD,r);
890}
891
892/* $79 ROL extended -**** */
893OP_HANDLER( rol_ex )
894{
895   UINT16 t,r;
896   EXTBYTE(t); r = CC&0x01; r |= t<<1;
897   CLR_NZVC; SET_FLAGS8(t,t,r);
898   WM(EAD,r);
899}
900
901/* $7a DEC extended -***- */
902OP_HANDLER( dec_ex )
903{
904   UINT8 t;
905   EXTBYTE(t); --t;
906   CLR_NZV; SET_FLAGS8D(t);
907   WM(EAD,t);
908}
909
910/* $7b TIM --**0- */ /* HD63701YO only */
911OP_HANDLER( tim_di )
912{
913   UINT8 t, r;
914   IMMBYTE(t);
915   DIRBYTE(r);
916   r &= t;
917   CLR_NZV; SET_NZ8(r);
918}
919
920/* $7c INC extended -***- */
921OP_HANDLER( inc_ex )
922{
923   UINT8 t;
924   EXTBYTE(t); ++t;
925   CLR_NZV; SET_FLAGS8I(t);
926   WM(EAD,t);
927}
928
929/* $7d TST extended -**0- */
930OP_HANDLER( tst_ex )
931{
932   UINT8 t;
933   EXTBYTE(t); CLR_NZVC; SET_NZ8(t);
934}
935
936/* $7e JMP extended ----- */
937OP_HANDLER( jmp_ex )
938{
939   EXTENDED; PC=EA;
940}
941
942/* $7f CLR extended -0100 */
943OP_HANDLER( clr_ex )
944{
945   EXTENDED; WM(EAD,0);
946   CLR_NZVC; SEZ;
947}
948
949/* $80 SUBA immediate ?**** */
950OP_HANDLER( suba_im )
951{
952   UINT16    t,r;
953   IMMBYTE(t); r = A-t;
954   CLR_NZVC; SET_FLAGS8(A,t,r);
955   A = r;
956}
957
958/* $81 CMPA immediate ?**** */
959OP_HANDLER( cmpa_im )
960{
961   UINT16    t,r;
962   IMMBYTE(t); r = A-t;
963   CLR_NZVC; SET_FLAGS8(A,t,r);
964}
965
966/* $82 SBCA immediate ?**** */
967OP_HANDLER( sbca_im )
968{
969   UINT16    t,r;
970   IMMBYTE(t); r = A-t-(CC&0x01);
971   CLR_NZVC; SET_FLAGS8(A,t,r);
972   A = r;
973}
974
975/* $83 SUBD immediate -**** */
976OP_HANDLER( subd_im )
977{
978   UINT32 r,d;
979   PAIR b;
980   IMMWORD(b);
981   d = D;
982   r = d - b.d;
983   CLR_NZVC;
984   SET_FLAGS16(d,b.d,r);
985   D = r;
986}
987
988/* $84 ANDA immediate -**0- */
989OP_HANDLER( anda_im )
990{
991   UINT8 t;
992   IMMBYTE(t); A &= t;
993   CLR_NZV; SET_NZ8(A);
994}
995
996/* $85 BITA immediate -**0- */
997OP_HANDLER( bita_im )
998{
999   UINT8 t,r;
1000   IMMBYTE(t); r = A&t;
1001   CLR_NZV; SET_NZ8(r);
1002}
1003
1004/* $86 LDA immediate -**0- */
1005OP_HANDLER( lda_im )
1006{
1007   IMMBYTE(A);
1008   CLR_NZV; SET_NZ8(A);
1009}
1010
1011/* is this a legal instruction? */
1012/* $87 STA immediate -**0- */
1013OP_HANDLER( sta_im )
1014{
1015   CLR_NZV; SET_NZ8(A);
1016   IMM8; WM(EAD,A);
1017}
1018
1019/* $88 EORA immediate -**0- */
1020OP_HANDLER( eora_im )
1021{
1022   UINT8 t;
1023   IMMBYTE(t); A ^= t;
1024   CLR_NZV; SET_NZ8(A);
1025}
1026
1027/* $89 ADCA immediate ***** */
1028OP_HANDLER( adca_im )
1029{
1030   UINT16 t,r;
1031   IMMBYTE(t); r = A+t+(CC&0x01);
1032   CLR_HNZVC; SET_FLAGS8(A,t,r); SET_H(A,t,r);
1033   A = r;
1034}
1035
1036/* $8a ORA immediate -**0- */
1037OP_HANDLER( ora_im )
1038{
1039   UINT8 t;
1040   IMMBYTE(t); A |= t;
1041   CLR_NZV; SET_NZ8(A);
1042}
1043
1044/* $8b ADDA immediate ***** */
1045OP_HANDLER( adda_im )
1046{
1047   UINT16 t,r;
1048   IMMBYTE(t); r = A+t;
1049   CLR_HNZVC; SET_FLAGS8(A,t,r); SET_H(A,t,r);
1050   A = r;
1051}
1052
1053/* $8c CMPX immediate -***- */
1054OP_HANDLER( cmpx_im )
1055{
1056   UINT32 r,d;
1057   PAIR b;
1058   IMMWORD(b);
1059   d = X;
1060   r = d - b.d;
1061   CLR_NZV;
1062   SET_NZ16(r); SET_V16(d,b.d,r);
1063}
1064
1065/* $8c CPX immediate -**** (6803) */
1066OP_HANDLER( cpx_im )
1067{
1068   UINT32 r,d;
1069   PAIR b;
1070   IMMWORD(b);
1071   d = X;
1072   r = d - b.d;
1073   CLR_NZVC; SET_FLAGS16(d,b.d,r);
1074}
1075
1076
1077/* $8d BSR ----- */
1078OP_HANDLER( bsr )
1079{
1080   UINT8 t;
1081   IMMBYTE(t);
1082   PUSHWORD(pPC);
1083   PC += SIGNED(t);
1084}
1085
1086/* $8e LDS immediate -**0- */
1087OP_HANDLER( lds_im )
1088{
1089   IMMWORD(m_s);
1090   CLR_NZV;
1091   SET_NZ16(S);
1092}
1093
1094/* $8f STS immediate -**0- */
1095OP_HANDLER( sts_im )
1096{
1097   CLR_NZV;
1098   SET_NZ16(S);
1099   IMM16;
1100   WM16(EAD,&m_s);
1101}
1102
1103/* $90 SUBA direct ?**** */
1104OP_HANDLER( suba_di )
1105{
1106   UINT16    t,r;
1107   DIRBYTE(t); r = A-t;
1108   CLR_NZVC; SET_FLAGS8(A,t,r);
1109   A = r;
1110}
1111
1112/* $91 CMPA direct ?**** */
1113OP_HANDLER( cmpa_di )
1114{
1115   UINT16    t,r;
1116   DIRBYTE(t); r = A-t;
1117   CLR_NZVC; SET_FLAGS8(A,t,r);
1118}
1119
1120/* $92 SBCA direct ?**** */
1121OP_HANDLER( sbca_di )
1122{
1123   UINT16    t,r;
1124   DIRBYTE(t); r = A-t-(CC&0x01);
1125   CLR_NZVC; SET_FLAGS8(A,t,r);
1126   A = r;
1127}
1128
1129/* $93 SUBD direct -**** */
1130OP_HANDLER( subd_di )
1131{
1132   UINT32 r,d;
1133   PAIR b;
1134   DIRWORD(b);
1135   d = D;
1136   r = d - b.d;
1137   CLR_NZVC;
1138   SET_FLAGS16(d,b.d,r);
1139   D=r;
1140}
1141
1142/* $94 ANDA direct -**0- */
1143OP_HANDLER( anda_di )
1144{
1145   UINT8 t;
1146   DIRBYTE(t); A &= t;
1147   CLR_NZV; SET_NZ8(A);
1148}
1149
1150/* $95 BITA direct -**0- */
1151OP_HANDLER( bita_di )
1152{
1153   UINT8 t,r;
1154   DIRBYTE(t); r = A&t;
1155   CLR_NZV; SET_NZ8(r);
1156}
1157
1158/* $96 LDA direct -**0- */
1159OP_HANDLER( lda_di )
1160{
1161   DIRBYTE(A);
1162   CLR_NZV;
1163   SET_NZ8(A);
1164}
1165
1166/* $97 STA direct -**0- */
1167OP_HANDLER( sta_di )
1168{
1169   CLR_NZV;
1170   SET_NZ8(A);
1171   DIRECT;
1172   WM(EAD,A);
1173}
1174
1175/* $98 EORA direct -**0- */
1176OP_HANDLER( eora_di )
1177{
1178   UINT8 t;
1179   DIRBYTE(t);
1180   A ^= t;
1181   CLR_NZV;
1182   SET_NZ8(A);
1183}
1184
1185/* $99 ADCA direct ***** */
1186OP_HANDLER( adca_di )
1187{
1188   UINT16 t,r;
1189   DIRBYTE(t);
1190   r = A+t+(CC&0x01);
1191   CLR_HNZVC;
1192   SET_FLAGS8(A,t,r);
1193   SET_H(A,t,r);
1194   A = r;
1195}
1196
1197/* $9a ORA direct -**0- */
1198OP_HANDLER( ora_di )
1199{
1200   UINT8 t;
1201   DIRBYTE(t);
1202   A |= t;
1203   CLR_NZV;
1204   SET_NZ8(A);
1205}
1206
1207/* $9b ADDA direct ***** */
1208OP_HANDLER( adda_di )
1209{
1210   UINT16 t,r;
1211   DIRBYTE(t);
1212   r = A + t;
1213   CLR_HNZVC;
1214   SET_FLAGS8(A,t,r);
1215   SET_H(A,t,r);
1216   A = r;
1217}
1218
1219/* $9c CMPX direct -***- */
1220OP_HANDLER( cmpx_di )
1221{
1222   UINT32 r,d;
1223   PAIR b;
1224   DIRWORD(b);
1225   d = X;
1226   r = d - b.d;
1227   CLR_NZV;
1228   SET_NZ16(r);
1229   SET_V16(d,b.d,r);
1230}
1231
1232/* $9c CPX direct -**** (6803) */
1233OP_HANDLER( cpx_di )
1234{
1235   UINT32 r,d;
1236   PAIR b;
1237   DIRWORD(b);
1238   d = X;
1239   r = d - b.d;
1240   CLR_NZVC;
1241   SET_FLAGS16(d,b.d,r);
1242}
1243
1244/* $9d JSR direct ----- */
1245OP_HANDLER( jsr_di )
1246{
1247   DIRECT;
1248   PUSHWORD(pPC);
1249   PC = EA;
1250}
1251
1252/* $9e LDS direct -**0- */
1253OP_HANDLER( lds_di )
1254{
1255   DIRWORD(m_s);
1256   CLR_NZV;
1257   SET_NZ16(S);
1258}
1259
1260/* $9f STS direct -**0- */
1261OP_HANDLER( sts_di )
1262{
1263   CLR_NZV;
1264   SET_NZ16(S);
1265   DIRECT;
1266   WM16(EAD,&m_s);
1267}
1268
1269/* $a0 SUBA indexed ?**** */
1270OP_HANDLER( suba_ix )
1271{
1272   UINT16    t,r;
1273   IDXBYTE(t);
1274   r = A - t;
1275   CLR_NZVC;
1276   SET_FLAGS8(A,t,r);
1277   A = r;
1278}
1279
1280/* $a1 CMPA indexed ?**** */
1281OP_HANDLER( cmpa_ix )
1282{
1283   UINT16    t,r;
1284   IDXBYTE(t);
1285   r = A - t;
1286   CLR_NZVC;
1287   SET_FLAGS8(A,t,r);
1288}
1289
1290/* $a2 SBCA indexed ?**** */
1291OP_HANDLER( sbca_ix )
1292{
1293   UINT16    t,r;
1294   IDXBYTE(t);
1295   r = A - t - (CC&0x01);
1296   CLR_NZVC;
1297   SET_FLAGS8(A,t,r);
1298   A = r;
1299}
1300
1301/* $a3 SUBD indexed -**** */
1302OP_HANDLER( subd_ix )
1303{
1304   UINT32 r,d;
1305   PAIR b;
1306   IDXWORD(b);
1307   d = D;
1308   r = d - b.d;
1309   CLR_NZVC;
1310   SET_FLAGS16(d,b.d,r);
1311   D = r;
1312}
1313
1314/* $a4 ANDA indexed -**0- */
1315OP_HANDLER( anda_ix )
1316{
1317   UINT8 t;
1318   IDXBYTE(t); A &= t;
1319   CLR_NZV;
1320   SET_NZ8(A);
1321}
1322
1323/* $a5 BITA indexed -**0- */
1324OP_HANDLER( bita_ix )
1325{
1326   UINT8 t,r;
1327   IDXBYTE(t); r = A&t;
1328   CLR_NZV;
1329   SET_NZ8(r);
1330}
1331
1332/* $a6 LDA indexed -**0- */
1333OP_HANDLER( lda_ix )
1334{
1335   IDXBYTE(A);
1336   CLR_NZV;
1337   SET_NZ8(A);
1338}
1339
1340/* $a7 STA indexed -**0- */
1341OP_HANDLER( sta_ix )
1342{
1343   CLR_NZV;
1344   SET_NZ8(A);
1345   INDEXED;
1346   WM(EAD,A);
1347}
1348
1349/* $a8 EORA indexed -**0- */
1350OP_HANDLER( eora_ix )
1351{
1352   UINT8 t;
1353   IDXBYTE(t);
1354   A ^= t;
1355   CLR_NZV;
1356   SET_NZ8(A);
1357}
1358
1359/* $a9 ADCA indexed ***** */
1360OP_HANDLER( adca_ix )
1361{
1362   UINT16 t,r;
1363   IDXBYTE(t);
1364   r = A + t + (CC&0x01);
1365   CLR_HNZVC;
1366   SET_FLAGS8(A,t,r);
1367   SET_H(A,t,r);
1368   A = r;
1369}
1370
1371/* $aa ORA indexed -**0- */
1372OP_HANDLER( ora_ix )
1373{
1374   UINT8 t;
1375   IDXBYTE(t);
1376   A |= t;
1377   CLR_NZV;
1378   SET_NZ8(A);
1379}
1380
1381/* $ab ADDA indexed ***** */
1382OP_HANDLER( adda_ix )
1383{
1384   UINT16 t,r;
1385   IDXBYTE(t);
1386   r = A+t;
1387   CLR_HNZVC;
1388   SET_FLAGS8(A,t,r);
1389   SET_H(A,t,r);
1390   A = r;
1391}
1392
1393/* $ac CMPX indexed -***- */
1394OP_HANDLER( cmpx_ix )
1395{
1396   UINT32 r,d;
1397   PAIR b;
1398   IDXWORD(b);
1399   d = X;
1400   r = d - b.d;
1401   CLR_NZV;
1402   SET_NZ16(r);
1403   SET_V16(d,b.d,r);
1404}
1405
1406/* $ac CPX indexed -**** (6803)*/
1407OP_HANDLER( cpx_ix )
1408{
1409   UINT32 r,d;
1410   PAIR b;
1411   IDXWORD(b);
1412   d = X;
1413   r = d - b.d;
1414   CLR_NZVC;
1415   SET_FLAGS16(d,b.d,r);
1416}
1417
1418/* $ad JSR indexed ----- */
1419OP_HANDLER( jsr_ix )
1420{
1421   INDEXED;
1422   PUSHWORD(pPC);
1423   PC = EA;
1424}
1425
1426/* $ae LDS indexed -**0- */
1427OP_HANDLER( lds_ix )
1428{
1429   IDXWORD(m_s);
1430   CLR_NZV;
1431   SET_NZ16(S);
1432}
1433
1434/* $af STS indexed -**0- */
1435OP_HANDLER( sts_ix )
1436{
1437   CLR_NZV;
1438   SET_NZ16(S);
1439   INDEXED;
1440   WM16(EAD,&m_s);
1441}
1442
1443/* $b0 SUBA extended ?**** */
1444OP_HANDLER( suba_ex )
1445{
1446   UINT16    t,r;
1447   EXTBYTE(t);
1448   r = A - t;
1449   CLR_NZVC;
1450   SET_FLAGS8(A,t,r);
1451   A = r;
1452}
1453
1454/* $b1 CMPA extended ?**** */
1455OP_HANDLER( cmpa_ex )
1456{
1457   UINT16    t,r;
1458   EXTBYTE(t);
1459   r = A-t;
1460   CLR_NZVC;
1461   SET_FLAGS8(A,t,r);
1462}
1463
1464/* $b2 SBCA extended ?**** */
1465OP_HANDLER( sbca_ex )
1466{
1467   UINT16    t,r;
1468   EXTBYTE(t);
1469   r = A-t-(CC&0x01);
1470   CLR_NZVC;
1471   SET_FLAGS8(A,t,r);
1472   A = r;
1473}
1474
1475/* $b3 SUBD extended -**** */
1476OP_HANDLER( subd_ex )
1477{
1478   UINT32 r,d;
1479   PAIR b;
1480   EXTWORD(b);
1481   d = D;
1482   r = d - b.d;
1483   CLR_NZVC;
1484   SET_FLAGS16(d,b.d,r);
1485   D=r;
1486}
1487
1488/* $b4 ANDA extended -**0- */
1489OP_HANDLER( anda_ex )
1490{
1491   UINT8 t;
1492   EXTBYTE(t);
1493   A &= t;
1494   CLR_NZV;
1495   SET_NZ8(A);
1496}
1497
1498/* $b5 BITA extended -**0- */
1499OP_HANDLER( bita_ex )
1500{
1501   UINT8 t,r;
1502   EXTBYTE(t);
1503   r = A&t;
1504   CLR_NZV;
1505   SET_NZ8(r);
1506}
1507
1508/* $b6 LDA extended -**0- */
1509OP_HANDLER( lda_ex )
1510{
1511   EXTBYTE(A);
1512   CLR_NZV;
1513   SET_NZ8(A);
1514}
1515
1516/* $b7 STA extended -**0- */
1517OP_HANDLER( sta_ex )
1518{
1519   CLR_NZV;
1520   SET_NZ8(A);
1521   EXTENDED;
1522   WM(EAD,A);
1523}
1524
1525/* $b8 EORA extended -**0- */
1526OP_HANDLER( eora_ex )
1527{
1528   UINT8 t;
1529   EXTBYTE(t);
1530   A ^= t;
1531   CLR_NZV;
1532   SET_NZ8(A);
1533}
1534
1535/* $b9 ADCA extended ***** */
1536OP_HANDLER( adca_ex )
1537{
1538   UINT16 t,r;
1539   EXTBYTE(t);
1540   r = A+t+(CC&0x01);
1541   CLR_HNZVC;
1542   SET_FLAGS8(A,t,r);
1543   SET_H(A,t,r);
1544   A = r;
1545}
1546
1547/* $ba ORA extended -**0- */
1548OP_HANDLER( ora_ex )
1549{
1550   UINT8 t;
1551   EXTBYTE(t);
1552   A |= t;
1553   CLR_NZV;
1554   SET_NZ8(A);
1555}
1556
1557/* $bb ADDA extended ***** */
1558OP_HANDLER( adda_ex )
1559{
1560   UINT16 t,r;
1561   EXTBYTE(t);
1562   r = A+t;
1563   CLR_HNZVC;
1564   SET_FLAGS8(A,t,r);
1565   SET_H(A,t,r);
1566   A = r;
1567}
1568
1569/* $bc CMPX extended -***- */
1570OP_HANDLER( cmpx_ex )
1571{
1572   UINT32 r,d;
1573   PAIR b;
1574   EXTWORD(b);
1575   d = X;
1576   r = d - b.d;
1577   CLR_NZV;
1578   SET_NZ16(r);
1579   SET_V16(d,b.d,r);
1580}
1581
1582/* $bc CPX extended -**** (6803) */
1583OP_HANDLER( cpx_ex )
1584{
1585   UINT32 r,d;
1586   PAIR b;
1587   EXTWORD(b);
1588   d = X;
1589   r = d - b.d;
1590   CLR_NZVC;
1591   SET_FLAGS16(d,b.d,r);
1592}
1593
1594/* $bd JSR extended ----- */
1595OP_HANDLER( jsr_ex )
1596{
1597   EXTENDED;
1598   PUSHWORD(pPC);
1599   PC = EA;
1600}
1601
1602/* $be LDS extended -**0- */
1603OP_HANDLER( lds_ex )
1604{
1605   EXTWORD(m_s);
1606   CLR_NZV;
1607   SET_NZ16(S);
1608}
1609
1610/* $bf STS extended -**0- */
1611OP_HANDLER( sts_ex )
1612{
1613   CLR_NZV;
1614   SET_NZ16(S);
1615   EXTENDED;
1616   WM16(EAD,&m_s);
1617}
1618
1619/* $c0 SUBB immediate ?**** */
1620OP_HANDLER( subb_im )
1621{
1622   UINT16    t,r;
1623   IMMBYTE(t);
1624   r = B-t;
1625   CLR_NZVC;
1626   SET_FLAGS8(B,t,r);
1627   B = r;
1628}
1629
1630/* $c1 CMPB immediate ?**** */
1631OP_HANDLER( cmpb_im )
1632{
1633   UINT16    t,r;
1634   IMMBYTE(t);
1635   r = B-t;
1636   CLR_NZVC;
1637   SET_FLAGS8(B,t,r);
1638}
1639
1640/* $c2 SBCB immediate ?**** */
1641OP_HANDLER( sbcb_im )
1642{
1643   UINT16    t,r;
1644   IMMBYTE(t);
1645   r = B-t-(CC&0x01);
1646   CLR_NZVC;
1647   SET_FLAGS8(B,t,r);
1648   B = r;
1649}
1650
1651/* $c3 ADDD immediate -**** */
1652OP_HANDLER( addd_im )
1653{
1654   UINT32 r,d;
1655   PAIR b;
1656   IMMWORD(b);
1657   d = D;
1658   r = d + b.d;
1659   CLR_NZVC;
1660   SET_FLAGS16(d,b.d,r);
1661   D = r;
1662}
1663
1664/* $c4 ANDB immediate -**0- */
1665OP_HANDLER( andb_im )
1666{
1667   UINT8 t;
1668   IMMBYTE(t);
1669   B &= t;
1670   CLR_NZV;
1671   SET_NZ8(B);
1672}
1673
1674/* $c5 BITB immediate -**0- */
1675OP_HANDLER( bitb_im )
1676{
1677   UINT8 t,r;
1678   IMMBYTE(t);
1679   r = B&t;
1680   CLR_NZV;
1681   SET_NZ8(r);
1682}
1683
1684/* $c6 LDB immediate -**0- */
1685OP_HANDLER( ldb_im )
1686{
1687   IMMBYTE(B);
1688   CLR_NZV;
1689   SET_NZ8(B);
1690}
1691
1692/* is this a legal instruction? */
1693/* $c7 STB immediate -**0- */
1694OP_HANDLER( stb_im )
1695{
1696   CLR_NZV;
1697   SET_NZ8(B);
1698   IMM8;
1699   WM(EAD,B);
1700}
1701
1702/* $c8 EORB immediate -**0- */
1703OP_HANDLER( eorb_im )
1704{
1705   UINT8 t;
1706   IMMBYTE(t);
1707   B ^= t;
1708   CLR_NZV;
1709   SET_NZ8(B);
1710}
1711
1712/* $c9 ADCB immediate ***** */
1713OP_HANDLER( adcb_im )
1714{
1715   UINT16 t,r;
1716   IMMBYTE(t);
1717   r = B+t+(CC&0x01);
1718   CLR_HNZVC;
1719   SET_FLAGS8(B,t,r);
1720   SET_H(B,t,r);
1721   B = r;
1722}
1723
1724/* $ca ORB immediate -**0- */
1725OP_HANDLER( orb_im )
1726{
1727   UINT8 t;
1728   IMMBYTE(t);
1729   B |= t;
1730   CLR_NZV;
1731   SET_NZ8(B);
1732}
1733
1734/* $cb ADDB immediate ***** */
1735OP_HANDLER( addb_im )
1736{
1737   UINT16 t,r;
1738   IMMBYTE(t);
1739   r = B+t;
1740   CLR_HNZVC;
1741   SET_FLAGS8(B,t,r);
1742   SET_H(B,t,r);
1743   B = r;
1744}
1745
1746/* $CC LDD immediate -**0- */
1747OP_HANDLER( ldd_im )
1748{
1749   IMMWORD(m_d);
1750   CLR_NZV;
1751   SET_NZ16(D);
1752}
1753
1754/* is this a legal instruction? */
1755/* $cd STD immediate -**0- */
1756OP_HANDLER( std_im )
1757{
1758   IMM16;
1759   CLR_NZV;
1760   SET_NZ16(D);
1761   WM16(EAD,&m_d);
1762}
1763
1764/* $ce LDX immediate -**0- */
1765OP_HANDLER( ldx_im )
1766{
1767   IMMWORD(m_x);
1768   CLR_NZV;
1769   SET_NZ16(X);
1770}
1771
1772/* $cf STX immediate -**0- */
1773OP_HANDLER( stx_im )
1774{
1775   CLR_NZV;
1776   SET_NZ16(X);
1777   IMM16;
1778   WM16(EAD,&m_x);
1779}
1780
1781/* $d0 SUBB direct ?**** */
1782OP_HANDLER( subb_di )
1783{
1784   UINT16    t,r;
1785   DIRBYTE(t);
1786   r = B-t;
1787   CLR_NZVC;
1788   SET_FLAGS8(B,t,r);
1789   B = r;
1790}
1791
1792/* $d1 CMPB direct ?**** */
1793OP_HANDLER( cmpb_di )
1794{
1795   UINT16    t,r;
1796   DIRBYTE(t);
1797   r = B-t;
1798   CLR_NZVC;
1799   SET_FLAGS8(B,t,r);
1800}
1801
1802/* $d2 SBCB direct ?**** */
1803OP_HANDLER( sbcb_di )
1804{
1805   UINT16    t,r;
1806   DIRBYTE(t);
1807   r = B-t-(CC&0x01);
1808   CLR_NZVC;
1809   SET_FLAGS8(B,t,r);
1810   B = r;
1811}
1812
1813/* $d3 ADDD direct -**** */
1814OP_HANDLER( addd_di )
1815{
1816   UINT32 r,d;
1817   PAIR b;
1818   DIRWORD(b);
1819   d = D;
1820   r = d + b.d;
1821   CLR_NZVC;
1822   SET_FLAGS16(d,b.d,r);
1823   D = r;
1824}
1825
1826/* $d4 ANDB direct -**0- */
1827OP_HANDLER( andb_di )
1828{
1829   UINT8 t;
1830   DIRBYTE(t);
1831   B &= t;
1832   CLR_NZV;
1833   SET_NZ8(B);
1834}
1835
1836/* $d5 BITB direct -**0- */
1837OP_HANDLER( bitb_di )
1838{
1839   UINT8 t,r;
1840   DIRBYTE(t);
1841   r = B&t;
1842   CLR_NZV;
1843   SET_NZ8(r);
1844}
1845
1846/* $d6 LDB direct -**0- */
1847OP_HANDLER( ldb_di )
1848{
1849   DIRBYTE(B);
1850   CLR_NZV;
1851   SET_NZ8(B);
1852}
1853
1854/* $d7 STB direct -**0- */
1855OP_HANDLER( stb_di )
1856{
1857   CLR_NZV;
1858   SET_NZ8(B);
1859   DIRECT;
1860   WM(EAD,B);
1861}
1862
1863/* $d8 EORB direct -**0- */
1864OP_HANDLER( eorb_di )
1865{
1866   UINT8 t;
1867   DIRBYTE(t);
1868   B ^= t;
1869   CLR_NZV;
1870   SET_NZ8(B);
1871}
1872
1873/* $d9 ADCB direct ***** */
1874OP_HANDLER( adcb_di )
1875{
1876   UINT16 t,r;
1877   DIRBYTE(t);
1878   r = B+t+(CC&0x01);
1879   CLR_HNZVC;
1880   SET_FLAGS8(B,t,r);
1881   SET_H(B,t,r);
1882   B = r;
1883}
1884
1885/* $da ORB direct -**0- */
1886OP_HANDLER( orb_di )
1887{
1888   UINT8 t;
1889   DIRBYTE(t);
1890   B |= t;
1891   CLR_NZV;
1892   SET_NZ8(B);
1893}
1894
1895/* $db ADDB direct ***** */
1896OP_HANDLER( addb_di )
1897{
1898   UINT16 t,r;
1899   DIRBYTE(t);
1900   r = B+t;
1901   CLR_HNZVC;
1902   SET_FLAGS8(B,t,r);
1903   SET_H(B,t,r);
1904   B = r;
1905}
1906
1907/* $dc LDD direct -**0- */
1908OP_HANDLER( ldd_di )
1909{
1910   DIRWORD(m_d);
1911   CLR_NZV;
1912   SET_NZ16(D);
1913}
1914
1915/* $dd STD direct -**0- */
1916OP_HANDLER( std_di )
1917{
1918   DIRECT;
1919   CLR_NZV;
1920   SET_NZ16(D);
1921   WM16(EAD,&m_d);
1922}
1923
1924/* $de LDX direct -**0- */
1925OP_HANDLER( ldx_di )
1926{
1927   DIRWORD(m_x);
1928   CLR_NZV;
1929   SET_NZ16(X);
1930}
1931
1932/* $dF STX direct -**0- */
1933OP_HANDLER( stx_di )
1934{
1935   CLR_NZV;
1936   SET_NZ16(X);
1937   DIRECT;
1938   WM16(EAD,&m_x);
1939}
1940
1941/* $e0 SUBB indexed ?**** */
1942OP_HANDLER( subb_ix )
1943{
1944   UINT16    t,r;
1945   IDXBYTE(t);
1946   r = B-t;
1947   CLR_NZVC;
1948   SET_FLAGS8(B,t,r);
1949   B = r;
1950}
1951
1952/* $e1 CMPB indexed ?**** */
1953OP_HANDLER( cmpb_ix )
1954{
1955   UINT16    t,r;
1956   IDXBYTE(t);
1957   r = B-t;
1958   CLR_NZVC;
1959   SET_FLAGS8(B,t,r);
1960}
1961
1962/* $e2 SBCB indexed ?**** */
1963OP_HANDLER( sbcb_ix )
1964{
1965   UINT16    t,r;
1966   IDXBYTE(t);
1967   r = B-t-(CC&0x01);
1968   CLR_NZVC;
1969   SET_FLAGS8(B,t,r);
1970   B = r;
1971}
1972
1973/* $e3 ADDD indexed -**** */
1974OP_HANDLER( addd_ix )
1975{
1976   UINT32 r,d;
1977   PAIR b;
1978   IDXWORD(b);
1979   d = D;
1980   r = d + b.d;
1981   CLR_NZVC;
1982   SET_FLAGS16(d,b.d,r);
1983   D = r;
1984}
1985
1986/* $e4 ANDB indexed -**0- */
1987OP_HANDLER( andb_ix )
1988{
1989   UINT8 t;
1990   IDXBYTE(t);
1991   B &= t;
1992   CLR_NZV;
1993   SET_NZ8(B);
1994}
1995
1996/* $e5 BITB indexed -**0- */
1997OP_HANDLER( bitb_ix )
1998{
1999   UINT8 t,r;
2000   IDXBYTE(t);
2001   r = B&t;
2002   CLR_NZV;
2003   SET_NZ8(r);
2004}
2005
2006/* $e6 LDB indexed -**0- */
2007OP_HANDLER( ldb_ix )
2008{
2009   IDXBYTE(B);
2010   CLR_NZV;
2011   SET_NZ8(B);
2012}
2013
2014/* $e7 STB indexed -**0- */
2015OP_HANDLER( stb_ix )
2016{
2017   CLR_NZV;
2018   SET_NZ8(B);
2019   INDEXED;
2020   WM(EAD,B);
2021}
2022
2023/* $e8 EORB indexed -**0- */
2024OP_HANDLER( eorb_ix )
2025{
2026   UINT8 t;
2027   IDXBYTE(t);
2028   B ^= t;
2029   CLR_NZV;
2030   SET_NZ8(B);
2031}
2032
2033/* $e9 ADCB indexed ***** */
2034OP_HANDLER( adcb_ix )
2035{
2036   UINT16 t,r;
2037   IDXBYTE(t);
2038   r = B+t+(CC&0x01);
2039   CLR_HNZVC;
2040   SET_FLAGS8(B,t,r);
2041   SET_H(B,t,r);
2042   B = r;
2043}
2044
2045/* $ea ORB indexed -**0- */
2046OP_HANDLER( orb_ix )
2047{
2048   UINT8 t;
2049   IDXBYTE(t);
2050   B |= t;
2051   CLR_NZV;
2052   SET_NZ8(B);
2053}
2054
2055/* $eb ADDB indexed ***** */
2056OP_HANDLER( addb_ix )
2057{
2058   UINT16 t,r;
2059   IDXBYTE(t);
2060   r = B+t;
2061   CLR_HNZVC;
2062   SET_FLAGS8(B,t,r);
2063   SET_H(B,t,r);
2064   B = r;
2065}
2066
2067/* $ec LDD indexed -**0- */
2068OP_HANDLER( ldd_ix )
2069{
2070   IDXWORD(m_d);
2071   CLR_NZV;
2072   SET_NZ16(D);
2073}
2074
2075/* $ec ADCX immediate -****    NSC8105 only.  Flags are a guess - copied from addb_im() */
2076OP_HANDLER( adcx_im )
2077{
2078   UINT16 t,r;
2079   IMMBYTE(t);
2080   r = X+t+(CC&0x01);
2081   CLR_HNZVC;
2082   SET_FLAGS8(X,t,r);
2083   SET_H(X,t,r);
2084   X = r;
2085}
2086
2087/* $ed STD indexed -**0- */
2088OP_HANDLER( std_ix )
2089{
2090   INDEXED;
2091   CLR_NZV;
2092   SET_NZ16(D);
2093   WM16(EAD,&m_d);
2094}
2095
2096/* $ee LDX indexed -**0- */
2097OP_HANDLER( ldx_ix )
2098{
2099   IDXWORD(m_x);
2100   CLR_NZV;
2101   SET_NZ16(X);
2102}
2103
2104/* $ef STX indexed -**0- */
2105OP_HANDLER( stx_ix )
2106{
2107   CLR_NZV;
2108   SET_NZ16(X);
2109   INDEXED;
2110   WM16(EAD,&m_x);
2111}
2112
2113/* $f0 SUBB extended ?**** */
2114OP_HANDLER( subb_ex )
2115{
2116   UINT16    t,r;
2117   EXTBYTE(t);
2118   r = B-t;
2119   CLR_NZVC;
2120   SET_FLAGS8(B,t,r);
2121   B = r;
2122}
2123
2124/* $f1 CMPB extended ?**** */
2125OP_HANDLER( cmpb_ex )
2126{
2127   UINT16    t,r;
2128   EXTBYTE(t);
2129   r = B-t;
2130   CLR_NZVC;
2131   SET_FLAGS8(B,t,r);
2132}
2133
2134/* $f2 SBCB extended ?**** */
2135OP_HANDLER( sbcb_ex )
2136{
2137   UINT16    t,r;
2138   EXTBYTE(t);
2139   r = B-t-(CC&0x01);
2140   CLR_NZVC;
2141   SET_FLAGS8(B,t,r);
2142   B = r;
2143}
2144
2145/* $f3 ADDD extended -**** */
2146OP_HANDLER( addd_ex )
2147{
2148   UINT32 r,d;
2149   PAIR b;
2150   EXTWORD(b);
2151   d = D;
2152   r = d + b.d;
2153   CLR_NZVC;
2154   SET_FLAGS16(d,b.d,r);
2155   D = r;
2156}
2157
2158/* $f4 ANDB extended -**0- */
2159OP_HANDLER( andb_ex )
2160{
2161   UINT8 t;
2162   EXTBYTE(t);
2163   B &= t;
2164   CLR_NZV;
2165   SET_NZ8(B);
2166}
2167
2168/* $f5 BITB extended -**0- */
2169OP_HANDLER( bitb_ex )
2170{
2171   UINT8 t,r;
2172   EXTBYTE(t);
2173   r = B & t;
2174   CLR_NZV;
2175   SET_NZ8(r);
2176}
2177
2178/* $f6 LDB extended -**0- */
2179OP_HANDLER( ldb_ex )
2180{
2181   EXTBYTE(B);
2182   CLR_NZV;
2183   SET_NZ8(B);
2184}
2185
2186/* $f7 STB extended -**0- */
2187OP_HANDLER( stb_ex )
2188{
2189   CLR_NZV;
2190   SET_NZ8(B);
2191   EXTENDED;
2192   WM(EAD,B);
2193}
2194
2195/* $f8 EORB extended -**0- */
2196OP_HANDLER( eorb_ex )
2197{
2198   UINT8 t;
2199   EXTBYTE(t);
2200   B ^= t;
2201   CLR_NZV;
2202   SET_NZ8(B);
2203}
2204
2205/* $f9 ADCB extended ***** */
2206OP_HANDLER( adcb_ex )
2207{
2208   UINT16 t,r;
2209   EXTBYTE(t);
2210   r = B+t+(CC&0x01);
2211   CLR_HNZVC;
2212   SET_FLAGS8(B,t,r);
2213   SET_H(B,t,r);
2214   B = r;
2215}
2216
2217/* $fa ORB extended -**0- */
2218OP_HANDLER( orb_ex )
2219{
2220   UINT8 t;
2221   EXTBYTE(t);
2222   B |= t;
2223   CLR_NZV;
2224   SET_NZ8(B);
2225}
2226
2227/* $fb ADDB extended ***** */
2228OP_HANDLER( addb_ex )
2229{
2230   UINT16 t,r;
2231   EXTBYTE(t);
2232   r = B+t;
2233   CLR_HNZVC;
2234   SET_FLAGS8(B,t,r);
2235   SET_H(B,t,r);
2236   B = r;
2237}
2238
2239/* $fc LDD extended -**0- */
2240OP_HANDLER( ldd_ex )
2241{
2242   EXTWORD(m_d);
2243   CLR_NZV;
2244   SET_NZ16(D);
2245}
2246
2247/* $fc ADDX extended -****    NSC8105 only.  Flags are a guess */
2248OP_HANDLER( addx_ex )
2249{
2250   UINT32 r,d;
2251   PAIR b;
2252   EXTWORD(b);
2253   d = X;
2254   r = d + b.d;
2255   CLR_NZVC;
2256   SET_FLAGS16(d,b.d,r);
2257   X = r;
2258}
2259
2260/* $fd STD extended -**0- */
2261OP_HANDLER( std_ex )
2262{
2263   EXTENDED;
2264   CLR_NZV;
2265   SET_NZ16(D);
2266   WM16(EAD,&m_d);
2267}
2268
2269/* $fe LDX extended -**0- */
2270OP_HANDLER( ldx_ex )
2271{
2272   EXTWORD(m_x);
2273   CLR_NZV;
2274   SET_NZ16(X);
2275}
2276
2277/* $ff STX extended -**0- */
2278OP_HANDLER( stx_ex )
2279{
2280   CLR_NZV;
2281   SET_NZ16(X);
2282   EXTENDED;
2283   WM16(EAD,&m_x);
2284}
Property changes on: trunk/src/emu/cpu/m6800/6800ops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/m6800/6800tbl.inc
r0r28739
1
2const m6800_cpu_device::op_func m6800_cpu_device::m6800_insn[0x100] = {
3&m6800_cpu_device::illegal,&m6800_cpu_device::nop,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tap,    &m6800_cpu_device::tpa,
4&m6800_cpu_device::inx,    &m6800_cpu_device::dex,    &m6800_cpu_device::clv,    &m6800_cpu_device::sev,    &m6800_cpu_device::clc,    &m6800_cpu_device::sec,    &m6800_cpu_device::cli,    &m6800_cpu_device::sei,
5&m6800_cpu_device::sba,    &m6800_cpu_device::cba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tab,    &m6800_cpu_device::tba,
6&m6800_cpu_device::illegal,&m6800_cpu_device::daa,    &m6800_cpu_device::illegal,&m6800_cpu_device::aba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,
7&m6800_cpu_device::bra,    &m6800_cpu_device::brn,    &m6800_cpu_device::bhi,    &m6800_cpu_device::bls,    &m6800_cpu_device::bcc,    &m6800_cpu_device::bcs,    &m6800_cpu_device::bne,    &m6800_cpu_device::beq,
8&m6800_cpu_device::bvc,    &m6800_cpu_device::bvs,    &m6800_cpu_device::bpl,    &m6800_cpu_device::bmi,    &m6800_cpu_device::bge,    &m6800_cpu_device::blt,    &m6800_cpu_device::bgt,    &m6800_cpu_device::ble,
9&m6800_cpu_device::tsx,    &m6800_cpu_device::ins,    &m6800_cpu_device::pula,   &m6800_cpu_device::pulb,   &m6800_cpu_device::des,    &m6800_cpu_device::txs,    &m6800_cpu_device::psha,   &m6800_cpu_device::pshb,
10&m6800_cpu_device::illegal,&m6800_cpu_device::rts,    &m6800_cpu_device::illegal,&m6800_cpu_device::rti,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::wai,    &m6800_cpu_device::swi,
11&m6800_cpu_device::nega,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::coma,   &m6800_cpu_device::lsra,   &m6800_cpu_device::illegal,&m6800_cpu_device::rora,   &m6800_cpu_device::asra,
12&m6800_cpu_device::asla,   &m6800_cpu_device::rola,   &m6800_cpu_device::deca,   &m6800_cpu_device::illegal,&m6800_cpu_device::inca,   &m6800_cpu_device::tsta,   &m6800_cpu_device::illegal,&m6800_cpu_device::clra,
13&m6800_cpu_device::negb,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::comb,   &m6800_cpu_device::lsrb,   &m6800_cpu_device::illegal,&m6800_cpu_device::rorb,   &m6800_cpu_device::asrb,
14&m6800_cpu_device::aslb,   &m6800_cpu_device::rolb,   &m6800_cpu_device::decb,   &m6800_cpu_device::illegal,&m6800_cpu_device::incb,   &m6800_cpu_device::tstb,   &m6800_cpu_device::illegal,&m6800_cpu_device::clrb,
15&m6800_cpu_device::neg_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::ror_ix, &m6800_cpu_device::asr_ix,
16&m6800_cpu_device::asl_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::clr_ix,
17&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::ror_ex, &m6800_cpu_device::asr_ex,
18&m6800_cpu_device::asl_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::clr_ex,
19&m6800_cpu_device::suba_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_im,&m6800_cpu_device::bita_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::sta_im,
20&m6800_cpu_device::eora_im,&m6800_cpu_device::adca_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adda_im,&m6800_cpu_device::cmpx_im,&m6800_cpu_device::bsr,    &m6800_cpu_device::lds_im, &m6800_cpu_device::sts_im,
21&m6800_cpu_device::suba_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_di,&m6800_cpu_device::bita_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::sta_di,
22&m6800_cpu_device::eora_di,&m6800_cpu_device::adca_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adda_di,&m6800_cpu_device::cmpx_di,&m6800_cpu_device::jsr_di, &m6800_cpu_device::lds_di, &m6800_cpu_device::sts_di,
23&m6800_cpu_device::suba_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ix,&m6800_cpu_device::bita_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::sta_ix,
24&m6800_cpu_device::eora_ix,&m6800_cpu_device::adca_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adda_ix,&m6800_cpu_device::cmpx_ix,&m6800_cpu_device::jsr_ix, &m6800_cpu_device::lds_ix, &m6800_cpu_device::sts_ix,
25&m6800_cpu_device::suba_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ex,&m6800_cpu_device::bita_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::sta_ex,
26&m6800_cpu_device::eora_ex,&m6800_cpu_device::adca_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adda_ex,&m6800_cpu_device::cmpx_ex,&m6800_cpu_device::jsr_ex, &m6800_cpu_device::lds_ex, &m6800_cpu_device::sts_ex,
27&m6800_cpu_device::subb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_im,&m6800_cpu_device::bitb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::stb_im,
28&m6800_cpu_device::eorb_im,&m6800_cpu_device::adcb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::addb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_im, &m6800_cpu_device::stx_im,
29&m6800_cpu_device::subb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_di,&m6800_cpu_device::bitb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::stb_di,
30&m6800_cpu_device::eorb_di,&m6800_cpu_device::adcb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::addb_di,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_di, &m6800_cpu_device::stx_di,
31&m6800_cpu_device::subb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_ix,&m6800_cpu_device::bitb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::stb_ix,
32&m6800_cpu_device::eorb_ix,&m6800_cpu_device::adcb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::addb_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_ix, &m6800_cpu_device::stx_ix,
33&m6800_cpu_device::subb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_ex,&m6800_cpu_device::bitb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::stb_ex,
34&m6800_cpu_device::eorb_ex,&m6800_cpu_device::adcb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::addb_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_ex, &m6800_cpu_device::stx_ex
35};
36
37const m6800_cpu_device::op_func m6800_cpu_device::m6803_insn[0x100] = {
38&m6800_cpu_device::illegal,&m6800_cpu_device::nop,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::lsrd,   &m6800_cpu_device::asld,   &m6800_cpu_device::tap,    &m6800_cpu_device::tpa,
39&m6800_cpu_device::inx,    &m6800_cpu_device::dex,    &m6800_cpu_device::clv,    &m6800_cpu_device::sev,    &m6800_cpu_device::clc,    &m6800_cpu_device::sec,    &m6800_cpu_device::cli,    &m6800_cpu_device::sei,
40&m6800_cpu_device::sba,    &m6800_cpu_device::cba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tab,    &m6800_cpu_device::tba,
41&m6800_cpu_device::illegal,&m6800_cpu_device::daa,    &m6800_cpu_device::illegal,&m6800_cpu_device::aba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,
42&m6800_cpu_device::bra,    &m6800_cpu_device::brn,    &m6800_cpu_device::bhi,    &m6800_cpu_device::bls,    &m6800_cpu_device::bcc,    &m6800_cpu_device::bcs,    &m6800_cpu_device::bne,    &m6800_cpu_device::beq,
43&m6800_cpu_device::bvc,    &m6800_cpu_device::bvs,    &m6800_cpu_device::bpl,    &m6800_cpu_device::bmi,    &m6800_cpu_device::bge,    &m6800_cpu_device::blt,    &m6800_cpu_device::bgt,    &m6800_cpu_device::ble,
44&m6800_cpu_device::tsx,    &m6800_cpu_device::ins,    &m6800_cpu_device::pula,   &m6800_cpu_device::pulb,   &m6800_cpu_device::des,    &m6800_cpu_device::txs,    &m6800_cpu_device::psha,   &m6800_cpu_device::pshb,
45&m6800_cpu_device::pulx,   &m6800_cpu_device::rts,    &m6800_cpu_device::abx,    &m6800_cpu_device::rti,    &m6800_cpu_device::pshx,   &m6800_cpu_device::mul,    &m6800_cpu_device::wai,    &m6800_cpu_device::swi,
46&m6800_cpu_device::nega,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::coma,   &m6800_cpu_device::lsra,   &m6800_cpu_device::illegal,&m6800_cpu_device::rora,   &m6800_cpu_device::asra,
47&m6800_cpu_device::asla,   &m6800_cpu_device::rola,   &m6800_cpu_device::deca,   &m6800_cpu_device::illegal,&m6800_cpu_device::inca,   &m6800_cpu_device::tsta,   &m6800_cpu_device::illegal,&m6800_cpu_device::clra,
48&m6800_cpu_device::negb,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::comb,   &m6800_cpu_device::lsrb,   &m6800_cpu_device::illegal,&m6800_cpu_device::rorb,   &m6800_cpu_device::asrb,
49&m6800_cpu_device::aslb,   &m6800_cpu_device::rolb,   &m6800_cpu_device::decb,   &m6800_cpu_device::illegal,&m6800_cpu_device::incb,   &m6800_cpu_device::tstb,   &m6800_cpu_device::illegal,&m6800_cpu_device::clrb,
50&m6800_cpu_device::neg_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::ror_ix, &m6800_cpu_device::asr_ix,
51&m6800_cpu_device::asl_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::clr_ix,
52&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::ror_ex, &m6800_cpu_device::asr_ex,
53&m6800_cpu_device::asl_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::clr_ex,
54&m6800_cpu_device::suba_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::subd_im,&m6800_cpu_device::anda_im,&m6800_cpu_device::bita_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::sta_im,
55&m6800_cpu_device::eora_im,&m6800_cpu_device::adca_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adda_im,&m6800_cpu_device::cpx_im ,&m6800_cpu_device::bsr,    &m6800_cpu_device::lds_im, &m6800_cpu_device::sts_im,
56&m6800_cpu_device::suba_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::subd_di,&m6800_cpu_device::anda_di,&m6800_cpu_device::bita_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::sta_di,
57&m6800_cpu_device::eora_di,&m6800_cpu_device::adca_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adda_di,&m6800_cpu_device::cpx_di ,&m6800_cpu_device::jsr_di, &m6800_cpu_device::lds_di, &m6800_cpu_device::sts_di,
58&m6800_cpu_device::suba_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::subd_ix,&m6800_cpu_device::anda_ix,&m6800_cpu_device::bita_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::sta_ix,
59&m6800_cpu_device::eora_ix,&m6800_cpu_device::adca_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adda_ix,&m6800_cpu_device::cpx_ix ,&m6800_cpu_device::jsr_ix, &m6800_cpu_device::lds_ix, &m6800_cpu_device::sts_ix,
60&m6800_cpu_device::suba_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::subd_ex,&m6800_cpu_device::anda_ex,&m6800_cpu_device::bita_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::sta_ex,
61&m6800_cpu_device::eora_ex,&m6800_cpu_device::adca_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adda_ex,&m6800_cpu_device::cpx_ex ,&m6800_cpu_device::jsr_ex, &m6800_cpu_device::lds_ex, &m6800_cpu_device::sts_ex,
62&m6800_cpu_device::subb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::addd_im,&m6800_cpu_device::andb_im,&m6800_cpu_device::bitb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::stb_im,
63&m6800_cpu_device::eorb_im,&m6800_cpu_device::adcb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::addb_im,&m6800_cpu_device::ldd_im, &m6800_cpu_device::std_im, &m6800_cpu_device::ldx_im, &m6800_cpu_device::stx_im,
64&m6800_cpu_device::subb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::addd_di,&m6800_cpu_device::andb_di,&m6800_cpu_device::bitb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::stb_di,
65&m6800_cpu_device::eorb_di,&m6800_cpu_device::adcb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::addb_di,&m6800_cpu_device::ldd_di, &m6800_cpu_device::std_di, &m6800_cpu_device::ldx_di, &m6800_cpu_device::stx_di,
66&m6800_cpu_device::subb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::addd_ix,&m6800_cpu_device::andb_ix,&m6800_cpu_device::bitb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::stb_ix,
67&m6800_cpu_device::eorb_ix,&m6800_cpu_device::adcb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::addb_ix,&m6800_cpu_device::ldd_ix, &m6800_cpu_device::std_ix, &m6800_cpu_device::ldx_ix, &m6800_cpu_device::stx_ix,
68&m6800_cpu_device::subb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::addd_ex,&m6800_cpu_device::andb_ex,&m6800_cpu_device::bitb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::stb_ex,
69&m6800_cpu_device::eorb_ex,&m6800_cpu_device::adcb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::addb_ex,&m6800_cpu_device::ldd_ex, &m6800_cpu_device::std_ex, &m6800_cpu_device::ldx_ex, &m6800_cpu_device::stx_ex
70};
71
72const m6800_cpu_device::op_func m6800_cpu_device::hd63701_insn[0x100] = {
73&m6800_cpu_device::trap,   &m6800_cpu_device::nop,    &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::lsrd,   &m6800_cpu_device::asld,   &m6800_cpu_device::tap,    &m6800_cpu_device::tpa,
74&m6800_cpu_device::inx,    &m6800_cpu_device::dex,    &m6800_cpu_device::clv,    &m6800_cpu_device::sev,    &m6800_cpu_device::clc,    &m6800_cpu_device::sec,    &m6800_cpu_device::cli,    &m6800_cpu_device::sei,
75&m6800_cpu_device::sba,    &m6800_cpu_device::cba,    &m6800_cpu_device::undoc1, &m6800_cpu_device::undoc2, &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::tab,    &m6800_cpu_device::tba,
76&m6800_cpu_device::xgdx,   &m6800_cpu_device::daa,    &m6800_cpu_device::slp,    &m6800_cpu_device::aba,    &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::trap,
77&m6800_cpu_device::bra,    &m6800_cpu_device::brn,    &m6800_cpu_device::bhi,    &m6800_cpu_device::bls,    &m6800_cpu_device::bcc,    &m6800_cpu_device::bcs,    &m6800_cpu_device::bne,    &m6800_cpu_device::beq,
78&m6800_cpu_device::bvc,    &m6800_cpu_device::bvs,    &m6800_cpu_device::bpl,    &m6800_cpu_device::bmi,    &m6800_cpu_device::bge,    &m6800_cpu_device::blt,    &m6800_cpu_device::bgt,    &m6800_cpu_device::ble,
79&m6800_cpu_device::tsx,    &m6800_cpu_device::ins,    &m6800_cpu_device::pula,   &m6800_cpu_device::pulb,   &m6800_cpu_device::des,    &m6800_cpu_device::txs,    &m6800_cpu_device::psha,   &m6800_cpu_device::pshb,
80&m6800_cpu_device::pulx,   &m6800_cpu_device::rts,    &m6800_cpu_device::abx,    &m6800_cpu_device::rti,    &m6800_cpu_device::pshx,   &m6800_cpu_device::mul,    &m6800_cpu_device::wai,    &m6800_cpu_device::swi,
81&m6800_cpu_device::nega,   &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::coma,   &m6800_cpu_device::lsra,   &m6800_cpu_device::trap,   &m6800_cpu_device::rora,   &m6800_cpu_device::asra,
82&m6800_cpu_device::asla,   &m6800_cpu_device::rola,   &m6800_cpu_device::deca,   &m6800_cpu_device::trap,   &m6800_cpu_device::inca,   &m6800_cpu_device::tsta,   &m6800_cpu_device::trap,   &m6800_cpu_device::clra,
83&m6800_cpu_device::negb,   &m6800_cpu_device::trap,   &m6800_cpu_device::trap,   &m6800_cpu_device::comb,   &m6800_cpu_device::lsrb,   &m6800_cpu_device::trap,   &m6800_cpu_device::rorb,   &m6800_cpu_device::asrb,
84&m6800_cpu_device::aslb,   &m6800_cpu_device::rolb,   &m6800_cpu_device::decb,   &m6800_cpu_device::trap,   &m6800_cpu_device::incb,   &m6800_cpu_device::tstb,   &m6800_cpu_device::trap,   &m6800_cpu_device::clrb,
85&m6800_cpu_device::neg_ix, &m6800_cpu_device::aim_ix, &m6800_cpu_device::oim_ix, &m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::eim_ix, &m6800_cpu_device::ror_ix, &m6800_cpu_device::asr_ix,
86&m6800_cpu_device::asl_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::tim_ix, &m6800_cpu_device::inc_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::clr_ix,
87&m6800_cpu_device::neg_ex, &m6800_cpu_device::aim_di, &m6800_cpu_device::oim_di, &m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::eim_di, &m6800_cpu_device::ror_ex, &m6800_cpu_device::asr_ex,
88&m6800_cpu_device::asl_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::tim_di, &m6800_cpu_device::inc_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::clr_ex,
89&m6800_cpu_device::suba_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::subd_im,&m6800_cpu_device::anda_im,&m6800_cpu_device::bita_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::sta_im,
90&m6800_cpu_device::eora_im,&m6800_cpu_device::adca_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adda_im,&m6800_cpu_device::cpx_im ,&m6800_cpu_device::bsr,    &m6800_cpu_device::lds_im, &m6800_cpu_device::sts_im,
91&m6800_cpu_device::suba_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::subd_di,&m6800_cpu_device::anda_di,&m6800_cpu_device::bita_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::sta_di,
92&m6800_cpu_device::eora_di,&m6800_cpu_device::adca_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adda_di,&m6800_cpu_device::cpx_di ,&m6800_cpu_device::jsr_di, &m6800_cpu_device::lds_di, &m6800_cpu_device::sts_di,
93&m6800_cpu_device::suba_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::subd_ix,&m6800_cpu_device::anda_ix,&m6800_cpu_device::bita_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::sta_ix,
94&m6800_cpu_device::eora_ix,&m6800_cpu_device::adca_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adda_ix,&m6800_cpu_device::cpx_ix ,&m6800_cpu_device::jsr_ix, &m6800_cpu_device::lds_ix, &m6800_cpu_device::sts_ix,
95&m6800_cpu_device::suba_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::subd_ex,&m6800_cpu_device::anda_ex,&m6800_cpu_device::bita_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::sta_ex,
96&m6800_cpu_device::eora_ex,&m6800_cpu_device::adca_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adda_ex,&m6800_cpu_device::cpx_ex ,&m6800_cpu_device::jsr_ex, &m6800_cpu_device::lds_ex, &m6800_cpu_device::sts_ex,
97&m6800_cpu_device::subb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::addd_im,&m6800_cpu_device::andb_im,&m6800_cpu_device::bitb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::stb_im,
98&m6800_cpu_device::eorb_im,&m6800_cpu_device::adcb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::addb_im,&m6800_cpu_device::ldd_im, &m6800_cpu_device::std_im, &m6800_cpu_device::ldx_im, &m6800_cpu_device::stx_im,
99&m6800_cpu_device::subb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::addd_di,&m6800_cpu_device::andb_di,&m6800_cpu_device::bitb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::stb_di,
100&m6800_cpu_device::eorb_di,&m6800_cpu_device::adcb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::addb_di,&m6800_cpu_device::ldd_di, &m6800_cpu_device::std_di, &m6800_cpu_device::ldx_di, &m6800_cpu_device::stx_di,
101&m6800_cpu_device::subb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::addd_ix,&m6800_cpu_device::andb_ix,&m6800_cpu_device::bitb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::stb_ix,
102&m6800_cpu_device::eorb_ix,&m6800_cpu_device::adcb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::addb_ix,&m6800_cpu_device::ldd_ix, &m6800_cpu_device::std_ix, &m6800_cpu_device::ldx_ix, &m6800_cpu_device::stx_ix,
103&m6800_cpu_device::subb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::addd_ex,&m6800_cpu_device::andb_ex,&m6800_cpu_device::bitb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::stb_ex,
104&m6800_cpu_device::eorb_ex,&m6800_cpu_device::adcb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::addb_ex,&m6800_cpu_device::ldd_ex, &m6800_cpu_device::std_ex, &m6800_cpu_device::ldx_ex, &m6800_cpu_device::stx_ex
105};
106
107const m6800_cpu_device::op_func m6800_cpu_device::nsc8105_insn[0x100] = {
108&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::nop,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tap,    &m6800_cpu_device::illegal,&m6800_cpu_device::tpa,
109&m6800_cpu_device::inx,    &m6800_cpu_device::clv,    &m6800_cpu_device::dex,    &m6800_cpu_device::sev,    &m6800_cpu_device::clc,    &m6800_cpu_device::cli,    &m6800_cpu_device::sec,    &m6800_cpu_device::sei,
110&m6800_cpu_device::sba,    &m6800_cpu_device::illegal,&m6800_cpu_device::cba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tab,    &m6800_cpu_device::illegal,&m6800_cpu_device::tba,
111&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::daa,    &m6800_cpu_device::aba,    &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,
112&m6800_cpu_device::bra,    &m6800_cpu_device::bhi,    &m6800_cpu_device::brn,    &m6800_cpu_device::bls,    &m6800_cpu_device::bcc,    &m6800_cpu_device::bne,    &m6800_cpu_device::bcs,    &m6800_cpu_device::beq,
113&m6800_cpu_device::bvc,    &m6800_cpu_device::bpl,    &m6800_cpu_device::bvs,    &m6800_cpu_device::bmi,    &m6800_cpu_device::bge,    &m6800_cpu_device::bgt,    &m6800_cpu_device::blt,    &m6800_cpu_device::ble,
114&m6800_cpu_device::tsx,    &m6800_cpu_device::pula,   &m6800_cpu_device::ins,    &m6800_cpu_device::pulb,   &m6800_cpu_device::des,    &m6800_cpu_device::psha,   &m6800_cpu_device::txs,    &m6800_cpu_device::pshb,
115&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::rts,    &m6800_cpu_device::rti,    &m6800_cpu_device::illegal,&m6800_cpu_device::wai,    &m6800_cpu_device::illegal,&m6800_cpu_device::swi,
116&m6800_cpu_device::suba_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::bita_im,&m6800_cpu_device::sta_im,
117&m6800_cpu_device::eora_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adca_im,&m6800_cpu_device::adda_im,&m6800_cpu_device::cmpx_im,&m6800_cpu_device::lds_im, &m6800_cpu_device::bsr,    &m6800_cpu_device::sts_im,
118&m6800_cpu_device::suba_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::bita_di,&m6800_cpu_device::sta_di,
119&m6800_cpu_device::eora_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adca_di,&m6800_cpu_device::adda_di,&m6800_cpu_device::cmpx_di,&m6800_cpu_device::lds_di, &m6800_cpu_device::jsr_di, &m6800_cpu_device::sts_di,
120&m6800_cpu_device::suba_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::bita_ix,&m6800_cpu_device::sta_ix,
121&m6800_cpu_device::eora_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adca_ix,&m6800_cpu_device::adda_ix,&m6800_cpu_device::cmpx_ix,&m6800_cpu_device::lds_ix, &m6800_cpu_device::jsr_ix, &m6800_cpu_device::sts_ix,
122&m6800_cpu_device::suba_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::bita_ex,&m6800_cpu_device::sta_ex,
123&m6800_cpu_device::eora_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adca_ex,&m6800_cpu_device::adda_ex,&m6800_cpu_device::cmpx_ex,&m6800_cpu_device::lds_ex, &m6800_cpu_device::jsr_ex, &m6800_cpu_device::sts_ex,
124&m6800_cpu_device::nega,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::coma,   &m6800_cpu_device::lsra,   &m6800_cpu_device::rora,   &m6800_cpu_device::illegal,&m6800_cpu_device::asra,
125&m6800_cpu_device::asla,   &m6800_cpu_device::deca,   &m6800_cpu_device::rola,   &m6800_cpu_device::illegal,&m6800_cpu_device::inca,   &m6800_cpu_device::illegal,&m6800_cpu_device::tsta,   &m6800_cpu_device::clra,
126&m6800_cpu_device::negb,   &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::comb,   &m6800_cpu_device::lsrb,   &m6800_cpu_device::rorb,   &m6800_cpu_device::illegal,&m6800_cpu_device::asrb,
127&m6800_cpu_device::aslb,   &m6800_cpu_device::decb,   &m6800_cpu_device::rolb,   &m6800_cpu_device::illegal,&m6800_cpu_device::incb,   &m6800_cpu_device::illegal,&m6800_cpu_device::tstb,   &m6800_cpu_device::clrb,
128&m6800_cpu_device::neg_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::ror_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::asr_ix,
129&m6800_cpu_device::asl_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::clr_ix,
130&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::ror_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::asr_ex,
131&m6800_cpu_device::asl_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::clr_ex,
132&m6800_cpu_device::subb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::bitb_im,&m6800_cpu_device::stb_im,
133&m6800_cpu_device::eorb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::adcb_im,&m6800_cpu_device::addb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_im, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_im,
134&m6800_cpu_device::subb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::bitb_di,&m6800_cpu_device::stb_di,
135&m6800_cpu_device::eorb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::adcb_di,&m6800_cpu_device::addb_di,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_di, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_di,
136&m6800_cpu_device::subb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::bitb_ix,&m6800_cpu_device::stb_ix,
137&m6800_cpu_device::eorb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::adcb_ix,&m6800_cpu_device::addb_ix,&m6800_cpu_device::adcx_im,&m6800_cpu_device::ldx_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_ix,
138&m6800_cpu_device::subb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::bitb_ex,&m6800_cpu_device::stb_ex,
139&m6800_cpu_device::eorb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::adcb_ex,&m6800_cpu_device::addb_ex,&m6800_cpu_device::addx_ex,&m6800_cpu_device::ldx_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_ex
140};
Property changes on: trunk/src/emu/cpu/m6800/6800tbl.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/m6800/m6800.c
r28738r28739
823823}
824824
825825/* include the opcode prototypes and function pointer tables */
826#include "6800tbl.c"
826#include "6800tbl.inc"
827827
828828/* include the opcode functions */
829#include "6800ops.c"
829#include "6800ops.inc"
830830
831831int m6800_cpu_device::m6800_rx()
832832{
trunk/src/emu/cpu/dsp56k/dsp56ops.c
r28738r28739
1/***************************************************************************
2
3    dsp56ops.c
4    Core implementation for the portable Motorola/Freescale DSP56k emulator.
5    Written by Andrew Gardner
6
7***************************************************************************/
8
9/* NOTES For register setting:
10   FM.3-4 : When A2 or B2 is read, the register contents occupy the low-order portion
11            (bits 7-0) of the word; the high-order portion (bits 16-8) is sign-extended. When A2 or B2
12            is written, the register receives the low-order portion of the word; the high-order portion is not used
13          : ...much more!
14          : ...shifter/limiter/overflow notes too.
15
16*/
17
18/*
19TODO:
20    - 0x01ee: should this move sign extend?  otherwise the test-against-minus means nothing.
21    - Restore only the proper bits upon loop termination!
22    - BFCLR has some errata in the docs that may need to be applied.
23*/
24
25/************************/
26/* Datatypes and macros */
27/************************/
28enum addSubOpType { OP_ADD,
29               OP_SUB,
30               OP_OTHER };
31
32enum dataType { DT_BYTE,
33            DT_WORD,
34            DT_DOUBLE_WORD,
35            DT_LONG_WORD };
36
37struct typed_pointer
38{
39   void* addr;
40   char  data_type;
41};
42
43//#define ADDRESS(X) (X<<1)
44#define BITS(CUR,MASK) (Dsp56kOpMask(CUR,MASK))
45
46/*********************/
47/* Opcode prototypes */
48/*********************/
49static size_t dsp56k_op_addsub_2 (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
50static size_t dsp56k_op_mac_1    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
51static size_t dsp56k_op_macr_1   (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
52static size_t dsp56k_op_move_1   (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
53static size_t dsp56k_op_mpy_1    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
54static size_t dsp56k_op_mpyr_1   (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
55static size_t dsp56k_op_tfr_2    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
56static size_t dsp56k_op_mpy_2    (dsp56k_core* cpustate, const UINT16 op_byte, UINT8* cycles);
57static size_t dsp56k_op_mac_2    (dsp56k_core* cpustate, const UINT16 op_byte, UINT8* cycles);
58static size_t dsp56k_op_clr      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
59static size_t dsp56k_op_add      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
60static size_t dsp56k_op_move     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
61static size_t dsp56k_op_tfr      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
62static size_t dsp56k_op_rnd      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
63static size_t dsp56k_op_tst      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
64static size_t dsp56k_op_inc      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
65static size_t dsp56k_op_inc24    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
66static size_t dsp56k_op_or       (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
67static size_t dsp56k_op_asr      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
68static size_t dsp56k_op_asl      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
69static size_t dsp56k_op_lsr      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
70static size_t dsp56k_op_lsl      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
71static size_t dsp56k_op_eor      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
72static size_t dsp56k_op_subl     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
73static size_t dsp56k_op_sub      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
74static size_t dsp56k_op_clr24    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
75static size_t dsp56k_op_sbc      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
76static size_t dsp56k_op_cmp      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
77static size_t dsp56k_op_neg      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
78static size_t dsp56k_op_not      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
79static size_t dsp56k_op_dec      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
80static size_t dsp56k_op_dec24    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
81static size_t dsp56k_op_and      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
82static size_t dsp56k_op_abs      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
83static size_t dsp56k_op_ror      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
84static size_t dsp56k_op_rol      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
85static size_t dsp56k_op_cmpm     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
86static size_t dsp56k_op_mpy      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
87static size_t dsp56k_op_mpyr     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
88static size_t dsp56k_op_mac      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
89static size_t dsp56k_op_macr     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
90static size_t dsp56k_op_adc      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
91static size_t dsp56k_op_andi     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
92static size_t dsp56k_op_asl4     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
93static size_t dsp56k_op_asr4     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
94static size_t dsp56k_op_asr16    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
95static size_t dsp56k_op_bfop     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
96static size_t dsp56k_op_bfop_1   (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
97static size_t dsp56k_op_bfop_2   (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
98static size_t dsp56k_op_bcc      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
99static size_t dsp56k_op_bcc_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
100static size_t dsp56k_op_bcc_2    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
101static size_t dsp56k_op_bra      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
102static size_t dsp56k_op_bra_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
103static size_t dsp56k_op_bra_2    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
104static size_t dsp56k_op_brkcc    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
105static size_t dsp56k_op_bscc     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
106static size_t dsp56k_op_bscc_1   (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
107static size_t dsp56k_op_bsr      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
108static size_t dsp56k_op_bsr_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
109static size_t dsp56k_op_chkaau   (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
110static size_t dsp56k_op_debug    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
111static size_t dsp56k_op_debugcc  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
112static size_t dsp56k_op_div      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
113static size_t dsp56k_op_dmac     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
114static size_t dsp56k_op_do       (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
115static size_t dsp56k_op_do_1     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
116static size_t dsp56k_op_do_2     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
117static size_t dsp56k_op_doforever(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
118static size_t dsp56k_op_enddo    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
119static size_t dsp56k_op_ext      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
120static size_t dsp56k_op_illegal  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
121static size_t dsp56k_op_imac     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
122static size_t dsp56k_op_impy     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
123static size_t dsp56k_op_jcc      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
124static size_t dsp56k_op_jcc_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
125static size_t dsp56k_op_jmp      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
126static size_t dsp56k_op_jmp_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
127static size_t dsp56k_op_jscc     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
128static size_t dsp56k_op_jscc_1   (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
129static size_t dsp56k_op_jsr      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
130static size_t dsp56k_op_jsr_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
131static size_t dsp56k_op_jsr_2    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
132static size_t dsp56k_op_lea      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
133static size_t dsp56k_op_lea_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
134static size_t dsp56k_op_macsuuu  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
135static size_t dsp56k_op_move_2   (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
136static size_t dsp56k_op_movec    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
137static size_t dsp56k_op_movec_1  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
138static size_t dsp56k_op_movec_2  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
139static size_t dsp56k_op_movec_3  (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
140static size_t dsp56k_op_movec_4  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
141static size_t dsp56k_op_movec_5  (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
142static size_t dsp56k_op_movei    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
143static size_t dsp56k_op_movem    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
144static size_t dsp56k_op_movem_1  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
145static size_t dsp56k_op_movem_2  (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
146static size_t dsp56k_op_movep    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
147static size_t dsp56k_op_movep_1  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
148static size_t dsp56k_op_moves    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
149static size_t dsp56k_op_mpysuuu  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
150static size_t dsp56k_op_negc     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
151static size_t dsp56k_op_nop      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
152static size_t dsp56k_op_norm     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
153static size_t dsp56k_op_ori      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
154static size_t dsp56k_op_rep      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
155static size_t dsp56k_op_rep_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
156static size_t dsp56k_op_rep_2    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
157static size_t dsp56k_op_repcc    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
158static size_t dsp56k_op_reset    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
159static size_t dsp56k_op_rti      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
160static size_t dsp56k_op_rts      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
161static size_t dsp56k_op_stop     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
162static size_t dsp56k_op_swap     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
163static size_t dsp56k_op_swi      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
164static size_t dsp56k_op_tcc      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
165static size_t dsp56k_op_tfr2     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
166static size_t dsp56k_op_tfr3     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
167static size_t dsp56k_op_tst2     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
168static size_t dsp56k_op_wait     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
169static size_t dsp56k_op_zero     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
170
171
172static void execute_register_to_register_data_move(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value);
173static void execute_address_register_update(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value);
174static void execute_x_memory_data_move (dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value);
175static void execute_x_memory_data_move2(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register);
176static void execute_dual_x_memory_data_read(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register);
177static void execute_x_memory_data_move_with_short_displacement(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2);
178
179static UINT16   decode_BBB_bitmask(dsp56k_core* cpustate, UINT16 BBB, UINT16 *iVal);
180static int      decode_cccc_table(dsp56k_core* cpustate, UINT16 cccc);
181static void     decode_DDDDD_table(dsp56k_core* cpustate, UINT16 DDDDD, typed_pointer* ret);
182static void     decode_DD_table(dsp56k_core* cpustate, UINT16 DD, typed_pointer* ret);
183static void     decode_DDF_table(dsp56k_core* cpustate, UINT16 DD, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
184static void     decode_F_table(dsp56k_core* cpustate, UINT16 F, typed_pointer* ret);
185static void     decode_h0hF_table(dsp56k_core* cpustate, UINT16 h0h, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
186static void     decode_HH_table(dsp56k_core* cpustate, UINT16 HH, typed_pointer* ret);
187static void     decode_HHH_table(dsp56k_core* cpustate, UINT16 HHH, typed_pointer* ret);
188static void     decode_IIII_table(dsp56k_core* cpustate, UINT16 IIII, typed_pointer* src_ret, typed_pointer* dst_ret, void* working);
189static void     decode_JJJF_table(dsp56k_core* cpustate, UINT16 JJJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
190static void     decode_JJF_table(dsp56k_core* cpustate, UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
191static void     decode_JF_table(dsp56k_core* cpustate, UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
192static void     decode_KKK_table(dsp56k_core* cpustate, UINT16 KKK, typed_pointer* dst_ret1, typed_pointer* dst_ret2, void* working);
193static void     decode_QQF_table(dsp56k_core* cpustate, UINT16 QQ, UINT16 F, void **S1, void **S2, void **D);
194static void     decode_QQF_special_table(dsp56k_core* cpustate, UINT16 QQ, UINT16 F, void **S1, void **S2, void **D);
195static void     decode_QQQF_table(dsp56k_core* cpustate, UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D);
196static void     decode_RR_table(dsp56k_core* cpustate, UINT16 RR, typed_pointer* ret);
197static void     decode_TT_table(dsp56k_core* cpustate, UINT16 TT, typed_pointer* ret);
198static void     decode_uuuuF_table(dsp56k_core* cpustate, UINT16 uuuu, UINT16 F, UINT8 add_sub_other, typed_pointer* src_ret, typed_pointer* dst_ret);
199static void     decode_Z_table(dsp56k_core* cpustate, UINT16 Z, typed_pointer* ret);
200
201static void     execute_m_table(dsp56k_core* cpustate, int x, UINT16 m);
202static void     execute_mm_table(dsp56k_core* cpustate, UINT16 rnum, UINT16 mm);
203static void     execute_MM_table(dsp56k_core* cpustate, UINT16 rnum, UINT16 MM);
204static UINT16   execute_q_table(dsp56k_core* cpustate, int RR, UINT16 q);
205static void     execute_z_table(dsp56k_core* cpustate, int RR, UINT16 z);
206
207static UINT16   assemble_address_from_Pppppp_table(dsp56k_core* cpustate, UINT16 P, UINT16 ppppp);
208static UINT16   assemble_address_from_IO_short_address(dsp56k_core* cpustate, UINT16 pp);
209static UINT16   assemble_address_from_6bit_signed_relative_short_address(dsp56k_core* cpustate, UINT16 srs);
210
211static void dsp56k_process_loop(dsp56k_core* cpustate);
212static void dsp56k_process_rep(dsp56k_core* cpustate, size_t repSize);
213
214
215
216/********************/
217/* Helper Functions */
218/********************/
219static UINT16 Dsp56kOpMask(UINT16 op, UINT16 mask);
220
221/* These arguments are written source->destination to fall in line with the processor's paradigm. */
222static void SetDestinationValue(typed_pointer source, typed_pointer dest);
223
224static void SetDataMemoryValue(dsp56k_core* cpustate, typed_pointer source, UINT32 destinationAddr);
225static void SetProgramMemoryValue(dsp56k_core* cpustate, typed_pointer source, UINT32 destinationAddr);
226
227
228
229/***************************************************************************
230    IMPLEMENTATION
231***************************************************************************/
232
233static void execute_one(dsp56k_core* cpustate)
234{
235   UINT16 op;
236   UINT16 op2;
237   size_t size = 0x1337;
238   UINT8 cycle_count = 0;
239
240   /* For MAME */
241   cpustate->op = ROPCODE(ADDRESS(PC));
242   debugger_instruction_hook(cpustate->device, PC);
243
244   /* The words we're going to be working with */
245   op = ROPCODE(ADDRESS(PC));
246   op2 = ROPCODE(ADDRESS(PC) + ADDRESS(1));
247
248
249   /* DECODE */
250   /* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/
251   if ((op & 0xe000) == 0x6000)
252   {
253      typed_pointer d_register = {NULL, DT_BYTE};
254
255      /* Quote: (MOVE, MAC(R), MPY(R), ADD, SUB, TFR) */
256      UINT16 op_byte = op & 0x00ff;
257
258      /* ADD : 011m mKKK 0rru Fuuu : A-22 */
259      /* SUB : 011m mKKK 0rru Fuuu : A-202 */
260      /* Note: 0x0094 check allows command to drop through to MOVE and TFR */
261      if (((op & 0xe080) == 0x6000) && ((op & 0x0094) != 0x0010))
262      {
263         size = dsp56k_op_addsub_2(cpustate, op_byte, &d_register, &cycle_count);
264      }
265      /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */
266      else if ((op & 0xe094) == 0x6084)
267      {
268         size = dsp56k_op_mac_1(cpustate, op_byte, &d_register, &cycle_count);
269      }
270      /* MACR: 011m mKKK 1--1 F1QQ : A-124 */
271      else if ((op & 0xe094) == 0x6094)
272      {
273         size = dsp56k_op_macr_1(cpustate, op_byte, &d_register, &cycle_count);
274      }
275      /* TFR : 011m mKKK 0rr1 F0DD : A-212 */
276      else if ((op & 0xe094) == 0x6010)
277      {
278         size = dsp56k_op_tfr_2(cpustate, op_byte, &d_register, &cycle_count);
279      }
280      /* MOVE : 011m mKKK 0rr1 0000 : A-128 */
281      else if ((op & 0xe09f) == 0x6010)
282      {
283         /* Note: The opcode encoding : 011x xxxx 0xx1 0000 (move + double memory read)
284                  is .identical. to (tfr X0,A + two parallel reads).  This sparks the notion
285                  that these 'move' opcodes don't actually exist and are just there as
286                  documentation.  Real-world examples would need to be examined to come
287                  to a satisfactory conclusion, but as it stands, tfr will override this
288                  move operation. */
289         size = dsp56k_op_move_1(cpustate, op_byte, &d_register, &cycle_count);
290      }
291      /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */
292      else if ((op & 0xe094) == 0x6080)
293      {
294         size = dsp56k_op_mpy_1(cpustate, op_byte, &d_register, &cycle_count);
295      }
296      /* MPYR : 011m mKKK 1--1 F0QQ : A-162 */
297      else if ((op & 0xe094) == 0x6090)
298      {
299         size = dsp56k_op_mpyr_1(cpustate, op_byte, &d_register, &cycle_count);
300      }
301
302      /* Now evaluate the parallel data move */
303      execute_dual_x_memory_data_read(cpustate, op, &d_register);
304   }
305   /* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */
306   else if ((op & 0xfe00) == 0x1600)
307   {
308      /* Quote: (MPY or MAC) */
309      UINT16 op_byte = op & 0x00ff;
310
311      /* MPY : 0001 0110 RRDD FQQQ : A-160 */
312      if ((op & 0xff00) == 0x1600)
313      {
314         size = dsp56k_op_mpy_2(cpustate, op_byte, &cycle_count);
315      }
316      /* MAC : 0001 0111 RRDD FQQQ : A-122 */
317      else if ((op & 0xff00) == 0x1700)
318      {
319         size = dsp56k_op_mac_2(cpustate, op_byte, &cycle_count);
320      }
321
322      /* Now evaluate the parallel data move */
323      /* TODO // decode_x_memory_data_write_and_register_data_move(op, parallel_move_str, parallel_move_str2); */
324      logerror("DSP56k: Unemulated Dual X Memory Data And Register Data Move @ 0x%x\n", PC);
325   }
326
327   /* Handle Other parallel types */
328   else
329   {
330      /***************************************/
331      /* 32 General parallel move operations */
332      /***************************************/
333
334      enum pType { kNoParallelDataMove,
335                  kRegisterToRegister,
336                  kAddressRegister,
337                  kXMemoryDataMove,
338                  kXMemoryDataMove2,
339                  kXMemoryDataMoveWithDisp };
340
341      int parallelType = -1;
342      UINT16 op_byte = 0x0000;
343      typed_pointer d_register = {NULL, DT_BYTE};
344      UINT64 prev_accum_value = U64(0x0000000000000000);
345
346      /* Note: it's important that NPDM comes before RtRDM here */
347      /* No Parallel Data Move : 0100 1010 .... .... : A-131 */
348      if ((op & 0xff00) == 0x4a00)
349      {
350         op_byte = op & 0x00ff;
351         parallelType = kNoParallelDataMove;
352      }
353      /* Register to Register Data Move : 0100 IIII .... .... : A-133 */
354      else if ((op & 0xf000) == 0x4000)
355      {
356         op_byte = op & 0x00ff;
357         parallelType = kRegisterToRegister;
358      }
359      /* Address Register Update : 0011 0zRR .... .... : A-135 */
360      else if ((op & 0xf800) == 0x3000)
361      {
362         op_byte = op & 0x00ff;
363         parallelType = kAddressRegister;
364      }
365      /* X Memory Data Move : 1mRR HHHW .... .... : A-137 */
366      else if ((op & 0x8000) == 0x8000)
367      {
368         op_byte = op & 0x00ff;
369         parallelType = kXMemoryDataMove;
370      }
371      /* X Memory Data Move : 0101 HHHW .... .... : A-137 */
372      else if ((op & 0xf000) == 0x5000)
373      {
374         op_byte = op & 0x00ff;
375         parallelType = kXMemoryDataMove2;
376      }
377      /* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */
378      else if ((op & 0xff00) == 0x0500)
379      {
380         /* Now check it against all the other potential collisions */
381         /* This is necessary because "don't care bits" get in the way. */
382         /*
383         MOVE(M) :   0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152
384         MOVE(C) :   0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144
385         MOVE :      0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128
386         */
387         if (((op2 & 0xfe20) != 0x0200) &&
388            ((op2 & 0xf810) != 0x3800) &&
389            ((op2 & 0x00ff) != 0x0011))
390         {
391            op_byte = op2 & 0x00ff;
392            parallelType = kXMemoryDataMoveWithDisp;
393         }
394      }
395
396
397      if (parallelType != -1)
398      {
399         /* Note: There is much overlap between opcodes down here */
400         /*       To this end, certain ops must come before others in the list */
401
402         /* CLR : .... .... 0000 F001 : A-60 */
403         if ((op_byte & 0x00f7) == 0x0001)
404         {
405            size = dsp56k_op_clr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
406         }
407         /* ADD : .... .... 0000 FJJJ : A-22 */
408         else if ((op_byte & 0x00f0) == 0x0000)
409         {
410            size = dsp56k_op_add(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
411         }
412
413
414         /* MOVE : .... .... 0001 0001 : A-128 */
415         else if ((op_byte & 0x00ff) == 0x0011)
416         {
417            size = dsp56k_op_move(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
418         }
419         /* TFR : .... .... 0001 FJJJ : A-212 */
420         else if ((op_byte & 0x00f0) == 0x0010)
421         {
422            size = dsp56k_op_tfr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
423         }
424
425
426         /* RND : .... .... 0010 F000 : A-188 */
427         else if ((op_byte & 0x00f7) == 0x0020)
428         {
429            size = dsp56k_op_rnd(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
430         }
431         /* TST : .... .... 0010 F001 : A-218 */
432         else if ((op_byte & 0x00f7) == 0x0021)
433         {
434            size = dsp56k_op_tst(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
435         }
436         /* INC : .... .... 0010 F010 : A-104 */
437         else if ((op_byte & 0x00f7) == 0x0022)
438         {
439            size = dsp56k_op_inc(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
440         }
441         /* INC24 : .... .... 0010 F011 : A-106 */
442         else if ((op_byte & 0x00f7) == 0x0023)
443         {
444            size = dsp56k_op_inc24(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
445         }
446         /* OR : .... .... 0010 F1JJ : A-176 */
447         else if ((op_byte & 0x00f4) == 0x0024)
448         {
449            size = dsp56k_op_or(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
450         }
451
452
453         /* ASR : .... .... 0011 F000 : A-32 */
454         else if ((op_byte & 0x00f7) == 0x0030)
455         {
456            size = dsp56k_op_asr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
457         }
458         /* ASL : .... .... 0011 F001 : A-28 */
459         else if ((op_byte & 0x00f7) == 0x0031)
460         {
461            size = dsp56k_op_asl(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
462         }
463         /* LSR : .... .... 0011 F010 : A-120 */
464         else if ((op_byte & 0x00f7) == 0x0032)
465         {
466            size = dsp56k_op_lsr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
467         }
468         /* LSL : .... .... 0011 F011 : A-118 */
469         else if ((op_byte & 0x00f7) == 0x0033)
470         {
471            size = dsp56k_op_lsl(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
472         }
473         /* EOR : .... .... 0011 F1JJ : A-94 */
474         else if ((op_byte & 0x00f4) == 0x0034)
475         {
476            size = dsp56k_op_eor(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
477         }
478
479
480         /* SUBL : .... .... 0100 F001 : A-204 */
481         else if ((op_byte & 0x00f7) == 0x0041)
482         {
483            size = dsp56k_op_subl(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
484         }
485         /* SUB : .... .... 0100 FJJJ : A-202 */
486         else if ((op_byte & 0x00f0) == 0x0040)
487         {
488            size = dsp56k_op_sub(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
489         }
490
491
492         /* CLR24 : .... .... 0101 F001 : A-62 */
493         else if ((op_byte & 0x00f7) == 0x0051)
494         {
495            size = dsp56k_op_clr24(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
496         }
497         /* SBC : .... .... 0101 F01J : A-198 */
498         else if ((op_byte & 0x00f6) == 0x0052)
499         {
500            size = dsp56k_op_sbc(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
501         }
502         /* CMP : .... .... 0101 FJJJ : A-64 */
503         else if ((op_byte & 0x00f0) == 0x0050)
504         {
505            size = dsp56k_op_cmp(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
506         }
507
508
509         /* NEG : .... .... 0110 F000 : A-166 */
510         else if ((op_byte & 0x00f7) == 0x0060)
511         {
512            size = dsp56k_op_neg(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
513         }
514         /* NOT : .... .... 0110 F001 : A-174 */
515         else if ((op_byte & 0x00f7) == 0x0061)
516         {
517            size = dsp56k_op_not(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
518         }
519         /* DEC : .... .... 0110 F010 : A-72 */
520         else if ((op_byte & 0x00f7) == 0x0062)
521         {
522            size = dsp56k_op_dec(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
523         }
524         /* DEC24 : .... .... 0110 F011 : A-74 */
525         else if ((op_byte & 0x00f7) == 0x0063)
526         {
527            size = dsp56k_op_dec24(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
528         }
529         /* AND : .... .... 0110 F1JJ : A-24 */
530         else if ((op_byte & 0x00f4) == 0x0064)
531         {
532            size = dsp56k_op_and(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
533         }
534
535
536         /* ABS : .... .... 0111 F001 : A-18 */
537         if ((op_byte & 0x00f7) == 0x0071)
538         {
539            size = dsp56k_op_abs(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
540         }
541         /* ROR : .... .... 0111 F010 : A-192 */
542         else if ((op_byte & 0x00f7) == 0x0072)
543         {
544            size = dsp56k_op_ror(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
545         }
546         /* ROL : .... .... 0111 F011 : A-190 */
547         else if ((op_byte & 0x00f7) == 0x0073)
548         {
549            size = dsp56k_op_rol(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
550         }
551         /* CMPM : .... .... 0111 FJJJ : A-66 */
552         else if ((op_byte & 0x00f0) == 0x0070)
553         {
554            size = dsp56k_op_cmpm(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
555         }
556
557
558         /* MPY : .... .... 1k00 FQQQ : A-160    -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */
559         else if ((op_byte & 0x00b0) == 0x0080)
560         {
561            size = dsp56k_op_mpy(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
562         }
563         /* MPYR : .... .... 1k01 FQQQ : A-162 */
564         else if ((op_byte & 0x00b0) == 0x0090)
565         {
566            size = dsp56k_op_mpyr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
567         }
568         /* MAC : .... .... 1k10 FQQQ : A-122 */
569         else if ((op_byte & 0x00b0) == 0x00a0)
570         {
571            size = dsp56k_op_mac(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
572         }
573         /* MACR : .... .... 1k11 FQQQ : A-124   -- DRAMA - rr vs xx (805) */
574         else if ((op_byte & 0x00b0) == 0x00b0)
575         {
576            size = dsp56k_op_macr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
577         }
578
579
580         /* Now evaluate the parallel data move */
581         switch (parallelType)
582         {
583         case kNoParallelDataMove:
584            /* DO NOTHING */
585            break;
586         case kRegisterToRegister:
587            execute_register_to_register_data_move(cpustate, op, &d_register, &prev_accum_value);
588            break;
589         case kAddressRegister:
590            execute_address_register_update(cpustate, op, &d_register, &prev_accum_value);
591            break;
592         case kXMemoryDataMove:
593            execute_x_memory_data_move(cpustate, op, &d_register, &prev_accum_value);
594            break;
595         case kXMemoryDataMove2:
596            execute_x_memory_data_move2(cpustate, op, &d_register);
597            break;
598         case kXMemoryDataMoveWithDisp:
599            execute_x_memory_data_move_with_short_displacement(cpustate, op, op2);
600            size = 2;
601            break;
602         }
603      }
604   }
605
606   /* Drop out if you've already completed your work. */
607   if (size != 0x1337)
608   {
609      PC += size;
610
611      dsp56k_process_loop(cpustate);
612      dsp56k_process_rep(cpustate, size);
613
614      cpustate->icount -= 4;  /* Temporarily hard-coded at 4 clocks per opcode */ /* cycle_count */
615      return;
616   }
617
618
619   /******************************/
620   /* Remaining non-parallel ops */
621   /******************************/
622
623   /* ADC : 0001 0101 0000 F01J : A-20 */
624   if ((op & 0xfff6) == 0x1502)
625   {
626      size = dsp56k_op_adc(cpustate, op, &cycle_count);
627   }
628   /* ANDI : 0001 1EE0 iiii iiii : A-26 */
629   /* (MoveP sneaks in here if you don't check 0x0600) */
630   else if (((op & 0xf900) == 0x1800) & ((op & 0x0600) != 0x0000))
631   {
632      size = dsp56k_op_andi(cpustate, op, &cycle_count);
633   }
634   /* ASL4 : 0001 0101 0011 F001 : A-30 */
635   else if ((op & 0xfff7) == 0x1531)
636   {
637      size = dsp56k_op_asl4(cpustate, op, &cycle_count);
638   }
639   /* ASR4 : 0001 0101 0011 F000 : A-34 */
640   else if ((op & 0xfff7) == 0x1530)
641   {
642      size = dsp56k_op_asr4(cpustate, op, &cycle_count);
643   }
644   /* ASR16 : 0001 0101 0111 F000 : A-36 */
645   else if ((op & 0xfff7) == 0x1570)
646   {
647      size = dsp56k_op_asr16(cpustate, op, &cycle_count);
648   }
649   /* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */
650   else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x1200))
651   {
652      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
653   }
654   /* BFCHG : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */
655   else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x1200))
656   {
657      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
658   }
659   /* BFCHG : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */
660   else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x1200))
661   {
662      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
663   }
664   /* BFCLR : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */
665   else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x0400))
666   {
667      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
668   }
669   /* BFCLR : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */
670   else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x0400))
671   {
672      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
673   }
674   /* BFCLR : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */
675   else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x0400))
676   {
677      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
678   }
679   /* BFSET : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */
680   else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x1800))
681   {
682      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
683   }
684   /* BFSET : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */
685   else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x1800))
686   {
687      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
688   }
689   /* BFSET : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */
690   else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x1800))
691   {
692      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
693   }
694   /* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */
695   else if (((op & 0xffc0) == 0x1440) && ((op2 & 0x1f00) == 0x1000))
696   {
697      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
698   }
699   /* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */
700   else if (((op & 0xffe0) == 0x1420) && ((op2 & 0x1f00) == 0x1000))
701   {
702      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
703   }
704   /* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */
705   else if (((op & 0xffe0) == 0x1400) && ((op2 & 0x1f00) == 0x1000))
706   {
707      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
708   }
709   /* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */
710   else if (((op & 0xffc0) == 0x1440) && ((op2 & 0x1f00) == 0x0000))
711   {
712      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
713   }
714   /* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */
715   else if (((op & 0xffe0) == 0x1420) && ((op2 & 0x1f00) == 0x0000))
716   {
717      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
718   }
719   /* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */
720   else if (((op & 0xffe0) == 0x1400) && ((op2 & 0x1f00) == 0x0000))
721   {
722      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
723   }
724   /* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */
725   else if (((op & 0xff30) == 0x0730) && ((op2 & 0x0000) == 0x0000))
726   {
727      size = dsp56k_op_bcc(cpustate, op, op2, &cycle_count);
728   }
729   /* Bcc : 0010 11cc ccee eeee : A-48 */
730   else if ((op & 0xfc00) == 0x2c00)
731   {
732      size = dsp56k_op_bcc_1(cpustate, op, &cycle_count);
733   }
734   /* Bcc : 0000 0111 RR10 cccc : A-48 */
735   else if ((op & 0xff30) == 0x0720)
736   {
737      size = dsp56k_op_bcc_2(cpustate, op, &cycle_count);
738   }
739   /* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */
740   else if (((op & 0xfffc) == 0x013c) && ((op2 & 0x0000) == 0x0000))
741   {
742      size = dsp56k_op_bra(cpustate, op, op2, &cycle_count);
743   }
744   /* BRA : 0000 1011 aaaa aaaa : A-50 */
745   else if ((op & 0xff00) == 0x0b00)
746   {
747      size = dsp56k_op_bra_1(cpustate, op, &cycle_count);
748   }
749   /* BRA : 0000 0001 0010 11RR : A-50 */
750   else if ((op & 0xfffc) == 0x012c)
751   {
752      size = dsp56k_op_bra_2(cpustate, op, &cycle_count);
753   }
754   /* BRKc : 0000 0001 0001 cccc : A-52 */
755   else if ((op & 0xfff0) == 0x0110)
756   {
757      size = dsp56k_op_brkcc(cpustate, op, &cycle_count);
758   }
759   /* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */
760   else if (((op & 0xff30) == 0x0710) && ((op2 & 0x0000) == 0x0000))
761   {
762      size = dsp56k_op_bscc(cpustate, op, op2, &cycle_count);
763   }
764   /* BScc : 0000 0111 RR00 cccc : A-54 */
765   else if ((op & 0xff30) == 0x0700)
766   {
767      size = dsp56k_op_bscc_1(cpustate, op, &cycle_count);
768   }
769   /* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */
770   else if (((op & 0xfffc) == 0x0138) && ((op2 & 0x0000) == 0x0000))
771   {
772      size = dsp56k_op_bsr(cpustate, op, op2, &cycle_count);
773   }
774   /* BSR : 0000 0001 0010 10RR : A-56 */
775   else if ((op & 0xfffc) == 0x0128)
776   {
777      size = dsp56k_op_bsr_1(cpustate, op, &cycle_count);
778   }
779   /* CHKAAU : 0000 0000 0000 0100 : A-58 */
780   else if ((op & 0xffff) == 0x0004)
781   {
782      size = dsp56k_op_chkaau(cpustate, op, &cycle_count);
783   }
784   /* DEBUG : 0000 0000 0000 0001 : A-68 */
785   else if ((op & 0xffff) == 0x0001)
786   {
787      size = dsp56k_op_debug(cpustate, op, &cycle_count);
788   }
789   /* DEBUGcc : 0000 0000 0101 cccc : A-70 */
790   else if ((op & 0xfff0) == 0x0050)
791   {
792      size = dsp56k_op_debugcc(cpustate, op, &cycle_count);
793   }
794   /* DIV : 0001 0101 0--0 F1DD : A-76 */
795   else if ((op & 0xff94) == 0x1504)
796   {
797      size = dsp56k_op_div(cpustate, op, &cycle_count);
798   }
799   /* DMAC : 0001 0101 10s1 FsQQ : A-80 */
800   else if ((op & 0xffd0) == 0x1590)
801   {
802      size = dsp56k_op_dmac(cpustate, op, &cycle_count);
803   }
804   /* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */
805   else if (((op & 0xffe0) == 0x00c0) && ((op2 & 0x0000) == 0x0000))
806   {
807      size = dsp56k_op_do(cpustate, op, op2, &cycle_count);
808   }
809   /* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */
810   else if (((op & 0xff00) == 0x0e00) && ((op2 & 0x0000) == 0x0000))
811   {
812      size = dsp56k_op_do_1(cpustate, op, op2, &cycle_count);
813   }
814   /* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */
815   else if (((op & 0xffe0) == 0x0400) && ((op2 & 0x0000) == 0x0000))
816   {
817      size = dsp56k_op_do_2(cpustate, op, op2, &cycle_count);
818   }
819   /* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */
820   else if (((op & 0xffff) == 0x0002) && ((op2 & 0x0000) == 0x0000))
821   {
822      size = dsp56k_op_doforever(cpustate, op, op2, &cycle_count);
823   }
824   /* ENDDO : 0000 0000 0000 1001 : A-92 */
825   else if ((op & 0xffff) == 0x0009)
826   {
827      size = dsp56k_op_enddo(cpustate, op, &cycle_count);
828   }
829   /* EXT : 0001 0101 0101 F010 : A-96 */
830   else if ((op & 0xfff7) == 0x1552)
831   {
832      size = dsp56k_op_ext(cpustate, op, &cycle_count);
833   }
834   /* ILLEGAL : 0000 0000 0000 1111 : A-98 */
835   else if ((op & 0xffff) == 0x000f)
836   {
837      size = dsp56k_op_illegal(cpustate, op, &cycle_count);
838   }
839   /* IMAC : 0001 0101 1010 FQQQ : A-100 */
840   else if ((op & 0xfff0) == 0x15a0)
841   {
842      size = dsp56k_op_imac(cpustate, op, &cycle_count);
843   }
844   /* IMPY : 0001 0101 1000 FQQQ : A-102 */
845   else if ((op & 0xfff0) == 0x1580)
846   {
847      size = dsp56k_op_impy(cpustate, op, &cycle_count);
848   }
849   /* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */
850   else if (((op & 0xff30) == 0x0630) && ((op2 & 0x0000) == 0x0000))
851   {
852      size = dsp56k_op_jcc(cpustate, op, op2, &cycle_count);
853   }
854   /* Jcc : 0000 0110 RR10 cccc : A-108 */
855   else if ((op & 0xff30) == 0x0620 )
856   {
857      size = dsp56k_op_jcc_1(cpustate, op, &cycle_count);
858   }
859   /* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */
860   else if (((op & 0xfffc) == 0x0134) && ((op2 & 0x0000) == 0x0000))
861   {
862      size = dsp56k_op_jmp(cpustate, op, op2, &cycle_count);
863   }
864   /* JMP : 0000 0001 0010 01RR : A-110 */
865   else if ((op & 0xfffc) == 0x0124)
866   {
867      size = dsp56k_op_jmp_1(cpustate, op, &cycle_count);
868   }
869   /* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */
870   else if (((op & 0xff30) == 0x0610) && ((op2 & 0x0000) == 0x0000))
871   {
872      size = dsp56k_op_jscc(cpustate, op, op2, &cycle_count);
873   }
874   /* JScc : 0000 0110 RR00 cccc : A-112 */
875   else if ((op & 0xff30) == 0x0600)
876   {
877      size = dsp56k_op_jscc_1(cpustate, op, &cycle_count);
878   }
879   /* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */
880   else if (((op & 0xfffc) == 0x0130) && ((op2 & 0x0000) == 0x0000))
881   {
882      size = dsp56k_op_jsr(cpustate, op, op2, &cycle_count);
883   }
884   /* JSR : 0000 1010 AAAA AAAA : A-114 */
885   else if ((op & 0xff00) == 0x0a00)
886   {
887      size = dsp56k_op_jsr_1(cpustate, op, &cycle_count);
888   }
889   /* JSR : 0000 0001 0010 00RR : A-114 */
890   else if ((op & 0xfffc) == 0x0120)
891   {
892      size = dsp56k_op_jsr_2(cpustate, op, &cycle_count);
893   }
894   /* LEA : 0000 0001 11TT MMRR : A-116 */
895   else if ((op & 0xffc0) == 0x01c0)
896   {
897      size = dsp56k_op_lea(cpustate, op, &cycle_count);
898   }
899   /* LEA : 0000 0001 10NN MMRR : A-116 */
900   else if ((op & 0xffc0) == 0x0180)
901   {
902      size = dsp56k_op_lea_1(cpustate, op, &cycle_count);
903   }
904   /* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */
905   else if ((op & 0xfff0) == 0x15e0)
906   {
907      size = dsp56k_op_macsuuu(cpustate, op, &cycle_count);
908   }
909   /* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */
910   else if (((op & 0xff00) == 0x0500) && ((op2 & 0x00ff) == 0x0011))
911   {
912      size = dsp56k_op_move_2(cpustate, op, op2, &cycle_count);
913   }
914   /* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */
915   else if ((op & 0xf810) == 0x3800)
916   {
917      size = dsp56k_op_movec(cpustate, op, &cycle_count);
918   }
919   /* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */
920   else if ((op & 0xf814) == 0x3810)
921   {
922      size = dsp56k_op_movec_1(cpustate, op, &cycle_count);
923   }
924   /* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */
925   else if ((op & 0xf816) == 0x3816)
926   {
927      size = dsp56k_op_movec_2(cpustate, op, &cycle_count);
928   }
929   /* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */
930   else if (((op & 0xf816) == 0x3814) && ((op2 & 0x0000) == 0x0000))
931   {
932      size = dsp56k_op_movec_3(cpustate, op, op2, &cycle_count);
933   }
934   /* MOVE(C) : 0010 10dd dddD DDDD : A-144 */
935   else if ((op & 0xfc00) == 0x2800)
936   {
937      size = dsp56k_op_movec_4(cpustate, op, &cycle_count);
938   }
939   /* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */
940   else if (((op & 0xff00) == 0x0500) && ((op2 & 0xf810) == 0x3800))
941   {
942      size = dsp56k_op_movec_5(cpustate, op, op2, &cycle_count);
943   }
944   /* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */
945   else if ((op & 0xfc00) == 0x2000)
946   {
947      size = dsp56k_op_movei(cpustate, op, &cycle_count);
948   }
949   /* MOVE(M) : 0000 001W RR0M MHHH : A-152 */
950   else if ((op & 0xfe20) == 0x0200)
951   {
952      size = dsp56k_op_movem(cpustate, op, &cycle_count);
953   }
954   /* MOVE(M) : 0000 001W RR11 mmRR : A-152 */
955   else if ((op & 0xfe30) == 0x0230)
956   {
957      size = dsp56k_op_movem_1(cpustate, op, &cycle_count);
958   }
959   /* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */
960   else if (((op & 0xff00) == 0x0500) && ((op2 & 0xfe20) == 0x0200))
961   {
962      size = dsp56k_op_movem_2(cpustate, op, op2, &cycle_count);
963   }
964   /* MOVE(P) : 0001 100W HH1p pppp : A-156 */
965   else if ((op & 0xfe20) == 0x1820)
966   {
967      size = dsp56k_op_movep(cpustate, op, &cycle_count);
968   }
969   /* MOVE(P) : 0000 110W RRmp pppp : A-156 */
970   else if ((op & 0xfe00) == 0x0c00)
971   {
972      size = dsp56k_op_movep_1(cpustate, op, &cycle_count);
973   }
974   /* MOVE(S) : 0001 100W HH0a aaaa : A-158 */
975   else if ((op & 0xfe20) == 0x1800)
976   {
977      size = dsp56k_op_moves(cpustate, op, &cycle_count);
978   }
979   /* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */
980   else if ((op & 0xfff0) == 0x15c0)
981   {
982      size = dsp56k_op_mpysuuu(cpustate, op, &cycle_count);
983   }
984   /* NEGC : 0001 0101 0110 F000 : A-168 */
985   else if ((op & 0xfff7) == 0x1560)
986   {
987      size = dsp56k_op_negc(cpustate, op, &cycle_count);
988   }
989   /* NOP : 0000 0000 0000 0000 : A-170 */
990   else if ((op & 0xffff) == 0x0000)
991   {
992      size = dsp56k_op_nop(cpustate, op, &cycle_count);
993   }
994   /* NORM : 0001 0101 0010 F0RR : A-172 */
995   else if ((op & 0xfff4) == 0x1520)
996   {
997      size = dsp56k_op_norm(cpustate, op, &cycle_count);
998   }
999   /* ORI : 0001 1EE1 iiii iiii : A-178 */
1000   else if ((op & 0xf900) == 0x1900)
1001   {
1002      size = dsp56k_op_ori(cpustate, op, &cycle_count);
1003   }
1004   /* REP : 0000 0000 111- --RR : A-180 */
1005   else if ((op & 0xffe0) == 0x00e0)
1006   {
1007      size = dsp56k_op_rep(cpustate, op, &cycle_count);
1008   }
1009   /* REP : 0000 1111 iiii iiii : A-180 */
1010   else if ((op & 0xff00) == 0x0f00)
1011   {
1012      size = dsp56k_op_rep_1(cpustate, op, &cycle_count);
1013   }
1014   /* REP : 0000 0100 001D DDDD : A-180 */
1015   else if ((op & 0xffe0) == 0x0420)
1016   {
1017      size = dsp56k_op_rep_2(cpustate, op, &cycle_count);
1018   }
1019   /* REPcc : 0000 0001 0101 cccc : A-184 */
1020   else if ((op & 0xfff0) == 0x0150)
1021   {
1022      size = dsp56k_op_repcc(cpustate, op, &cycle_count);
1023   }
1024   /* RESET : 0000 0000 0000 1000 : A-186 */
1025   else if ((op & 0xffff) == 0x0008)
1026   {
1027      size = dsp56k_op_reset(cpustate, op, &cycle_count);
1028   }
1029   /* RTI : 0000 0000 0000 0111 : A-194 */
1030   else if ((op & 0xffff) == 0x0007)
1031   {
1032      size = dsp56k_op_rti(cpustate, op, &cycle_count);
1033   }
1034   /* RTS : 0000 0000 0000 0110 : A-196 */
1035   else if ((op & 0xffff) == 0x0006)
1036   {
1037      size = dsp56k_op_rts(cpustate, op, &cycle_count);
1038   }
1039   /* STOP : 0000 0000 0000 1010 : A-200 */
1040   else if ((op & 0xffff) == 0x000a)
1041   {
1042      size = dsp56k_op_stop(cpustate, op, &cycle_count);
1043   }
1044   /* SWAP : 0001 0101 0111 F001 : A-206 */
1045   else if ((op & 0xfff7) == 0x1571)
1046   {
1047      size = dsp56k_op_swap(cpustate, op, &cycle_count);
1048   }
1049   /* SWI : 0000 0000 0000 0101 : A-208 */
1050   else if ((op & 0xffff) == 0x0005)
1051   {
1052      size = dsp56k_op_swi(cpustate, op, &cycle_count);
1053   }
1054   /* Tcc : 0001 00cc ccTT Fh0h : A-210 */
1055   else if ((op & 0xfc02) == 0x1000)
1056   {
1057      size = dsp56k_op_tcc(cpustate, op, &cycle_count);
1058   }
1059   /* TFR(2) : 0001 0101 0000 F00J : A-214 */
1060   else if ((op & 0xfff6) == 0x1500)
1061   {
1062      size = dsp56k_op_tfr2(cpustate, op, &cycle_count);
1063   }
1064   /* TFR(3) : 0010 01mW RRDD FHHH : A-216 */
1065   else if ((op & 0xfc00) == 0x2400)
1066   {
1067      size = dsp56k_op_tfr3(cpustate, op, &cycle_count);
1068   }
1069   /* TST(2) : 0001 0101 0001 -1DD : A-220 */
1070   else if ((op & 0xfff4) == 0x1514)
1071   {
1072      size = dsp56k_op_tst2(cpustate, op, &cycle_count);
1073   }
1074   /* WAIT : 0000 0000 0000 1011 : A-222 */
1075   else if ((op & 0xffff) == 0x000b)
1076   {
1077      size = dsp56k_op_wait(cpustate, op, &cycle_count);
1078   }
1079   /* ZERO : 0001 0101 0101 F000 : A-224 */
1080   else if ((op & 0xfff7) == 0x1550)
1081   {
1082      size = dsp56k_op_zero(cpustate, op, &cycle_count);
1083   }
1084
1085
1086   /* Not recognized?  Nudge debugger onto the next word */
1087   if (size == 0x1337)
1088   {
1089      logerror("DSP56k: Unimplemented opcode at 0x%04x : %04x\n", PC, op);
1090      size = 1 ;                      /* Just to get the debugger past the bad opcode */
1091   }
1092
1093   /* Must have been a good opcode */
1094   PC += size;
1095
1096   dsp56k_process_loop(cpustate);
1097   dsp56k_process_rep(cpustate, size);
1098
1099   cpustate->icount -= 4;  /* Temporarily hard-coded at 4 clocks per opcode */ /* cycle_count */
1100}
1101
1102
1103
1104
1105/***************************************************************************
1106    Opcode implementations
1107***************************************************************************/
1108
1109/*******************************/
1110/* 32 Parallel move operations */
1111/*******************************/
1112
1113/* ADD : 011m mKKK 0rru Fuuu : A-22 */
1114/* SUB : 011m mKKK 0rru Fuuu : A-202 */
1115static size_t dsp56k_op_addsub_2(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1116{
1117   UINT64 useVal = 0;
1118   UINT8 op_type = OP_OTHER;
1119   typed_pointer S = {NULL, DT_BYTE};
1120   typed_pointer D = {NULL, DT_BYTE};
1121
1122   decode_uuuuF_table(cpustate, BITS(op_byte,0x0017), BITS(op_byte,0x0008), op_type, &S, &D);
1123
1124   /* If you gave an invalid operation type, presume it's a nop and move on with the parallel move */
1125   if (op_type == OP_OTHER)
1126   {
1127      d_register->addr = NULL;
1128      d_register->data_type = DT_BYTE;
1129      cycles += 2;
1130      return 1;
1131   }
1132
1133   /* It's a real operation.  Get on with it. */
1134   switch(S.data_type)
1135   {
1136      case DT_WORD:        useVal = (UINT64)*((UINT16*)S.addr) << 16; break;
1137      case DT_DOUBLE_WORD: useVal = (UINT64)*((UINT32*)S.addr);       break;
1138      case DT_LONG_WORD:   useVal = (UINT64)*((UINT64*)S.addr);       break;
1139   }
1140
1141   /* Sign-extend word for proper add/sub op */
1142   if ((S.data_type == DT_WORD) && useVal & U64(0x0000000080000000))
1143      useVal |= U64(0x000000ff00000000);
1144
1145   /* Operate*/
1146   if (op_type == OP_ADD)
1147      *((UINT64*)D.addr) += useVal;
1148   else if (op_type == OP_SUB)
1149      *((UINT64*)D.addr) -= useVal;
1150
1151   d_register->addr = D.addr;
1152   d_register->data_type = D.data_type;
1153
1154   /* S L E U N Z V C */
1155   /* * * * * * * * * */
1156   /* TODO S, L, E, U, V, C */
1157   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1158   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1159
1160   cycles += 2;        /* TODO: + mv oscillator cycles */
1161   return 1;
1162}
1163
1164/* MAC : 011m mKKK 1xx0 F1QQ : A-122 */
1165static size_t dsp56k_op_mac_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1166{
1167   INT64 opD = 0;
1168   INT64 result = 0;
1169
1170   INT32 s1 = 0;
1171   INT32 s2 = 0;
1172
1173   void* D = NULL;
1174   void* S1 = NULL;
1175   void* S2 = NULL;
1176
1177   decode_QQF_table(cpustate, BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S1, &S2, &D);
1178
1179   /* Cast both values as being signed */
1180   s1 = *((INT16*)S1);
1181   s2 = *((INT16*)S2);
1182
1183   /* Fixed-point 2's complement multiplication requires a shift */
1184   result = (s1 * s2) << 1;
1185
1186   /* Sign extend D into a temp variable */
1187   opD = (*((UINT64*)D));
1188   if (opD & U64(0x0000008000000000))
1189      opD |= U64(0xffffff0000000000);
1190   else
1191      opD &= U64(0x000000ffffffffff);
1192
1193   /* Accumulate */
1194   opD += result;
1195
1196   /* And out the bits that don't live in the register */
1197   opD &= U64(0x000000ffffffffff);
1198
1199   (*((UINT64*)D)) = (UINT64)opD;
1200
1201   /* For the parallel move */
1202   d_register->addr = D;
1203   d_register->data_type = DT_LONG_WORD;
1204
1205   /* S L E U N Z V C */
1206   /* * * * * * * * - */
1207   /* TODO: S, L, E, V */
1208   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1209   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1210
1211   cycles += 2;        /* TODO: +mv oscillator cycles */
1212   return 1;
1213}
1214
1215/* MACR: 011m mKKK 1--1 F1QQ : A-124 */
1216static size_t dsp56k_op_macr_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1217{
1218   /* S L E U N Z V C */
1219   /* * * * * * * * - */
1220   return 0;
1221}
1222
1223/* MOVE : 011m mKKK 0rr1 0000 : A-128 */
1224static size_t dsp56k_op_move_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1225{
1226   /* S L E U N Z V C */
1227   /* * * - - - - - - */
1228   return 0;
1229}
1230
1231/* MPY : 011m mKKK 1xx0 F0QQ : A-160 */
1232static size_t dsp56k_op_mpy_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1233{
1234   INT64 result = 0;
1235
1236   INT32 s1 = 0;
1237   INT32 s2 = 0;
1238
1239   void* D = NULL;
1240   void* S1 = NULL;
1241   void* S2 = NULL;
1242
1243   decode_QQF_table(cpustate, BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S1, &S2, &D);
1244
1245   /* Cast both values as being signed */
1246   s1 = *((INT16*)S1);
1247   s2 = *((INT16*)S2);
1248
1249   /* Fixed-point 2's complement multiplication requires a shift */
1250   result = (s1 * s2) << 1;
1251
1252   /* And out the bits that don't live in the register */
1253   (*((UINT64*)D)) = result & U64(0x000000ffffffffff);
1254
1255   /* For the parallel move */
1256   d_register->addr = D;
1257   d_register->data_type = DT_LONG_WORD;
1258
1259   /* S L E U N Z V C */
1260   /* * * * * * * * - */
1261   /* TODO: S, L, E, V */
1262   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1263   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1264
1265   cycles += 2;        /* TODO: +mv oscillator cycles */
1266   return 1;
1267}
1268
1269/* MPYR : 011m mKKK 1--1 F0QQ : A-162 */
1270static size_t dsp56k_op_mpyr_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1271{
1272   /* S L E U N Z V C */
1273   /* * * * * * * * - */
1274   return 0;
1275}
1276
1277/* TFR : 011m mKKK 0rr1 F0DD : A-212 */
1278static size_t dsp56k_op_tfr_2(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1279{
1280   /* S L E U N Z V C */
1281   /* - - - - - - - - */
1282   return 0;
1283}
1284
1285/* MPY : 0001 0110 RRDD FQQQ : A-160 */
1286static size_t dsp56k_op_mpy_2(dsp56k_core* cpustate, const UINT16 op_byte, UINT8* cycles)
1287{
1288   /* S L E U N Z V C */
1289   /* * * * * * * * - */
1290   return 0;
1291}
1292
1293/* MAC : 0001 0111 RRDD FQQQ : A-122 */
1294static size_t dsp56k_op_mac_2(dsp56k_core* cpustate, const UINT16 op_byte, UINT8* cycles)
1295{
1296   /* S L E U N Z V C */
1297   /* * * * * * * * - */
1298   return 0;
1299}
1300
1301/* CLR : .... .... 0000 F001 : A-60 */
1302static size_t dsp56k_op_clr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1303{
1304   typed_pointer D = {NULL, DT_LONG_WORD};
1305   typed_pointer clear = {NULL, DT_LONG_WORD};
1306   UINT64 clear_val = U64(0x0000000000000000);
1307
1308   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1309
1310   *p_accum = *((UINT64*)D.addr);
1311
1312   clear.addr = &clear_val;
1313   clear.data_type = DT_LONG_WORD;
1314   SetDestinationValue(clear, D);
1315
1316   d_register->addr = D.addr;
1317   d_register->data_type = D.data_type;
1318
1319   /* S L E U N Z V C */
1320   /* * * * * * * 0 - */
1321   /* TODO - S, L */
1322   DSP56K_E_CLEAR();
1323   DSP56K_U_SET();
1324   DSP56K_N_CLEAR();
1325   DSP56K_Z_SET();
1326   DSP56K_V_CLEAR();
1327
1328   cycles += 2;    /* TODO: + mv oscillator clock cycles */
1329   return 1;
1330}
1331
1332/* ADD : .... .... 0000 FJJJ : A-22 */
1333static size_t dsp56k_op_add(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1334{
1335   UINT64 addVal = 0;
1336
1337   typed_pointer S = {NULL, DT_BYTE};
1338   typed_pointer D = {NULL, DT_BYTE};
1339   decode_JJJF_table(cpustate, BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
1340
1341   *p_accum = *((UINT64*)D.addr);
1342
1343   switch(S.data_type)
1344   {
1345      case DT_WORD:        addVal = (UINT64)*((UINT16*)S.addr) << 16; break;
1346      case DT_DOUBLE_WORD: addVal = (UINT64)*((UINT32*)S.addr);       break;
1347      case DT_LONG_WORD:   addVal = (UINT64)*((UINT64*)S.addr);       break;
1348   }
1349
1350   /* Sign-extend word for proper add/sub op */
1351   if ((S.data_type == DT_WORD) && addVal & U64(0x0000000080000000))
1352      addVal |= U64(0x000000ff00000000);
1353
1354   /* Operate*/
1355   *((UINT64*)D.addr) += addVal;
1356
1357   d_register->addr = D.addr;
1358   d_register->data_type = D.data_type;
1359
1360   /* S L E U N Z V C */
1361   /* * * * * * * * * */
1362   /* TODO S, L, E, U, V, C */
1363   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1364   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1365
1366   cycles += 2;        /* TODO: + mv oscillator cycles */
1367   return 1;
1368}
1369
1370/* MOVE : .... .... 0001 0001 : A-128 */
1371static size_t dsp56k_op_move(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1372{
1373   /* Equivalent to a nop with a parallel move */
1374   /* These can't be used later.  Hopefully compilers would pick this up. */
1375   *p_accum = 0;
1376   d_register->addr = NULL;
1377   d_register->data_type = DT_BYTE;
1378
1379   /* S L E U N Z V C */
1380   /* * * - - - - - - */
1381   /* TODO: S, L */
1382   cycles += 2;    /* TODO: + mv oscillator cycles */
1383   return 1;
1384}
1385
1386/* TFR : .... .... 0001 FJJJ : A-212 */
1387static size_t dsp56k_op_tfr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1388{
1389   typed_pointer S = {NULL, DT_BYTE};
1390   typed_pointer D = {NULL, DT_BYTE};
1391
1392   decode_JJJF_table(cpustate, BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
1393
1394   *p_accum = *((UINT64*)D.addr);
1395
1396   SetDestinationValue(S, D);
1397
1398   d_register->addr = D.addr;
1399   d_register->data_type = D.data_type;
1400
1401   /* S L E U N Z V C */
1402   /* * * - - - - - - */
1403   /* TODO: S, L */
1404   cycles += 2;        /* TODO: + mv oscillator cycles */
1405   return 1;
1406}
1407
1408/* RND : .... .... 0010 F000 : A-188 */
1409static size_t dsp56k_op_rnd(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1410{
1411   typed_pointer D = {NULL, DT_BYTE};
1412
1413   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1414
1415   *p_accum = *((UINT64*)D.addr);
1416
1417   /* WARNING : ROUNDING NOT FULLY IMPLEMENTED YET! */
1418   if ((*((UINT64*)D.addr) & U64(0x000000000000ffff)) >= 0x8000)
1419      *((UINT64*)D.addr) += U64(0x0000000000010000);
1420
1421   *((UINT64*)D.addr) = *((UINT64*)D.addr) & U64(0x000000ffffff0000);
1422
1423   d_register->addr = D.addr;
1424   d_register->data_type = D.data_type;
1425
1426   /* S L E U N Z V C */
1427   /* * * * * * * * - */
1428   /* TODO: S, L, E, U, V */
1429   if ((*((UINT64*)D.addr)) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1430   if ((*((UINT64*)D.addr)) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1431
1432   cycles += 2;        /* TODO: + mv oscillator clock cycles */
1433   return 1;
1434}
1435
1436/* TST : .... .... 0010 F001 : A-218 */
1437static size_t dsp56k_op_tst(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1438{
1439   typed_pointer D = {NULL, DT_LONG_WORD};
1440
1441   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1442
1443   *p_accum = *((UINT64*)D.addr);
1444
1445   d_register->addr = D.addr;
1446   d_register->data_type = D.data_type;
1447
1448   /* S L E U N Z V C */
1449   /* 0 * * * * * 0 0 */
1450   /* TODO: S, L, E, U */
1451   if ((*((UINT64*)D.addr)) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1452   if ((*((UINT64*)D.addr)) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1453   DSP56K_V_CLEAR();
1454   DSP56K_C_CLEAR();
1455
1456   cycles += 2;    /* TODO: + mv oscillator clock cycles */
1457   return 1;
1458}
1459
1460/* INC : .... .... 0010 F010 : A-104 */
1461static size_t dsp56k_op_inc(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1462{
1463   typed_pointer D = {NULL, DT_BYTE};
1464   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1465
1466   /* Save some data for the parallel move */
1467   *p_accum = *((UINT64*)D.addr);
1468
1469   /* Make sure the destination is a real 40-bit value */
1470   *((UINT64*)D.addr) &= U64(0x000000ffffffffff);
1471
1472   /* Increment */
1473   *((UINT64*)D.addr) = *((UINT64*)D.addr) + 1;
1474
1475   d_register->addr = D.addr;
1476   d_register->data_type = D.data_type;
1477
1478   /* S L E U N Z V C */
1479   /* * * * * * * * * */
1480   /* TODO: S, L, E, U */
1481   if ( *((UINT64*)D.addr) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1482   if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1483   if ((*((UINT64*)D.addr) & U64(0xffffff0000000000)) != 0) DSP56K_V_SET(); else DSP56K_V_CLEAR();
1484   if ((*((UINT64*)D.addr) & U64(0xffffff0000000000)) != 0) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1485
1486   cycles += 2;    /* TODO: +mv oscillator cycles */
1487   return 1;
1488}
1489
1490/* INC24 : .... .... 0010 F011 : A-106 */
1491static size_t dsp56k_op_inc24(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1492{
1493   UINT32 workBits24;
1494
1495   typed_pointer D = {NULL, DT_BYTE};
1496   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1497
1498   /* Save some data for the parallel move */
1499   *p_accum = *((UINT64*)D.addr);
1500
1501   /* TODO: I wonder if workBits24 should be signed? */
1502   workBits24 = ((*((UINT64*)D.addr)) & U64(0x000000ffffff0000)) >> 16;
1503   workBits24++;
1504   //workBits24 &= 0x00ffffff;     /* Solves -x issues - TODO: huh? */
1505
1506   /* Set the D bits with the dec result */
1507   *((UINT64*)D.addr) &= U64(0x000000000000ffff);
1508   *((UINT64*)D.addr) |= (((UINT64)(workBits24)) << 16);
1509
1510   d_register->addr = D.addr;
1511   d_register->data_type = D.data_type;
1512
1513   /* S L E U N Z V C */
1514   /* * * * * * ? * * */
1515   /* TODO: S, L, E, U */
1516   if ( *((UINT64*)D.addr) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1517   if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1518   if ((workBits24 & 0xff000000) != 0) DSP56K_V_SET(); else DSP56K_V_CLEAR();
1519   if ((workBits24 & 0xff000000) != 0) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1520
1521   cycles += 2;        /* TODO: + mv oscillator clock cycles */
1522   return 1;
1523}
1524
1525/* OR : .... .... 0010 F1JJ : A-176 */
1526static size_t dsp56k_op_or(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1527{
1528   typed_pointer S = {NULL, DT_BYTE};
1529   typed_pointer D = {NULL, DT_BYTE};
1530
1531   decode_JJF_table(cpustate, BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S, &D);
1532
1533   /* Save some data for the parallel move */
1534   *p_accum = *((UINT64*)D.addr);
1535
1536   /* OR a word of S with A1|B1 */
1537   ((PAIR64*)D.addr)->w.h = *((UINT16*)S.addr) | ((PAIR64*)D.addr)->w.h;
1538
1539   d_register->addr = D.addr;
1540   d_register->data_type = D.data_type;
1541
1542   /* S L E U N Z V C */
1543   /* * * - - ? ? 0 - */
1544   /* TODO: S, L */
1545   if ( *((UINT64*)D.addr) & U64(0x0000000080000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1546   if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1547   DSP56K_V_CLEAR();
1548
1549   cycles += 2;        /* TODO: + mv oscillator cycles */
1550   return 1;
1551}
1552
1553/* ASR : .... .... 0011 F000 : A-32 */
1554static size_t dsp56k_op_asr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1555{
1556   typed_pointer D = {NULL, DT_BYTE};
1557   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1558
1559   *p_accum = *((UINT64*)D.addr);
1560
1561   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) >> 1;
1562
1563   /* Make sure the MSB is maintained */
1564   if (*p_accum & U64(0x0000008000000000))
1565      *((UINT64*)D.addr) |= U64(0x0000008000000000);
1566   else
1567      *((UINT64*)D.addr) &= (~U64(0x0000008000000000));
1568
1569   /* For the parallel move */
1570   d_register->addr = D.addr;
1571   d_register->data_type = D.data_type;
1572
1573   /* S L E U N Z V C */
1574   /* * * * * * * 0 ? */
1575   /* TODO: S, L, E, U */
1576   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1577   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1578   DSP56K_V_CLEAR();
1579   if (*p_accum & U64(0x0000000000000001))           DSP56K_C_SET(); else DSP56K_C_CLEAR();
1580
1581   cycles += 2;        /* TODO: + mv oscillator cycles */
1582   return 1;
1583}
1584
1585/* ASL : .... .... 0011 F001 : A-28 */
1586static size_t dsp56k_op_asl(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1587{
1588   /* S L E U N Z V C */
1589   /* * * * * * * ? ? */
1590   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significant
1591          bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
1592   /* C - Set if bit 39 of source operand is set. Cleared otherwise. */
1593   return 0;
1594}
1595
1596/* LSR : .... .... 0011 F010 : A-120 */
1597static size_t dsp56k_op_lsr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1598{
1599   typed_pointer D = {NULL, DT_BYTE};
1600   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1601
1602   *p_accum = *((UINT64*)D.addr);
1603
1604   ((PAIR64*)D.addr)->w.h = (((PAIR64*)D.addr)->w.h) >> 1;
1605
1606   /* Make sure bit 31 gets a 0 */
1607   ((PAIR64*)D.addr)->w.h &= (~0x8000);
1608
1609   /* For the parallel move */
1610   d_register->addr = D.addr;
1611   d_register->data_type = D.data_type;
1612
1613   /* S L E U N Z V C */
1614   /* * * - - ? ? 0 ? */
1615   /* TODO: S, L */
1616   DSP56K_N_CLEAR();
1617   if (((PAIR64*)D.addr)->w.h == 0)        DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1618   DSP56K_V_CLEAR();
1619   if (*p_accum & U64(0x0000000000010000)) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1620
1621   cycles += 2;        /* TODO: + mv oscillator cycles */
1622   return 1;
1623}
1624
1625/* LSL : .... .... 0011 F011 : A-118 */
1626static size_t dsp56k_op_lsl(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1627{
1628   /* S L E U N Z V C */
1629   /* * * - - ? ? 0 ? */
1630   /* N - Set if bit 31 of the result is set. Cleared otherwise. */
1631   /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
1632   /* C - Set if bit 31 of the source operand is set. Cleared otherwise. */
1633   return 0;
1634}
1635
1636/* EOR : .... .... 0011 F1JJ : A-94 */
1637static size_t dsp56k_op_eor(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1638{
1639   /* S L E U N Z V C */
1640   /* * * - - ? ? 0 - */
1641   /* N - Set if bit 31 of the result is set. Cleared otherwise. */
1642   /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
1643   return 0;
1644}
1645
1646/* SUBL : .... .... 0100 F001 : A-204 */
1647static size_t dsp56k_op_subl(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1648{
1649   /* S L E U N Z V C */
1650   /* * * * * * * ? * */
1651   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significant
1652          bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
1653   return 0;
1654}
1655
1656/* SUB : .... .... 0100 FJJJ : A-202 */
1657static size_t dsp56k_op_sub(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1658{
1659   UINT64 useVal = 0;
1660   typed_pointer S = {NULL, DT_BYTE};
1661   typed_pointer D = {NULL, DT_BYTE};
1662
1663   decode_JJJF_table(cpustate, BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S, &D);
1664
1665   /* Get on with it. */
1666   switch(S.data_type)
1667   {
1668      case DT_WORD:        useVal = (UINT64)*((UINT16*)S.addr) << 16; break;
1669      case DT_DOUBLE_WORD: useVal = (UINT64)*((UINT32*)S.addr);       break;
1670      case DT_LONG_WORD:   useVal = (UINT64)*((UINT64*)S.addr);       break;
1671   }
1672
1673   /* Sign-extend word for proper sub op */
1674   if ((S.data_type == DT_WORD) && useVal & U64(0x0000000080000000))
1675      useVal |= U64(0x000000ff00000000);
1676
1677   /* Make sure they're both real 40-bit values */
1678   useVal &= U64(0x000000ffffffffff);
1679   *((UINT64*)D.addr) &= U64(0x000000ffffffffff);
1680
1681   /* Operate*/
1682   *((UINT64*)D.addr) -= useVal;
1683
1684   d_register->addr = D.addr;
1685   d_register->data_type = D.data_type;
1686
1687   /* S L E U N Z V C */
1688   /* * * * * * * * * */
1689   /* TODO S, L, E, U */
1690   if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1691   if ( *((UINT64*)D.addr) == 0)                     DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1692   if ((*((UINT64*)D.addr) & U64(0xffffff0000000000)) != 0) DSP56K_V_SET(); else DSP56K_V_CLEAR();
1693   if ((*((UINT64*)D.addr) & U64(0xffffff0000000000)) != 0) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1694
1695   cycles += 2;        /* TODO: + mv oscillator cycles */
1696   return 1;
1697}
1698
1699/* CLR24 : .... .... 0101 F001 : A-62 */
1700static size_t dsp56k_op_clr24(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1701{
1702   /* S L E U N Z V C */
1703   /* * * * * * ? 0 - */
1704   /* Z - Set if the 24 most significant bits of the destination result are all zeroes. */
1705   return 0;
1706}
1707
1708/* SBC : .... .... 0101 F01J : A-198 */
1709static size_t dsp56k_op_sbc(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1710{
1711   /* S L E U N Z V C */
1712   /* * * * * * * * * */
1713   return 0;
1714}
1715
1716/* CMP : .... .... 0101 FJJJ : A-64 */
1717static size_t dsp56k_op_cmp(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1718{
1719   UINT64 cmpVal = 0;
1720   UINT64 result = 0;
1721
1722   typed_pointer S = {NULL, DT_BYTE};
1723   typed_pointer D = {NULL, DT_BYTE};
1724
1725   decode_JJJF_table(cpustate, BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
1726
1727   *p_accum = *((UINT64*)D.addr);
1728
1729   switch(S.data_type)
1730   {
1731      case DT_WORD:        cmpVal = (UINT64)*((UINT16*)S.addr) << 16;  break;
1732      case DT_DOUBLE_WORD: cmpVal = (UINT64)*((UINT32*)S.addr);  break;
1733      case DT_LONG_WORD:   cmpVal = (UINT64)*((UINT64*)S.addr);  break;
1734   }
1735
1736   /* Sign-extend word for proper subtraction op */
1737   if ((S.data_type == DT_WORD) && cmpVal & U64(0x0000000080000000))
1738      cmpVal |= U64(0x000000ff00000000);
1739
1740   /* Make sure they're both real 40-bit values */
1741   cmpVal &= U64(0x000000ffffffffff);
1742   *((UINT64*)D.addr) &= U64(0x000000ffffffffff);
1743
1744   /* Operate */
1745   result = *((UINT64*)D.addr) - cmpVal;
1746
1747   d_register->addr = D.addr;
1748   d_register->data_type = D.data_type;
1749
1750   /* S L E U N Z V C */
1751   /* * * * * * * * * */
1752   /* TODO: S, L, E, U */
1753   if ( result & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1754   if ( result == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1755   if ((result & U64(0xffffff0000000000)) != 0) DSP56K_V_SET(); else DSP56K_V_CLEAR();
1756   if ((result & U64(0xffffff0000000000)) != 0) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1757
1758
1759   cycles += 2;        /* TODO: + mv oscillator clock cycles */
1760   return 1;
1761}
1762
1763/* NEG : .... .... 0110 F000 : A-166 */
1764static size_t dsp56k_op_neg(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1765{
1766   /* S L E U N Z V C */
1767   /* * * * * * * * * */
1768   return 0;
1769}
1770
1771/* NOT : .... .... 0110 F001 : A-174 */
1772static size_t dsp56k_op_not(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1773{
1774   typed_pointer D = {NULL, DT_BYTE};
1775   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1776
1777   *p_accum = *((UINT64*)D.addr);
1778
1779   /* Invert bits [16:31] of D */
1780   ((PAIR64*)D.addr)->w.h = ~(((PAIR64*)D.addr)->w.h);
1781
1782   d_register->addr = D.addr;
1783   d_register->data_type = D.data_type;
1784
1785   /* S L E U N Z V C */
1786   /* * * - - ? ? 0 - */
1787   /* TODO: S?, L */
1788   if ( *((UINT64*)D.addr) & U64(0x0000000080000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1789   if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1790   DSP56K_V_CLEAR();
1791
1792   cycles += 2;        /* TODO: + mv oscillator cycles */
1793   return 1;
1794}
1795
1796/* DEC : .... .... 0110 F010 : A-72 */
1797static size_t dsp56k_op_dec(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1798{
1799   /* S L E U N Z V C */
1800   /* * * * * * * * * */
1801   return 0;
1802}
1803
1804/* DEC24 : .... .... 0110 F011 : A-74 */
1805static size_t dsp56k_op_dec24(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1806{
1807   UINT32 workBits24;
1808
1809   typed_pointer D = {NULL, DT_BYTE};
1810   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1811
1812   /* Save some data for the parallel move */
1813   *p_accum = *((UINT64*)D.addr);
1814
1815   /* TODO: I wonder if workBits24 should be signed? */
1816   workBits24 = ((*((UINT64*)D.addr)) & U64(0x000000ffffff0000)) >> 16;
1817   workBits24--;
1818   workBits24 &= 0x00ffffff;       /* Solves -x issues */
1819
1820   /* Set the D bits with the dec result */
1821   *((UINT64*)D.addr) &= U64(0x000000000000ffff);
1822   *((UINT64*)D.addr) |= (((UINT64)(workBits24)) << 16);
1823
1824   d_register->addr = D.addr;
1825   d_register->data_type = D.data_type;
1826
1827   /* S L E U N Z V C */
1828   /* * * * * * ? * * */
1829   /* TODO: S, L, E, U, V, C */
1830   if ( *((UINT64*)D.addr) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1831   if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1832
1833   cycles += 2;        /* TODO: + mv oscillator clock cycles */
1834   return 1;
1835}
1836
1837/* AND : .... .... 0110 F1JJ : A-24 */
1838static size_t dsp56k_op_and(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1839{
1840   typed_pointer S = {NULL, DT_BYTE};
1841   typed_pointer D = {NULL, DT_BYTE};
1842
1843   decode_JJF_table(cpustate, BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S, &D);
1844
1845   /* Save some data for the parallel move */
1846   *p_accum = *((UINT64*)D.addr);
1847
1848   /* AND a word of S with A1|B1 */
1849   ((PAIR64*)D.addr)->w.h = *((UINT16*)S.addr) & ((PAIR64*)D.addr)->w.h;
1850
1851   d_register->addr = D.addr;
1852   d_register->data_type = D.data_type;
1853
1854   /* S L E U N Z V C */
1855   /* * * - - ? ? 0 - */
1856   /* TODO: S, L */
1857   if ( *((UINT64*)D.addr) & U64(0x0000000080000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1858   if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1859   DSP56K_V_CLEAR();
1860
1861   cycles += 2;        /* TODO: + mv oscillator cycles */
1862   return 1;
1863}
1864
1865/* ABS : .... .... 0111 F001 : A-18 */
1866static size_t dsp56k_op_abs(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1867{
1868   INT64 opD = 0;
1869   typed_pointer D = {NULL, DT_LONG_WORD};
1870
1871   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1872
1873   *p_accum = *((UINT64*)D.addr);
1874
1875   /* Sign extend D into a temp variable */
1876   opD = *p_accum;
1877   if (opD &  U64(0x0000008000000000))
1878      opD |= U64(0xffffff0000000000);
1879   else
1880      opD &= U64(0x000000ffffffffff);
1881
1882   /* Take the absolute value and clean up */
1883   opD = (opD < 0) ? -opD : opD;
1884   opD &= U64(0x000000ffffffffff);
1885
1886   /* Reassign */
1887   *((UINT64*)D.addr) = opD;
1888
1889   /* Special overflow case */
1890   if ((*p_accum) == U64(0x0000008000000000))
1891      *((UINT64*)D.addr) = U64(0x0000007fffffffff);
1892
1893   /* S L E U N Z V C */
1894   /* * * * * * * * - */
1895   /* TODO: S, L, E, U */
1896   if ( *((UINT64*)D.addr) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1897   if ((*((UINT64*)D.addr) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1898   if ((*p_accum)         == U64(0x0000008000000000))       DSP56K_V_SET(); else DSP56K_V_CLEAR();
1899
1900   cycles += 2;            /* TODO: + mv oscillator clock cycles */
1901   return 1;
1902}
1903
1904/* ROR : .... .... 0111 F010 : A-192 */
1905static size_t dsp56k_op_ror(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1906{
1907   /* S L E U N Z V C */
1908   /* * * - - ? ? 0 ? */
1909   /* N - Set if bit 31 of the result is set. Cleared otherwise. */
1910   /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
1911   /* C - Set if bit 16 of the source operand is set. Cleared otherwise. */
1912   return 0;
1913}
1914
1915/* ROL : .... .... 0111 F011 : A-190 */
1916static size_t dsp56k_op_rol(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1917{
1918   /* S L E U N Z V C */
1919   /* * * - - ? ? 0 ? */
1920   /* N - Set if bit 31 of the result is set. Cleared otherwise. */
1921   /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
1922   /* C - Set if bit 31 of the source operand is set. Cleared otherwise. */
1923   return 0;
1924}
1925
1926/* CMPM : .... .... 0111 FJJJ : A-66 */
1927static size_t dsp56k_op_cmpm(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1928{
1929   INT64 absS;
1930   INT64 absD;
1931   INT64 absResult;
1932
1933   typed_pointer S = {NULL, DT_BYTE};
1934   typed_pointer D = {NULL, DT_BYTE};
1935
1936   decode_JJJF_table(cpustate, BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
1937
1938   *p_accum = *((UINT64*)D.addr);
1939
1940   /* Sign extend and get absolute value of the source */
1941   if (S.addr == &A || S.addr == &B)
1942   {
1943      absS = *((UINT64*)S.addr);
1944      if (absS &  U64(0x0000008000000000))
1945         absS |= U64(0xffffff8000000000);
1946   }
1947   else
1948   {
1949      absS = (*((UINT16*)S.addr)) << 16;
1950      if (absS &  U64(0x0000000080000000))
1951         absS |= U64(0xffffffff80000000);
1952   }
1953   absS = (absS < 0) ? -absS : absS;
1954
1955   /* Sign extend and get absolute value of the destination */
1956   if (D.addr == &A || D.addr == &B)
1957   {
1958      absD = *((UINT64*)D.addr);
1959      if (absD &  U64(0x0000008000000000))
1960         absD |= U64(0xffffff8000000000);
1961   }
1962   else
1963   {
1964      absD = (*((UINT16*)D.addr)) << 16;
1965      if (absS &  U64(0x0000000080000000))
1966         absS |= U64(0xffffffff80000000);
1967   }
1968   absD = (absD < 0) ? -absD : absD;
1969
1970   /* Compare */
1971   absResult = absD - absS;
1972
1973   d_register->addr = D.addr;
1974   d_register->data_type = D.data_type;
1975
1976   /* S L E U N Z V C */
1977   /* * * * * * * * * */
1978   /* TODO: S, L, E, U */
1979   if ( (absResult) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1980   if (((absResult) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1981   if ( (absResult  & U64(0xffffff0000000000)) != 0)  DSP56K_V_SET(); else DSP56K_V_CLEAR();
1982   if ( (absResult  & U64(0xffffff0000000000)) != 0)  DSP56K_C_SET(); else DSP56K_C_CLEAR();
1983
1984   cycles += 2;        /* TODO: +mv oscillator cycles */
1985   return 1;
1986}
1987
1988/* MPY : .... .... 1k00 FQQQ : A-160    -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */
1989static size_t dsp56k_op_mpy(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1990{
1991   UINT16 k = 0;
1992   INT64 result = 0;
1993
1994   INT32 s1 = 0;
1995   INT32 s2 = 0;
1996
1997   void* D = NULL;
1998   void* S1 = NULL;
1999   void* S2 = NULL;
2000
2001   decode_QQQF_table(cpustate, BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D);
2002
2003   k = BITS(op_byte,0x0040);
2004
2005   /* Cast both values as being signed */
2006   s1 = *((INT16*)S1);
2007   s2 = *((INT16*)S2);
2008
2009   /* Fixed-point 2's complement multiplication requires a shift */
2010   result = (s1 * s2) << 1;
2011
2012   /* Negate the product if necessary */
2013   if (k)
2014      result *= -1;
2015
2016   (*((UINT64*)D)) = result & U64(0x000000ffffffffff);
2017
2018   /* S L E U N Z V C */
2019   /* * * * * * * * - */
2020   /* TODO: S, L, E, V */
2021   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
2022   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2023
2024   cycles += 2;        /* TODO: +mv oscillator cycles */
2025   return 1;
2026}
2027
2028/* MPYR : .... .... 1k01 FQQQ : A-162 */
2029static size_t dsp56k_op_mpyr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
2030{
2031   /* S L E U N Z V C */
2032   /* * * * * * * * - */
2033   return 0;
2034}
2035
2036/* MAC : .... .... 1k10 FQQQ : A-122 */
2037static size_t dsp56k_op_mac(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
2038{
2039   UINT16 k = 0;
2040   INT64 opD = 0;
2041   INT64 result = 0;
2042
2043   INT32 s1 = 0;
2044   INT32 s2 = 0;
2045
2046   void* D = NULL;
2047   void* S1 = NULL;
2048   void* S2 = NULL;
2049
2050   decode_QQQF_table(cpustate, BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D);
2051
2052   k = BITS(op_byte,0x0040);
2053
2054   /* Cast both values as being signed */
2055   s1 = *((INT16*)S1);
2056   s2 = *((INT16*)S2);
2057
2058   /* Fixed-point 2's complement multiplication requires a shift */
2059   result = (s1 * s2) << 1;
2060
2061   /* Sign extend D into a temp variable */
2062   opD = (*((UINT64*)D));
2063   if (opD & U64(0x0000008000000000))
2064      opD |= U64(0xffffff0000000000);
2065   else
2066      opD &= U64(0x000000ffffffffff);
2067
2068   /* Negate if necessary */
2069   if (k)
2070      result *= -1;
2071
2072   /* Accumulate */
2073   opD += result;
2074
2075   /* And out the bits that don't live in the register */
2076   opD &= U64(0x000000ffffffffff);
2077
2078   (*((UINT64*)D)) = (UINT64)opD;
2079
2080   /* For the parallel move */
2081   d_register->addr = D;
2082   d_register->data_type = DT_LONG_WORD;
2083
2084   /* S L E U N Z V C */
2085   /* * * * * * * * - */
2086   /* TODO: S, L, E, V */
2087   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
2088   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2089
2090   cycles += 2;        /* TODO: +mv oscillator cycles */
2091   return 1;
2092}
2093
2094/* MACR : .... .... 1k11 FQQQ : A-124   -- DRAMA - rr vs xx (805) */
2095static size_t dsp56k_op_macr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
2096{
2097   UINT16 k = 0;
2098   INT64 opD = 0;
2099   INT64 result = 0;
2100
2101   INT32 s1 = 0;
2102   INT32 s2 = 0;
2103
2104   void* D = NULL;
2105   void* S1 = NULL;
2106   void* S2 = NULL;
2107
2108   decode_QQQF_table(cpustate, BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D);
2109
2110   k = BITS(op_byte,0x0040);
2111
2112   /* Cast both values as being signed */
2113   s1 = *((INT16*)S1);
2114   s2 = *((INT16*)S2);
2115
2116   /* Fixed-point 2's complement multiplication requires a shift */
2117   result = (s1 * s2) << 1;
2118
2119   /* Sign extend D into a temp variable */
2120   opD = (*((UINT64*)D));
2121   if (opD & U64(0x0000008000000000))
2122      opD |= U64(0xffffff0000000000);
2123   else
2124      opD &= U64(0x000000ffffffffff);
2125
2126   /* Negate if necessary */
2127   if (k)
2128      result *= -1;
2129
2130   /* Accumulate */
2131   opD += result;
2132
2133   /* Round the result */
2134   /* WARNING : ROUNDING NOT FULLY IMPLEMENTED YET! */
2135   if ((opD & U64(0x000000000000ffff)) >= 0x8000)
2136      opD += U64(0x0000000000010000);
2137
2138   opD &= U64(0x000000ffffff0000);
2139
2140   /* And out the bits that don't live in the register */
2141   opD &= U64(0x000000ffffffffff);
2142
2143   /* Store the result */
2144   (*((UINT64*)D)) = (UINT64)opD;
2145
2146   /* For the parallel move */
2147   d_register->addr = D;
2148   d_register->data_type = DT_LONG_WORD;
2149
2150   /* S L E U N Z V C */
2151   /* * * * * * * * - */
2152   /* TODO: S, L, E, V */
2153   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
2154   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2155
2156   cycles += 2;        /* TODO: +mv oscillator cycles */
2157   return 1;
2158}
2159
2160
2161/******************************/
2162/* Remaining non-parallel ops */
2163/******************************/
2164
2165/* ADC : 0001 0101 0000 F01J : A-20 */
2166static size_t dsp56k_op_adc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2167{
2168   /* S L E U N Z V C */
2169   /* - * * * * * * * */
2170   return 0;
2171}
2172
2173/* ANDI : 0001 1EE0 iiii iiii : A-26 */
2174static size_t dsp56k_op_andi(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2175{
2176   UINT16 immediate = BITS(op,0x00ff);
2177
2178   /* There is not currently a good way to refer to CCR or MR.  Explicitly decode here. */
2179   switch(BITS(op,0x0600))
2180   {
2181      case 0x01:  /* MR */
2182         SR &= ((immediate << 8) | 0x00ff);
2183         break;
2184
2185      case 0x02:  /* CCR */
2186         SR &= (immediate | 0xff00);
2187         break;
2188
2189      case 0x03:  /* OMR */
2190         OMR &= (UINT8)(immediate);
2191         break;
2192
2193      default:
2194         fatalerror("DSP56k - BAD EE value in andi operation\n") ;
2195   }
2196
2197   /* S L E U N Z V C */
2198   /* - ? ? ? ? ? ? ? */
2199   /* All ? bits - Cleared if the corresponding bit in the immediate data is cleared and if the operand
2200      is the CCR. Not affected otherwise. */
2201   cycles += 2;
2202   return 1;
2203}
2204
2205/* ASL4 : 0001 0101 0011 F001 : A-30 */
2206static size_t dsp56k_op_asl4(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2207{
2208   UINT64 p_accum = 0;
2209   typed_pointer D = {NULL, DT_BYTE};
2210   decode_F_table(cpustate, BITS(op,0x0008), &D);
2211
2212   p_accum = *((UINT64*)D.addr);
2213
2214   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) << 4;
2215   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) & U64(0x000000ffffffffff);
2216
2217   /* S L E U N Z V C */
2218   /* - ? * * * * ? ? */
2219   /* TODO: L, E, U  */
2220   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if bit 35 through 39 are
2221          not the same. */
2222   /* C - Set if bit 36 of source operand is set. Cleared otherwise. */
2223   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
2224   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2225   if ( (*((UINT64*)D.addr) & U64(0x000000ff00000000)) != (p_accum & U64(0x000000ff00000000)) ) DSP56K_V_SET(); else DSP56K_V_CLEAR();
2226   if (p_accum & U64(0x0000001000000000))            DSP56K_C_SET(); else DSP56K_C_CLEAR();
2227
2228   cycles += 2;
2229   return 1;
2230}
2231
2232/* ASR4 : 0001 0101 0011 F000 : A-34 */
2233static size_t dsp56k_op_asr4(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2234{
2235   UINT64 p_accum = 0;
2236   typed_pointer D = {NULL, DT_BYTE};
2237   decode_F_table(cpustate, BITS(op,0x0008), &D);
2238
2239   p_accum = *((UINT64*)D.addr);
2240
2241   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) >> 4;
2242   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) & U64(0x000000ffffffffff);
2243
2244   /* The top 4 bits become the old bit 39 */
2245   if (p_accum & U64(0x0000008000000000))
2246      *((UINT64*)D.addr) |= U64(0x000000f000000000);
2247   else
2248      *((UINT64*)D.addr) &= (~U64(0x000000f000000000));
2249
2250   /* S L E U N Z V C */
2251   /* - * * * * * 0 ? */
2252   /* TODO: E, U  */
2253   /* C - Set if bit 3 of source operand is set. Cleared otherwise. */
2254   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
2255   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2256   DSP56K_V_CLEAR();
2257   if (p_accum & U64(0x0000000000000008))            DSP56K_C_SET(); else DSP56K_C_CLEAR();
2258
2259   cycles += 2;
2260   return 1;
2261}
2262
2263/* ASR16 : 0001 0101 0111 F000 : A-36 */
2264static size_t dsp56k_op_asr16(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2265{
2266   UINT64 backupVal;
2267   typed_pointer D = {NULL, DT_BYTE};
2268
2269   decode_F_table(cpustate, BITS(op,0x0008), &D);
2270
2271   backupVal = *((UINT64*)D.addr);
2272
2273   *((UINT64*)D.addr) = *((UINT64*)D.addr) >> 16;
2274
2275   if(backupVal & U64(0x0000008000000000))
2276      *((UINT64*)D.addr) |= U64(0x000000ffff000000);
2277   else
2278      *((UINT64*)D.addr) &= U64(0x0000000000ffffff);
2279
2280   /* S L E U N Z V C */
2281   /* - * * * * * 0 ? */
2282   /* TODO: E, U */
2283   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
2284   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2285   DSP56K_V_CLEAR();
2286   if (backupVal & U64(0x0000000000008000))          DSP56K_C_SET(); else DSP56K_C_CLEAR();
2287
2288   cycles += 2;
2289   return 1;
2290}
2291
2292/* BFCHG  : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */
2293/* BFCLR  : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */
2294/* BFSET  : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */
2295/* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */
2296/* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */
2297static size_t dsp56k_op_bfop(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2298{
2299   UINT16 workAddr = 0x0000;
2300   UINT16 workingWord = 0x0000;
2301   UINT16 previousValue = 0x0000;
2302   typed_pointer tempTP = { NULL, DT_BYTE };
2303
2304   UINT16 iVal = op2 & 0x00ff;
2305   decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal);
2306
2307   workAddr = assemble_address_from_Pppppp_table(cpustate, BITS(op,0x0020), BITS(op,0x001f));
2308   previousValue = cpustate->data->read_word(ADDRESS(workAddr));
2309   workingWord = previousValue;
2310
2311   switch(BITS(op2, 0x1f00))
2312   {
2313      case 0x12:  /* BFCHG */
2314         workingWord ^= iVal;
2315         break;
2316      case 0x04:  /* BFCLR */
2317         workingWord = workingWord & (~iVal);
2318         break;
2319      case 0x18:  /* BFSET */
2320         workingWord = workingWord | iVal;
2321         break;
2322      case 0x10:  /* BFTSTH */
2323         /* Just the test below */
2324         break;
2325      case 0x00:  /* BFTSTL */
2326         /* Just the test below */
2327         break;
2328   }
2329
2330   tempTP.addr = &workingWord;
2331   tempTP.data_type = DT_WORD;
2332   SetDataMemoryValue(cpustate, tempTP, ADDRESS(workAddr));
2333
2334   /* S L E U N Z V C */
2335   /* - * - - - - - ? */
2336   /* TODO: L */
2337   switch(BITS(op2, 0x1f00))
2338   {
2339      case 0x12:  /* BFCHG */
2340         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2341      case 0x04:  /* BFCLR */
2342         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2343      case 0x18:  /* BFSET */
2344         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2345      case 0x10:  /* BFTSTH */
2346         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2347      case 0x00:  /* BFTSTL */
2348         if ((iVal & previousValue) == 0x0000) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2349   }
2350
2351   cycles += 4;    /* TODO: + mvb oscillator clock cycles */
2352   return 2;
2353}
2354
2355/* BFCHG  : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */
2356/* BFCLR  : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */
2357/* BFSET  : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */
2358/* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */
2359/* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */
2360static size_t dsp56k_op_bfop_1(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2361{
2362   UINT16 workAddr = 0x0000;
2363   UINT16 workingWord = 0x0000;
2364   UINT16 previousValue = 0x0000;
2365   typed_pointer R = { NULL, DT_BYTE };
2366   typed_pointer tempTP = { NULL, DT_BYTE };
2367
2368   UINT16 iVal = op2 & 0x00ff;
2369   decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal);
2370
2371   decode_RR_table(cpustate, BITS(op,0x0003), &R);
2372
2373   workAddr = *((UINT16*)R.addr);
2374   previousValue = cpustate->data->read_word(ADDRESS(workAddr));
2375   workingWord = previousValue;
2376
2377   switch(BITS(op2, 0x1f00))
2378   {
2379      case 0x12:  /* BFCHG */
2380         workingWord ^= iVal;
2381         break;
2382      case 0x04:  /* BFCLR */
2383         workingWord = workingWord & (~iVal);
2384         break;
2385      case 0x18:  /* BFSET */
2386         workingWord = workingWord | iVal;
2387         break;
2388      case 0x10:  /* BFTSTH */
2389         /* Just the test below */
2390         break;
2391      case 0x00:  /* BFTSTL */
2392         /* Just the test below */
2393         break;
2394   }
2395
2396   tempTP.addr = &workingWord;
2397   tempTP.data_type = DT_WORD;
2398   SetDataMemoryValue(cpustate, tempTP, ADDRESS(workAddr));
2399
2400   /* S L E U N Z V C */
2401   /* - * - - - - - ? */
2402   /* TODO: L */
2403   switch(BITS(op2, 0x1f00))
2404   {
2405      case 0x12:  /* BFCHG */
2406         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2407      case 0x04:  /* BFCLR */
2408         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2409      case 0x18:  /* BFSET */
2410         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2411      case 0x10:  /* BFTSTH */
2412         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2413      case 0x00:  /* BFTSTL */
2414         if ((iVal & previousValue) == 0x0000) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2415   }
2416
2417   cycles += 4;    /* TODO: + mvb oscillator clock cycles */
2418   return 2;
2419}
2420
2421/* BFCHG  : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */
2422/* BFCLR  : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */
2423/* BFSET  : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */
2424/* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */
2425/* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */
2426static size_t dsp56k_op_bfop_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2427{
2428   UINT16 workingWord = 0x0000;
2429   UINT16 previousValue = 0x0000;
2430
2431   UINT16 iVal = op2 & 0x00ff;
2432   typed_pointer S = { NULL, DT_BYTE };
2433
2434   decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal);
2435   decode_DDDDD_table(cpustate, BITS(op,0x001f), &S);
2436
2437   /* A & B are special */
2438   if (S.data_type == DT_LONG_WORD)
2439      previousValue = ((PAIR64*)S.addr)->w.h;
2440   else
2441      previousValue = *((UINT16*)S.addr);
2442
2443   workingWord = previousValue;
2444
2445   switch(BITS(op2, 0x1f00))
2446   {
2447      case 0x12:  /* BFCHG */
2448         workingWord ^= iVal;
2449         break;
2450      case 0x04:  /* BFCLR */
2451         workingWord = workingWord & (~iVal);
2452         break;
2453      case 0x18:  /* BFSET */
2454         workingWord = workingWord | iVal;
2455         break;
2456      case 0x10:  /* BFTSTH */
2457         /* Just the test below */
2458         break;
2459      case 0x00:  /* BFTSTL */
2460         /* Just the test below */
2461         break;
2462   }
2463
2464   /* Put the data back where it belongs (A & B are special) */
2465   if (S.data_type == DT_LONG_WORD)
2466      ((PAIR64*)S.addr)->w.h = workingWord;
2467   else
2468      *((UINT16*)S.addr) = workingWord;
2469
2470   /* S L E U N Z V C */
2471   /* - * - - - - - ? */
2472   /* TODO: L */
2473   switch(BITS(op2, 0x1f00))
2474   {
2475      case 0x12:  /* BFCHG */
2476         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2477      case 0x04:  /* BFCLR */
2478         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2479      case 0x18:  /* BFSET */
2480         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2481      case 0x10:  /* BFTSTH */
2482         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2483      case 0x00:  /* BFTSTL */
2484         if ((iVal & previousValue) == 0x0000) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2485   }
2486
2487   cycles += 4;    /* TODO: + mvb oscillator clock cycles */
2488   return 2;
2489}
2490
2491/* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */
2492static size_t dsp56k_op_bcc(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2493{
2494   int shouldBranch = decode_cccc_table(cpustate, BITS(op,0x000f));
2495
2496   if (shouldBranch)
2497   {
2498      INT16 offset = (INT16)op2;
2499
2500      PC += 2;
2501
2502      cpustate->ppc = PC;
2503      PC += offset;
2504
2505      cycles += 4;
2506      return 0;
2507   }
2508   else
2509   {
2510      cycles += 4;
2511      return 2;
2512   }
2513
2514   /* S L E U N Z V C */
2515   /* - - - - - - - - */
2516   return 0;
2517}
2518
2519/* Bcc : 0010 11cc ccee eeee : A-48 */
2520static size_t dsp56k_op_bcc_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2521{
2522   int shouldBranch = decode_cccc_table(cpustate, BITS(op,0x03c0));
2523
2524   if (shouldBranch)
2525   {
2526      INT16 offset = (INT16)assemble_address_from_6bit_signed_relative_short_address(cpustate, BITS(op,0x003f));
2527
2528      PC += 1;
2529
2530      cpustate->ppc = PC;
2531      PC += offset;
2532
2533      cycles += 4;
2534      return 0;
2535   }
2536   else
2537   {
2538      cycles += 4;
2539      return 1;
2540   }
2541
2542   /* S L E U N Z V C */
2543   /* - - - - - - - - */
2544   return 0;
2545}
2546
2547/* Bcc : 0000 0111 RR10 cccc : A-48 */
2548static size_t dsp56k_op_bcc_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2549{
2550   /* S L E U N Z V C */
2551   /* - - - - - - - - */
2552   return 0;
2553}
2554
2555/* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */
2556static size_t dsp56k_op_bra(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2557{
2558   /* S L E U N Z V C */
2559   /* - - - - - - - - */
2560   return 0;
2561}
2562
2563/* BRA : 0000 1011 aaaa aaaa : A-50 */
2564static size_t dsp56k_op_bra_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2565{
2566   /* 8 bit immediate, relative offset */
2567   INT8 branchOffset = (INT8)BITS(op,0x00ff);
2568
2569   /* "The PC Contains the address of the next instruction" */
2570   PC += 1;
2571
2572   /* Jump */
2573   cpustate->ppc = PC;
2574   PC += branchOffset;
2575
2576   /* S L E U N Z V C */
2577   /* - - - - - - - - */
2578   cycles += 4; /* TODO: + jx oscillator clock cycles */
2579   return 0;
2580}
2581
2582/* BRA : 0000 0001 0010 11RR : A-50 */
2583static size_t dsp56k_op_bra_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2584{
2585   /* S L E U N Z V C */
2586   /* - - - - - - - - */
2587   return 0;
2588}
2589
2590/* BRKcc : 0000 0001 0001 cccc : A-52 */
2591static size_t dsp56k_op_brkcc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2592{
2593   int shouldBreak = decode_cccc_table(cpustate, BITS(op,0x000f));
2594
2595   if (shouldBreak)
2596   {
2597      /* TODO: I think this PC = LA thing is off-by-1, but it's working this way because its consistently so */
2598      cpustate->ppc = PC;
2599      PC = LA;
2600
2601      SR = SSL;   /* TODO: A-83.  I believe only the Loop Flag and Forever Flag come back here. */
2602      SP--;
2603
2604      LA = SSH;
2605      LC = SSL;
2606      SP--;
2607
2608      cycles += 8;
2609      return 0;
2610   }
2611   else
2612   {
2613      cycles += 2;
2614      return 1;
2615   }
2616
2617   /* S L E U N Z V C */
2618   /* - - - - - - - - */
2619   return 0;
2620}
2621
2622/* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */
2623static size_t dsp56k_op_bscc(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2624{
2625   int shouldBranch = decode_cccc_table(cpustate, BITS(op,0x000f));
2626
2627   if (shouldBranch)
2628   {
2629      /* The PC Contains the address of the next instruction */
2630      PC += 2;
2631
2632      /* Push */
2633      SP++;
2634      SSH = PC;
2635      SSL = SR;
2636
2637      /* Change */
2638      cpustate->ppc = PC;
2639      PC = PC + (INT16)op2;
2640
2641      /* S L E U N Z V C */
2642      /* - - - - - - - - */
2643      cycles += 4;        /* TODO: + jx oscillator clock cycles */
2644      return 0;
2645   }
2646
2647   /* S L E U N Z V C */
2648   /* - - - - - - - - */
2649   cycles += 4;        /* TODO: + jx oscillator clock cycles */
2650   return 2;
2651}
2652
2653/* BScc : 0000 0111 RR00 cccc : A-54 */
2654static size_t dsp56k_op_bscc_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2655{
2656   /* S L E U N Z V C */
2657   /* - - - - - - - - */
2658   return 0;
2659}
2660
2661/* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */
2662static size_t dsp56k_op_bsr(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2663{
2664   /* The PC Contains the address of the next instruction */
2665   PC += 2;
2666
2667   /* Push */
2668   SP++;
2669   SSH = PC;
2670   SSL = SR;
2671
2672   /* Change */
2673   cpustate->ppc = PC;
2674   PC = PC + (INT16)op2;
2675
2676   /* S L E U N Z V C */
2677   /* - - - - - - - - */
2678   cycles += 4;    /* TODO: + jx oscillator clock cycles */
2679   return 0;
2680}
2681
2682/* BSR : 0000 0001 0010 10RR : A-56 */
2683static size_t dsp56k_op_bsr_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2684{
2685   /* S L E U N Z V C */
2686   /* - - - - - - - - */
2687   return 0;
2688}
2689
2690/* CHKAAU : 0000 0000 0000 0100 : A-58 */
2691static size_t dsp56k_op_chkaau(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2692{
2693   /* S L E U N Z V C */
2694   /* - - - - ? ? ? - */
2695   /* V - Set if the result of the last address ALU update performed a modulo wrap. Cleared if
2696          result of the last address ALU did not perform a modulo wrap.*/
2697   /* Z - Set if the result of the last address ALU update is 0. Cleared if the result of the last
2698          address ALU is positive. */
2699   /* N - Set if the result of the last address ALU update is negative. Cleared if the result of the
2700          last address ALU is positive. */
2701   return 0;
2702}
2703
2704/* DEBUG : 0000 0000 0000 0001 : A-68 */
2705static size_t dsp56k_op_debug(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2706{
2707   /* S L E U N Z V C */
2708   /* - - - - - - - - */
2709   return 0;
2710}
2711
2712/* DEBUGcc : 0000 0000 0101 cccc : A-70 */
2713static size_t dsp56k_op_debugcc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2714{
2715   /* S L E U N Z V C */
2716   /* - - - - - - - - */
2717   return 0;
2718}
2719
2720/* DIV : 0001 0101 0--0 F1DD : A-76 */
2721/* WARNING : DOCS SAY THERE IS A PARALLEL MOVE HERE !!! */
2722static size_t dsp56k_op_div(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2723{
2724   /* WARNING : THIS DOES NOT WORK.  IT DOESN'T EVEN TRY !!! */
2725   typed_pointer S = {NULL, DT_BYTE};
2726   typed_pointer D = {NULL, DT_BYTE};
2727
2728   decode_DDF_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S, &D);
2729
2730   /* S L E U N Z V C */
2731   /* - * - - - - ? ? */
2732   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significantst
2733          bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
2734   /* C - Set if bit 39 of the result is cleared. Cleared otherwise. */
2735   cycles += 2;
2736   return 1;
2737}
2738
2739/* DMAC : 0001 0101 10s1 FsQQ : A-80 */
2740static size_t dsp56k_op_dmac(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2741{
2742   UINT8 ss = 0;
2743   INT64 result = 0;
2744
2745   void* D = NULL;
2746   void* S1 = NULL;
2747   void* S2 = NULL;
2748
2749   decode_QQF_special_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S1, &S2, &D);
2750
2751   ss = BITS(op,0x0024);
2752
2753   /* Fixed-point 2's complement multiplication requires a shift */
2754   if (ss == 0x00 || ss == 0x01)
2755   {
2756      /* Signed * Signed */
2757      INT32 s1 = ((INT32)(*((UINT16*)S1)));
2758      INT32 s2 = ((INT32)(*((UINT16*)S2)));
2759      result = ( s1 * s2 ) << 1;
2760   }
2761   else if (ss == 0x2)
2762   {
2763      /* Signed * Unsigned */
2764      /* WARNING : THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
2765      INT32 s1 = ((INT32)(*((UINT16*)S1)));
2766      INT32 s2 = (UINT32)(*((UINT16*)S2));
2767      result = ( s1 * s2 ) << 1;
2768   }
2769   else if (ss == 0x3)
2770   {
2771      /* Unsigned * Unsigned */
2772      UINT32 s1 = (UINT32)(*((UINT16*)S1));
2773      UINT32 s2 = (UINT32)(*((UINT16*)S2));
2774      result = ( s1 * s2 ) << 1;
2775   }
2776
2777   /* Shift right, then accumulate */
2778   (*((UINT64*)D)) =  (*((UINT64*)D)) >> 16;
2779   (*((UINT64*)D)) += result;
2780
2781   /* S L E U N Z V C */
2782   /* - * * * * * * - */
2783   /* TODO: L, E, U, V */
2784   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
2785   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2786
2787   cycles += 2;
2788   return 1;
2789}
2790
2791/* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */
2792static size_t dsp56k_op_do(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2793{
2794   /* S L E U N Z V C */
2795   /* - * - - - - - - */
2796   return 0;
2797}
2798
2799/* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */
2800static size_t dsp56k_op_do_1(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2801{
2802   UINT8 retSize = 0;
2803   UINT8 iValue = BITS(op,0x00ff);
2804
2805   /* Don't execute if the loop counter == 0 */
2806   if (iValue != 0x00)
2807   {
2808      /* First instruction cycle */
2809      SP++;                       /* TODO: Should i really inc here first? */
2810      SSH = LA;
2811      SSL = LC;
2812      LC = (UINT16)iValue;
2813
2814
2815      /* Second instruction cycle */
2816      SP++;                       /* TODO: See above */
2817      SSH = PC + 2;               /* Keep these stack entries in 'word-based-index' space */
2818      SSL = SR;
2819      LA = PC + 2 + op2;          /* TODO: The docs subtract 1 from here? */
2820
2821
2822      /* Third instruction cycle */
2823      LF_bit_set(cpustate, 1);
2824
2825      /* Undocumented, but it must be true to nest Dos in DoForevers */
2826      FV_bit_set(cpustate, 0);
2827
2828
2829      /* S L E U N Z V C */
2830      /* - * - - - - - - */
2831      /* TODO : L */
2832
2833      cycles += 6;    /* TODO: + mv oscillator cycles */
2834      retSize = 2;
2835   }
2836   else
2837   {
2838      /* Skip over the contents of the loop */
2839      cpustate->ppc = PC;
2840      PC = PC + 2 + op2;
2841
2842      cycles += 10;   /* TODO: + mv oscillator cycles */
2843      retSize = 0;
2844   }
2845
2846   return retSize;
2847}
2848
2849/* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */
2850static size_t dsp56k_op_do_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2851{
2852   UINT8 retSize = 0;
2853   UINT16 lValue = 0x0000;
2854   typed_pointer S = {NULL, DT_BYTE};
2855   decode_DDDDD_table(cpustate, BITS(op,0x001f), &S);
2856
2857   /* TODO: Does not properly shift-limit sources A&B - Fix per the docs. */
2858   /* TODO: There are other cases besides A&B this code won't work. */
2859   if      (S.addr == &A) lValue = *((UINT16*)(&A1));
2860   else if (S.addr == &B) lValue = *((UINT16*)(&B1));
2861   else                   lValue = *((UINT16*)S.addr);
2862
2863   /* HACK */
2864   if (lValue >= 0xfff0)
2865   {
2866      logerror("Dsp56k : DO_2 operation changed %04x to 0000.\n", lValue);
2867      lValue = 0x0000;
2868   }
2869
2870   /* TODO: Fix for special cased SP S */
2871   if (S.addr == &SP)
2872      logerror("DSP56k: do with SP as the source not properly implemented yet.\n");
2873
2874   /* TODO: Fix for special cased SSSL S */
2875   if (S.addr == &SSL)
2876      logerror("DSP56k: do with SP as the source not properly implemented yet.\n");
2877
2878   /* Don't execute if the loop counter == 0 */
2879   if (lValue != 0x00)
2880   {
2881      /* First instruction cycle */
2882      SP++;                       /* TODO: Should i really inc here first? */
2883      SSH = LA;
2884      SSL = LC;
2885      LC = (UINT16)lValue;
2886
2887
2888      /* Second instruction cycle */
2889      SP++;                       /* TODO: See above */
2890      SSH = PC + 2;               /* Keep these stack entries in 'word-based-index' space */
2891      SSL = SR;
2892      LA = PC + 2 + op2;          /* TODO: The docs subtract 1 from here? */
2893
2894
2895      /* Third instruction cycle */
2896      LF_bit_set(cpustate, 1);
2897
2898
2899      /* S L E U N Z V C */
2900      /* - * - - - - - - */
2901      /* TODO : L */
2902
2903      cycles += 6;    /* TODO: + mv oscillator cycles */
2904      retSize = 2;
2905   }
2906   else
2907   {
2908      /* Skip over the contents of the loop */
2909      cpustate->ppc = PC;
2910      PC = PC + 2 + op2;
2911
2912      cycles += 10;   /* TODO: + mv oscillator cycles */
2913      retSize = 0;
2914   }
2915
2916   return retSize;
2917}
2918
2919/* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */
2920static size_t dsp56k_op_doforever(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2921{
2922   /* First instruction cycle */
2923   SP++;
2924   SSH = LA;
2925   SSL = LC;
2926
2927   /* Second instruction cycle */
2928   SP++;
2929   SSH = PC + 2;
2930   SSL = SR;
2931   LA = PC + 2 + op2;
2932
2933   /* Third instruction cycle */
2934   LF_bit_set(cpustate, 1);
2935   FV_bit_set(cpustate, 1);
2936
2937   /* S L E U N Z V C */
2938   /* - - - - - - - - */
2939   cycles += 6;
2940   return 2;
2941}
2942
2943/* ENDDO : 0000 0000 0000 1001 : A-92 */
2944static size_t dsp56k_op_enddo(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2945{
2946   /* S L E U N Z V C */
2947   /* - - - - - - - - */
2948   return 0;
2949}
2950
2951/* EXT : 0001 0101 0101 F010 : A-96 */
2952static size_t dsp56k_op_ext(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2953{
2954   /* S L E U N Z V C */
2955   /* - * * * * * * - */
2956   return 0;
2957}
2958
2959/* ILLEGAL : 0000 0000 0000 1111 : A-98 */
2960static size_t dsp56k_op_illegal(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2961{
2962   /* S L E U N Z V C */
2963   /* - - - - - - - - */
2964   return 0;
2965}
2966
2967/* IMAC : 0001 0101 1010 FQQQ : A-100 */
2968static size_t dsp56k_op_imac(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2969{
2970   INT64 opD = 0;
2971   INT64 result = 0;
2972
2973   INT32 s1 = 0;
2974   INT32 s2 = 0;
2975
2976   void* D = NULL;
2977   void* S1 = NULL;
2978   void* S2 = NULL;
2979
2980   decode_QQQF_table(cpustate, BITS(op,0x0007), BITS(op,0x0008), &S1, &S2, &D);
2981
2982   /* Cast both values as being signed */
2983   s1 = *((INT16*)S1);
2984   s2 = *((INT16*)S2);
2985
2986   /* Integral multiply doesn't require the shift */
2987   result = (s1 * s2);
2988
2989   /* Shift result 16 bits to the left before adding to destination */
2990   result = (result << 16) & 0xffff0000;
2991
2992   /* Sign extend D into a temp variable */
2993   opD = (*((UINT64*)D));
2994   if (opD & U64(0x0000008000000000))
2995      opD |= U64(0xffffff0000000000);
2996   else
2997      opD &= U64(0x000000ffffffffff);
2998
2999   /* Accumulate */
3000   opD += result;
3001
3002   /* And out the bits that don't live in the register */
3003   opD &= U64(0x000000ffffffffff);
3004
3005   (*((UINT64*)D)) = (UINT64)opD;
3006
3007   /* S L E U N Z V C */
3008   /* - * ? ? * ? ? - */
3009   /* TODO: L */
3010   /* U,E - Will not be set correctly by this instruction*/
3011   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
3012   if ((*((UINT64*)D) & U64(0x000000ffffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
3013   DSP56K_V_CLEAR();
3014
3015   cycles += 2;
3016   return 1;
3017}
3018
3019/* IMPY : 0001 0101 1000 FQQQ : A-102 */
3020static size_t dsp56k_op_impy(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3021{
3022   /* S L E U N Z V C */
3023   /* - * ? ? * ? ? - */
3024   /* Z - Set if the 24 most significant bits of the destination result are all zeroes. */
3025   /* U,E - Will not be set correctly by this instruction*/
3026   /* V - Set to zero regardless of the overflow */
3027   return 0;
3028}
3029
3030/* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */
3031static size_t dsp56k_op_jcc(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3032{
3033   /* S L E U N Z V C */
3034   /* - - - - - - - - */
3035   return 0;
3036}
3037
3038/* Jcc : 0000 0110 RR10 cccc : A-108 */
3039static size_t dsp56k_op_jcc_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3040{
3041   /* S L E U N Z V C */
3042   /* - - - - - - - - */
3043   return 0;
3044}
3045
3046/* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */
3047static size_t dsp56k_op_jmp(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3048{
3049   cpustate->ppc = PC;
3050   PC = op2;
3051
3052   /* S L E U N Z V C */
3053   /* - - - - - - - - */
3054
3055   cycles += 4;    /* TODO: + jx */
3056   return 0;
3057}
3058
3059/* JMP : 0000 0001 0010 01RR : A-110 */
3060static size_t dsp56k_op_jmp_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3061{
3062   typed_pointer R = { NULL, DT_BYTE };
3063   decode_RR_table(cpustate, BITS(op,0x0003), &R);
3064
3065   cpustate->ppc = PC;
3066   PC = *((UINT16*)R.addr);
3067
3068   /* S L E U N Z V C */
3069   /* - - - - - - - - */
3070
3071   cycles += 4;    /* TODO: + jx */
3072   return 0;
3073}
3074
3075/* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */
3076static size_t dsp56k_op_jscc(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3077{
3078   int shouldJump = decode_cccc_table(cpustate, BITS(op,0x000f));
3079
3080   if(shouldJump)
3081   {
3082      /* TODO: It says "signed" absolute offset.  Weird. */
3083      UINT16 branchOffset = op2;
3084
3085      /* TODO: Verify, since it's not in the docs, but it must be true */
3086      PC += 2;
3087
3088      SP++;
3089      SSH = PC;
3090      SSL = SR;
3091
3092      cpustate->ppc = PC;
3093      PC = branchOffset;
3094
3095      cycles += 4;    /* TODO: +jx oscillator clock cycles */
3096      return 0;
3097   }
3098   else
3099   {
3100      cycles += 4;    /* TODO: +jx oscillator clock cycles */
3101      return 2;
3102   }
3103
3104   /* S L E U N Z V C */
3105   /* - - - - - - - - */
3106   return 0;
3107}
3108
3109/* JScc : 0000 0110 RR00 cccc : A-112 */
3110static size_t dsp56k_op_jscc_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3111{
3112   /* S L E U N Z V C */
3113   /* - - - - - - - - */
3114   return 0;
3115}
3116
3117/* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */
3118static size_t dsp56k_op_jsr(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3119{
3120   /* TODO: It says "signed" absolute offset.  Weird. */
3121   UINT16 branchOffset = op2;
3122
3123   /* TODO: Verify, since it's not in the docs, but it must be true */
3124   PC += 2;
3125
3126   /* TODO: This is a hacky implementation of Long vs Fast Interrupts.  Do it right someday! */
3127   if (PC < ADDRESS(0x40))
3128   {
3129      /* Long interrupt gets the previous PC, not the current one */
3130      SP++;
3131      SSH = cpustate->ppc;
3132      SSL = SR;
3133
3134      cpustate->ppc = cpustate->ppc;
3135      PC = branchOffset;
3136   }
3137   else
3138   {
3139      /* Normal operation */
3140      SP++;
3141      SSH = PC;
3142      SSL = SR;
3143
3144      cpustate->ppc = PC;
3145      PC = branchOffset;
3146   }
3147
3148   /* S L E U N Z V C */
3149   /* - - - - - - - - */
3150   cycles += 4;        /* TODO: + jx oscillator cycles */
3151   return 0;
3152}
3153
3154/* JSR : 0000 1010 AAAA AAAA : A-114 */
3155static size_t dsp56k_op_jsr_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3156{
3157   /* S L E U N Z V C */
3158   /* - - - - - - - - */
3159   return 0;
3160}
3161
3162/* JSR : 0000 0001 0010 00RR : A-114 */
3163static size_t dsp56k_op_jsr_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3164{
3165   /* S L E U N Z V C */
3166   /* - - - - - - - - */
3167   return 0;
3168}
3169
3170/* LEA : 0000 0001 11TT MMRR : A-116 */
3171static size_t dsp56k_op_lea(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3172{
3173   UINT16 ea = 0;
3174   UINT16 *rX = NULL;
3175   UINT16 *nX = NULL;
3176   typed_pointer D = {NULL, DT_BYTE};
3177   decode_TT_table(cpustate, BITS(op,0x0030), &D);
3178
3179   /* TODO: change the execute_mm_functions to return values.  Maybe */
3180   /* Because this calculation isn't applied, do everything locally */
3181   /* RR table */
3182   switch(BITS(op,0x0003))
3183   {
3184      case 0x0: rX = &R0;  nX = &N0;  break;
3185      case 0x1: rX = &R1;  nX = &N1;  break;
3186      case 0x2: rX = &R2;  nX = &N2;  break;
3187      case 0x3: rX = &R3;  nX = &N3;  break;
3188   }
3189
3190   /* MM table */
3191   switch(BITS(op,0x000c))
3192   {
3193      case 0x0: ea = *rX;       break;
3194      case 0x1: ea = *rX + 1;   break;
3195      case 0x2: ea = *rX - 1;   break;
3196      case 0x3: ea = *rX + *nX; break;
3197   }
3198
3199   *((UINT16*)D.addr) = ea;
3200
3201   /* S L E U N Z V C */
3202   /* - - - - - - - - */
3203   return 1;
3204}
3205
3206/* LEA : 0000 0001 10NN MMRR : A-116 */
3207static size_t dsp56k_op_lea_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3208{
3209   /* S L E U N Z V C */
3210   /* - - - - - - - - */
3211   return 0;
3212}
3213
3214/* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */
3215static size_t dsp56k_op_macsuuu(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3216{
3217   UINT8 s = 0;
3218   INT64 result = 0;
3219
3220   void* D = NULL;
3221   void* S1 = NULL;
3222   void* S2 = NULL;
3223
3224   decode_QQF_special_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S1, &S2, &D);
3225
3226   s = BITS(op,0x0004);
3227
3228   /* Fixed-point 2's complement multiplication requires a shift */
3229   if (s)
3230   {
3231      /* Unsigned * Unsigned */
3232      UINT32 s1 = (UINT32)(*((UINT16*)S1));
3233      UINT32 s2 = (UINT32)(*((UINT16*)S2));
3234      result = ( s1 * s2 ) << 1;
3235   }
3236   else
3237   {
3238      /* Signed * Unsigned */
3239      /* WARNING : THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
3240      INT32 s1 = ((INT32)(*((UINT16*)S1)));
3241      INT32 s2 = (UINT32)(*((UINT16*)S2));
3242      result = ( s1 * s2 ) << 1;
3243   }
3244
3245   (*((UINT64*)D)) += result;
3246
3247   /* And out the bits that don't live in the register */
3248   (*((UINT64*)D)) &= U64(0x000000ffffffffff);
3249
3250   /* S L E U N Z V C */
3251   /* - * * * * * * - */
3252   /* TODO: L, E, U, V */
3253   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
3254   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
3255
3256   cycles += 2;
3257   return 1;
3258}
3259
3260/* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */
3261static size_t dsp56k_op_move_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3262{
3263   /* S L E U N Z V C */
3264   /* * * - - - - - - */
3265   return 0;
3266}
3267
3268/* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */
3269static size_t dsp56k_op_movec(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3270{
3271   UINT8 W;
3272   typed_pointer R = { NULL, DT_BYTE };
3273   typed_pointer SD = { NULL, DT_BYTE };
3274
3275   W = BITS(op,0x0400);
3276   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &SD);
3277   decode_RR_table(cpustate, BITS(op,0x0003), &R);
3278
3279   if (W)
3280   {
3281      /* Write D */
3282      UINT16 value = cpustate->data->read_word(ADDRESS(*((UINT16*)R.addr))) ;
3283      typed_pointer temp_src = { &value, DT_WORD };
3284      SetDestinationValue(temp_src, SD);
3285   }
3286   else
3287   {
3288      /* Read S */
3289      UINT16 dataMemOffset = *((UINT16*)R.addr);
3290      SetDataMemoryValue(cpustate, SD, ADDRESS(dataMemOffset));
3291   }
3292
3293   execute_MM_table(cpustate, BITS(op,0x0003), BITS(op,0x000c));
3294
3295   /* S L E U N Z V C */
3296   /* * ? ? ? ? ? ? ? */
3297   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3298      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3299      limiting occurred. All ? bits are not affected otherwise.*/
3300   if (W && (SD.addr != &SR))
3301   {
3302      /* If you're writing to something other than the SR */
3303      /* TODO */
3304   }
3305
3306   cycles += 2;    /* TODO: + mvc */
3307   return 1;
3308}
3309
3310/* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */
3311static size_t dsp56k_op_movec_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3312{
3313   UINT8 W;
3314   UINT16 memOffset;
3315   typed_pointer SD = {NULL, DT_BYTE};
3316
3317   W = BITS(op,0x0400);
3318   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &SD);
3319   memOffset = execute_q_table(cpustate, BITS(op,0x0003), BITS(op,0x0008));
3320
3321   if (W)
3322   {
3323      /* Write D */
3324      UINT16 tempData = cpustate->data->read_word(ADDRESS(memOffset));
3325      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3326      SetDestinationValue(temp_src, SD);
3327   }
3328   else
3329   {
3330      /* Read S */
3331      UINT16 tempData = *((UINT16*)SD.addr);
3332      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3333      SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset));
3334   }
3335
3336   /* S L E U N Z V C */
3337   /* * ? ? ? ? ? ? ? */
3338   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3339      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3340      limiting occurred. All ? bits are not affected otherwise.*/
3341   if (W && (SD.addr != &SR))
3342   {
3343      /* If you're writing to something other than the SR */
3344      /* TODO */
3345   }
3346
3347   cycles += 2;        /* + mvc oscillator clock cycles */
3348   return 1;
3349}
3350
3351/* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */
3352static size_t dsp56k_op_movec_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3353{
3354   UINT8 W;
3355   UINT16 memOffset;
3356   typed_pointer SD = {NULL, DT_BYTE};
3357   typed_pointer XMemOffset = {NULL, DT_BYTE};
3358
3359   W = BITS(op,0x0400);
3360   decode_Z_table(cpustate, BITS(op,0x0008), &XMemOffset);
3361   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &SD);
3362
3363   memOffset = *((UINT16*)XMemOffset.addr);
3364
3365   if (W)
3366   {
3367      /* Write D */
3368      UINT16 tempData = cpustate->data->read_word(ADDRESS(memOffset));
3369      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3370      SetDestinationValue(temp_src, SD);
3371   }
3372   else
3373   {
3374      /* Read S */
3375      UINT16 tempData = *((UINT16*)SD.addr);
3376      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3377      SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset));
3378   }
3379
3380
3381   /* S L E U N Z V C */
3382   /* * ? ? ? ? ? ? ? */
3383   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3384      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3385      limiting occurred. All ? bits are not affected otherwise.*/
3386   if (W && (SD.addr != &SR))
3387   {
3388      /* If you're writing to something other than the SR */
3389      /* TODO */
3390   }
3391
3392   cycles += 2;        /* + mvc oscillator clock cycles */
3393   return 1;
3394}
3395
3396/* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */
3397static size_t dsp56k_op_movec_3(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3398{
3399   UINT8 W;
3400   UINT8 t;
3401   typed_pointer SD = { NULL, DT_BYTE };
3402
3403   W = BITS(op,0x0400);
3404   t = BITS(op,0x0008);
3405   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &SD);
3406
3407   if (W)
3408   {
3409      /* Write D */
3410      if (t)
3411      {
3412         /* 16-bit long data */
3413         typed_pointer temp_src = { (void*)&op2, DT_WORD };
3414         SetDestinationValue(temp_src, SD);
3415      }
3416      else
3417      {
3418         /* 16-bit long address */
3419         UINT16 tempD = cpustate->data->read_word(ADDRESS(op2));
3420         typed_pointer tempTP = {&tempD, DT_WORD};
3421         SetDestinationValue(tempTP, SD);
3422      }
3423   }
3424   else
3425   {
3426      /* Read S */
3427      if (t)
3428      {
3429         /* 16-bit long data */
3430         logerror("DSP56k: Movec - I don't think this exists?");
3431      }
3432      else
3433      {
3434         /* 16-bit long address */
3435         SetDataMemoryValue(cpustate, SD, ADDRESS(op2));
3436      }
3437   }
3438
3439   /* S L E U N Z V C */
3440   /* * ? ? ? ? ? ? ? */
3441   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3442      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3443      limiting occurred. All ? bits are not affected otherwise.*/
3444   if (W && (SD.addr != &SR))
3445   {
3446      /* If you're writing to something other than the SR */
3447      /* TODO */
3448   }
3449
3450   cycles += 2;    /* TODO: + mvc */
3451   return 2;
3452}
3453
3454/* MOVE(C) : 0010 10dd dddD DDDD : A-144 */
3455static size_t dsp56k_op_movec_4(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3456{
3457   typed_pointer S = {NULL, DT_BYTE};
3458   typed_pointer D = {NULL, DT_BYTE};
3459
3460   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &S);
3461   decode_DDDDD_table(cpustate, BITS(op,0x001f), &D);
3462
3463   SetDestinationValue(S, D);
3464
3465   /* S L E U N Z V C */
3466   /* * ? ? ? ? ? ? ? */
3467   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3468      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3469      limiting occurred. All ? bits are not affected otherwise.*/
3470   if (D.addr != &SR)
3471   {
3472      /* If you're writing to something other than the SR */
3473      /* TODO */
3474   }
3475
3476   cycles += 2;
3477   return 1;
3478}
3479
3480/* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */
3481static size_t dsp56k_op_movec_5(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3482{
3483   INT8 xx;
3484   UINT8 W;
3485   UINT16 memOffset;
3486   typed_pointer SD = { NULL, DT_BYTE };
3487
3488   xx = (INT8)(op & 0x00ff);
3489   W = BITS(op2,0x0400);
3490   decode_DDDDD_table(cpustate, BITS(op2,0x03e0), &SD);
3491
3492   memOffset = R2 + (INT16)xx;
3493
3494   if (W)
3495   {
3496      /* Write D */
3497      UINT16 tempData = cpustate->data->read_word(ADDRESS(memOffset));
3498      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3499      SetDestinationValue(temp_src, SD);
3500   }
3501   else
3502   {
3503      /* Read S */
3504      UINT16 tempData = *((UINT16*)SD.addr);
3505      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3506      SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset));
3507   }
3508
3509   /* S L E U N Z V C */
3510   /* * ? ? ? ? ? ? ? */
3511   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3512      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3513      limiting occurred. All ? bits are not affected otherwise.*/
3514   if (W && (SD.addr != &SR))
3515   {
3516      /* If you're writing to something other than the SR */
3517      /* TODO */
3518   }
3519
3520   cycles += 2;    /* TODO: + mvc oscillator clock cycles */
3521   return 2;
3522}
3523
3524/* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */
3525static size_t dsp56k_op_movei(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3526{
3527   typed_pointer D = {NULL, DT_BYTE};
3528   typed_pointer immTP = {NULL, DT_BYTE};
3529
3530   /* Typecasting to INT16 sign-extends the BBBBBBBB operand */
3531   UINT16 immediateSignExtended = (INT16)(op & 0x00ff);
3532   immTP.addr = &immediateSignExtended;
3533   immTP.data_type = DT_WORD;
3534
3535   decode_DD_table(cpustate, BITS(op,0x0300), &D);
3536
3537   SetDestinationValue(immTP, D);
3538
3539   /* S L E U N Z V C */
3540   /* - - - - - - - - */
3541   cycles += 2;
3542   return 1;
3543}
3544
3545/* MOVE(M) : 0000 001W RR0M MHHH : A-152 */
3546static size_t dsp56k_op_movem(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3547{
3548   UINT8 W;
3549   typed_pointer R = { NULL, DT_BYTE };
3550   typed_pointer SD = { NULL, DT_BYTE };
3551
3552   W = BITS(op,0x0100);
3553   decode_RR_table(cpustate, BITS(op,0x00c0), &R);
3554   decode_HHH_table(cpustate, BITS(op,0x0007), &SD);
3555
3556   if (W)
3557   {
3558      /* Read from Program Memory */
3559      typed_pointer data;
3560      UINT16 ldata = cpustate->program->read_word(ADDRESS(*((UINT16*)R.addr)));
3561
3562      data.addr = &ldata;
3563      data.data_type = DT_WORD;
3564      SetDestinationValue(data, SD) ;
3565   }
3566   else
3567   {
3568      /* Write to Program Memory */
3569      SetProgramMemoryValue(cpustate, SD, ADDRESS(*((UINT16*)R.addr))) ;
3570   }
3571
3572   execute_MM_table(cpustate, BITS(op,0x00c0), BITS(op,0x0018));
3573
3574   /* S L E U N Z V C */
3575   /* * * - - - - - - */
3576   /* TODO: S, L */
3577   cycles += 2;    /* TODO: + mvm oscillator clock cycles */
3578   return 1;
3579}
3580
3581/* MOVE(M) : 0000 001W RR11 mmRR : A-152 */
3582static size_t dsp56k_op_movem_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3583{
3584   /* S L E U N Z V C */
3585   /* * * - - - - - - */
3586   return 0;
3587}
3588
3589/* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */
3590static size_t dsp56k_op_movem_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3591{
3592   /* S L E U N Z V C */
3593   /* * * - - - - - - */
3594   return 0;
3595}
3596
3597/* MOVE(P) : 0001 100W HH1p pppp : A-156 */
3598static size_t dsp56k_op_movep(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3599{
3600   UINT16 W;
3601   UINT16 pp;
3602   typed_pointer SD = {NULL, DT_BYTE};
3603
3604   decode_HH_table(cpustate, BITS(op,0x00c0), &SD);
3605   /* TODO: Special cases for A & B */
3606
3607   pp = op & 0x001f;
3608   pp = assemble_address_from_IO_short_address(cpustate, pp);
3609
3610   W = BITS(op,0x0100);
3611
3612   if (W)
3613   {
3614      UINT16 data = cpustate->data->read_word(ADDRESS(pp));
3615
3616      typed_pointer tempTP;
3617      tempTP.addr = &data;
3618      tempTP.data_type = DT_WORD;
3619
3620      SetDestinationValue(tempTP, SD);
3621   }
3622   else
3623   {
3624      SetDataMemoryValue(cpustate, SD, ADDRESS(pp));
3625   }
3626
3627   /* S L E U N Z V C */
3628   /* * * - - - - - - */
3629   /* TODO: S, L */
3630
3631   cycles += 4;        /* TODO: + mvp oscillator cycles */
3632   return 1;
3633}
3634
3635/* MOVE(P) : 0000 110W RRmp pppp : A-156 */
3636static size_t dsp56k_op_movep_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3637{
3638   /* X:<Rx> and X:<pp> */
3639   UINT16 W;
3640   UINT16 pp;
3641
3642   typed_pointer SD = {NULL, DT_BYTE};
3643   decode_RR_table(cpustate, BITS(op,0x00c0), &SD);
3644
3645   pp = op & 0x001f;
3646   pp = assemble_address_from_IO_short_address(cpustate, pp);
3647
3648   W = BITS(op,0x0100);
3649
3650   /* A little different than most W if's - opposite read and write */
3651   if (W)
3652   {
3653      UINT16 data = cpustate->data->read_word(ADDRESS(*((UINT16*)SD.addr)));
3654
3655      typed_pointer tempTP;
3656      tempTP.addr = &data;
3657      tempTP.data_type = DT_WORD;
3658
3659      SetDataMemoryValue(cpustate, tempTP, ADDRESS(pp));
3660   }
3661   else
3662   {
3663      /* TODO */
3664      fatalerror("dsp56k : move(p) NOTHING HERE (yet)\n") ;
3665   }
3666
3667   /* Postincrement */
3668   execute_m_table(cpustate, BITS(op,0x00c0), BITS(op,0x0020));
3669
3670   /* S L E U N Z V C */
3671   /* * * - - - - - - */
3672   /* TODO: S, L */
3673   cycles += 4;        /* TODO: + mvp oscillator cycles */
3674   return 1;
3675}
3676
3677/* MOVE(S) : 0001 100W HH0a aaaa : A-158 */
3678static size_t dsp56k_op_moves(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3679{
3680   /* S L E U N Z V C */
3681   /* * * - - - - - - */
3682   return 0;
3683}
3684
3685/* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */
3686static size_t dsp56k_op_mpysuuu(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3687{
3688   UINT8 s = 0;
3689   INT64 result = 0;
3690
3691   void* D = NULL;
3692   void* S1 = NULL;
3693   void* S2 = NULL;
3694
3695   decode_QQF_special_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S1, &S2, &D);
3696
3697   s = BITS(op,0x0004);
3698
3699   /* Fixed-point 2's complement multiplication requires a shift */
3700   if (s)
3701   {
3702      /* Unsigned * Unsigned */
3703      UINT32 s1 = (UINT32)(*((UINT16*)S1));
3704      UINT32 s2 = (UINT32)(*((UINT16*)S2));
3705      result = ( s1 * s2 ) << 1;
3706   }
3707   else
3708   {
3709      /* Signed * Unsigned */
3710      /* WARNING : THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
3711      INT32 s1 = ((INT32)(*((UINT16*)S1)));
3712      INT32 s2 = (UINT32)(*((UINT16*)S2));
3713      result = ( s1 * s2 ) << 1;
3714   }
3715
3716   (*((UINT64*)D)) = result;
3717
3718   /* And out the bits that don't live in the register */
3719   (*((UINT64*)D)) &= U64(0x000000ffffffffff);
3720
3721   /* S L E U N Z V C */
3722   /* - * * * * * * - */
3723   /* TODO: L, E, U, V */
3724   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
3725   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
3726
3727   cycles += 2;
3728   return 1;
3729}
3730
3731/* NEGC : 0001 0101 0110 F000 : A-168 */
3732static size_t dsp56k_op_negc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3733{
3734   /* S L E U N Z V C */
3735   /* - * * * * * * * */
3736   return 0;
3737}
3738
3739/* NOP : 0000 0000 0000 0000 : A-170 */
3740static size_t dsp56k_op_nop(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3741{
3742   /* S L E U N Z V C */
3743   /* - - - - - - - - */
3744   return 1;
3745}
3746
3747/* NORM : 0001 0101 0010 F0RR : A-172 */
3748static size_t dsp56k_op_norm(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3749{
3750   /* S L E U N Z V C */
3751   /* - * * * * * ? - */
3752   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significantst
3753          bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
3754   return 0;
3755}
3756
3757/* ORI : 0001 1EE1 iiii iiii : A-178 */
3758static size_t dsp56k_op_ori(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3759{
3760   /* S L E U N Z V C */
3761   /* - ? ? ? ? ? ? ? */
3762   /* All ? bits - Set if the corresponding bit in the immediate data is set and if the operand is the
3763      CCR. Not affected otherwise. */
3764   return 0;
3765}
3766
3767/* REP : 0000 0000 111- --RR : A-180 */
3768static size_t dsp56k_op_rep(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3769{
3770   /* S L E U N Z V C */
3771   /* - * - - - - - - */
3772   return 0;
3773}
3774
3775/* REP : 0000 1111 iiii iiii : A-180 */
3776static size_t dsp56k_op_rep_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3777{
3778   /* TODO: This is non-interruptable, probably have to turn off interrupts here */
3779   UINT16 iVal = op & 0x00ff;
3780
3781   if (iVal != 0)
3782   {
3783      TEMP = LC;
3784      LC = iVal;
3785
3786      cpustate->repFlag = 1;
3787      cpustate->repAddr = PC + ADDRESS(1);
3788
3789      cycles += 4;        /* TODO: + mv oscillator clock cycles */
3790   }
3791   else
3792   {
3793      cycles += 6;        /* TODO: + mv oscillator clock cycles */
3794   }
3795
3796
3797   /* S L E U N Z V C */
3798   /* - * - - - - - - */
3799   /* TODO: L */
3800   return 1;
3801}
3802
3803/* REP : 0000 0100 001D DDDD : A-180 */
3804static size_t dsp56k_op_rep_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3805{
3806   /* TODO: This is non-interruptable, probably have to turn off interrupts here */
3807   UINT16 repValue;
3808   typed_pointer D = {NULL, DT_BYTE};
3809   decode_DDDDD_table(cpustate, BITS(op,0x001f), &D);
3810
3811   /* TODO: handle special A&B source cases */
3812   if (D.addr == &A || D.addr == &B)
3813      logerror("DSP56k ERROR : Rep with A or B instruction not implemented yet!\n");
3814
3815   repValue = *((UINT16*)D.addr);
3816
3817   if (repValue != 0)
3818   {
3819      TEMP = LC;
3820      LC = repValue;
3821
3822      cpustate->repFlag = 1;
3823      cpustate->repAddr = PC + ADDRESS(1);
3824
3825      cycles += 4;        /* TODO: + mv oscillator clock cycles */
3826   }
3827   else
3828   {
3829      cycles += 6;        /* TODO: + mv oscillator clock cycles */
3830   }
3831
3832   /* S L E U N Z V C */
3833   /* - * - - - - - - */
3834   /* TODO: L */
3835   return 1;
3836}
3837
3838/* REPcc : 0000 0001 0101 cccc : A-184 */
3839static size_t dsp56k_op_repcc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3840{
3841   /* S L E U N Z V C */
3842   /* - - - - - - - - */
3843   return 0;
3844}
3845
3846/* RESET : 0000 0000 0000 1000 : A-186 */
3847static size_t dsp56k_op_reset(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3848{
3849   /* S L E U N Z V C */
3850   /* - - - - - - - - */
3851   return 0;
3852}
3853
3854/* RTI : 0000 0000 0000 0111 : A-194 */
3855static size_t dsp56k_op_rti(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3856{
3857   /* WARNING : THERE SHOULD BE A MORE GENERAL HANDLING OF STACK ERRORS. */
3858   if (SP == 0)
3859   {
3860      dsp56k_add_pending_interrupt(cpustate, "Stack Error");
3861      return 0;
3862   }
3863
3864   cpustate->ppc = PC;
3865   PC = SSH;
3866
3867   SR = SSL;
3868   SP = SP - 1;
3869
3870   /* S L E U N Z V C */
3871   /* ? ? ? ? ? ? ? ? */
3872   /* All ? bits - Set according to value pulled from the stack. */
3873   cycles += 4;        /* TODO: + rx oscillator clock cycles */
3874   return 0;
3875}
3876
3877/* RTS : 0000 0000 0000 0110 : A-196 */
3878static size_t dsp56k_op_rts(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3879{
3880   /* Pop */
3881   cpustate->ppc = PC;
3882   PC = SSH;
3883
3884   /* SR = SSL; The status register is not affected. */
3885
3886   SP--;
3887
3888   /* S L E U N Z V C */
3889   /* - - - - - - - - */
3890   cycles += 4;    /* TODO: + rx oscillator clock cycles */
3891   return 0;
3892}
3893
3894/* STOP : 0000 0000 0000 1010 : A-200 */
3895static size_t dsp56k_op_stop(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3896{
3897   /* S L E U N Z V C */
3898   /* - - - - - - - - */
3899   return 0;
3900}
3901
3902/* SWAP : 0001 0101 0111 F001 : A-206 */
3903static size_t dsp56k_op_swap(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3904{
3905   /* S L E U N Z V C */
3906   /* - - - - - - - - */
3907   return 0;
3908}
3909
3910/* SWI : 0000 0000 0000 0101 : A-208 */
3911static size_t dsp56k_op_swi(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3912{
3913   /* S L E U N Z V C */
3914   /* - - - - - - - - */
3915   return 0;
3916}
3917
3918/* Tcc : 0001 00cc ccTT Fh0h : A-210 */
3919static size_t dsp56k_op_tcc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3920{
3921   int shouldTransfer = decode_cccc_table(cpustate, BITS(op,0x03c0));
3922
3923   if (shouldTransfer)
3924   {
3925      typed_pointer S = {NULL, DT_BYTE};
3926      typed_pointer D = {NULL, DT_BYTE};
3927      typed_pointer S2 = {&R0, DT_WORD};
3928      typed_pointer D2 = {NULL, DT_BYTE};
3929
3930      decode_h0hF_table(cpustate, BITS(op,0x0007),BITS(op,0x0008), &S, &D);
3931      SetDestinationValue(S, D);
3932
3933      /* TODO: What's up with that A,A* thing in the docs?  Can you only ignore the R0->RX transfer if you do an A,A? */
3934      decode_RR_table(cpustate, BITS(op,0x0030), &D2); /* TT is the same as RR */
3935      SetDestinationValue(S2, D2);
3936   }
3937
3938   /* S L E U N Z V C */
3939   /* - - - - - - - - */
3940   cycles += 2;
3941   return 1;
3942}
3943
3944/* TFR(2) : 0001 0101 0000 F00J : A-214 */
3945static size_t dsp56k_op_tfr2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3946{
3947   typed_pointer S = {NULL, DT_BYTE};
3948   typed_pointer D = {NULL, DT_BYTE};
3949
3950   decode_JF_table(cpustate, BITS(op,0x0001), BITS(op,0x0008), &S, &D);
3951
3952   SetDestinationValue(S, D);
3953
3954   /* S L E U N Z V C */
3955   /* - * - - - - - - */
3956   /* TODO: L */
3957   cycles += 2;
3958   return 1;
3959}
3960
3961/* TFR(3) : 0010 01mW RRDD FHHH : A-216 */
3962static size_t dsp56k_op_tfr3(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3963{
3964   /* S L E U N Z V C */
3965   /* * * - - - - - - */
3966   return 0;
3967}
3968
3969/* TST(2) : 0001 0101 0001 -1DD : A-220 */
3970static size_t dsp56k_op_tst2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3971{
3972   typed_pointer D = {NULL, DT_BYTE};
3973   decode_DD_table(cpustate, BITS(op,0x0003), &D);
3974
3975   /* S L E U N Z V C */
3976   /* - * * * * * 0 0 */
3977   /* (L,E,U should be set to 0) */
3978   DSP56K_L_CLEAR();
3979   DSP56K_E_CLEAR();
3980   /* U_CLEAR(); */ /* TODO: Conflicting opinions?  "Set if unnormalized."  Documentation is weird (A&B?) */
3981   if ((*((UINT16*)D.addr)) &  0x8000) DSP56K_N_SET(); else DSP56K_N_CLEAR();
3982   if ((*((UINT16*)D.addr)) == 0x0000) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
3983   /* DSP56K_V_CLEAR(); */ /* Unaffected */
3984   DSP56K_C_CLEAR();
3985
3986   cycles += 2;
3987   return 1;
3988}
3989
3990/* WAIT : 0000 0000 0000 1011 : A-222 */
3991static size_t dsp56k_op_wait(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3992{
3993   /* S L E U N Z V C */
3994   /* - - - - - - - - */
3995   return 0;
3996}
3997
3998/* ZERO : 0001 0101 0101 F000 : A-224 */
3999static size_t dsp56k_op_zero(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
4000{
4001   /* S L E U N Z V C */
4002   /* - * * * * * * - */
4003   return 0;
4004}
4005
4006
4007
4008/***************************************************************************
4009    Table decoding
4010***************************************************************************/
4011static UINT16 decode_BBB_bitmask(dsp56k_core* cpustate, UINT16 BBB, UINT16 *iVal)
4012{
4013   UINT16 retVal = 0x0000;
4014
4015   switch(BBB)
4016   {
4017      case 0x4: retVal = 0xff00;  *iVal <<= 8;  break;
4018      case 0x2: retVal = 0x0ff0;  *iVal <<= 4;  break;
4019      case 0x1: retVal = 0x00ff;  *iVal <<= 0;  break;
4020   }
4021
4022   return retVal;
4023}
4024
4025static int decode_cccc_table(dsp56k_core* cpustate, UINT16 cccc)
4026{
4027   int retVal = 0;
4028
4029   /* Not fully tested */
4030   switch (cccc)
4031   {
4032      /* Arranged according to mnemonic table - not decoding table */
4033      case 0x0: if( C() == 0)                         retVal = 1;  break;  /* cc(hs) */
4034      case 0x8: if( C() == 1)                         retVal = 1;  break;  /* cs(lo) */
4035      case 0x5: if( E() == 0)                         retVal = 1;  break;  /* ec */
4036      case 0xa: if( Z() == 1)                         retVal = 1;  break;  /* eq */
4037      case 0xd: if( E() == 1)                         retVal = 1;  break;  /* es */
4038      case 0x1: if((N() ^  V()) == 0)                 retVal = 1;  break;  /* ge */
4039      case 0x7: if((Z() | (N() ^ V())) == 0)          retVal = 1;  break;  /* gt */
4040      case 0x6: if( L() == 0)                         retVal = 1;  break;  /* lc */
4041      case 0xf: if((Z() | (N() ^ V())) == 1)          retVal = 1;  break;  /* le */
4042      case 0xe: if( L() == 1)                         retVal = 1;  break;  /* ls */
4043      case 0x9: if((N() ^  V()) == 1)                 retVal = 1;  break;  /* lt */
4044      case 0xb: if( N() == 1)                         retVal = 1;  break;  /* mi */
4045      case 0x2: if( Z() == 0)                         retVal = 1;  break;  /* ne */
4046      case 0xc: if((Z() | ((!U()) & (!E()))) == 1)    retVal = 1;  break;  /* nr */
4047      case 0x3: if( N() == 0)                         retVal = 1;  break;  /* pl */
4048      case 0x4: if((Z() | ((!U()) & (!E()))) == 0)    retVal = 1;  break;  /* nn */
4049   }
4050
4051   return retVal;
4052}
4053
4054static void decode_DDDDD_table(dsp56k_core* cpustate, UINT16 DDDDD, typed_pointer* ret)
4055{
4056   switch(DDDDD)
4057   {
4058      case 0x00: ret->addr = &X0;  ret->data_type = DT_WORD;       break;
4059      case 0x01: ret->addr = &Y0;  ret->data_type = DT_WORD;       break;
4060      case 0x02: ret->addr = &X1;  ret->data_type = DT_WORD;       break;
4061      case 0x03: ret->addr = &Y1;  ret->data_type = DT_WORD;       break;
4062      case 0x04: ret->addr = &A ;  ret->data_type = DT_LONG_WORD;  break;
4063      case 0x05: ret->addr = &B ;  ret->data_type = DT_LONG_WORD;  break;
4064      case 0x06: ret->addr = &A0;  ret->data_type = DT_WORD;       break;
4065      case 0x07: ret->addr = &B0;  ret->data_type = DT_WORD;       break;
4066      case 0x08: ret->addr = &LC;  ret->data_type = DT_WORD;       break;
4067      case 0x09: ret->addr = &SR;  ret->data_type = DT_WORD;       break;
4068      case 0x0a: ret->addr = &OMR; ret->data_type = DT_BYTE;       break;
4069      case 0x0b: ret->addr = &SP;  ret->data_type = DT_BYTE;       break;
4070      case 0x0c: ret->addr = &A1;  ret->data_type = DT_WORD;       break;
4071      case 0x0d: ret->addr = &B1;  ret->data_type = DT_WORD;       break;
4072      case 0x0e: ret->addr = &A2;  ret->data_type = DT_BYTE;       break;
4073      case 0x0f: ret->addr = &B2;  ret->data_type = DT_BYTE;       break;
4074
4075      case 0x10: ret->addr = &R0;  ret->data_type = DT_WORD;       break;
4076      case 0x11: ret->addr = &R1;  ret->data_type = DT_WORD;       break;
4077      case 0x12: ret->addr = &R2;  ret->data_type = DT_WORD;       break;
4078      case 0x13: ret->addr = &R3;  ret->data_type = DT_WORD;       break;
4079      case 0x14: ret->addr = &M0;  ret->data_type = DT_WORD;       break;
4080      case 0x15: ret->addr = &M1;  ret->data_type = DT_WORD;       break;
4081      case 0x16: ret->addr = &M2;  ret->data_type = DT_WORD;       break;
4082      case 0x17: ret->addr = &M3;  ret->data_type = DT_WORD;       break;
4083      case 0x18: ret->addr = &SSH; ret->data_type = DT_WORD;       break;
4084      case 0x19: ret->addr = &SSL; ret->data_type = DT_WORD;       break;
4085      case 0x1a: ret->addr = &LA;  ret->data_type = DT_WORD;       break;
4086      /*no 0x1b  */
4087      case 0x1c: ret->addr = &N0;  ret->data_type = DT_WORD;       break;
4088      case 0x1d: ret->addr = &N1;  ret->data_type = DT_WORD;       break;
4089      case 0x1e: ret->addr = &N2;  ret->data_type = DT_WORD;       break;
4090      case 0x1f: ret->addr = &N3;  ret->data_type = DT_WORD;       break;
4091   }
4092}
4093
4094static void decode_DD_table(dsp56k_core* cpustate, UINT16 DD, typed_pointer* ret)
4095{
4096   switch(DD)
4097   {
4098      case 0x00: ret->addr = &X0;  ret->data_type = DT_WORD;  break;
4099      case 0x01: ret->addr = &Y0;  ret->data_type = DT_WORD;  break;
4100      case 0x02: ret->addr = &X1;  ret->data_type = DT_WORD;  break;
4101      case 0x03: ret->addr = &Y1;  ret->data_type = DT_WORD;  break;
4102   }
4103}
4104
4105static void decode_DDF_table(dsp56k_core* cpustate, UINT16 DD, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4106{
4107   UINT16 switchVal = (DD << 1) | F;
4108
4109   switch (switchVal)
4110   {
4111      case 0x0: src_ret->addr = &X0;  src_ret->data_type = DT_WORD; dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4112      case 0x1: src_ret->addr = &X0;  src_ret->data_type = DT_WORD; dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4113      case 0x2: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD; dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4114      case 0x3: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD; dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4115      case 0x4: src_ret->addr = &X1;  src_ret->data_type = DT_WORD; dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4116      case 0x5: src_ret->addr = &X1;  src_ret->data_type = DT_WORD; dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4117      case 0x6: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD; dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4118      case 0x7: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD; dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4119   }
4120}
4121
4122static void decode_F_table(dsp56k_core* cpustate, UINT16 F, typed_pointer* ret)
4123{
4124   switch(F)
4125   {
4126      case 0x0: ret->addr = &A;  ret->data_type = DT_LONG_WORD;  break;
4127      case 0x1: ret->addr = &B;  ret->data_type = DT_LONG_WORD;  break;
4128   }
4129}
4130
4131static void decode_h0hF_table(dsp56k_core* cpustate, UINT16 h0h, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4132{
4133   UINT16 switchVal = (h0h << 1) | F ;
4134
4135   switch (switchVal)
4136   {
4137      case 0x8: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;       dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4138      case 0x9: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;       dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4139      case 0xa: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;       dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4140      case 0xb: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;       dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4141      case 0x2: src_ret->addr = &A;   src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4142      case 0x1: src_ret->addr = &A;   src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4143      case 0x0: src_ret->addr = &B;   src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4144      case 0x3: src_ret->addr = &B;   src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4145   }
4146}
4147
4148static void decode_HH_table(dsp56k_core* cpustate, UINT16 HH, typed_pointer* ret)
4149{
4150   switch(HH)
4151   {
4152      case 0x0: ret->addr = &X0;  ret->data_type = DT_WORD;       break;
4153      case 0x1: ret->addr = &Y0;  ret->data_type = DT_WORD;       break;
4154      case 0x2: ret->addr = &A;   ret->data_type = DT_LONG_WORD;  break;
4155      case 0x3: ret->addr = &B;   ret->data_type = DT_LONG_WORD;  break;
4156   }
4157}
4158
4159static void decode_HHH_table(dsp56k_core* cpustate, UINT16 HHH, typed_pointer* ret)
4160{
4161   switch(HHH)
4162   {
4163      case 0x0: ret->addr = &X0;  ret->data_type = DT_WORD;       break;
4164      case 0x1: ret->addr = &Y0;  ret->data_type = DT_WORD;       break;
4165      case 0x2: ret->addr = &X1;  ret->data_type = DT_WORD;       break;
4166      case 0x3: ret->addr = &Y1;  ret->data_type = DT_WORD;       break;
4167      case 0x4: ret->addr = &A;   ret->data_type = DT_LONG_WORD;  break;
4168      case 0x5: ret->addr = &B;   ret->data_type = DT_LONG_WORD;  break;
4169      case 0x6: ret->addr = &A0;  ret->data_type = DT_WORD;       break;
4170      case 0x7: ret->addr = &B0;  ret->data_type = DT_WORD;       break;
4171   }
4172}
4173
4174static void decode_IIII_table(dsp56k_core* cpustate, UINT16 IIII, typed_pointer* src_ret, typed_pointer* dst_ret, void *working)
4175{
4176   void *opposite = 0x00 ;
4177
4178   if (working == &A) opposite = &B ;
4179   else               opposite = &A ;
4180
4181   switch(IIII)
4182   {
4183      case 0x0: src_ret->addr = &X0;      src_ret->data_type = DT_WORD;       dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4184      case 0x1: src_ret->addr = &Y0;      src_ret->data_type = DT_WORD;       dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4185      case 0x2: src_ret->addr = &X1;      src_ret->data_type = DT_WORD;       dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4186      case 0x3: src_ret->addr = &Y1;      src_ret->data_type = DT_WORD;       dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4187      case 0x4: src_ret->addr = &A;       src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &X0;       dst_ret->data_type = DT_WORD;       break;
4188      case 0x5: src_ret->addr = &B;       src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &Y0;       dst_ret->data_type = DT_WORD;       break;
4189      case 0x6: src_ret->addr = &A0;      src_ret->data_type = DT_WORD;       dst_ret->addr = &X0;       dst_ret->data_type = DT_WORD;       break;
4190      case 0x7: src_ret->addr = &B0;      src_ret->data_type = DT_WORD;       dst_ret->addr = &Y0;       dst_ret->data_type = DT_WORD;       break;
4191      case 0x8: src_ret->addr = working;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4192      case 0x9: src_ret->addr = working;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4193      case 0xc: src_ret->addr = &A;       src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &X1;       dst_ret->data_type = DT_WORD;       break;
4194      case 0xd: src_ret->addr = &B;       src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &Y1;       dst_ret->data_type = DT_WORD;       break;
4195      case 0xe: src_ret->addr = &A0;      src_ret->data_type = DT_WORD;       dst_ret->addr = &X1;       dst_ret->data_type = DT_WORD;       break;
4196      case 0xf: src_ret->addr = &B0;      src_ret->data_type = DT_WORD;       dst_ret->addr = &Y1;       dst_ret->data_type = DT_WORD;       break;
4197   }
4198}
4199
4200static void decode_JJJF_table(dsp56k_core* cpustate, UINT16 JJJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4201{
4202   UINT16 switchVal = (JJJ << 1) | F ;
4203
4204   switch(switchVal)
4205   {
4206      case 0x0: src_ret->addr = &B;   src_ret->data_type = DT_LONG_WORD;    dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4207      case 0x1: src_ret->addr = &A;   src_ret->data_type = DT_LONG_WORD;    dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4208      case 0x4: src_ret->addr = &X;   src_ret->data_type = DT_DOUBLE_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4209      case 0x5: src_ret->addr = &X;   src_ret->data_type = DT_DOUBLE_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4210      case 0x6: src_ret->addr = &Y;   src_ret->data_type = DT_DOUBLE_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4211      case 0x7: src_ret->addr = &Y;   src_ret->data_type = DT_DOUBLE_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4212      case 0x8: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;         dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4213      case 0x9: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;         dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4214      case 0xa: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;         dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4215      case 0xb: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;         dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4216      case 0xc: src_ret->addr = &X1;  src_ret->data_type = DT_WORD;         dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4217      case 0xd: src_ret->addr = &X1;  src_ret->data_type = DT_WORD;         dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4218      case 0xe: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD;         dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4219      case 0xf: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD;         dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4220   }
4221}
4222
4223static void decode_JJF_table(dsp56k_core* cpustate, UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4224{
4225   UINT16 switchVal = (JJ << 1) | F ;
4226
4227   switch (switchVal)
4228   {
4229      case 0x0: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4230      case 0x1: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4231      case 0x2: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4232      case 0x3: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4233      case 0x4: src_ret->addr = &X1;  src_ret->data_type = DT_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4234      case 0x5: src_ret->addr = &X1;  src_ret->data_type = DT_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4235      case 0x6: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4236      case 0x7: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4237   }
4238}
4239
4240static void decode_JF_table(dsp56k_core* cpustate, UINT16 J, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4241{
4242   UINT16 switchVal = (J << 1) | F ;
4243
4244   switch (switchVal)
4245   {
4246      case 0x0: src_ret->addr = &A;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &X;  dst_ret->data_type = DT_DOUBLE_WORD;  break;
4247      case 0x1: src_ret->addr = &B;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &X;  dst_ret->data_type = DT_DOUBLE_WORD;  break;
4248      case 0x2: src_ret->addr = &A;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &Y;  dst_ret->data_type = DT_DOUBLE_WORD;  break;
4249      case 0x3: src_ret->addr = &B;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &Y;  dst_ret->data_type = DT_DOUBLE_WORD;  break;
4250   }
4251}
4252
4253static void decode_KKK_table(dsp56k_core* cpustate, UINT16 KKK, typed_pointer* dst_ret1, typed_pointer* dst_ret2, void* working)
4254{
4255   void *opposite = 0x00 ;
4256
4257   if (working == &A) opposite = &B ;
4258   else               opposite = &A ;
4259
4260   switch(KKK)
4261   {
4262      case 0x0: dst_ret1->addr = opposite;  dst_ret1->data_type = DT_LONG_WORD;  dst_ret2->addr = &X0;  dst_ret2->data_type = DT_WORD;  break;
4263      case 0x1: dst_ret1->addr = &Y0;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X0;  dst_ret2->data_type = DT_WORD;  break;
4264      case 0x2: dst_ret1->addr = &X1;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X0;  dst_ret2->data_type = DT_WORD;  break;
4265      case 0x3: dst_ret1->addr = &Y1;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X0;  dst_ret2->data_type = DT_WORD;  break;
4266      case 0x4: dst_ret1->addr = &X0;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X1;  dst_ret2->data_type = DT_WORD;  break;
4267      case 0x5: dst_ret1->addr = &Y0;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X1;  dst_ret2->data_type = DT_WORD;  break;
4268      case 0x6: dst_ret1->addr = opposite;  dst_ret1->data_type = DT_LONG_WORD;  dst_ret2->addr = &Y0;  dst_ret2->data_type = DT_WORD;  break;
4269      case 0x7: dst_ret1->addr = &Y1;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X1;  dst_ret2->data_type = DT_WORD;  break;
4270   }
4271}
4272
4273static void decode_QQF_table(dsp56k_core* cpustate, UINT16 QQ, UINT16 F, void **S1, void **S2, void **D)
4274{
4275   UINT16 switchVal = (QQ << 1) | F ;
4276
4277   switch(switchVal)
4278   {
4279      case 0x0: *S1 = &X0;  *S2 = &Y0;  *D = &A;  break;
4280      case 0x1: *S1 = &X0;  *S2 = &Y0;  *D = &B;  break;
4281      case 0x2: *S1 = &X0;  *S2 = &Y1;  *D = &A;  break;
4282      case 0x3: *S1 = &X0;  *S2 = &Y1;  *D = &B;  break;
4283      case 0x4: *S1 = &X1;  *S2 = &Y0;  *D = &A;  break;
4284      case 0x5: *S1 = &X1;  *S2 = &Y0;  *D = &B;  break;
4285      case 0x6: *S1 = &X1;  *S2 = &Y1;  *D = &A;  break;
4286      case 0x7: *S1 = &X1;  *S2 = &Y1;  *D = &B;  break;
4287   }
4288}
4289
4290static void decode_QQF_special_table(dsp56k_core* cpustate, UINT16 QQ, UINT16 F, void **S1, void **S2, void **D)
4291{
4292   UINT16 switchVal = (QQ << 1) | F ;
4293
4294   switch(switchVal)
4295   {
4296      case 0x0: *S1 = &Y0;  *S2 = &X0;  *D = &A;  break;
4297      case 0x1: *S1 = &Y0;  *S2 = &X0;  *D = &B;  break;
4298      case 0x2: *S1 = &Y1;  *S2 = &X0;  *D = &A;  break;
4299      case 0x3: *S1 = &Y1;  *S2 = &X0;  *D = &B;  break;
4300      case 0x4: *S1 = &X1;  *S2 = &Y0;  *D = &A;  break;
4301      case 0x5: *S1 = &X1;  *S2 = &Y0;  *D = &B;  break;
4302      case 0x6: *S1 = &X1;  *S2 = &Y1;  *D = &A;  break;
4303      case 0x7: *S1 = &X1;  *S2 = &Y1;  *D = &B;  break;
4304   }
4305}
4306
4307static void decode_QQQF_table(dsp56k_core* cpustate, UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D)
4308{
4309   UINT16 switchVal = (QQQ << 1) | F;
4310
4311   switch(switchVal)
4312   {
4313      case 0x0: *S1 = &X0;  *S2 = &X0;  *D = &A;  break;
4314      case 0x1: *S1 = &X0;  *S2 = &X0;  *D = &B;  break;
4315      case 0x2: *S1 = &X1;  *S2 = &X0;  *D = &A;  break;
4316      case 0x3: *S1 = &X1;  *S2 = &X0;  *D = &B;  break;
4317      case 0x4: *S1 = &A1;  *S2 = &Y0;  *D = &A;  break;
4318      case 0x5: *S1 = &A1;  *S2 = &Y0;  *D = &B;  break;
4319      case 0x6: *S1 = &B1;  *S2 = &X0;  *D = &A;  break;
4320      case 0x7: *S1 = &B1;  *S2 = &X0;  *D = &B;  break;
4321      case 0x8: *S1 = &Y0;  *S2 = &X0;  *D = &A;  break;
4322      case 0x9: *S1 = &Y0;  *S2 = &X0;  *D = &B;  break;
4323      case 0xa: *S1 = &Y1;  *S2 = &X0;  *D = &A;  break;
4324      case 0xb: *S1 = &Y1;  *S2 = &X0;  *D = &B;  break;
4325      case 0xc: *S1 = &Y0;  *S2 = &X1;  *D = &A;  break;
4326      case 0xd: *S1 = &Y0;  *S2 = &X1;  *D = &B;  break;
4327      case 0xe: *S1 = &Y1;  *S2 = &X1;  *D = &A;  break;
4328      case 0xf: *S1 = &Y1;  *S2 = &X1;  *D = &B;  break;
4329   }
4330}
4331
4332static void decode_RR_table(dsp56k_core* cpustate, UINT16 RR, typed_pointer* ret)
4333{
4334   switch(RR)
4335   {
4336      case 0x00: ret->addr = &R0;  ret->data_type = DT_WORD;  break;
4337      case 0x01: ret->addr = &R1;  ret->data_type = DT_WORD;  break;
4338      case 0x02: ret->addr = &R2;  ret->data_type = DT_WORD;  break;
4339      case 0x03: ret->addr = &R3;  ret->data_type = DT_WORD;  break;
4340   }
4341}
4342
4343static void decode_TT_table(dsp56k_core* cpustate, UINT16 TT, typed_pointer* ret)
4344{
4345   switch(TT)
4346   {
4347      case 0x00: ret->addr = &R0;  ret->data_type = DT_WORD;  break;
4348      case 0x01: ret->addr = &R1;  ret->data_type = DT_WORD;  break;
4349      case 0x02: ret->addr = &R2;  ret->data_type = DT_WORD;  break;
4350      case 0x03: ret->addr = &R3;  ret->data_type = DT_WORD;  break;
4351   }
4352}
4353
4354
4355static void decode_uuuuF_table(dsp56k_core* cpustate, UINT16 uuuu, UINT16 F, UINT8 add_sub_other, typed_pointer* src_ret, typed_pointer* dst_ret)
4356{
4357   UINT16 switchVal = (uuuu << 1) | F;
4358
4359   /* Unknown uuuuFs have been seen in the wild */
4360   add_sub_other = OP_OTHER;
4361   src_ret->addr = NULL; src_ret->data_type = DT_BYTE;
4362   dst_ret->addr = NULL; dst_ret->data_type = DT_BYTE;
4363
4364   switch(switchVal)
4365   {
4366      case 0x00: add_sub_other = OP_ADD;
4367               src_ret->addr = &X0; src_ret->data_type = DT_WORD;
4368               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4369      case 0x08: add_sub_other = OP_SUB;
4370               src_ret->addr = &X0; src_ret->data_type = DT_WORD;
4371               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4372      case 0x01: add_sub_other = OP_ADD;
4373               src_ret->addr = &X0; src_ret->data_type = DT_WORD;
4374               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4375      case 0x09: add_sub_other = OP_SUB;
4376               src_ret->addr = &X0; src_ret->data_type = DT_WORD;
4377               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4378      case 0x02: add_sub_other = OP_ADD;
4379               src_ret->addr = &Y0; src_ret->data_type = DT_WORD;
4380               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4381      case 0x0a: add_sub_other = OP_SUB;
4382               src_ret->addr = &Y0; src_ret->data_type = DT_WORD;
4383               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4384      case 0x03: add_sub_other = OP_ADD;
4385               src_ret->addr = &Y0; src_ret->data_type = DT_WORD;
4386               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4387      case 0x0b: add_sub_other = OP_SUB;
4388               src_ret->addr = &Y0; src_ret->data_type = DT_WORD;
4389               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4390      case 0x04: add_sub_other = OP_ADD;
4391               src_ret->addr = &X1; src_ret->data_type = DT_WORD;
4392               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4393      case 0x0c: add_sub_other = OP_SUB;
4394               src_ret->addr = &X1; src_ret->data_type = DT_WORD;
4395               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4396      case 0x05: add_sub_other = OP_ADD;
4397               src_ret->addr = &X1; src_ret->data_type = DT_WORD;
4398               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4399      case 0x0d: add_sub_other = OP_SUB;
4400               src_ret->addr = &X1; src_ret->data_type = DT_WORD;
4401               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4402      case 0x06: add_sub_other = OP_ADD;
4403               src_ret->addr = &Y1; src_ret->data_type = DT_WORD;
4404               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4405      case 0x0e: add_sub_other = OP_SUB;
4406               src_ret->addr = &Y1; src_ret->data_type = DT_WORD;
4407               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4408      case 0x07: add_sub_other = OP_ADD;
4409               src_ret->addr = &Y1; src_ret->data_type = DT_WORD;
4410               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4411      case 0x0f: add_sub_other = OP_SUB;
4412               src_ret->addr = &Y1; src_ret->data_type = DT_WORD;
4413               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4414      case 0x18: add_sub_other = OP_ADD;
4415               src_ret->addr = &B;  src_ret->data_type = DT_LONG_WORD;
4416               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4417      case 0x1a: add_sub_other = OP_SUB;
4418               src_ret->addr = &B;  src_ret->data_type = DT_LONG_WORD;
4419               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4420      case 0x19: add_sub_other = OP_ADD;
4421               src_ret->addr = &A;  src_ret->data_type = DT_LONG_WORD;
4422               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4423      case 0x1b: add_sub_other = OP_SUB;
4424               src_ret->addr = &A;  src_ret->data_type = DT_LONG_WORD;
4425               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4426   }
4427}
4428
4429static void decode_Z_table(dsp56k_core* cpustate, UINT16 Z, typed_pointer* ret)
4430{
4431   switch(Z)
4432   {
4433      /* Fixed as per the Family Manual addendum */
4434      case 0x01: ret->addr = &A1;  ret->data_type = DT_WORD;  break;
4435      case 0x00: ret->addr = &B1;  ret->data_type = DT_WORD;  break;
4436   }
4437}
4438
4439static void execute_m_table(dsp56k_core* cpustate, int x, UINT16 m)
4440{
4441   UINT16 *rX = 0x00 ;
4442   UINT16 *nX = 0x00 ;
4443
4444   switch(x)
4445   {
4446      case 0x0: rX = &R0;  nX = &N0; break;
4447      case 0x1: rX = &R1;  nX = &N1; break;
4448      case 0x2: rX = &R2;  nX = &N2; break;
4449      case 0x3: rX = &R3;  nX = &N3; break;
4450   }
4451
4452   switch(m)
4453   {
4454      case 0x0: (*rX)++;             break;
4455      case 0x1: (*rX) = (*rX)+(*nX); break;
4456   }
4457}
4458
4459static void execute_mm_table(dsp56k_core* cpustate, UINT16 rnum, UINT16 mm)
4460{
4461   UINT16 *rX = NULL;
4462   UINT16 *nX = NULL;
4463
4464   switch(rnum)
4465   {
4466      case 0x0: rX = &R0;  nX = &N0;  break;
4467      case 0x1: rX = &R1;  nX = &N1;  break;
4468      case 0x2: rX = &R2;  nX = &N2;  break;
4469      case 0x3: fatalerror("Dsp56k: Error. execute_mm_table specified R3 as its first source!\n");  break;
4470   }
4471
4472   switch(mm)
4473   {
4474      case 0x0: (*rX)++;                  R3++;           break;
4475      case 0x1: (*rX)++;                  R3 = R3 + N3;   break;
4476      case 0x2: (*rX) = (*rX) + (*nX);    R3++;           break;
4477      case 0x3: (*rX) = (*rX) + (*nX);    R3 = R3 + N3;   break;
4478   }
4479}
4480
4481static void execute_MM_table(dsp56k_core* cpustate, UINT16 rnum, UINT16 MM)
4482{
4483   UINT16 *rX = 0x00 ;
4484   UINT16 *nX = 0x00 ;
4485
4486   switch(rnum)
4487   {
4488      case 0x0: rX = &R0;  nX = &N0;  break;
4489      case 0x1: rX = &R1;  nX = &N1;  break;
4490      case 0x2: rX = &R2;  nX = &N2;  break;
4491      case 0x3: rX = &R3;  nX = &N3;  break;
4492   }
4493
4494   switch(MM)
4495   {
4496      case 0x0: /* do nothing */      break;
4497      case 0x1: (*rX)++ ;             break;
4498      case 0x2: (*rX)-- ;             break;
4499      case 0x3: (*rX) = (*rX)+(*nX) ; break;
4500   }
4501}
4502
4503/* Returns R value */
4504static UINT16 execute_q_table(dsp56k_core* cpustate, int RR, UINT16 q)
4505{
4506   UINT16 *rX = 0x0000;
4507   UINT16 *nX = 0x0000;
4508
4509   switch(RR)
4510   {
4511      case 0x0: rX = &R0;  nX = &N0;  break;
4512      case 0x1: rX = &R1;  nX = &N1;  break;
4513      case 0x2: rX = &R2;  nX = &N2;  break;
4514      case 0x3: rX = &R3;  nX = &N3;  break;
4515   }
4516
4517   switch(q)
4518   {
4519      case 0x0: /* No permanent changes */ ; return (*rX)+(*nX);
4520      case 0x1: (*rX)--;                     return (*rX);    /* This one is special - it's a *PRE-decrement*! */
4521   }
4522
4523   /* Should not get here */
4524   fatalerror("dsp56k: execute_q_table did something impossible!\n");
4525   return 0;
4526}
4527
4528static void execute_z_table(dsp56k_core* cpustate, int RR, UINT16 z)
4529{
4530   UINT16 *rX = 0x00;
4531   UINT16 *nX = 0x00;
4532
4533   switch(RR)
4534   {
4535      case 0x0: rX = &R0;  nX = &N0;  break;
4536      case 0x1: rX = &R1;  nX = &N1;  break;
4537      case 0x2: rX = &R2;  nX = &N2;  break;
4538      case 0x3: rX = &R3;  nX = &N3;  break;
4539   }
4540
4541   switch(z)
4542   {
4543      case 0x0: (*rX)--;               break;
4544      case 0x1: (*rX) = (*rX) + (*nX); break;
4545   }
4546}
4547
4548static UINT16 assemble_address_from_Pppppp_table(dsp56k_core* cpustate, UINT16 P, UINT16 ppppp)
4549{
4550   UINT16 destAddr = 0x00 ;
4551
4552   switch (P)
4553   {
4554      case 0x0: destAddr = ppppp;  break;     /* TODO:  Does this really only address up to 0x32? */
4555      case 0x1: destAddr = assemble_address_from_IO_short_address(cpustate, ppppp);  break;
4556   }
4557
4558   return destAddr ;
4559}
4560
4561static UINT16 assemble_address_from_IO_short_address(dsp56k_core* cpustate, UINT16 pp)
4562{
4563   UINT16 fullAddy = 0xffe0;
4564   fullAddy |= pp;
4565   return fullAddy;
4566}
4567
4568static UINT16 assemble_address_from_6bit_signed_relative_short_address(dsp56k_core* cpustate, UINT16 srs)
4569{
4570   UINT16 fullAddy = srs ;
4571   if (fullAddy & 0x0020)
4572      fullAddy |= 0xffc0 ;
4573
4574   return fullAddy ;
4575}
4576
4577static void dsp56k_process_loop(dsp56k_core* cpustate)
4578{
4579   /* TODO: This might not work for dos nested in doForevers */
4580   if (LF_bit(cpustate) && FV_bit(cpustate))
4581   {
4582      /* Do Forever*/
4583      if (PC == LA)
4584      {
4585         LC--;
4586
4587         cpustate->ppc = PC;
4588         PC = SSH;
4589      }
4590   }
4591   else if (LF_bit(cpustate))
4592   {
4593      /* Do */
4594      if (PC == LA)
4595      {
4596         if (LC == 1)
4597         {
4598            /* End of loop processing */
4599            SR = SSL;   /* TODO: A-83.  I believe only the Loop Flag comes back here.  And maybe the do forever bit too. */
4600            SP--;
4601
4602            LA = SSH;
4603            LC = SSL;
4604            SP--;
4605         }
4606         else
4607         {
4608            LC--;
4609            PC = SSH;
4610         }
4611      }
4612   }
4613}
4614
4615static void dsp56k_process_rep(dsp56k_core* cpustate, size_t repSize)
4616{
4617   if (cpustate->repFlag)
4618   {
4619      if (PC == cpustate->repAddr)
4620      {
4621         if (LC == 1)
4622         {
4623            /* End of rep processing */
4624            LC = TEMP;
4625            cpustate->repFlag = 0;
4626            cpustate->repAddr = 0x0000;
4627         }
4628         else
4629         {
4630            LC--;
4631            PC -= repSize;      /* A little strange - rewind by the size of the rep'd op */
4632         }
4633      }
4634   }
4635}
4636
4637
4638/***************************************************************************
4639    Parallel Memory Ops
4640***************************************************************************/
4641/* Register to Register Data Move : 0100 IIII .... .... : A-132 */
4642static void execute_register_to_register_data_move(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value)
4643{
4644   typed_pointer S = {NULL, DT_BYTE};
4645   typed_pointer D = {NULL, DT_BYTE};
4646
4647   decode_IIII_table(cpustate, BITS(op,0x0f00), &S, &D, d_register->addr);
4648
4649   /* If the source is the same as the ALU destination, use the previous accumulator value */
4650   if (d_register->addr == S.addr)
4651   {
4652      typed_pointer tempTP;
4653      tempTP.addr = prev_accum_value;
4654      tempTP.data_type = DT_LONG_WORD;
4655      SetDestinationValue(tempTP, D);
4656   }
4657   else
4658   {
4659      SetDestinationValue(S, D);
4660   }
4661}
4662
4663/* Address Register Update : 0011 0zRR .... .... : A-135 */
4664static void execute_address_register_update(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value)
4665{
4666   execute_z_table(cpustate, BITS(op,0x0300), BITS(op,0x0400));
4667}
4668
4669/* X Memory Data Move : 1mRR HHHW .... .... : A-137 */
4670static void execute_x_memory_data_move(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value)
4671{
4672   UINT16 W;
4673   typed_pointer R = {NULL, DT_BYTE};
4674   typed_pointer SD = {NULL, DT_BYTE};
4675
4676   W = BITS(op,0x0100);
4677   decode_HHH_table(cpustate, BITS(op,0x0e00), &SD);
4678   decode_RR_table(cpustate, BITS(op,0x3000),&R);
4679
4680   if (W)
4681   {
4682      /* From X:<ea> to SD */
4683      UINT16 data = cpustate->data->read_word(ADDRESS(*((UINT16*)R.addr)));
4684
4685      typed_pointer tempTP;
4686      tempTP.addr = &data;
4687      tempTP.data_type = DT_WORD;
4688
4689      SetDestinationValue(tempTP, SD);
4690   }
4691   else
4692   {
4693      /* From SD to X:<ea> */
4694      /* If the source is the same as the ALU destination, use the previous accumulator value */
4695      if (d_register->addr == SD.addr)
4696      {
4697         typed_pointer tempTP;
4698         tempTP.addr = prev_accum_value;
4699         tempTP.data_type = DT_LONG_WORD;
4700
4701         SetDataMemoryValue(cpustate, tempTP, ADDRESS(*((UINT16*)R.addr))) ;
4702      }
4703      else
4704      {
4705         SetDataMemoryValue(cpustate, SD, ADDRESS(*((UINT16*)R.addr))) ;
4706      }
4707   }
4708
4709   execute_m_table(cpustate, BITS(op,0x3000), BITS(op,0x4000));
4710}
4711
4712/* X Memory Data Move : 0101 HHHW .... .... : A-137 */
4713/* NOTE: previous accumulator value is not needed since ^F1 is always the opposite accumulator */
4714static void execute_x_memory_data_move2(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register)
4715{
4716   UINT16 W;
4717   UINT16* mem_offset = NULL;
4718   typed_pointer SD = {NULL, DT_BYTE};
4719
4720   W = BITS(op,0x0100);
4721   decode_HHH_table(cpustate, BITS(op,0x0e000), &SD);
4722
4723   if (d_register->addr == &A)
4724      mem_offset = &B1;
4725   else
4726      mem_offset = &A1;
4727
4728   if (W)
4729   {
4730      /* Write D */
4731      UINT16 value = cpustate->data->read_word(ADDRESS(*mem_offset));
4732      typed_pointer tempV = {&value, DT_WORD};
4733      SetDestinationValue(tempV, SD);
4734   }
4735   else
4736   {
4737      /* Read S */
4738      SetDataMemoryValue(cpustate, SD, ADDRESS(*mem_offset));
4739   }
4740}
4741
4742/* X Memory Data Move With Short Displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */
4743static void execute_x_memory_data_move_with_short_displacement(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2)
4744{
4745   INT8 xx;
4746   UINT8 W;
4747   UINT16 memOffset;
4748   typed_pointer SD = { NULL, DT_BYTE };
4749
4750   xx = (INT8)(op & 0x00ff);
4751   W = BITS(op2,0x0100);
4752   decode_HHH_table(cpustate, BITS(op2,0x0e00), &SD);
4753
4754   memOffset = R2 + (INT16)xx;
4755
4756   if (W)
4757   {
4758      /* Write D */
4759      UINT16 tempData = cpustate->data->read_word(ADDRESS(memOffset));
4760      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
4761      SetDestinationValue(temp_src, SD);
4762   }
4763   else
4764   {
4765      /* Read S */
4766      UINT16 tempData = *((UINT16*)SD.addr);
4767      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
4768      SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset));
4769   }
4770}
4771
4772/* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/
4773static void execute_dual_x_memory_data_read(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register)
4774{
4775   typed_pointer tempV;
4776   UINT16 srcVal1 = 0x0000;
4777   UINT16 srcVal2 = 0x0000;
4778   typed_pointer R = {NULL, DT_BYTE};
4779   typed_pointer D1 = {NULL, DT_BYTE};
4780   typed_pointer D2 = {NULL, DT_BYTE};
4781
4782   decode_RR_table(cpustate, BITS(op,0x0060), &R);
4783   decode_KKK_table(cpustate, BITS(op,0x0700), &D1, &D2, d_register->addr);
4784
4785   /* Can't do an R3 for S1 */
4786   if (R.addr == &R3)
4787      fatalerror("Dsp56k: Error. Dual x memory data read specified R3 as its first source!\n");
4788
4789   /* The note on A-142 is very interesting.
4790      You can effectively access external memory in the last 64 bytes of X data memory! */
4791   if (*((UINT16*)D2.addr) >= 0xffc0)
4792      fatalerror("Dsp56k: Unimplemented access to external X Data Memory >= 0xffc0 in Dual X Memory Data Read.\n");
4793
4794   /* First memmove */
4795   srcVal1 = cpustate->data->read_word(ADDRESS(*((UINT16*)R.addr)));
4796   tempV.addr = &srcVal1;
4797   tempV.data_type = DT_WORD;
4798   SetDestinationValue(tempV, D1);
4799
4800   /* Second memmove */
4801   srcVal2 = cpustate->data->read_word(ADDRESS(R3));
4802   tempV.addr = &srcVal2;
4803   tempV.data_type = DT_WORD;
4804   SetDestinationValue(tempV, D2);
4805
4806   /* Touch up the R regs after all the moves */
4807   execute_mm_table(cpustate, BITS(op,0x0060), BITS(op,0x1800));
4808}
4809
4810/***************************************************************************
4811    Helper Functions
4812***************************************************************************/
4813static UINT16 Dsp56kOpMask(UINT16 cur, UINT16 mask)
4814{
4815   int i ;
4816
4817   UINT16 retVal = (cur & mask) ;
4818   UINT16 temp = 0x0000 ;
4819   int offsetCount = 0 ;
4820
4821   /* Shift everything right, eliminating 'whitespace' */
4822   for (i = 0; i < 16; i++)
4823   {
4824      if (mask & (0x1<<i))        /* If mask bit is non-zero */
4825      {
4826         temp |= (((retVal >> i) & 0x1) << offsetCount) ;
4827         offsetCount++ ;
4828      }
4829   }
4830
4831   return temp ;
4832}
4833
4834static void SetDestinationValue(typed_pointer source, typed_pointer dest)
4835{
4836   UINT64 destinationValue = 0 ;
4837
4838   switch(dest.data_type)
4839   {
4840      /* Copying to an 8-bit value */
4841      case DT_BYTE:
4842         switch(source.data_type)
4843         {
4844            /* From a ? */
4845            case DT_BYTE:        *((UINT8*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break;
4846            case DT_WORD:        *((UINT8*)dest.addr) = (*((UINT16*)source.addr)) & 0x00ff; break;
4847            case DT_DOUBLE_WORD: *((UINT8*)dest.addr) = (*((UINT32*)source.addr)) & 0x000000ff; break;
4848            case DT_LONG_WORD:   *((UINT8*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x00000000000000ff); break;
4849         }
4850      break ;
4851
4852      /* Copying to a 16-bit value */
4853      case DT_WORD:
4854         switch(source.data_type)
4855         {
4856            case DT_BYTE:        *((UINT16*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break;
4857            case DT_WORD:        *((UINT16*)dest.addr) = (*((UINT16*)source.addr)) & 0xffff; break;
4858            case DT_DOUBLE_WORD: *((UINT16*)dest.addr) = (*((UINT32*)source.addr)) & 0x0000ffff; break;
4859            case DT_LONG_WORD:   *((UINT16*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000000000ffff); break;    /* TODO: Shift limiter action! A-147 */
4860         }
4861      break ;
4862
4863      /* Copying to a 32-bit value */
4864      case DT_DOUBLE_WORD:
4865         switch(source.data_type)
4866         {
4867            case DT_BYTE:        *((UINT32*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break;
4868            case DT_WORD:        *((UINT32*)dest.addr) = (*((UINT16*)source.addr)) & 0xffff; break;
4869            case DT_DOUBLE_WORD: *((UINT32*)dest.addr) = (*((UINT32*)source.addr)) & 0xffffffff; break;
4870            case DT_LONG_WORD:   *((UINT32*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x00000000ffffffff); break;
4871         }
4872      break ;
4873
4874      /* Copying to a 64-bit value */
4875      case DT_LONG_WORD:
4876         switch(source.data_type)
4877         {
4878            case DT_BYTE:        *((UINT64*)dest.addr) = (*((UINT8*)source.addr)) & 0xff; break;
4879
4880            case DT_WORD:        destinationValue = (*((UINT16*)source.addr)) << 16;
4881                              if (destinationValue & U64(0x0000000080000000))
4882                                 destinationValue |= U64(0x000000ff00000000);
4883                              *((UINT64*)dest.addr) = (UINT64)destinationValue; break;    /* Forget not, yon shift register */
4884
4885            case DT_DOUBLE_WORD: *((UINT64*)dest.addr) = (*((UINT32*)source.addr)) & 0xffffffff; break;
4886            case DT_LONG_WORD:   *((UINT64*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000ffffffffff); break;
4887         }
4888      break ;
4889   }
4890}
4891
4892/* TODO: Wait-state timings! */
4893static void SetDataMemoryValue(dsp56k_core* cpustate, typed_pointer source, UINT32 destinationAddr)
4894{
4895   switch(source.data_type)
4896   {
4897      case DT_BYTE:        cpustate->data->write_word(destinationAddr, (UINT16)( (*((UINT8*) source.addr) & 0xff)               ) ) ; break ;
4898      case DT_WORD:        cpustate->data->write_word(destinationAddr, (UINT16)( (*((UINT16*)source.addr) & 0xffff)             ) ) ; break ;
4899      case DT_DOUBLE_WORD: cpustate->data->write_word(destinationAddr, (UINT16)( (*((UINT32*)source.addr) & 0x0000ffff)         ) ) ; break ;
4900
4901      /* !!! Is this universal ??? */
4902      /* !!! Forget not, yon shift-limiter !!! */
4903      case DT_LONG_WORD:   cpustate->data->write_word(destinationAddr, (UINT16)( ((*((UINT64*)source.addr)) & U64(0x00000000ffff0000)) >> 16) ) ; break ;
4904   }
4905}
4906
4907/* TODO: Wait-state timings! */
4908static void SetProgramMemoryValue(dsp56k_core* cpustate, typed_pointer source, UINT32 destinationAddr)
4909{
4910   switch(source.data_type)
4911   {
4912      case DT_BYTE:        cpustate->program->write_word(destinationAddr, (UINT16)( (*((UINT8*) source.addr) & 0xff)               ) ) ; break ;
4913      case DT_WORD:        cpustate->program->write_word(destinationAddr, (UINT16)( (*((UINT16*)source.addr) & 0xffff)             ) ) ; break ;
4914      case DT_DOUBLE_WORD: cpustate->program->write_word(destinationAddr, (UINT16)( (*((UINT32*)source.addr) & 0x0000ffff)         ) ) ; break ;
4915
4916      /* !!! Is this universal ??? */
4917      /* !!! Forget not, yon shift-limiter !!! */
4918      case DT_LONG_WORD:   cpustate->program->write_word(destinationAddr, (UINT16)( ((*((UINT64*)source.addr)) & U64(0x00000000ffff0000)) >> 16) ) ; break ;
4919   }
4920}
trunk/src/emu/cpu/dsp56k/dsp56ops.inc
r0r28739
1/***************************************************************************
2
3    dsp56ops.inc
4    Core implementation for the portable Motorola/Freescale DSP56k emulator.
5    Written by Andrew Gardner
6
7***************************************************************************/
8
9/* NOTES For register setting:
10   FM.3-4 : When A2 or B2 is read, the register contents occupy the low-order portion
11            (bits 7-0) of the word; the high-order portion (bits 16-8) is sign-extended. When A2 or B2
12            is written, the register receives the low-order portion of the word; the high-order portion is not used
13          : ...much more!
14          : ...shifter/limiter/overflow notes too.
15
16*/
17
18/*
19TODO:
20    - 0x01ee: should this move sign extend?  otherwise the test-against-minus means nothing.
21    - Restore only the proper bits upon loop termination!
22    - BFCLR has some errata in the docs that may need to be applied.
23*/
24
25/************************/
26/* Datatypes and macros */
27/************************/
28enum addSubOpType { OP_ADD,
29               OP_SUB,
30               OP_OTHER };
31
32enum dataType { DT_BYTE,
33            DT_WORD,
34            DT_DOUBLE_WORD,
35            DT_LONG_WORD };
36
37struct typed_pointer
38{
39   void* addr;
40   char  data_type;
41};
42
43//#define ADDRESS(X) (X<<1)
44#define BITS(CUR,MASK) (Dsp56kOpMask(CUR,MASK))
45
46/*********************/
47/* Opcode prototypes */
48/*********************/
49static size_t dsp56k_op_addsub_2 (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
50static size_t dsp56k_op_mac_1    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
51static size_t dsp56k_op_macr_1   (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
52static size_t dsp56k_op_move_1   (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
53static size_t dsp56k_op_mpy_1    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
54static size_t dsp56k_op_mpyr_1   (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
55static size_t dsp56k_op_tfr_2    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles);
56static size_t dsp56k_op_mpy_2    (dsp56k_core* cpustate, const UINT16 op_byte, UINT8* cycles);
57static size_t dsp56k_op_mac_2    (dsp56k_core* cpustate, const UINT16 op_byte, UINT8* cycles);
58static size_t dsp56k_op_clr      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
59static size_t dsp56k_op_add      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
60static size_t dsp56k_op_move     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
61static size_t dsp56k_op_tfr      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
62static size_t dsp56k_op_rnd      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
63static size_t dsp56k_op_tst      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
64static size_t dsp56k_op_inc      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
65static size_t dsp56k_op_inc24    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
66static size_t dsp56k_op_or       (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
67static size_t dsp56k_op_asr      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
68static size_t dsp56k_op_asl      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
69static size_t dsp56k_op_lsr      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
70static size_t dsp56k_op_lsl      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
71static size_t dsp56k_op_eor      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
72static size_t dsp56k_op_subl     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
73static size_t dsp56k_op_sub      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
74static size_t dsp56k_op_clr24    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
75static size_t dsp56k_op_sbc      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
76static size_t dsp56k_op_cmp      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
77static size_t dsp56k_op_neg      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
78static size_t dsp56k_op_not      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
79static size_t dsp56k_op_dec      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
80static size_t dsp56k_op_dec24    (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
81static size_t dsp56k_op_and      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
82static size_t dsp56k_op_abs      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
83static size_t dsp56k_op_ror      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
84static size_t dsp56k_op_rol      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
85static size_t dsp56k_op_cmpm     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
86static size_t dsp56k_op_mpy      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
87static size_t dsp56k_op_mpyr     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
88static size_t dsp56k_op_mac      (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
89static size_t dsp56k_op_macr     (dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
90static size_t dsp56k_op_adc      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
91static size_t dsp56k_op_andi     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
92static size_t dsp56k_op_asl4     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
93static size_t dsp56k_op_asr4     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
94static size_t dsp56k_op_asr16    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
95static size_t dsp56k_op_bfop     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
96static size_t dsp56k_op_bfop_1   (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
97static size_t dsp56k_op_bfop_2   (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
98static size_t dsp56k_op_bcc      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
99static size_t dsp56k_op_bcc_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
100static size_t dsp56k_op_bcc_2    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
101static size_t dsp56k_op_bra      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
102static size_t dsp56k_op_bra_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
103static size_t dsp56k_op_bra_2    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
104static size_t dsp56k_op_brkcc    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
105static size_t dsp56k_op_bscc     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
106static size_t dsp56k_op_bscc_1   (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
107static size_t dsp56k_op_bsr      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
108static size_t dsp56k_op_bsr_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
109static size_t dsp56k_op_chkaau   (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
110static size_t dsp56k_op_debug    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
111static size_t dsp56k_op_debugcc  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
112static size_t dsp56k_op_div      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
113static size_t dsp56k_op_dmac     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
114static size_t dsp56k_op_do       (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
115static size_t dsp56k_op_do_1     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
116static size_t dsp56k_op_do_2     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
117static size_t dsp56k_op_doforever(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
118static size_t dsp56k_op_enddo    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
119static size_t dsp56k_op_ext      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
120static size_t dsp56k_op_illegal  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
121static size_t dsp56k_op_imac     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
122static size_t dsp56k_op_impy     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
123static size_t dsp56k_op_jcc      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
124static size_t dsp56k_op_jcc_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
125static size_t dsp56k_op_jmp      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
126static size_t dsp56k_op_jmp_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
127static size_t dsp56k_op_jscc     (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
128static size_t dsp56k_op_jscc_1   (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
129static size_t dsp56k_op_jsr      (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
130static size_t dsp56k_op_jsr_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
131static size_t dsp56k_op_jsr_2    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
132static size_t dsp56k_op_lea      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
133static size_t dsp56k_op_lea_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
134static size_t dsp56k_op_macsuuu  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
135static size_t dsp56k_op_move_2   (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
136static size_t dsp56k_op_movec    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
137static size_t dsp56k_op_movec_1  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
138static size_t dsp56k_op_movec_2  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
139static size_t dsp56k_op_movec_3  (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
140static size_t dsp56k_op_movec_4  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
141static size_t dsp56k_op_movec_5  (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
142static size_t dsp56k_op_movei    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
143static size_t dsp56k_op_movem    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
144static size_t dsp56k_op_movem_1  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
145static size_t dsp56k_op_movem_2  (dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles);
146static size_t dsp56k_op_movep    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
147static size_t dsp56k_op_movep_1  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
148static size_t dsp56k_op_moves    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
149static size_t dsp56k_op_mpysuuu  (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
150static size_t dsp56k_op_negc     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
151static size_t dsp56k_op_nop      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
152static size_t dsp56k_op_norm     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
153static size_t dsp56k_op_ori      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
154static size_t dsp56k_op_rep      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
155static size_t dsp56k_op_rep_1    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
156static size_t dsp56k_op_rep_2    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
157static size_t dsp56k_op_repcc    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
158static size_t dsp56k_op_reset    (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
159static size_t dsp56k_op_rti      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
160static size_t dsp56k_op_rts      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
161static size_t dsp56k_op_stop     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
162static size_t dsp56k_op_swap     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
163static size_t dsp56k_op_swi      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
164static size_t dsp56k_op_tcc      (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
165static size_t dsp56k_op_tfr2     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
166static size_t dsp56k_op_tfr3     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
167static size_t dsp56k_op_tst2     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
168static size_t dsp56k_op_wait     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
169static size_t dsp56k_op_zero     (dsp56k_core* cpustate, const UINT16 op, UINT8* cycles);
170
171
172static void execute_register_to_register_data_move(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value);
173static void execute_address_register_update(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value);
174static void execute_x_memory_data_move (dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value);
175static void execute_x_memory_data_move2(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register);
176static void execute_dual_x_memory_data_read(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register);
177static void execute_x_memory_data_move_with_short_displacement(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2);
178
179static UINT16   decode_BBB_bitmask(dsp56k_core* cpustate, UINT16 BBB, UINT16 *iVal);
180static int      decode_cccc_table(dsp56k_core* cpustate, UINT16 cccc);
181static void     decode_DDDDD_table(dsp56k_core* cpustate, UINT16 DDDDD, typed_pointer* ret);
182static void     decode_DD_table(dsp56k_core* cpustate, UINT16 DD, typed_pointer* ret);
183static void     decode_DDF_table(dsp56k_core* cpustate, UINT16 DD, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
184static void     decode_F_table(dsp56k_core* cpustate, UINT16 F, typed_pointer* ret);
185static void     decode_h0hF_table(dsp56k_core* cpustate, UINT16 h0h, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
186static void     decode_HH_table(dsp56k_core* cpustate, UINT16 HH, typed_pointer* ret);
187static void     decode_HHH_table(dsp56k_core* cpustate, UINT16 HHH, typed_pointer* ret);
188static void     decode_IIII_table(dsp56k_core* cpustate, UINT16 IIII, typed_pointer* src_ret, typed_pointer* dst_ret, void* working);
189static void     decode_JJJF_table(dsp56k_core* cpustate, UINT16 JJJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
190static void     decode_JJF_table(dsp56k_core* cpustate, UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
191static void     decode_JF_table(dsp56k_core* cpustate, UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
192static void     decode_KKK_table(dsp56k_core* cpustate, UINT16 KKK, typed_pointer* dst_ret1, typed_pointer* dst_ret2, void* working);
193static void     decode_QQF_table(dsp56k_core* cpustate, UINT16 QQ, UINT16 F, void **S1, void **S2, void **D);
194static void     decode_QQF_special_table(dsp56k_core* cpustate, UINT16 QQ, UINT16 F, void **S1, void **S2, void **D);
195static void     decode_QQQF_table(dsp56k_core* cpustate, UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D);
196static void     decode_RR_table(dsp56k_core* cpustate, UINT16 RR, typed_pointer* ret);
197static void     decode_TT_table(dsp56k_core* cpustate, UINT16 TT, typed_pointer* ret);
198static void     decode_uuuuF_table(dsp56k_core* cpustate, UINT16 uuuu, UINT16 F, UINT8 add_sub_other, typed_pointer* src_ret, typed_pointer* dst_ret);
199static void     decode_Z_table(dsp56k_core* cpustate, UINT16 Z, typed_pointer* ret);
200
201static void     execute_m_table(dsp56k_core* cpustate, int x, UINT16 m);
202static void     execute_mm_table(dsp56k_core* cpustate, UINT16 rnum, UINT16 mm);
203static void     execute_MM_table(dsp56k_core* cpustate, UINT16 rnum, UINT16 MM);
204static UINT16   execute_q_table(dsp56k_core* cpustate, int RR, UINT16 q);
205static void     execute_z_table(dsp56k_core* cpustate, int RR, UINT16 z);
206
207static UINT16   assemble_address_from_Pppppp_table(dsp56k_core* cpustate, UINT16 P, UINT16 ppppp);
208static UINT16   assemble_address_from_IO_short_address(dsp56k_core* cpustate, UINT16 pp);
209static UINT16   assemble_address_from_6bit_signed_relative_short_address(dsp56k_core* cpustate, UINT16 srs);
210
211static void dsp56k_process_loop(dsp56k_core* cpustate);
212static void dsp56k_process_rep(dsp56k_core* cpustate, size_t repSize);
213
214
215
216/********************/
217/* Helper Functions */
218/********************/
219static UINT16 Dsp56kOpMask(UINT16 op, UINT16 mask);
220
221/* These arguments are written source->destination to fall in line with the processor's paradigm. */
222static void SetDestinationValue(typed_pointer source, typed_pointer dest);
223
224static void SetDataMemoryValue(dsp56k_core* cpustate, typed_pointer source, UINT32 destinationAddr);
225static void SetProgramMemoryValue(dsp56k_core* cpustate, typed_pointer source, UINT32 destinationAddr);
226
227
228
229/***************************************************************************
230    IMPLEMENTATION
231***************************************************************************/
232
233static void execute_one(dsp56k_core* cpustate)
234{
235   UINT16 op;
236   UINT16 op2;
237   size_t size = 0x1337;
238   UINT8 cycle_count = 0;
239
240   /* For MAME */
241   cpustate->op = ROPCODE(ADDRESS(PC));
242   debugger_instruction_hook(cpustate->device, PC);
243
244   /* The words we're going to be working with */
245   op = ROPCODE(ADDRESS(PC));
246   op2 = ROPCODE(ADDRESS(PC) + ADDRESS(1));
247
248
249   /* DECODE */
250   /* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/
251   if ((op & 0xe000) == 0x6000)
252   {
253      typed_pointer d_register = {NULL, DT_BYTE};
254
255      /* Quote: (MOVE, MAC(R), MPY(R), ADD, SUB, TFR) */
256      UINT16 op_byte = op & 0x00ff;
257
258      /* ADD : 011m mKKK 0rru Fuuu : A-22 */
259      /* SUB : 011m mKKK 0rru Fuuu : A-202 */
260      /* Note: 0x0094 check allows command to drop through to MOVE and TFR */
261      if (((op & 0xe080) == 0x6000) && ((op & 0x0094) != 0x0010))
262      {
263         size = dsp56k_op_addsub_2(cpustate, op_byte, &d_register, &cycle_count);
264      }
265      /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */
266      else if ((op & 0xe094) == 0x6084)
267      {
268         size = dsp56k_op_mac_1(cpustate, op_byte, &d_register, &cycle_count);
269      }
270      /* MACR: 011m mKKK 1--1 F1QQ : A-124 */
271      else if ((op & 0xe094) == 0x6094)
272      {
273         size = dsp56k_op_macr_1(cpustate, op_byte, &d_register, &cycle_count);
274      }
275      /* TFR : 011m mKKK 0rr1 F0DD : A-212 */
276      else if ((op & 0xe094) == 0x6010)
277      {
278         size = dsp56k_op_tfr_2(cpustate, op_byte, &d_register, &cycle_count);
279      }
280      /* MOVE : 011m mKKK 0rr1 0000 : A-128 */
281      else if ((op & 0xe09f) == 0x6010)
282      {
283         /* Note: The opcode encoding : 011x xxxx 0xx1 0000 (move + double memory read)
284                  is .identical. to (tfr X0,A + two parallel reads).  This sparks the notion
285                  that these 'move' opcodes don't actually exist and are just there as
286                  documentation.  Real-world examples would need to be examined to come
287                  to a satisfactory conclusion, but as it stands, tfr will override this
288                  move operation. */
289         size = dsp56k_op_move_1(cpustate, op_byte, &d_register, &cycle_count);
290      }
291      /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */
292      else if ((op & 0xe094) == 0x6080)
293      {
294         size = dsp56k_op_mpy_1(cpustate, op_byte, &d_register, &cycle_count);
295      }
296      /* MPYR : 011m mKKK 1--1 F0QQ : A-162 */
297      else if ((op & 0xe094) == 0x6090)
298      {
299         size = dsp56k_op_mpyr_1(cpustate, op_byte, &d_register, &cycle_count);
300      }
301
302      /* Now evaluate the parallel data move */
303      execute_dual_x_memory_data_read(cpustate, op, &d_register);
304   }
305   /* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */
306   else if ((op & 0xfe00) == 0x1600)
307   {
308      /* Quote: (MPY or MAC) */
309      UINT16 op_byte = op & 0x00ff;
310
311      /* MPY : 0001 0110 RRDD FQQQ : A-160 */
312      if ((op & 0xff00) == 0x1600)
313      {
314         size = dsp56k_op_mpy_2(cpustate, op_byte, &cycle_count);
315      }
316      /* MAC : 0001 0111 RRDD FQQQ : A-122 */
317      else if ((op & 0xff00) == 0x1700)
318      {
319         size = dsp56k_op_mac_2(cpustate, op_byte, &cycle_count);
320      }
321
322      /* Now evaluate the parallel data move */
323      /* TODO // decode_x_memory_data_write_and_register_data_move(op, parallel_move_str, parallel_move_str2); */
324      logerror("DSP56k: Unemulated Dual X Memory Data And Register Data Move @ 0x%x\n", PC);
325   }
326
327   /* Handle Other parallel types */
328   else
329   {
330      /***************************************/
331      /* 32 General parallel move operations */
332      /***************************************/
333
334      enum pType { kNoParallelDataMove,
335                  kRegisterToRegister,
336                  kAddressRegister,
337                  kXMemoryDataMove,
338                  kXMemoryDataMove2,
339                  kXMemoryDataMoveWithDisp };
340
341      int parallelType = -1;
342      UINT16 op_byte = 0x0000;
343      typed_pointer d_register = {NULL, DT_BYTE};
344      UINT64 prev_accum_value = U64(0x0000000000000000);
345
346      /* Note: it's important that NPDM comes before RtRDM here */
347      /* No Parallel Data Move : 0100 1010 .... .... : A-131 */
348      if ((op & 0xff00) == 0x4a00)
349      {
350         op_byte = op & 0x00ff;
351         parallelType = kNoParallelDataMove;
352      }
353      /* Register to Register Data Move : 0100 IIII .... .... : A-133 */
354      else if ((op & 0xf000) == 0x4000)
355      {
356         op_byte = op & 0x00ff;
357         parallelType = kRegisterToRegister;
358      }
359      /* Address Register Update : 0011 0zRR .... .... : A-135 */
360      else if ((op & 0xf800) == 0x3000)
361      {
362         op_byte = op & 0x00ff;
363         parallelType = kAddressRegister;
364      }
365      /* X Memory Data Move : 1mRR HHHW .... .... : A-137 */
366      else if ((op & 0x8000) == 0x8000)
367      {
368         op_byte = op & 0x00ff;
369         parallelType = kXMemoryDataMove;
370      }
371      /* X Memory Data Move : 0101 HHHW .... .... : A-137 */
372      else if ((op & 0xf000) == 0x5000)
373      {
374         op_byte = op & 0x00ff;
375         parallelType = kXMemoryDataMove2;
376      }
377      /* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */
378      else if ((op & 0xff00) == 0x0500)
379      {
380         /* Now check it against all the other potential collisions */
381         /* This is necessary because "don't care bits" get in the way. */
382         /*
383         MOVE(M) :   0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152
384         MOVE(C) :   0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144
385         MOVE :      0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128
386         */
387         if (((op2 & 0xfe20) != 0x0200) &&
388            ((op2 & 0xf810) != 0x3800) &&
389            ((op2 & 0x00ff) != 0x0011))
390         {
391            op_byte = op2 & 0x00ff;
392            parallelType = kXMemoryDataMoveWithDisp;
393         }
394      }
395
396
397      if (parallelType != -1)
398      {
399         /* Note: There is much overlap between opcodes down here */
400         /*       To this end, certain ops must come before others in the list */
401
402         /* CLR : .... .... 0000 F001 : A-60 */
403         if ((op_byte & 0x00f7) == 0x0001)
404         {
405            size = dsp56k_op_clr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
406         }
407         /* ADD : .... .... 0000 FJJJ : A-22 */
408         else if ((op_byte & 0x00f0) == 0x0000)
409         {
410            size = dsp56k_op_add(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
411         }
412
413
414         /* MOVE : .... .... 0001 0001 : A-128 */
415         else if ((op_byte & 0x00ff) == 0x0011)
416         {
417            size = dsp56k_op_move(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
418         }
419         /* TFR : .... .... 0001 FJJJ : A-212 */
420         else if ((op_byte & 0x00f0) == 0x0010)
421         {
422            size = dsp56k_op_tfr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
423         }
424
425
426         /* RND : .... .... 0010 F000 : A-188 */
427         else if ((op_byte & 0x00f7) == 0x0020)
428         {
429            size = dsp56k_op_rnd(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
430         }
431         /* TST : .... .... 0010 F001 : A-218 */
432         else if ((op_byte & 0x00f7) == 0x0021)
433         {
434            size = dsp56k_op_tst(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
435         }
436         /* INC : .... .... 0010 F010 : A-104 */
437         else if ((op_byte & 0x00f7) == 0x0022)
438         {
439            size = dsp56k_op_inc(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
440         }
441         /* INC24 : .... .... 0010 F011 : A-106 */
442         else if ((op_byte & 0x00f7) == 0x0023)
443         {
444            size = dsp56k_op_inc24(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
445         }
446         /* OR : .... .... 0010 F1JJ : A-176 */
447         else if ((op_byte & 0x00f4) == 0x0024)
448         {
449            size = dsp56k_op_or(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
450         }
451
452
453         /* ASR : .... .... 0011 F000 : A-32 */
454         else if ((op_byte & 0x00f7) == 0x0030)
455         {
456            size = dsp56k_op_asr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
457         }
458         /* ASL : .... .... 0011 F001 : A-28 */
459         else if ((op_byte & 0x00f7) == 0x0031)
460         {
461            size = dsp56k_op_asl(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
462         }
463         /* LSR : .... .... 0011 F010 : A-120 */
464         else if ((op_byte & 0x00f7) == 0x0032)
465         {
466            size = dsp56k_op_lsr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
467         }
468         /* LSL : .... .... 0011 F011 : A-118 */
469         else if ((op_byte & 0x00f7) == 0x0033)
470         {
471            size = dsp56k_op_lsl(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
472         }
473         /* EOR : .... .... 0011 F1JJ : A-94 */
474         else if ((op_byte & 0x00f4) == 0x0034)
475         {
476            size = dsp56k_op_eor(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
477         }
478
479
480         /* SUBL : .... .... 0100 F001 : A-204 */
481         else if ((op_byte & 0x00f7) == 0x0041)
482         {
483            size = dsp56k_op_subl(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
484         }
485         /* SUB : .... .... 0100 FJJJ : A-202 */
486         else if ((op_byte & 0x00f0) == 0x0040)
487         {
488            size = dsp56k_op_sub(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
489         }
490
491
492         /* CLR24 : .... .... 0101 F001 : A-62 */
493         else if ((op_byte & 0x00f7) == 0x0051)
494         {
495            size = dsp56k_op_clr24(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
496         }
497         /* SBC : .... .... 0101 F01J : A-198 */
498         else if ((op_byte & 0x00f6) == 0x0052)
499         {
500            size = dsp56k_op_sbc(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
501         }
502         /* CMP : .... .... 0101 FJJJ : A-64 */
503         else if ((op_byte & 0x00f0) == 0x0050)
504         {
505            size = dsp56k_op_cmp(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
506         }
507
508
509         /* NEG : .... .... 0110 F000 : A-166 */
510         else if ((op_byte & 0x00f7) == 0x0060)
511         {
512            size = dsp56k_op_neg(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
513         }
514         /* NOT : .... .... 0110 F001 : A-174 */
515         else if ((op_byte & 0x00f7) == 0x0061)
516         {
517            size = dsp56k_op_not(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
518         }
519         /* DEC : .... .... 0110 F010 : A-72 */
520         else if ((op_byte & 0x00f7) == 0x0062)
521         {
522            size = dsp56k_op_dec(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
523         }
524         /* DEC24 : .... .... 0110 F011 : A-74 */
525         else if ((op_byte & 0x00f7) == 0x0063)
526         {
527            size = dsp56k_op_dec24(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
528         }
529         /* AND : .... .... 0110 F1JJ : A-24 */
530         else if ((op_byte & 0x00f4) == 0x0064)
531         {
532            size = dsp56k_op_and(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
533         }
534
535
536         /* ABS : .... .... 0111 F001 : A-18 */
537         if ((op_byte & 0x00f7) == 0x0071)
538         {
539            size = dsp56k_op_abs(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
540         }
541         /* ROR : .... .... 0111 F010 : A-192 */
542         else if ((op_byte & 0x00f7) == 0x0072)
543         {
544            size = dsp56k_op_ror(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
545         }
546         /* ROL : .... .... 0111 F011 : A-190 */
547         else if ((op_byte & 0x00f7) == 0x0073)
548         {
549            size = dsp56k_op_rol(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
550         }
551         /* CMPM : .... .... 0111 FJJJ : A-66 */
552         else if ((op_byte & 0x00f0) == 0x0070)
553         {
554            size = dsp56k_op_cmpm(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
555         }
556
557
558         /* MPY : .... .... 1k00 FQQQ : A-160    -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */
559         else if ((op_byte & 0x00b0) == 0x0080)
560         {
561            size = dsp56k_op_mpy(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
562         }
563         /* MPYR : .... .... 1k01 FQQQ : A-162 */
564         else if ((op_byte & 0x00b0) == 0x0090)
565         {
566            size = dsp56k_op_mpyr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
567         }
568         /* MAC : .... .... 1k10 FQQQ : A-122 */
569         else if ((op_byte & 0x00b0) == 0x00a0)
570         {
571            size = dsp56k_op_mac(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
572         }
573         /* MACR : .... .... 1k11 FQQQ : A-124   -- DRAMA - rr vs xx (805) */
574         else if ((op_byte & 0x00b0) == 0x00b0)
575         {
576            size = dsp56k_op_macr(cpustate, op_byte, &d_register, &prev_accum_value, &cycle_count);
577         }
578
579
580         /* Now evaluate the parallel data move */
581         switch (parallelType)
582         {
583         case kNoParallelDataMove:
584            /* DO NOTHING */
585            break;
586         case kRegisterToRegister:
587            execute_register_to_register_data_move(cpustate, op, &d_register, &prev_accum_value);
588            break;
589         case kAddressRegister:
590            execute_address_register_update(cpustate, op, &d_register, &prev_accum_value);
591            break;
592         case kXMemoryDataMove:
593            execute_x_memory_data_move(cpustate, op, &d_register, &prev_accum_value);
594            break;
595         case kXMemoryDataMove2:
596            execute_x_memory_data_move2(cpustate, op, &d_register);
597            break;
598         case kXMemoryDataMoveWithDisp:
599            execute_x_memory_data_move_with_short_displacement(cpustate, op, op2);
600            size = 2;
601            break;
602         }
603      }
604   }
605
606   /* Drop out if you've already completed your work. */
607   if (size != 0x1337)
608   {
609      PC += size;
610
611      dsp56k_process_loop(cpustate);
612      dsp56k_process_rep(cpustate, size);
613
614      cpustate->icount -= 4;  /* Temporarily hard-coded at 4 clocks per opcode */ /* cycle_count */
615      return;
616   }
617
618
619   /******************************/
620   /* Remaining non-parallel ops */
621   /******************************/
622
623   /* ADC : 0001 0101 0000 F01J : A-20 */
624   if ((op & 0xfff6) == 0x1502)
625   {
626      size = dsp56k_op_adc(cpustate, op, &cycle_count);
627   }
628   /* ANDI : 0001 1EE0 iiii iiii : A-26 */
629   /* (MoveP sneaks in here if you don't check 0x0600) */
630   else if (((op & 0xf900) == 0x1800) & ((op & 0x0600) != 0x0000))
631   {
632      size = dsp56k_op_andi(cpustate, op, &cycle_count);
633   }
634   /* ASL4 : 0001 0101 0011 F001 : A-30 */
635   else if ((op & 0xfff7) == 0x1531)
636   {
637      size = dsp56k_op_asl4(cpustate, op, &cycle_count);
638   }
639   /* ASR4 : 0001 0101 0011 F000 : A-34 */
640   else if ((op & 0xfff7) == 0x1530)
641   {
642      size = dsp56k_op_asr4(cpustate, op, &cycle_count);
643   }
644   /* ASR16 : 0001 0101 0111 F000 : A-36 */
645   else if ((op & 0xfff7) == 0x1570)
646   {
647      size = dsp56k_op_asr16(cpustate, op, &cycle_count);
648   }
649   /* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */
650   else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x1200))
651   {
652      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
653   }
654   /* BFCHG : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */
655   else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x1200))
656   {
657      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
658   }
659   /* BFCHG : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */
660   else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x1200))
661   {
662      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
663   }
664   /* BFCLR : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */
665   else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x0400))
666   {
667      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
668   }
669   /* BFCLR : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */
670   else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x0400))
671   {
672      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
673   }
674   /* BFCLR : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */
675   else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x0400))
676   {
677      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
678   }
679   /* BFSET : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */
680   else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x1800))
681   {
682      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
683   }
684   /* BFSET : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */
685   else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x1800))
686   {
687      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
688   }
689   /* BFSET : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */
690   else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x1800))
691   {
692      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
693   }
694   /* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */
695   else if (((op & 0xffc0) == 0x1440) && ((op2 & 0x1f00) == 0x1000))
696   {
697      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
698   }
699   /* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */
700   else if (((op & 0xffe0) == 0x1420) && ((op2 & 0x1f00) == 0x1000))
701   {
702      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
703   }
704   /* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */
705   else if (((op & 0xffe0) == 0x1400) && ((op2 & 0x1f00) == 0x1000))
706   {
707      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
708   }
709   /* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */
710   else if (((op & 0xffc0) == 0x1440) && ((op2 & 0x1f00) == 0x0000))
711   {
712      size = dsp56k_op_bfop(cpustate, op, op2, &cycle_count);
713   }
714   /* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */
715   else if (((op & 0xffe0) == 0x1420) && ((op2 & 0x1f00) == 0x0000))
716   {
717      size = dsp56k_op_bfop_1(cpustate, op, op2, &cycle_count);
718   }
719   /* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */
720   else if (((op & 0xffe0) == 0x1400) && ((op2 & 0x1f00) == 0x0000))
721   {
722      size = dsp56k_op_bfop_2(cpustate, op, op2, &cycle_count);
723   }
724   /* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */
725   else if (((op & 0xff30) == 0x0730) && ((op2 & 0x0000) == 0x0000))
726   {
727      size = dsp56k_op_bcc(cpustate, op, op2, &cycle_count);
728   }
729   /* Bcc : 0010 11cc ccee eeee : A-48 */
730   else if ((op & 0xfc00) == 0x2c00)
731   {
732      size = dsp56k_op_bcc_1(cpustate, op, &cycle_count);
733   }
734   /* Bcc : 0000 0111 RR10 cccc : A-48 */
735   else if ((op & 0xff30) == 0x0720)
736   {
737      size = dsp56k_op_bcc_2(cpustate, op, &cycle_count);
738   }
739   /* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */
740   else if (((op & 0xfffc) == 0x013c) && ((op2 & 0x0000) == 0x0000))
741   {
742      size = dsp56k_op_bra(cpustate, op, op2, &cycle_count);
743   }
744   /* BRA : 0000 1011 aaaa aaaa : A-50 */
745   else if ((op & 0xff00) == 0x0b00)
746   {
747      size = dsp56k_op_bra_1(cpustate, op, &cycle_count);
748   }
749   /* BRA : 0000 0001 0010 11RR : A-50 */
750   else if ((op & 0xfffc) == 0x012c)
751   {
752      size = dsp56k_op_bra_2(cpustate, op, &cycle_count);
753   }
754   /* BRKc : 0000 0001 0001 cccc : A-52 */
755   else if ((op & 0xfff0) == 0x0110)
756   {
757      size = dsp56k_op_brkcc(cpustate, op, &cycle_count);
758   }
759   /* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */
760   else if (((op & 0xff30) == 0x0710) && ((op2 & 0x0000) == 0x0000))
761   {
762      size = dsp56k_op_bscc(cpustate, op, op2, &cycle_count);
763   }
764   /* BScc : 0000 0111 RR00 cccc : A-54 */
765   else if ((op & 0xff30) == 0x0700)
766   {
767      size = dsp56k_op_bscc_1(cpustate, op, &cycle_count);
768   }
769   /* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */
770   else if (((op & 0xfffc) == 0x0138) && ((op2 & 0x0000) == 0x0000))
771   {
772      size = dsp56k_op_bsr(cpustate, op, op2, &cycle_count);
773   }
774   /* BSR : 0000 0001 0010 10RR : A-56 */
775   else if ((op & 0xfffc) == 0x0128)
776   {
777      size = dsp56k_op_bsr_1(cpustate, op, &cycle_count);
778   }
779   /* CHKAAU : 0000 0000 0000 0100 : A-58 */
780   else if ((op & 0xffff) == 0x0004)
781   {
782      size = dsp56k_op_chkaau(cpustate, op, &cycle_count);
783   }
784   /* DEBUG : 0000 0000 0000 0001 : A-68 */
785   else if ((op & 0xffff) == 0x0001)
786   {
787      size = dsp56k_op_debug(cpustate, op, &cycle_count);
788   }
789   /* DEBUGcc : 0000 0000 0101 cccc : A-70 */
790   else if ((op & 0xfff0) == 0x0050)
791   {
792      size = dsp56k_op_debugcc(cpustate, op, &cycle_count);
793   }
794   /* DIV : 0001 0101 0--0 F1DD : A-76 */
795   else if ((op & 0xff94) == 0x1504)
796   {
797      size = dsp56k_op_div(cpustate, op, &cycle_count);
798   }
799   /* DMAC : 0001 0101 10s1 FsQQ : A-80 */
800   else if ((op & 0xffd0) == 0x1590)
801   {
802      size = dsp56k_op_dmac(cpustate, op, &cycle_count);
803   }
804   /* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */
805   else if (((op & 0xffe0) == 0x00c0) && ((op2 & 0x0000) == 0x0000))
806   {
807      size = dsp56k_op_do(cpustate, op, op2, &cycle_count);
808   }
809   /* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */
810   else if (((op & 0xff00) == 0x0e00) && ((op2 & 0x0000) == 0x0000))
811   {
812      size = dsp56k_op_do_1(cpustate, op, op2, &cycle_count);
813   }
814   /* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */
815   else if (((op & 0xffe0) == 0x0400) && ((op2 & 0x0000) == 0x0000))
816   {
817      size = dsp56k_op_do_2(cpustate, op, op2, &cycle_count);
818   }
819   /* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */
820   else if (((op & 0xffff) == 0x0002) && ((op2 & 0x0000) == 0x0000))
821   {
822      size = dsp56k_op_doforever(cpustate, op, op2, &cycle_count);
823   }
824   /* ENDDO : 0000 0000 0000 1001 : A-92 */
825   else if ((op & 0xffff) == 0x0009)
826   {
827      size = dsp56k_op_enddo(cpustate, op, &cycle_count);
828   }
829   /* EXT : 0001 0101 0101 F010 : A-96 */
830   else if ((op & 0xfff7) == 0x1552)
831   {
832      size = dsp56k_op_ext(cpustate, op, &cycle_count);
833   }
834   /* ILLEGAL : 0000 0000 0000 1111 : A-98 */
835   else if ((op & 0xffff) == 0x000f)
836   {
837      size = dsp56k_op_illegal(cpustate, op, &cycle_count);
838   }
839   /* IMAC : 0001 0101 1010 FQQQ : A-100 */
840   else if ((op & 0xfff0) == 0x15a0)
841   {
842      size = dsp56k_op_imac(cpustate, op, &cycle_count);
843   }
844   /* IMPY : 0001 0101 1000 FQQQ : A-102 */
845   else if ((op & 0xfff0) == 0x1580)
846   {
847      size = dsp56k_op_impy(cpustate, op, &cycle_count);
848   }
849   /* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */
850   else if (((op & 0xff30) == 0x0630) && ((op2 & 0x0000) == 0x0000))
851   {
852      size = dsp56k_op_jcc(cpustate, op, op2, &cycle_count);
853   }
854   /* Jcc : 0000 0110 RR10 cccc : A-108 */
855   else if ((op & 0xff30) == 0x0620 )
856   {
857      size = dsp56k_op_jcc_1(cpustate, op, &cycle_count);
858   }
859   /* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */
860   else if (((op & 0xfffc) == 0x0134) && ((op2 & 0x0000) == 0x0000))
861   {
862      size = dsp56k_op_jmp(cpustate, op, op2, &cycle_count);
863   }
864   /* JMP : 0000 0001 0010 01RR : A-110 */
865   else if ((op & 0xfffc) == 0x0124)
866   {
867      size = dsp56k_op_jmp_1(cpustate, op, &cycle_count);
868   }
869   /* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */
870   else if (((op & 0xff30) == 0x0610) && ((op2 & 0x0000) == 0x0000))
871   {
872      size = dsp56k_op_jscc(cpustate, op, op2, &cycle_count);
873   }
874   /* JScc : 0000 0110 RR00 cccc : A-112 */
875   else if ((op & 0xff30) == 0x0600)
876   {
877      size = dsp56k_op_jscc_1(cpustate, op, &cycle_count);
878   }
879   /* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */
880   else if (((op & 0xfffc) == 0x0130) && ((op2 & 0x0000) == 0x0000))
881   {
882      size = dsp56k_op_jsr(cpustate, op, op2, &cycle_count);
883   }
884   /* JSR : 0000 1010 AAAA AAAA : A-114 */
885   else if ((op & 0xff00) == 0x0a00)
886   {
887      size = dsp56k_op_jsr_1(cpustate, op, &cycle_count);
888   }
889   /* JSR : 0000 0001 0010 00RR : A-114 */
890   else if ((op & 0xfffc) == 0x0120)
891   {
892      size = dsp56k_op_jsr_2(cpustate, op, &cycle_count);
893   }
894   /* LEA : 0000 0001 11TT MMRR : A-116 */
895   else if ((op & 0xffc0) == 0x01c0)
896   {
897      size = dsp56k_op_lea(cpustate, op, &cycle_count);
898   }
899   /* LEA : 0000 0001 10NN MMRR : A-116 */
900   else if ((op & 0xffc0) == 0x0180)
901   {
902      size = dsp56k_op_lea_1(cpustate, op, &cycle_count);
903   }
904   /* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */
905   else if ((op & 0xfff0) == 0x15e0)
906   {
907      size = dsp56k_op_macsuuu(cpustate, op, &cycle_count);
908   }
909   /* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */
910   else if (((op & 0xff00) == 0x0500) && ((op2 & 0x00ff) == 0x0011))
911   {
912      size = dsp56k_op_move_2(cpustate, op, op2, &cycle_count);
913   }
914   /* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */
915   else if ((op & 0xf810) == 0x3800)
916   {
917      size = dsp56k_op_movec(cpustate, op, &cycle_count);
918   }
919   /* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */
920   else if ((op & 0xf814) == 0x3810)
921   {
922      size = dsp56k_op_movec_1(cpustate, op, &cycle_count);
923   }
924   /* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */
925   else if ((op & 0xf816) == 0x3816)
926   {
927      size = dsp56k_op_movec_2(cpustate, op, &cycle_count);
928   }
929   /* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */
930   else if (((op & 0xf816) == 0x3814) && ((op2 & 0x0000) == 0x0000))
931   {
932      size = dsp56k_op_movec_3(cpustate, op, op2, &cycle_count);
933   }
934   /* MOVE(C) : 0010 10dd dddD DDDD : A-144 */
935   else if ((op & 0xfc00) == 0x2800)
936   {
937      size = dsp56k_op_movec_4(cpustate, op, &cycle_count);
938   }
939   /* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */
940   else if (((op & 0xff00) == 0x0500) && ((op2 & 0xf810) == 0x3800))
941   {
942      size = dsp56k_op_movec_5(cpustate, op, op2, &cycle_count);
943   }
944   /* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */
945   else if ((op & 0xfc00) == 0x2000)
946   {
947      size = dsp56k_op_movei(cpustate, op, &cycle_count);
948   }
949   /* MOVE(M) : 0000 001W RR0M MHHH : A-152 */
950   else if ((op & 0xfe20) == 0x0200)
951   {
952      size = dsp56k_op_movem(cpustate, op, &cycle_count);
953   }
954   /* MOVE(M) : 0000 001W RR11 mmRR : A-152 */
955   else if ((op & 0xfe30) == 0x0230)
956   {
957      size = dsp56k_op_movem_1(cpustate, op, &cycle_count);
958   }
959   /* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */
960   else if (((op & 0xff00) == 0x0500) && ((op2 & 0xfe20) == 0x0200))
961   {
962      size = dsp56k_op_movem_2(cpustate, op, op2, &cycle_count);
963   }
964   /* MOVE(P) : 0001 100W HH1p pppp : A-156 */
965   else if ((op & 0xfe20) == 0x1820)
966   {
967      size = dsp56k_op_movep(cpustate, op, &cycle_count);
968   }
969   /* MOVE(P) : 0000 110W RRmp pppp : A-156 */
970   else if ((op & 0xfe00) == 0x0c00)
971   {
972      size = dsp56k_op_movep_1(cpustate, op, &cycle_count);
973   }
974   /* MOVE(S) : 0001 100W HH0a aaaa : A-158 */
975   else if ((op & 0xfe20) == 0x1800)
976   {
977      size = dsp56k_op_moves(cpustate, op, &cycle_count);
978   }
979   /* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */
980   else if ((op & 0xfff0) == 0x15c0)
981   {
982      size = dsp56k_op_mpysuuu(cpustate, op, &cycle_count);
983   }
984   /* NEGC : 0001 0101 0110 F000 : A-168 */
985   else if ((op & 0xfff7) == 0x1560)
986   {
987      size = dsp56k_op_negc(cpustate, op, &cycle_count);
988   }
989   /* NOP : 0000 0000 0000 0000 : A-170 */
990   else if ((op & 0xffff) == 0x0000)
991   {
992      size = dsp56k_op_nop(cpustate, op, &cycle_count);
993   }
994   /* NORM : 0001 0101 0010 F0RR : A-172 */
995   else if ((op & 0xfff4) == 0x1520)
996   {
997      size = dsp56k_op_norm(cpustate, op, &cycle_count);
998   }
999   /* ORI : 0001 1EE1 iiii iiii : A-178 */
1000   else if ((op & 0xf900) == 0x1900)
1001   {
1002      size = dsp56k_op_ori(cpustate, op, &cycle_count);
1003   }
1004   /* REP : 0000 0000 111- --RR : A-180 */
1005   else if ((op & 0xffe0) == 0x00e0)
1006   {
1007      size = dsp56k_op_rep(cpustate, op, &cycle_count);
1008   }
1009   /* REP : 0000 1111 iiii iiii : A-180 */
1010   else if ((op & 0xff00) == 0x0f00)
1011   {
1012      size = dsp56k_op_rep_1(cpustate, op, &cycle_count);
1013   }
1014   /* REP : 0000 0100 001D DDDD : A-180 */
1015   else if ((op & 0xffe0) == 0x0420)
1016   {
1017      size = dsp56k_op_rep_2(cpustate, op, &cycle_count);
1018   }
1019   /* REPcc : 0000 0001 0101 cccc : A-184 */
1020   else if ((op & 0xfff0) == 0x0150)
1021   {
1022      size = dsp56k_op_repcc(cpustate, op, &cycle_count);
1023   }
1024   /* RESET : 0000 0000 0000 1000 : A-186 */
1025   else if ((op & 0xffff) == 0x0008)
1026   {
1027      size = dsp56k_op_reset(cpustate, op, &cycle_count);
1028   }
1029   /* RTI : 0000 0000 0000 0111 : A-194 */
1030   else if ((op & 0xffff) == 0x0007)
1031   {
1032      size = dsp56k_op_rti(cpustate, op, &cycle_count);
1033   }
1034   /* RTS : 0000 0000 0000 0110 : A-196 */
1035   else if ((op & 0xffff) == 0x0006)
1036   {
1037      size = dsp56k_op_rts(cpustate, op, &cycle_count);
1038   }
1039   /* STOP : 0000 0000 0000 1010 : A-200 */
1040   else if ((op & 0xffff) == 0x000a)
1041   {
1042      size = dsp56k_op_stop(cpustate, op, &cycle_count);
1043   }
1044   /* SWAP : 0001 0101 0111 F001 : A-206 */
1045   else if ((op & 0xfff7) == 0x1571)
1046   {
1047      size = dsp56k_op_swap(cpustate, op, &cycle_count);
1048   }
1049   /* SWI : 0000 0000 0000 0101 : A-208 */
1050   else if ((op & 0xffff) == 0x0005)
1051   {
1052      size = dsp56k_op_swi(cpustate, op, &cycle_count);
1053   }
1054   /* Tcc : 0001 00cc ccTT Fh0h : A-210 */
1055   else if ((op & 0xfc02) == 0x1000)
1056   {
1057      size = dsp56k_op_tcc(cpustate, op, &cycle_count);
1058   }
1059   /* TFR(2) : 0001 0101 0000 F00J : A-214 */
1060   else if ((op & 0xfff6) == 0x1500)
1061   {
1062      size = dsp56k_op_tfr2(cpustate, op, &cycle_count);
1063   }
1064   /* TFR(3) : 0010 01mW RRDD FHHH : A-216 */
1065   else if ((op & 0xfc00) == 0x2400)
1066   {
1067      size = dsp56k_op_tfr3(cpustate, op, &cycle_count);
1068   }
1069   /* TST(2) : 0001 0101 0001 -1DD : A-220 */
1070   else if ((op & 0xfff4) == 0x1514)
1071   {
1072      size = dsp56k_op_tst2(cpustate, op, &cycle_count);
1073   }
1074   /* WAIT : 0000 0000 0000 1011 : A-222 */
1075   else if ((op & 0xffff) == 0x000b)
1076   {
1077      size = dsp56k_op_wait(cpustate, op, &cycle_count);
1078   }
1079   /* ZERO : 0001 0101 0101 F000 : A-224 */
1080   else if ((op & 0xfff7) == 0x1550)
1081   {
1082      size = dsp56k_op_zero(cpustate, op, &cycle_count);
1083   }
1084
1085
1086   /* Not recognized?  Nudge debugger onto the next word */
1087   if (size == 0x1337)
1088   {
1089      logerror("DSP56k: Unimplemented opcode at 0x%04x : %04x\n", PC, op);
1090      size = 1 ;                      /* Just to get the debugger past the bad opcode */
1091   }
1092
1093   /* Must have been a good opcode */
1094   PC += size;
1095
1096   dsp56k_process_loop(cpustate);
1097   dsp56k_process_rep(cpustate, size);
1098
1099   cpustate->icount -= 4;  /* Temporarily hard-coded at 4 clocks per opcode */ /* cycle_count */
1100}
1101
1102
1103
1104
1105/***************************************************************************
1106    Opcode implementations
1107***************************************************************************/
1108
1109/*******************************/
1110/* 32 Parallel move operations */
1111/*******************************/
1112
1113/* ADD : 011m mKKK 0rru Fuuu : A-22 */
1114/* SUB : 011m mKKK 0rru Fuuu : A-202 */
1115static size_t dsp56k_op_addsub_2(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1116{
1117   UINT64 useVal = 0;
1118   UINT8 op_type = OP_OTHER;
1119   typed_pointer S = {NULL, DT_BYTE};
1120   typed_pointer D = {NULL, DT_BYTE};
1121
1122   decode_uuuuF_table(cpustate, BITS(op_byte,0x0017), BITS(op_byte,0x0008), op_type, &S, &D);
1123
1124   /* If you gave an invalid operation type, presume it's a nop and move on with the parallel move */
1125   if (op_type == OP_OTHER)
1126   {
1127      d_register->addr = NULL;
1128      d_register->data_type = DT_BYTE;
1129      cycles += 2;
1130      return 1;
1131   }
1132
1133   /* It's a real operation.  Get on with it. */
1134   switch(S.data_type)
1135   {
1136      case DT_WORD:        useVal = (UINT64)*((UINT16*)S.addr) << 16; break;
1137      case DT_DOUBLE_WORD: useVal = (UINT64)*((UINT32*)S.addr);       break;
1138      case DT_LONG_WORD:   useVal = (UINT64)*((UINT64*)S.addr);       break;
1139   }
1140
1141   /* Sign-extend word for proper add/sub op */
1142   if ((S.data_type == DT_WORD) && useVal & U64(0x0000000080000000))
1143      useVal |= U64(0x000000ff00000000);
1144
1145   /* Operate*/
1146   if (op_type == OP_ADD)
1147      *((UINT64*)D.addr) += useVal;
1148   else if (op_type == OP_SUB)
1149      *((UINT64*)D.addr) -= useVal;
1150
1151   d_register->addr = D.addr;
1152   d_register->data_type = D.data_type;
1153
1154   /* S L E U N Z V C */
1155   /* * * * * * * * * */
1156   /* TODO S, L, E, U, V, C */
1157   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1158   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1159
1160   cycles += 2;        /* TODO: + mv oscillator cycles */
1161   return 1;
1162}
1163
1164/* MAC : 011m mKKK 1xx0 F1QQ : A-122 */
1165static size_t dsp56k_op_mac_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1166{
1167   INT64 opD = 0;
1168   INT64 result = 0;
1169
1170   INT32 s1 = 0;
1171   INT32 s2 = 0;
1172
1173   void* D = NULL;
1174   void* S1 = NULL;
1175   void* S2 = NULL;
1176
1177   decode_QQF_table(cpustate, BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S1, &S2, &D);
1178
1179   /* Cast both values as being signed */
1180   s1 = *((INT16*)S1);
1181   s2 = *((INT16*)S2);
1182
1183   /* Fixed-point 2's complement multiplication requires a shift */
1184   result = (s1 * s2) << 1;
1185
1186   /* Sign extend D into a temp variable */
1187   opD = (*((UINT64*)D));
1188   if (opD & U64(0x0000008000000000))
1189      opD |= U64(0xffffff0000000000);
1190   else
1191      opD &= U64(0x000000ffffffffff);
1192
1193   /* Accumulate */
1194   opD += result;
1195
1196   /* And out the bits that don't live in the register */
1197   opD &= U64(0x000000ffffffffff);
1198
1199   (*((UINT64*)D)) = (UINT64)opD;
1200
1201   /* For the parallel move */
1202   d_register->addr = D;
1203   d_register->data_type = DT_LONG_WORD;
1204
1205   /* S L E U N Z V C */
1206   /* * * * * * * * - */
1207   /* TODO: S, L, E, V */
1208   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1209   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1210
1211   cycles += 2;        /* TODO: +mv oscillator cycles */
1212   return 1;
1213}
1214
1215/* MACR: 011m mKKK 1--1 F1QQ : A-124 */
1216static size_t dsp56k_op_macr_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1217{
1218   /* S L E U N Z V C */
1219   /* * * * * * * * - */
1220   return 0;
1221}
1222
1223/* MOVE : 011m mKKK 0rr1 0000 : A-128 */
1224static size_t dsp56k_op_move_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1225{
1226   /* S L E U N Z V C */
1227   /* * * - - - - - - */
1228   return 0;
1229}
1230
1231/* MPY : 011m mKKK 1xx0 F0QQ : A-160 */
1232static size_t dsp56k_op_mpy_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1233{
1234   INT64 result = 0;
1235
1236   INT32 s1 = 0;
1237   INT32 s2 = 0;
1238
1239   void* D = NULL;
1240   void* S1 = NULL;
1241   void* S2 = NULL;
1242
1243   decode_QQF_table(cpustate, BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S1, &S2, &D);
1244
1245   /* Cast both values as being signed */
1246   s1 = *((INT16*)S1);
1247   s2 = *((INT16*)S2);
1248
1249   /* Fixed-point 2's complement multiplication requires a shift */
1250   result = (s1 * s2) << 1;
1251
1252   /* And out the bits that don't live in the register */
1253   (*((UINT64*)D)) = result & U64(0x000000ffffffffff);
1254
1255   /* For the parallel move */
1256   d_register->addr = D;
1257   d_register->data_type = DT_LONG_WORD;
1258
1259   /* S L E U N Z V C */
1260   /* * * * * * * * - */
1261   /* TODO: S, L, E, V */
1262   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1263   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1264
1265   cycles += 2;        /* TODO: +mv oscillator cycles */
1266   return 1;
1267}
1268
1269/* MPYR : 011m mKKK 1--1 F0QQ : A-162 */
1270static size_t dsp56k_op_mpyr_1(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1271{
1272   /* S L E U N Z V C */
1273   /* * * * * * * * - */
1274   return 0;
1275}
1276
1277/* TFR : 011m mKKK 0rr1 F0DD : A-212 */
1278static size_t dsp56k_op_tfr_2(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles)
1279{
1280   /* S L E U N Z V C */
1281   /* - - - - - - - - */
1282   return 0;
1283}
1284
1285/* MPY : 0001 0110 RRDD FQQQ : A-160 */
1286static size_t dsp56k_op_mpy_2(dsp56k_core* cpustate, const UINT16 op_byte, UINT8* cycles)
1287{
1288   /* S L E U N Z V C */
1289   /* * * * * * * * - */
1290   return 0;
1291}
1292
1293/* MAC : 0001 0111 RRDD FQQQ : A-122 */
1294static size_t dsp56k_op_mac_2(dsp56k_core* cpustate, const UINT16 op_byte, UINT8* cycles)
1295{
1296   /* S L E U N Z V C */
1297   /* * * * * * * * - */
1298   return 0;
1299}
1300
1301/* CLR : .... .... 0000 F001 : A-60 */
1302static size_t dsp56k_op_clr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1303{
1304   typed_pointer D = {NULL, DT_LONG_WORD};
1305   typed_pointer clear = {NULL, DT_LONG_WORD};
1306   UINT64 clear_val = U64(0x0000000000000000);
1307
1308   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1309
1310   *p_accum = *((UINT64*)D.addr);
1311
1312   clear.addr = &clear_val;
1313   clear.data_type = DT_LONG_WORD;
1314   SetDestinationValue(clear, D);
1315
1316   d_register->addr = D.addr;
1317   d_register->data_type = D.data_type;
1318
1319   /* S L E U N Z V C */
1320   /* * * * * * * 0 - */
1321   /* TODO - S, L */
1322   DSP56K_E_CLEAR();
1323   DSP56K_U_SET();
1324   DSP56K_N_CLEAR();
1325   DSP56K_Z_SET();
1326   DSP56K_V_CLEAR();
1327
1328   cycles += 2;    /* TODO: + mv oscillator clock cycles */
1329   return 1;
1330}
1331
1332/* ADD : .... .... 0000 FJJJ : A-22 */
1333static size_t dsp56k_op_add(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1334{
1335   UINT64 addVal = 0;
1336
1337   typed_pointer S = {NULL, DT_BYTE};
1338   typed_pointer D = {NULL, DT_BYTE};
1339   decode_JJJF_table(cpustate, BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
1340
1341   *p_accum = *((UINT64*)D.addr);
1342
1343   switch(S.data_type)
1344   {
1345      case DT_WORD:        addVal = (UINT64)*((UINT16*)S.addr) << 16; break;
1346      case DT_DOUBLE_WORD: addVal = (UINT64)*((UINT32*)S.addr);       break;
1347      case DT_LONG_WORD:   addVal = (UINT64)*((UINT64*)S.addr);       break;
1348   }
1349
1350   /* Sign-extend word for proper add/sub op */
1351   if ((S.data_type == DT_WORD) && addVal & U64(0x0000000080000000))
1352      addVal |= U64(0x000000ff00000000);
1353
1354   /* Operate*/
1355   *((UINT64*)D.addr) += addVal;
1356
1357   d_register->addr = D.addr;
1358   d_register->data_type = D.data_type;
1359
1360   /* S L E U N Z V C */
1361   /* * * * * * * * * */
1362   /* TODO S, L, E, U, V, C */
1363   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1364   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1365
1366   cycles += 2;        /* TODO: + mv oscillator cycles */
1367   return 1;
1368}
1369
1370/* MOVE : .... .... 0001 0001 : A-128 */
1371static size_t dsp56k_op_move(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1372{
1373   /* Equivalent to a nop with a parallel move */
1374   /* These can't be used later.  Hopefully compilers would pick this up. */
1375   *p_accum = 0;
1376   d_register->addr = NULL;
1377   d_register->data_type = DT_BYTE;
1378
1379   /* S L E U N Z V C */
1380   /* * * - - - - - - */
1381   /* TODO: S, L */
1382   cycles += 2;    /* TODO: + mv oscillator cycles */
1383   return 1;
1384}
1385
1386/* TFR : .... .... 0001 FJJJ : A-212 */
1387static size_t dsp56k_op_tfr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1388{
1389   typed_pointer S = {NULL, DT_BYTE};
1390   typed_pointer D = {NULL, DT_BYTE};
1391
1392   decode_JJJF_table(cpustate, BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
1393
1394   *p_accum = *((UINT64*)D.addr);
1395
1396   SetDestinationValue(S, D);
1397
1398   d_register->addr = D.addr;
1399   d_register->data_type = D.data_type;
1400
1401   /* S L E U N Z V C */
1402   /* * * - - - - - - */
1403   /* TODO: S, L */
1404   cycles += 2;        /* TODO: + mv oscillator cycles */
1405   return 1;
1406}
1407
1408/* RND : .... .... 0010 F000 : A-188 */
1409static size_t dsp56k_op_rnd(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1410{
1411   typed_pointer D = {NULL, DT_BYTE};
1412
1413   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1414
1415   *p_accum = *((UINT64*)D.addr);
1416
1417   /* WARNING : ROUNDING NOT FULLY IMPLEMENTED YET! */
1418   if ((*((UINT64*)D.addr) & U64(0x000000000000ffff)) >= 0x8000)
1419      *((UINT64*)D.addr) += U64(0x0000000000010000);
1420
1421   *((UINT64*)D.addr) = *((UINT64*)D.addr) & U64(0x000000ffffff0000);
1422
1423   d_register->addr = D.addr;
1424   d_register->data_type = D.data_type;
1425
1426   /* S L E U N Z V C */
1427   /* * * * * * * * - */
1428   /* TODO: S, L, E, U, V */
1429   if ((*((UINT64*)D.addr)) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1430   if ((*((UINT64*)D.addr)) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1431
1432   cycles += 2;        /* TODO: + mv oscillator clock cycles */
1433   return 1;
1434}
1435
1436/* TST : .... .... 0010 F001 : A-218 */
1437static size_t dsp56k_op_tst(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1438{
1439   typed_pointer D = {NULL, DT_LONG_WORD};
1440
1441   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1442
1443   *p_accum = *((UINT64*)D.addr);
1444
1445   d_register->addr = D.addr;
1446   d_register->data_type = D.data_type;
1447
1448   /* S L E U N Z V C */
1449   /* 0 * * * * * 0 0 */
1450   /* TODO: S, L, E, U */
1451   if ((*((UINT64*)D.addr)) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1452   if ((*((UINT64*)D.addr)) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1453   DSP56K_V_CLEAR();
1454   DSP56K_C_CLEAR();
1455
1456   cycles += 2;    /* TODO: + mv oscillator clock cycles */
1457   return 1;
1458}
1459
1460/* INC : .... .... 0010 F010 : A-104 */
1461static size_t dsp56k_op_inc(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1462{
1463   typed_pointer D = {NULL, DT_BYTE};
1464   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1465
1466   /* Save some data for the parallel move */
1467   *p_accum = *((UINT64*)D.addr);
1468
1469   /* Make sure the destination is a real 40-bit value */
1470   *((UINT64*)D.addr) &= U64(0x000000ffffffffff);
1471
1472   /* Increment */
1473   *((UINT64*)D.addr) = *((UINT64*)D.addr) + 1;
1474
1475   d_register->addr = D.addr;
1476   d_register->data_type = D.data_type;
1477
1478   /* S L E U N Z V C */
1479   /* * * * * * * * * */
1480   /* TODO: S, L, E, U */
1481   if ( *((UINT64*)D.addr) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1482   if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1483   if ((*((UINT64*)D.addr) & U64(0xffffff0000000000)) != 0) DSP56K_V_SET(); else DSP56K_V_CLEAR();
1484   if ((*((UINT64*)D.addr) & U64(0xffffff0000000000)) != 0) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1485
1486   cycles += 2;    /* TODO: +mv oscillator cycles */
1487   return 1;
1488}
1489
1490/* INC24 : .... .... 0010 F011 : A-106 */
1491static size_t dsp56k_op_inc24(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1492{
1493   UINT32 workBits24;
1494
1495   typed_pointer D = {NULL, DT_BYTE};
1496   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1497
1498   /* Save some data for the parallel move */
1499   *p_accum = *((UINT64*)D.addr);
1500
1501   /* TODO: I wonder if workBits24 should be signed? */
1502   workBits24 = ((*((UINT64*)D.addr)) & U64(0x000000ffffff0000)) >> 16;
1503   workBits24++;
1504   //workBits24 &= 0x00ffffff;     /* Solves -x issues - TODO: huh? */
1505
1506   /* Set the D bits with the dec result */
1507   *((UINT64*)D.addr) &= U64(0x000000000000ffff);
1508   *((UINT64*)D.addr) |= (((UINT64)(workBits24)) << 16);
1509
1510   d_register->addr = D.addr;
1511   d_register->data_type = D.data_type;
1512
1513   /* S L E U N Z V C */
1514   /* * * * * * ? * * */
1515   /* TODO: S, L, E, U */
1516   if ( *((UINT64*)D.addr) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1517   if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1518   if ((workBits24 & 0xff000000) != 0) DSP56K_V_SET(); else DSP56K_V_CLEAR();
1519   if ((workBits24 & 0xff000000) != 0) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1520
1521   cycles += 2;        /* TODO: + mv oscillator clock cycles */
1522   return 1;
1523}
1524
1525/* OR : .... .... 0010 F1JJ : A-176 */
1526static size_t dsp56k_op_or(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1527{
1528   typed_pointer S = {NULL, DT_BYTE};
1529   typed_pointer D = {NULL, DT_BYTE};
1530
1531   decode_JJF_table(cpustate, BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S, &D);
1532
1533   /* Save some data for the parallel move */
1534   *p_accum = *((UINT64*)D.addr);
1535
1536   /* OR a word of S with A1|B1 */
1537   ((PAIR64*)D.addr)->w.h = *((UINT16*)S.addr) | ((PAIR64*)D.addr)->w.h;
1538
1539   d_register->addr = D.addr;
1540   d_register->data_type = D.data_type;
1541
1542   /* S L E U N Z V C */
1543   /* * * - - ? ? 0 - */
1544   /* TODO: S, L */
1545   if ( *((UINT64*)D.addr) & U64(0x0000000080000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1546   if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1547   DSP56K_V_CLEAR();
1548
1549   cycles += 2;        /* TODO: + mv oscillator cycles */
1550   return 1;
1551}
1552
1553/* ASR : .... .... 0011 F000 : A-32 */
1554static size_t dsp56k_op_asr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1555{
1556   typed_pointer D = {NULL, DT_BYTE};
1557   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1558
1559   *p_accum = *((UINT64*)D.addr);
1560
1561   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) >> 1;
1562
1563   /* Make sure the MSB is maintained */
1564   if (*p_accum & U64(0x0000008000000000))
1565      *((UINT64*)D.addr) |= U64(0x0000008000000000);
1566   else
1567      *((UINT64*)D.addr) &= (~U64(0x0000008000000000));
1568
1569   /* For the parallel move */
1570   d_register->addr = D.addr;
1571   d_register->data_type = D.data_type;
1572
1573   /* S L E U N Z V C */
1574   /* * * * * * * 0 ? */
1575   /* TODO: S, L, E, U */
1576   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1577   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1578   DSP56K_V_CLEAR();
1579   if (*p_accum & U64(0x0000000000000001))           DSP56K_C_SET(); else DSP56K_C_CLEAR();
1580
1581   cycles += 2;        /* TODO: + mv oscillator cycles */
1582   return 1;
1583}
1584
1585/* ASL : .... .... 0011 F001 : A-28 */
1586static size_t dsp56k_op_asl(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1587{
1588   /* S L E U N Z V C */
1589   /* * * * * * * ? ? */
1590   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significant
1591          bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
1592   /* C - Set if bit 39 of source operand is set. Cleared otherwise. */
1593   return 0;
1594}
1595
1596/* LSR : .... .... 0011 F010 : A-120 */
1597static size_t dsp56k_op_lsr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1598{
1599   typed_pointer D = {NULL, DT_BYTE};
1600   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1601
1602   *p_accum = *((UINT64*)D.addr);
1603
1604   ((PAIR64*)D.addr)->w.h = (((PAIR64*)D.addr)->w.h) >> 1;
1605
1606   /* Make sure bit 31 gets a 0 */
1607   ((PAIR64*)D.addr)->w.h &= (~0x8000);
1608
1609   /* For the parallel move */
1610   d_register->addr = D.addr;
1611   d_register->data_type = D.data_type;
1612
1613   /* S L E U N Z V C */
1614   /* * * - - ? ? 0 ? */
1615   /* TODO: S, L */
1616   DSP56K_N_CLEAR();
1617   if (((PAIR64*)D.addr)->w.h == 0)        DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1618   DSP56K_V_CLEAR();
1619   if (*p_accum & U64(0x0000000000010000)) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1620
1621   cycles += 2;        /* TODO: + mv oscillator cycles */
1622   return 1;
1623}
1624
1625/* LSL : .... .... 0011 F011 : A-118 */
1626static size_t dsp56k_op_lsl(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1627{
1628   /* S L E U N Z V C */
1629   /* * * - - ? ? 0 ? */
1630   /* N - Set if bit 31 of the result is set. Cleared otherwise. */
1631   /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
1632   /* C - Set if bit 31 of the source operand is set. Cleared otherwise. */
1633   return 0;
1634}
1635
1636/* EOR : .... .... 0011 F1JJ : A-94 */
1637static size_t dsp56k_op_eor(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1638{
1639   /* S L E U N Z V C */
1640   /* * * - - ? ? 0 - */
1641   /* N - Set if bit 31 of the result is set. Cleared otherwise. */
1642   /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
1643   return 0;
1644}
1645
1646/* SUBL : .... .... 0100 F001 : A-204 */
1647static size_t dsp56k_op_subl(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1648{
1649   /* S L E U N Z V C */
1650   /* * * * * * * ? * */
1651   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significant
1652          bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
1653   return 0;
1654}
1655
1656/* SUB : .... .... 0100 FJJJ : A-202 */
1657static size_t dsp56k_op_sub(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1658{
1659   UINT64 useVal = 0;
1660   typed_pointer S = {NULL, DT_BYTE};
1661   typed_pointer D = {NULL, DT_BYTE};
1662
1663   decode_JJJF_table(cpustate, BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S, &D);
1664
1665   /* Get on with it. */
1666   switch(S.data_type)
1667   {
1668      case DT_WORD:        useVal = (UINT64)*((UINT16*)S.addr) << 16; break;
1669      case DT_DOUBLE_WORD: useVal = (UINT64)*((UINT32*)S.addr);       break;
1670      case DT_LONG_WORD:   useVal = (UINT64)*((UINT64*)S.addr);       break;
1671   }
1672
1673   /* Sign-extend word for proper sub op */
1674   if ((S.data_type == DT_WORD) && useVal & U64(0x0000000080000000))
1675      useVal |= U64(0x000000ff00000000);
1676
1677   /* Make sure they're both real 40-bit values */
1678   useVal &= U64(0x000000ffffffffff);
1679   *((UINT64*)D.addr) &= U64(0x000000ffffffffff);
1680
1681   /* Operate*/
1682   *((UINT64*)D.addr) -= useVal;
1683
1684   d_register->addr = D.addr;
1685   d_register->data_type = D.data_type;
1686
1687   /* S L E U N Z V C */
1688   /* * * * * * * * * */
1689   /* TODO S, L, E, U */
1690   if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1691   if ( *((UINT64*)D.addr) == 0)                     DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1692   if ((*((UINT64*)D.addr) & U64(0xffffff0000000000)) != 0) DSP56K_V_SET(); else DSP56K_V_CLEAR();
1693   if ((*((UINT64*)D.addr) & U64(0xffffff0000000000)) != 0) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1694
1695   cycles += 2;        /* TODO: + mv oscillator cycles */
1696   return 1;
1697}
1698
1699/* CLR24 : .... .... 0101 F001 : A-62 */
1700static size_t dsp56k_op_clr24(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1701{
1702   /* S L E U N Z V C */
1703   /* * * * * * ? 0 - */
1704   /* Z - Set if the 24 most significant bits of the destination result are all zeroes. */
1705   return 0;
1706}
1707
1708/* SBC : .... .... 0101 F01J : A-198 */
1709static size_t dsp56k_op_sbc(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1710{
1711   /* S L E U N Z V C */
1712   /* * * * * * * * * */
1713   return 0;
1714}
1715
1716/* CMP : .... .... 0101 FJJJ : A-64 */
1717static size_t dsp56k_op_cmp(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1718{
1719   UINT64 cmpVal = 0;
1720   UINT64 result = 0;
1721
1722   typed_pointer S = {NULL, DT_BYTE};
1723   typed_pointer D = {NULL, DT_BYTE};
1724
1725   decode_JJJF_table(cpustate, BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
1726
1727   *p_accum = *((UINT64*)D.addr);
1728
1729   switch(S.data_type)
1730   {
1731      case DT_WORD:        cmpVal = (UINT64)*((UINT16*)S.addr) << 16;  break;
1732      case DT_DOUBLE_WORD: cmpVal = (UINT64)*((UINT32*)S.addr);  break;
1733      case DT_LONG_WORD:   cmpVal = (UINT64)*((UINT64*)S.addr);  break;
1734   }
1735
1736   /* Sign-extend word for proper subtraction op */
1737   if ((S.data_type == DT_WORD) && cmpVal & U64(0x0000000080000000))
1738      cmpVal |= U64(0x000000ff00000000);
1739
1740   /* Make sure they're both real 40-bit values */
1741   cmpVal &= U64(0x000000ffffffffff);
1742   *((UINT64*)D.addr) &= U64(0x000000ffffffffff);
1743
1744   /* Operate */
1745   result = *((UINT64*)D.addr) - cmpVal;
1746
1747   d_register->addr = D.addr;
1748   d_register->data_type = D.data_type;
1749
1750   /* S L E U N Z V C */
1751   /* * * * * * * * * */
1752   /* TODO: S, L, E, U */
1753   if ( result & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
1754   if ( result == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1755   if ((result & U64(0xffffff0000000000)) != 0) DSP56K_V_SET(); else DSP56K_V_CLEAR();
1756   if ((result & U64(0xffffff0000000000)) != 0) DSP56K_C_SET(); else DSP56K_C_CLEAR();
1757
1758
1759   cycles += 2;        /* TODO: + mv oscillator clock cycles */
1760   return 1;
1761}
1762
1763/* NEG : .... .... 0110 F000 : A-166 */
1764static size_t dsp56k_op_neg(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1765{
1766   /* S L E U N Z V C */
1767   /* * * * * * * * * */
1768   return 0;
1769}
1770
1771/* NOT : .... .... 0110 F001 : A-174 */
1772static size_t dsp56k_op_not(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1773{
1774   typed_pointer D = {NULL, DT_BYTE};
1775   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1776
1777   *p_accum = *((UINT64*)D.addr);
1778
1779   /* Invert bits [16:31] of D */
1780   ((PAIR64*)D.addr)->w.h = ~(((PAIR64*)D.addr)->w.h);
1781
1782   d_register->addr = D.addr;
1783   d_register->data_type = D.data_type;
1784
1785   /* S L E U N Z V C */
1786   /* * * - - ? ? 0 - */
1787   /* TODO: S?, L */
1788   if ( *((UINT64*)D.addr) & U64(0x0000000080000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1789   if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1790   DSP56K_V_CLEAR();
1791
1792   cycles += 2;        /* TODO: + mv oscillator cycles */
1793   return 1;
1794}
1795
1796/* DEC : .... .... 0110 F010 : A-72 */
1797static size_t dsp56k_op_dec(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1798{
1799   /* S L E U N Z V C */
1800   /* * * * * * * * * */
1801   return 0;
1802}
1803
1804/* DEC24 : .... .... 0110 F011 : A-74 */
1805static size_t dsp56k_op_dec24(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1806{
1807   UINT32 workBits24;
1808
1809   typed_pointer D = {NULL, DT_BYTE};
1810   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1811
1812   /* Save some data for the parallel move */
1813   *p_accum = *((UINT64*)D.addr);
1814
1815   /* TODO: I wonder if workBits24 should be signed? */
1816   workBits24 = ((*((UINT64*)D.addr)) & U64(0x000000ffffff0000)) >> 16;
1817   workBits24--;
1818   workBits24 &= 0x00ffffff;       /* Solves -x issues */
1819
1820   /* Set the D bits with the dec result */
1821   *((UINT64*)D.addr) &= U64(0x000000000000ffff);
1822   *((UINT64*)D.addr) |= (((UINT64)(workBits24)) << 16);
1823
1824   d_register->addr = D.addr;
1825   d_register->data_type = D.data_type;
1826
1827   /* S L E U N Z V C */
1828   /* * * * * * ? * * */
1829   /* TODO: S, L, E, U, V, C */
1830   if ( *((UINT64*)D.addr) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1831   if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1832
1833   cycles += 2;        /* TODO: + mv oscillator clock cycles */
1834   return 1;
1835}
1836
1837/* AND : .... .... 0110 F1JJ : A-24 */
1838static size_t dsp56k_op_and(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1839{
1840   typed_pointer S = {NULL, DT_BYTE};
1841   typed_pointer D = {NULL, DT_BYTE};
1842
1843   decode_JJF_table(cpustate, BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S, &D);
1844
1845   /* Save some data for the parallel move */
1846   *p_accum = *((UINT64*)D.addr);
1847
1848   /* AND a word of S with A1|B1 */
1849   ((PAIR64*)D.addr)->w.h = *((UINT16*)S.addr) & ((PAIR64*)D.addr)->w.h;
1850
1851   d_register->addr = D.addr;
1852   d_register->data_type = D.data_type;
1853
1854   /* S L E U N Z V C */
1855   /* * * - - ? ? 0 - */
1856   /* TODO: S, L */
1857   if ( *((UINT64*)D.addr) & U64(0x0000000080000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1858   if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1859   DSP56K_V_CLEAR();
1860
1861   cycles += 2;        /* TODO: + mv oscillator cycles */
1862   return 1;
1863}
1864
1865/* ABS : .... .... 0111 F001 : A-18 */
1866static size_t dsp56k_op_abs(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1867{
1868   INT64 opD = 0;
1869   typed_pointer D = {NULL, DT_LONG_WORD};
1870
1871   decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
1872
1873   *p_accum = *((UINT64*)D.addr);
1874
1875   /* Sign extend D into a temp variable */
1876   opD = *p_accum;
1877   if (opD &  U64(0x0000008000000000))
1878      opD |= U64(0xffffff0000000000);
1879   else
1880      opD &= U64(0x000000ffffffffff);
1881
1882   /* Take the absolute value and clean up */
1883   opD = (opD < 0) ? -opD : opD;
1884   opD &= U64(0x000000ffffffffff);
1885
1886   /* Reassign */
1887   *((UINT64*)D.addr) = opD;
1888
1889   /* Special overflow case */
1890   if ((*p_accum) == U64(0x0000008000000000))
1891      *((UINT64*)D.addr) = U64(0x0000007fffffffff);
1892
1893   /* S L E U N Z V C */
1894   /* * * * * * * * - */
1895   /* TODO: S, L, E, U */
1896   if ( *((UINT64*)D.addr) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1897   if ((*((UINT64*)D.addr) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1898   if ((*p_accum)         == U64(0x0000008000000000))       DSP56K_V_SET(); else DSP56K_V_CLEAR();
1899
1900   cycles += 2;            /* TODO: + mv oscillator clock cycles */
1901   return 1;
1902}
1903
1904/* ROR : .... .... 0111 F010 : A-192 */
1905static size_t dsp56k_op_ror(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1906{
1907   /* S L E U N Z V C */
1908   /* * * - - ? ? 0 ? */
1909   /* N - Set if bit 31 of the result is set. Cleared otherwise. */
1910   /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
1911   /* C - Set if bit 16 of the source operand is set. Cleared otherwise. */
1912   return 0;
1913}
1914
1915/* ROL : .... .... 0111 F011 : A-190 */
1916static size_t dsp56k_op_rol(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1917{
1918   /* S L E U N Z V C */
1919   /* * * - - ? ? 0 ? */
1920   /* N - Set if bit 31 of the result is set. Cleared otherwise. */
1921   /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
1922   /* C - Set if bit 31 of the source operand is set. Cleared otherwise. */
1923   return 0;
1924}
1925
1926/* CMPM : .... .... 0111 FJJJ : A-66 */
1927static size_t dsp56k_op_cmpm(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1928{
1929   INT64 absS;
1930   INT64 absD;
1931   INT64 absResult;
1932
1933   typed_pointer S = {NULL, DT_BYTE};
1934   typed_pointer D = {NULL, DT_BYTE};
1935
1936   decode_JJJF_table(cpustate, BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
1937
1938   *p_accum = *((UINT64*)D.addr);
1939
1940   /* Sign extend and get absolute value of the source */
1941   if (S.addr == &A || S.addr == &B)
1942   {
1943      absS = *((UINT64*)S.addr);
1944      if (absS &  U64(0x0000008000000000))
1945         absS |= U64(0xffffff8000000000);
1946   }
1947   else
1948   {
1949      absS = (*((UINT16*)S.addr)) << 16;
1950      if (absS &  U64(0x0000000080000000))
1951         absS |= U64(0xffffffff80000000);
1952   }
1953   absS = (absS < 0) ? -absS : absS;
1954
1955   /* Sign extend and get absolute value of the destination */
1956   if (D.addr == &A || D.addr == &B)
1957   {
1958      absD = *((UINT64*)D.addr);
1959      if (absD &  U64(0x0000008000000000))
1960         absD |= U64(0xffffff8000000000);
1961   }
1962   else
1963   {
1964      absD = (*((UINT16*)D.addr)) << 16;
1965      if (absS &  U64(0x0000000080000000))
1966         absS |= U64(0xffffffff80000000);
1967   }
1968   absD = (absD < 0) ? -absD : absD;
1969
1970   /* Compare */
1971   absResult = absD - absS;
1972
1973   d_register->addr = D.addr;
1974   d_register->data_type = D.data_type;
1975
1976   /* S L E U N Z V C */
1977   /* * * * * * * * * */
1978   /* TODO: S, L, E, U */
1979   if ( (absResult) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
1980   if (((absResult) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
1981   if ( (absResult  & U64(0xffffff0000000000)) != 0)  DSP56K_V_SET(); else DSP56K_V_CLEAR();
1982   if ( (absResult  & U64(0xffffff0000000000)) != 0)  DSP56K_C_SET(); else DSP56K_C_CLEAR();
1983
1984   cycles += 2;        /* TODO: +mv oscillator cycles */
1985   return 1;
1986}
1987
1988/* MPY : .... .... 1k00 FQQQ : A-160    -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */
1989static size_t dsp56k_op_mpy(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
1990{
1991   UINT16 k = 0;
1992   INT64 result = 0;
1993
1994   INT32 s1 = 0;
1995   INT32 s2 = 0;
1996
1997   void* D = NULL;
1998   void* S1 = NULL;
1999   void* S2 = NULL;
2000
2001   decode_QQQF_table(cpustate, BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D);
2002
2003   k = BITS(op_byte,0x0040);
2004
2005   /* Cast both values as being signed */
2006   s1 = *((INT16*)S1);
2007   s2 = *((INT16*)S2);
2008
2009   /* Fixed-point 2's complement multiplication requires a shift */
2010   result = (s1 * s2) << 1;
2011
2012   /* Negate the product if necessary */
2013   if (k)
2014      result *= -1;
2015
2016   (*((UINT64*)D)) = result & U64(0x000000ffffffffff);
2017
2018   /* S L E U N Z V C */
2019   /* * * * * * * * - */
2020   /* TODO: S, L, E, V */
2021   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
2022   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2023
2024   cycles += 2;        /* TODO: +mv oscillator cycles */
2025   return 1;
2026}
2027
2028/* MPYR : .... .... 1k01 FQQQ : A-162 */
2029static size_t dsp56k_op_mpyr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
2030{
2031   /* S L E U N Z V C */
2032   /* * * * * * * * - */
2033   return 0;
2034}
2035
2036/* MAC : .... .... 1k10 FQQQ : A-122 */
2037static size_t dsp56k_op_mac(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
2038{
2039   UINT16 k = 0;
2040   INT64 opD = 0;
2041   INT64 result = 0;
2042
2043   INT32 s1 = 0;
2044   INT32 s2 = 0;
2045
2046   void* D = NULL;
2047   void* S1 = NULL;
2048   void* S2 = NULL;
2049
2050   decode_QQQF_table(cpustate, BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D);
2051
2052   k = BITS(op_byte,0x0040);
2053
2054   /* Cast both values as being signed */
2055   s1 = *((INT16*)S1);
2056   s2 = *((INT16*)S2);
2057
2058   /* Fixed-point 2's complement multiplication requires a shift */
2059   result = (s1 * s2) << 1;
2060
2061   /* Sign extend D into a temp variable */
2062   opD = (*((UINT64*)D));
2063   if (opD & U64(0x0000008000000000))
2064      opD |= U64(0xffffff0000000000);
2065   else
2066      opD &= U64(0x000000ffffffffff);
2067
2068   /* Negate if necessary */
2069   if (k)
2070      result *= -1;
2071
2072   /* Accumulate */
2073   opD += result;
2074
2075   /* And out the bits that don't live in the register */
2076   opD &= U64(0x000000ffffffffff);
2077
2078   (*((UINT64*)D)) = (UINT64)opD;
2079
2080   /* For the parallel move */
2081   d_register->addr = D;
2082   d_register->data_type = DT_LONG_WORD;
2083
2084   /* S L E U N Z V C */
2085   /* * * * * * * * - */
2086   /* TODO: S, L, E, V */
2087   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
2088   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2089
2090   cycles += 2;        /* TODO: +mv oscillator cycles */
2091   return 1;
2092}
2093
2094/* MACR : .... .... 1k11 FQQQ : A-124   -- DRAMA - rr vs xx (805) */
2095static size_t dsp56k_op_macr(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
2096{
2097   UINT16 k = 0;
2098   INT64 opD = 0;
2099   INT64 result = 0;
2100
2101   INT32 s1 = 0;
2102   INT32 s2 = 0;
2103
2104   void* D = NULL;
2105   void* S1 = NULL;
2106   void* S2 = NULL;
2107
2108   decode_QQQF_table(cpustate, BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D);
2109
2110   k = BITS(op_byte,0x0040);
2111
2112   /* Cast both values as being signed */
2113   s1 = *((INT16*)S1);
2114   s2 = *((INT16*)S2);
2115
2116   /* Fixed-point 2's complement multiplication requires a shift */
2117   result = (s1 * s2) << 1;
2118
2119   /* Sign extend D into a temp variable */
2120   opD = (*((UINT64*)D));
2121   if (opD & U64(0x0000008000000000))
2122      opD |= U64(0xffffff0000000000);
2123   else
2124      opD &= U64(0x000000ffffffffff);
2125
2126   /* Negate if necessary */
2127   if (k)
2128      result *= -1;
2129
2130   /* Accumulate */
2131   opD += result;
2132
2133   /* Round the result */
2134   /* WARNING : ROUNDING NOT FULLY IMPLEMENTED YET! */
2135   if ((opD & U64(0x000000000000ffff)) >= 0x8000)
2136      opD += U64(0x0000000000010000);
2137
2138   opD &= U64(0x000000ffffff0000);
2139
2140   /* And out the bits that don't live in the register */
2141   opD &= U64(0x000000ffffffffff);
2142
2143   /* Store the result */
2144   (*((UINT64*)D)) = (UINT64)opD;
2145
2146   /* For the parallel move */
2147   d_register->addr = D;
2148   d_register->data_type = DT_LONG_WORD;
2149
2150   /* S L E U N Z V C */
2151   /* * * * * * * * - */
2152   /* TODO: S, L, E, V */
2153   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
2154   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2155
2156   cycles += 2;        /* TODO: +mv oscillator cycles */
2157   return 1;
2158}
2159
2160
2161/******************************/
2162/* Remaining non-parallel ops */
2163/******************************/
2164
2165/* ADC : 0001 0101 0000 F01J : A-20 */
2166static size_t dsp56k_op_adc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2167{
2168   /* S L E U N Z V C */
2169   /* - * * * * * * * */
2170   return 0;
2171}
2172
2173/* ANDI : 0001 1EE0 iiii iiii : A-26 */
2174static size_t dsp56k_op_andi(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2175{
2176   UINT16 immediate = BITS(op,0x00ff);
2177
2178   /* There is not currently a good way to refer to CCR or MR.  Explicitly decode here. */
2179   switch(BITS(op,0x0600))
2180   {
2181      case 0x01:  /* MR */
2182         SR &= ((immediate << 8) | 0x00ff);
2183         break;
2184
2185      case 0x02:  /* CCR */
2186         SR &= (immediate | 0xff00);
2187         break;
2188
2189      case 0x03:  /* OMR */
2190         OMR &= (UINT8)(immediate);
2191         break;
2192
2193      default:
2194         fatalerror("DSP56k - BAD EE value in andi operation\n") ;
2195   }
2196
2197   /* S L E U N Z V C */
2198   /* - ? ? ? ? ? ? ? */
2199   /* All ? bits - Cleared if the corresponding bit in the immediate data is cleared and if the operand
2200      is the CCR. Not affected otherwise. */
2201   cycles += 2;
2202   return 1;
2203}
2204
2205/* ASL4 : 0001 0101 0011 F001 : A-30 */
2206static size_t dsp56k_op_asl4(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2207{
2208   UINT64 p_accum = 0;
2209   typed_pointer D = {NULL, DT_BYTE};
2210   decode_F_table(cpustate, BITS(op,0x0008), &D);
2211
2212   p_accum = *((UINT64*)D.addr);
2213
2214   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) << 4;
2215   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) & U64(0x000000ffffffffff);
2216
2217   /* S L E U N Z V C */
2218   /* - ? * * * * ? ? */
2219   /* TODO: L, E, U  */
2220   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if bit 35 through 39 are
2221          not the same. */
2222   /* C - Set if bit 36 of source operand is set. Cleared otherwise. */
2223   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
2224   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2225   if ( (*((UINT64*)D.addr) & U64(0x000000ff00000000)) != (p_accum & U64(0x000000ff00000000)) ) DSP56K_V_SET(); else DSP56K_V_CLEAR();
2226   if (p_accum & U64(0x0000001000000000))            DSP56K_C_SET(); else DSP56K_C_CLEAR();
2227
2228   cycles += 2;
2229   return 1;
2230}
2231
2232/* ASR4 : 0001 0101 0011 F000 : A-34 */
2233static size_t dsp56k_op_asr4(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2234{
2235   UINT64 p_accum = 0;
2236   typed_pointer D = {NULL, DT_BYTE};
2237   decode_F_table(cpustate, BITS(op,0x0008), &D);
2238
2239   p_accum = *((UINT64*)D.addr);
2240
2241   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) >> 4;
2242   *((UINT64*)D.addr) = (*((UINT64*)D.addr)) & U64(0x000000ffffffffff);
2243
2244   /* The top 4 bits become the old bit 39 */
2245   if (p_accum & U64(0x0000008000000000))
2246      *((UINT64*)D.addr) |= U64(0x000000f000000000);
2247   else
2248      *((UINT64*)D.addr) &= (~U64(0x000000f000000000));
2249
2250   /* S L E U N Z V C */
2251   /* - * * * * * 0 ? */
2252   /* TODO: E, U  */
2253   /* C - Set if bit 3 of source operand is set. Cleared otherwise. */
2254   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
2255   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2256   DSP56K_V_CLEAR();
2257   if (p_accum & U64(0x0000000000000008))            DSP56K_C_SET(); else DSP56K_C_CLEAR();
2258
2259   cycles += 2;
2260   return 1;
2261}
2262
2263/* ASR16 : 0001 0101 0111 F000 : A-36 */
2264static size_t dsp56k_op_asr16(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2265{
2266   UINT64 backupVal;
2267   typed_pointer D = {NULL, DT_BYTE};
2268
2269   decode_F_table(cpustate, BITS(op,0x0008), &D);
2270
2271   backupVal = *((UINT64*)D.addr);
2272
2273   *((UINT64*)D.addr) = *((UINT64*)D.addr) >> 16;
2274
2275   if(backupVal & U64(0x0000008000000000))
2276      *((UINT64*)D.addr) |= U64(0x000000ffff000000);
2277   else
2278      *((UINT64*)D.addr) &= U64(0x0000000000ffffff);
2279
2280   /* S L E U N Z V C */
2281   /* - * * * * * 0 ? */
2282   /* TODO: E, U */
2283   if (*((UINT64*)D.addr) & U64(0x0000008000000000)) DSP56K_N_SET(); else DSP56K_N_CLEAR();
2284   if (*((UINT64*)D.addr) == 0)                      DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2285   DSP56K_V_CLEAR();
2286   if (backupVal & U64(0x0000000000008000))          DSP56K_C_SET(); else DSP56K_C_CLEAR();
2287
2288   cycles += 2;
2289   return 1;
2290}
2291
2292/* BFCHG  : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */
2293/* BFCLR  : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */
2294/* BFSET  : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */
2295/* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */
2296/* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */
2297static size_t dsp56k_op_bfop(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2298{
2299   UINT16 workAddr = 0x0000;
2300   UINT16 workingWord = 0x0000;
2301   UINT16 previousValue = 0x0000;
2302   typed_pointer tempTP = { NULL, DT_BYTE };
2303
2304   UINT16 iVal = op2 & 0x00ff;
2305   decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal);
2306
2307   workAddr = assemble_address_from_Pppppp_table(cpustate, BITS(op,0x0020), BITS(op,0x001f));
2308   previousValue = cpustate->data->read_word(ADDRESS(workAddr));
2309   workingWord = previousValue;
2310
2311   switch(BITS(op2, 0x1f00))
2312   {
2313      case 0x12:  /* BFCHG */
2314         workingWord ^= iVal;
2315         break;
2316      case 0x04:  /* BFCLR */
2317         workingWord = workingWord & (~iVal);
2318         break;
2319      case 0x18:  /* BFSET */
2320         workingWord = workingWord | iVal;
2321         break;
2322      case 0x10:  /* BFTSTH */
2323         /* Just the test below */
2324         break;
2325      case 0x00:  /* BFTSTL */
2326         /* Just the test below */
2327         break;
2328   }
2329
2330   tempTP.addr = &workingWord;
2331   tempTP.data_type = DT_WORD;
2332   SetDataMemoryValue(cpustate, tempTP, ADDRESS(workAddr));
2333
2334   /* S L E U N Z V C */
2335   /* - * - - - - - ? */
2336   /* TODO: L */
2337   switch(BITS(op2, 0x1f00))
2338   {
2339      case 0x12:  /* BFCHG */
2340         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2341      case 0x04:  /* BFCLR */
2342         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2343      case 0x18:  /* BFSET */
2344         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2345      case 0x10:  /* BFTSTH */
2346         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2347      case 0x00:  /* BFTSTL */
2348         if ((iVal & previousValue) == 0x0000) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2349   }
2350
2351   cycles += 4;    /* TODO: + mvb oscillator clock cycles */
2352   return 2;
2353}
2354
2355/* BFCHG  : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */
2356/* BFCLR  : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */
2357/* BFSET  : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */
2358/* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */
2359/* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */
2360static size_t dsp56k_op_bfop_1(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2361{
2362   UINT16 workAddr = 0x0000;
2363   UINT16 workingWord = 0x0000;
2364   UINT16 previousValue = 0x0000;
2365   typed_pointer R = { NULL, DT_BYTE };
2366   typed_pointer tempTP = { NULL, DT_BYTE };
2367
2368   UINT16 iVal = op2 & 0x00ff;
2369   decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal);
2370
2371   decode_RR_table(cpustate, BITS(op,0x0003), &R);
2372
2373   workAddr = *((UINT16*)R.addr);
2374   previousValue = cpustate->data->read_word(ADDRESS(workAddr));
2375   workingWord = previousValue;
2376
2377   switch(BITS(op2, 0x1f00))
2378   {
2379      case 0x12:  /* BFCHG */
2380         workingWord ^= iVal;
2381         break;
2382      case 0x04:  /* BFCLR */
2383         workingWord = workingWord & (~iVal);
2384         break;
2385      case 0x18:  /* BFSET */
2386         workingWord = workingWord | iVal;
2387         break;
2388      case 0x10:  /* BFTSTH */
2389         /* Just the test below */
2390         break;
2391      case 0x00:  /* BFTSTL */
2392         /* Just the test below */
2393         break;
2394   }
2395
2396   tempTP.addr = &workingWord;
2397   tempTP.data_type = DT_WORD;
2398   SetDataMemoryValue(cpustate, tempTP, ADDRESS(workAddr));
2399
2400   /* S L E U N Z V C */
2401   /* - * - - - - - ? */
2402   /* TODO: L */
2403   switch(BITS(op2, 0x1f00))
2404   {
2405      case 0x12:  /* BFCHG */
2406         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2407      case 0x04:  /* BFCLR */
2408         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2409      case 0x18:  /* BFSET */
2410         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2411      case 0x10:  /* BFTSTH */
2412         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2413      case 0x00:  /* BFTSTL */
2414         if ((iVal & previousValue) == 0x0000) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2415   }
2416
2417   cycles += 4;    /* TODO: + mvb oscillator clock cycles */
2418   return 2;
2419}
2420
2421/* BFCHG  : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */
2422/* BFCLR  : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */
2423/* BFSET  : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */
2424/* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */
2425/* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */
2426static size_t dsp56k_op_bfop_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2427{
2428   UINT16 workingWord = 0x0000;
2429   UINT16 previousValue = 0x0000;
2430
2431   UINT16 iVal = op2 & 0x00ff;
2432   typed_pointer S = { NULL, DT_BYTE };
2433
2434   decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal);
2435   decode_DDDDD_table(cpustate, BITS(op,0x001f), &S);
2436
2437   /* A & B are special */
2438   if (S.data_type == DT_LONG_WORD)
2439      previousValue = ((PAIR64*)S.addr)->w.h;
2440   else
2441      previousValue = *((UINT16*)S.addr);
2442
2443   workingWord = previousValue;
2444
2445   switch(BITS(op2, 0x1f00))
2446   {
2447      case 0x12:  /* BFCHG */
2448         workingWord ^= iVal;
2449         break;
2450      case 0x04:  /* BFCLR */
2451         workingWord = workingWord & (~iVal);
2452         break;
2453      case 0x18:  /* BFSET */
2454         workingWord = workingWord | iVal;
2455         break;
2456      case 0x10:  /* BFTSTH */
2457         /* Just the test below */
2458         break;
2459      case 0x00:  /* BFTSTL */
2460         /* Just the test below */
2461         break;
2462   }
2463
2464   /* Put the data back where it belongs (A & B are special) */
2465   if (S.data_type == DT_LONG_WORD)
2466      ((PAIR64*)S.addr)->w.h = workingWord;
2467   else
2468      *((UINT16*)S.addr) = workingWord;
2469
2470   /* S L E U N Z V C */
2471   /* - * - - - - - ? */
2472   /* TODO: L */
2473   switch(BITS(op2, 0x1f00))
2474   {
2475      case 0x12:  /* BFCHG */
2476         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2477      case 0x04:  /* BFCLR */
2478         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2479      case 0x18:  /* BFSET */
2480         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2481      case 0x10:  /* BFTSTH */
2482         if ((iVal & previousValue) == iVal) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2483      case 0x00:  /* BFTSTL */
2484         if ((iVal & previousValue) == 0x0000) DSP56K_C_SET(); else DSP56K_C_CLEAR(); break;
2485   }
2486
2487   cycles += 4;    /* TODO: + mvb oscillator clock cycles */
2488   return 2;
2489}
2490
2491/* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */
2492static size_t dsp56k_op_bcc(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2493{
2494   int shouldBranch = decode_cccc_table(cpustate, BITS(op,0x000f));
2495
2496   if (shouldBranch)
2497   {
2498      INT16 offset = (INT16)op2;
2499
2500      PC += 2;
2501
2502      cpustate->ppc = PC;
2503      PC += offset;
2504
2505      cycles += 4;
2506      return 0;
2507   }
2508   else
2509   {
2510      cycles += 4;
2511      return 2;
2512   }
2513
2514   /* S L E U N Z V C */
2515   /* - - - - - - - - */
2516   return 0;
2517}
2518
2519/* Bcc : 0010 11cc ccee eeee : A-48 */
2520static size_t dsp56k_op_bcc_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2521{
2522   int shouldBranch = decode_cccc_table(cpustate, BITS(op,0x03c0));
2523
2524   if (shouldBranch)
2525   {
2526      INT16 offset = (INT16)assemble_address_from_6bit_signed_relative_short_address(cpustate, BITS(op,0x003f));
2527
2528      PC += 1;
2529
2530      cpustate->ppc = PC;
2531      PC += offset;
2532
2533      cycles += 4;
2534      return 0;
2535   }
2536   else
2537   {
2538      cycles += 4;
2539      return 1;
2540   }
2541
2542   /* S L E U N Z V C */
2543   /* - - - - - - - - */
2544   return 0;
2545}
2546
2547/* Bcc : 0000 0111 RR10 cccc : A-48 */
2548static size_t dsp56k_op_bcc_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2549{
2550   /* S L E U N Z V C */
2551   /* - - - - - - - - */
2552   return 0;
2553}
2554
2555/* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */
2556static size_t dsp56k_op_bra(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2557{
2558   /* S L E U N Z V C */
2559   /* - - - - - - - - */
2560   return 0;
2561}
2562
2563/* BRA : 0000 1011 aaaa aaaa : A-50 */
2564static size_t dsp56k_op_bra_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2565{
2566   /* 8 bit immediate, relative offset */
2567   INT8 branchOffset = (INT8)BITS(op,0x00ff);
2568
2569   /* "The PC Contains the address of the next instruction" */
2570   PC += 1;
2571
2572   /* Jump */
2573   cpustate->ppc = PC;
2574   PC += branchOffset;
2575
2576   /* S L E U N Z V C */
2577   /* - - - - - - - - */
2578   cycles += 4; /* TODO: + jx oscillator clock cycles */
2579   return 0;
2580}
2581
2582/* BRA : 0000 0001 0010 11RR : A-50 */
2583static size_t dsp56k_op_bra_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2584{
2585   /* S L E U N Z V C */
2586   /* - - - - - - - - */
2587   return 0;
2588}
2589
2590/* BRKcc : 0000 0001 0001 cccc : A-52 */
2591static size_t dsp56k_op_brkcc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2592{
2593   int shouldBreak = decode_cccc_table(cpustate, BITS(op,0x000f));
2594
2595   if (shouldBreak)
2596   {
2597      /* TODO: I think this PC = LA thing is off-by-1, but it's working this way because its consistently so */
2598      cpustate->ppc = PC;
2599      PC = LA;
2600
2601      SR = SSL;   /* TODO: A-83.  I believe only the Loop Flag and Forever Flag come back here. */
2602      SP--;
2603
2604      LA = SSH;
2605      LC = SSL;
2606      SP--;
2607
2608      cycles += 8;
2609      return 0;
2610   }
2611   else
2612   {
2613      cycles += 2;
2614      return 1;
2615   }
2616
2617   /* S L E U N Z V C */
2618   /* - - - - - - - - */
2619   return 0;
2620}
2621
2622/* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */
2623static size_t dsp56k_op_bscc(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2624{
2625   int shouldBranch = decode_cccc_table(cpustate, BITS(op,0x000f));
2626
2627   if (shouldBranch)
2628   {
2629      /* The PC Contains the address of the next instruction */
2630      PC += 2;
2631
2632      /* Push */
2633      SP++;
2634      SSH = PC;
2635      SSL = SR;
2636
2637      /* Change */
2638      cpustate->ppc = PC;
2639      PC = PC + (INT16)op2;
2640
2641      /* S L E U N Z V C */
2642      /* - - - - - - - - */
2643      cycles += 4;        /* TODO: + jx oscillator clock cycles */
2644      return 0;
2645   }
2646
2647   /* S L E U N Z V C */
2648   /* - - - - - - - - */
2649   cycles += 4;        /* TODO: + jx oscillator clock cycles */
2650   return 2;
2651}
2652
2653/* BScc : 0000 0111 RR00 cccc : A-54 */
2654static size_t dsp56k_op_bscc_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2655{
2656   /* S L E U N Z V C */
2657   /* - - - - - - - - */
2658   return 0;
2659}
2660
2661/* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */
2662static size_t dsp56k_op_bsr(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2663{
2664   /* The PC Contains the address of the next instruction */
2665   PC += 2;
2666
2667   /* Push */
2668   SP++;
2669   SSH = PC;
2670   SSL = SR;
2671
2672   /* Change */
2673   cpustate->ppc = PC;
2674   PC = PC + (INT16)op2;
2675
2676   /* S L E U N Z V C */
2677   /* - - - - - - - - */
2678   cycles += 4;    /* TODO: + jx oscillator clock cycles */
2679   return 0;
2680}
2681
2682/* BSR : 0000 0001 0010 10RR : A-56 */
2683static size_t dsp56k_op_bsr_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2684{
2685   /* S L E U N Z V C */
2686   /* - - - - - - - - */
2687   return 0;
2688}
2689
2690/* CHKAAU : 0000 0000 0000 0100 : A-58 */
2691static size_t dsp56k_op_chkaau(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2692{
2693   /* S L E U N Z V C */
2694   /* - - - - ? ? ? - */
2695   /* V - Set if the result of the last address ALU update performed a modulo wrap. Cleared if
2696          result of the last address ALU did not perform a modulo wrap.*/
2697   /* Z - Set if the result of the last address ALU update is 0. Cleared if the result of the last
2698          address ALU is positive. */
2699   /* N - Set if the result of the last address ALU update is negative. Cleared if the result of the
2700          last address ALU is positive. */
2701   return 0;
2702}
2703
2704/* DEBUG : 0000 0000 0000 0001 : A-68 */
2705static size_t dsp56k_op_debug(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2706{
2707   /* S L E U N Z V C */
2708   /* - - - - - - - - */
2709   return 0;
2710}
2711
2712/* DEBUGcc : 0000 0000 0101 cccc : A-70 */
2713static size_t dsp56k_op_debugcc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2714{
2715   /* S L E U N Z V C */
2716   /* - - - - - - - - */
2717   return 0;
2718}
2719
2720/* DIV : 0001 0101 0--0 F1DD : A-76 */
2721/* WARNING : DOCS SAY THERE IS A PARALLEL MOVE HERE !!! */
2722static size_t dsp56k_op_div(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2723{
2724   /* WARNING : THIS DOES NOT WORK.  IT DOESN'T EVEN TRY !!! */
2725   typed_pointer S = {NULL, DT_BYTE};
2726   typed_pointer D = {NULL, DT_BYTE};
2727
2728   decode_DDF_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S, &D);
2729
2730   /* S L E U N Z V C */
2731   /* - * - - - - ? ? */
2732   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significantst
2733          bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
2734   /* C - Set if bit 39 of the result is cleared. Cleared otherwise. */
2735   cycles += 2;
2736   return 1;
2737}
2738
2739/* DMAC : 0001 0101 10s1 FsQQ : A-80 */
2740static size_t dsp56k_op_dmac(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2741{
2742   UINT8 ss = 0;
2743   INT64 result = 0;
2744
2745   void* D = NULL;
2746   void* S1 = NULL;
2747   void* S2 = NULL;
2748
2749   decode_QQF_special_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S1, &S2, &D);
2750
2751   ss = BITS(op,0x0024);
2752
2753   /* Fixed-point 2's complement multiplication requires a shift */
2754   if (ss == 0x00 || ss == 0x01)
2755   {
2756      /* Signed * Signed */
2757      INT32 s1 = ((INT32)(*((UINT16*)S1)));
2758      INT32 s2 = ((INT32)(*((UINT16*)S2)));
2759      result = ( s1 * s2 ) << 1;
2760   }
2761   else if (ss == 0x2)
2762   {
2763      /* Signed * Unsigned */
2764      /* WARNING : THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
2765      INT32 s1 = ((INT32)(*((UINT16*)S1)));
2766      INT32 s2 = (UINT32)(*((UINT16*)S2));
2767      result = ( s1 * s2 ) << 1;
2768   }
2769   else if (ss == 0x3)
2770   {
2771      /* Unsigned * Unsigned */
2772      UINT32 s1 = (UINT32)(*((UINT16*)S1));
2773      UINT32 s2 = (UINT32)(*((UINT16*)S2));
2774      result = ( s1 * s2 ) << 1;
2775   }
2776
2777   /* Shift right, then accumulate */
2778   (*((UINT64*)D)) =  (*((UINT64*)D)) >> 16;
2779   (*((UINT64*)D)) += result;
2780
2781   /* S L E U N Z V C */
2782   /* - * * * * * * - */
2783   /* TODO: L, E, U, V */
2784   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
2785   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
2786
2787   cycles += 2;
2788   return 1;
2789}
2790
2791/* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */
2792static size_t dsp56k_op_do(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2793{
2794   /* S L E U N Z V C */
2795   /* - * - - - - - - */
2796   return 0;
2797}
2798
2799/* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */
2800static size_t dsp56k_op_do_1(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2801{
2802   UINT8 retSize = 0;
2803   UINT8 iValue = BITS(op,0x00ff);
2804
2805   /* Don't execute if the loop counter == 0 */
2806   if (iValue != 0x00)
2807   {
2808      /* First instruction cycle */
2809      SP++;                       /* TODO: Should i really inc here first? */
2810      SSH = LA;
2811      SSL = LC;
2812      LC = (UINT16)iValue;
2813
2814
2815      /* Second instruction cycle */
2816      SP++;                       /* TODO: See above */
2817      SSH = PC + 2;               /* Keep these stack entries in 'word-based-index' space */
2818      SSL = SR;
2819      LA = PC + 2 + op2;          /* TODO: The docs subtract 1 from here? */
2820
2821
2822      /* Third instruction cycle */
2823      LF_bit_set(cpustate, 1);
2824
2825      /* Undocumented, but it must be true to nest Dos in DoForevers */
2826      FV_bit_set(cpustate, 0);
2827
2828
2829      /* S L E U N Z V C */
2830      /* - * - - - - - - */
2831      /* TODO : L */
2832
2833      cycles += 6;    /* TODO: + mv oscillator cycles */
2834      retSize = 2;
2835   }
2836   else
2837   {
2838      /* Skip over the contents of the loop */
2839      cpustate->ppc = PC;
2840      PC = PC + 2 + op2;
2841
2842      cycles += 10;   /* TODO: + mv oscillator cycles */
2843      retSize = 0;
2844   }
2845
2846   return retSize;
2847}
2848
2849/* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */
2850static size_t dsp56k_op_do_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2851{
2852   UINT8 retSize = 0;
2853   UINT16 lValue = 0x0000;
2854   typed_pointer S = {NULL, DT_BYTE};
2855   decode_DDDDD_table(cpustate, BITS(op,0x001f), &S);
2856
2857   /* TODO: Does not properly shift-limit sources A&B - Fix per the docs. */
2858   /* TODO: There are other cases besides A&B this code won't work. */
2859   if      (S.addr == &A) lValue = *((UINT16*)(&A1));
2860   else if (S.addr == &B) lValue = *((UINT16*)(&B1));
2861   else                   lValue = *((UINT16*)S.addr);
2862
2863   /* HACK */
2864   if (lValue >= 0xfff0)
2865   {
2866      logerror("Dsp56k : DO_2 operation changed %04x to 0000.\n", lValue);
2867      lValue = 0x0000;
2868   }
2869
2870   /* TODO: Fix for special cased SP S */
2871   if (S.addr == &SP)
2872      logerror("DSP56k: do with SP as the source not properly implemented yet.\n");
2873
2874   /* TODO: Fix for special cased SSSL S */
2875   if (S.addr == &SSL)
2876      logerror("DSP56k: do with SP as the source not properly implemented yet.\n");
2877
2878   /* Don't execute if the loop counter == 0 */
2879   if (lValue != 0x00)
2880   {
2881      /* First instruction cycle */
2882      SP++;                       /* TODO: Should i really inc here first? */
2883      SSH = LA;
2884      SSL = LC;
2885      LC = (UINT16)lValue;
2886
2887
2888      /* Second instruction cycle */
2889      SP++;                       /* TODO: See above */
2890      SSH = PC + 2;               /* Keep these stack entries in 'word-based-index' space */
2891      SSL = SR;
2892      LA = PC + 2 + op2;          /* TODO: The docs subtract 1 from here? */
2893
2894
2895      /* Third instruction cycle */
2896      LF_bit_set(cpustate, 1);
2897
2898
2899      /* S L E U N Z V C */
2900      /* - * - - - - - - */
2901      /* TODO : L */
2902
2903      cycles += 6;    /* TODO: + mv oscillator cycles */
2904      retSize = 2;
2905   }
2906   else
2907   {
2908      /* Skip over the contents of the loop */
2909      cpustate->ppc = PC;
2910      PC = PC + 2 + op2;
2911
2912      cycles += 10;   /* TODO: + mv oscillator cycles */
2913      retSize = 0;
2914   }
2915
2916   return retSize;
2917}
2918
2919/* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */
2920static size_t dsp56k_op_doforever(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
2921{
2922   /* First instruction cycle */
2923   SP++;
2924   SSH = LA;
2925   SSL = LC;
2926
2927   /* Second instruction cycle */
2928   SP++;
2929   SSH = PC + 2;
2930   SSL = SR;
2931   LA = PC + 2 + op2;
2932
2933   /* Third instruction cycle */
2934   LF_bit_set(cpustate, 1);
2935   FV_bit_set(cpustate, 1);
2936
2937   /* S L E U N Z V C */
2938   /* - - - - - - - - */
2939   cycles += 6;
2940   return 2;
2941}
2942
2943/* ENDDO : 0000 0000 0000 1001 : A-92 */
2944static size_t dsp56k_op_enddo(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2945{
2946   /* S L E U N Z V C */
2947   /* - - - - - - - - */
2948   return 0;
2949}
2950
2951/* EXT : 0001 0101 0101 F010 : A-96 */
2952static size_t dsp56k_op_ext(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2953{
2954   /* S L E U N Z V C */
2955   /* - * * * * * * - */
2956   return 0;
2957}
2958
2959/* ILLEGAL : 0000 0000 0000 1111 : A-98 */
2960static size_t dsp56k_op_illegal(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2961{
2962   /* S L E U N Z V C */
2963   /* - - - - - - - - */
2964   return 0;
2965}
2966
2967/* IMAC : 0001 0101 1010 FQQQ : A-100 */
2968static size_t dsp56k_op_imac(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
2969{
2970   INT64 opD = 0;
2971   INT64 result = 0;
2972
2973   INT32 s1 = 0;
2974   INT32 s2 = 0;
2975
2976   void* D = NULL;
2977   void* S1 = NULL;
2978   void* S2 = NULL;
2979
2980   decode_QQQF_table(cpustate, BITS(op,0x0007), BITS(op,0x0008), &S1, &S2, &D);
2981
2982   /* Cast both values as being signed */
2983   s1 = *((INT16*)S1);
2984   s2 = *((INT16*)S2);
2985
2986   /* Integral multiply doesn't require the shift */
2987   result = (s1 * s2);
2988
2989   /* Shift result 16 bits to the left before adding to destination */
2990   result = (result << 16) & 0xffff0000;
2991
2992   /* Sign extend D into a temp variable */
2993   opD = (*((UINT64*)D));
2994   if (opD & U64(0x0000008000000000))
2995      opD |= U64(0xffffff0000000000);
2996   else
2997      opD &= U64(0x000000ffffffffff);
2998
2999   /* Accumulate */
3000   opD += result;
3001
3002   /* And out the bits that don't live in the register */
3003   opD &= U64(0x000000ffffffffff);
3004
3005   (*((UINT64*)D)) = (UINT64)opD;
3006
3007   /* S L E U N Z V C */
3008   /* - * ? ? * ? ? - */
3009   /* TODO: L */
3010   /* U,E - Will not be set correctly by this instruction*/
3011   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
3012   if ((*((UINT64*)D) & U64(0x000000ffffff0000)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
3013   DSP56K_V_CLEAR();
3014
3015   cycles += 2;
3016   return 1;
3017}
3018
3019/* IMPY : 0001 0101 1000 FQQQ : A-102 */
3020static size_t dsp56k_op_impy(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3021{
3022   /* S L E U N Z V C */
3023   /* - * ? ? * ? ? - */
3024   /* Z - Set if the 24 most significant bits of the destination result are all zeroes. */
3025   /* U,E - Will not be set correctly by this instruction*/
3026   /* V - Set to zero regardless of the overflow */
3027   return 0;
3028}
3029
3030/* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */
3031static size_t dsp56k_op_jcc(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3032{
3033   /* S L E U N Z V C */
3034   /* - - - - - - - - */
3035   return 0;
3036}
3037
3038/* Jcc : 0000 0110 RR10 cccc : A-108 */
3039static size_t dsp56k_op_jcc_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3040{
3041   /* S L E U N Z V C */
3042   /* - - - - - - - - */
3043   return 0;
3044}
3045
3046/* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */
3047static size_t dsp56k_op_jmp(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3048{
3049   cpustate->ppc = PC;
3050   PC = op2;
3051
3052   /* S L E U N Z V C */
3053   /* - - - - - - - - */
3054
3055   cycles += 4;    /* TODO: + jx */
3056   return 0;
3057}
3058
3059/* JMP : 0000 0001 0010 01RR : A-110 */
3060static size_t dsp56k_op_jmp_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3061{
3062   typed_pointer R = { NULL, DT_BYTE };
3063   decode_RR_table(cpustate, BITS(op,0x0003), &R);
3064
3065   cpustate->ppc = PC;
3066   PC = *((UINT16*)R.addr);
3067
3068   /* S L E U N Z V C */
3069   /* - - - - - - - - */
3070
3071   cycles += 4;    /* TODO: + jx */
3072   return 0;
3073}
3074
3075/* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */
3076static size_t dsp56k_op_jscc(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3077{
3078   int shouldJump = decode_cccc_table(cpustate, BITS(op,0x000f));
3079
3080   if(shouldJump)
3081   {
3082      /* TODO: It says "signed" absolute offset.  Weird. */
3083      UINT16 branchOffset = op2;
3084
3085      /* TODO: Verify, since it's not in the docs, but it must be true */
3086      PC += 2;
3087
3088      SP++;
3089      SSH = PC;
3090      SSL = SR;
3091
3092      cpustate->ppc = PC;
3093      PC = branchOffset;
3094
3095      cycles += 4;    /* TODO: +jx oscillator clock cycles */
3096      return 0;
3097   }
3098   else
3099   {
3100      cycles += 4;    /* TODO: +jx oscillator clock cycles */
3101      return 2;
3102   }
3103
3104   /* S L E U N Z V C */
3105   /* - - - - - - - - */
3106   return 0;
3107}
3108
3109/* JScc : 0000 0110 RR00 cccc : A-112 */
3110static size_t dsp56k_op_jscc_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3111{
3112   /* S L E U N Z V C */
3113   /* - - - - - - - - */
3114   return 0;
3115}
3116
3117/* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */
3118static size_t dsp56k_op_jsr(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3119{
3120   /* TODO: It says "signed" absolute offset.  Weird. */
3121   UINT16 branchOffset = op2;
3122
3123   /* TODO: Verify, since it's not in the docs, but it must be true */
3124   PC += 2;
3125
3126   /* TODO: This is a hacky implementation of Long vs Fast Interrupts.  Do it right someday! */
3127   if (PC < ADDRESS(0x40))
3128   {
3129      /* Long interrupt gets the previous PC, not the current one */
3130      SP++;
3131      SSH = cpustate->ppc;
3132      SSL = SR;
3133
3134      cpustate->ppc = cpustate->ppc;
3135      PC = branchOffset;
3136   }
3137   else
3138   {
3139      /* Normal operation */
3140      SP++;
3141      SSH = PC;
3142      SSL = SR;
3143
3144      cpustate->ppc = PC;
3145      PC = branchOffset;
3146   }
3147
3148   /* S L E U N Z V C */
3149   /* - - - - - - - - */
3150   cycles += 4;        /* TODO: + jx oscillator cycles */
3151   return 0;
3152}
3153
3154/* JSR : 0000 1010 AAAA AAAA : A-114 */
3155static size_t dsp56k_op_jsr_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3156{
3157   /* S L E U N Z V C */
3158   /* - - - - - - - - */
3159   return 0;
3160}
3161
3162/* JSR : 0000 0001 0010 00RR : A-114 */
3163static size_t dsp56k_op_jsr_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3164{
3165   /* S L E U N Z V C */
3166   /* - - - - - - - - */
3167   return 0;
3168}
3169
3170/* LEA : 0000 0001 11TT MMRR : A-116 */
3171static size_t dsp56k_op_lea(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3172{
3173   UINT16 ea = 0;
3174   UINT16 *rX = NULL;
3175   UINT16 *nX = NULL;
3176   typed_pointer D = {NULL, DT_BYTE};
3177   decode_TT_table(cpustate, BITS(op,0x0030), &D);
3178
3179   /* TODO: change the execute_mm_functions to return values.  Maybe */
3180   /* Because this calculation isn't applied, do everything locally */
3181   /* RR table */
3182   switch(BITS(op,0x0003))
3183   {
3184      case 0x0: rX = &R0;  nX = &N0;  break;
3185      case 0x1: rX = &R1;  nX = &N1;  break;
3186      case 0x2: rX = &R2;  nX = &N2;  break;
3187      case 0x3: rX = &R3;  nX = &N3;  break;
3188   }
3189
3190   /* MM table */
3191   switch(BITS(op,0x000c))
3192   {
3193      case 0x0: ea = *rX;       break;
3194      case 0x1: ea = *rX + 1;   break;
3195      case 0x2: ea = *rX - 1;   break;
3196      case 0x3: ea = *rX + *nX; break;
3197   }
3198
3199   *((UINT16*)D.addr) = ea;
3200
3201   /* S L E U N Z V C */
3202   /* - - - - - - - - */
3203   return 1;
3204}
3205
3206/* LEA : 0000 0001 10NN MMRR : A-116 */
3207static size_t dsp56k_op_lea_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3208{
3209   /* S L E U N Z V C */
3210   /* - - - - - - - - */
3211   return 0;
3212}
3213
3214/* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */
3215static size_t dsp56k_op_macsuuu(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3216{
3217   UINT8 s = 0;
3218   INT64 result = 0;
3219
3220   void* D = NULL;
3221   void* S1 = NULL;
3222   void* S2 = NULL;
3223
3224   decode_QQF_special_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S1, &S2, &D);
3225
3226   s = BITS(op,0x0004);
3227
3228   /* Fixed-point 2's complement multiplication requires a shift */
3229   if (s)
3230   {
3231      /* Unsigned * Unsigned */
3232      UINT32 s1 = (UINT32)(*((UINT16*)S1));
3233      UINT32 s2 = (UINT32)(*((UINT16*)S2));
3234      result = ( s1 * s2 ) << 1;
3235   }
3236   else
3237   {
3238      /* Signed * Unsigned */
3239      /* WARNING : THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
3240      INT32 s1 = ((INT32)(*((UINT16*)S1)));
3241      INT32 s2 = (UINT32)(*((UINT16*)S2));
3242      result = ( s1 * s2 ) << 1;
3243   }
3244
3245   (*((UINT64*)D)) += result;
3246
3247   /* And out the bits that don't live in the register */
3248   (*((UINT64*)D)) &= U64(0x000000ffffffffff);
3249
3250   /* S L E U N Z V C */
3251   /* - * * * * * * - */
3252   /* TODO: L, E, U, V */
3253   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
3254   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
3255
3256   cycles += 2;
3257   return 1;
3258}
3259
3260/* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */
3261static size_t dsp56k_op_move_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3262{
3263   /* S L E U N Z V C */
3264   /* * * - - - - - - */
3265   return 0;
3266}
3267
3268/* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */
3269static size_t dsp56k_op_movec(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3270{
3271   UINT8 W;
3272   typed_pointer R = { NULL, DT_BYTE };
3273   typed_pointer SD = { NULL, DT_BYTE };
3274
3275   W = BITS(op,0x0400);
3276   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &SD);
3277   decode_RR_table(cpustate, BITS(op,0x0003), &R);
3278
3279   if (W)
3280   {
3281      /* Write D */
3282      UINT16 value = cpustate->data->read_word(ADDRESS(*((UINT16*)R.addr))) ;
3283      typed_pointer temp_src = { &value, DT_WORD };
3284      SetDestinationValue(temp_src, SD);
3285   }
3286   else
3287   {
3288      /* Read S */
3289      UINT16 dataMemOffset = *((UINT16*)R.addr);
3290      SetDataMemoryValue(cpustate, SD, ADDRESS(dataMemOffset));
3291   }
3292
3293   execute_MM_table(cpustate, BITS(op,0x0003), BITS(op,0x000c));
3294
3295   /* S L E U N Z V C */
3296   /* * ? ? ? ? ? ? ? */
3297   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3298      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3299      limiting occurred. All ? bits are not affected otherwise.*/
3300   if (W && (SD.addr != &SR))
3301   {
3302      /* If you're writing to something other than the SR */
3303      /* TODO */
3304   }
3305
3306   cycles += 2;    /* TODO: + mvc */
3307   return 1;
3308}
3309
3310/* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */
3311static size_t dsp56k_op_movec_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3312{
3313   UINT8 W;
3314   UINT16 memOffset;
3315   typed_pointer SD = {NULL, DT_BYTE};
3316
3317   W = BITS(op,0x0400);
3318   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &SD);
3319   memOffset = execute_q_table(cpustate, BITS(op,0x0003), BITS(op,0x0008));
3320
3321   if (W)
3322   {
3323      /* Write D */
3324      UINT16 tempData = cpustate->data->read_word(ADDRESS(memOffset));
3325      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3326      SetDestinationValue(temp_src, SD);
3327   }
3328   else
3329   {
3330      /* Read S */
3331      UINT16 tempData = *((UINT16*)SD.addr);
3332      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3333      SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset));
3334   }
3335
3336   /* S L E U N Z V C */
3337   /* * ? ? ? ? ? ? ? */
3338   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3339      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3340      limiting occurred. All ? bits are not affected otherwise.*/
3341   if (W && (SD.addr != &SR))
3342   {
3343      /* If you're writing to something other than the SR */
3344      /* TODO */
3345   }
3346
3347   cycles += 2;        /* + mvc oscillator clock cycles */
3348   return 1;
3349}
3350
3351/* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */
3352static size_t dsp56k_op_movec_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3353{
3354   UINT8 W;
3355   UINT16 memOffset;
3356   typed_pointer SD = {NULL, DT_BYTE};
3357   typed_pointer XMemOffset = {NULL, DT_BYTE};
3358
3359   W = BITS(op,0x0400);
3360   decode_Z_table(cpustate, BITS(op,0x0008), &XMemOffset);
3361   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &SD);
3362
3363   memOffset = *((UINT16*)XMemOffset.addr);
3364
3365   if (W)
3366   {
3367      /* Write D */
3368      UINT16 tempData = cpustate->data->read_word(ADDRESS(memOffset));
3369      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3370      SetDestinationValue(temp_src, SD);
3371   }
3372   else
3373   {
3374      /* Read S */
3375      UINT16 tempData = *((UINT16*)SD.addr);
3376      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3377      SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset));
3378   }
3379
3380
3381   /* S L E U N Z V C */
3382   /* * ? ? ? ? ? ? ? */
3383   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3384      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3385      limiting occurred. All ? bits are not affected otherwise.*/
3386   if (W && (SD.addr != &SR))
3387   {
3388      /* If you're writing to something other than the SR */
3389      /* TODO */
3390   }
3391
3392   cycles += 2;        /* + mvc oscillator clock cycles */
3393   return 1;
3394}
3395
3396/* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */
3397static size_t dsp56k_op_movec_3(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3398{
3399   UINT8 W;
3400   UINT8 t;
3401   typed_pointer SD = { NULL, DT_BYTE };
3402
3403   W = BITS(op,0x0400);
3404   t = BITS(op,0x0008);
3405   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &SD);
3406
3407   if (W)
3408   {
3409      /* Write D */
3410      if (t)
3411      {
3412         /* 16-bit long data */
3413         typed_pointer temp_src = { (void*)&op2, DT_WORD };
3414         SetDestinationValue(temp_src, SD);
3415      }
3416      else
3417      {
3418         /* 16-bit long address */
3419         UINT16 tempD = cpustate->data->read_word(ADDRESS(op2));
3420         typed_pointer tempTP = {&tempD, DT_WORD};
3421         SetDestinationValue(tempTP, SD);
3422      }
3423   }
3424   else
3425   {
3426      /* Read S */
3427      if (t)
3428      {
3429         /* 16-bit long data */
3430         logerror("DSP56k: Movec - I don't think this exists?");
3431      }
3432      else
3433      {
3434         /* 16-bit long address */
3435         SetDataMemoryValue(cpustate, SD, ADDRESS(op2));
3436      }
3437   }
3438
3439   /* S L E U N Z V C */
3440   /* * ? ? ? ? ? ? ? */
3441   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3442      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3443      limiting occurred. All ? bits are not affected otherwise.*/
3444   if (W && (SD.addr != &SR))
3445   {
3446      /* If you're writing to something other than the SR */
3447      /* TODO */
3448   }
3449
3450   cycles += 2;    /* TODO: + mvc */
3451   return 2;
3452}
3453
3454/* MOVE(C) : 0010 10dd dddD DDDD : A-144 */
3455static size_t dsp56k_op_movec_4(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3456{
3457   typed_pointer S = {NULL, DT_BYTE};
3458   typed_pointer D = {NULL, DT_BYTE};
3459
3460   decode_DDDDD_table(cpustate, BITS(op,0x03e0), &S);
3461   decode_DDDDD_table(cpustate, BITS(op,0x001f), &D);
3462
3463   SetDestinationValue(S, D);
3464
3465   /* S L E U N Z V C */
3466   /* * ? ? ? ? ? ? ? */
3467   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3468      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3469      limiting occurred. All ? bits are not affected otherwise.*/
3470   if (D.addr != &SR)
3471   {
3472      /* If you're writing to something other than the SR */
3473      /* TODO */
3474   }
3475
3476   cycles += 2;
3477   return 1;
3478}
3479
3480/* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */
3481static size_t dsp56k_op_movec_5(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3482{
3483   INT8 xx;
3484   UINT8 W;
3485   UINT16 memOffset;
3486   typed_pointer SD = { NULL, DT_BYTE };
3487
3488   xx = (INT8)(op & 0x00ff);
3489   W = BITS(op2,0x0400);
3490   decode_DDDDD_table(cpustate, BITS(op2,0x03e0), &SD);
3491
3492   memOffset = R2 + (INT16)xx;
3493
3494   if (W)
3495   {
3496      /* Write D */
3497      UINT16 tempData = cpustate->data->read_word(ADDRESS(memOffset));
3498      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3499      SetDestinationValue(temp_src, SD);
3500   }
3501   else
3502   {
3503      /* Read S */
3504      UINT16 tempData = *((UINT16*)SD.addr);
3505      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
3506      SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset));
3507   }
3508
3509   /* S L E U N Z V C */
3510   /* * ? ? ? ? ? ? ? */
3511   /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
3512      bit of the source operand. If SR is not specified as a destination operand, L is set if data
3513      limiting occurred. All ? bits are not affected otherwise.*/
3514   if (W && (SD.addr != &SR))
3515   {
3516      /* If you're writing to something other than the SR */
3517      /* TODO */
3518   }
3519
3520   cycles += 2;    /* TODO: + mvc oscillator clock cycles */
3521   return 2;
3522}
3523
3524/* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */
3525static size_t dsp56k_op_movei(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3526{
3527   typed_pointer D = {NULL, DT_BYTE};
3528   typed_pointer immTP = {NULL, DT_BYTE};
3529
3530   /* Typecasting to INT16 sign-extends the BBBBBBBB operand */
3531   UINT16 immediateSignExtended = (INT16)(op & 0x00ff);
3532   immTP.addr = &immediateSignExtended;
3533   immTP.data_type = DT_WORD;
3534
3535   decode_DD_table(cpustate, BITS(op,0x0300), &D);
3536
3537   SetDestinationValue(immTP, D);
3538
3539   /* S L E U N Z V C */
3540   /* - - - - - - - - */
3541   cycles += 2;
3542   return 1;
3543}
3544
3545/* MOVE(M) : 0000 001W RR0M MHHH : A-152 */
3546static size_t dsp56k_op_movem(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3547{
3548   UINT8 W;
3549   typed_pointer R = { NULL, DT_BYTE };
3550   typed_pointer SD = { NULL, DT_BYTE };
3551
3552   W = BITS(op,0x0100);
3553   decode_RR_table(cpustate, BITS(op,0x00c0), &R);
3554   decode_HHH_table(cpustate, BITS(op,0x0007), &SD);
3555
3556   if (W)
3557   {
3558      /* Read from Program Memory */
3559      typed_pointer data;
3560      UINT16 ldata = cpustate->program->read_word(ADDRESS(*((UINT16*)R.addr)));
3561
3562      data.addr = &ldata;
3563      data.data_type = DT_WORD;
3564      SetDestinationValue(data, SD) ;
3565   }
3566   else
3567   {
3568      /* Write to Program Memory */
3569      SetProgramMemoryValue(cpustate, SD, ADDRESS(*((UINT16*)R.addr))) ;
3570   }
3571
3572   execute_MM_table(cpustate, BITS(op,0x00c0), BITS(op,0x0018));
3573
3574   /* S L E U N Z V C */
3575   /* * * - - - - - - */
3576   /* TODO: S, L */
3577   cycles += 2;    /* TODO: + mvm oscillator clock cycles */
3578   return 1;
3579}
3580
3581/* MOVE(M) : 0000 001W RR11 mmRR : A-152 */
3582static size_t dsp56k_op_movem_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3583{
3584   /* S L E U N Z V C */
3585   /* * * - - - - - - */
3586   return 0;
3587}
3588
3589/* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */
3590static size_t dsp56k_op_movem_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
3591{
3592   /* S L E U N Z V C */
3593   /* * * - - - - - - */
3594   return 0;
3595}
3596
3597/* MOVE(P) : 0001 100W HH1p pppp : A-156 */
3598static size_t dsp56k_op_movep(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3599{
3600   UINT16 W;
3601   UINT16 pp;
3602   typed_pointer SD = {NULL, DT_BYTE};
3603
3604   decode_HH_table(cpustate, BITS(op,0x00c0), &SD);
3605   /* TODO: Special cases for A & B */
3606
3607   pp = op & 0x001f;
3608   pp = assemble_address_from_IO_short_address(cpustate, pp);
3609
3610   W = BITS(op,0x0100);
3611
3612   if (W)
3613   {
3614      UINT16 data = cpustate->data->read_word(ADDRESS(pp));
3615
3616      typed_pointer tempTP;
3617      tempTP.addr = &data;
3618      tempTP.data_type = DT_WORD;
3619
3620      SetDestinationValue(tempTP, SD);
3621   }
3622   else
3623   {
3624      SetDataMemoryValue(cpustate, SD, ADDRESS(pp));
3625   }
3626
3627   /* S L E U N Z V C */
3628   /* * * - - - - - - */
3629   /* TODO: S, L */
3630
3631   cycles += 4;        /* TODO: + mvp oscillator cycles */
3632   return 1;
3633}
3634
3635/* MOVE(P) : 0000 110W RRmp pppp : A-156 */
3636static size_t dsp56k_op_movep_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3637{
3638   /* X:<Rx> and X:<pp> */
3639   UINT16 W;
3640   UINT16 pp;
3641
3642   typed_pointer SD = {NULL, DT_BYTE};
3643   decode_RR_table(cpustate, BITS(op,0x00c0), &SD);
3644
3645   pp = op & 0x001f;
3646   pp = assemble_address_from_IO_short_address(cpustate, pp);
3647
3648   W = BITS(op,0x0100);
3649
3650   /* A little different than most W if's - opposite read and write */
3651   if (W)
3652   {
3653      UINT16 data = cpustate->data->read_word(ADDRESS(*((UINT16*)SD.addr)));
3654
3655      typed_pointer tempTP;
3656      tempTP.addr = &data;
3657      tempTP.data_type = DT_WORD;
3658
3659      SetDataMemoryValue(cpustate, tempTP, ADDRESS(pp));
3660   }
3661   else
3662   {
3663      /* TODO */
3664      fatalerror("dsp56k : move(p) NOTHING HERE (yet)\n") ;
3665   }
3666
3667   /* Postincrement */
3668   execute_m_table(cpustate, BITS(op,0x00c0), BITS(op,0x0020));
3669
3670   /* S L E U N Z V C */
3671   /* * * - - - - - - */
3672   /* TODO: S, L */
3673   cycles += 4;        /* TODO: + mvp oscillator cycles */
3674   return 1;
3675}
3676
3677/* MOVE(S) : 0001 100W HH0a aaaa : A-158 */
3678static size_t dsp56k_op_moves(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3679{
3680   /* S L E U N Z V C */
3681   /* * * - - - - - - */
3682   return 0;
3683}
3684
3685/* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */
3686static size_t dsp56k_op_mpysuuu(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3687{
3688   UINT8 s = 0;
3689   INT64 result = 0;
3690
3691   void* D = NULL;
3692   void* S1 = NULL;
3693   void* S2 = NULL;
3694
3695   decode_QQF_special_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S1, &S2, &D);
3696
3697   s = BITS(op,0x0004);
3698
3699   /* Fixed-point 2's complement multiplication requires a shift */
3700   if (s)
3701   {
3702      /* Unsigned * Unsigned */
3703      UINT32 s1 = (UINT32)(*((UINT16*)S1));
3704      UINT32 s2 = (UINT32)(*((UINT16*)S2));
3705      result = ( s1 * s2 ) << 1;
3706   }
3707   else
3708   {
3709      /* Signed * Unsigned */
3710      /* WARNING : THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
3711      INT32 s1 = ((INT32)(*((UINT16*)S1)));
3712      INT32 s2 = (UINT32)(*((UINT16*)S2));
3713      result = ( s1 * s2 ) << 1;
3714   }
3715
3716   (*((UINT64*)D)) = result;
3717
3718   /* And out the bits that don't live in the register */
3719   (*((UINT64*)D)) &= U64(0x000000ffffffffff);
3720
3721   /* S L E U N Z V C */
3722   /* - * * * * * * - */
3723   /* TODO: L, E, U, V */
3724   if ( *((UINT64*)D) & U64(0x0000008000000000))       DSP56K_N_SET(); else DSP56K_N_CLEAR();
3725   if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
3726
3727   cycles += 2;
3728   return 1;
3729}
3730
3731/* NEGC : 0001 0101 0110 F000 : A-168 */
3732static size_t dsp56k_op_negc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3733{
3734   /* S L E U N Z V C */
3735   /* - * * * * * * * */
3736   return 0;
3737}
3738
3739/* NOP : 0000 0000 0000 0000 : A-170 */
3740static size_t dsp56k_op_nop(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3741{
3742   /* S L E U N Z V C */
3743   /* - - - - - - - - */
3744   return 1;
3745}
3746
3747/* NORM : 0001 0101 0010 F0RR : A-172 */
3748static size_t dsp56k_op_norm(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3749{
3750   /* S L E U N Z V C */
3751   /* - * * * * * ? - */
3752   /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significantst
3753          bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
3754   return 0;
3755}
3756
3757/* ORI : 0001 1EE1 iiii iiii : A-178 */
3758static size_t dsp56k_op_ori(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3759{
3760   /* S L E U N Z V C */
3761   /* - ? ? ? ? ? ? ? */
3762   /* All ? bits - Set if the corresponding bit in the immediate data is set and if the operand is the
3763      CCR. Not affected otherwise. */
3764   return 0;
3765}
3766
3767/* REP : 0000 0000 111- --RR : A-180 */
3768static size_t dsp56k_op_rep(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3769{
3770   /* S L E U N Z V C */
3771   /* - * - - - - - - */
3772   return 0;
3773}
3774
3775/* REP : 0000 1111 iiii iiii : A-180 */
3776static size_t dsp56k_op_rep_1(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3777{
3778   /* TODO: This is non-interruptable, probably have to turn off interrupts here */
3779   UINT16 iVal = op & 0x00ff;
3780
3781   if (iVal != 0)
3782   {
3783      TEMP = LC;
3784      LC = iVal;
3785
3786      cpustate->repFlag = 1;
3787      cpustate->repAddr = PC + ADDRESS(1);
3788
3789      cycles += 4;        /* TODO: + mv oscillator clock cycles */
3790   }
3791   else
3792   {
3793      cycles += 6;        /* TODO: + mv oscillator clock cycles */
3794   }
3795
3796
3797   /* S L E U N Z V C */
3798   /* - * - - - - - - */
3799   /* TODO: L */
3800   return 1;
3801}
3802
3803/* REP : 0000 0100 001D DDDD : A-180 */
3804static size_t dsp56k_op_rep_2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3805{
3806   /* TODO: This is non-interruptable, probably have to turn off interrupts here */
3807   UINT16 repValue;
3808   typed_pointer D = {NULL, DT_BYTE};
3809   decode_DDDDD_table(cpustate, BITS(op,0x001f), &D);
3810
3811   /* TODO: handle special A&B source cases */
3812   if (D.addr == &A || D.addr == &B)
3813      logerror("DSP56k ERROR : Rep with A or B instruction not implemented yet!\n");
3814
3815   repValue = *((UINT16*)D.addr);
3816
3817   if (repValue != 0)
3818   {
3819      TEMP = LC;
3820      LC = repValue;
3821
3822      cpustate->repFlag = 1;
3823      cpustate->repAddr = PC + ADDRESS(1);
3824
3825      cycles += 4;        /* TODO: + mv oscillator clock cycles */
3826   }
3827   else
3828   {
3829      cycles += 6;        /* TODO: + mv oscillator clock cycles */
3830   }
3831
3832   /* S L E U N Z V C */
3833   /* - * - - - - - - */
3834   /* TODO: L */
3835   return 1;
3836}
3837
3838/* REPcc : 0000 0001 0101 cccc : A-184 */
3839static size_t dsp56k_op_repcc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3840{
3841   /* S L E U N Z V C */
3842   /* - - - - - - - - */
3843   return 0;
3844}
3845
3846/* RESET : 0000 0000 0000 1000 : A-186 */
3847static size_t dsp56k_op_reset(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3848{
3849   /* S L E U N Z V C */
3850   /* - - - - - - - - */
3851   return 0;
3852}
3853
3854/* RTI : 0000 0000 0000 0111 : A-194 */
3855static size_t dsp56k_op_rti(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3856{
3857   /* WARNING : THERE SHOULD BE A MORE GENERAL HANDLING OF STACK ERRORS. */
3858   if (SP == 0)
3859   {
3860      dsp56k_add_pending_interrupt(cpustate, "Stack Error");
3861      return 0;
3862   }
3863
3864   cpustate->ppc = PC;
3865   PC = SSH;
3866
3867   SR = SSL;
3868   SP = SP - 1;
3869
3870   /* S L E U N Z V C */
3871   /* ? ? ? ? ? ? ? ? */
3872   /* All ? bits - Set according to value pulled from the stack. */
3873   cycles += 4;        /* TODO: + rx oscillator clock cycles */
3874   return 0;
3875}
3876
3877/* RTS : 0000 0000 0000 0110 : A-196 */
3878static size_t dsp56k_op_rts(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3879{
3880   /* Pop */
3881   cpustate->ppc = PC;
3882   PC = SSH;
3883
3884   /* SR = SSL; The status register is not affected. */
3885
3886   SP--;
3887
3888   /* S L E U N Z V C */
3889   /* - - - - - - - - */
3890   cycles += 4;    /* TODO: + rx oscillator clock cycles */
3891   return 0;
3892}
3893
3894/* STOP : 0000 0000 0000 1010 : A-200 */
3895static size_t dsp56k_op_stop(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3896{
3897   /* S L E U N Z V C */
3898   /* - - - - - - - - */
3899   return 0;
3900}
3901
3902/* SWAP : 0001 0101 0111 F001 : A-206 */
3903static size_t dsp56k_op_swap(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3904{
3905   /* S L E U N Z V C */
3906   /* - - - - - - - - */
3907   return 0;
3908}
3909
3910/* SWI : 0000 0000 0000 0101 : A-208 */
3911static size_t dsp56k_op_swi(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3912{
3913   /* S L E U N Z V C */
3914   /* - - - - - - - - */
3915   return 0;
3916}
3917
3918/* Tcc : 0001 00cc ccTT Fh0h : A-210 */
3919static size_t dsp56k_op_tcc(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3920{
3921   int shouldTransfer = decode_cccc_table(cpustate, BITS(op,0x03c0));
3922
3923   if (shouldTransfer)
3924   {
3925      typed_pointer S = {NULL, DT_BYTE};
3926      typed_pointer D = {NULL, DT_BYTE};
3927      typed_pointer S2 = {&R0, DT_WORD};
3928      typed_pointer D2 = {NULL, DT_BYTE};
3929
3930      decode_h0hF_table(cpustate, BITS(op,0x0007),BITS(op,0x0008), &S, &D);
3931      SetDestinationValue(S, D);
3932
3933      /* TODO: What's up with that A,A* thing in the docs?  Can you only ignore the R0->RX transfer if you do an A,A? */
3934      decode_RR_table(cpustate, BITS(op,0x0030), &D2); /* TT is the same as RR */
3935      SetDestinationValue(S2, D2);
3936   }
3937
3938   /* S L E U N Z V C */
3939   /* - - - - - - - - */
3940   cycles += 2;
3941   return 1;
3942}
3943
3944/* TFR(2) : 0001 0101 0000 F00J : A-214 */
3945static size_t dsp56k_op_tfr2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3946{
3947   typed_pointer S = {NULL, DT_BYTE};
3948   typed_pointer D = {NULL, DT_BYTE};
3949
3950   decode_JF_table(cpustate, BITS(op,0x0001), BITS(op,0x0008), &S, &D);
3951
3952   SetDestinationValue(S, D);
3953
3954   /* S L E U N Z V C */
3955   /* - * - - - - - - */
3956   /* TODO: L */
3957   cycles += 2;
3958   return 1;
3959}
3960
3961/* TFR(3) : 0010 01mW RRDD FHHH : A-216 */
3962static size_t dsp56k_op_tfr3(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3963{
3964   /* S L E U N Z V C */
3965   /* * * - - - - - - */
3966   return 0;
3967}
3968
3969/* TST(2) : 0001 0101 0001 -1DD : A-220 */
3970static size_t dsp56k_op_tst2(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3971{
3972   typed_pointer D = {NULL, DT_BYTE};
3973   decode_DD_table(cpustate, BITS(op,0x0003), &D);
3974
3975   /* S L E U N Z V C */
3976   /* - * * * * * 0 0 */
3977   /* (L,E,U should be set to 0) */
3978   DSP56K_L_CLEAR();
3979   DSP56K_E_CLEAR();
3980   /* U_CLEAR(); */ /* TODO: Conflicting opinions?  "Set if unnormalized."  Documentation is weird (A&B?) */
3981   if ((*((UINT16*)D.addr)) &  0x8000) DSP56K_N_SET(); else DSP56K_N_CLEAR();
3982   if ((*((UINT16*)D.addr)) == 0x0000) DSP56K_Z_SET(); else DSP56K_Z_CLEAR();
3983   /* DSP56K_V_CLEAR(); */ /* Unaffected */
3984   DSP56K_C_CLEAR();
3985
3986   cycles += 2;
3987   return 1;
3988}
3989
3990/* WAIT : 0000 0000 0000 1011 : A-222 */
3991static size_t dsp56k_op_wait(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
3992{
3993   /* S L E U N Z V C */
3994   /* - - - - - - - - */
3995   return 0;
3996}
3997
3998/* ZERO : 0001 0101 0101 F000 : A-224 */
3999static size_t dsp56k_op_zero(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
4000{
4001   /* S L E U N Z V C */
4002   /* - * * * * * * - */
4003   return 0;
4004}
4005
4006
4007
4008/***************************************************************************
4009    Table decoding
4010***************************************************************************/
4011static UINT16 decode_BBB_bitmask(dsp56k_core* cpustate, UINT16 BBB, UINT16 *iVal)
4012{
4013   UINT16 retVal = 0x0000;
4014
4015   switch(BBB)
4016   {
4017      case 0x4: retVal = 0xff00;  *iVal <<= 8;  break;
4018      case 0x2: retVal = 0x0ff0;  *iVal <<= 4;  break;
4019      case 0x1: retVal = 0x00ff;  *iVal <<= 0;  break;
4020   }
4021
4022   return retVal;
4023}
4024
4025static int decode_cccc_table(dsp56k_core* cpustate, UINT16 cccc)
4026{
4027   int retVal = 0;
4028
4029   /* Not fully tested */
4030   switch (cccc)
4031   {
4032      /* Arranged according to mnemonic table - not decoding table */
4033      case 0x0: if( C() == 0)                         retVal = 1;  break;  /* cc(hs) */
4034      case 0x8: if( C() == 1)                         retVal = 1;  break;  /* cs(lo) */
4035      case 0x5: if( E() == 0)                         retVal = 1;  break;  /* ec */
4036      case 0xa: if( Z() == 1)                         retVal = 1;  break;  /* eq */
4037      case 0xd: if( E() == 1)                         retVal = 1;  break;  /* es */
4038      case 0x1: if((N() ^  V()) == 0)                 retVal = 1;  break;  /* ge */
4039      case 0x7: if((Z() | (N() ^ V())) == 0)          retVal = 1;  break;  /* gt */
4040      case 0x6: if( L() == 0)                         retVal = 1;  break;  /* lc */
4041      case 0xf: if((Z() | (N() ^ V())) == 1)          retVal = 1;  break;  /* le */
4042      case 0xe: if( L() == 1)                         retVal = 1;  break;  /* ls */
4043      case 0x9: if((N() ^  V()) == 1)                 retVal = 1;  break;  /* lt */
4044      case 0xb: if( N() == 1)                         retVal = 1;  break;  /* mi */
4045      case 0x2: if( Z() == 0)                         retVal = 1;  break;  /* ne */
4046      case 0xc: if((Z() | ((!U()) & (!E()))) == 1)    retVal = 1;  break;  /* nr */
4047      case 0x3: if( N() == 0)                         retVal = 1;  break;  /* pl */
4048      case 0x4: if((Z() | ((!U()) & (!E()))) == 0)    retVal = 1;  break;  /* nn */
4049   }
4050
4051   return retVal;
4052}
4053
4054static void decode_DDDDD_table(dsp56k_core* cpustate, UINT16 DDDDD, typed_pointer* ret)
4055{
4056   switch(DDDDD)
4057   {
4058      case 0x00: ret->addr = &X0;  ret->data_type = DT_WORD;       break;
4059      case 0x01: ret->addr = &Y0;  ret->data_type = DT_WORD;       break;
4060      case 0x02: ret->addr = &X1;  ret->data_type = DT_WORD;       break;
4061      case 0x03: ret->addr = &Y1;  ret->data_type = DT_WORD;       break;
4062      case 0x04: ret->addr = &A ;  ret->data_type = DT_LONG_WORD;  break;
4063      case 0x05: ret->addr = &B ;  ret->data_type = DT_LONG_WORD;  break;
4064      case 0x06: ret->addr = &A0;  ret->data_type = DT_WORD;       break;
4065      case 0x07: ret->addr = &B0;  ret->data_type = DT_WORD;       break;
4066      case 0x08: ret->addr = &LC;  ret->data_type = DT_WORD;       break;
4067      case 0x09: ret->addr = &SR;  ret->data_type = DT_WORD;       break;
4068      case 0x0a: ret->addr = &OMR; ret->data_type = DT_BYTE;       break;
4069      case 0x0b: ret->addr = &SP;  ret->data_type = DT_BYTE;       break;
4070      case 0x0c: ret->addr = &A1;  ret->data_type = DT_WORD;       break;
4071      case 0x0d: ret->addr = &B1;  ret->data_type = DT_WORD;       break;
4072      case 0x0e: ret->addr = &A2;  ret->data_type = DT_BYTE;       break;
4073      case 0x0f: ret->addr = &B2;  ret->data_type = DT_BYTE;       break;
4074
4075      case 0x10: ret->addr = &R0;  ret->data_type = DT_WORD;       break;
4076      case 0x11: ret->addr = &R1;  ret->data_type = DT_WORD;       break;
4077      case 0x12: ret->addr = &R2;  ret->data_type = DT_WORD;       break;
4078      case 0x13: ret->addr = &R3;  ret->data_type = DT_WORD;       break;
4079      case 0x14: ret->addr = &M0;  ret->data_type = DT_WORD;       break;
4080      case 0x15: ret->addr = &M1;  ret->data_type = DT_WORD;       break;
4081      case 0x16: ret->addr = &M2;  ret->data_type = DT_WORD;       break;
4082      case 0x17: ret->addr = &M3;  ret->data_type = DT_WORD;       break;
4083      case 0x18: ret->addr = &SSH; ret->data_type = DT_WORD;       break;
4084      case 0x19: ret->addr = &SSL; ret->data_type = DT_WORD;       break;
4085      case 0x1a: ret->addr = &LA;  ret->data_type = DT_WORD;       break;
4086      /*no 0x1b  */
4087      case 0x1c: ret->addr = &N0;  ret->data_type = DT_WORD;       break;
4088      case 0x1d: ret->addr = &N1;  ret->data_type = DT_WORD;       break;
4089      case 0x1e: ret->addr = &N2;  ret->data_type = DT_WORD;       break;
4090      case 0x1f: ret->addr = &N3;  ret->data_type = DT_WORD;       break;
4091   }
4092}
4093
4094static void decode_DD_table(dsp56k_core* cpustate, UINT16 DD, typed_pointer* ret)
4095{
4096   switch(DD)
4097   {
4098      case 0x00: ret->addr = &X0;  ret->data_type = DT_WORD;  break;
4099      case 0x01: ret->addr = &Y0;  ret->data_type = DT_WORD;  break;
4100      case 0x02: ret->addr = &X1;  ret->data_type = DT_WORD;  break;
4101      case 0x03: ret->addr = &Y1;  ret->data_type = DT_WORD;  break;
4102   }
4103}
4104
4105static void decode_DDF_table(dsp56k_core* cpustate, UINT16 DD, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4106{
4107   UINT16 switchVal = (DD << 1) | F;
4108
4109   switch (switchVal)
4110   {
4111      case 0x0: src_ret->addr = &X0;  src_ret->data_type = DT_WORD; dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4112      case 0x1: src_ret->addr = &X0;  src_ret->data_type = DT_WORD; dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4113      case 0x2: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD; dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4114      case 0x3: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD; dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4115      case 0x4: src_ret->addr = &X1;  src_ret->data_type = DT_WORD; dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4116      case 0x5: src_ret->addr = &X1;  src_ret->data_type = DT_WORD; dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4117      case 0x6: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD; dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4118      case 0x7: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD; dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4119   }
4120}
4121
4122static void decode_F_table(dsp56k_core* cpustate, UINT16 F, typed_pointer* ret)
4123{
4124   switch(F)
4125   {
4126      case 0x0: ret->addr = &A;  ret->data_type = DT_LONG_WORD;  break;
4127      case 0x1: ret->addr = &B;  ret->data_type = DT_LONG_WORD;  break;
4128   }
4129}
4130
4131static void decode_h0hF_table(dsp56k_core* cpustate, UINT16 h0h, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4132{
4133   UINT16 switchVal = (h0h << 1) | F ;
4134
4135   switch (switchVal)
4136   {
4137      case 0x8: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;       dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4138      case 0x9: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;       dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4139      case 0xa: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;       dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4140      case 0xb: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;       dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4141      case 0x2: src_ret->addr = &A;   src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4142      case 0x1: src_ret->addr = &A;   src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4143      case 0x0: src_ret->addr = &B;   src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4144      case 0x3: src_ret->addr = &B;   src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4145   }
4146}
4147
4148static void decode_HH_table(dsp56k_core* cpustate, UINT16 HH, typed_pointer* ret)
4149{
4150   switch(HH)
4151   {
4152      case 0x0: ret->addr = &X0;  ret->data_type = DT_WORD;       break;
4153      case 0x1: ret->addr = &Y0;  ret->data_type = DT_WORD;       break;
4154      case 0x2: ret->addr = &A;   ret->data_type = DT_LONG_WORD;  break;
4155      case 0x3: ret->addr = &B;   ret->data_type = DT_LONG_WORD;  break;
4156   }
4157}
4158
4159static void decode_HHH_table(dsp56k_core* cpustate, UINT16 HHH, typed_pointer* ret)
4160{
4161   switch(HHH)
4162   {
4163      case 0x0: ret->addr = &X0;  ret->data_type = DT_WORD;       break;
4164      case 0x1: ret->addr = &Y0;  ret->data_type = DT_WORD;       break;
4165      case 0x2: ret->addr = &X1;  ret->data_type = DT_WORD;       break;
4166      case 0x3: ret->addr = &Y1;  ret->data_type = DT_WORD;       break;
4167      case 0x4: ret->addr = &A;   ret->data_type = DT_LONG_WORD;  break;
4168      case 0x5: ret->addr = &B;   ret->data_type = DT_LONG_WORD;  break;
4169      case 0x6: ret->addr = &A0;  ret->data_type = DT_WORD;       break;
4170      case 0x7: ret->addr = &B0;  ret->data_type = DT_WORD;       break;
4171   }
4172}
4173
4174static void decode_IIII_table(dsp56k_core* cpustate, UINT16 IIII, typed_pointer* src_ret, typed_pointer* dst_ret, void *working)
4175{
4176   void *opposite = 0x00 ;
4177
4178   if (working == &A) opposite = &B ;
4179   else               opposite = &A ;
4180
4181   switch(IIII)
4182   {
4183      case 0x0: src_ret->addr = &X0;      src_ret->data_type = DT_WORD;       dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4184      case 0x1: src_ret->addr = &Y0;      src_ret->data_type = DT_WORD;       dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4185      case 0x2: src_ret->addr = &X1;      src_ret->data_type = DT_WORD;       dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4186      case 0x3: src_ret->addr = &Y1;      src_ret->data_type = DT_WORD;       dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4187      case 0x4: src_ret->addr = &A;       src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &X0;       dst_ret->data_type = DT_WORD;       break;
4188      case 0x5: src_ret->addr = &B;       src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &Y0;       dst_ret->data_type = DT_WORD;       break;
4189      case 0x6: src_ret->addr = &A0;      src_ret->data_type = DT_WORD;       dst_ret->addr = &X0;       dst_ret->data_type = DT_WORD;       break;
4190      case 0x7: src_ret->addr = &B0;      src_ret->data_type = DT_WORD;       dst_ret->addr = &Y0;       dst_ret->data_type = DT_WORD;       break;
4191      case 0x8: src_ret->addr = working;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4192      case 0x9: src_ret->addr = working;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = opposite;  dst_ret->data_type = DT_LONG_WORD;  break;
4193      case 0xc: src_ret->addr = &A;       src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &X1;       dst_ret->data_type = DT_WORD;       break;
4194      case 0xd: src_ret->addr = &B;       src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &Y1;       dst_ret->data_type = DT_WORD;       break;
4195      case 0xe: src_ret->addr = &A0;      src_ret->data_type = DT_WORD;       dst_ret->addr = &X1;       dst_ret->data_type = DT_WORD;       break;
4196      case 0xf: src_ret->addr = &B0;      src_ret->data_type = DT_WORD;       dst_ret->addr = &Y1;       dst_ret->data_type = DT_WORD;       break;
4197   }
4198}
4199
4200static void decode_JJJF_table(dsp56k_core* cpustate, UINT16 JJJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4201{
4202   UINT16 switchVal = (JJJ << 1) | F ;
4203
4204   switch(switchVal)
4205   {
4206      case 0x0: src_ret->addr = &B;   src_ret->data_type = DT_LONG_WORD;    dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4207      case 0x1: src_ret->addr = &A;   src_ret->data_type = DT_LONG_WORD;    dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4208      case 0x4: src_ret->addr = &X;   src_ret->data_type = DT_DOUBLE_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4209      case 0x5: src_ret->addr = &X;   src_ret->data_type = DT_DOUBLE_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4210      case 0x6: src_ret->addr = &Y;   src_ret->data_type = DT_DOUBLE_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4211      case 0x7: src_ret->addr = &Y;   src_ret->data_type = DT_DOUBLE_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4212      case 0x8: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;         dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4213      case 0x9: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;         dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4214      case 0xa: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;         dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4215      case 0xb: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;         dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4216      case 0xc: src_ret->addr = &X1;  src_ret->data_type = DT_WORD;         dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4217      case 0xd: src_ret->addr = &X1;  src_ret->data_type = DT_WORD;         dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4218      case 0xe: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD;         dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4219      case 0xf: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD;         dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4220   }
4221}
4222
4223static void decode_JJF_table(dsp56k_core* cpustate, UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4224{
4225   UINT16 switchVal = (JJ << 1) | F ;
4226
4227   switch (switchVal)
4228   {
4229      case 0x0: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4230      case 0x1: src_ret->addr = &X0;  src_ret->data_type = DT_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4231      case 0x2: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4232      case 0x3: src_ret->addr = &Y0;  src_ret->data_type = DT_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4233      case 0x4: src_ret->addr = &X1;  src_ret->data_type = DT_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4234      case 0x5: src_ret->addr = &X1;  src_ret->data_type = DT_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4235      case 0x6: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD;  dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD;  break;
4236      case 0x7: src_ret->addr = &Y1;  src_ret->data_type = DT_WORD;  dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD;  break;
4237   }
4238}
4239
4240static void decode_JF_table(dsp56k_core* cpustate, UINT16 J, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
4241{
4242   UINT16 switchVal = (J << 1) | F ;
4243
4244   switch (switchVal)
4245   {
4246      case 0x0: src_ret->addr = &A;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &X;  dst_ret->data_type = DT_DOUBLE_WORD;  break;
4247      case 0x1: src_ret->addr = &B;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &X;  dst_ret->data_type = DT_DOUBLE_WORD;  break;
4248      case 0x2: src_ret->addr = &A;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &Y;  dst_ret->data_type = DT_DOUBLE_WORD;  break;
4249      case 0x3: src_ret->addr = &B;  src_ret->data_type = DT_LONG_WORD;  dst_ret->addr = &Y;  dst_ret->data_type = DT_DOUBLE_WORD;  break;
4250   }
4251}
4252
4253static void decode_KKK_table(dsp56k_core* cpustate, UINT16 KKK, typed_pointer* dst_ret1, typed_pointer* dst_ret2, void* working)
4254{
4255   void *opposite = 0x00 ;
4256
4257   if (working == &A) opposite = &B ;
4258   else               opposite = &A ;
4259
4260   switch(KKK)
4261   {
4262      case 0x0: dst_ret1->addr = opposite;  dst_ret1->data_type = DT_LONG_WORD;  dst_ret2->addr = &X0;  dst_ret2->data_type = DT_WORD;  break;
4263      case 0x1: dst_ret1->addr = &Y0;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X0;  dst_ret2->data_type = DT_WORD;  break;
4264      case 0x2: dst_ret1->addr = &X1;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X0;  dst_ret2->data_type = DT_WORD;  break;
4265      case 0x3: dst_ret1->addr = &Y1;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X0;  dst_ret2->data_type = DT_WORD;  break;
4266      case 0x4: dst_ret1->addr = &X0;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X1;  dst_ret2->data_type = DT_WORD;  break;
4267      case 0x5: dst_ret1->addr = &Y0;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X1;  dst_ret2->data_type = DT_WORD;  break;
4268      case 0x6: dst_ret1->addr = opposite;  dst_ret1->data_type = DT_LONG_WORD;  dst_ret2->addr = &Y0;  dst_ret2->data_type = DT_WORD;  break;
4269      case 0x7: dst_ret1->addr = &Y1;       dst_ret1->data_type = DT_WORD;       dst_ret2->addr = &X1;  dst_ret2->data_type = DT_WORD;  break;
4270   }
4271}
4272
4273static void decode_QQF_table(dsp56k_core* cpustate, UINT16 QQ, UINT16 F, void **S1, void **S2, void **D)
4274{
4275   UINT16 switchVal = (QQ << 1) | F ;
4276
4277   switch(switchVal)
4278   {
4279      case 0x0: *S1 = &X0;  *S2 = &Y0;  *D = &A;  break;
4280      case 0x1: *S1 = &X0;  *S2 = &Y0;  *D = &B;  break;
4281      case 0x2: *S1 = &X0;  *S2 = &Y1;  *D = &A;  break;
4282      case 0x3: *S1 = &X0;  *S2 = &Y1;  *D = &B;  break;
4283      case 0x4: *S1 = &X1;  *S2 = &Y0;  *D = &A;  break;
4284      case 0x5: *S1 = &X1;  *S2 = &Y0;  *D = &B;  break;
4285      case 0x6: *S1 = &X1;  *S2 = &Y1;  *D = &A;  break;
4286      case 0x7: *S1 = &X1;  *S2 = &Y1;  *D = &B;  break;
4287   }
4288}
4289
4290static void decode_QQF_special_table(dsp56k_core* cpustate, UINT16 QQ, UINT16 F, void **S1, void **S2, void **D)
4291{
4292   UINT16 switchVal = (QQ << 1) | F ;
4293
4294   switch(switchVal)
4295   {
4296      case 0x0: *S1 = &Y0;  *S2 = &X0;  *D = &A;  break;
4297      case 0x1: *S1 = &Y0;  *S2 = &X0;  *D = &B;  break;
4298      case 0x2: *S1 = &Y1;  *S2 = &X0;  *D = &A;  break;
4299      case 0x3: *S1 = &Y1;  *S2 = &X0;  *D = &B;  break;
4300      case 0x4: *S1 = &X1;  *S2 = &Y0;  *D = &A;  break;
4301      case 0x5: *S1 = &X1;  *S2 = &Y0;  *D = &B;  break;
4302      case 0x6: *S1 = &X1;  *S2 = &Y1;  *D = &A;  break;
4303      case 0x7: *S1 = &X1;  *S2 = &Y1;  *D = &B;  break;
4304   }
4305}
4306
4307static void decode_QQQF_table(dsp56k_core* cpustate, UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D)
4308{
4309   UINT16 switchVal = (QQQ << 1) | F;
4310
4311   switch(switchVal)
4312   {
4313      case 0x0: *S1 = &X0;  *S2 = &X0;  *D = &A;  break;
4314      case 0x1: *S1 = &X0;  *S2 = &X0;  *D = &B;  break;
4315      case 0x2: *S1 = &X1;  *S2 = &X0;  *D = &A;  break;
4316      case 0x3: *S1 = &X1;  *S2 = &X0;  *D = &B;  break;
4317      case 0x4: *S1 = &A1;  *S2 = &Y0;  *D = &A;  break;
4318      case 0x5: *S1 = &A1;  *S2 = &Y0;  *D = &B;  break;
4319      case 0x6: *S1 = &B1;  *S2 = &X0;  *D = &A;  break;
4320      case 0x7: *S1 = &B1;  *S2 = &X0;  *D = &B;  break;
4321      case 0x8: *S1 = &Y0;  *S2 = &X0;  *D = &A;  break;
4322      case 0x9: *S1 = &Y0;  *S2 = &X0;  *D = &B;  break;
4323      case 0xa: *S1 = &Y1;  *S2 = &X0;  *D = &A;  break;
4324      case 0xb: *S1 = &Y1;  *S2 = &X0;  *D = &B;  break;
4325      case 0xc: *S1 = &Y0;  *S2 = &X1;  *D = &A;  break;
4326      case 0xd: *S1 = &Y0;  *S2 = &X1;  *D = &B;  break;
4327      case 0xe: *S1 = &Y1;  *S2 = &X1;  *D = &A;  break;
4328      case 0xf: *S1 = &Y1;  *S2 = &X1;  *D = &B;  break;
4329   }
4330}
4331
4332static void decode_RR_table(dsp56k_core* cpustate, UINT16 RR, typed_pointer* ret)
4333{
4334   switch(RR)
4335   {
4336      case 0x00: ret->addr = &R0;  ret->data_type = DT_WORD;  break;
4337      case 0x01: ret->addr = &R1;  ret->data_type = DT_WORD;  break;
4338      case 0x02: ret->addr = &R2;  ret->data_type = DT_WORD;  break;
4339      case 0x03: ret->addr = &R3;  ret->data_type = DT_WORD;  break;
4340   }
4341}
4342
4343static void decode_TT_table(dsp56k_core* cpustate, UINT16 TT, typed_pointer* ret)
4344{
4345   switch(TT)
4346   {
4347      case 0x00: ret->addr = &R0;  ret->data_type = DT_WORD;  break;
4348      case 0x01: ret->addr = &R1;  ret->data_type = DT_WORD;  break;
4349      case 0x02: ret->addr = &R2;  ret->data_type = DT_WORD;  break;
4350      case 0x03: ret->addr = &R3;  ret->data_type = DT_WORD;  break;
4351   }
4352}
4353
4354
4355static void decode_uuuuF_table(dsp56k_core* cpustate, UINT16 uuuu, UINT16 F, UINT8 add_sub_other, typed_pointer* src_ret, typed_pointer* dst_ret)
4356{
4357   UINT16 switchVal = (uuuu << 1) | F;
4358
4359   /* Unknown uuuuFs have been seen in the wild */
4360   add_sub_other = OP_OTHER;
4361   src_ret->addr = NULL; src_ret->data_type = DT_BYTE;
4362   dst_ret->addr = NULL; dst_ret->data_type = DT_BYTE;
4363
4364   switch(switchVal)
4365   {
4366      case 0x00: add_sub_other = OP_ADD;
4367               src_ret->addr = &X0; src_ret->data_type = DT_WORD;
4368               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4369      case 0x08: add_sub_other = OP_SUB;
4370               src_ret->addr = &X0; src_ret->data_type = DT_WORD;
4371               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4372      case 0x01: add_sub_other = OP_ADD;
4373               src_ret->addr = &X0; src_ret->data_type = DT_WORD;
4374               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4375      case 0x09: add_sub_other = OP_SUB;
4376               src_ret->addr = &X0; src_ret->data_type = DT_WORD;
4377               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4378      case 0x02: add_sub_other = OP_ADD;
4379               src_ret->addr = &Y0; src_ret->data_type = DT_WORD;
4380               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4381      case 0x0a: add_sub_other = OP_SUB;
4382               src_ret->addr = &Y0; src_ret->data_type = DT_WORD;
4383               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4384      case 0x03: add_sub_other = OP_ADD;
4385               src_ret->addr = &Y0; src_ret->data_type = DT_WORD;
4386               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4387      case 0x0b: add_sub_other = OP_SUB;
4388               src_ret->addr = &Y0; src_ret->data_type = DT_WORD;
4389               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4390      case 0x04: add_sub_other = OP_ADD;
4391               src_ret->addr = &X1; src_ret->data_type = DT_WORD;
4392               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4393      case 0x0c: add_sub_other = OP_SUB;
4394               src_ret->addr = &X1; src_ret->data_type = DT_WORD;
4395               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4396      case 0x05: add_sub_other = OP_ADD;
4397               src_ret->addr = &X1; src_ret->data_type = DT_WORD;
4398               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4399      case 0x0d: add_sub_other = OP_SUB;
4400               src_ret->addr = &X1; src_ret->data_type = DT_WORD;
4401               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4402      case 0x06: add_sub_other = OP_ADD;
4403               src_ret->addr = &Y1; src_ret->data_type = DT_WORD;
4404               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4405      case 0x0e: add_sub_other = OP_SUB;
4406               src_ret->addr = &Y1; src_ret->data_type = DT_WORD;
4407               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4408      case 0x07: add_sub_other = OP_ADD;
4409               src_ret->addr = &Y1; src_ret->data_type = DT_WORD;
4410               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4411      case 0x0f: add_sub_other = OP_SUB;
4412               src_ret->addr = &Y1; src_ret->data_type = DT_WORD;
4413               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4414      case 0x18: add_sub_other = OP_ADD;
4415               src_ret->addr = &B;  src_ret->data_type = DT_LONG_WORD;
4416               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4417      case 0x1a: add_sub_other = OP_SUB;
4418               src_ret->addr = &B;  src_ret->data_type = DT_LONG_WORD;
4419               dst_ret->addr = &A;  dst_ret->data_type = DT_LONG_WORD; break;
4420      case 0x19: add_sub_other = OP_ADD;
4421               src_ret->addr = &A;  src_ret->data_type = DT_LONG_WORD;
4422               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4423      case 0x1b: add_sub_other = OP_SUB;
4424               src_ret->addr = &A;  src_ret->data_type = DT_LONG_WORD;
4425               dst_ret->addr = &B;  dst_ret->data_type = DT_LONG_WORD; break;
4426   }
4427}
4428
4429static void decode_Z_table(dsp56k_core* cpustate, UINT16 Z, typed_pointer* ret)
4430{
4431   switch(Z)
4432   {
4433      /* Fixed as per the Family Manual addendum */
4434      case 0x01: ret->addr = &A1;  ret->data_type = DT_WORD;  break;
4435      case 0x00: ret->addr = &B1;  ret->data_type = DT_WORD;  break;
4436   }
4437}
4438
4439static void execute_m_table(dsp56k_core* cpustate, int x, UINT16 m)
4440{
4441   UINT16 *rX = 0x00 ;
4442   UINT16 *nX = 0x00 ;
4443
4444   switch(x)
4445   {
4446      case 0x0: rX = &R0;  nX = &N0; break;
4447      case 0x1: rX = &R1;  nX = &N1; break;
4448      case 0x2: rX = &R2;  nX = &N2; break;
4449      case 0x3: rX = &R3;  nX = &N3; break;
4450   }
4451
4452   switch(m)
4453   {
4454      case 0x0: (*rX)++;             break;
4455      case 0x1: (*rX) = (*rX)+(*nX); break;
4456   }
4457}
4458
4459static void execute_mm_table(dsp56k_core* cpustate, UINT16 rnum, UINT16 mm)
4460{
4461   UINT16 *rX = NULL;
4462   UINT16 *nX = NULL;
4463
4464   switch(rnum)
4465   {
4466      case 0x0: rX = &R0;  nX = &N0;  break;
4467      case 0x1: rX = &R1;  nX = &N1;  break;
4468      case 0x2: rX = &R2;  nX = &N2;  break;
4469      case 0x3: fatalerror("Dsp56k: Error. execute_mm_table specified R3 as its first source!\n");  break;
4470   }
4471
4472   switch(mm)
4473   {
4474      case 0x0: (*rX)++;                  R3++;           break;
4475      case 0x1: (*rX)++;                  R3 = R3 + N3;   break;
4476      case 0x2: (*rX) = (*rX) + (*nX);    R3++;           break;
4477      case 0x3: (*rX) = (*rX) + (*nX);    R3 = R3 + N3;   break;
4478   }
4479}
4480
4481static void execute_MM_table(dsp56k_core* cpustate, UINT16 rnum, UINT16 MM)
4482{
4483   UINT16 *rX = 0x00 ;
4484   UINT16 *nX = 0x00 ;
4485
4486   switch(rnum)
4487   {
4488      case 0x0: rX = &R0;  nX = &N0;  break;
4489      case 0x1: rX = &R1;  nX = &N1;  break;
4490      case 0x2: rX = &R2;  nX = &N2;  break;
4491      case 0x3: rX = &R3;  nX = &N3;  break;
4492   }
4493
4494   switch(MM)
4495   {
4496      case 0x0: /* do nothing */      break;
4497      case 0x1: (*rX)++ ;             break;
4498      case 0x2: (*rX)-- ;             break;
4499      case 0x3: (*rX) = (*rX)+(*nX) ; break;
4500   }
4501}
4502
4503/* Returns R value */
4504static UINT16 execute_q_table(dsp56k_core* cpustate, int RR, UINT16 q)
4505{
4506   UINT16 *rX = 0x0000;
4507   UINT16 *nX = 0x0000;
4508
4509   switch(RR)
4510   {
4511      case 0x0: rX = &R0;  nX = &N0;  break;
4512      case 0x1: rX = &R1;  nX = &N1;  break;
4513      case 0x2: rX = &R2;  nX = &N2;  break;
4514      case 0x3: rX = &R3;  nX = &N3;  break;
4515   }
4516
4517   switch(q)
4518   {
4519      case 0x0: /* No permanent changes */ ; return (*rX)+(*nX);
4520      case 0x1: (*rX)--;                     return (*rX);    /* This one is special - it's a *PRE-decrement*! */
4521   }
4522
4523   /* Should not get here */
4524   fatalerror("dsp56k: execute_q_table did something impossible!\n");
4525   return 0;
4526}
4527
4528static void execute_z_table(dsp56k_core* cpustate, int RR, UINT16 z)
4529{
4530   UINT16 *rX = 0x00;
4531   UINT16 *nX = 0x00;
4532
4533   switch(RR)
4534   {
4535      case 0x0: rX = &R0;  nX = &N0;  break;
4536      case 0x1: rX = &R1;  nX = &N1;  break;
4537      case 0x2: rX = &R2;  nX = &N2;  break;
4538      case 0x3: rX = &R3;  nX = &N3;  break;
4539   }
4540
4541   switch(z)
4542   {
4543      case 0x0: (*rX)--;               break;
4544      case 0x1: (*rX) = (*rX) + (*nX); break;
4545   }
4546}
4547
4548static UINT16 assemble_address_from_Pppppp_table(dsp56k_core* cpustate, UINT16 P, UINT16 ppppp)
4549{
4550   UINT16 destAddr = 0x00 ;
4551
4552   switch (P)
4553   {
4554      case 0x0: destAddr = ppppp;  break;     /* TODO:  Does this really only address up to 0x32? */
4555      case 0x1: destAddr = assemble_address_from_IO_short_address(cpustate, ppppp);  break;
4556   }
4557
4558   return destAddr ;
4559}
4560
4561static UINT16 assemble_address_from_IO_short_address(dsp56k_core* cpustate, UINT16 pp)
4562{
4563   UINT16 fullAddy = 0xffe0;
4564   fullAddy |= pp;
4565   return fullAddy;
4566}
4567
4568static UINT16 assemble_address_from_6bit_signed_relative_short_address(dsp56k_core* cpustate, UINT16 srs)
4569{
4570   UINT16 fullAddy = srs ;
4571   if (fullAddy & 0x0020)
4572      fullAddy |= 0xffc0 ;
4573
4574   return fullAddy ;
4575}
4576
4577static void dsp56k_process_loop(dsp56k_core* cpustate)
4578{
4579   /* TODO: This might not work for dos nested in doForevers */
4580   if (LF_bit(cpustate) && FV_bit(cpustate))
4581   {
4582      /* Do Forever*/
4583      if (PC == LA)
4584      {
4585         LC--;
4586
4587         cpustate->ppc = PC;
4588         PC = SSH;
4589      }
4590   }
4591   else if (LF_bit(cpustate))
4592   {
4593      /* Do */
4594      if (PC == LA)
4595      {
4596         if (LC == 1)
4597         {
4598            /* End of loop processing */
4599            SR = SSL;   /* TODO: A-83.  I believe only the Loop Flag comes back here.  And maybe the do forever bit too. */
4600            SP--;
4601
4602            LA = SSH;
4603            LC = SSL;
4604            SP--;
4605         }
4606         else
4607         {
4608            LC--;
4609            PC = SSH;
4610         }
4611      }
4612   }
4613}
4614
4615static void dsp56k_process_rep(dsp56k_core* cpustate, size_t repSize)
4616{
4617   if (cpustate->repFlag)
4618   {
4619      if (PC == cpustate->repAddr)
4620      {
4621         if (LC == 1)
4622         {
4623            /* End of rep processing */
4624            LC = TEMP;
4625            cpustate->repFlag = 0;
4626            cpustate->repAddr = 0x0000;
4627         }
4628         else
4629         {
4630            LC--;
4631            PC -= repSize;      /* A little strange - rewind by the size of the rep'd op */
4632         }
4633      }
4634   }
4635}
4636
4637
4638/***************************************************************************
4639    Parallel Memory Ops
4640***************************************************************************/
4641/* Register to Register Data Move : 0100 IIII .... .... : A-132 */
4642static void execute_register_to_register_data_move(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value)
4643{
4644   typed_pointer S = {NULL, DT_BYTE};
4645   typed_pointer D = {NULL, DT_BYTE};
4646
4647   decode_IIII_table(cpustate, BITS(op,0x0f00), &S, &D, d_register->addr);
4648
4649   /* If the source is the same as the ALU destination, use the previous accumulator value */
4650   if (d_register->addr == S.addr)
4651   {
4652      typed_pointer tempTP;
4653      tempTP.addr = prev_accum_value;
4654      tempTP.data_type = DT_LONG_WORD;
4655      SetDestinationValue(tempTP, D);
4656   }
4657   else
4658   {
4659      SetDestinationValue(S, D);
4660   }
4661}
4662
4663/* Address Register Update : 0011 0zRR .... .... : A-135 */
4664static void execute_address_register_update(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value)
4665{
4666   execute_z_table(cpustate, BITS(op,0x0300), BITS(op,0x0400));
4667}
4668
4669/* X Memory Data Move : 1mRR HHHW .... .... : A-137 */
4670static void execute_x_memory_data_move(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value)
4671{
4672   UINT16 W;
4673   typed_pointer R = {NULL, DT_BYTE};
4674   typed_pointer SD = {NULL, DT_BYTE};
4675
4676   W = BITS(op,0x0100);
4677   decode_HHH_table(cpustate, BITS(op,0x0e00), &SD);
4678   decode_RR_table(cpustate, BITS(op,0x3000),&R);
4679
4680   if (W)
4681   {
4682      /* From X:<ea> to SD */
4683      UINT16 data = cpustate->data->read_word(ADDRESS(*((UINT16*)R.addr)));
4684
4685      typed_pointer tempTP;
4686      tempTP.addr = &data;
4687      tempTP.data_type = DT_WORD;
4688
4689      SetDestinationValue(tempTP, SD);
4690   }
4691   else
4692   {
4693      /* From SD to X:<ea> */
4694      /* If the source is the same as the ALU destination, use the previous accumulator value */
4695      if (d_register->addr == SD.addr)
4696      {
4697         typed_pointer tempTP;
4698         tempTP.addr = prev_accum_value;
4699         tempTP.data_type = DT_LONG_WORD;
4700
4701         SetDataMemoryValue(cpustate, tempTP, ADDRESS(*((UINT16*)R.addr))) ;
4702      }
4703      else
4704      {
4705         SetDataMemoryValue(cpustate, SD, ADDRESS(*((UINT16*)R.addr))) ;
4706      }
4707   }
4708
4709   execute_m_table(cpustate, BITS(op,0x3000), BITS(op,0x4000));
4710}
4711
4712/* X Memory Data Move : 0101 HHHW .... .... : A-137 */
4713/* NOTE: previous accumulator value is not needed since ^F1 is always the opposite accumulator */
4714static void execute_x_memory_data_move2(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register)
4715{
4716   UINT16 W;
4717   UINT16* mem_offset = NULL;
4718   typed_pointer SD = {NULL, DT_BYTE};
4719
4720   W = BITS(op,0x0100);
4721   decode_HHH_table(cpustate, BITS(op,0x0e000), &SD);
4722
4723   if (d_register->addr == &A)
4724      mem_offset = &B1;
4725   else
4726      mem_offset = &A1;
4727
4728   if (W)
4729   {
4730      /* Write D */
4731      UINT16 value = cpustate->data->read_word(ADDRESS(*mem_offset));
4732      typed_pointer tempV = {&value, DT_WORD};
4733      SetDestinationValue(tempV, SD);
4734   }
4735   else
4736   {
4737      /* Read S */
4738      SetDataMemoryValue(cpustate, SD, ADDRESS(*mem_offset));
4739   }
4740}
4741
4742/* X Memory Data Move With Short Displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */
4743static void execute_x_memory_data_move_with_short_displacement(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2)
4744{
4745   INT8 xx;
4746   UINT8 W;
4747   UINT16 memOffset;
4748   typed_pointer SD = { NULL, DT_BYTE };
4749
4750   xx = (INT8)(op & 0x00ff);
4751   W = BITS(op2,0x0100);
4752   decode_HHH_table(cpustate, BITS(op2,0x0e00), &SD);
4753
4754   memOffset = R2 + (INT16)xx;
4755
4756   if (W)
4757   {
4758      /* Write D */
4759      UINT16 tempData = cpustate->data->read_word(ADDRESS(memOffset));
4760      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
4761      SetDestinationValue(temp_src, SD);
4762   }
4763   else
4764   {
4765      /* Read S */
4766      UINT16 tempData = *((UINT16*)SD.addr);
4767      typed_pointer temp_src = { (void*)&tempData, DT_WORD };
4768      SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset));
4769   }
4770}
4771
4772/* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/
4773static void execute_dual_x_memory_data_read(dsp56k_core* cpustate, const UINT16 op, typed_pointer* d_register)
4774{
4775   typed_pointer tempV;
4776   UINT16 srcVal1 = 0x0000;
4777   UINT16 srcVal2 = 0x0000;
4778   typed_pointer R = {NULL, DT_BYTE};
4779   typed_pointer D1 = {NULL, DT_BYTE};
4780   typed_pointer D2 = {NULL, DT_BYTE};
4781
4782   decode_RR_table(cpustate, BITS(op,0x0060), &R);
4783   decode_KKK_table(cpustate, BITS(op,0x0700), &D1, &D2, d_register->addr);
4784
4785   /* Can't do an R3 for S1 */
4786   if (R.addr == &R3)
4787      fatalerror("Dsp56k: Error. Dual x memory data read specified R3 as its first source!\n");
4788
4789   /* The note on A-142 is very interesting.
4790      You can effectively access external memory in the last 64 bytes of X data memory! */
4791   if (*((UINT16*)D2.addr) >= 0xffc0)
4792      fatalerror("Dsp56k: Unimplemented access to external X Data Memory >= 0xffc0 in Dual X Memory Data Read.\n");
4793
4794   /* First memmove */
4795   srcVal1 = cpustate->data->read_word(ADDRESS(*((UINT16*)R.addr)));
4796   tempV.addr = &srcVal1;
4797   tempV.data_type = DT_WORD;
4798   SetDestinationValue(tempV, D1);
4799
4800   /* Second memmove */
4801   srcVal2 = cpustate->data->read_word(ADDRESS(R3));
4802   tempV.addr = &srcVal2;
4803   tempV.data_type = DT_WORD;
4804   SetDestinationValue(tempV, D2);
4805
4806   /* Touch up the R regs after all the moves */
4807   execute_mm_table(cpustate, BITS(op,0x0060), BITS(op,0x1800));
4808}
4809
4810/***************************************************************************
4811    Helper Functions
4812***************************************************************************/
4813static UINT16 Dsp56kOpMask(UINT16 cur, UINT16 mask)
4814{
4815   int i ;
4816
4817   UINT16 retVal = (cur & mask) ;
4818   UINT16 temp = 0x0000 ;
4819   int offsetCount = 0 ;
4820
4821   /* Shift everything right, eliminating 'whitespace' */
4822   for (i = 0; i < 16; i++)
4823   {
4824      if (mask & (0x1<<i))        /* If mask bit is non-zero */
4825      {
4826         temp |= (((retVal >> i) & 0x1) << offsetCount) ;
4827         offsetCount++ ;
4828      }
4829   }
4830
4831   return temp ;
4832}
4833
4834static void SetDestinationValue(typed_pointer source, typed_pointer dest)
4835{
4836   UINT64 destinationValue = 0 ;
4837
4838   switch(dest.data_type)
4839   {
4840      /* Copying to an 8-bit value */
4841      case DT_BYTE:
4842         switch(source.data_type)
4843         {
4844            /* From a ? */
4845            case DT_BYTE:        *((UINT8*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break;
4846            case DT_WORD:        *((UINT8*)dest.addr) = (*((UINT16*)source.addr)) & 0x00ff; break;
4847            case DT_DOUBLE_WORD: *((UINT8*)dest.addr) = (*((UINT32*)source.addr)) & 0x000000ff; break;
4848            case DT_LONG_WORD:   *((UINT8*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x00000000000000ff); break;
4849         }
4850      break ;
4851
4852      /* Copying to a 16-bit value */
4853      case DT_WORD:
4854         switch(source.data_type)
4855         {
4856            case DT_BYTE:        *((UINT16*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break;
4857            case DT_WORD:        *((UINT16*)dest.addr) = (*((UINT16*)source.addr)) & 0xffff; break;
4858            case DT_DOUBLE_WORD: *((UINT16*)dest.addr) = (*((UINT32*)source.addr)) & 0x0000ffff; break;
4859            case DT_LONG_WORD:   *((UINT16*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000000000ffff); break;    /* TODO: Shift limiter action! A-147 */
4860         }
4861      break ;
4862
4863      /* Copying to a 32-bit value */
4864      case DT_DOUBLE_WORD:
4865         switch(source.data_type)
4866         {
4867            case DT_BYTE:        *((UINT32*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break;
4868            case DT_WORD:        *((UINT32*)dest.addr) = (*((UINT16*)source.addr)) & 0xffff; break;
4869            case DT_DOUBLE_WORD: *((UINT32*)dest.addr) = (*((UINT32*)source.addr)) & 0xffffffff; break;
4870            case DT_LONG_WORD:   *((UINT32*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x00000000ffffffff); break;
4871         }
4872      break ;
4873
4874      /* Copying to a 64-bit value */
4875      case DT_LONG_WORD:
4876         switch(source.data_type)
4877         {
4878            case DT_BYTE:        *((UINT64*)dest.addr) = (*((UINT8*)source.addr)) & 0xff; break;
4879
4880            case DT_WORD:        destinationValue = (*((UINT16*)source.addr)) << 16;
4881                              if (destinationValue & U64(0x0000000080000000))
4882                                 destinationValue |= U64(0x000000ff00000000);
4883                              *((UINT64*)dest.addr) = (UINT64)destinationValue; break;    /* Forget not, yon shift register */
4884
4885            case DT_DOUBLE_WORD: *((UINT64*)dest.addr) = (*((UINT32*)source.addr)) & 0xffffffff; break;
4886            case DT_LONG_WORD:   *((UINT64*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000ffffffffff); break;
4887         }
4888      break ;
4889   }
4890}
4891
4892/* TODO: Wait-state timings! */
4893static void SetDataMemoryValue(dsp56k_core* cpustate, typed_pointer source, UINT32 destinationAddr)
4894{
4895   switch(source.data_type)
4896   {
4897      case DT_BYTE:        cpustate->data->write_word(destinationAddr, (UINT16)( (*((UINT8*) source.addr) & 0xff)               ) ) ; break ;
4898      case DT_WORD:        cpustate->data->write_word(destinationAddr, (UINT16)( (*((UINT16*)source.addr) & 0xffff)             ) ) ; break ;
4899      case DT_DOUBLE_WORD: cpustate->data->write_word(destinationAddr, (UINT16)( (*((UINT32*)source.addr) & 0x0000ffff)         ) ) ; break ;
4900
4901      /* !!! Is this universal ??? */
4902      /* !!! Forget not, yon shift-limiter !!! */
4903      case DT_LONG_WORD:   cpustate->data->write_word(destinationAddr, (UINT16)( ((*((UINT64*)source.addr)) & U64(0x00000000ffff0000)) >> 16) ) ; break ;
4904   }
4905}
4906
4907/* TODO: Wait-state timings! */
4908static void SetProgramMemoryValue(dsp56k_core* cpustate, typed_pointer source, UINT32 destinationAddr)
4909{
4910   switch(source.data_type)
4911   {
4912      case DT_BYTE:        cpustate->program->write_word(destinationAddr, (UINT16)( (*((UINT8*) source.addr) & 0xff)               ) ) ; break ;
4913      case DT_WORD:        cpustate->program->write_word(destinationAddr, (UINT16)( (*((UINT16*)source.addr) & 0xffff)             ) ) ; break ;
4914      case DT_DOUBLE_WORD: cpustate->program->write_word(destinationAddr, (UINT16)( (*((UINT32*)source.addr) & 0x0000ffff)         ) ) ; break ;
4915
4916      /* !!! Is this universal ??? */
4917      /* !!! Forget not, yon shift-limiter !!! */
4918      case DT_LONG_WORD:   cpustate->program->write_word(destinationAddr, (UINT16)( ((*((UINT64*)source.addr)) & U64(0x00000000ffff0000)) >> 16) ) ; break ;
4919   }
4920}
Property changes on: trunk/src/emu/cpu/dsp56k/dsp56ops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/dsp56k/dsp56k.c
r28738r28739
304304/***************************************************************************
305305    CORE INCLUDE
306306***************************************************************************/
307#include "dsp56ops.c"
307#include "dsp56ops.inc"
308308
309309
310310/***************************************************************************
trunk/src/emu/cpu/m6805/6805ops.c
r28738r28739
1
2/*
3
4HNZC
5
6? = undefined
7* = affected
8- = unaffected
90 = cleared
101 = set
11# = ccr directly affected by instruction
12@ = special - carry set if bit 7 is set
13
14*/
15
16#define OP_HANDLER(_name) void m6805_base_device::_name()
17#define DERIVED_OP_HANDLER(_arch,_name) void _arch##_device::_name()
18
19#define OP_HANDLER_BIT(_name) void m6805_base_device::_name(UINT8 bit)
20
21OP_HANDLER( illegal )
22{
23   logerror("M6805: illegal opcode\n");
24}
25
26/* $00/$02/$04/$06/$08/$0A/$0C/$0E BRSET direct,relative ---- */
27OP_HANDLER_BIT( brset )
28{
29   UINT8 t,r;
30   DIRBYTE(r);
31   IMMBYTE(t);
32
33   CLC;
34
35   if (r&bit) {
36      SEC;
37      PC+=SIGNED(t);
38   }
39}
40
41/* $01/$03/$05/$07/$09/$0B/$0D/$0F BRCLR direct,relative ---- */
42OP_HANDLER_BIT( brclr )
43{
44   UINT8 t,r;
45   DIRBYTE(r);
46   IMMBYTE(t);
47
48   SEC;
49
50   if (!(r&bit)) {
51      CLC;
52      PC+=SIGNED(t);
53   }
54}
55
56/* $10/$12/$14/$16/$18/$1A/$1C/$1E BSET direct ---- */
57OP_HANDLER_BIT( bset )
58{
59   UINT8 t,r;
60   DIRBYTE(t); r=t|bit;
61   WM(EAD,r);
62}
63
64/* $11/$13/$15/$17/$19/$1B/$1D/$1F BCLR direct ---- */
65OP_HANDLER_BIT( bclr)
66{
67   UINT8 t,r;
68   DIRBYTE(t); r=t&(~bit);
69   WM(EAD,r);
70}
71
72/* $20 BRA relative ---- */
73OP_HANDLER( bra )
74{
75   UINT8 t;
76   IMMBYTE(t);
77   PC+=SIGNED(t);
78}
79
80/* $21 BRN relative ---- */
81static UINT8 m6805_brn_t; // hack around GCC 4.6 error because we need the side effects of IMMBYTE
82OP_HANDLER( brn )
83{
84   IMMBYTE(m6805_brn_t);
85}
86
87/* $22 BHI relative ---- */
88OP_HANDLER( bhi )
89{
90   BRANCH( !(CC&(CFLAG|ZFLAG)) );
91}
92
93/* $23 BLS relative ---- */
94OP_HANDLER( bls )
95{
96   BRANCH( CC&(CFLAG|ZFLAG) );
97}
98
99/* $24 BCC relative ---- */
100OP_HANDLER( bcc )
101{
102   BRANCH( !(CC&CFLAG) );
103}
104
105/* $25 BCS relative ---- */
106OP_HANDLER( bcs )
107{
108   BRANCH( CC&CFLAG );
109}
110
111/* $26 BNE relative ---- */
112OP_HANDLER( bne )
113{
114   BRANCH( !(CC&ZFLAG) );
115}
116
117/* $27 BEQ relative ---- */
118OP_HANDLER( beq )
119{
120   BRANCH( CC&ZFLAG );
121}
122
123/* $28 BHCC relative ---- */
124OP_HANDLER( bhcc )
125{
126   BRANCH( !(CC&HFLAG) );
127}
128
129/* $29 BHCS relative ---- */
130OP_HANDLER( bhcs )
131{
132   BRANCH( CC&HFLAG );
133}
134
135/* $2a BPL relative ---- */
136OP_HANDLER( bpl )
137{
138   BRANCH( !(CC&NFLAG) );
139}
140
141/* $2b BMI relative ---- */
142OP_HANDLER( bmi )
143{
144   BRANCH( CC&NFLAG );
145}
146
147/* $2c BMC relative ---- */
148OP_HANDLER( bmc )
149{
150   BRANCH( !(CC&IFLAG) );
151}
152
153/* $2d BMS relative ---- */
154OP_HANDLER( bms )
155{
156   BRANCH( CC&IFLAG );
157}
158
159/* $2e BIL relative ---- */
160OP_HANDLER( bil )
161{
162   BRANCH(m_irq_state[0] != CLEAR_LINE);
163}
164
165DERIVED_OP_HANDLER( hd63705, bil )
166{
167   BRANCH(m_nmi_state != CLEAR_LINE);
168}
169
170/* $2f BIH relative ---- */
171OP_HANDLER( bih )
172{
173   BRANCH(m_irq_state[0] == CLEAR_LINE);
174}
175
176DERIVED_OP_HANDLER( hd63705, bih )
177{
178   BRANCH(m_nmi_state == CLEAR_LINE);
179}
180
181/* $30 NEG direct -*** */
182OP_HANDLER( neg_di )
183{
184   UINT8 t;
185   UINT16 r;
186   DIRBYTE(t);
187   r=-t;
188   CLR_NZC;
189   SET_FLAGS8(0,t,r);
190   WM(EAD,r);
191}
192
193/* $31 ILLEGAL */
194
195/* $32 ILLEGAL */
196
197/* $33 COM direct -**1 */
198OP_HANDLER( com_di )
199{
200   UINT8 t;
201   DIRBYTE(t);
202   t = ~t;
203   CLR_NZ;
204   SET_NZ8(t);
205   SEC;
206   WM(EAD,t);
207}
208
209/* $34 LSR direct -0** */
210OP_HANDLER( lsr_di )
211{
212   UINT8 t;
213   DIRBYTE(t);
214   CLR_NZC;
215   CC |= (t&0x01);
216   t >>= 1;
217   SET_Z8(t);
218   WM(EAD,t);
219}
220
221/* $35 ILLEGAL */
222
223/* $36 ROR direct -*** */
224OP_HANDLER( ror_di )
225{
226   UINT8 t,r;
227   DIRBYTE(t);
228   r = (CC & 0x01) << 7;
229   CLR_NZC;
230   CC |= (t & 0x01);
231   r |= t>>1;
232   SET_NZ8(r);
233   WM(EAD,r);
234}
235
236/* $37 ASR direct ?*** */
237OP_HANDLER( asr_di )
238{
239   UINT8 t;
240   DIRBYTE(t);
241   CLR_NZC; CC|=(t&0x01);
242   t>>=1; t|=((t&0x40)<<1);
243   SET_NZ8(t);
244   WM(EAD,t);
245}
246
247/* $38 LSL direct ?*** */
248OP_HANDLER( lsl_di )
249{
250   UINT8 t;
251   UINT16 r;
252   DIRBYTE(t);
253   r = t << 1;
254   CLR_NZC;
255   SET_FLAGS8(t,t,r);
256   WM(EAD,r);
257}
258
259/* $39 ROL direct -*** */
260OP_HANDLER( rol_di )
261{
262   UINT16 t,r;
263   DIRBYTE(t);
264   r = CC & 0x01;
265   r |= t << 1;
266   CLR_NZC;
267   SET_FLAGS8(t,t,r);
268   WM(EAD,r);
269}
270
271/* $3a DEC direct -**- */
272OP_HANDLER( dec_di )
273{
274   UINT8 t;
275   DIRBYTE(t);
276   --t;
277   CLR_NZ; SET_FLAGS8D(t);
278   WM(EAD,t);
279}
280
281/* $3b ILLEGAL */
282
283/* $3c INC direct -**- */
284OP_HANDLER( inc_di )
285{
286   UINT8 t;
287   DIRBYTE(t);
288   ++t;
289   CLR_NZ; SET_FLAGS8I(t);
290   WM(EAD,t);
291}
292
293/* $3d TST direct -**- */
294OP_HANDLER( tst_di )
295{
296   UINT8 t;
297   DIRBYTE(t);
298   CLR_NZ; SET_NZ8(t);
299}
300
301/* $3e ILLEGAL */
302
303/* $3f CLR direct -0100 */
304OP_HANDLER( clr_di )
305{
306   DIRECT;
307   CLR_NZ; SEZ;
308   WM(EAD,0);
309}
310
311/* $40 NEGA inherent ?*** */
312OP_HANDLER( nega )
313{
314   UINT16 r;
315   r = -A;
316   CLR_NZC; SET_FLAGS8(0,A,r);
317   A = r;
318}
319
320/* $41 ILLEGAL */
321
322/* $42 ILLEGAL */
323
324/* $43 COMA inherent -**1 */
325OP_HANDLER( coma )
326{
327   A = ~A;
328   CLR_NZ;
329   SET_NZ8(A);
330   SEC;
331}
332
333/* $44 LSRA inherent -0** */
334OP_HANDLER( lsra )
335{
336   CLR_NZC;
337   CC |= (A & 0x01);
338   A >>= 1;
339   SET_Z8(A);
340}
341
342/* $45 ILLEGAL */
343
344/* $46 RORA inherent -*** */
345OP_HANDLER( rora )
346{
347   UINT8 r;
348   r = (CC & 0x01) << 7;
349   CLR_NZC;
350   CC |= (A & 0x01);
351   r |= A >> 1;
352   SET_NZ8(r);
353   A = r;
354}
355
356/* $47 ASRA inherent ?*** */
357OP_HANDLER( asra )
358{
359   CLR_NZC;
360   CC |= (A & 0x01);
361   A = (A & 0x80) | (A >> 1);
362   SET_NZ8(A);
363}
364
365/* $48 LSLA inherent ?*** */
366OP_HANDLER( lsla )
367{
368   UINT16 r;
369   r = A << 1;
370   CLR_NZC;
371   SET_FLAGS8(A,A,r);
372   A = r;
373}
374
375/* $49 ROLA inherent -*** */
376OP_HANDLER( rola )
377{
378   UINT16 t,r;
379   t = A;
380   r = CC & 0x01;
381   r |= t << 1;
382   CLR_NZC;
383   SET_FLAGS8(t,t,r);
384   A = r;
385}
386
387/* $4a DECA inherent -**- */
388OP_HANDLER( deca )
389{
390   --A;
391   CLR_NZ;
392   SET_FLAGS8D(A);
393}
394
395/* $4b ILLEGAL */
396
397/* $4c INCA inherent -**- */
398OP_HANDLER( inca )
399{
400   ++A;
401   CLR_NZ;
402   SET_FLAGS8I(A);
403}
404
405/* $4d TSTA inherent -**- */
406OP_HANDLER( tsta )
407{
408   CLR_NZ;
409   SET_NZ8(A);
410}
411
412/* $4e ILLEGAL */
413
414/* $4f CLRA inherent -010 */
415OP_HANDLER( clra )
416{
417   A = 0;
418   CLR_NZ;
419   SEZ;
420}
421
422/* $50 NEGX inherent ?*** */
423OP_HANDLER( negx )
424{
425   UINT16 r;
426   r = -X;
427   CLR_NZC;
428   SET_FLAGS8(0,X,r);
429   X = r;
430}
431
432/* $51 ILLEGAL */
433
434/* $52 ILLEGAL */
435
436/* $53 COMX inherent -**1 */
437OP_HANDLER( comx )
438{
439   X = ~X;
440   CLR_NZ;
441   SET_NZ8(X);
442   SEC;
443}
444
445/* $54 LSRX inherent -0** */
446OP_HANDLER( lsrx )
447{
448   CLR_NZC;
449   CC |= (X & 0x01);
450   X >>= 1;
451   SET_Z8(X);
452}
453
454/* $55 ILLEGAL */
455
456/* $56 RORX inherent -*** */
457OP_HANDLER( rorx )
458{
459   UINT8 r;
460   r = (CC & 0x01) << 7;
461   CLR_NZC;
462   CC |= (X & 0x01);
463   r |= X>>1;
464   SET_NZ8(r);
465   X = r;
466}
467
468/* $57 ASRX inherent ?*** */
469OP_HANDLER( asrx )
470{
471   CLR_NZC;
472   CC |= (X & 0x01);
473   X = (X & 0x80) | (X >> 1);
474   SET_NZ8(X);
475}
476
477/* $58 ASLX inherent ?*** */
478OP_HANDLER( aslx )
479{
480   UINT16 r;
481   r = X << 1;
482   CLR_NZC;
483   SET_FLAGS8(X,X,r);
484   X = r;
485}
486
487/* $59 ROLX inherent -*** */
488OP_HANDLER( rolx )
489{
490   UINT16 t,r;
491   t = X;
492   r = CC & 0x01;
493   r |= t<<1;
494   CLR_NZC;
495   SET_FLAGS8(t,t,r);
496   X = r;
497}
498
499/* $5a DECX inherent -**- */
500OP_HANDLER( decx )
501{
502   --X;
503   CLR_NZ;
504   SET_FLAGS8D(X);
505}
506
507/* $5b ILLEGAL */
508
509/* $5c INCX inherent -**- */
510OP_HANDLER( incx )
511{
512   ++X;
513   CLR_NZ;
514   SET_FLAGS8I(X);
515}
516
517/* $5d TSTX inherent -**- */
518OP_HANDLER( tstx )
519{
520   CLR_NZ;
521   SET_NZ8(X);
522}
523
524/* $5e ILLEGAL */
525
526/* $5f CLRX inherent -010 */
527OP_HANDLER( clrx )
528{
529   X = 0;
530   CLR_NZC;
531   SEZ;
532}
533
534/* $60 NEG indexed, 1 byte offset -*** */
535OP_HANDLER( neg_ix1 )
536{
537   UINT8 t;
538   UINT16 r;
539   IDX1BYTE(t); r=-t;
540   CLR_NZC; SET_FLAGS8(0,t,r);
541   WM(EAD,r);
542}
543
544/* $61 ILLEGAL */
545
546/* $62 ILLEGAL */
547
548/* $63 COM indexed, 1 byte offset -**1 */
549OP_HANDLER( com_ix1 )
550{
551   UINT8 t;
552   IDX1BYTE(t); t = ~t;
553   CLR_NZ; SET_NZ8(t); SEC;
554   WM(EAD,t);
555}
556
557/* $64 LSR indexed, 1 byte offset -0** */
558OP_HANDLER( lsr_ix1 )
559{
560   UINT8 t;
561   IDX1BYTE(t);
562   CLR_NZC;
563   CC |= (t & 0x01);
564   t >>= 1;
565   SET_Z8(t);
566   WM(EAD,t);
567}
568
569/* $65 ILLEGAL */
570
571/* $66 ROR indexed, 1 byte offset -*** */
572OP_HANDLER( ror_ix1 )
573{
574   UINT8 t,r;
575   IDX1BYTE(t);
576   r = (CC & 0x01) << 7;
577   CLR_NZC;
578   CC |= (t & 0x01);
579   r |= t>>1;
580   SET_NZ8(r);
581   WM(EAD,r);
582}
583
584/* $67 ASR indexed, 1 byte offset ?*** */
585OP_HANDLER( asr_ix1 )
586{
587   UINT8 t;
588   IDX1BYTE(t);
589   CLR_NZC; CC|=(t&0x01);
590   t>>=1; t|=((t&0x40)<<1);
591   SET_NZ8(t);
592   WM(EAD,t);
593}
594
595/* $68 LSL indexed, 1 byte offset ?*** */
596OP_HANDLER( lsl_ix1 )
597{
598   UINT8 t;
599   UINT16 r;
600   IDX1BYTE(t);
601   r = t << 1;
602   CLR_NZC;
603   SET_FLAGS8(t,t,r);
604   WM(EAD,r);
605}
606
607/* $69 ROL indexed, 1 byte offset -*** */
608OP_HANDLER( rol_ix1 )
609{
610   UINT16 t,r;
611   IDX1BYTE(t);
612   r = CC & 0x01;
613   r |= t << 1;
614   CLR_NZC;
615   SET_FLAGS8(t,t,r);
616   WM(EAD,r);
617}
618
619/* $6a DEC indexed, 1 byte offset -**- */
620OP_HANDLER( dec_ix1 )
621{
622   UINT8 t;
623   IDX1BYTE(t);
624   --t;
625   CLR_NZ; SET_FLAGS8D(t);
626   WM(EAD,t);
627}
628
629/* $6b ILLEGAL */
630
631/* $6c INC indexed, 1 byte offset -**- */
632OP_HANDLER( inc_ix1 )
633{
634   UINT8 t;
635   IDX1BYTE(t);
636   ++t;
637   CLR_NZ; SET_FLAGS8I(t);
638   WM(EAD,t);
639}
640
641/* $6d TST indexed, 1 byte offset -**- */
642OP_HANDLER( tst_ix1 )
643{
644   UINT8 t;
645   IDX1BYTE(t);
646   CLR_NZ; SET_NZ8(t);
647}
648
649/* $6e ILLEGAL */
650
651/* $6f CLR indexed, 1 byte offset -0100 */
652OP_HANDLER( clr_ix1 )
653{
654   INDEXED1;
655   CLR_NZC; SEZ;
656   WM(EAD,0);
657}
658
659/* $70 NEG indexed -*** */
660OP_HANDLER( neg_ix )
661{
662   UINT8 t;
663   UINT16 r;
664   IDXBYTE(t); r=-t;
665   CLR_NZC; SET_FLAGS8(0,t,r);
666   WM(EAD,r);
667}
668
669/* $71 ILLEGAL */
670
671/* $72 ILLEGAL */
672
673/* $73 COM indexed -**1 */
674OP_HANDLER( com_ix )
675{
676   UINT8 t;
677   IDXBYTE(t); t = ~t;
678   CLR_NZ; SET_NZ8(t); SEC;
679   WM(EAD,t);
680}
681
682/* $74 LSR indexed -0** */
683OP_HANDLER( lsr_ix )
684{
685   UINT8 t;
686   IDXBYTE(t);
687   CLR_NZC;
688   CC |= (t & 0x01);
689   t >>= 1;
690   SET_Z8(t);
691   WM(EAD,t);
692}
693
694/* $75 ILLEGAL */
695
696/* $76 ROR indexed -*** */
697OP_HANDLER( ror_ix )
698{
699   UINT8 t,r;
700   IDXBYTE(t);
701   r = (CC & 0x01) << 7;
702   CLR_NZC;
703   CC |= (t & 0x01);
704   r |= t >> 1;
705   SET_NZ8(r);
706   WM(EAD,r);
707}
708
709/* $77 ASR indexed ?*** */
710OP_HANDLER( asr_ix )
711{
712   UINT8 t;
713   IDXBYTE(t);
714   CLR_NZC;
715   CC |= (t & 0x01);
716   t = (t & 0x80) | (t >> 1);
717   SET_NZ8(t);
718   WM(EAD,t);
719}
720
721/* $78 LSL indexed ?*** */
722OP_HANDLER( lsl_ix )
723{
724   UINT8 t;
725   UINT16 r;
726   IDXBYTE(t); r=t<<1;
727   CLR_NZC; SET_FLAGS8(t,t,r);
728   WM(EAD,r);
729}
730
731/* $79 ROL indexed -*** */
732OP_HANDLER( rol_ix )
733{
734   UINT16 t,r;
735   IDXBYTE(t);
736   r = CC & 0x01;
737   r |= t << 1;
738   CLR_NZC;
739   SET_FLAGS8(t,t,r);
740   WM(EAD,r);
741}
742
743/* $7a DEC indexed -**- */
744OP_HANDLER( dec_ix )
745{
746   UINT8 t;
747   IDXBYTE(t);
748   --t;
749   CLR_NZ; SET_FLAGS8D(t);
750   WM(EAD,t);
751}
752
753/* $7b ILLEGAL */
754
755/* $7c INC indexed -**- */
756OP_HANDLER( inc_ix )
757{
758   UINT8 t;
759   IDXBYTE(t);
760   ++t;
761   CLR_NZ; SET_FLAGS8I(t);
762   WM(EAD,t);
763}
764
765/* $7d TST indexed -**- */
766OP_HANDLER( tst_ix )
767{
768   UINT8 t;
769   IDXBYTE(t);
770   CLR_NZ; SET_NZ8(t);
771}
772
773/* $7e ILLEGAL */
774
775/* $7f CLR indexed -0100 */
776OP_HANDLER( clr_ix )
777{
778   INDEXED;
779   CLR_NZC; SEZ;
780   WM(EAD,0);
781}
782
783/* $80 RTI inherent #### */
784OP_HANDLER( rti )
785{
786   PULLBYTE(CC);
787   PULLBYTE(A);
788   PULLBYTE(X);
789   PULLWORD(m_pc);
790#if IRQ_LEVEL_DETECT
791   if( m_irq_state != CLEAR_LINE && (CC & IFLAG) == 0 )
792   {
793      m_pending_interrupts |= M6805_INT_IRQ;
794   }
795#endif
796}
797
798/* $81 RTS inherent ---- */
799OP_HANDLER( rts )
800{
801   PULLWORD(m_pc);
802}
803
804/* $82 ILLEGAL */
805
806/* $83 SWI absolute indirect ---- */
807OP_HANDLER( swi )
808{
809   PUSHWORD(m_pc);
810   PUSHBYTE(m_x);
811   PUSHBYTE(m_a);
812   PUSHBYTE(m_cc);
813   SEI;
814   RM16(0xfffc, &m_pc);
815}
816
817DERIVED_OP_HANDLER( hd63705, swi )
818{
819   PUSHWORD(m_pc);
820   PUSHBYTE(m_x);
821   PUSHBYTE(m_a);
822   PUSHBYTE(m_cc);
823   SEI;
824   RM16(0x1ffa, &m_pc);
825}
826/* $84 ILLEGAL */
827
828/* $85 ILLEGAL */
829
830/* $86 ILLEGAL */
831
832/* $87 ILLEGAL */
833
834/* $88 ILLEGAL */
835
836/* $89 ILLEGAL */
837
838/* $8A ILLEGAL */
839
840/* $8B ILLEGAL */
841
842/* $8C ILLEGAL */
843
844/* $8D ILLEGAL */
845
846/* $8E ILLEGAL */
847
848/* $8F ILLEGAL */
849
850/* $90 ILLEGAL */
851
852/* $91 ILLEGAL */
853
854/* $92 ILLEGAL */
855
856/* $93 ILLEGAL */
857
858/* $94 ILLEGAL */
859
860/* $95 ILLEGAL */
861
862/* $96 ILLEGAL */
863
864/* $97 TAX inherent ---- */
865OP_HANDLER( tax )
866{
867   X = A;
868}
869
870/* $98 CLC */
871
872/* $99 SEC */
873
874/* $9A CLI */
875
876/* $9B SEI */
877
878/* $9C RSP inherent ---- */
879OP_HANDLER( rsp )
880{
881   S = SP_MASK;
882}
883
884/* $9D NOP inherent ---- */
885OP_HANDLER( nop )
886{
887}
888
889/* $9E ILLEGAL */
890
891/* $9F TXA inherent ---- */
892OP_HANDLER( txa )
893{
894   A = X;
895}
896
897/* $a0 SUBA immediate ?*** */
898OP_HANDLER( suba_im )
899{
900   UINT16    t,r;
901   IMMBYTE(t);
902   r = A - t;
903   CLR_NZC;
904   SET_FLAGS8(A,t,r);
905   A = r;
906}
907
908/* $a1 CMPA immediate ?*** */
909OP_HANDLER( cmpa_im )
910{
911   UINT16    t,r;
912   IMMBYTE(t);
913   r = A - t;
914   CLR_NZC;
915   SET_FLAGS8(A,t,r);
916}
917
918/* $a2 SBCA immediate ?*** */
919OP_HANDLER( sbca_im )
920{
921   UINT16    t,r;
922   IMMBYTE(t);
923   r = A - t - (CC & 0x01);
924   CLR_NZC;
925   SET_FLAGS8(A,t,r);
926   A = r;
927}
928
929/* $a3 CPX immediate -*** */
930OP_HANDLER( cpx_im )
931{
932   UINT16    t,r;
933   IMMBYTE(t);
934   r = X - t;
935   CLR_NZC;
936   SET_FLAGS8(X,t,r);
937}
938
939/* $a4 ANDA immediate -**- */
940OP_HANDLER( anda_im )
941{
942   UINT8 t;
943   IMMBYTE(t);
944   A &= t;
945   CLR_NZ;
946   SET_NZ8(A);
947}
948
949/* $a5 BITA immediate -**- */
950OP_HANDLER( bita_im )
951{
952   UINT8 t,r;
953   IMMBYTE(t);
954   r = A & t;
955   CLR_NZ;
956   SET_NZ8(r);
957}
958
959/* $a6 LDA immediate -**- */
960OP_HANDLER( lda_im )
961{
962   IMMBYTE(A);
963   CLR_NZ;
964   SET_NZ8(A);
965}
966
967/* $a7 ILLEGAL */
968
969/* $a8 EORA immediate -**- */
970OP_HANDLER( eora_im )
971{
972   UINT8 t;
973   IMMBYTE(t);
974   A ^= t;
975   CLR_NZ;
976   SET_NZ8(A);
977}
978
979/* $a9 ADCA immediate **** */
980OP_HANDLER( adca_im )
981{
982   UINT16 t,r;
983   IMMBYTE(t);
984   r = A + t + (CC & 0x01);
985   CLR_HNZC;
986   SET_FLAGS8(A,t,r);
987   SET_H(A,t,r);
988   A = r;
989}
990
991/* $aa ORA immediate -**- */
992OP_HANDLER( ora_im )
993{
994   UINT8 t;
995   IMMBYTE(t);
996   A |= t;
997   CLR_NZ;
998   SET_NZ8(A);
999}
1000
1001/* $ab ADDA immediate **** */
1002OP_HANDLER( adda_im )
1003{
1004   UINT16 t,r;
1005   IMMBYTE(t);
1006   r = A + t;
1007   CLR_HNZC;
1008   SET_FLAGS8(A,t,r);
1009   SET_H(A,t,r);
1010   A = r;
1011}
1012
1013/* $ac ILLEGAL */
1014
1015/* $ad BSR ---- */
1016OP_HANDLER( bsr )
1017{
1018   UINT8 t;
1019   IMMBYTE(t);
1020   PUSHWORD(m_pc);
1021   PC += SIGNED(t);
1022}
1023
1024/* $ae LDX immediate -**- */
1025OP_HANDLER( ldx_im )
1026{
1027   IMMBYTE(X);
1028   CLR_NZ;
1029   SET_NZ8(X);
1030}
1031
1032/* $af ILLEGAL */
1033
1034/* $b0 SUBA direct ?*** */
1035OP_HANDLER( suba_di )
1036{
1037   UINT16    t,r;
1038   DIRBYTE(t);
1039   r = A - t;
1040   CLR_NZC;
1041   SET_FLAGS8(A,t,r);
1042   A = r;
1043}
1044
1045/* $b1 CMPA direct ?*** */
1046OP_HANDLER( cmpa_di )
1047{
1048   UINT16    t,r;
1049   DIRBYTE(t);
1050   r = A - t;
1051   CLR_NZC;
1052   SET_FLAGS8(A,t,r);
1053}
1054
1055/* $b2 SBCA direct ?*** */
1056OP_HANDLER( sbca_di )
1057{
1058   UINT16    t,r;
1059   DIRBYTE(t);
1060   r = A - t - (CC & 0x01);
1061   CLR_NZC;
1062   SET_FLAGS8(A,t,r);
1063   A = r;
1064}
1065
1066/* $b3 CPX direct -*** */
1067OP_HANDLER( cpx_di )
1068{
1069   UINT16    t,r;
1070   DIRBYTE(t);
1071   r = X - t;
1072   CLR_NZC;
1073   SET_FLAGS8(X,t,r);
1074}
1075
1076/* $b4 ANDA direct -**- */
1077OP_HANDLER( anda_di )
1078{
1079   UINT8 t;
1080   DIRBYTE(t);
1081   A &= t;
1082   CLR_NZ;
1083   SET_NZ8(A);
1084}
1085
1086/* $b5 BITA direct -**- */
1087OP_HANDLER( bita_di )
1088{
1089   UINT8 t,r;
1090   DIRBYTE(t);
1091   r = A & t;
1092   CLR_NZ;
1093   SET_NZ8(r);
1094}
1095
1096/* $b6 LDA direct -**- */
1097OP_HANDLER( lda_di )
1098{
1099   DIRBYTE(A);
1100   CLR_NZ;
1101   SET_NZ8(A);
1102}
1103
1104/* $b7 STA direct -**- */
1105OP_HANDLER( sta_di )
1106{
1107   CLR_NZ;
1108   SET_NZ8(A);
1109   DIRECT;
1110   WM(EAD,A);
1111}
1112
1113/* $b8 EORA direct -**- */
1114OP_HANDLER( eora_di )
1115{
1116   UINT8 t;
1117   DIRBYTE(t);
1118   A ^= t;
1119   CLR_NZ;
1120   SET_NZ8(A);
1121}
1122
1123/* $b9 ADCA direct **** */
1124OP_HANDLER( adca_di )
1125{
1126   UINT16 t,r;
1127   DIRBYTE(t);
1128   r = A + t + (CC & 0x01);
1129   CLR_HNZC;
1130   SET_FLAGS8(A,t,r);
1131   SET_H(A,t,r);
1132   A = r;
1133}
1134
1135/* $ba ORA direct -**- */
1136OP_HANDLER( ora_di )
1137{
1138   UINT8 t;
1139   DIRBYTE(t);
1140   A |= t;
1141   CLR_NZ;
1142   SET_NZ8(A);
1143}
1144
1145/* $bb ADDA direct **** */
1146OP_HANDLER( adda_di )
1147{
1148   UINT16 t,r;
1149   DIRBYTE(t);
1150   r = A + t;
1151   CLR_HNZC;
1152   SET_FLAGS8(A,t,r);
1153   SET_H(A,t,r);
1154   A = r;
1155}
1156
1157/* $bc JMP direct -*** */
1158OP_HANDLER( jmp_di )
1159{
1160   DIRECT;
1161   PC = EA;
1162}
1163
1164/* $bd JSR direct ---- */
1165OP_HANDLER( jsr_di )
1166{
1167   DIRECT;
1168   PUSHWORD(m_pc);
1169   PC = EA;
1170}
1171
1172/* $be LDX direct -**- */
1173OP_HANDLER( ldx_di )
1174{
1175   DIRBYTE(X);
1176   CLR_NZ;
1177   SET_NZ8(X);
1178}
1179
1180/* $bf STX direct -**- */
1181OP_HANDLER( stx_di )
1182{
1183   CLR_NZ;
1184   SET_NZ8(X);
1185   DIRECT;
1186   WM(EAD,X);
1187}
1188
1189/* $c0 SUBA extended ?*** */
1190OP_HANDLER( suba_ex )
1191{
1192   UINT16    t,r;
1193   EXTBYTE(t);
1194   r = A - t;
1195   CLR_NZC;
1196   SET_FLAGS8(A,t,r);
1197   A = r;
1198}
1199
1200/* $c1 CMPA extended ?*** */
1201OP_HANDLER( cmpa_ex )
1202{
1203   UINT16    t,r;
1204   EXTBYTE(t);
1205   r = A - t;
1206   CLR_NZC;
1207   SET_FLAGS8(A,t,r);
1208}
1209
1210/* $c2 SBCA extended ?*** */
1211OP_HANDLER( sbca_ex )
1212{
1213   UINT16    t,r;
1214   EXTBYTE(t);
1215   r = A - t - (CC & 0x01);
1216   CLR_NZC;
1217   SET_FLAGS8(A,t,r);
1218   A = r;
1219}
1220
1221/* $c3 CPX extended -*** */
1222OP_HANDLER( cpx_ex )
1223{
1224   UINT16    t,r;
1225   EXTBYTE(t);
1226   r = X - t;
1227   CLR_NZC;
1228   SET_FLAGS8(X,t,r);
1229}
1230
1231/* $c4 ANDA extended -**- */
1232OP_HANDLER( anda_ex )
1233{
1234   UINT8 t;
1235   EXTBYTE(t);
1236   A &= t;
1237   CLR_NZ;
1238   SET_NZ8(A);
1239}
1240
1241/* $c5 BITA extended -**- */
1242OP_HANDLER( bita_ex )
1243{
1244   UINT8 t,r;
1245   EXTBYTE(t);
1246   r = A & t;
1247   CLR_NZ;
1248   SET_NZ8(r);
1249}
1250
1251/* $c6 LDA extended -**- */
1252OP_HANDLER( lda_ex )
1253{
1254   EXTBYTE(A);
1255   CLR_NZ;
1256   SET_NZ8(A);
1257}
1258
1259/* $c7 STA extended -**- */
1260OP_HANDLER( sta_ex )
1261{
1262   CLR_NZ;
1263   SET_NZ8(A);
1264   EXTENDED;
1265   WM(EAD,A);
1266}
1267
1268/* $c8 EORA extended -**- */
1269OP_HANDLER( eora_ex )
1270{
1271   UINT8 t;
1272   EXTBYTE(t);
1273   A ^= t;
1274   CLR_NZ;
1275   SET_NZ8(A);
1276}
1277
1278/* $c9 ADCA extended **** */
1279OP_HANDLER( adca_ex )
1280{
1281   UINT16 t,r;
1282   EXTBYTE(t);
1283   r = A + t + (CC & 0x01);
1284   CLR_HNZC;
1285   SET_FLAGS8(A,t,r);
1286   SET_H(A,t,r);
1287   A = r;
1288}
1289
1290/* $ca ORA extended -**- */
1291OP_HANDLER( ora_ex )
1292{
1293   UINT8 t;
1294   EXTBYTE(t);
1295   A |= t;
1296   CLR_NZ;
1297   SET_NZ8(A);
1298}
1299
1300/* $cb ADDA extended **** */
1301OP_HANDLER( adda_ex )
1302{
1303   UINT16 t,r;
1304   EXTBYTE(t);
1305   r = A + t;
1306   CLR_HNZC;
1307   SET_FLAGS8(A,t,r);
1308   SET_H(A,t,r);
1309   A = r;
1310}
1311
1312/* $cc JMP extended -*** */
1313OP_HANDLER( jmp_ex )
1314{
1315   EXTENDED;
1316   PC = EA;
1317}
1318
1319/* $cd JSR extended ---- */
1320OP_HANDLER( jsr_ex )
1321{
1322   EXTENDED;
1323   PUSHWORD(m_pc);
1324   PC = EA;
1325}
1326
1327/* $ce LDX extended -**- */
1328OP_HANDLER( ldx_ex )
1329{
1330   EXTBYTE(X);
1331   CLR_NZ;
1332   SET_NZ8(X);
1333}
1334
1335/* $cf STX extended -**- */
1336OP_HANDLER( stx_ex )
1337{
1338   CLR_NZ;
1339   SET_NZ8(X);
1340   EXTENDED;
1341   WM(EAD,X);
1342}
1343
1344/* $d0 SUBA indexed, 2 byte offset ?*** */
1345OP_HANDLER( suba_ix2 )
1346{
1347   UINT16    t,r;
1348   IDX2BYTE(t);
1349   r = A - t;
1350   CLR_NZC;
1351   SET_FLAGS8(A,t,r);
1352   A = r;
1353}
1354
1355/* $d1 CMPA indexed, 2 byte offset ?*** */
1356OP_HANDLER( cmpa_ix2 )
1357{
1358   UINT16    t,r;
1359   IDX2BYTE(t);
1360   r = A - t;
1361   CLR_NZC;
1362   SET_FLAGS8(A,t,r);
1363}
1364
1365/* $d2 SBCA indexed, 2 byte offset ?*** */
1366OP_HANDLER( sbca_ix2 )
1367{
1368   UINT16    t,r;
1369   IDX2BYTE(t);
1370   r = A - t - (CC & 0x01);
1371   CLR_NZC;
1372   SET_FLAGS8(A,t,r);
1373   A = r;
1374}
1375
1376/* $d3 CPX indexed, 2 byte offset -*** */
1377OP_HANDLER( cpx_ix2 )
1378{
1379   UINT16    t,r;
1380   IDX2BYTE(t);
1381   r = X - t;
1382   CLR_NZC;
1383   SET_FLAGS8(X,t,r);
1384}
1385
1386/* $d4 ANDA indexed, 2 byte offset -**- */
1387OP_HANDLER( anda_ix2 )
1388{
1389   UINT8 t;
1390   IDX2BYTE(t);
1391   A &= t;
1392   CLR_NZ;
1393   SET_NZ8(A);
1394}
1395
1396/* $d5 BITA indexed, 2 byte offset -**- */
1397OP_HANDLER( bita_ix2 )
1398{
1399   UINT8 t,r;
1400   IDX2BYTE(t);
1401   r = A & t;
1402   CLR_NZ;
1403   SET_NZ8(r);
1404}
1405
1406/* $d6 LDA indexed, 2 byte offset -**- */
1407OP_HANDLER( lda_ix2 )
1408{
1409   IDX2BYTE(A);
1410   CLR_NZ;
1411   SET_NZ8(A);
1412}
1413
1414/* $d7 STA indexed, 2 byte offset -**- */
1415OP_HANDLER( sta_ix2 )
1416{
1417   CLR_NZ;
1418   SET_NZ8(A);
1419   INDEXED2;
1420   WM(EAD,A);
1421}
1422
1423/* $d8 EORA indexed, 2 byte offset -**- */
1424OP_HANDLER( eora_ix2 )
1425{
1426   UINT8 t;
1427   IDX2BYTE(t);
1428   A ^= t;
1429   CLR_NZ;
1430   SET_NZ8(A);
1431}
1432
1433/* $d9 ADCA indexed, 2 byte offset **** */
1434OP_HANDLER( adca_ix2 )
1435{
1436   UINT16 t,r;
1437   IDX2BYTE(t);
1438   r = A + t + (CC & 0x01);
1439   CLR_HNZC;
1440   SET_FLAGS8(A,t,r);
1441   SET_H(A,t,r);
1442   A = r;
1443}
1444
1445/* $da ORA indexed, 2 byte offset -**- */
1446OP_HANDLER( ora_ix2 )
1447{
1448   UINT8 t;
1449   IDX2BYTE(t);
1450   A |= t;
1451   CLR_NZ;
1452   SET_NZ8(A);
1453}
1454
1455/* $db ADDA indexed, 2 byte offset **** */
1456OP_HANDLER( adda_ix2 )
1457{
1458   UINT16 t,r;
1459   IDX2BYTE(t);
1460   r = A + t;
1461   CLR_HNZC;
1462   SET_FLAGS8(A,t,r);
1463   SET_H(A,t,r);
1464   A = r;
1465}
1466
1467/* $dc JMP indexed, 2 byte offset -*** */
1468OP_HANDLER( jmp_ix2 )
1469{
1470   INDEXED2;
1471   PC = EA;
1472}
1473
1474/* $dd JSR indexed, 2 byte offset ---- */
1475OP_HANDLER( jsr_ix2 )
1476{
1477   INDEXED2;
1478   PUSHWORD(m_pc);
1479   PC = EA;
1480}
1481
1482/* $de LDX indexed, 2 byte offset -**- */
1483OP_HANDLER( ldx_ix2 )
1484{
1485   IDX2BYTE(X);
1486   CLR_NZ;
1487   SET_NZ8(X);
1488}
1489
1490/* $df STX indexed, 2 byte offset -**- */
1491OP_HANDLER( stx_ix2 )
1492{
1493   CLR_NZ;
1494   SET_NZ8(X);
1495   INDEXED2;
1496   WM(EAD,X);
1497}
1498
1499/* $e0 SUBA indexed, 1 byte offset ?*** */
1500OP_HANDLER( suba_ix1 )
1501{
1502   UINT16    t,r;
1503   IDX1BYTE(t);
1504   r = A - t;
1505   CLR_NZC;
1506   SET_FLAGS8(A,t,r);
1507   A = r;
1508}
1509
1510/* $e1 CMPA indexed, 1 byte offset ?*** */
1511OP_HANDLER( cmpa_ix1 )
1512{
1513   UINT16    t,r;
1514   IDX1BYTE(t);
1515   r = A - t;
1516   CLR_NZC;
1517   SET_FLAGS8(A,t,r);
1518}
1519
1520/* $e2 SBCA indexed, 1 byte offset ?*** */
1521OP_HANDLER( sbca_ix1 )
1522{
1523   UINT16    t,r;
1524   IDX1BYTE(t);
1525   r = A - t - (CC & 0x01);
1526   CLR_NZC;
1527   SET_FLAGS8(A,t,r);
1528   A = r;
1529}
1530
1531/* $e3 CPX indexed, 1 byte offset -*** */
1532OP_HANDLER( cpx_ix1 )
1533{
1534   UINT16    t,r;
1535   IDX1BYTE(t);
1536   r = X - t;
1537   CLR_NZC;
1538   SET_FLAGS8(X,t,r);
1539}
1540
1541/* $e4 ANDA indexed, 1 byte offset -**- */
1542OP_HANDLER( anda_ix1 )
1543{
1544   UINT8 t;
1545   IDX1BYTE(t);
1546   A &= t;
1547   CLR_NZ;
1548   SET_NZ8(A);
1549}
1550
1551/* $e5 BITA indexed, 1 byte offset -**- */
1552OP_HANDLER( bita_ix1 )
1553{
1554   UINT8 t,r;
1555   IDX1BYTE(t);
1556   r = A & t;
1557   CLR_NZ;
1558   SET_NZ8(r);
1559}
1560
1561/* $e6 LDA indexed, 1 byte offset -**- */
1562OP_HANDLER( lda_ix1 )
1563{
1564   IDX1BYTE(A);
1565   CLR_NZ;
1566   SET_NZ8(A);
1567}
1568
1569/* $e7 STA indexed, 1 byte offset -**- */
1570OP_HANDLER( sta_ix1 )
1571{
1572   CLR_NZ;
1573   SET_NZ8(A);
1574   INDEXED1;
1575   WM(EAD,A);
1576}
1577
1578/* $e8 EORA indexed, 1 byte offset -**- */
1579OP_HANDLER( eora_ix1 )
1580{
1581   UINT8 t;
1582   IDX1BYTE(t);
1583   A ^= t;
1584   CLR_NZ;
1585   SET_NZ8(A);
1586}
1587
1588/* $e9 ADCA indexed, 1 byte offset **** */
1589OP_HANDLER( adca_ix1 )
1590{
1591   UINT16 t,r;
1592   IDX1BYTE(t);
1593   r = A + t + (CC & 0x01);
1594   CLR_HNZC;
1595   SET_FLAGS8(A,t,r);
1596   SET_H(A,t,r);
1597   A = r;
1598}
1599
1600/* $ea ORA indexed, 1 byte offset -**- */
1601OP_HANDLER( ora_ix1 )
1602{
1603   UINT8 t;
1604   IDX1BYTE(t);
1605   A |= t;
1606   CLR_NZ;
1607   SET_NZ8(A);
1608}
1609
1610/* $eb ADDA indexed, 1 byte offset **** */
1611OP_HANDLER( adda_ix1 )
1612{
1613   UINT16 t,r;
1614   IDX1BYTE(t);
1615   r = A + t;
1616   CLR_HNZC;
1617   SET_FLAGS8(A,t,r);
1618   SET_H(A,t,r);
1619   A = r;
1620}
1621
1622/* $ec JMP indexed, 1 byte offset -*** */
1623OP_HANDLER( jmp_ix1 )
1624{
1625   INDEXED1;
1626   PC = EA;
1627}
1628
1629/* $ed JSR indexed, 1 byte offset ---- */
1630OP_HANDLER( jsr_ix1 )
1631{
1632   INDEXED1;
1633   PUSHWORD(m_pc);
1634   PC = EA;
1635}
1636
1637/* $ee LDX indexed, 1 byte offset -**- */
1638OP_HANDLER( ldx_ix1 )
1639{
1640   IDX1BYTE(X);
1641   CLR_NZ;
1642   SET_NZ8(X);
1643}
1644
1645/* $ef STX indexed, 1 byte offset -**- */
1646OP_HANDLER( stx_ix1 )
1647{
1648   CLR_NZ;
1649   SET_NZ8(X);
1650   INDEXED1;
1651   WM(EAD,X);
1652}
1653
1654/* $f0 SUBA indexed ?*** */
1655OP_HANDLER( suba_ix )
1656{
1657   UINT16    t,r;
1658   IDXBYTE(t);
1659   r = A - t;
1660   CLR_NZC;
1661   SET_FLAGS8(A,t,r);
1662   A = r;
1663}
1664
1665/* $f1 CMPA indexed ?*** */
1666OP_HANDLER( cmpa_ix )
1667{
1668   UINT16    t,r;
1669   IDXBYTE(t);
1670   r = A - t;
1671   CLR_NZC;
1672   SET_FLAGS8(A,t,r);
1673}
1674
1675/* $f2 SBCA indexed ?*** */
1676OP_HANDLER( sbca_ix )
1677{
1678   UINT16    t,r;
1679   IDXBYTE(t);
1680   r = A - t - (CC & 0x01);
1681   CLR_NZC;
1682   SET_FLAGS8(A,t,r);
1683   A = r;
1684}
1685
1686/* $f3 CPX indexed -*** */
1687OP_HANDLER( cpx_ix )
1688{
1689   UINT16    t,r;
1690   IDXBYTE(t);
1691   r = X - t;
1692   CLR_NZC;
1693   SET_FLAGS8(X,t,r);
1694}
1695
1696/* $f4 ANDA indexed -**- */
1697OP_HANDLER( anda_ix )
1698{
1699   UINT8 t;
1700   IDXBYTE(t);
1701   A &= t;
1702   CLR_NZ;
1703   SET_NZ8(A);
1704}
1705
1706/* $f5 BITA indexed -**- */
1707OP_HANDLER( bita_ix )
1708{
1709   UINT8 t,r;
1710   IDXBYTE(t);
1711   r = A & t;
1712   CLR_NZ;
1713   SET_NZ8(r);
1714}
1715
1716/* $f6 LDA indexed -**- */
1717OP_HANDLER( lda_ix )
1718{
1719   IDXBYTE(A);
1720   CLR_NZ;
1721   SET_NZ8(A);
1722}
1723
1724/* $f7 STA indexed -**- */
1725OP_HANDLER( sta_ix )
1726{
1727   CLR_NZ;
1728   SET_NZ8(A);
1729   INDEXED;
1730   WM(EAD,A);
1731}
1732
1733/* $f8 EORA indexed -**- */
1734OP_HANDLER( eora_ix )
1735{
1736   UINT8 t;
1737   IDXBYTE(t);
1738   A ^= t;
1739   CLR_NZ;
1740   SET_NZ8(A);
1741}
1742
1743/* $f9 ADCA indexed **** */
1744OP_HANDLER( adca_ix )
1745{
1746   UINT16 t,r;
1747   IDXBYTE(t);
1748   r = A + t + (CC & 0x01);
1749   CLR_HNZC;
1750   SET_FLAGS8(A,t,r);
1751   SET_H(A,t,r);
1752   A = r;
1753}
1754
1755/* $fa ORA indexed -**- */
1756OP_HANDLER( ora_ix )
1757{
1758   UINT8 t;
1759   IDXBYTE(t);
1760   A |= t;
1761   CLR_NZ;
1762   SET_NZ8(A);
1763}
1764
1765/* $fb ADDA indexed **** */
1766OP_HANDLER( adda_ix )
1767{
1768   UINT16 t,r;
1769   IDXBYTE(t);
1770   r = A + t;
1771   CLR_HNZC;
1772   SET_FLAGS8(A,t,r);
1773   SET_H(A,t,r);
1774   A = r;
1775}
1776
1777/* $fc JMP indexed -*** */
1778OP_HANDLER( jmp_ix )
1779{
1780   INDEXED;
1781   PC = EA;
1782}
1783
1784/* $fd JSR indexed ---- */
1785OP_HANDLER( jsr_ix )
1786{
1787   INDEXED;
1788   PUSHWORD(m_pc);
1789   PC = EA;
1790}
1791
1792/* $fe LDX indexed -**- */
1793OP_HANDLER( ldx_ix )
1794{
1795   IDXBYTE(X);
1796   CLR_NZ;
1797   SET_NZ8(X);
1798}
1799
1800/* $ff STX indexed -**- */
1801OP_HANDLER( stx_ix )
1802{
1803   CLR_NZ;
1804   SET_NZ8(X);
1805   INDEXED;
1806   WM(EAD,X);
1807}
trunk/src/emu/cpu/m6805/6805ops.inc
r0r28739
1
2/*
3
4HNZC
5
6? = undefined
7* = affected
8- = unaffected
90 = cleared
101 = set
11# = ccr directly affected by instruction
12@ = special - carry set if bit 7 is set
13
14*/
15
16#define OP_HANDLER(_name) void m6805_base_device::_name()
17#define DERIVED_OP_HANDLER(_arch,_name) void _arch##_device::_name()
18
19#define OP_HANDLER_BIT(_name) void m6805_base_device::_name(UINT8 bit)
20
21OP_HANDLER( illegal )
22{
23   logerror("M6805: illegal opcode\n");
24}
25
26/* $00/$02/$04/$06/$08/$0A/$0C/$0E BRSET direct,relative ---- */
27OP_HANDLER_BIT( brset )
28{
29   UINT8 t,r;
30   DIRBYTE(r);
31   IMMBYTE(t);
32
33   CLC;
34
35   if (r&bit) {
36      SEC;
37      PC+=SIGNED(t);
38   }
39}
40
41/* $01/$03/$05/$07/$09/$0B/$0D/$0F BRCLR direct,relative ---- */
42OP_HANDLER_BIT( brclr )
43{
44   UINT8 t,r;
45   DIRBYTE(r);
46   IMMBYTE(t);
47
48   SEC;
49
50   if (!(r&bit)) {
51      CLC;
52      PC+=SIGNED(t);
53   }
54}
55
56/* $10/$12/$14/$16/$18/$1A/$1C/$1E BSET direct ---- */
57OP_HANDLER_BIT( bset )
58{
59   UINT8 t,r;
60   DIRBYTE(t); r=t|bit;
61   WM(EAD,r);
62}
63
64/* $11/$13/$15/$17/$19/$1B/$1D/$1F BCLR direct ---- */
65OP_HANDLER_BIT( bclr)
66{
67   UINT8 t,r;
68   DIRBYTE(t); r=t&(~bit);
69   WM(EAD,r);
70}
71
72/* $20 BRA relative ---- */
73OP_HANDLER( bra )
74{
75   UINT8 t;
76   IMMBYTE(t);
77   PC+=SIGNED(t);
78}
79
80/* $21 BRN relative ---- */
81static UINT8 m6805_brn_t; // hack around GCC 4.6 error because we need the side effects of IMMBYTE
82OP_HANDLER( brn )
83{
84   IMMBYTE(m6805_brn_t);
85}
86
87/* $22 BHI relative ---- */
88OP_HANDLER( bhi )
89{
90   BRANCH( !(CC&(CFLAG|ZFLAG)) );
91}
92
93/* $23 BLS relative ---- */
94OP_HANDLER( bls )
95{
96   BRANCH( CC&(CFLAG|ZFLAG) );
97}
98
99/* $24 BCC relative ---- */
100OP_HANDLER( bcc )
101{
102   BRANCH( !(CC&CFLAG) );
103}
104
105/* $25 BCS relative ---- */
106OP_HANDLER( bcs )
107{
108   BRANCH( CC&CFLAG );
109}
110
111/* $26 BNE relative ---- */
112OP_HANDLER( bne )
113{
114   BRANCH( !(CC&ZFLAG) );
115}
116
117/* $27 BEQ relative ---- */
118OP_HANDLER( beq )
119{
120   BRANCH( CC&ZFLAG );
121}
122
123/* $28 BHCC relative ---- */
124OP_HANDLER( bhcc )
125{
126   BRANCH( !(CC&HFLAG) );
127}
128
129/* $29 BHCS relative ---- */
130OP_HANDLER( bhcs )
131{
132   BRANCH( CC&HFLAG );
133}
134
135/* $2a BPL relative ---- */
136OP_HANDLER( bpl )
137{
138   BRANCH( !(CC&NFLAG) );
139}
140
141/* $2b BMI relative ---- */
142OP_HANDLER( bmi )
143{
144   BRANCH( CC&NFLAG );
145}
146
147/* $2c BMC relative ---- */
148OP_HANDLER( bmc )
149{
150   BRANCH( !(CC&IFLAG) );
151}
152
153/* $2d BMS relative ---- */
154OP_HANDLER( bms )
155{
156   BRANCH( CC&IFLAG );
157}
158
159/* $2e BIL relative ---- */
160OP_HANDLER( bil )
161{
162   BRANCH(m_irq_state[0] != CLEAR_LINE);
163}
164
165DERIVED_OP_HANDLER( hd63705, bil )
166{
167   BRANCH(m_nmi_state != CLEAR_LINE);
168}
169
170/* $2f BIH relative ---- */
171OP_HANDLER( bih )
172{
173   BRANCH(m_irq_state[0] == CLEAR_LINE);
174}
175
176DERIVED_OP_HANDLER( hd63705, bih )
177{
178   BRANCH(m_nmi_state == CLEAR_LINE);
179}
180
181/* $30 NEG direct -*** */
182OP_HANDLER( neg_di )
183{
184   UINT8 t;
185   UINT16 r;
186   DIRBYTE(t);
187   r=-t;
188   CLR_NZC;
189   SET_FLAGS8(0,t,r);
190   WM(EAD,r);
191}
192
193/* $31 ILLEGAL */
194
195/* $32 ILLEGAL */
196
197/* $33 COM direct -**1 */
198OP_HANDLER( com_di )
199{
200   UINT8 t;
201   DIRBYTE(t);
202   t = ~t;
203   CLR_NZ;
204   SET_NZ8(t);
205   SEC;
206   WM(EAD,t);
207}
208
209/* $34 LSR direct -0** */
210OP_HANDLER( lsr_di )
211{
212   UINT8 t;
213   DIRBYTE(t);
214   CLR_NZC;
215   CC |= (t&0x01);
216   t >>= 1;
217   SET_Z8(t);
218   WM(EAD,t);
219}
220
221/* $35 ILLEGAL */
222
223/* $36 ROR direct -*** */
224OP_HANDLER( ror_di )
225{
226   UINT8 t,r;
227   DIRBYTE(t);
228   r = (CC & 0x01) << 7;
229   CLR_NZC;
230   CC |= (t & 0x01);
231   r |= t>>1;
232   SET_NZ8(r);
233   WM(EAD,r);
234}
235
236/* $37 ASR direct ?*** */
237OP_HANDLER( asr_di )
238{
239   UINT8 t;
240   DIRBYTE(t);
241   CLR_NZC; CC|=(t&0x01);
242   t>>=1; t|=((t&0x40)<<1);
243   SET_NZ8(t);
244   WM(EAD,t);
245}
246
247/* $38 LSL direct ?*** */
248OP_HANDLER( lsl_di )
249{
250   UINT8 t;
251   UINT16 r;
252   DIRBYTE(t);
253   r = t << 1;
254   CLR_NZC;
255   SET_FLAGS8(t,t,r);
256   WM(EAD,r);
257}
258
259/* $39 ROL direct -*** */
260OP_HANDLER( rol_di )
261{
262   UINT16 t,r;
263   DIRBYTE(t);
264   r = CC & 0x01;
265   r |= t << 1;
266   CLR_NZC;
267   SET_FLAGS8(t,t,r);
268   WM(EAD,r);
269}
270
271/* $3a DEC direct -**- */
272OP_HANDLER( dec_di )
273{
274   UINT8 t;
275   DIRBYTE(t);
276   --t;
277   CLR_NZ; SET_FLAGS8D(t);
278   WM(EAD,t);
279}
280
281/* $3b ILLEGAL */
282
283/* $3c INC direct -**- */
284OP_HANDLER( inc_di )
285{
286   UINT8 t;
287   DIRBYTE(t);
288   ++t;
289   CLR_NZ; SET_FLAGS8I(t);
290   WM(EAD,t);
291}
292
293/* $3d TST direct -**- */
294OP_HANDLER( tst_di )
295{
296   UINT8 t;
297   DIRBYTE(t);
298   CLR_NZ; SET_NZ8(t);
299}
300
301/* $3e ILLEGAL */
302
303/* $3f CLR direct -0100 */
304OP_HANDLER( clr_di )
305{
306   DIRECT;
307   CLR_NZ; SEZ;
308   WM(EAD,0);
309}
310
311/* $40 NEGA inherent ?*** */
312OP_HANDLER( nega )
313{
314   UINT16 r;
315   r = -A;
316   CLR_NZC; SET_FLAGS8(0,A,r);
317   A = r;
318}
319
320/* $41 ILLEGAL */
321
322/* $42 ILLEGAL */
323
324/* $43 COMA inherent -**1 */
325OP_HANDLER( coma )
326{
327   A = ~A;
328   CLR_NZ;
329   SET_NZ8(A);
330   SEC;
331}
332
333/* $44 LSRA inherent -0** */
334OP_HANDLER( lsra )
335{
336   CLR_NZC;
337   CC |= (A & 0x01);
338   A >>= 1;
339   SET_Z8(A);
340}
341
342/* $45 ILLEGAL */
343
344/* $46 RORA inherent -*** */
345OP_HANDLER( rora )
346{
347   UINT8 r;
348   r = (CC & 0x01) << 7;
349   CLR_NZC;
350   CC |= (A & 0x01);
351   r |= A >> 1;
352   SET_NZ8(r);
353   A = r;
354}
355
356/* $47 ASRA inherent ?*** */
357OP_HANDLER( asra )
358{
359   CLR_NZC;
360   CC |= (A & 0x01);
361   A = (A & 0x80) | (A >> 1);
362   SET_NZ8(A);
363}
364
365/* $48 LSLA inherent ?*** */
366OP_HANDLER( lsla )
367{
368   UINT16 r;
369   r = A << 1;
370   CLR_NZC;
371   SET_FLAGS8(A,A,r);
372   A = r;
373}
374
375/* $49 ROLA inherent -*** */
376OP_HANDLER( rola )
377{
378   UINT16 t,r;
379   t = A;
380   r = CC & 0x01;
381   r |= t << 1;
382   CLR_NZC;
383   SET_FLAGS8(t,t,r);
384   A = r;
385}
386
387/* $4a DECA inherent -**- */
388OP_HANDLER( deca )
389{
390   --A;
391   CLR_NZ;
392   SET_FLAGS8D(A);
393}
394
395/* $4b ILLEGAL */
396
397/* $4c INCA inherent -**- */
398OP_HANDLER( inca )
399{
400   ++A;
401   CLR_NZ;
402   SET_FLAGS8I(A);
403}
404
405/* $4d TSTA inherent -**- */
406OP_HANDLER( tsta )
407{
408   CLR_NZ;
409   SET_NZ8(A);
410}
411
412/* $4e ILLEGAL */
413
414/* $4f CLRA inherent -010 */
415OP_HANDLER( clra )
416{
417   A = 0;
418   CLR_NZ;
419   SEZ;
420}
421
422/* $50 NEGX inherent ?*** */
423OP_HANDLER( negx )
424{
425   UINT16 r;
426   r = -X;
427   CLR_NZC;
428   SET_FLAGS8(0,X,r);
429   X = r;
430}
431
432/* $51 ILLEGAL */
433
434/* $52 ILLEGAL */
435
436/* $53 COMX inherent -**1 */
437OP_HANDLER( comx )
438{
439   X = ~X;
440   CLR_NZ;
441   SET_NZ8(X);
442   SEC;
443}
444
445/* $54 LSRX inherent -0** */
446OP_HANDLER( lsrx )
447{
448   CLR_NZC;
449   CC |= (X & 0x01);
450   X >>= 1;
451   SET_Z8(X);
452}
453
454/* $55 ILLEGAL */
455
456/* $56 RORX inherent -*** */
457OP_HANDLER( rorx )
458{
459   UINT8 r;
460   r = (CC & 0x01) << 7;
461   CLR_NZC;
462   CC |= (X & 0x01);
463   r |= X>>1;
464   SET_NZ8(r);
465   X = r;
466}
467
468/* $57 ASRX inherent ?*** */
469OP_HANDLER( asrx )
470{
471   CLR_NZC;
472   CC |= (X & 0x01);
473   X = (X & 0x80) | (X >> 1);
474   SET_NZ8(X);
475}
476
477/* $58 ASLX inherent ?*** */
478OP_HANDLER( aslx )
479{
480   UINT16 r;
481   r = X << 1;
482   CLR_NZC;
483   SET_FLAGS8(X,X,r);
484   X = r;
485}
486
487/* $59 ROLX inherent -*** */
488OP_HANDLER( rolx )
489{
490   UINT16 t,r;
491   t = X;
492   r = CC & 0x01;
493   r |= t<<1;
494   CLR_NZC;
495   SET_FLAGS8(t,t,r);
496   X = r;
497}
498
499/* $5a DECX inherent -**- */
500OP_HANDLER( decx )
501{
502   --X;
503   CLR_NZ;
504   SET_FLAGS8D(X);
505}
506
507/* $5b ILLEGAL */
508
509/* $5c INCX inherent -**- */
510OP_HANDLER( incx )
511{
512   ++X;
513   CLR_NZ;
514   SET_FLAGS8I(X);
515}
516
517/* $5d TSTX inherent -**- */
518OP_HANDLER( tstx )
519{
520   CLR_NZ;
521   SET_NZ8(X);
522}
523
524/* $5e ILLEGAL */
525
526/* $5f CLRX inherent -010 */
527OP_HANDLER( clrx )
528{
529   X = 0;
530   CLR_NZC;
531   SEZ;
532}
533
534/* $60 NEG indexed, 1 byte offset -*** */
535OP_HANDLER( neg_ix1 )
536{
537   UINT8 t;
538   UINT16 r;
539   IDX1BYTE(t); r=-t;
540   CLR_NZC; SET_FLAGS8(0,t,r);
541   WM(EAD,r);
542}
543
544/* $61 ILLEGAL */
545
546/* $62 ILLEGAL */
547
548/* $63 COM indexed, 1 byte offset -**1 */
549OP_HANDLER( com_ix1 )
550{
551   UINT8 t;
552   IDX1BYTE(t); t = ~t;
553   CLR_NZ; SET_NZ8(t); SEC;
554   WM(EAD,t);
555}
556
557/* $64 LSR indexed, 1 byte offset -0** */
558OP_HANDLER( lsr_ix1 )
559{
560   UINT8 t;
561   IDX1BYTE(t);
562   CLR_NZC;
563   CC |= (t & 0x01);
564   t >>= 1;
565   SET_Z8(t);
566   WM(EAD,t);
567}
568
569/* $65 ILLEGAL */
570
571/* $66 ROR indexed, 1 byte offset -*** */
572OP_HANDLER( ror_ix1 )
573{
574   UINT8 t,r;
575   IDX1BYTE(t);
576   r = (CC & 0x01) << 7;
577   CLR_NZC;
578   CC |= (t & 0x01);
579   r |= t>>1;
580   SET_NZ8(r);
581   WM(EAD,r);
582}
583
584/* $67 ASR indexed, 1 byte offset ?*** */
585OP_HANDLER( asr_ix1 )
586{
587   UINT8 t;
588   IDX1BYTE(t);
589   CLR_NZC; CC|=(t&0x01);
590   t>>=1; t|=((t&0x40)<<1);
591   SET_NZ8(t);
592   WM(EAD,t);
593}
594
595/* $68 LSL indexed, 1 byte offset ?*** */
596OP_HANDLER( lsl_ix1 )
597{
598   UINT8 t;
599   UINT16 r;
600   IDX1BYTE(t);
601   r = t << 1;
602   CLR_NZC;
603   SET_FLAGS8(t,t,r);
604   WM(EAD,r);
605}
606
607/* $69 ROL indexed, 1 byte offset -*** */
608OP_HANDLER( rol_ix1 )
609{
610   UINT16 t,r;
611   IDX1BYTE(t);
612   r = CC & 0x01;
613   r |= t << 1;
614   CLR_NZC;
615   SET_FLAGS8(t,t,r);
616   WM(EAD,r);
617}
618
619/* $6a DEC indexed, 1 byte offset -**- */
620OP_HANDLER( dec_ix1 )
621{
622   UINT8 t;
623   IDX1BYTE(t);
624   --t;
625   CLR_NZ; SET_FLAGS8D(t);
626   WM(EAD,t);
627}
628
629/* $6b ILLEGAL */
630
631/* $6c INC indexed, 1 byte offset -**- */
632OP_HANDLER( inc_ix1 )
633{
634   UINT8 t;
635   IDX1BYTE(t);
636   ++t;
637   CLR_NZ; SET_FLAGS8I(t);
638   WM(EAD,t);
639}
640
641/* $6d TST indexed, 1 byte offset -**- */
642OP_HANDLER( tst_ix1 )
643{
644   UINT8 t;
645   IDX1BYTE(t);
646   CLR_NZ; SET_NZ8(t);
647}
648
649/* $6e ILLEGAL */
650
651/* $6f CLR indexed, 1 byte offset -0100 */
652OP_HANDLER( clr_ix1 )
653{
654   INDEXED1;
655   CLR_NZC; SEZ;
656   WM(EAD,0);
657}
658
659/* $70 NEG indexed -*** */
660OP_HANDLER( neg_ix )
661{
662   UINT8 t;
663   UINT16 r;
664   IDXBYTE(t); r=-t;
665   CLR_NZC; SET_FLAGS8(0,t,r);
666   WM(EAD,r);
667}
668
669/* $71 ILLEGAL */
670
671/* $72 ILLEGAL */
672
673/* $73 COM indexed -**1 */
674OP_HANDLER( com_ix )
675{
676   UINT8 t;
677   IDXBYTE(t); t = ~t;
678   CLR_NZ; SET_NZ8(t); SEC;
679   WM(EAD,t);
680}
681
682/* $74 LSR indexed -0** */
683OP_HANDLER( lsr_ix )
684{
685   UINT8 t;
686   IDXBYTE(t);
687   CLR_NZC;
688   CC |= (t & 0x01);
689   t >>= 1;
690   SET_Z8(t);
691   WM(EAD,t);
692}
693
694/* $75 ILLEGAL */
695
696/* $76 ROR indexed -*** */
697OP_HANDLER( ror_ix )
698{
699   UINT8 t,r;
700   IDXBYTE(t);
701   r = (CC & 0x01) << 7;
702   CLR_NZC;
703   CC |= (t & 0x01);
704   r |= t >> 1;
705   SET_NZ8(r);
706   WM(EAD,r);
707}
708
709/* $77 ASR indexed ?*** */
710OP_HANDLER( asr_ix )
711{
712   UINT8 t;
713   IDXBYTE(t);
714   CLR_NZC;
715   CC |= (t & 0x01);
716   t = (t & 0x80) | (t >> 1);
717   SET_NZ8(t);
718   WM(EAD,t);
719}
720
721/* $78 LSL indexed ?*** */
722OP_HANDLER( lsl_ix )
723{
724   UINT8 t;
725   UINT16 r;
726   IDXBYTE(t); r=t<<1;
727   CLR_NZC; SET_FLAGS8(t,t,r);
728   WM(EAD,r);
729}
730
731/* $79 ROL indexed -*** */
732OP_HANDLER( rol_ix )
733{
734   UINT16 t,r;
735   IDXBYTE(t);
736   r = CC & 0x01;
737   r |= t << 1;
738   CLR_NZC;
739   SET_FLAGS8(t,t,r);
740   WM(EAD,r);
741}
742
743/* $7a DEC indexed -**- */
744OP_HANDLER( dec_ix )
745{
746   UINT8 t;
747   IDXBYTE(t);
748   --t;
749   CLR_NZ; SET_FLAGS8D(t);
750   WM(EAD,t);
751}
752
753/* $7b ILLEGAL */
754
755/* $7c INC indexed -**- */
756OP_HANDLER( inc_ix )
757{
758   UINT8 t;
759   IDXBYTE(t);
760   ++t;
761   CLR_NZ; SET_FLAGS8I(t);
762   WM(EAD,t);
763}
764
765/* $7d TST indexed -**- */
766OP_HANDLER( tst_ix )
767{
768   UINT8 t;
769   IDXBYTE(t);
770   CLR_NZ; SET_NZ8(t);
771}
772
773/* $7e ILLEGAL */
774
775/* $7f CLR indexed -0100 */
776OP_HANDLER( clr_ix )
777{
778   INDEXED;
779   CLR_NZC; SEZ;
780   WM(EAD,0);
781}
782
783/* $80 RTI inherent #### */
784OP_HANDLER( rti )
785{
786   PULLBYTE(CC);
787   PULLBYTE(A);
788   PULLBYTE(X);
789   PULLWORD(m_pc);
790#if IRQ_LEVEL_DETECT
791   if( m_irq_state != CLEAR_LINE && (CC & IFLAG) == 0 )
792   {
793      m_pending_interrupts |= M6805_INT_IRQ;
794   }
795#endif
796}
797
798/* $81 RTS inherent ---- */
799OP_HANDLER( rts )
800{
801   PULLWORD(m_pc);
802}
803
804/* $82 ILLEGAL */
805
806/* $83 SWI absolute indirect ---- */
807OP_HANDLER( swi )
808{
809   PUSHWORD(m_pc);
810   PUSHBYTE(m_x);
811   PUSHBYTE(m_a);
812   PUSHBYTE(m_cc);
813   SEI;
814   RM16(0xfffc, &m_pc);
815}
816
817DERIVED_OP_HANDLER( hd63705, swi )
818{
819   PUSHWORD(m_pc);
820   PUSHBYTE(m_x);
821   PUSHBYTE(m_a);
822   PUSHBYTE(m_cc);
823   SEI;
824   RM16(0x1ffa, &m_pc);
825}
826/* $84 ILLEGAL */
827
828/* $85 ILLEGAL */
829
830/* $86 ILLEGAL */
831
832/* $87 ILLEGAL */
833
834/* $88 ILLEGAL */
835
836/* $89 ILLEGAL */
837
838/* $8A ILLEGAL */
839
840/* $8B ILLEGAL */
841
842/* $8C ILLEGAL */
843
844/* $8D ILLEGAL */
845
846/* $8E ILLEGAL */
847
848/* $8F ILLEGAL */
849
850/* $90 ILLEGAL */
851
852/* $91 ILLEGAL */
853
854/* $92 ILLEGAL */
855
856/* $93 ILLEGAL */
857
858/* $94 ILLEGAL */
859
860/* $95 ILLEGAL */
861
862/* $96 ILLEGAL */
863
864/* $97 TAX inherent ---- */
865OP_HANDLER( tax )
866{
867   X = A;
868}
869
870/* $98 CLC */
871
872/* $99 SEC */
873
874/* $9A CLI */
875
876/* $9B SEI */
877
878/* $9C RSP inherent ---- */
879OP_HANDLER( rsp )
880{
881   S = SP_MASK;
882}
883
884/* $9D NOP inherent ---- */
885OP_HANDLER( nop )
886{
887}
888
889/* $9E ILLEGAL */
890
891/* $9F TXA inherent ---- */
892OP_HANDLER( txa )
893{
894   A = X;
895}
896
897/* $a0 SUBA immediate ?*** */
898OP_HANDLER( suba_im )
899{
900   UINT16    t,r;
901   IMMBYTE(t);
902   r = A - t;
903   CLR_NZC;
904   SET_FLAGS8(A,t,r);
905   A = r;
906}
907
908/* $a1 CMPA immediate ?*** */
909OP_HANDLER( cmpa_im )
910{
911   UINT16    t,r;
912   IMMBYTE(t);
913   r = A - t;
914   CLR_NZC;
915   SET_FLAGS8(A,t,r);
916}
917
918/* $a2 SBCA immediate ?*** */
919OP_HANDLER( sbca_im )
920{
921   UINT16    t,r;
922   IMMBYTE(t);
923   r = A - t - (CC & 0x01);
924   CLR_NZC;
925   SET_FLAGS8(A,t,r);
926   A = r;
927}
928
929/* $a3 CPX immediate -*** */
930OP_HANDLER( cpx_im )
931{
932   UINT16    t,r;
933   IMMBYTE(t);
934   r = X - t;
935   CLR_NZC;
936   SET_FLAGS8(X,t,r);
937}
938
939/* $a4 ANDA immediate -**- */
940OP_HANDLER( anda_im )
941{
942   UINT8 t;
943   IMMBYTE(t);
944   A &= t;
945   CLR_NZ;
946   SET_NZ8(A);
947}
948
949/* $a5 BITA immediate -**- */
950OP_HANDLER( bita_im )
951{
952   UINT8 t,r;
953   IMMBYTE(t);
954   r = A & t;
955   CLR_NZ;
956   SET_NZ8(r);
957}
958
959/* $a6 LDA immediate -**- */
960OP_HANDLER( lda_im )
961{
962   IMMBYTE(A);
963   CLR_NZ;
964   SET_NZ8(A);
965}
966
967/* $a7 ILLEGAL */
968
969/* $a8 EORA immediate -**- */
970OP_HANDLER( eora_im )
971{
972   UINT8 t;
973   IMMBYTE(t);
974   A ^= t;
975   CLR_NZ;
976   SET_NZ8(A);
977}
978
979/* $a9 ADCA immediate **** */
980OP_HANDLER( adca_im )
981{
982   UINT16 t,r;
983   IMMBYTE(t);
984   r = A + t + (CC & 0x01);
985   CLR_HNZC;
986   SET_FLAGS8(A,t,r);
987   SET_H(A,t,r);
988   A = r;
989}
990
991/* $aa ORA immediate -**- */
992OP_HANDLER( ora_im )
993{
994   UINT8 t;
995   IMMBYTE(t);
996   A |= t;
997   CLR_NZ;
998   SET_NZ8(A);
999}
1000
1001/* $ab ADDA immediate **** */
1002OP_HANDLER( adda_im )
1003{
1004   UINT16 t,r;
1005   IMMBYTE(t);
1006   r = A + t;
1007   CLR_HNZC;
1008   SET_FLAGS8(A,t,r);
1009   SET_H(A,t,r);
1010   A = r;
1011}
1012
1013/* $ac ILLEGAL */
1014
1015/* $ad BSR ---- */
1016OP_HANDLER( bsr )
1017{
1018   UINT8 t;
1019   IMMBYTE(t);
1020   PUSHWORD(m_pc);
1021   PC += SIGNED(t);
1022}
1023
1024/* $ae LDX immediate -**- */
1025OP_HANDLER( ldx_im )
1026{
1027   IMMBYTE(X);
1028   CLR_NZ;
1029   SET_NZ8(X);
1030}
1031
1032/* $af ILLEGAL */
1033
1034/* $b0 SUBA direct ?*** */
1035OP_HANDLER( suba_di )
1036{
1037   UINT16    t,r;
1038   DIRBYTE(t);
1039   r = A - t;
1040   CLR_NZC;
1041   SET_FLAGS8(A,t,r);
1042   A = r;
1043}
1044
1045/* $b1 CMPA direct ?*** */
1046OP_HANDLER( cmpa_di )
1047{
1048   UINT16    t,r;
1049   DIRBYTE(t);
1050   r = A - t;
1051   CLR_NZC;
1052   SET_FLAGS8(A,t,r);
1053}
1054
1055/* $b2 SBCA direct ?*** */
1056OP_HANDLER( sbca_di )
1057{
1058   UINT16    t,r;
1059   DIRBYTE(t);
1060   r = A - t - (CC & 0x01);
1061   CLR_NZC;
1062   SET_FLAGS8(A,t,r);
1063   A = r;
1064}
1065
1066/* $b3 CPX direct -*** */
1067OP_HANDLER( cpx_di )
1068{
1069   UINT16    t,r;
1070   DIRBYTE(t);
1071   r = X - t;
1072   CLR_NZC;
1073   SET_FLAGS8(X,t,r);
1074}
1075
1076/* $b4 ANDA direct -**- */
1077OP_HANDLER( anda_di )
1078{
1079   UINT8 t;
1080   DIRBYTE(t);
1081   A &= t;
1082   CLR_NZ;
1083   SET_NZ8(A);
1084}
1085
1086/* $b5 BITA direct -**- */
1087OP_HANDLER( bita_di )
1088{
1089   UINT8 t,r;
1090   DIRBYTE(t);
1091   r = A & t;
1092   CLR_NZ;
1093   SET_NZ8(r);
1094}
1095
1096/* $b6 LDA direct -**- */
1097OP_HANDLER( lda_di )
1098{
1099   DIRBYTE(A);
1100   CLR_NZ;
1101   SET_NZ8(A);
1102}
1103
1104/* $b7 STA direct -**- */
1105OP_HANDLER( sta_di )
1106{
1107   CLR_NZ;
1108   SET_NZ8(A);
1109   DIRECT;
1110   WM(EAD,A);
1111}
1112
1113/* $b8 EORA direct -**- */
1114OP_HANDLER( eora_di )
1115{
1116   UINT8 t;
1117   DIRBYTE(t);
1118   A ^= t;
1119   CLR_NZ;
1120   SET_NZ8(A);
1121}
1122
1123/* $b9 ADCA direct **** */
1124OP_HANDLER( adca_di )
1125{
1126   UINT16 t,r;
1127   DIRBYTE(t);
1128   r = A + t + (CC & 0x01);
1129   CLR_HNZC;
1130   SET_FLAGS8(A,t,r);
1131   SET_H(A,t,r);
1132   A = r;
1133}
1134
1135/* $ba ORA direct -**- */
1136OP_HANDLER( ora_di )
1137{
1138   UINT8 t;
1139   DIRBYTE(t);
1140   A |= t;
1141   CLR_NZ;
1142   SET_NZ8(A);
1143}
1144
1145/* $bb ADDA direct **** */
1146OP_HANDLER( adda_di )
1147{
1148   UINT16 t,r;
1149   DIRBYTE(t);
1150   r = A + t;
1151   CLR_HNZC;
1152   SET_FLAGS8(A,t,r);
1153   SET_H(A,t,r);
1154   A = r;
1155}
1156
1157/* $bc JMP direct -*** */
1158OP_HANDLER( jmp_di )
1159{
1160   DIRECT;
1161   PC = EA;
1162}
1163
1164/* $bd JSR direct ---- */
1165OP_HANDLER( jsr_di )
1166{
1167   DIRECT;
1168   PUSHWORD(m_pc);
1169   PC = EA;
1170}
1171
1172/* $be LDX direct -**- */
1173OP_HANDLER( ldx_di )
1174{
1175   DIRBYTE(X);
1176   CLR_NZ;
1177   SET_NZ8(X);
1178}
1179
1180/* $bf STX direct -**- */
1181OP_HANDLER( stx_di )
1182{
1183   CLR_NZ;
1184   SET_NZ8(X);
1185   DIRECT;
1186   WM(EAD,X);
1187}
1188
1189/* $c0 SUBA extended ?*** */
1190OP_HANDLER( suba_ex )
1191{
1192   UINT16    t,r;
1193   EXTBYTE(t);
1194   r = A - t;
1195   CLR_NZC;
1196   SET_FLAGS8(A,t,r);
1197   A = r;
1198}
1199
1200/* $c1 CMPA extended ?*** */
1201OP_HANDLER( cmpa_ex )
1202{
1203   UINT16    t,r;
1204   EXTBYTE(t);
1205   r = A - t;
1206   CLR_NZC;
1207   SET_FLAGS8(A,t,r);
1208}
1209
1210/* $c2 SBCA extended ?*** */
1211OP_HANDLER( sbca_ex )
1212{
1213   UINT16    t,r;
1214   EXTBYTE(t);
1215   r = A - t - (CC & 0x01);
1216   CLR_NZC;
1217   SET_FLAGS8(A,t,r);
1218   A = r;
1219}
1220
1221/* $c3 CPX extended -*** */
1222OP_HANDLER( cpx_ex )
1223{
1224   UINT16    t,r;
1225   EXTBYTE(t);
1226   r = X - t;
1227   CLR_NZC;
1228   SET_FLAGS8(X,t,r);
1229}
1230
1231/* $c4 ANDA extended -**- */
1232OP_HANDLER( anda_ex )
1233{
1234   UINT8 t;
1235   EXTBYTE(t);
1236   A &= t;
1237   CLR_NZ;
1238   SET_NZ8(A);
1239}
1240
1241/* $c5 BITA extended -**- */
1242OP_HANDLER( bita_ex )
1243{
1244   UINT8 t,r;
1245   EXTBYTE(t);
1246   r = A & t;
1247   CLR_NZ;
1248   SET_NZ8(r);
1249}
1250
1251/* $c6 LDA extended -**- */
1252OP_HANDLER( lda_ex )
1253{
1254   EXTBYTE(A);
1255   CLR_NZ;
1256   SET_NZ8(A);
1257}
1258
1259/* $c7 STA extended -**- */
1260OP_HANDLER( sta_ex )
1261{
1262   CLR_NZ;
1263   SET_NZ8(A);
1264   EXTENDED;
1265   WM(EAD,A);
1266}
1267
1268/* $c8 EORA extended -**- */
1269OP_HANDLER( eora_ex )
1270{
1271   UINT8 t;
1272   EXTBYTE(t);
1273   A ^= t;
1274   CLR_NZ;
1275   SET_NZ8(A);
1276}
1277
1278/* $c9 ADCA extended **** */
1279OP_HANDLER( adca_ex )
1280{
1281   UINT16 t,r;
1282   EXTBYTE(t);
1283   r = A + t + (CC & 0x01);
1284   CLR_HNZC;
1285   SET_FLAGS8(A,t,r);
1286   SET_H(A,t,r);
1287   A = r;
1288}
1289
1290/* $ca ORA extended -**- */
1291OP_HANDLER( ora_ex )
1292{
1293   UINT8 t;
1294   EXTBYTE(t);
1295   A |= t;
1296   CLR_NZ;
1297   SET_NZ8(A);
1298}
1299
1300/* $cb ADDA extended **** */
1301OP_HANDLER( adda_ex )
1302{
1303   UINT16 t,r;
1304   EXTBYTE(t);
1305   r = A + t;
1306   CLR_HNZC;
1307   SET_FLAGS8(A,t,r);
1308   SET_H(A,t,r);
1309   A = r;
1310}
1311
1312/* $cc JMP extended -*** */
1313OP_HANDLER( jmp_ex )
1314{
1315   EXTENDED;
1316   PC = EA;
1317}
1318
1319/* $cd JSR extended ---- */
1320OP_HANDLER( jsr_ex )
1321{
1322   EXTENDED;
1323   PUSHWORD(m_pc);
1324   PC = EA;
1325}
1326
1327/* $ce LDX extended -**- */
1328OP_HANDLER( ldx_ex )
1329{
1330   EXTBYTE(X);
1331   CLR_NZ;
1332   SET_NZ8(X);
1333}
1334
1335/* $cf STX extended -**- */
1336OP_HANDLER( stx_ex )
1337{
1338   CLR_NZ;
1339   SET_NZ8(X);
1340   EXTENDED;
1341   WM(EAD,X);
1342}
1343
1344/* $d0 SUBA indexed, 2 byte offset ?*** */
1345OP_HANDLER( suba_ix2 )
1346{
1347   UINT16    t,r;
1348   IDX2BYTE(t);
1349   r = A - t;
1350   CLR_NZC;
1351   SET_FLAGS8(A,t,r);
1352   A = r;
1353}
1354
1355/* $d1 CMPA indexed, 2 byte offset ?*** */
1356OP_HANDLER( cmpa_ix2 )
1357{
1358   UINT16    t,r;
1359   IDX2BYTE(t);
1360   r = A - t;
1361   CLR_NZC;
1362   SET_FLAGS8(A,t,r);
1363}
1364
1365/* $d2 SBCA indexed, 2 byte offset ?*** */
1366OP_HANDLER( sbca_ix2 )
1367{
1368   UINT16    t,r;
1369   IDX2BYTE(t);
1370   r = A - t - (CC & 0x01);
1371   CLR_NZC;
1372   SET_FLAGS8(A,t,r);
1373   A = r;
1374}
1375
1376/* $d3 CPX indexed, 2 byte offset -*** */
1377OP_HANDLER( cpx_ix2 )
1378{
1379   UINT16    t,r;
1380   IDX2BYTE(t);
1381   r = X - t;
1382   CLR_NZC;
1383   SET_FLAGS8(X,t,r);
1384}
1385
1386/* $d4 ANDA indexed, 2 byte offset -**- */
1387OP_HANDLER( anda_ix2 )
1388{
1389   UINT8 t;
1390   IDX2BYTE(t);
1391   A &= t;
1392   CLR_NZ;
1393   SET_NZ8(A);
1394}
1395
1396/* $d5 BITA indexed, 2 byte offset -**- */
1397OP_HANDLER( bita_ix2 )
1398{
1399   UINT8 t,r;
1400   IDX2BYTE(t);
1401   r = A & t;
1402   CLR_NZ;
1403   SET_NZ8(r);
1404}
1405
1406/* $d6 LDA indexed, 2 byte offset -**- */
1407OP_HANDLER( lda_ix2 )
1408{
1409   IDX2BYTE(A);
1410   CLR_NZ;
1411   SET_NZ8(A);
1412}
1413
1414/* $d7 STA indexed, 2 byte offset -**- */
1415OP_HANDLER( sta_ix2 )
1416{
1417   CLR_NZ;
1418   SET_NZ8(A);
1419   INDEXED2;
1420   WM(EAD,A);
1421}
1422
1423/* $d8 EORA indexed, 2 byte offset -**- */
1424OP_HANDLER( eora_ix2 )
1425{
1426   UINT8 t;
1427   IDX2BYTE(t);
1428   A ^= t;
1429   CLR_NZ;
1430   SET_NZ8(A);
1431}
1432
1433/* $d9 ADCA indexed, 2 byte offset **** */
1434OP_HANDLER( adca_ix2 )
1435{
1436   UINT16 t,r;
1437   IDX2BYTE(t);
1438   r = A + t + (CC & 0x01);
1439   CLR_HNZC;
1440   SET_FLAGS8(A,t,r);
1441   SET_H(A,t,r);
1442   A = r;
1443}
1444
1445/* $da ORA indexed, 2 byte offset -**- */
1446OP_HANDLER( ora_ix2 )
1447{
1448   UINT8 t;
1449   IDX2BYTE(t);
1450   A |= t;
1451   CLR_NZ;
1452   SET_NZ8(A);
1453}
1454
1455/* $db ADDA indexed, 2 byte offset **** */
1456OP_HANDLER( adda_ix2 )
1457{
1458   UINT16 t,r;
1459   IDX2BYTE(t);
1460   r = A + t;
1461   CLR_HNZC;
1462   SET_FLAGS8(A,t,r);
1463   SET_H(A,t,r);
1464   A = r;
1465}
1466
1467/* $dc JMP indexed, 2 byte offset -*** */
1468OP_HANDLER( jmp_ix2 )
1469{
1470   INDEXED2;
1471   PC = EA;
1472}
1473
1474/* $dd JSR indexed, 2 byte offset ---- */
1475OP_HANDLER( jsr_ix2 )
1476{
1477   INDEXED2;
1478   PUSHWORD(m_pc);
1479   PC = EA;
1480}
1481
1482/* $de LDX indexed, 2 byte offset -**- */
1483OP_HANDLER( ldx_ix2 )
1484{
1485   IDX2BYTE(X);
1486   CLR_NZ;
1487   SET_NZ8(X);
1488}
1489
1490/* $df STX indexed, 2 byte offset -**- */
1491OP_HANDLER( stx_ix2 )
1492{
1493   CLR_NZ;
1494   SET_NZ8(X);
1495   INDEXED2;
1496   WM(EAD,X);
1497}
1498
1499/* $e0 SUBA indexed, 1 byte offset ?*** */
1500OP_HANDLER( suba_ix1 )
1501{
1502   UINT16    t,r;
1503   IDX1BYTE(t);
1504   r = A - t;
1505   CLR_NZC;
1506   SET_FLAGS8(A,t,r);
1507   A = r;
1508}
1509
1510/* $e1 CMPA indexed, 1 byte offset ?*** */
1511OP_HANDLER( cmpa_ix1 )
1512{
1513   UINT16    t,r;
1514   IDX1BYTE(t);
1515   r = A - t;
1516   CLR_NZC;
1517   SET_FLAGS8(A,t,r);
1518}
1519
1520/* $e2 SBCA indexed, 1 byte offset ?*** */
1521OP_HANDLER( sbca_ix1 )
1522{
1523   UINT16    t,r;
1524   IDX1BYTE(t);
1525   r = A - t - (CC & 0x01);
1526   CLR_NZC;
1527   SET_FLAGS8(A,t,r);
1528   A = r;
1529}
1530
1531/* $e3 CPX indexed, 1 byte offset -*** */
1532OP_HANDLER( cpx_ix1 )
1533{
1534   UINT16    t,r;
1535   IDX1BYTE(t);
1536   r = X - t;
1537   CLR_NZC;
1538   SET_FLAGS8(X,t,r);
1539}
1540
1541/* $e4 ANDA indexed, 1 byte offset -**- */
1542OP_HANDLER( anda_ix1 )
1543{
1544   UINT8 t;
1545   IDX1BYTE(t);
1546   A &= t;
1547   CLR_NZ;
1548   SET_NZ8(A);
1549}
1550
1551/* $e5 BITA indexed, 1 byte offset -**- */
1552OP_HANDLER( bita_ix1 )
1553{
1554   UINT8 t,r;
1555   IDX1BYTE(t);
1556   r = A & t;
1557   CLR_NZ;
1558   SET_NZ8(r);
1559}
1560
1561/* $e6 LDA indexed, 1 byte offset -**- */
1562OP_HANDLER( lda_ix1 )
1563{
1564   IDX1BYTE(A);
1565   CLR_NZ;
1566   SET_NZ8(A);
1567}
1568
1569/* $e7 STA indexed, 1 byte offset -**- */
1570OP_HANDLER( sta_ix1 )
1571{
1572   CLR_NZ;
1573   SET_NZ8(A);
1574   INDEXED1;
1575   WM(EAD,A);
1576}
1577
1578/* $e8 EORA indexed, 1 byte offset -**- */
1579OP_HANDLER( eora_ix1 )
1580{
1581   UINT8 t;
1582   IDX1BYTE(t);
1583   A ^= t;
1584   CLR_NZ;
1585   SET_NZ8(A);
1586}
1587
1588/* $e9 ADCA indexed, 1 byte offset **** */
1589OP_HANDLER( adca_ix1 )
1590{
1591   UINT16 t,r;
1592   IDX1BYTE(t);
1593   r = A + t + (CC & 0x01);
1594   CLR_HNZC;
1595   SET_FLAGS8(A,t,r);
1596   SET_H(A,t,r);
1597   A = r;
1598}
1599
1600/* $ea ORA indexed, 1 byte offset -**- */
1601OP_HANDLER( ora_ix1 )
1602{
1603   UINT8 t;
1604   IDX1BYTE(t);
1605   A |= t;
1606   CLR_NZ;
1607   SET_NZ8(A);
1608}
1609
1610/* $eb ADDA indexed, 1 byte offset **** */
1611OP_HANDLER( adda_ix1 )
1612{
1613   UINT16 t,r;
1614   IDX1BYTE(t);
1615   r = A + t;
1616   CLR_HNZC;
1617   SET_FLAGS8(A,t,r);
1618   SET_H(A,t,r);
1619   A = r;
1620}
1621
1622/* $ec JMP indexed, 1 byte offset -*** */
1623OP_HANDLER( jmp_ix1 )
1624{
1625   INDEXED1;
1626   PC = EA;
1627}
1628
1629/* $ed JSR indexed, 1 byte offset ---- */
1630OP_HANDLER( jsr_ix1 )
1631{
1632   INDEXED1;
1633   PUSHWORD(m_pc);
1634   PC = EA;
1635}
1636
1637/* $ee LDX indexed, 1 byte offset -**- */
1638OP_HANDLER( ldx_ix1 )
1639{
1640   IDX1BYTE(X);
1641   CLR_NZ;
1642   SET_NZ8(X);
1643}
1644
1645/* $ef STX indexed, 1 byte offset -**- */
1646OP_HANDLER( stx_ix1 )
1647{
1648   CLR_NZ;
1649   SET_NZ8(X);
1650   INDEXED1;
1651   WM(EAD,X);
1652}
1653
1654/* $f0 SUBA indexed ?*** */
1655OP_HANDLER( suba_ix )
1656{
1657   UINT16    t,r;
1658   IDXBYTE(t);
1659   r = A - t;
1660   CLR_NZC;
1661   SET_FLAGS8(A,t,r);
1662   A = r;
1663}
1664
1665/* $f1 CMPA indexed ?*** */
1666OP_HANDLER( cmpa_ix )
1667{
1668   UINT16    t,r;
1669   IDXBYTE(t);
1670   r = A - t;
1671   CLR_NZC;
1672   SET_FLAGS8(A,t,r);
1673}
1674
1675/* $f2 SBCA indexed ?*** */
1676OP_HANDLER( sbca_ix )
1677{
1678   UINT16    t,r;
1679   IDXBYTE(t);
1680   r = A - t - (CC & 0x01);
1681   CLR_NZC;
1682   SET_FLAGS8(A,t,r);
1683   A = r;
1684}
1685
1686/* $f3 CPX indexed -*** */
1687OP_HANDLER( cpx_ix )
1688{
1689   UINT16    t,r;
1690   IDXBYTE(t);
1691   r = X - t;
1692   CLR_NZC;
1693   SET_FLAGS8(X,t,r);
1694}
1695
1696/* $f4 ANDA indexed -**- */
1697OP_HANDLER( anda_ix )
1698{
1699   UINT8 t;
1700   IDXBYTE(t);
1701   A &= t;
1702   CLR_NZ;
1703   SET_NZ8(A);
1704}
1705
1706/* $f5 BITA indexed -**- */
1707OP_HANDLER( bita_ix )
1708{
1709   UINT8 t,r;
1710   IDXBYTE(t);
1711   r = A & t;
1712   CLR_NZ;
1713   SET_NZ8(r);
1714}
1715
1716/* $f6 LDA indexed -**- */
1717OP_HANDLER( lda_ix )
1718{
1719   IDXBYTE(A);
1720   CLR_NZ;
1721   SET_NZ8(A);
1722}
1723
1724/* $f7 STA indexed -**- */
1725OP_HANDLER( sta_ix )
1726{
1727   CLR_NZ;
1728   SET_NZ8(A);
1729   INDEXED;
1730   WM(EAD,A);
1731}
1732
1733/* $f8 EORA indexed -**- */
1734OP_HANDLER( eora_ix )
1735{
1736   UINT8 t;
1737   IDXBYTE(t);
1738   A ^= t;
1739   CLR_NZ;
1740   SET_NZ8(A);
1741}
1742
1743/* $f9 ADCA indexed **** */
1744OP_HANDLER( adca_ix )
1745{
1746   UINT16 t,r;
1747   IDXBYTE(t);
1748   r = A + t + (CC & 0x01);
1749   CLR_HNZC;
1750   SET_FLAGS8(A,t,r);
1751   SET_H(A,t,r);
1752   A = r;
1753}
1754
1755/* $fa ORA indexed -**- */
1756OP_HANDLER( ora_ix )
1757{
1758   UINT8 t;
1759   IDXBYTE(t);
1760   A |= t;
1761   CLR_NZ;
1762   SET_NZ8(A);
1763}
1764
1765/* $fb ADDA indexed **** */
1766OP_HANDLER( adda_ix )
1767{
1768   UINT16 t,r;
1769   IDXBYTE(t);
1770   r = A + t;
1771   CLR_HNZC;
1772   SET_FLAGS8(A,t,r);
1773   SET_H(A,t,r);
1774   A = r;
1775}
1776
1777/* $fc JMP indexed -*** */
1778OP_HANDLER( jmp_ix )
1779{
1780   INDEXED;
1781   PC = EA;
1782}
1783
1784/* $fd JSR indexed ---- */
1785OP_HANDLER( jsr_ix )
1786{
1787   INDEXED;
1788   PUSHWORD(m_pc);
1789   PC = EA;
1790}
1791
1792/* $fe LDX indexed -**- */
1793OP_HANDLER( ldx_ix )
1794{
1795   IDXBYTE(X);
1796   CLR_NZ;
1797   SET_NZ8(X);
1798}
1799
1800/* $ff STX indexed -**- */
1801OP_HANDLER( stx_ix )
1802{
1803   CLR_NZ;
1804   SET_NZ8(X);
1805   INDEXED;
1806   WM(EAD,X);
1807}
Property changes on: trunk/src/emu/cpu/m6805/6805ops.inc
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/m6805/m6805.c
r28738r28739
557557   }
558558}
559559
560#include "6805ops.c"
560#include "6805ops.inc"
561561
562562//-------------------------------------------------
563563//  execute_clocks_to_cycles - convert the raw

Previous 199869 Revisions Next


© 1997-2024 The MAME Team