ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
8086.c
Go to the documentation of this file.
1/*****************************************************************************
2 * ugBASIC - an isomorphic BASIC language compiler for retrocomputers *
3 *****************************************************************************
4 * Copyright 2021-2026 Marco Spedaletti (asimov@mclink.it)
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *----------------------------------------------------------------------------
18 * Concesso in licenza secondo i termini della Licenza Apache, versione 2.0
19 * (la "Licenza"); è proibito usare questo file se non in conformità alla
20 * Licenza. Una copia della Licenza è disponibile all'indirizzo:
21 *
22 * http://www.apache.org/licenses/LICENSE-2.0
23 *
24 * Se non richiesto dalla legislazione vigente o concordato per iscritto,
25 * il software distribuito nei termini della Licenza è distribuito
26 * "COSì COM'è", SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o
27 * implicite. Consultare la Licenza per il testo specifico che regola le
28 * autorizzazioni e le limitazioni previste dalla medesima.
29 ****************************************************************************/
30
31/****************************************************************************
32 * INCLUDE SECTION
33 ****************************************************************************/
34
35#include "cpu.h"
36
37#include <math.h>
38
39/****************************************************************************
40 * CODE SECTION
41 ****************************************************************************/
42
43#if defined(__pccga__)
44
45void cpu_init( Environment * _environment ) {
46
47 _environment->stackSize = 0xffff;
48 _environment->stackStartAddress = 0x0000;
49
50}
51
52void cpu_nop( Environment * _environment ) {
53
54 outline0("NOP");
55
56}
57
58void cpu_ztoa( Environment * _environment ) {
59
60 inline( cpu_ztoa )
61
63
64 outline1("JE %syes", label );
65 outline0("MOV AL, 0");
66 outline1("JMP %s", label );
67 outhead1("%syes:", label );
68 outline0("MOV AL, 0xff");
69 outhead1("%s:", label );
70
72
73}
74
75void cpu_ctoa( Environment * _environment ) {
76
77 inline( cpu_ctoa )
78
80
81 outline1("JC %syes", label );
82 outline0("MOV AL, 0");
83 outline1("JMP %s", label );
84 outhead1("%syes:", label );
85 outline0("MOV AL, 0xff");
86 outhead1("%s:", label );
87
89
90}
91
106void cpu_beq( Environment * _environment, char * _label ) {
107
108 inline( cpu_beq )
109
110 outline1("JZ %s", _label);
111
113
114}
115
122void cpu_bneq( Environment * _environment, char * _label ) {
123
124 inline( cpu_bneq )
125
126 outline1("JNZ %s", _label);
127
129
130}
131
132void cpu_bveq( Environment * _environment, char * _value, char * _label ) {
133
134 inline( cpu_bveq )
135
136 outline1("MOV AL, [%s]", _value);
137 outline0("CMP AL, 0");
138 cpu_beq( _environment, _label );
139
141
142}
143
144void cpu_bvneq( Environment * _environment, char * _value, char * _label ) {
145
146 inline( cpu_bvneq )
147
148 outline1("MOV AL, [%s]", _value);
149 outline0("CMP AL, 0");
150 cpu_bneq( _environment, _label );
151
153
154}
155
156void cpu_label( Environment * _environment, char * _label ) {
157 outhead1("%s:", _label);
158}
159
160void cpu_peek( Environment * _environment, char * _address, char * _target ) {
161
162 inline( cpu_peek )
163
164 outline1("MOV SI, [%s]", _address);
165 outline0("MOV AL, [SI]");
166 outline1("MOV [%s], AL", _target);
167
169
170}
171
172void cpu_poke( Environment * _environment, char * _address, char * _source ) {
173
174 inline( cpu_poke )
175
176 outline1("MOV AL, [%s]", _source);
177 outline1("MOV DI, [%s]", _address);
178 outline0("MOV [DI], AL");
179
181
182}
183
184void cpu_poke_const( Environment * _environment, char * _address, int _source ) {
185
186 // inline( cpu_poke )
187
188 outline1("MOV AL, 0x%2.2x", (unsigned char)(_source&0xff));
189 outline1("MOV DI, [%s]", _address);
190 outline0("MOV [DI], AL");
191
192 // no_embedded( cpu_poke )
193
194}
195
196void cpu_peekw( Environment * _environment, char * _address, char * _target ) {
197
198 inline( cpu_peek )
199
200 outline1("MOV SI, [%s]", _address);
201 outline0("MOV AX, [SI]");
202 outline1("MOV [%s], AX", _target);
203
205
206}
207
208void cpu_pokew( Environment * _environment, char * _address, char * _source ) {
209
210 inline( cpu_poke )
211
212 outline1("MOV AX, [%s]", _source);
213 outline1("MOV DI, [%s]", _address);
214 outline0("MOV [DI], AX");
215
217
218}
219
220void cpu_pokew_const( Environment * _environment, char * _address, int _source ) {
221
222 // inline( cpu_poke )
223
224 outline1("MOV AX, 0x%4.4x", (unsigned short)(_source&0xffFF));
225 outline1("MOV DI, [%s]", _address);
226 outline0("MOV [DI], AX");
227
228 // no_embedded( cpu_poke )
229
230}
231
232void cpu_peekd( Environment * _environment, char * _address, char * _target ) {
233
234 inline( cpu_peek )
235
236 outline1("MOV SI, [%s]", _address);
237 outline0("MOV AX, [SI]");
238 outline1("MOV [%s], AX", _target);
239 outline0("INC SI" );
240 outline0("INC SI" );
241 outline0("MOV AX, [SI]");
242 outline1("MOV [%s], AX", address_displacement( _environment, _target, "+2" ));
243
245
246}
247
248void cpu_poked( Environment * _environment, char * _address, char * _source ) {
249
250 inline( cpu_poke )
251
252 outline1("MOV AX, [%s]", _source);
253 outline1("MOV DI, [%s]", _address);
254 outline0("MOV [DI], AX");
255 outline0("INC DI");
256 outline0("INC DI");
257 outline1("MOV AX, [%s]", address_displacement( _environment, _source, "+2") );
258 outline0("MOV [DI], AX");
259
261
262}
263
264void cpu_poked_const( Environment * _environment, char * _address, int _source ) {
265
266 // inline( cpu_poke )
267
268 outline1("MOV AX, 0x%4.4x", (unsigned short)(_source&0xffff));
269 outline1("MOV DI, [%s]", _address);
270 outline0("MOV [DI], AX");
271 outline0("INC DI");
272 outline0("INC DI");
273 outline1("MOV AX, 0x%4.4x", (unsigned short)((_source>>16)&0xffff));
274 outline0("MOV [DI], AX");
275
276 // no_embedded( cpu_poke )
277
278}
279
293void cpu_fill_blocks( Environment * _environment, char * _address, char * _blocks, char * _pattern ) {
294
296
297 embedded( cpu_fill_blocks, src_hw_8086_cpu_fill_blocks_asm );
298
299 outline1("MOV CL, [%s]", _blocks);
300 outline1("MOV AL, [%s]", _pattern);
301 outline1("MOV DI, [%s]", _address);
302 outline0("CALL CPUFILLBLOCKS");
303
304 done( )
305
306}
307
321void cpu_fill( Environment * _environment, char * _address, char * _bytes, int _bytes_width, char * _pattern ) {
322
324
326
327 embedded( cpu_fill, src_hw_8086_cpu_fill_asm );
328
329 if ( _bytes_width == 8 ) {
330 outline1("MOV CL, [%s]", _bytes);
331 } else {
332 outline1("MOV CX, [%s]", _bytes);
333 }
334
335 if ( _pattern ) {
336 outline1("MOV AL, [%s]", _pattern);
337 } else {
338 outline0("MOV AL, 0");
339 }
340 outline1("MOV BX, [%s]", _address);
341
342 if ( _bytes_width == 8 ) {
343 outline0("CALL CPUFILL8");
344 } else {
345 outline0("CALL CPUFILL16");
346 }
347
348 done( )
349}
350
364void cpu_fill_size( Environment * _environment, char * _address, int _bytes, char * _pattern ) {
365
367
369
370 embedded( cpu_fill, src_hw_8086_cpu_fill_asm );
371
372 outline1("MOV CL, 0x%2.2x", (unsigned char) ( _bytes & 0xff ) );
373
374 if ( _bytes < 256 ) {
375
376 } else {
377 outline1("MOV CH, 0x%2.2x", (unsigned char) ( ( _bytes >> 8 ) & 0xff ) );
378 }
379
380 if ( _pattern ) {
381 outline1("MOV AL, [%s]", _pattern);
382 } else {
383 outline0("MOV AL, 0");
384 }
385
386 outline1("MOV BX, [%s]", _address);
387 if ( _bytes < 256 ) {
388 outline0("CALL CPUFILL8");
389 } else {
390 outline0("CALL CPUFILL16");
391 }
392
393 done( )
394
395}
396
410void cpu_fill_size_value( Environment * _environment, char * _address, int _bytes, int _pattern ) {
411
413
415
416 embedded( cpu_fill, src_hw_8086_cpu_fill_asm );
417
418 outline1("MOV CL, 0x%2.2x", (unsigned char) ( _bytes & 0xff ) );
419
420 if ( _bytes < 256 ) {
421
422 } else {
423 outline1("MOV CH, 0x%2.2x", (unsigned char) ( ( _bytes >> 8 ) & 0xff ) );
424 }
425
426 outline1("MOV AL, 0x%2.2x", _pattern);
427 outline1("MOV BX, [%s]", _address);
428 if ( _bytes < 256 ) {
429 outline0("CALL CPUFILL8");
430 } else {
431 outline0("CALL CPUFILL16");
432 }
433
434 done( )
435
436}
437
451void cpu_fill_direct( Environment * _environment, char * _address, char * _bytes, char * _pattern ) {
452
454
456
457 embedded( cpu_fill, src_hw_8086_cpu_fill_asm );
458
459 outline1("MOV CX, [%s]", _bytes);
460 if ( _pattern ) {
461 outline1("MOV AL, [%s]", _pattern);
462 } else {
463 outline0("MOV AL, 0");
464 }
465 outline1("MOV BX, %s", _address);
466 outline0("CALL CPUFILL16");
467
468 done( )
469
470}
471
485void cpu_fill_direct_size( Environment * _environment, char * _address, int _bytes, char * _pattern ) {
486
488
490
491 embedded( cpu_fill, src_hw_8086_cpu_fill_asm );
492
493 outline1("MOV CL, 0x%2.2x", (unsigned char) ( _bytes & 0xff ) );
494
495 if ( _bytes < 256 ) {
496
497 } else {
498 outline1("MOV CH, 0x%2.2x", (unsigned char) ( ( _bytes >> 8 ) & 0xff ) );
499 }
500
501 if ( _pattern ) {
502 outline1("MOV AL, [%s]", _pattern);
503 } else {
504 outline0("MOV AL, 0");
505 }
506
507 outline1("MOV BX, %s", _address);
508 if ( _bytes < 256 ) {
509 outline0("CALL CPUFILL8");
510 } else {
511 outline0("CALL CPUFILL16");
512 }
513
514 done( )
515
516}
517
531void cpu_fill_direct_size_value( Environment * _environment, char * _address, int _bytes, int _pattern ) {
532
534
536
537 embedded( cpu_fill, src_hw_8086_cpu_fill_asm );
538
539 outline1("MOV CL, 0x%2.2x", (unsigned char) ( _bytes & 0xff ) );
540
541 if ( _bytes < 256 ) {
542
543 } else {
544 outline1("MOV CH, 0x%2.2x", (unsigned char) ( ( _bytes >> 8 ) & 0xff ) );
545 }
546
547 outline1("MOV AL, 0x%2.2x", _pattern);
548 outline1("MOV BX, %s", _address);
549 if ( _bytes < 256 ) {
550 outline0("CALL CPUFILL8");
551 } else {
552 outline0("CALL CPUFILL16");
553 }
554
555 done( )
556
557}
558
559/*****************************************************************************
560 * 8 BIT MANIPULATION
561 ****************************************************************************/
562
570void cpu_move_8bit( Environment * _environment, char *_source, char *_destination ) {
571
572 inline( cpu_move_8bit )
573
574 outline1("MOV AL, [%s]", _source);
575 outline1("MOV [%s], AL", _destination);
576
578
579}
580
588void cpu_store_8bit( Environment * _environment, char *_destination, int _value ) {
589
590 inline( cpu_store_8bit )
591
592 outline2("MOV BYTE [%s], 0x%2.2x", _destination, ( _value & 0xff ) );
593
595
596}
597
605void cpu_store_char( Environment * _environment, char *_destination, int _value ) {
606
607 inline( cpu_store_char )
608
609 outline2("MOV BYTE [%s], '%c'", _destination, ( _value & 0xff ) );
610
612
613}
614
615void cpu_store_8bit_with_offset( Environment * _environment, char *_destination, int _value, int _offset ) {
616
618
619 outline3("MOV BYTE [%s+%d], 0x%2.2x", _destination, ( _offset & 0xff ), ( _value & 0xff ));
620
622
623}
624
625void cpu_store_8bit_with_offset2( Environment * _environment, char *_destination, char * _offset, int _value ) {
626
628
629 outline1("MOV DI, %s", _destination );
630 outline1("MOV AL, [%s]", _offset );
631 outline0("MOV AH, 0" );
632 outline0("ADD DI, AX" );
633 outline1("MOV BYTE [DI], 0x%2.2x", ( _value & 0xff ));
634
636
637}
638
648void cpu_compare_8bit( Environment * _environment, char *_source, char *_destination, char *_other, int _positive ) {
649
651
652 inline( cpu_compare_8bit )
653
654 outline1("MOV AL, [%s]", _destination);
655 outline1("MOV DI, %s", _source);
656 outline0("CMP AL, [DI]");
657 outline1("JNZ %s", label);
658 outline1("MOV AL, 0x%2.2x", (unsigned char)(0xff*_positive));
659 if ( _other ) {
660 outline1("MOV [%s], AL", _other);
661 } else {
662 outline1("MOV [%s], AL", _destination);
663 }
664 outline1("JMP %sb2", label);
665 outhead1("%s:", label);
666 outline1("MOV AL, 0x%2.2x", (unsigned char)(0xff*(1-_positive)));
667 if ( _other ) {
668 outline1("MOV [%s], AL", _other);
669 } else {
670 outline1("MOV [%s], AL", _destination);
671 }
672 outhead1("%sb2:", label);
673
675
676}
677
687void cpu_compare_8bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _positive ) {
688
690
691 inline( cpu_compare_8bit )
692
693 outline1("MOV DI, %s", _source);
694 outline1("CMP BYTE [DI], 0x%2.2x", (unsigned char)(_destination&0xff));
695 outline1("JNZ %s", label);
696 outline1("MOV AL, 0x%2.2x", (unsigned char)(0xff*_positive));
697 outline1("MOV [%s], AL", _other);
698 outline1("JMP %sb2", label);
699 outhead1("%s:", label);
700 outline1("MOV AL, 0x%2.2x", (unsigned char)(0xff*(1-_positive)));
701 outline1("MOV [%s], AL", _other);
702 outhead1("%sb2:", label);
703
705
706}
707
708void cpu_compare_and_branch_8bit( Environment * _environment, char *_source, char * _destination, char *_label, int _positive ) {
709
711
713
714 outline1("MOV AL, [%s]", _destination);
715 outline1("MOV BL, [%s]", _source);
716 outline0("CMP AL, BL" );
717 if ( _positive ) {
718 outline1("JZ %s", _label);
719 } else {
720 outline1("JNZ %s", _label);
721 }
722
724
725}
726
736void cpu_compare_and_branch_8bit_const( Environment * _environment, char *_source, int _destination, char *_label, int _positive ) {
737
739
741
742 outline1("MOV AL, 0x%2.2x", _destination);
743 outline1("MOV BL, [%s]", _source);
744 outline1("CMP AL, BL", _destination );
745 if ( _positive ) {
746 outline1("JZ %s", _label);
747 } else {
748 outline1("JNZ %s", _label);
749 }
750
752
753}
754
764void cpu_prepare_for_compare_and_branch_8bit( Environment * _environment, char *_source ) {
765
767
768 outline1("MOV AL, [%s]", _source);
769
771
772}
773
783void cpu_execute_compare_and_branch_8bit_const( Environment * _environment, int _destination, char *_label, int _positive ) {
784
786
788
789 outline1("CMP AL, 0x%2.2x", _destination );
790 if ( _positive ) {
791 outline1("JZ %s", _label);
792 } else {
793 outline1("JNZ %s", _label);
794 }
795
797
798}
799
809void cpu_compare_and_branch_char_const( Environment * _environment, char *_source, int _destination, char *_label, int _positive ) {
810
812
814
815 outline1("MOV AL, [%s]", _source);
816 outline1("CMP AL, '%c'", _destination );
817 if ( _positive ) {
818 outline1("JZ %s", _label);
819 } else {
820 outline1("JNZ %s", _label);
821 }
822
824
825}
826
836void cpu_less_than_8bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
837
839
841
842 embedded( cpu_less_than_8bit, src_hw_8086_cpu_less_than_8bit_asm );
843
844 outline1("MOV AL, [%s]", _source);
845 outline1("MOV BL, [%s]", _destination);
846 if ( _signed ) {
847 if ( _equal ) {
848 outline0("CALL CPULTE8S");
849 } else {
850 outline0("CALL CPULT8S");
851 }
852 } else {
853 if ( _equal ) {
854 outline0("CALL CPULTE8U");
855 } else {
856 outline0("CALL CPULT8U");
857 }
858 }
859 if ( _other ) {
860 outline1("MOV [%s], AL", _other);
861 } else {
862 outline1("MOV [%s], AL", _destination);
863 }
864
865 done( )
866
867}
868
869void cpu_less_than_8bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
870
872
874
875 embedded( cpu_less_than_8bit, src_hw_8086_cpu_less_than_8bit_asm );
876
877 outline1("MOV AL, [%s]", _source);
878 outline1("MOV BL, 0x%2.2x", (unsigned char)(_destination&0xff));
879 if ( _signed ) {
880 if ( _equal ) {
881 outline0("CALL CPULTE8S");
882 } else {
883 outline0("CALL CPULT8S");
884 }
885 } else {
886 if ( _equal ) {
887 outline0("CALL CPULTE8U");
888 } else {
889 outline0("CALL CPULT8U");
890 }
891 }
892 if ( _other ) {
893 outline1("MOV [%s], AL", _other);
894 } else {
895 outline1("MOV [%s], AL", _destination);
896 }
897
898 done( )
899
900}
901
902void cpu_less_than_and_branch_8bit_const( Environment * _environment, char *_source, int _destination, char *_label, int _equal, int _signed ) {
903
905
907
908 embedded( cpu_less_than_8bit, src_hw_8086_cpu_less_than_8bit_asm );
909
910 outline1("MOV AL, [%s]", _source);
911 outline1("MOV BL, 0x%2.2x", (unsigned char)(_destination&0xff));
912 if ( _signed ) {
913 if ( _equal ) {
914 outline0("CALL CPULTE8S");
915 } else {
916 outline0("CALL CPULT8S");
917 }
918 } else {
919 if ( _equal ) {
920 outline0("CALL CPULTE8U");
921 } else {
922 outline0("CALL CPULT8U");
923 }
924 }
925 outline0("CMP AL, 0");
926 outline1("JZ %sb2:", label);
927 outline1("JMP %s", _label);
928 outhead1("%sb2:", label);
929
930 done( )
931
932}
933
943void cpu_greater_than_8bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
944
945 cpu_less_than_8bit( _environment, _source, _destination, _other, !_equal, _signed );
946 if ( _other ) {
947 cpu_not_8bit( _environment, _other, _other );
948 } else {
949 cpu_not_8bit( _environment, _destination, _destination );
950 }
951
952}
953
954void cpu_greater_than_8bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
955
956 cpu_less_than_8bit_const( _environment, _source, _destination, _other, !_equal, _signed );
957 cpu_not_8bit( _environment, _other, _other );
958
959}
960
969void cpu_math_add_8bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
970
971 inline( cpu_math_add_8bit )
972
973 outline1("MOV AL, [%s]", _source );
974 outline1("MOV BL, [%s]", _destination );
975 outline0("ADD AL, BL" );
976 if ( _other ) {
977 outline1("MOV [%s], AL", _other );
978 } else {
979 outline1("MOV [%s], AL", _destination );
980 }
981
983
984}
985
986void cpu_math_add_8bit_const( Environment * _environment, char *_source, int _destination, char *_other ) {
987
988 inline( cpu_math_add_8bit )
989
990 outline1("MOV AL, [%s]", _source );
991 outline1("MOV BL, 0x%2.2x", (unsigned char)(_destination&0xff) );
992 outline0("ADD AL, BL" );
993 outline1("MOV [%s], AL", _other );
994
996
997}
998
1007void cpu_math_sub_8bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
1008
1009 inline( cpu_math_sub_8bit )
1010
1011 outline1("MOV AL, [%s]", _source );
1012 outline1("MOV BL, [%s]", _destination );
1013 outline0("SUB AL, BL" );
1014 if ( _other ) {
1015 outline1("MOV [%s], AL", _other );
1016 } else {
1017 outline1("MOV [%s], AL", _destination );
1018 }
1019
1021
1022}
1023
1031void cpu_math_double_8bit( Environment * _environment, char *_source, char *_other, int _signed ) {
1032
1033 inline( cpu_math_double_8bit )
1034
1035 outline1("MOV AL, [%s]", _source );
1036 outline0("ADD AL, AL" );
1037 if ( _other ) {
1038 outline1("MOV [%s], AL", _other );
1039 } else {
1040 outline1("MOV [%s], AL", _source );
1041 }
1042
1044
1045}
1046
1055
1056void cpu_math_mul_8bit_to_16bit( Environment * _environment, char *_source, char *_destination, char *_other, int _signed ) {
1057
1059
1061
1062 if ( _signed ) {
1063
1064 outline1("MOV AL, [%s]", _source );
1065 outline0("MOV AH, 0" );
1066 outline1("MOV BL, [%s]", _destination );
1067 outline0("MOV BH, 0" );
1068 outline0("IMUL BX" );
1069 outline1("MOV [%s], AX", _other );
1070
1071 } else {
1072
1073 outline1("MOV AL, [%s]", _source );
1074 outline0("MOV AH, 0" );
1075 outline1("MOV BL, [%s]", _destination );
1076 outline0("MOV BH, 0" );
1077 outline0("MUL BX" );
1078 outline1("MOV [%s], AX", _other );
1079
1080 }
1081
1083
1084}
1085
1093void cpu_math_div2_const_8bit( Environment * _environment, char *_source, int _steps, int _signed, char * _remainder ) {
1094
1096
1097 embedded( cpu_math_div2_const_8bit, src_hw_8086_cpu_math_div2_const_8bit_asm );
1098
1099 if ( _remainder ) {
1100 outline1("MOV AL, [%s]", _source );
1101 outline0("AND 0x1" );
1102 outline1("MOV [%s], AL", _remainder );
1103 }
1104 outline1("MOV AL, [%s]", _source);
1105 outline1("MOV CL, 0x%2.2x", _steps);
1106 if ( _signed ) {
1107 outline0("CALL CPUDIV2CONST8S");
1108 } else {
1109 outline0("CALL CPUDIV2CONST8U");
1110 }
1111 outline1("MOV [%s], AL", _source);
1112
1113 done( )
1114
1115}
1116
1124void cpu_math_mul2_const_8bit( Environment * _environment, char *_source, int _steps, int _signed ) {
1125
1126 inline( cpu_math_mul2_const_8bit )
1127
1128 embedded( cpu_math_mul2_const_8bit, src_hw_8086_cpu_math_mul2_const_8bit_asm );
1129
1130 outline1("MOV AL, [%s]", _source);
1131 outline1("MOV CL, 0x%2.2x", _steps);
1132 if ( _signed ) {
1133 outline0("CALL CPUMUL2CONST8S");
1134 } else {
1135 outline0("CALL CPUMUL2CONST8U");
1136 }
1137 outline1("MOV [%s], AL", _source);
1138
1139 done( )
1140
1141}
1142
1150void cpu_math_complement_const_8bit( Environment * _environment, char *_source, int _value ) {
1151
1153
1154 outline1("MOV BL, [%s]", _source );
1155 outline1("MOV AL, 0x%2.2x", ( _value & 0xff ) );
1156 outline0("SUB AL, BL" );
1157 outline1("MOV [%s], AL", _source );
1158
1160
1161}
1162
1170void cpu_math_and_const_8bit( Environment * _environment, char *_source, int _mask ) {
1171
1172 inline( cpu_math_and_const_8bit )
1173
1174 outline1("MOV AL, [%s]", _source );
1175 outline1("AND AL, 0x%2.2x", _mask );
1176 outline1("MOV [%s], AL", _source );
1177
1179
1180}
1181
1182/*****************************************************************************
1183 * 16 BIT MANIPULATION
1184 ****************************************************************************/
1185
1193void cpu_move_16bit( Environment * _environment, char *_source, char *_destination ) {
1194
1195 inline( cpu_move_16bit )
1196
1197 outline1("MOV AX, [%s]", _source );
1198 outline1("MOV [%s], AX", _destination );
1199
1201
1202}
1203
1204void cpu_addressof_16bit( Environment * _environment, char *_source, char *_destination ) {
1205
1206 inline( cpu_addressof_16bit )
1207
1208 outline1("MOV AX, %s", _source );
1209 outline1("MOV [%s], AX", _destination );
1210
1212
1213}
1214
1222void cpu_store_16bit( Environment * _environment, char *_destination, int _value ) {
1223
1224 inline( cpu_store_16bit )
1225
1226 outline1("MOV AX, 0x%4.4x", _value & 0xffff );
1227 outline1("MOV [%s], AX", _destination );
1228
1230
1231}
1232
1241void cpu_compare_16bit( Environment * _environment, char *_source, char *_destination, char *_other, int _positive ) {
1242
1244
1245 inline( cpu_compare_16bit )
1246
1247 outline1("MOV AX, [%s]", _source);
1248 outline1("MOV BX, [%s]", _destination);
1249 outline0("CMP AX, BX");
1250 outline1("JNZ %s", label);
1251 outline1("MOV AL, 0x%2.2x", 0xff*_positive);
1252 if ( _other ) {
1253 outline1("MOV [%s], AL", _other);
1254 } else {
1255 outline1("MOV [%s], AL", _destination);
1256 }
1257 outline1("JMP %sb2", label);
1258 outhead1("%s:", label);
1259 outline1("MOV AL, 0x%2.2x", 0xff*(1-_positive));
1260 if ( _other ) {
1261 outline1("MOV [%s], AL", _other);
1262 } else {
1263 outline1("MOV [%s], AL", _destination);
1264 }
1265 outhead1("%sb2:", label);
1266
1268
1269}
1270
1279void cpu_compare_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _positive ) {
1280
1282
1283 inline( cpu_compare_16bit )
1284
1285 outline1("MOV AX, [%s]", _source);
1286 outline1("MOV BX, 0x%4.4x", _destination);
1287 outline0("CMP AX, BX");
1288 outline1("JNZ %s", label);
1289 outline1("MOV AL, 0x%2.2x", 0xff*_positive);
1290 if ( _other ) {
1291 outline1("MOV [%s], AL", _other);
1292 } else {
1293 outline1("MOV [%s], AL", _destination);
1294 }
1295 outline1("JMP %sb2", label);
1296 outhead1("%s:", label);
1297 outline1("MOV AL, 0x%2.2x", 0xff*(1-_positive));
1298 if ( _other ) {
1299 outline1("MOV [%s], AL", _other);
1300 } else {
1301 outline1("MOV [%s], AL", _destination);
1302 }
1303 outhead1("%sb2:", label);
1304
1306
1307}
1308
1309void cpu_compare_and_branch_16bit( Environment * _environment, char *_source, char *_destination, char *_label, int _positive ) {
1310
1312
1314
1315 outline1("MOV AX, [%s]", _source);
1316 outline1("MOV BX, [%s]", _destination);
1317 outline0("CMP AX, BX");
1318 if ( _positive ) {
1319 outline1("JZ %s", _label);
1320 } else {
1321 outline1("JNZ %s", _label);
1322 }
1323
1325
1326}
1327
1337void cpu_compare_and_branch_16bit_const( Environment * _environment, char *_source, int _destination, char *_label, int _positive ) {
1338
1340
1342
1343 outline1("MOV AX, [%s]", _source);
1344 outline1("MOV BX, 0x%4.4x", _destination);
1345 outline0("CMP AX, BX");
1346 if ( _positive ) {
1347 outline1("JZ %s", _label);
1348 } else {
1349 outline1("JNZ %s", _label);
1350 }
1351
1353
1354}
1355
1365void cpu_less_than_16bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
1366
1368
1370
1371 embedded( cpu_less_than_16bit, src_hw_8086_cpu_less_than_16bit_asm );
1372
1373 if ( _signed ) {
1374
1375 outline1("MOV AX, [%s]", _source);
1376 outline1("MOV BX, [%s]", _destination);
1377 if ( _equal ) {
1378 outline0("CALL CPULTE16S");
1379 } else {
1380 outline0("CALL CPULT16S");
1381 }
1382 if ( _other ) {
1383 outline1("MOV [%s], AL", _other);
1384 } else {
1385 outline1("MOV [%s], AL", _destination);
1386 }
1387
1388 } else {
1389
1390 outline1("MOV AX, [%s]", _destination);
1391 outline1("MOV BX, [%s]", _source);
1392 if ( _equal ) {
1393 outline0("CALL CPULTE16U");
1394 } else {
1395 outline0("CALL CPULT16U");
1396 }
1397 if ( _other ) {
1398 outline1("MOV [%s], AL", _other);
1399 } else {
1400 outline1("MOV [%s], AL", _destination);
1401 }
1402
1403 }
1404
1405 done( )
1406
1407}
1408
1409void cpu_less_than_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
1410
1412
1414
1415 embedded( cpu_less_than_16bit, src_hw_8086_cpu_less_than_16bit_asm );
1416
1417 if ( _signed ) {
1418
1419 outline1("MOV AX, [%s]", _source);
1420 outline1("MOV BX, 0x%4.4x", _destination);
1421 if ( _equal ) {
1422 outline0("CALL CPULTE16S");
1423 } else {
1424 outline0("CALL CPULT16S");
1425 }
1426 if ( _other ) {
1427 outline1("MOV [%s], AL", _other);
1428 } else {
1429 outline1("MOV [%s], AL", _destination);
1430 }
1431
1432 } else {
1433
1434 outline1("MOV AX, 0x%4.4x", _destination);
1435 outline1("MOV BX, [%s]", _source);
1436 if ( _equal ) {
1437 outline0("CALL CPULTE16U");
1438 } else {
1439 outline0("CALL CPULT16U");
1440 }
1441 if ( _other ) {
1442 outline1("MOV [%s], AL", _other);
1443 } else {
1444 outline1("MOV [%s], AL", _destination);
1445 }
1446
1447 }
1448
1449 done( )
1450
1451}
1452
1462void cpu_greater_than_16bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
1463
1464 cpu_less_than_16bit( _environment, _source, _destination, _other, !_equal, _signed );
1465 if ( _other ) {
1466 cpu_not_8bit( _environment, _other, _other );
1467 } else {
1468 cpu_not_8bit( _environment, _destination, _destination );
1469 }
1470
1471}
1472
1473void cpu_greater_than_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
1474
1475 cpu_less_than_16bit_const( _environment, _source, _destination, _other, !_equal, _signed );
1476 cpu_not_8bit( _environment, _other, _other );
1477
1478}
1479
1488void cpu_math_add_16bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
1489
1490 inline( cpu_math_add_16bit )
1491
1492 outline1("MOV AX, [%s]", _source );
1493 outline1("MOV BX, [%s]", _destination );
1494 outline0("ADD AX, BX" );
1495 if ( _other ) {
1496 outline1("MOV [%s], AX", _other );
1497 } else {
1498 outline1("MOV [%s], AX", _destination );
1499 }
1500
1502
1503}
1504
1505void cpu_math_add_16bit_const( Environment * _environment, char *_source, int _destination, char *_other ) {
1506
1507 inline( cpu_math_add_16bit )
1508
1509 outline1("MOV AX, [%s]", _source );
1510 outline1("MOV BX, 0x%4.4x", ( _destination & 0xffff ) );
1511 outline0("ADD AX, BX" );
1512 outline1("MOV [%s], AX", _other );
1513
1515
1516}
1517
1518void cpu_math_add_16bit_with_16bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
1519
1521
1522 outline1("MOV AX, [%s]", _source );
1523 outline1("MOV BX, %s", _destination );
1524 outline0("ADD AX, BX" );
1525 outline1("MOV [%s], AX", _other );
1526
1528
1529}
1530
1538void cpu_math_double_16bit( Environment * _environment, char *_source, char *_other, int _signed ) {
1539
1540 inline( cpu_math_double_16bit )
1541
1542 outline1("MOV AX, [%s]", _source );
1543 outline0("SAL AX, 1" );
1544 if ( _other ) {
1545 outline1("MOV [%s], AX", _other );
1546 } else {
1547 outline1("MOV [%s], AX", _source );
1548 }
1549
1551
1552}
1553
1562void cpu_math_mul_16bit_to_32bit( Environment * _environment, char *_source, char *_destination, char *_other, int _signed ) {
1563
1565
1567
1568 outline1("MOV AX, [%s]", _source );
1569 outline1("MOV BX, [%s]", _destination );
1570 if ( _signed ) {
1571
1572 outline0("IMUL BX" );
1573
1574 } else {
1575
1576 outline1("MUL BX", _source );
1577
1578 }
1579
1580 outline1("MOV [%s], AX", _other );
1581 outline1("MOV [%s], DX", address_displacement( _environment, _other, "+2" ) );
1582
1584
1585}
1586
1587void cpu_math_mul_nbit_to_nbit( Environment * _environment, char *_source, char *_destination, char *_other, int _bits ) {
1588
1590
1591 int i;
1592
1593 char afterLabel[MAX_TEMPORARY_STORAGE]; sprintf( afterLabel, "%safter", label);
1594 char destination[MAX_TEMPORARY_STORAGE]; sprintf( destination, "CPUMATHMULNBITTONBIT%d_DESTINATION", (_bits>>3));
1595 char source[MAX_TEMPORARY_STORAGE]; sprintf( source, "CPUMATHMULNBITTONBIT%d_SOURCE", (_bits>>3));
1596 char other[MAX_TEMPORARY_STORAGE]; sprintf( other, "CPUMATHMULNBITTONBIT%d_OTHER", (_bits>>3));
1597
1598 // no_inline( cpu_math_mul_nbit_to_nbit )
1599
1600 // embedded( cpu_math_mul_nbit_to_nbit, src_hw_6502_cpu_math_mul_nbit_to_nbit_asm )
1601
1602 if ( ! _environment->cpuOptimization.cpu_math_mul_nbit_to_nbit[_bits>>3] ) {
1603
1604 outline1("JMP %s", afterLabel );
1605
1606 outhead2("CPUMATHMULNBITTONBIT%d_SOURCE: times %d db 0", _bits>>3, _bits>>3 );
1607 outhead2("CPUMATHMULNBITTONBIT%d_DESTINATION: times %d db 0", _bits>>3, _bits>>3 );
1608 outhead2("CPUMATHMULNBITTONBIT%d_OTHER: times %d db 0", _bits>>3, _bits>>3 );
1609
1610 outhead1("CPUMATHMULNBITTONBIT%d:", _bits>>3);
1611 outhead0("MOV AL, $00");
1612 for( i=0; i<(_bits>>3); ++i ) {
1613 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
1614 outline1("MOV [%s], AL", address_displacement( _environment, other, offset ) );
1615 }
1616 outline1("MOV CL, 0x%2.2x", _bits );
1617
1618 outhead1("CPUMATHMULNBITTONBIT%dL1:", _bits>>3);
1619
1620 // The process of multiplying binary numbers is similar and easier to do than
1621 // decimal multiplication as binary numbers consist of only two digits which
1622 // are 0 and 1. The method of multiplying binary numbers is given below. The
1623 // same set of rules also apply to binary numbers with a decimal point. Let
1624 // us take the example of multiplying (11101) and (1001).
1625 //
1626 // The decimal equivalent of (11101) is 29 and the decimal equivalent
1627 // of (1001) is 9. Now let us multiply these numbers.
1628
1629 // Step 1: Write down the multiplicand (11101) and the multiplier (1001)
1630 // one below the other in proper positions.
1631
1632 char multiplyByBit0Label[MAX_TEMPORARY_STORAGE]; sprintf( multiplyByBit0Label, "%sb%dbit0", label, _bits>>3 );
1633
1634 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", (_bits>>3)-1 );
1635
1636 outline1("MOV AL, [%s]", address_displacement( _environment, destination, offset ) );
1637 outline0("SAR AL, 1" );
1638 outline1("MOV [%s], AL", address_displacement( _environment, destination, offset ) );
1639 for( i=(_bits>>3)-2; i>-1; --i ) {
1640 sprintf( offset, "%d", i );
1641 outline1("MOV AL, [%s]", address_displacement( _environment, destination, offset ) );
1642 outline0("ROR AL, 1" );
1643 outline1("MOV [%s], AL", address_displacement( _environment, destination, offset ) );
1644 }
1645 outline1("JC %sx", multiplyByBit0Label );
1646 outline1("JMP %s", multiplyByBit0Label );
1647 outhead1("%sx:", multiplyByBit0Label );
1648
1649 // Step 2: Multiply the rightmost digit or the least significant bit (LSB)
1650 // of the multiplier (1) with all the digits of the multiplicand (11101).
1651
1652 outline0("CLC" );
1653 for( i=0; i<(_bits>>3); ++i ) {
1654 sprintf( offset, "%d", i );
1655 outline1("MOV AL, [%s]", address_displacement( _environment, source, offset ) );
1656 outline1("ADC AL, [%s]", address_displacement( _environment, other, offset ) );
1657 outline1("MOV [%s], AL", address_displacement( _environment, other, offset ) );
1658 }
1659
1660 // Step 3: Add a place holder of '0' or 'X' before multiplying the next
1661 // higher order digit of the multiplier& with the multiplicand.
1662
1663 outhead1("%s:", multiplyByBit0Label);
1664
1665 outline0("CLC" );
1666 outline1("MOV AL, [%s]", address_displacement( _environment, source, "0" ) );
1667 outline0("SAL AL, 1" );
1668 outline1("MOV [%s], AL", address_displacement( _environment, source, "0" ) );
1669 for( i=1; i<(_bits>>3); ++i ) {
1670 sprintf( offset, "%d", i );
1671 outline1("MOV AL, [%s]", address_displacement( _environment, source, offset ) );
1672 outline0("ROL AL, 1" );
1673 outline1("MOV [%s], AL", address_displacement( _environment, source, offset ) );
1674 }
1675
1676 // Step 4: Repeat the same process for all the next higher-order digits
1677 // until we reach the most significant bit (MSB) which is the left-most
1678 // digit of the multiplicand with the multiplier.
1679
1680 outline0("DEC CL" );
1681 outline0("CMP CL, 0" );
1682 outline1("JNZ CPUMATHMULNBITTONBIT%dL1", (_bits>>3) );
1683
1684 outline0("RET" );
1685
1686 // Step 5: The product obtained in each row is called the partial product.
1687 // Finally, add all the partial products. To add all the binary numbers
1688 // use the rules of binary addition.
1689
1690 // (The rules for binary addition are listed as follows: 0 + 0 = 0, 0 + 1 = 1, and 1 + 1 = 0, with a carryover of 1. So, 1 + 1 = 10 and 1 + 1 + 1 = 11 in the binary number system)
1691 outhead1("%s:", afterLabel );
1692
1693 }
1694
1695 for( i=0; i<(_bits>>3); ++i ) {
1696 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
1697 outline1("MOV AL, [%s]", address_displacement( _environment, _source, offset ) );
1698 outline1("MOV [%s], AL", address_displacement( _environment, source, offset ) );
1699 outline1("MOV AL, [%s]", address_displacement( _environment, _destination, offset ) );
1700 outline1("MOV [%s], AL", address_displacement( _environment, destination, offset ) );
1701 }
1702 outline1("CALL CPUMATHMULNBITTONBIT%d", _bits >> 3 );
1703 for( i=0; i<(_bits>>3); ++i ) {
1704 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
1705 outline1("MOV AL, [%s]", address_displacement( _environment, other, offset ) );
1706 if ( _other ) {
1707 outline1("MOV [%s], AL", address_displacement( _environment, _other, offset ) );
1708 } else {
1709 outline1("MOV [%s], AL", address_displacement( _environment, _destination, offset ) );
1710 }
1711 }
1712
1713 // done()
1714
1715}
1716
1717
1718void cpu_math_mul2_const_nbit( Environment * _environment, char *_source, int _steps, int _bits ) {
1719
1720 int i;
1721
1722 inline( cpu_math_mul2_const_nbit )
1723
1724 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", (_bits>>3)-1 );
1725 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset));
1726 outline0("AND AL, 0x80");
1727 outline0("MOV BL, AL");
1728 while( _steps ) {
1729 outline0("CLC")
1730 outline1("MOV AL, [%s]", address_displacement(_environment, _source, "0"));
1731 outline0("SAL AL, 1");
1732 outline1("MOV [%s], AL", address_displacement(_environment, _source, "0"));
1733 for( i=1; i<(_bits>>3); ++i ) {
1734 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i);
1735 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset));
1736 outline0("ROL AL, 1");
1737 outline1("MOV [%s], AL", address_displacement(_environment, _source, offset));
1738 }
1739 --_steps;
1740 }
1741 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset));
1742 outline0("OR AL, BL");
1743 outline1("MOV [%s], AL", address_displacement(_environment, _source, offset));
1744
1746
1747}
1748
1749void cpu_math_div2_const_nbit( Environment * _environment, char *_source, int _steps, int _bits, char * _remainder ) {
1750
1751 inline( cpu_math_div2_const_nbit )
1752
1754
1755 if ( _remainder ) {
1756 outline1("MOV AL, [%s]", _source);
1757 outline0("AND AL, 0x01" );
1758 outline1("MOV [%s], AL", _remainder);
1759 }
1760 char offsetMsb[MAX_TEMPORARY_STORAGE]; sprintf( offsetMsb, "%d", (_bits>>3)-1 );
1761
1762 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offsetMsb));
1763 outline0("AND AL, 0x80");
1764 outline0("MOV BL, AL");
1765 outline0("CMP AL, 0x80");
1766 outline1("JNZ %snocomplement", label );
1767 cpu_complement2_nbit( _environment, _source, _source, _bits );
1768 outhead1("%snocomplement:", label );
1769 while( _steps ) {
1770 outline0("CLC");
1771 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offsetMsb));
1772 outline0("SAR AL, 1");
1773 outline1("MOV [%s], AL", address_displacement(_environment, _source, offsetMsb));
1774 for( int i=(_bits>>3)-2; i>-1; --i ) {
1775 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
1776 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset));
1777 outline0("ROR AL, 1");
1778 outline1("MOV [%s], AL", address_displacement(_environment, _source, offset));
1779 }
1780 --_steps;
1781 }
1782 outline0("MOV AL, BL");
1783 outline0("CMP AL, 0x80");
1784 outline1("JNZ %snocomplement2", label );
1785 cpu_complement2_nbit( _environment, _source, _source, _bits );
1786 outhead1("%snocomplement2:", label );
1787
1789
1790}
1791
1800void cpu_math_sub_16bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
1801
1802 inline( cpu_math_sub_16bit )
1803
1804 outline1("MOV AX, [%s]", _source );
1805 outline1("MOV BX, [%s]", _destination );
1806 outline0("SBB AX, BX" );
1807 if ( _other ) {
1808 outline1("MOV [%s], AX", _other );
1809 } else {
1810 outline1("MOV [%s], AX", _destination );
1811 }
1812
1814
1815}
1816
1824void cpu_math_complement_const_16bit( Environment * _environment, char *_source, int _value ) {
1825
1827
1828 outline1("MOV AX, 0x%4.4x", _value );
1829 outline1("MOV BX, [%s]", _source );
1830 outline0("SUB AX, BX" );
1831 outline1("MOV [%s], AX", _source );
1832
1834
1835}
1836
1844void cpu_math_div2_const_16bit( Environment * _environment, char *_source, int _steps, int _signed, char * _remainder ) {
1845
1847
1848 embedded( cpu_math_div2_const_16bit, src_hw_8086_cpu_math_div2_const_16bit_asm )
1849
1850 if ( _remainder ) {
1851 outline1("MOV AX, [%s]", _source );
1852 outline0("AND AL, 0x1" );
1853 outline1("MOV [%s], AL", _remainder );
1854 }
1855 if ( _signed ) {
1856 if ( _steps ) {
1857 outline1("MOV AX, [%s]", _source );
1858 outline1("MOV CL, 0x%2.2x", _steps );
1859 outline0("CALL CPUDIV2CONST16S" );
1860 outline1("MOV [%s], AX", _source );
1861 }
1862 } else {
1863 if ( _steps ) {
1864 outline1("MOV AX, [%s]", _source );
1865 outline1("MOV CL, 0x%2.2x", _steps );
1866 outline0("CALL CPUDIV2CONST16U" );
1867 outline1("MOV [%s], AX", _source );
1868 }
1869
1870 }
1871
1872 done( )
1873
1874}
1875
1883void cpu_math_mul2_const_16bit( Environment * _environment, char *_source, int _steps, int _signed ) {
1884
1886
1888
1889 outline1("MOV AX, [%s]", _source );
1890 outline1("MOV CL, 0x%2.2x", _steps );
1891 outline0("SAL AX, CL" );
1892 outline1("MOV [%s], AX", _source );
1893
1895
1896}
1897
1905void cpu_math_and_const_16bit( Environment * _environment, char *_source, int _mask ) {
1906
1907 inline( cpu_math_and_const_16bit )
1908
1909 outline1("MOV AX, [%s]", _source );
1910 outline1("AND AX, 0x%4.4x", (unsigned short)( _mask & 0xffff ) );
1911 outline1("MOV [%s], AX", _source );
1912
1914
1915}
1916
1917/*****************************************************************************
1918 * 32 BIT MANIPULATION
1919 ****************************************************************************/
1920
1928void cpu_move_32bit( Environment * _environment, char *_source, char *_destination ) {
1929
1930 inline( cpu_move_32bit )
1931
1932 outline1("MOV AX, [%s]", _source );
1933 outline1("MOV [%s], AX", _destination );
1934 outline1("MOV AX, [%s]", address_displacement(_environment, _source, "2") );
1935 outline1("MOV [%s], AX", address_displacement(_environment, _destination, "2") );
1936
1938
1939}
1940
1948void cpu_store_32bit( Environment * _environment, char *_destination, int _value ) {
1949
1950 inline( cpu_store_32bit )
1951
1952 outline1("MOV AX, 0x%4.4x", ( _value & 0xffff ) );
1953 outline1("MOV [%s], AX", _destination );
1954 outline1("MOV AX, 0x%4.4x", ( ( _value >> 16 ) & 0xffff ) );
1955 outline1("MOV [%s], AX", address_displacement(_environment, _destination, "2") );
1956
1958
1959}
1960
1970void cpu_compare_32bit( Environment * _environment, char *_source, char *_destination, char *_other, int _positive ) {
1971
1972 inline( cpu_compare_32bit )
1973
1975
1976 outline1("MOV AX, [%s]", _source);
1977 outline1("MOV BX, [%s]", _destination);
1978 outline0("CMP AX, BX");
1979 outline1("JNZ %s", label);
1980 outline1("MOV AX, [%s]", address_displacement(_environment, _source, "2"));
1981 outline1("MOV BX, [%s]", address_displacement(_environment, _destination, "2"));
1982 outline0("CMP AX, BX");
1983 outline1("JNZ %s", label);
1984 outline1("MOV AL, 0x%2.2x", 0xff*_positive);
1985 if ( _other ) {
1986 outline1("MOV [%s], AL", _other);
1987 } else {
1988 outline1("MOV [%s], AL", _destination);
1989 }
1990 outline1("JMP %s_2", label);
1991 outhead1("%s:", label);
1992 outline1("MOV AL, 0x%2.2x", 0xff*(1-_positive));
1993 if ( _other ) {
1994 outline1("MOV [%s], AL", _other);
1995 } else {
1996 outline1("MOV [%s], AL", _destination);
1997 }
1998 outhead1("%s_2:", label);
1999
2001
2002}
2003
2013void cpu_compare_32bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _positive ) {
2014
2015 inline( cpu_compare_32bit )
2016
2018
2019 outline1("MOV AX, [%s]", _source);
2020 outline1("MOV BX, 0x%4.4x", (unsigned short)(_destination&0xffff));
2021 outline0("CMP AX, BX");
2022 outline1("JNZ %s", label);
2023 outline1("MOV AX, [%s]", address_displacement(_environment, _source, "2"));
2024 outline1("MOV BX, 0x%4.4x", (unsigned short)((_destination>>16)&0xffff));
2025 outline0("CMP AX, BX");
2026 outline1("JNZ %s", label);
2027 outline1("MOV AL, 0x%2.2x", 0xff*_positive);
2028 outline1("MOV [%s], AL", _other);
2029 outline1("JMP %s_2", label);
2030 outhead1("%s:", label);
2031 outline1("MOV AL, 0x%2.2x", 0xff*(1-_positive));
2032 outline1("MOV [%s], AL", _other);
2033 outhead1("%s_2:", label);
2034
2036
2037}
2038
2048void cpu_compare_and_branch_32bit_const( Environment * _environment, char *_source, int _destination, char *_label, int _positive ) {
2049
2051
2053
2054 outline1("MOV AX, [%s]", _source);
2055 outline1("MOV BX, 0x%4.4x", (unsigned short)(_destination&0xffff));
2056 outline0("CMP AX, BX");
2057 outline1("JNZ %s", label);
2058 outline1("MOV AX, [%s]", address_displacement(_environment, _source, "2"));
2059 outline1("MOV BX, 0x%4.4x", (unsigned short)((_destination>>16)&0xffff));
2060 outline0("CMP AX, BX");
2061 outline1("JNZ %s", label);
2062 if ( _positive ) {
2063 outline1("JMP %s", _label);
2064 outhead1("%s:", label );
2065 } else {
2066 outline1("JMP %snot", label);
2067 outhead1("%s:", label );
2068 outline1("JMP %s", _label);
2069 outhead1("%snot:", label );
2070 }
2071
2073
2074}
2075
2085void cpu_less_than_32bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
2086
2088
2090
2091 embedded( cpu_less_than_32bit, src_hw_8086_cpu_less_than_32bit_asm );
2092
2093 outline1("MOV BX, [%s]", _source);
2094 outline1("MOV AX, [%s]", address_displacement( _environment, _source, "+2" ) );
2095 outline1("MOV DX, [%s]", _destination);
2096 outline1("MOV CX, [%s]", address_displacement( _environment, _destination, "+2" ) );
2097 if ( _signed ) {
2098
2099 if ( _equal ) {
2100 outline0("CALL CPULTE32S");
2101 } else {
2102 outline0("CALL CPULT32S");
2103 }
2104 } else {
2105 if ( _equal ) {
2106 outline0("CALL CPULTE32U");
2107 } else {
2108 outline0("CALL CPULT32U");
2109 }
2110 }
2111 if ( _other ) {
2112 outline1("MOV [%s], AL", _other);
2113 } else {
2114 outline1("MOV [%s], AL", _destination);
2115 }
2116
2117 done( )
2118
2119
2120}
2121
2122void cpu_less_than_32bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
2123
2125
2127
2128 embedded( cpu_less_than_32bit, src_hw_8086_cpu_less_than_32bit_asm );
2129
2130 outline1("MOV BX, [%s]", _source);
2131 outline1("MOV AX, [%s]", address_displacement( _environment, _source, "+2" ) );
2132 outline1("MOV DX, 0x%4.4x", (unsigned short)(_destination&0xffff));
2133 outline1("MOV CX, 0x%4.4x", (unsigned short)((_destination>>16)&0xffff));
2134 if ( _signed ) {
2135
2136 if ( _equal ) {
2137 outline0("CALL CPULTE32S");
2138 } else {
2139 outline0("CALL CPULT32S");
2140 }
2141 } else {
2142 if ( _equal ) {
2143 outline0("CALL CPULTE32U");
2144 } else {
2145 outline0("CALL CPULT32U");
2146 }
2147 }
2148 if ( _other ) {
2149 outline1("MOV [%s], AL", _other);
2150 } else {
2151 outline1("MOV [%s], AL", _destination);
2152 }
2153
2154 done( )
2155
2156}
2157
2167void cpu_greater_than_32bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
2168
2169 cpu_less_than_32bit( _environment, _source, _destination, _other, !_equal, _signed );
2170 if ( _other ) {
2171 cpu_not_8bit( _environment, _other, _other );
2172 } else {
2173 cpu_not_8bit( _environment, _destination, _destination );
2174 }
2175
2176}
2177
2178void cpu_greater_than_32bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
2179
2180 cpu_less_than_32bit_const( _environment, _source, _destination, _other, !_equal, _signed );
2181 cpu_not_8bit( _environment, _other, _other );
2182
2183}
2184
2185void cpu_greater_than_nbit( Environment * _environment, char *_source, char * _destination, char *_other, int _equal, int _bits ) {
2186
2187 inline( cpu_greater_than_nbit )
2188
2189 cpu_less_than_nbit( _environment, _source, _destination, _other, !_equal, _bits );
2190 cpu_not_8bit( _environment, _other, _other );
2191
2193
2194}
2195
2196void cpu_greater_than_nbit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _bits ) {
2197
2198 inline( cpu_greater_than_nbit )
2199
2200 cpu_less_than_nbit_const( _environment, _source, _destination, _other, !_equal, _bits );
2201 cpu_not_8bit( _environment, _other, _other );
2202
2204
2205}
2206
2215void cpu_math_add_32bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
2216
2217 inline( cpu_math_add_32bit )
2218
2219 outline1("MOV AX, [%s]", _source );
2220 outline1("MOV BX, [%s]", _destination );
2221 outline0("ADD AX, BX" );
2222 if ( _other ) {
2223 outline1("MOV [%s], AX", _other );
2224 } else {
2225 outline1("MOV [%s], AX", _destination );
2226 }
2227 outline1("MOV AX, [%s]", address_displacement( _environment, _source, "+2" ) );
2228 outline1("MOV BX, [%s]", address_displacement( _environment, _destination, "+2" ) );
2229 outline0("ADD AX, BX" );
2230 if ( _other ) {
2231 outline1("MOV [%s], AX", address_displacement( _environment, _other, "+2" ) );
2232 } else {
2233 outline1("MOV [%s], AX", address_displacement( _environment, _destination, "+2" ) );
2234 }
2235
2237
2238}
2239
2240void cpu_math_add_32bit_const( Environment * _environment, char *_source, int _destination, char *_other ) {
2241
2242 inline( cpu_math_add_32bit_const )
2243
2244 outline1("MOV AX, [%s]", _source );
2245 outline1("MOV BX, 0x%4.4x", (unsigned short)(_destination&0xffff) );
2246 outline0("ADD AX, BX" );
2247 outline1("MOV [%s], AX", _other );
2248 outline1("MOV AX, [%s]", address_displacement( _environment, _source, "+2" ) );
2249 outline1("MOV BX, 0x%4.4x", (unsigned short)((_destination>>16)&0xffff) );
2250 outline0("ADC AX, BX" );
2251 outline1("MOV [%s], AX", address_displacement( _environment, _other, "+2" ) );
2252
2254
2255}
2256
2257void cpu_math_add_nbit( Environment * _environment, char *_source, char *_destination, char *_other, int _bits ) {
2258
2259 inline( cpu_math_add_nbit )
2260
2261 outline0("CLC");
2262 for( int i=0; i<(_bits>>3); ++i ) {
2263 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
2264 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset));
2265 outline1("ADC AL, [%s]", address_displacement(_environment, _destination, offset));
2266 if ( _other ) {
2267 outline1("MOV [%s], AL", address_displacement(_environment, _other, offset));
2268 } else {
2269 outline1("MOV [%s], AL", address_displacement(_environment, _destination, offset));
2270 }
2271 }
2273
2274}
2275
2283void cpu_math_double_32bit( Environment * _environment, char *_source, char *_other, int _signed ) {
2284
2285 inline( cpu_math_double_32bit )
2286
2287 if ( _other ) {
2288 cpu_math_add_32bit( _environment, _source, _source, _other );
2289 } else {
2290 cpu_math_add_32bit( _environment, _source, _source, _source );
2291 }
2292
2294
2295}
2296
2305void cpu_math_sub_32bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
2306
2307 inline( cpu_math_sub_32bit )
2308
2310
2311 outline1("MOV AX, [%s]", _source );
2312 outline1("MOV BX, [%s]", _destination );
2313 outline0("SUB AX, BX" );
2314 outline1("MOV [%s], AX", _other );
2315 outline1("MOV AX, [%s]", address_displacement( _environment, _source, "+2" ) );
2316 outline1("MOV BX, [%s]", address_displacement( _environment, _destination, "+2" ) );
2317 outline0("SBB AX, BX" );
2318 outline1("MOV [%s], AX", address_displacement( _environment, _other, "+2" ) );
2319
2321
2322}
2323
2324void cpu_math_sub_nbit( Environment * _environment, char *_source, char *_destination, char *_other, int _bits ) {
2325
2326 inline( cpu_math_sub_nbit )
2327
2328 outline0("CLC");
2329 for( int i=0; i<(_bits)>>3; ++i ) {
2330 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
2331 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset));
2332 outline1("SBB AL, [%s]", address_displacement(_environment, _destination, offset));
2333 if ( _other ) {
2334 outline1("MOV [%s], AL", address_displacement(_environment, _other, offset));
2335 } else {
2336 outline1("MOV [%s], AL", address_displacement(_environment, _destination, offset));
2337 }
2338 }
2339
2341
2342}
2343
2351void cpu_math_complement_const_32bit( Environment * _environment, char *_source, int _value ) {
2352
2354
2355 outline1("MOV AX, 0x%4.4x", (unsigned short)(_value&0xffff) );
2356 outline1("MOV BX, [%s]", _source );
2357 outline0("SUB AX, BX" );
2358 outline1("MOV [%s], AX", _source );
2359 outline1("MOV BX, [%s]", address_displacement( _environment, _source, "+2" ) );
2360 outline1("MOV AX, 0x%4.4x", (unsigned short)((_value>>16)&0xffff) );
2361 outline0("SBB AX, BX" );
2362 outline1("MOV [%s], AX", address_displacement( _environment, _source, "+2" ) );
2363
2365
2366}
2367
2375void cpu_math_div2_const_32bit( Environment * _environment, char *_source, int _steps, int _signed, char * _remainder ) {
2376
2378
2380
2381 if ( _remainder ) {
2382 outline1("MOV AL, [%s]", _source );
2383 outline0("AND 0x1" );
2384 outline1("MOV [%s], AL", _remainder );
2385 }
2386 if ( _signed ) {
2387 outline1("MOV AL, [%s]", address_displacement(_environment, _source, "3") );
2388 outline0("AND AL, 0x80" );
2389 outline0("PUSH AX" );
2390 outline0("CMP AL, 0" );
2391 outline1("JZ %spos", label );
2392 cpu_complement2_32bit( _environment, _source, _source );
2393 outline1("JMP %spos2", label );
2394 outhead1("%spos:", label );
2395 outhead1("%spos2:", label );
2396 outline1("MOV AX, [%s]", _source );
2397 outline1("MOV BX, [%s]", address_displacement(_environment, _source, "2") );
2398 while( _steps ) {
2399 outline0("SAR BX, 1" );
2400 outline0("ROR AX, 1" );
2401 --_steps;
2402 }
2403 outline1("MOV [%s], AX", _source );
2404 outline1("MOV [%s], BX", address_displacement( _environment, _source, "2" ) );
2405 outline0("POP AX" );
2406 outline0("CMP AL, 0" );
2407 outline1("JZ %sdone", label );
2408 cpu_complement2_32bit( _environment, _source, _source );
2409 outhead1("%sdone:", label );
2410 } else {
2411 outline1("MOV AX, [%s]", _source );
2412 outline1("MOV BX, [%s]", address_displacement(_environment, _source, "2") );
2413 while( _steps ) {
2414 outline0("SAR BX, 1" );
2415 outline0("ROR AX, 1" );
2416 --_steps;
2417 }
2418 outline1("MOV [%s], AX", _source );
2419 outline1("MOV [%s], BX", address_displacement( _environment, _source, "2" ) );
2420 }
2421
2423
2424}
2425
2426
2434void cpu_math_mul2_const_32bit( Environment * _environment, char *_source, int _steps, int _signed ) {
2435
2437
2439
2440 if ( _signed ) {
2441 outline1("MOV AL, [%s]", address_displacement(_environment, _source, "3") );
2442 outline0("AND AL, 0x80" );
2443 outline0("PUSH AX" );
2444 outline0("CMP AL, 0" );
2445 outline1("JZ %spos", label );
2446 cpu_complement2_32bit( _environment, _source, _source );
2447 outline1("JMP %spos2", label );
2448 outhead1("%spos:", label );
2449 outhead1("%spos2:", label );
2450 outline1("MOV AX, [%s]", _source );
2451 outline1("MOV BX, [%s]", address_displacement(_environment, _source, "2") );
2452 while( _steps ) {
2453 outline0("SAL AX, 1" );
2454 outline0("ROL BX, 1" );
2455 --_steps;
2456 }
2457 outline1("MOV [%s], AX", _source );
2458 outline1("MOV [%s], BX", address_displacement( _environment, _source, "2" ) );
2459 outline0("POP AX" );
2460 outline0("CMP AL, 0" );
2461 outline1("JZ %sdone", label );
2462 cpu_complement2_32bit( _environment, _source, _source );
2463 outhead1("%sdone:", label );
2464 } else {
2465 outline1("MOV AX, [%s]", _source );
2466 outline1("MOV BX, [%s]", address_displacement(_environment, _source, "2") );
2467 while( _steps ) {
2468 outline0("SAL AX, 1" );
2469 outline0("ROL BX, 1" );
2470 --_steps;
2471 }
2472 outline1("MOV [%s], AX", _source );
2473 outline1("MOV [%s], BX", address_displacement( _environment, _source, "2" ) );
2474 }
2475
2477
2478}
2479
2487void cpu_math_and_const_32bit( Environment * _environment, char *_source, int _mask ) {
2488
2489 inline( cpu_math_and_const_32bit )
2490
2491 outline1("MOV AX, [%s]", _source );
2492 outline1("AND AX, 0x%4.4x", (unsigned short)( _mask & 0xffff ) );
2493 outline1("MOV [%s], AX", _source );
2494 outline1("MOV AX, [%s]", address_displacement(_environment, _source, "2") );
2495 outline1("AND AX, 0x%4.4x", (unsigned short)( (_mask>>16) & 0xffff ) );
2496 outline1("MOV [%s], AX", address_displacement(_environment, _source, "2") );
2497
2499
2500}
2501
2505void cpu_combine_nibbles( Environment * _environment, char * _low_nibble, char * _hi_nibble, char * _byte ) {
2506
2507 inline( cpu_combine_nibbles )
2508
2509 outline1("MOV BL, [%s]", _low_nibble );
2510 outline1("MOV AL, [%s]", _hi_nibble );
2511 outline0("SAL AL, 1");
2512 outline0("SAL AL, 1");
2513 outline0("SAL AL, 1");
2514 outline0("SAL AL, 1");
2515 outline0("OR AL, BL");
2516 outline1("MOV [%s], AL", _byte );
2517
2519
2520}
2521
2522void cpu_jump( Environment * _environment, char * _label ) {
2523
2524 outline1("JMP %s", _label );
2525
2526}
2527
2528void cpu_call_addr( Environment * _environment, int _address ) {
2529
2530 outline1("CALL 0x%4.4x", _address );
2531
2532}
2533
2534void cpu_call( Environment * _environment, char * _label ) {
2535
2536 outline1("CALL %s", _label );
2537
2538}
2539
2540void cpu_call_indirect( Environment * _environment, char * _value ) {
2541
2542 outline1( "CALL [%s]", _value )
2543
2544}
2545
2546void cpu_jump_indirect( Environment * _environment, char * _value ) {
2547
2548 outline1( "JMP [%s]", _value )
2549
2550}
2551
2552int cpu_register_decode( Environment * _environment, char * _register ) {
2553
2555
2556 if ( !_environment->emptyProcedure ) {
2557
2558 if ( strcmp( _register, "AL" ) == 0 ) {
2559 result = REGISTER_AL;
2560 } else if ( strcmp( _register, "AH" ) == 0 ) {
2561 result = REGISTER_AH;
2562 } else if ( strcmp( _register, "BL" ) == 0 ) {
2563 result = REGISTER_BL;
2564 } else if ( strcmp( _register, "BH" ) == 0 ) {
2565 result = REGISTER_BH;
2566 } else if ( strcmp( _register, "CL" ) == 0 ) {
2567 result = REGISTER_CL;
2568 } else if ( strcmp( _register, "CH" ) == 0 ) {
2569 result = REGISTER_CH;
2570 } else if ( strcmp( _register, "DL" ) == 0 ) {
2571 result = REGISTER_DL;
2572 } else if ( strcmp( _register, "DH" ) == 0 ) {
2573 result = REGISTER_DH;
2574 } else if ( strcmp( _register, "AX" ) == 0 ) {
2575 result = REGISTER_AX;
2576 } else if ( strcmp( _register, "BX" ) == 0 ) {
2577 result = REGISTER_BX;
2578 } else if ( strcmp( _register, "CX" ) == 0 ) {
2579 result = REGISTER_CX;
2580 } else if ( strcmp( _register, "DX" ) == 0 ) {
2581 result = REGISTER_DX;
2582 } else if ( strcmp( _register, "SP" ) == 0 ) {
2583 result = REGISTER_SP;
2584 } else if ( strcmp( _register, "BP" ) == 0 ) {
2585 result = REGISTER_BP;
2586 } else if ( strcmp( _register, "SI" ) == 0 ) {
2587 result = REGISTER_SI;
2588 } else if ( strcmp( _register, "DI" ) == 0 ) {
2589 result = REGISTER_DI;
2590 } else if ( strcmp( _register, "CARRY" ) == 0 ) {
2591 result = REGISTER_CARRY;
2592 } else if ( strcmp( _register, "ZERO" ) == 0 ) {
2593 result = REGISTER_ZERO;
2594 } else {
2595
2596 }
2597
2598 }
2599
2600 return (int)result;
2601
2602}
2603
2604void cpu_set_asmio( Environment * _environment, int _asmio, int _value ) {
2605
2606 if ( IS_REGISTER( _asmio ) ) {
2607
2609
2610 CPU8086Register reg = (CPU8086Register) _asmio;
2611
2612 switch ( reg ) {
2613 case REGISTER_NONE:
2615 break;
2616 break;
2617 case REGISTER_AL:
2618 outline1( "MOV AL, 0x%2.2x", (unsigned char)(_value & 0xff ) );
2619 break;
2620 case REGISTER_AH:
2621 outline1( "MOV AH, 0x%2.2x", (unsigned char)(_value & 0xff ) );
2622 break;
2623 case REGISTER_BL:
2624 outline1( "MOV BL, 0x%2.2x", (unsigned char)(_value & 0xff ) );
2625 break;
2626 case REGISTER_BH:
2627 outline1( "MOV BH, 0x%2.2x", (unsigned char)(_value & 0xff ) );
2628 break;
2629 case REGISTER_CL:
2630 outline1( "MOV CL, 0x%2.2x", (unsigned char)(_value & 0xff ) );
2631 break;
2632 case REGISTER_CH:
2633 outline1( "MOV CH, 0x%2.2x", (unsigned char)(_value & 0xff ) );
2634 break;
2635 case REGISTER_DL:
2636 outline1( "MOV DL, 0x%2.2x", (unsigned char)(_value & 0xff ) );
2637 break;
2638 case REGISTER_DH:
2639 outline1( "MOV DH, 0x%2.2x", (unsigned char)(_value & 0xff ) );
2640 break;
2641 case REGISTER_AX:
2642 outline1( "MOV AX, 0x%4.4x", (unsigned short)(_value & 0xffff ) );
2643 break;
2644 case REGISTER_BX:
2645 outline1( "MOV BX, 0x%4.4x", (unsigned short)(_value & 0xffff ) );
2646 break;
2647 case REGISTER_CX:
2648 outline1( "MOV CX, 0x%4.4x", (unsigned short)(_value & 0xffff ) );
2649 break;
2650 case REGISTER_DX:
2651 outline1( "MOV DX, 0x%4.4x", (unsigned short)(_value & 0xffff ) );
2652 break;
2653 case REGISTER_SP:
2654 outline1( "MOV SP, 0x%4.4x", (unsigned short)(_value & 0xffff ) );
2655 break;
2656 case REGISTER_BP:
2657 outline1( "MOV BP, 0x%4.4x", (unsigned short)(_value & 0xffff ) );
2658 break;
2659 case REGISTER_SI:
2660 outline1( "MOV SI, 0x%4.4x", (unsigned short)(_value & 0xffff ) );
2661 break;
2662 case REGISTER_DI:
2663 outline1( "MOV DI, 0x%4.4x", (unsigned short)(_value & 0xffff ) );
2664 break;
2665 }
2666
2667 } else {
2668
2669 CPU8086Stack stk = (CPU8086Stack) _asmio;
2670
2671 switch ( stk ) {
2672 case STACK_NONE:
2673 break;
2674 case STACK_BYTE:
2675 outline1( "MOV AL, 0x%2.2x", (unsigned char)(_value & 0xff ) );
2676 outline0( "PUSH AL" );
2677 break;
2678 case STACK_WORD:
2679 outline1( "MOV AX, 0x%4.4x", (unsigned short)(_value & 0xffff) );
2680 outline0( "PUSH AX" );
2681 break;
2682 case STACK_DWORD:
2683 outline1( "MOV AX, 0x%4.4x", (unsigned short)(_value & 0xffff) );
2684 outline0( "PUSH AX" );
2685 outline1( "MOV AX, 0x%4.4x", (unsigned short)((_value>>16) & 0xffff) );
2686 outline0( "PUSH AX" );
2687 break;
2688 }
2689
2690 }
2691
2692}
2693
2694void cpu_set_asmio_indirect( Environment * _environment, int _asmio, char * _value ) {
2695
2696 if ( IS_REGISTER( _asmio ) ) {
2697
2699
2700 CPU8086Register reg = (CPU8086Register) _asmio;
2701
2702 switch ( reg ) {
2703 case REGISTER_NONE:
2705 break;
2706 break;
2707 case REGISTER_AL:
2708 outline1( "MOV AL, [%s]", _value );
2709 break;
2710 case REGISTER_AH:
2711 outline1( "MOV AH, [%s]", _value );
2712 break;
2713 case REGISTER_BL:
2714 outline1( "MOV BL, [%s]", _value );
2715 break;
2716 case REGISTER_BH:
2717 outline1( "MOV BH, [%s]", _value );
2718 break;
2719 case REGISTER_CL:
2720 outline1( "MOV CL, [%s]", _value );
2721 break;
2722 case REGISTER_CH:
2723 outline1( "MOV CH, [%s]", _value );
2724 break;
2725 case REGISTER_DL:
2726 outline1( "MOV DL, [%s]", _value );
2727 break;
2728 case REGISTER_DH:
2729 outline1( "MOV DH, [%s]", _value );
2730 break;
2731 case REGISTER_AX:
2732 outline1( "MOV AX, [%s]", _value );
2733 break;
2734 case REGISTER_BX:
2735 outline1( "MOV BX, [%s]", _value );
2736 break;
2737 case REGISTER_CX:
2738 outline1( "MOV CX, [%s]", _value );
2739 break;
2740 case REGISTER_DX:
2741 outline1( "MOV DX, [%s]", _value );
2742 break;
2743 case REGISTER_SP:
2744 outline1( "MOV SP, [%s]", _value );
2745 break;
2746 case REGISTER_BP:
2747 outline1( "MOV BP, [%s]", _value );
2748 break;
2749 case REGISTER_SI:
2750 outline1( "MOV SI, [%s]", _value );
2751 break;
2752 case REGISTER_DI:
2753 outline1( "MOV DI, [%s]", _value );
2754 break;
2755 }
2756
2757 } else {
2758
2759 CPU8086Stack stk = (CPU8086Stack) _asmio;
2760
2761 switch ( stk ) {
2762 case STACK_NONE:
2763 break;
2764 case STACK_BYTE:
2765 outline1( "MOV AL, [%s]", _value );
2766 outline0( "PUSH AL" );
2767 break;
2768 case STACK_WORD:
2769 outline1( "MOV AX, [%s]", _value );
2770 outline0( "PUSH AX" );
2771 break;
2772 case STACK_DWORD:
2773 outline1( "MOV AX, [%s]", _value );
2774 outline0( "PUSH AX" );
2775 outline1( "MOV AX, [%s]", address_displacement( _environment, _value, "+2" ) );
2776 outline0( "PUSH AX" );
2777 break;
2778 }
2779
2780 }
2781
2782}
2783
2784void cpu_get_asmio_indirect( Environment * _environment, int _asmio, char * _value ) {
2785
2786 if ( IS_REGISTER( _asmio ) ) {
2787
2789
2790 CPU8086Register reg = (CPU8086Register) _asmio;
2791
2792 switch ( reg ) {
2793 case REGISTER_NONE:
2795 break;
2796 break;
2797 case REGISTER_AL:
2798 outline1( "MOV [%s], AL", _value );
2799 break;
2800 case REGISTER_AH:
2801 outline1( "MOV [%s], AH", _value );
2802 break;
2803 case REGISTER_BL:
2804 outline1( "MOV [%s], BL", _value );
2805 break;
2806 case REGISTER_BH:
2807 outline1( "MOV [%s], BH", _value );
2808 break;
2809 case REGISTER_CL:
2810 outline1( "MOV [%s], CL", _value );
2811 break;
2812 case REGISTER_CH:
2813 outline1( "MOV [%s], CH", _value );
2814 break;
2815 case REGISTER_DL:
2816 outline1( "MOV [%s], DL", _value );
2817 break;
2818 case REGISTER_DH:
2819 outline1( "MOV [%s], DH", _value );
2820 break;
2821 case REGISTER_AX:
2822 outline1( "MOV [%s], AX", _value );
2823 break;
2824 case REGISTER_BX:
2825 outline1( "MOV [%s], BX", _value );
2826 break;
2827 case REGISTER_CX:
2828 outline1( "MOV [%s], CX", _value );
2829 break;
2830 case REGISTER_DX:
2831 outline1( "MOV [%s], DX", _value );
2832 break;
2833 case REGISTER_SP:
2834 outline1( "MOV [%s], SP", _value );
2835 break;
2836 case REGISTER_BP:
2837 outline1( "MOV [%s], BP", _value );
2838 break;
2839 case REGISTER_SI:
2840 outline1( "MOV [%s], SI", _value );
2841 break;
2842 case REGISTER_DI:
2843 outline1( "MOV [%s], DI", _value );
2844 break;
2845 }
2846
2847 } else {
2848
2849 CPU8086Stack stk = (CPU8086Stack) _asmio;
2850
2851 switch ( stk ) {
2852 case STACK_NONE:
2853 break;
2854 case STACK_BYTE:
2855 outline0( "POP AL" );
2856 outline1( "MOV [%s], AL", _value );
2857 break;
2858 case STACK_WORD:
2859 outline0( "POP AX" );
2860 outline1( "MOV [%s], AX", _value );
2861 break;
2862 case STACK_DWORD:
2863 outline0( "POP AX" );
2864 outline1( "MOV [%s], AX", address_displacement( _environment, _value, "+2" ) );
2865 outline0( "POP AX" );
2866 outline1( "MOV [%s], AX", _value );
2867 break;
2868 }
2869
2870 }
2871
2872}
2873
2874void cpu_return( Environment * _environment ) {
2875
2876 outline0("RET" );
2877
2878}
2879
2880void cpu_pop( Environment * _environment ) {
2881
2882 outline0("POP AX" );
2883
2884}
2885
2886void cpu_halt( Environment * _environment ) {
2887
2889
2890 outhead1("%s:", label );
2891 outline1("JMP %s", label );
2892
2893}
2894
2895void cpu_end( Environment * _environment ) {
2896
2897 outline0("HLT");
2898
2899}
2900
2901void cpu_random( Environment * _environment, char * _entropy ) {
2902
2904
2906
2907 embedded( cpu_random, src_hw_8086_cpu_random_asm );
2908
2909 done()
2910
2911
2912}
2913
2914void cpu_random_8bit( Environment * _environment, char * _entropy, char * _result ) {
2915
2916 cpu_random( _environment, _entropy );
2917
2918 if ( _result ) {
2919 outline0("CALL CPURANDOM16" );
2920 outline1("MOV [%s], AL", _result );
2921 }
2922
2923}
2924
2925void cpu_random_16bit( Environment * _environment, char * _entropy, char * _result ) {
2926
2927 cpu_random( _environment, _entropy );
2928
2929 if ( _result ) {
2930 outline0("CALL CPURANDOM16" );
2931 outline1("MOV [%s], AX", _result );
2932 }
2933
2934}
2935
2936void cpu_random_32bit( Environment * _environment, char * _entropy, char * _result ) {
2937
2938 cpu_random( _environment, _entropy );
2939
2940 if ( _result ) {
2941 outline0("CALL CPURANDOM32" );
2942 outline1("MOV [%s], AX", _result );
2943 outline1("MOV [%s], BX", address_displacement( _environment, _result, "2" ) );
2944 }
2945
2946}
2947
2948void cpu_limit_16bit( Environment * _environment, char * _variable, int _value ) {
2949
2951
2952 outline1( "MOV AL, [%s]", _variable );
2953 outline1( "CMP AL, 0x%2.2x", (unsigned char)(_value&0xff) );
2954 outline1( "JB %s", label );
2955 outline1( "SUB AL, 0x%2.2x", (unsigned char)(_value&0xff) );
2956 outline1( "MOV [%s], AL", _variable );
2957 outhead1( "%s:", label );
2958
2959}
2960
2961void cpu_busy_wait( Environment * _environment, char * _timing ) {
2962
2964
2965 outline1("MOV AL, [%s]", _timing );
2966 outhead1("%s:", label );
2967 outline0("DEC AL");
2968 outline1("JNZ %s", label);
2969
2970}
2971
2979void cpu_port_out( Environment * _environment, char * _port, char * _value ) {
2980
2981 outline1("MOV AL, [%s]", _value );
2982 outline1("MOV DL, [%s]", _port );
2983 outline0("MOV dh, 0" );
2984 outline0("OUT DX, AL" );
2985
2986}
2987
2988void cpu_logical_and_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
2989
2991
2992 outline1("MOV AL, [%s]", _left );
2993 outline0("CMP AL, 0" );
2994 outline1("JZ %s", label );
2995 outline1("MOV AL, [%s]", _right );
2996 outline0("CMP AL, 0" );
2997 outline1("JZ %s", label );
2998 outline0("MOV AL, 0xff" );
2999 outline1("MOV [%s], AL", _result );
3000 outline1("JMP %s_2", label );
3001 outhead1("%s:", label );
3002 outline0("MOV AL, 0" );
3003 outline1("MOV [%s], AL", _result );
3004 outhead1("%s_2:", label );
3005
3006}
3007
3008void cpu_and_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3009
3010 outline1("MOV AL, [%s]", _left );
3011 outline1("MOV AH, [%s]", _right );
3012 outline0("AND AL, AH" );
3013 outline1("MOV [%s], AL", _result );
3014
3015}
3016
3017void cpu_and_8bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
3018
3019 outline1("MOV AL, [%s]", _left );
3020 outline1("MOV AH, 0x%2.2x", _right );
3021 outline0("AND AL, AH" );
3022 outline1("MOV [%s], AL", _result );
3023
3024}
3025
3026void cpu_and_16bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3027
3028 outline1("MOV AX, [%s]", _left );
3029 outline1("MOV BX, [%s]", _right );
3030 outline0("AND AX, BX" );
3031 outline1("MOV [%s], AX", _result );
3032
3033}
3034
3035void cpu_and_32bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3036
3037 cpu_and_16bit( _environment, _left, _right, _result );
3038 cpu_and_16bit( _environment,
3039 address_displacement( _environment, _left, "+2" ),
3040 address_displacement( _environment, _right, "+2" ),
3041 address_displacement( _environment, _result, "+2" )
3042 );
3043
3044}
3045
3046void cpu_logical_or_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3047
3049
3050 outline1("MOV AL, [%s]", _left );
3051 outline0("CMP AL, 0" );
3052 outline1("JZ %s", label );
3053 outline0("MOV AL, 0xff" );
3054 outline1("MOV [%s], AL", _result );
3055 outline1("JMP %s_2", label );
3056 outline1("MOV AL, [%s]", _right );
3057 outline0("CMP AL, 0" );
3058 outline1("JZ %s", label );
3059 outline0("MOV AL, 0xff" );
3060 outline1("MOV [%s], AL", _result );
3061 outline1("JMP %s_2", label );
3062 outhead1("%s:", label );
3063 outline0("MOV AL, 0" );
3064 outline1("MOV [%s], AL", _result );
3065 outhead1("%s_2:", label );
3066
3067}
3068
3069void cpu_or_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3070
3071 outline1("MOV AL, [%s]", _left );
3072 outline1("MOV AH, [%s]", _right );
3073 outline0("OR AL, AH" );
3074 outline1("MOV [%s], AL", _result );
3075
3076}
3077
3078void cpu_or_8bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
3079
3080 outline1("MOV AL, [%s]", _left );
3081 outline1("MOV AH, 0x%2.2x", _right );
3082 outline0("OR AL, AH" );
3083 outline1("MOV [%s], AL", _result );
3084
3085}
3086
3087void cpu_or_16bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3088
3089 outline1("MOV AX, [%s]", _left );
3090 outline1("MOV BX, [%s]", _right );
3091 outline0("OR AX, BX" );
3092 outline1("MOV [%s], AX", _result );
3093
3094}
3095
3096void cpu_or_32bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3097
3098 cpu_or_16bit( _environment, _left, _right, _result );
3099 cpu_or_16bit( _environment,
3100 address_displacement( _environment, _left, "+2" ),
3101 address_displacement( _environment, _right, "+2" ),
3102 address_displacement( _environment, _result, "+2" )
3103 );
3104
3105}
3106
3107void cpu_xor_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3108
3109 outline1("MOV AL, [%s]", _left );
3110 outline1("MOV AH, [%s]", _right );
3111 outline0("XOR AL, AH" );
3112 outline1("MOV [%s], AL", _result );
3113
3114}
3115
3116void cpu_xor_8bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
3117
3118 outline1("MOV AL, [%s]", _left );
3119 outline1("MOV AH, 0x%2.2x", _right );
3120 outline0("XOR AL, AH" );
3121 outline1("MOV [%s], AL", _result );
3122
3123}
3124
3125void cpu_xor_16bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3126
3127 outline1("MOV AX, [%s]", _left );
3128 outline1("MOV BX, [%s]", _right );
3129 outline0("XOR AX, BX" );
3130 outline1("MOV [%s], AX", _result );
3131
3132}
3133
3134void cpu_xor_16bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
3135
3136 outline1("MOV AX, [%s]", _left );
3137 outline1("MOV BX, 0x%4.4x", _right );
3138 outline0("XOR AX, BX" );
3139 outline1("MOV [%s], AX", _result );
3140
3141}
3142
3143
3144void cpu_xor_32bit( Environment * _environment, char * _left, char * _right, char * _result ) {
3145
3146 cpu_xor_16bit( _environment, _left, _right, _result );
3147 cpu_xor_16bit( _environment,
3148 address_displacement( _environment, _left, "+2" ),
3149 address_displacement( _environment, _right, "+2" ),
3150 address_displacement( _environment, _result, "+2" )
3151 );
3152
3153}
3154
3155void cpu_xor_32bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
3156
3157 cpu_xor_16bit_const( _environment, _left, (unsigned short)(_right&0xffff), _result );
3158 cpu_xor_16bit_const( _environment,
3159 address_displacement( _environment, _left, "+2" ),
3160 (unsigned short)((_right>>16)&0xffff),
3161 address_displacement( _environment, _result, "+2" )
3162 );
3163
3164}
3165
3166void cpu_swap_8bit( Environment * _environment, char * _left, char * _right ) {
3167
3168 inline( cpu_swap_8bit )
3169
3170 outline1("MOV AL, [%s]", _right );
3171 outline1("MOV AH, [%s]", _left );
3172 outline0("XCHG AL, AH" );
3173 outline1("MOV [%s], AL", _right );
3174 outline1("MOV [%s], AH", _left );
3175
3177
3178}
3179
3180void cpu_swap_16bit( Environment * _environment, char * _left, char * _right ) {
3181
3182 inline( cpu_swap_8bit )
3183
3184 outline1("MOV AX, [%s]", _right );
3185 outline1("MOV BX, [%s]", _left );
3186 outline0("XCHG AX, BX" );
3187 outline1("MOV [%s], AX", _right );
3188 outline1("MOV [%s], BX", _left );
3189
3191
3192}
3193
3194void cpu_swap_32bit( Environment * _environment, char * _left, char * _right ) {
3195
3196 cpu_swap_16bit( _environment, _left, _right );
3197 cpu_swap_16bit( _environment, address_displacement( _environment, _left, "+2" ), address_displacement( _environment, _right, "+2" ) );
3198
3199}
3200
3201void cpu_logical_not_8bit( Environment * _environment, char * _value, char * _result ) {
3202
3203 outline1("MOV AL, [%s]", _value );
3204 outline0("XOR AL, 0xff" );
3205 outline1("MOV [%s], AL", _result );
3206
3207}
3208
3209void cpu_not_8bit( Environment * _environment, char * _value, char * _result ) {
3210
3211 outline1("MOV AL, [%s]", _value );
3212 outline0("XOR AL, 0xff" );
3213 outline1("MOV [%s], AL", _result );
3214
3215}
3216
3217void cpu_not_16bit( Environment * _environment, char * _value, char * _result ) {
3218
3219 outline1("MOV AX, [%s]", _value );
3220 outline0("XOR AX, 0xffff" );
3221 outline1("MOV [%s], AX", _result );
3222
3223}
3224
3225void cpu_not_32bit( Environment * _environment, char * _value, char * _result ) {
3226
3227 cpu_not_16bit( _environment, _value, _result );
3228 cpu_not_16bit( _environment,
3229 address_displacement( _environment, _value, "+2" ),
3230 address_displacement( _environment, _result, "+2" )
3231 );
3232
3233}
3234
3235void cpu_di( Environment * _environment ) {
3236
3237 outline0("CLI");
3238
3239}
3240
3241void cpu_ei( Environment * _environment ) {
3242
3243 outline0("STI");
3244
3245}
3246
3247void cpu_inc( Environment * _environment, char * _variable ) {
3248
3249 outline1("MOV AL, [%s]", _variable );
3250 outline0("INC AL" );
3251 outline1("MOV [%s], AL", _variable );
3252
3253}
3254
3255void cpu_dec( Environment * _environment, char * _variable ) {
3256
3257 outline1("MOV AL, [%s]", _variable );
3258 outline0("DEC AL" );
3259 outline1("MOV [%s], AL", _variable );
3260
3261}
3262
3263void cpu_inc_16bit( Environment * _environment, char * _variable ) {
3264
3265 outline1("MOV AX, [%s]", _variable );
3266 outline0("INC AX" );
3267 outline1("MOV [%s], AX", _variable );
3268
3269}
3270
3271void cpu_inc_32bit( Environment * _environment, char * _variable ) {
3272
3274
3275 outline1("MOV AX, [%s]", _variable );
3276 outline0("INC AX" );
3277 outline1("MOV [%s], AX", _variable );
3278 outline1("JNC %s", label );
3279 outline1("MOV AX, [%s]", address_displacement( _environment, _variable, "+2" ) );
3280 outline0("INC AX" );
3281 outline1("MOV [%s], AX", address_displacement( _environment, _variable, "+2" ) );
3282 outhead1("%s:", label );
3283
3284}
3285
3286void cpu_inc_nbit( Environment * _environment, char * _variable, int _bits ) {
3287
3289
3290 inline( cpu_inc_nbit )
3291
3292 for( int i=0; i<(_bits>>3);++i ) {
3293 char offset[MAX_TEMPORARY_STORAGE]; sprintf(offset, "%d", i );
3294 outline1("MOV AL, [%s]", address_displacement(_environment, _variable, offset ) );
3295 outline0("INC AL");
3296 outline1("MOV [%s], AL", address_displacement(_environment, _variable, offset ) );
3297 outline1("JNZ %s", label );
3298 }
3299 outhead1("%s:", label );
3300
3302
3303}
3304
3305void cpu_dec_16bit( Environment * _environment, char * _variable ) {
3306
3307 outline1("MOV AX, [%s]", _variable );
3308 outline0("DEC AX" );
3309 outline1("MOV [%s], AX", _variable );
3310
3311}
3312
3313void cpu_dec_32bit( Environment * _environment, char * _variable ) {
3314
3316
3317 outline1("MOV AX, [%s]", _variable );
3318 outline0("DEC AX" );
3319 outline1("MOV [%s], AX", _variable );
3320 outline0("CMP AX, 0xffff" );
3321 outline1("JNZ %s", label );
3322 outline1("MOV AX, [%s]", address_displacement( _environment, _variable, "+2" ) );
3323 outline0("DEC AX" );
3324 outline1("MOV [%s], AX", address_displacement( _environment, _variable, "+2" ) );
3325 outhead1("%s:", label );
3326
3327}
3328
3329void cpu_dec_nbit( Environment * _environment, char * _variable, int _bits ) {
3330
3332
3333 inline( cpu_dec_32bit )
3334
3335 for( int i=0; i<(_bits>>3); ++i ) {
3336 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
3337 outline1("MOV AL, [%s]", address_displacement(_environment, _variable, offset) );
3338 outline0("DEC AL" );
3339 outline1("MOV [%s], AL", address_displacement(_environment, _variable, offset) );
3340 outline0("CMP AL, 0xFF" );
3341 outline1("JNZ %s", label );
3342 }
3343 outhead1("%s:", label );
3344
3346
3347}
3348
3349void cpu_less_than_nbit( Environment * _environment, char *_source, char * _destination, char *_other, int _equal, int _bits ) {
3350
3352
3353 int i;
3354
3355 inline( cpu_less_than_nbit )
3356
3357 if ( _equal ) {
3358
3359 cpu_compare_nbit( _environment, _source, _destination, _other, 1, _bits );
3360
3361 if ( _other ) {
3362 outline1("MOV AL, [%s]", _other);
3363 } else {
3364 outline1("MOV AL, [%s]", _destination);
3365 }
3366
3367 outline0("CMP AL, 0" );
3368 outline1("JZ %sless", label );
3369 outline1("JMP %sdone", label );
3370 outhead1("%sless:", label );
3371
3372 }
3373
3374 for( i=(_bits>>3)-1; i>-1; --i ) {
3375 char offset[MAX_TEMPORARY_STORAGE]; sprintf(offset, "%d", i );
3376 outline1("MOV AL, [%s]", address_displacement(_environment, _destination, offset ) );
3377 outline0("MOV BL, AL");
3378 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset ) );
3379 outline0("CMP AL, BL");
3380 outline2("JZ %snext%dx", label, i );
3381 outline1("JC %sbga", label );
3382 outline1("JMP %sagb", label );
3383 outhead2("%snext%dx:", label, i );
3384 }
3385
3386 outhead1("%sbga:", label );
3387 outline0("MOV AL, 0xff" );
3388 outline1("MOV [%s], AL", _other );
3389 outline1("JMP %sdone", label );
3390
3391 outhead1("%sagb:", label );
3392 outline0("MOV AL, 0x00" );
3393 outline1("MOV [%s], AL", _other );
3394 outline1("JMP %sdone", label );
3395
3396 outhead1("%sdone:", label );
3397
3399
3400}
3401
3402void cpu_less_than_nbit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _bits ) {
3403
3405
3406 int i;
3407
3408 inline( cpu_less_than_nbit_const )
3409
3410 if ( _equal ) {
3411
3412 cpu_compare_nbit_const( _environment, _source, _destination, _other, 1, _bits );
3413
3414 outline1("MOV AL, [%s]", _other);
3415 outline0("CMP AL, 0" );
3416 outline1("JZ %sless", label );
3417 outline1("JMP %sdone", label );
3418 outhead1("%sless:", label );
3419
3420 }
3421
3422 for( i=(_bits>>3)-2; i>-1; --i ) {
3423 char offset[MAX_TEMPORARY_STORAGE]; sprintf(offset, "%d", i );
3424 outline1("MOV BL, $%2.2x", (unsigned char)((_destination>>(i*8))&0xff) );
3425 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset ) );
3426 outline0("CMP AL, BL");
3427 outline2("JZ %snext%dx", label, i );
3428 outline1("JC %sbga", label );
3429 outline1("JMP %sagb", label );
3430 outhead2("%snext%dx:", label, i );
3431 }
3432
3433 outhead1("%sbga:", label );
3434 outline0("MOV AL, 0xff" );
3435 outline1("MOV [%s], AL", _other );
3436 outline1("JMP %sdone", label );
3437
3438 outhead1("%sagb:", label );
3439 outline0("MOV AL, 0x00" );
3440 outline1("MOV [%s], AL", _other );
3441 outline1("JMP %sdone", label );
3442
3443 outhead1("%sdone:", label );
3444
3446
3447}
3448
3449void cpu_mem_move( Environment * _environment, char *_source, char *_destination, char *_size ) {
3450
3451 deploy( duff, src_hw_8086_duff_asm );
3452
3453 outline1("MOV SI, [%s]", _source);
3454 outline1("MOV DI, [%s]", _destination);
3455 outline1("MOV CL, [%s]", _size);
3456 outline0("MOV CH, 0");
3457 outline0("CALL DUFFDEVICE");
3458
3459}
3460
3461void cpu_mem_move_16bit( Environment * _environment, char *_source, char *_destination, char *_size ) {
3462
3463 deploy( duff, src_hw_8086_duff_asm );
3464
3465 outline1("MOV SI, [%s]", _source);
3466 outline1("MOV DI, [%s]", _destination);
3467 outline1("MOV CX, [%s]", _size);
3468 outline0("CALL DUFFDEVICE");
3469
3470}
3471
3472void cpu_mem_move_direct( Environment * _environment, char *_source, char *_destination, char *_size ) {
3473
3474 deploy( duff, src_hw_8086_duff_asm );
3475
3476 outline1("MOV SI, %s", _source);
3477 outline1("MOV DI, %s", _destination);
3478 outline1("MOV CL, [%s]", _size);
3479 outline0("MOV CH, 0");
3480 outline0("CALL DUFFDEVICE");
3481
3482}
3483
3484void cpu_mem_move_direct2( Environment * _environment, char *_source, char *_destination, char *_size ) {
3485
3486 deploy( duff, src_hw_8086_duff_asm );
3487
3488 outline1("MOV SI, %s", _source);
3489 outline1("MOV DI, %s", _destination);
3490 outline1("MOV CX, [%s]", _size);
3491 outline0("CALL DUFFDEVICE");
3492
3493}
3494
3495void cpu_mem_move_direct2_size( Environment * _environment, char *_source, char *_destination, int _size ) {
3496
3497 deploy( duff, src_hw_8086_duff_asm );
3498
3499 outline1("MOV SI, [%s]", _source);
3500 outline1("MOV DI, %s", _destination);
3501 outline1("MOV CX, 0x%4.4x", _size );
3502 outline0("CALL DUFFDEVICE");
3503
3504}
3505
3506void cpu_mem_move_size( Environment * _environment, char *_source, char *_destination, int _size ) {
3507
3508 if ( _size > 0 ) {
3509
3510 deploy( duff, src_hw_8086_duff_asm );
3511
3512 outline1("MOV SI, [%s]", _source);
3513 outline1("MOV DI, [%s]", _destination);
3514 outline1("MOV CX, 0x%4.4x", _size );
3515 outline0("CALL DUFFDEVICE");
3516
3517 }
3518
3519}
3520
3521void cpu_mem_move_direct_size( Environment * _environment, char *_source, char *_destination, int _size ) {
3522
3523 if ( _size > 0 ) {
3524
3525 deploy( duff, src_hw_8086_duff_asm );
3526
3527 outline1("MOV SI, %s", _source);
3528 outline1("MOV DI, %s", _destination);
3529 outline1("MOV CX, 0x%4.4x", _size );
3530 outline0("CALL DUFFDEVICE");
3531
3532 }
3533
3534}
3535
3536void cpu_mem_move_direct_indirect_size( Environment * _environment, char *_source, char *_destination, int _size ) {
3537
3538 if ( _size ) {
3539
3540 deploy( duff, src_hw_8086_duff_asm );
3541
3542 outline1("MOV SI, %s", _source);
3543 outline1("MOV DI, [%s]", _destination);
3544 outline1("MOV CX, 0x%4.4x", _size );
3545 outline0("CALL DUFFDEVICE");
3546
3547 }
3548
3549}
3550
3551void cpu_mem_move_indirect_direct_size( Environment * _environment, char *_source, char *_destination, int _size ) {
3552
3553 if ( _size ) {
3554
3555 deploy( duff, src_hw_8086_duff_asm );
3556
3557 outline1("MOV SI, [%s]", _source);
3558 outline1("MOV DI, %s", _destination);
3559 outline1("MOV CX, 0x%4.4x", _size );
3560 outline0("CALL DUFFDEVICE");
3561
3562 }
3563
3564}
3565
3566void cpu_compare_memory( Environment * _environment, char *_source, char *_destination, char *_size, char * _result, int _equal ) {
3567
3569
3570 outline1("MOV SI, [%s]", _source);
3571 outline1("MOV DI, [%s]", _destination);
3572 outline1("MOV CX, [%s]", _size);
3573 outline0("PUSH ES");
3574 outline0("PUSH DX");
3575 outline0("MOV DX, DS");
3576 outline0("MOV ES, DX");
3577 outline0("POP DX");
3578 outline0("CLD");
3579 outline0("REPE CMPSB");
3580 outline0("POP ES");
3581
3582 outline1("JNE %sdiff", label);
3583 outhead1("%sequal:", label );
3584 outline1("MOV AL, 0x%2.2x", _equal ? 255 : 0 );
3585 outline1("MOV [%s], AL", _result );
3586 outline1("JMP %sfinal", label );
3587 outhead1("%sdiff:", label );
3588 outline1("MOV AL, 0x%2.2x", _equal ? 0 : 255 );
3589 outline1("MOV [%s], AL", _result );
3590 outhead1("%sfinal:", label );
3591
3592}
3593
3594void cpu_compare_memory_size( Environment * _environment, char *_source, char *_destination, int _size, char * _result, int _equal ) {
3595
3597
3598 outline1("MOV SI, [%s]", _source);
3599 outline1("MOV DI, [%s]", _destination);
3600 outline1("MOV CX, 0x%4.4x", (unsigned short)(_size&0xffff));
3601 outline0("PUSH ES");
3602 outline0("PUSH DX");
3603 outline0("MOV DX, DS");
3604 outline0("MOV ES, DX");
3605 outline0("POP DX");
3606 outline0("CLD");
3607 outline0("REPE CMPSB");
3608 outline0("POP ES");
3609
3610 outline1("JNE %sdiff", label);
3611 outhead1("%sequal:", label );
3612 outline1("MOV AL, 0x%2.2x", _equal ? 255 : 0 );
3613 outline1("MOV [%s], AL", _result );
3614 outline1("JMP %sfinal", label );
3615 outhead1("%sdiff:", label );
3616 outline1("MOV AL, 0x%2.2x", _equal ? 0 : 255 );
3617 outline1("MOV [%s], AL", _result );
3618 outhead1("%sfinal:", label );
3619
3620 // comparazione:
3621 // cmpsb ; Confronta [SI] con [DI]
3622 // ja string_maggiore ; Salta se il primo byte è maggiore (no carry)
3623 // jb string_minore ; Salta se il primo byte è minore (carry)
3624
3625 // loop comparazione ; Ripeti il ciclo se i byte sono uguali
3626
3627}
3628
3629void cpu_less_than_memory( Environment * _environment, char *_source, char *_destination, char *_size, char * _result, int _equal ) {
3630
3632
3633 char greaterLabel[MAX_TEMPORARY_STORAGE];
3634 sprintf( greaterLabel, "%sgt", label );
3635 char lesserLabel[MAX_TEMPORARY_STORAGE];
3636 sprintf( lesserLabel, "%slt", label );
3637
3638 outline1("MOV SI, [%s]", _source);
3639 outline1("MOV DI, [%s]", _destination);
3640 outline1("MOV CX, %s]", _size);
3641 outline0("PUSH ES");
3642 outline0("PUSH DX");
3643 outline0("MOV DX, DS");
3644 outline0("MOV ES, DX");
3645 outline0("POP DX");
3646 outline0("CLD");
3647
3648 outhead1("%s:", label);
3649 outline0("CMPSB");
3650 if ( !_equal ) {
3651 outline1("JAE %s", greaterLabel);
3652 } else {
3653 outline1("JA %s", greaterLabel);
3654 }
3655 outline1("LOOP %s", label );
3656 outline0("POP ES");
3657
3658 outline0("MOV AL, 0xff");
3659 outline1("JMP %s", label);
3660
3661 outhead1("%s:", greaterLabel );
3662 outline0("MOV AL, 0");
3663 outhead1("%s:", label );
3664
3665}
3666
3667void cpu_less_than_memory_size( Environment * _environment, char *_source, char *_destination, int _size, char * _result, int _equal ) {
3668
3670
3671 char greaterLabel[MAX_TEMPORARY_STORAGE];
3672 sprintf( greaterLabel, "%sgt", label );
3673 char lesserLabel[MAX_TEMPORARY_STORAGE];
3674 sprintf( lesserLabel, "%slt", label );
3675
3676 outline1("MOV SI, [%s]", _source);
3677 outline1("MOV DI, [%s]", _destination);
3678 outline1("MOV CX, 0x%4.4x", (unsigned short)(_size&0xffff));
3679 outline0("PUSH ES");
3680 outline0("PUSH DX");
3681 outline0("MOV DX, DS");
3682 outline0("MOV ES, DX");
3683 outline0("POP DX");
3684 outline0("CLD");
3685
3686 outhead1("%s:", label);
3687 outline0("CMPSB");
3688 if ( !_equal ) {
3689 outline1("JAE %s", greaterLabel);
3690 } else {
3691 outline1("JA %s", greaterLabel);
3692 }
3693 outline1("LOOP %s", label );
3694
3695 outline0("MOV AL, 0xff");
3696 outline1("JMP %s", label);
3697 outline0("POP ES");
3698
3699 outhead1("%s:", greaterLabel );
3700 outline0("MOV AL, 0");
3701 outhead1("%s:", label );
3702
3703}
3704
3705void cpu_greater_than_memory( Environment * _environment, char *_source, char *_destination, char *_size, char * _result, int _equal ) {
3706
3707 cpu_less_than_memory( _environment, _source, _destination, _size, _result, !_equal );
3708 cpu_not_8bit( _environment, _result, _result );
3709
3710}
3711
3712void cpu_greater_than_memory_size( Environment * _environment, char *_source, char *_destination, int _size, char * _result, int _equal ) {
3713
3714 cpu_less_than_memory_size( _environment, _source, _destination, _size, _result, !_equal );
3715 cpu_not_8bit( _environment, _result, _result );
3716
3717}
3718
3719void cpu_math_add_16bit_with_8bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
3720
3721 outline1("MOV AX, [%s]", _source );
3722 outline1("MOV BL, [%s]", _destination );
3723 outline0("MOV BH, 0" );
3724 outline0("ADD AX, BX" );
3725 if ( _other ) {
3726 outline1("MOV [%s], AX", _other );
3727 } else {
3728 outline1("MOV [%s], AX", _destination );
3729 }
3730
3731}
3732
3733void cpu_math_sub_16bit_with_8bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
3734
3735 outline1("MOV AX, [%s]", _source );
3736 outline1("MOV BL, [%s]", _destination );
3737 outline0("MOV BH, 0" );
3738 outline0("SUB AX, BX" );
3739 if ( _other ) {
3740 outline1("MOV [%s], AX", _other );
3741 } else {
3742 outline1("MOV [%s], AX", _destination );
3743 }
3744
3745}
3746
3747void cpu_uppercase( Environment * _environment, char *_source, char *_size, char *_result ) {
3748
3750
3751 outline1("MOV CL, [%s]", _size);
3752 outline1("MOV SI, [%s]", _source );
3753 if ( _result ) {
3754 outline1("MOV DI, [%s]", _result );
3755 } else {
3756 outline1("MOV DI, [%s]", _source );
3757 }
3758 outhead1("%supper:", label );
3759 outline0("MOV AL, [SI]" );
3760
3761 outline0("CMP AL, 97");
3762 outline1("JC %snext", label);
3763
3764 outline0("CMP AL, 122");
3765 outline1("JNC %snext", label);
3766
3767 outline0("SUB AL, 32");
3768 outline0("MOV [DI], AL" );
3769 outline1("JMP %sdone", label );
3770
3771 outhead1("%snext:", label );
3772 outline0("MOV [DI], AL" );
3773
3774 outhead1("%sdone:", label );
3775 outline0("INC SI" );
3776 outline0("INC DI" );
3777 outline0("DEC CX" );
3778 outline0("CMP CX, 0" );
3779 outline1("JNZ %supper", label);
3780
3781}
3782
3783void cpu_lowercase( Environment * _environment, char *_source, char *_size, char *_result ) {
3784
3786
3787 outline1("MOV CL, [%s]", _size);
3788 outline1("MOV SI, [%s]", _source );
3789 if ( _result ) {
3790 outline1("MOV DI, [%s]", _result );
3791 } else {
3792 outline1("MOV DI, [%s]", _source );
3793 }
3794 outhead1("%slower:", label );
3795 outline0("MOV AL, [SI]" );
3796
3797 outline0("CMP AL, 65");
3798 outline1("JC %snext", label);
3799
3800 outline0("CMP AL, 91");
3801 outline1("JNC %snext", label);
3802
3803 outline0("SUB AL, 32");
3804 outline0("MOV [DI], AL" );
3805 outline1("JMP %sdone", label );
3806
3807 outhead1("%snext:", label );
3808 outline0("MOV [DI], AL" );
3809
3810 outhead1("%sdone:", label );
3811 outline0("INC SI" );
3812 outline0("INC DI" );
3813 outline0("DEC CX" );
3814 outline0("CMP CX, 0" );
3815 outline1("JNZ %slower", label);
3816
3817}
3818
3819void cpu_convert_string_into_8bit( Environment * _environment, char * _string, char * _len, char * _value ) {
3820
3821 Variable * temp = variable_temporary( _environment, VT_WORD, "(temp)" );
3822 cpu_convert_string_into_16bit( _environment, _string, _len, temp->realName );
3823 cpu_move_8bit( _environment, temp->realName, _value );
3824
3825}
3826
3827void cpu_convert_string_into_16bit( Environment * _environment, char * _string, char * _len, char * _value ) {
3828
3830
3831 embedded( cpu_convert_string_into_16bit, src_hw_8086_cpu_convert_string_into_16bit_asm );
3832
3833 outline1( "MOV SI, %s", _string );
3834 outline1( "MOV CX, [%s]", _len );
3835 outline0( "CALL CONVERTSTRING16BIT" );
3836 outline1( "MOV [%s], AX", _value );
3837
3838 done( )
3839
3840}
3841
3842void cpu_fill_indirect( Environment * _environment, char * _address, char * _size, char * _pattern, int _size_size ) {
3843
3845
3846 // Use the current bitmap address as starting address for filling routine.
3847 outline1("MOV DI, [%s]", _address);
3848 outline1("MOV SI, [%s]", _pattern);
3849
3850 // Fill the bitmap with the given pattern.
3851 if ( _size_size >= 16 ) {
3852 outline1("MOV CX, [%s]", _size);
3853 outhead1("%sx:", label);
3854 outline0("MOV AL, [SI]");
3855 outline0("MOV [DI], AL");
3856 outline0("INC DI");
3857 outline0("DEC CX");
3858 outline0("CMP CX, 0");
3859 outline1("JNZ %sx", label);
3860 } else {
3861 outline1("MOV CL, [%s]", _size);
3862 outline0("MOV CH, 0" );
3863 outhead1("%sx:", label);
3864 outline0("MOV AL, [SI]");
3865 outline0("MOV [DI], AL");
3866 outline0("INC DI");
3867 outline0("CMP CL, 0");
3868 outline1("JNZ %sx", label);
3869 }
3870
3871}
3872
3873void cpu_flip_8bit( Environment * _environment, char * _source, char * _destination ) {
3874
3876
3877 embedded( cpu_flip, src_hw_8086_cpu_flip_asm );
3878
3879 outline1("MOV SI, [%s]", _source);
3880 outline0("MOV AL, [SI]");
3881 outline0("CALL CPUFLIP8");
3882 if ( _destination ) {
3883 outline1("MOV DI, [%s]", _destination);
3884 outline0("MOV [DI], BL");
3885 } else {
3886 outline0("MOV [SI], BL");
3887 }
3888
3889 done( )
3890
3891}
3892
3893void cpu_flip( Environment * _environment, char * _source, char * _size, char * _destination ) {
3894
3896
3897 embedded( cpu_flip, src_hw_8086_cpu_flip_asm );
3898
3899 outline1("MOV SI, [%s]", _source);
3900 outline1("MOV DI, [%s]", _destination);
3901 outline1("MOV CL, [%s]", _size);
3902 outline0("CALL CPUFLIP");
3903
3904 done( )
3905
3906}
3907
3908void cpu_move_8bit_indirect( Environment * _environment, char *_source, char * _value ) {
3909
3910 outline1("MOV DI, [%s]", _value);
3911 outline1("MOV AL, [%s]", _source);
3912 outline0("MOV [DI], AL");
3913
3914}
3915
3916void cpu_move_8bit_with_offset2( Environment * _environment, char *_source, char * _value, char * _offset ) {
3917
3918 outline1("MOV SI, %s", _value);
3919 outline1("MOV AL, [%s]", _offset );
3920 outline0("MOV AH, 0" );
3921 outline0("ADD SI, AX" );
3922 outline1("MOV AL, [%s]", _source);
3923 outline0("MOV [SI], AL");
3924
3925}
3926
3927void cpu_move_8bit_indirect_with_offset( Environment * _environment, char *_source, char * _value, int _offset ) {
3928
3929 outline1("MOV SI, [%s]", _value);
3930 outline1("MOV AX, 0x%2.2x", ( _offset & 0xff ) );
3931 outline0("ADD SI, AX" );
3932 outline1("MOV AL, [%s]", _source);
3933 outline0("MOV [SI], AL");
3934
3935}
3936
3937void cpu_move_8bit_indirect2( Environment * _environment, char * _value, char *_source ) {
3938
3939 outline1("MOV DI, [%s]", _value);
3940 outline0("MOV AL, [DI]");
3941 outline1("MOV [%s], AL", _source);
3942
3943}
3944
3945void cpu_move_8bit_indirect2_8bit( Environment * _environment, char * _value, char * _offset, char *_source ) {
3946
3947 outline1("MOV SI, %s", _value);
3948 outline1("MOV AL, [%s]", _offset);
3949 outline0("MOV AH, 0");
3950 outline0("ADD SI, AX");
3951 outline0("MOV AL, [SI]");
3952 outline1("MOV [%s], AL", _source );
3953
3954}
3955
3956void cpu_move_8bit_indirect2_16bit( Environment * _environment, char * _value, char * _offset, char *_source ) {
3957
3958 outline1("MOV SI, %s", _value);
3959 outline1("MOV AX, [%s]", _offset);
3960 outline0("ADD SI, AX");
3961 outline0("MOV AL, [SI]");
3962 outline1("MOV [%s], AL", _source );
3963
3964}
3965
3966void cpu_move_16bit_indirect( Environment * _environment, char *_source, char * _value ) {
3967
3968 outline1("MOV DI, [%s]", _value);
3969 outline1("MOV AX, [%s]", _source);
3970 outline0("MOV [DI], AX");
3971
3972}
3973
3974void cpu_move_16bit_indirect2( Environment * _environment, char * _value, char *_source ) {
3975
3976 outline1("MOV DI, [%s]", _value);
3977 outline0("MOV AX, [DI]");
3978 outline1("MOV [%s], AX", _source);
3979
3980}
3981
3982void cpu_move_16bit_indirect2_8bit( Environment * _environment, char * _value, char * _offset, char *_source ) {
3983
3984 outline1("MOV SI, %s", _value);
3985 outline1("MOV AL, [%s]", _offset);
3986 outline0("MOV AH, 0");
3987 outline0("ADD SI, AX");
3988 outline0("ADD SI, AX");
3989 outline0("MOV AX, [SI]");
3990 outline1("MOV [%s], AX", _source );
3991
3992}
3993
3994void cpu_move_32bit_indirect( Environment * _environment, char *_source, char * _value ) {
3995
3996 outline1("MOV DI, [%s]", _value);
3997 outline1("MOV AX, [%s]", _source);
3998 outline0("MOV [DI], AX");
3999 outline0("INC DI");
4000 outline0("INC DI");
4001 outline1("MOV AX, [%s]", address_displacement(_environment, _source, "2"));
4002 outline0("MOV [DI], AX");
4003
4004}
4005
4006void cpu_move_nbit_indirect( Environment * _environment, int _n, char *_source, char * _value ) {
4007
4008 outline1("MOV DI, [%s]", _value);
4009
4010 char step[MAX_TEMPORARY_STORAGE];
4011 char step2[MAX_TEMPORARY_STORAGE];
4012
4013 int stepIndex = 0;
4014 while( _n ) {
4015 sprintf( step, "%d", stepIndex );
4016 sprintf( step2, "%d", stepIndex+2 );
4017 if ( _n >= 32 ) {
4018 outline1("MOV AX, [%s]", address_displacement(_environment, _source, step));
4019 outline0("MOV [DI], AX");
4020 outline0("INC DI");
4021 outline0("INC DI");
4022 outline1("MOV AX, [%s]", address_displacement(_environment, _source, step2));
4023 outline0("MOV [DI], AX");
4024 outline0("INC DI");
4025 outline0("INC DI");
4026 stepIndex += 4;
4027 _n -= 32;
4028 } else {
4029 switch( _n ) {
4030 case 32: case 31: case 30: case 29:
4031 case 28: case 27: case 26: case 25:
4032 outline1("MOV AX, [%s]", address_displacement(_environment, _source, step));
4033 outline0("MOV [DI], AX");
4034 outline0("INC DI");
4035 outline0("INC DI");
4036 outline1("MOV AX, [%s]", address_displacement(_environment, _source, step2));
4037 outline0("MOV [DI], AX");
4038 outline0("INC DI");
4039 outline0("INC DI");
4040 break;
4041 case 24: case 23: case 22: case 21:
4042 case 20: case 19: case 18: case 17:
4043 outline1("MOV AX, [%s]", address_displacement(_environment, _source, step));
4044 outline0("MOV [DI], AX");
4045 outline0("INC DI");
4046 outline0("INC DI");
4047 outline1("MOV AL, [%s]", address_displacement(_environment, _source, step2));
4048 outline0("MOV [DI], AL");
4049 outline0("INC DI");
4050 break;
4051 case 16: case 15: case 14: case 13:
4052 case 12: case 11: case 10: case 9:
4053 outline1("MOV AX, [%s]", address_displacement(_environment, _source, step));
4054 outline0("MOV [DI], AX");
4055 outline0("INC DI");
4056 outline0("INC DI");
4057 break;
4058 case 8: case 7: case 6: case 5:
4059 case 4: case 3: case 2: case 1:
4060 outline1("MOV AL, [%s]", address_displacement(_environment, _source, step2));
4061 outline0("MOV [DI], AL");
4062 outline0("INC DI");
4063 break;
4064 }
4065 _n = 0;
4066 }
4067 }
4068
4069}
4070
4071void cpu_move_32bit_indirect2( Environment * _environment, char * _value, char *_source ) {
4072
4073 outline1("MOV DI, [%s]", _value);
4074 outline0("MOV AX, [DI]");
4075 outline1("MOV [%s], AX", _source);
4076 outline0("INC DI");
4077 outline0("INC DI");
4078 outline0("MOV AX, [DI]");
4079 outline1("MOV [%s], AX", address_displacement( _environment, _source, "2" ) );
4080
4081}
4082
4083void cpu_move_nbit_indirect2( Environment * _environment, int _n, char * _value, char *_source ) {
4084
4085 outline1("MOV DI, [%s]", _value);
4086
4087 char step[MAX_TEMPORARY_STORAGE];
4088 char step2[MAX_TEMPORARY_STORAGE];
4089
4090 int stepIndex = 0;
4091 while( _n ) {
4092 sprintf( step, "%d", stepIndex );
4093 sprintf( step2, "%d", stepIndex+2 );
4094 if ( _n >= 32 ) {
4095 outline0("MOV AX, [DI]");
4096 outline1("MOV [%s], AX", address_displacement( _environment, _source, step ) );
4097 outline0("INC DI");
4098 outline0("INC DI");
4099 outline0("MOV AX, [DI]");
4100 outline1("MOV [%s], AX", address_displacement( _environment, _source, step2 ) );
4101 outline0("INC DI");
4102 outline0("INC DI");
4103 stepIndex += 4;
4104 _n -= 32;
4105 } else {
4106 switch( _n ) {
4107 case 32: case 31: case 30: case 29:
4108 case 28: case 27: case 26: case 25:
4109 outline0("MOV AX, [DI]");
4110 outline1("MOV [%s], AX", address_displacement( _environment, _source, step ) );
4111 outline0("INC DI");
4112 outline0("INC DI");
4113 outline0("MOV AX, [DI]");
4114 outline1("MOV [%s], AX", address_displacement( _environment, _source, step2 ) );
4115 outline0("INC DI");
4116 outline0("INC DI");
4117 break;
4118 case 24: case 23: case 22: case 21:
4119 case 20: case 19: case 18: case 17:
4120 outline0("MOV AX, [DI]");
4121 outline1("MOV [%s], AX", address_displacement( _environment, _source, step ) );
4122 outline0("INC DI");
4123 outline0("INC DI");
4124 outline0("MOV AL, [DI]");
4125 outline1("MOV [%s], AL", address_displacement( _environment, _source, step2 ) );
4126 outline0("INC DI");
4127 break;
4128 case 16: case 15: case 14: case 13:
4129 case 12: case 11: case 10: case 9:
4130 outline0("MOV AX, [DI]");
4131 outline1("MOV [%s], AX", address_displacement( _environment, _source, step ) );
4132 outline0("INC DI");
4133 outline0("INC DI");
4134 break;
4135 case 8: case 7: case 6: case 5:
4136 case 4: case 3: case 2: case 1:
4137 outline0("MOV AL, [DI]");
4138 outline1("MOV [%s], AL", address_displacement( _environment, _source, step ) );
4139 outline0("INC DI");
4140 break;
4141 }
4142 _n = 0;
4143 }
4144 }
4145
4146}
4147
4148void cpu_math_div_32bit_to_16bit( Environment * _environment, char *_source, char *_destination, char *_other, char * _other_remainder, int _signed ) {
4149
4151
4152 outline1( "MOV DX, [%s]", address_displacement( _environment, _source, "+2" ) );
4153 outline1( "MOV AX, [%s]", _source );
4154 outline1( "MOV BX, [%s]", _destination );
4155
4156 if ( _signed ) {
4157 outline0( "IDIV BX" );
4158 } else {
4159 outline0( "DIV BX" );
4160 }
4161
4162 outline1("MOV [%s], DX", _other_remainder);
4163 outline1("MOV [%s], AX", _other);
4164
4165}
4166
4167void cpu_math_div_32bit_to_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, char * _other_remainder, int _signed ) {
4168
4170
4171 outline1( "MOV DX, [%s]", address_displacement( _environment, _source, "+2" ) );
4172 outline1( "MOV AX, [%s]", _source );
4173 outline1( "MOV BX, 0x%4.4x", _destination );
4174
4175 if ( _signed ) {
4176 outline0( "IDIV BX" );
4177 } else {
4178 outline0( "DIV BX" );
4179 }
4180
4181 outline1("MOV [%s], DX", _other_remainder);
4182 outline1("MOV [%s], AX", _other);
4183
4184}
4185
4186void cpu_math_div_16bit_to_16bit( Environment * _environment, char *_source, char *_destination, char *_other, char * _other_remainder, int _signed ) {
4187
4189
4190 outline0( "MOV DX, 0" );
4191 outline1( "MOV AX, [%s]", _source );
4192 outline1( "MOV BX, [%s]", _destination );
4193
4194 if ( _signed ) {
4195 outline0( "IDIV BX" );
4196 } else {
4197 outline0( "DIV BX" );
4198 }
4199
4200 outline1("MOV [%s], DX", _other_remainder);
4201 outline1("MOV [%s], AX", _other);
4202
4203}
4204
4205void cpu_math_div_16bit_to_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, char * _other_remainder, int _signed ) {
4206
4208
4209 outline0( "MOV DX, 0" );
4210 outline1( "MOV AX, [%s]", _source );
4211 outline1( "MOV BX, 0x%4.4x", (unsigned short)(_destination&0xffff) );
4212
4213 if ( _signed ) {
4214 outline0( "IDIV BX" );
4215 } else {
4216 outline0( "DIV BX" );
4217 }
4218
4219 outline1("MOV [%s], DX", _other_remainder);
4220 outline1("MOV [%s], AX", _other);
4221
4222}
4223
4224void cpu_math_div_8bit_to_8bit( Environment * _environment, char *_source, char *_destination, char *_other, char * _other_remainder, int _signed ) {
4225
4227
4228 outline1( "MOV AX, [%s]", _source );
4229 outline1( "MOV BL, [%s]", _destination );
4230
4231 if ( _signed ) {
4232 outline0( "IDIV BL" );
4233 } else {
4234 outline0( "DIV BL" );
4235 }
4236
4237 outline1("MOV [%s], DX", _other_remainder);
4238 outline1("MOV [%s], AL", _other);
4239
4240}
4241
4242void cpu_math_div_8bit_to_8bit_const( Environment * _environment, char *_source, int _destination, char *_other, char * _other_remainder, int _signed ) {
4243
4245
4246 outline1( "MOV AL, [%s]", _source );
4247 outline1( "MOV BL, 0x%2.2x", (unsigned char)(_destination&0xff) );
4248
4249 if ( _signed ) {
4250 outline0( "IDIV BL" );
4251 } else {
4252 outline0( "DIV BL" );
4253 }
4254
4255 outline1("MOV [%s], DX", _other_remainder);
4256 outline1("MOV [%s], AL", _other);
4257
4258}
4259
4260void cpu_math_div_nbit_to_nbit( Environment * _environment, char *_source, char *_destination, char *_other, char * _other_remainder, int _bits ) {
4261
4263
4264 int i;
4265
4267
4268 char afterLabel[MAX_TEMPORARY_STORAGE]; sprintf( afterLabel, "%safter", label );
4269 char skipLabel[MAX_TEMPORARY_STORAGE]; sprintf( skipLabel, "%sskip", label );
4270 char skip2Label[MAX_TEMPORARY_STORAGE]; sprintf( skip2Label, "%sskipb", label );
4271 char skip3Label[MAX_TEMPORARY_STORAGE]; sprintf( skip3Label, "%sskipc", label );
4272 char skip4Label[MAX_TEMPORARY_STORAGE]; sprintf( skip4Label, "%sskipd", label );
4273 char quotient[MAX_TEMPORARY_STORAGE]; sprintf( quotient, "CPUMATHDIVNBITTONBIT%d_QUOTIENT", _bits >> 3 );
4274 char divisor[MAX_TEMPORARY_STORAGE]; sprintf( divisor, "CPUMATHDIVNBITTONBIT%d_DIVISOR", _bits >> 3 );
4275 char dividend[MAX_TEMPORARY_STORAGE]; sprintf( dividend, "CPUMATHDIVNBITTONBIT%d_DIVIDEND", _bits >> 3 );
4276 char result1[MAX_TEMPORARY_STORAGE]; sprintf( result1, "CPUMATHDIVNBITTONBIT%d_RESULT1", _bits >> 3 );
4277 char result2[MAX_TEMPORARY_STORAGE]; sprintf( result2, "CPUMATHDIVNBITTONBIT%d_RESULT2", _bits >> 3 );
4278 char k[MAX_TEMPORARY_STORAGE]; sprintf( k, "CPUMATHDIVNBITTONBIT%d_K", _bits >> 3 );
4279
4280 if ( ! _environment->cpuOptimization.cpu_math_div_nbit_to_nbit[_bits>>3] ) {
4281
4282 cpu_jump( _environment, afterLabel );
4283
4284 outhead2("%s: times %d db 0", quotient, _bits>>3 );
4285 outhead2("%s: times %d db 0", divisor, _bits>>3 );
4286 outhead2("%s: times %d db 0", dividend, _bits>>3 );
4287 outhead1("%s: db 0", k );
4288 outhead1("%s: db 0", result1 );
4289 outhead1("%s: db 0", result2 );
4290
4291 // public static long div(long dividend, long divisor) {
4292 // long quotient = 0;
4293
4294 outhead1("CPUMATHDIVNBITTONBIT%d:", _bits>>3);
4295 outhead0("MOV AL, 0x00");
4296 for( i=0; i<(_bits>>3); ++i ) {
4297 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
4298 outline1("MOV [%s], AL", address_displacement( _environment, quotient, offset ) );
4299 }
4300
4301 // int k = 0;
4302 cpu_store_8bit( _environment, k, 0 );
4303
4304 // while (divisor <= dividend && divisor > 0) {
4305
4306 cpu_label( _environment, label );
4307 cpu_less_than_nbit( _environment, divisor, dividend, result1, 1, _bits );
4308 cpu_greater_than_nbit_const( _environment, divisor, 0, result2, 0, _bits );
4309 cpu_and_8bit( _environment, result1, result2, result1 );
4310 cpu_compare_and_branch_8bit_const( _environment, result1, 0, skipLabel, 1 );
4311
4312 // divisor <<= 1;
4313
4314 cpu_math_mul2_const_nbit( _environment, divisor, 1, _bits );
4315
4316 // k++;
4317
4318 cpu_inc( _environment, k );
4319
4320 // }
4321
4322 cpu_jump( _environment, label );
4323
4324 cpu_label( _environment, skipLabel );
4325
4326 // while (k-- > 0) {
4327
4328 cpu_greater_than_8bit_const( _environment, k, 0, result1, 0, 1 );
4329 cpu_dec( _environment, k );
4330 cpu_compare_and_branch_8bit_const( _environment, result1, 0, skip2Label, 1 );
4331
4332 // divisor >>= 1;
4333
4334 cpu_math_div2_const_nbit( _environment, divisor, 1, _bits, NULL );
4335
4336 // if (divisor <= dividend) {
4337 cpu_less_than_nbit( _environment, divisor, dividend, result1, 1, _bits );
4338 cpu_compare_and_branch_8bit_const( _environment, result1, 0, skip3Label, 1 );
4339
4340 // dividend -= divisor;
4341
4342 cpu_math_sub_nbit( _environment, dividend, divisor, dividend, _bits );
4343
4344 // quotient = (quotient << 1) + 1;
4345 cpu_math_mul2_const_nbit( _environment, quotient, 1, _bits );
4346 cpu_inc_nbit( _environment, quotient, _bits );
4347
4348 // }
4349 cpu_jump( _environment, skip4Label );
4350 cpu_label( _environment, skip3Label );
4351 // else quotient <<= 1;
4352 cpu_math_mul2_const_nbit( _environment, quotient, 1, _bits );
4353 cpu_label( _environment, skip4Label );
4354 cpu_jump( _environment, skipLabel );
4355
4356 // }
4357 cpu_label( _environment, skip2Label );
4358 // return quotient;
4359 cpu_return( _environment );
4360
4361 cpu_label( _environment, afterLabel );
4362
4363 }
4364
4365 for( i=0; i<(_bits>>3); ++i ) {
4366 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
4367 outline1("MOV AL, [%s]", address_displacement( _environment, _source, offset ) );
4368 outline1("MOV [%s], AL", address_displacement( _environment, dividend, offset ) );
4369 outline1("MOV AL, [%s]", address_displacement( _environment, _destination, offset ) );
4370 outline1("MOV [%s], AL", address_displacement( _environment, divisor, offset ) );
4371 }
4372 outline1("CALL CPUMATHDIVNBITTONBIT%d", _bits>>3);
4373
4374 for( i=0; i<(_bits>>3); ++i ) {
4375 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
4376 if ( _other ) {
4377 outline1("MOV AL, [%s]", address_displacement( _environment, quotient, offset ) );
4378 outline1("MOV [%s], AL", address_displacement( _environment, _other, offset ) );
4379 } else {
4380 outline1("MOV AL, [%s]", address_displacement( _environment, quotient, offset ) );
4381 outline1("MOV [%s], AL", address_displacement( _environment, _destination, offset ) );
4382 }
4383 }
4384
4385 // }
4387
4388}
4389
4390void cpu_math_div_nbit_to_nbit_const( Environment * _environment, char *_source, int _destination, char *_other, char * _other_remainder, int _bits ) {
4391
4393
4394 int i;
4395
4397
4398 char afterLabel[MAX_TEMPORARY_STORAGE]; sprintf( afterLabel, "%safter", label );
4399 char data[MAX_TEMPORARY_STORAGE]; sprintf( data, "CPUMATHDIVNBITTONBITCONST%d_DATA", _bits >> 3 );
4400
4401 if ( ! _environment->cpuOptimization.cpu_math_div_nbit_to_nbit_const[_bits>>3] ) {
4402
4403 cpu_jump( _environment, afterLabel );
4404
4405 outhead2("%s: times %d db 0", data, _bits>>3 );
4406
4407 cpu_label( _environment, afterLabel );
4408
4409 }
4410
4411 for( i=0; i<(_bits>>3); ++i ) {
4412 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
4413 outline1("MOL AL, 0x%2.2x", (unsigned char)( (_destination >> (i*8)) & 0xff ) );
4414 outline1("MOV [%s], AL", address_displacement( _environment, data, offset ) );
4415 }
4416 cpu_math_div_nbit_to_nbit( _environment, _source, data, _other, _other_remainder, _bits );
4417
4418 // }
4420
4421}
4422
4423void cpu_bit_check( Environment * _environment, char *_value, int _position, char * _result, int _bitwidth ) {
4424
4426
4427 embedded( cpu_bit_check_extended, src_hw_8086_cpu_bit_check_extended_asm );
4428
4429 outline1("MOV DI, %s", _value);
4430 outline1("MOV AL, 0x%2.2x", _position );
4431 outline0("CALL CPUBITCHECKEXTENDED" );
4432
4433 if ( _result ) {
4434 outline1("MOV [%s], AL", _result);
4435 }
4436
4437 done( )
4438
4439}
4440
4441void cpu_bit_check_extended( Environment * _environment, char *_value, char * _position, char * _result, int _bitwidth ) {
4442
4444
4446
4447 embedded( cpu_bit_check_extended, src_hw_8086_cpu_bit_check_extended_asm );
4448
4449 outline1("MOV DI, %s", _value);
4450 outline1("MOV AL, [%s]", _position );
4451 outline0("CALL CPUBITCHECKEXTENDED" );
4452
4453 if ( _result ) {
4454 outline1("MOV [%s], AL", _result);
4455 }
4456
4457 done( )
4458
4459}
4460
4461void cpu_bit_inplace_8bit( Environment * _environment, char * _value, int _position, int * _bit ) {
4462
4463 _environment->bitmaskNeeded = 1;
4464
4466
4467 no_inline( cpu_bit_inplace )
4468
4469 embedded( cpu_bit_inplace, src_hw_8086_cpu_bit_inplace_asm );
4470
4471 if ( _bit ) {
4472 if ( * _bit ) {
4473 outline0("MOV AL, 0xff" );
4474 } else {
4475 outline0("MOV AL, 0x0" );
4476 }
4477 outline0("SAL AL, 1" );
4478 }
4479 outline1("MOV DI, %s", _value );
4480 outline1("MOV AL, 0x%2.2x", _position);
4481 outline0("CALL CPUBITINPLACE");
4482
4483 done( )
4484
4485}
4486
4487void cpu_bit_inplace_8bit_extended_indirect( Environment * _environment, char * _address, char * _position, char * _bit ) {
4488
4489 _environment->bitmaskNeeded = 1;
4490
4492
4493 no_inline( cpu_bit_inplace )
4494
4495 embedded( cpu_bit_inplace, src_hw_8086_cpu_bit_inplace_asm );
4496
4497 if ( _bit ) {
4498 outline1("MOV AL, [%s]", _bit );
4499 outline0("CMP AL, 0" );
4500 outline1("JZ %s", label );
4501 outline0("MOV AL, 1" );;
4502 outline0("SAL AL, 1" );
4503 outhead1("%s:", label );
4504 }
4505 outline1("MOV DI, [%s]", _address );
4506 outline1("MOV AL, [%s]", _position);
4507 outline0("CALL CPUBITINPLACE");
4508
4509 done( )
4510
4511}
4512
4514
4515 // variable_import( _environment, "N2DINV", VT_BUFFER, _environment->numberConfig.maxBytes );
4516 // variable_import( _environment, "N2DBUF", VT_BUFFER, _environment->numberConfig.maxDigits );
4517 // variable_import( _environment, "N2DEND", VT_BUFFER, 1 );
4518
4519}
4520
4521void cpu_number_to_string( Environment * _environment, char * _number, char * _string, char * _string_size, int _bits, int _signed ) {
4522
4524
4525 deploy_with_vars( numberToString, src_hw_8086_number_to_string_asm, cpu_number_to_string_vars );
4526
4527 outline0("MOV BL, 0");
4528 switch( _bits ) {
4529 case 8:
4530 outline1("MOV AL, [%s]", _number);
4531 outline0("MOV [N2DINV], AL");
4532 if ( _signed ) {
4533 outline0("AND AL, 0x80");
4534 outline0("CMP AL, 0");
4535 outline1("JZ %sp81", label);
4536 cpu_complement2_8bit( _environment, "N2DINV", NULL );
4537 outline0("MOV BL, 0xff");
4538 outhead1("%sp81:", label);
4539 }
4540 break;
4541 case 16:
4542 outline1("MOV AX, [%s]", _number);
4543 outline0("MOV [N2DINV], AX");
4544 if ( _signed ) {
4545 outline0("AND AH, 0x80");
4546 outline0("CMP AH, 0");
4547 outline1("JZ %sp81", label);
4548 cpu_complement2_16bit( _environment, "N2DINV", NULL );
4549 outline0("MOV BL, 0xff");
4550 outhead1("%sp81:", label);
4551 }
4552 break;
4553 case 32:
4554 outline1("MOV AX, [%s]", _number);
4555 outline0("MOV [N2DINV], AX");
4556 outline1("MOV AX, [%s]", address_displacement(_environment, _number, "2"));
4557 outline0("MOV [N2DINV+2], HL");
4558 if ( _signed ) {
4559 outline0("AND AH, 0x80");
4560 outline0("CMP AH, 0");
4561 outline1("JZ %sp81", label);
4562 cpu_complement2_32bit( _environment, "N2DINV", NULL );
4563 outline0("MOV BL, 0xff");
4564 outhead1("%sp81:", label);
4565 }
4566 break;
4567 default:
4568 cpu_mem_move_direct_size( _environment, _number, "N2DINV", _bits >> 3 );
4569 if ( _signed ) {
4570 outline1("MOV AL, [N2DINV+%d]", (_bits >> 3)-1 );
4571 outline0("AND AL, 0x80");
4572 outline0("CMP AL, 0");
4573 outline1("JZ %sp81", label);
4574 cpu_complement2_nbit( _environment, "N2DINV", NULL, _bits );
4575 outline0("MOV BL, 0xff");
4576 outhead1("%sp81:", label);
4577 }
4578 break;
4579 case 0:
4580 CRITICAL_DEBUG_UNSUPPORTED( _number, "unknown");
4581 }
4582
4583 outline1("MOV SI, [%s]", _string);
4584 outline0("CALL NUMBERTOSTRINGSIGNED");
4585 outline1("MOV [%s], AL", _string_size);
4586
4587}
4588
4589void cpu_bits_to_string_vars( Environment * _environment ) {
4590
4591 // variable_import( _environment, "BINSTRBUF", VT_BUFFER, 32 );
4592 variable_import( _environment, "BINTOSTRDIGIT0", VT_BYTE, '0' );
4593 variable_import( _environment, "BINTOSTRDIGIT1", VT_BYTE, '1' );
4594}
4595
4596void cpu_bits_to_string( Environment * _environment, char * _number, char * _string, char * _string_size, int _bits, char * _zero, char * _one ) {
4597
4598 deploy_with_vars( bitsToString,src_hw_8086_bits_to_string_asm, cpu_bits_to_string_vars );
4599
4600 if ( _zero ) {
4601 outline1("MOV AL, [%s]", _zero);
4602 } else {
4603 outline0("MOV AL, '0'" );
4604 }
4605 outline0("MOV [BINTOSTRDIGIT0], AL" );
4606
4607 if ( _one ) {
4608 outline1("MOV AL, [%s]", _one);
4609 } else {
4610 outline0("MOV AL, '1'" );
4611 }
4612 outline0("MOV [BINTOSTRDIGIT1], AL" );
4613
4614 switch( _bits ) {
4615 case 32:
4616 outline1("MOV AX, [%s]", address_displacement(_environment, _number, "2") );
4617 outline1("MOV BX, [%s]", _number );
4618 break;
4619 case 16:
4620 outline0("MOV AX, 0" );
4621 outline1("MOV BX, [%s]", _number );
4622 break;
4623 case 8:
4624 outline0("MOV AX, 0" );
4625 outline0("MOV BH, 0" );
4626 outline1("MOV BL, [%s]", _number );
4627 break;
4628 }
4629
4630 outline1("MOV DI, [%s]", _string);
4631 outline0("CALL BINSTR");
4632
4633 outline1("MOV AL, 0x%2.2x", ( _bits & 0xff ) );
4634 outline1("MOV [%s], AL", _string_size );
4635
4636}
4637
4638void cpu_hex_to_string_calc_string( Environment * _environment, char * _size, int _separator, char * _string_size ) {
4639
4641
4642 outline1("MOV AL, [%s]", _size );
4643 outline0("MOV AH, 0" );
4644 outline1("MOV BL, 0X%2.2x", 2 + (_separator?1:0));
4645 outline0("MOV BH, 0" );
4646 outline0("IMUL BX" );
4647 outline1("MOV [%s], AL", _string_size );
4648
4649}
4650
4651void cpu_hex_to_string_calc_string_size( Environment * _environment, int _size, int _separator, char * _string_size ) {
4652
4654
4655 outline1("MOV AL, $%2.2x", (unsigned char)(_size&0xff) );
4656 outline0("MOV AH, 0" );
4657 outline1("MOV BL, 0X%2.2x", 2 + (_separator?1:0));
4658 outline0("MOV BH, 0" );
4659 outline0("IMUL BX" );
4660 outline1("MOV [%s], AL", _string_size );
4661
4662}
4663
4664void cpu_hex_to_string( Environment * _environment, char * _number, char * _string, char * _size, int _separator ) {
4665
4667
4668 inline( cpu_hex_to_string )
4669
4670 embedded( cpu_hex_to_string, src_hw_8086_cpu_hex_to_string_asm );
4671
4672 outline1("MOV BL, 0x%2.2x", (unsigned char)(_separator));
4673 outline1("MOV CL, [%s]", _size );
4674 outline1("MOV SI, [%s]", _number );
4675 outline1("MOV DI, [%s]", _string );
4676 outline0("CALL H2STRING" );
4677
4678 done()
4679
4680}
4681
4682void cpu_encrypt( Environment * _environment, char * _data, char * _data_size, char * _key, char * _key_size, char * _output ) {
4683
4684 deploy( encrypt, src_hw_8086_encrypt_asm );
4685
4686 outline1("MOV SI, (%s)", _data );
4687 outline1("MOV DX, (%s)", _key );
4688 outline1("MOV DI, (%s)", _output );
4689 outline1("MOV CH, (%s)", _key_size );
4690 outline1("MOV CL, (%s)", _data_size );
4691 outline0("CALL ENCRYPT" );
4692
4693}
4694
4695void cpu_decrypt( Environment * _environment, char * _data, char * _data_size, char * _key, char * _key_size, char * _output, char * _result ) {
4696
4697 deploy( decrypt, src_hw_8086_decrypt_asm );
4698
4699 outline1("MOV SI, (%s)", _data );
4700 outline1("MOV DX, (%s)", _key );
4701 outline1("MOV DI, (%s)", _output );
4702 outline1("MOV CH, (%s)", _key_size );
4703 outline1("MOV CL, (%s)", _data_size );
4704 outline0("CALL DECRYPT" );
4705 cpu_ztoa( _environment );
4706 outline1("MOV [%s], AL", _result );
4707
4708}
4709
4710void cpu_dsdefine( Environment * _environment, char * _string, char * _index ) {
4711
4712 deploy( duff, src_hw_8086_duff_asm );
4713 deploy( dstring,src_hw_8086_dstring_asm );
4714
4715 outline1( "MOV SI, %s", _string );
4716 outline0( "CALL DSDEFINE" );
4717 outline1( "MOV [%s], BL", _index );
4718
4719}
4720
4721void cpu_dsalloc( Environment * _environment, char * _size, char * _index ) {
4722
4723 deploy( duff, src_hw_8086_duff_asm );
4724 deploy( dstring,src_hw_8086_dstring_asm );
4725
4726 outline1( "MOV CL, [%s]", _size );
4727 outline0( "CALL DSALLOC" );
4728 outline1( "MOV [%s], BL", _index );
4729
4730}
4731
4732void cpu_dsalloc_size( Environment * _environment, int _size, char * _index ) {
4733
4734 deploy( duff, src_hw_8086_duff_asm );
4735 deploy( dstring,src_hw_8086_dstring_asm );
4736
4737 outline1( "MOV CL, 0x%2.2x", ( _size & 0xff ) );
4738 outline0( "CALL DSALLOC" );
4739 outline1( "MOV [%s], BL", _index );
4740
4741}
4742
4743void cpu_dsfree( Environment * _environment, char * _index ) {
4744
4745 deploy( duff, src_hw_8086_duff_asm );
4746 deploy( dstring,src_hw_8086_dstring_asm );
4747
4748 outline1( "MOV BL, [%s]", _index );
4749 outline0( "CALL DSFREE" );
4750
4751}
4752
4753void cpu_dswrite( Environment * _environment, char * _index ) {
4754
4755 deploy( duff, src_hw_8086_duff_asm );
4756 deploy( dstring,src_hw_8086_dstring_asm );
4757
4758 outline1( "MOV BL, [%s]", _index );
4759 outline0( "CALL DSWRITE" );
4760
4761}
4762
4763void cpu_dsresize( Environment * _environment, char * _index, char * _resize ) {
4764
4765 deploy( duff, src_hw_8086_duff_asm );
4766 deploy( dstring,src_hw_8086_dstring_asm );
4767
4768 outline1( "MOV BL, [%s]", _index );
4769 outline1( "MOV CL, [%s]", _resize );
4770 outline0( "CALL DSRESIZE" );
4771
4772}
4773
4774void cpu_dsresize_size( Environment * _environment, char * _index, int _resize ) {
4775
4776 deploy( duff, src_hw_8086_duff_asm );
4777 deploy( dstring,src_hw_8086_dstring_asm );
4778
4779 outline1( "MOV BL, [%s]", _index );
4780 outline1( "MOV CL, 0x%2.2x", ( _resize & 0xff ) );
4781 outline0( "CALL DSRESIZE" );
4782
4783}
4784
4785void cpu_dsgc( Environment * _environment ) {
4786
4787 deploy( duff, src_hw_8086_duff_asm );
4788 deploy( dstring,src_hw_8086_dstring_asm );
4789
4790 outline0( "CALL DSGC" );
4791
4792}
4793
4794void cpu_dsinit( Environment * _environment ) {
4795
4796 deploy( duff, src_hw_8086_duff_asm );
4797 deploy( dstring,src_hw_8086_dstring_asm );
4798
4799 outline0( "CALL DSINIT" );
4800
4801}
4802
4803void cpu_dsdescriptor( Environment * _environment, char * _index, char * _address, char * _size ) {
4804
4805 deploy( duff, src_hw_8086_duff_asm );
4806 deploy( dstring,src_hw_8086_dstring_asm );
4807
4808 if ( _address || _size ) {
4809 outline1( "MOV BL, [%s]", _index );
4810 outline0( "CALL DSDESCRIPTOR" );
4811 if ( _size ) {
4812 outline0( "MOV AL, [DI]" );
4813 outline1( "MOV [%s], AL", _size );
4814 }
4815 if ( _address ) {
4816 outline0( "MOV DX, [DI+1]" );
4817 outline1( "MOV [%s], DX", _address );
4818 }
4819 }
4820
4821}
4822
4823void cpu_dsassign( Environment * _environment, char * _original, char * _copy ) {
4824
4825 deploy_preferred( duff, src_hw_8086_duff_asm );
4826 deploy( dstring,src_hw_8086_dstring_asm );
4827
4828 outline1( "MOV AL, [%s]", _original );
4829 outline1( "MOV BL, [%s]", _copy );
4830 outline0( "CALL DSASSIGN" );
4831 outline1( "MOV [%s], BL", _copy );
4832
4833}
4834
4835void cpu_dsassign_string( Environment * _environment, char * _string, char * _copy ) {
4836
4837 deploy( duff, src_hw_8086_duff_asm );
4838 deploy( dstring,src_hw_8086_dstring_asm );
4839
4840 outline1( "MOV SI, %s", _string );
4841 outline1( "MOV BL, [%s]", _copy );
4842 outline0( "CALL DSASSIGNSTR" );
4843 outline1( "MOV [%s], BL", _copy );
4844
4845}
4846
4847void cpu_move_8bit_indirect_with_offset2( Environment * _environment, char *_source, char * _value, char * _offset ) {
4848
4849 outline1("MOV DI, [%s]", _value);
4850 outline1("MOV CL, [%s]", _offset );
4851 outline0("MOV CH, 0" );
4852 outline0("ADD DI, CX" );
4853 outline1("MOV AL, [%s]", _source);
4854 outline0("MOV (DI), AL");
4855
4856}
4857
4858void cpu_complement2_8bit( Environment * _environment, char * _source, char * _destination ) {
4859 outline1( "MOV AL, [%s]", _source );
4860 outline0( "XOR AL, 0xff" );
4861 if ( _destination ) {
4862 outline1( "MOV [%s], AL", _destination );
4863 } else {
4864 outline1( "MOV [%s], AL", _source );
4865 }
4866 if ( _destination ) {
4867 cpu_inc( _environment, _destination );
4868 } else {
4869 cpu_inc( _environment, _source );
4870 }
4871}
4872
4873void cpu_complement2_16bit( Environment * _environment, char * _source, char * _destination ) {
4874 outline1( "MOV AX, [%s]", _source );
4875 outline0( "XOR AX, 0xffff" );
4876 if ( _destination ) {
4877 outline1( "MOV [%s], AX", _destination );
4878 } else {
4879 outline1( "MOV [%s], AX", _source );
4880 }
4881 if ( _destination ) {
4882 cpu_inc_16bit( _environment, _destination );
4883 } else {
4884 cpu_inc_16bit( _environment, _source );
4885 }
4886}
4887
4888void cpu_complement2_32bit( Environment * _environment, char * _source, char * _destination ) {
4889 outline1( "MOV AX, [%s]", _source );
4890 outline0( "XOR AX, 0xffff" );
4891 if ( _destination ) {
4892 outline1( "MOV [%s], AX", _destination );
4893 } else {
4894 outline1( "MOV [%s], AX", _source );
4895 }
4896 outline1( "MOV AX, [%s]", address_displacement( _environment, _source, "+2" ) );
4897 outline0( "XOR AX, 0xffff" );
4898 if ( _destination ) {
4899 outline1( "MOV [%s], AX", address_displacement( _environment, _destination, "+2" ) );
4900 } else {
4901 outline1( "MOV [%s], AX", address_displacement( _environment, _source, "+2" ) );
4902 }
4903 if ( _destination ) {
4904 cpu_inc_32bit( _environment, _destination );
4905 } else {
4906 cpu_inc_32bit( _environment, _source );
4907 }
4908}
4909
4910void cpu_complement2_nbit( Environment * _environment, char * _source, char * _destination, int _bits ) {
4911
4912 for( int i=0; i<(_bits>>3); ++i ) {
4913 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
4914 outline1( "MOV AL, [%s]", address_displacement(_environment, _source, offset) );
4915 outline0( "XOR AL, 0xFF" );
4916 if ( _destination ) {
4917 outline1( "MOV [%s], AL", address_displacement(_environment, _destination, "1") );
4918 } else {
4919 outline1( "MOV [%s], AL", address_displacement(_environment, _source, "1") );
4920 }
4921 }
4922 if ( _destination ) {
4923 cpu_inc_nbit( _environment, _destination, _bits );
4924 } else {
4925 cpu_inc_nbit( _environment, _source, _bits );
4926 }
4927
4928}
4929
4930void cpu_sqroot( Environment * _environment, char * _number, char * _result ) {
4931
4932 deploy( sqr, src_hw_8086_sqr_asm );
4933
4934 outline1("MOV AX, [%s]", _number );
4935 outline0("MOV DX, 0" );
4936
4937 outline0("CALL SQROOT" );
4938
4939 outline1("MOV [%s], AX", _result );
4940
4941}
4942
4943void cpu_dstring_vars( Environment * _environment ) {
4944
4945 int count = _environment->dstring.count == 0 ? DSTRING_DEFAULT_COUNT : _environment->dstring.count;
4946 int space = _environment->dstring.space == 0 ? DSTRING_DEFAULT_SPACE : _environment->dstring.space;
4947
4948 outhead1("stringscount EQU %d", count );
4949 outhead1("stringsspace EQU %d", space );
4950 outhead0("MAXSTRINGS: db stringscount" );
4951 outhead0("DESCRIPTORS: times stringscount*4 db 0" );
4952 outhead0("WORKING: times stringsspace db 0" );
4953 outhead0("TEMPORARY: times stringsspace db 0" );
4954 outhead0("FREE_STRING: dw (stringsspace-1)" );
4955
4956}
4957
4958void cpu_protothread_vars( Environment * _environment ) {
4959
4960 int count = _environment->protothreadConfig.count;
4961
4962 outhead1("PROTOTHREADLC: times %d db 0", count );
4963 outhead1("PROTOTHREADST: times %d db 0", count );
4964 outhead0("PROTOTHREADCT: db 0" );
4965 outhead0("PROTOTHREADLOOP:");
4966
4967 for( int i=0; i<count; ++i ) {
4968 outline1("MOV AL, #%d-1", i+1 ); /* prevents optimizer changing code length */
4969 outline0("MOV [PROTOTHREADCT], AL" );
4970 outline0("CALL PROTOTHREADVOID" );
4971 }
4972 outhead1("PROTOTHREADCOUNT: db %d", count );
4973
4974}
4975
4976
4977void cpu_protothread_loop( Environment * _environment ) {
4978
4979 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
4980
4981 outline0("CALL PROTOTHREADLOOP" );
4982
4983}
4984
4985void cpu_protothread_register_at( Environment * _environment, char * _index, char * _label ) {
4986
4987 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
4988
4989 outline1("MOV SI, %s", _label );
4990 outline1("MOV BL, [%s]", _index );
4991
4992 outline0("CALL PROTOTHREADREGAT" );
4993
4994}
4995
4996void cpu_protothread_register( Environment * _environment, char * _label, char * _index ) {
4997
4998 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
4999
5000 outline1("MOV SI, %s", _label );
5001
5002 outline0("CALL PROTOTHREADREG" );
5003
5004 outline1("MOV [%s], BL", _index );
5005
5006}
5007
5008void cpu_protothread_unregister( Environment * _environment, char * _index ) {
5009
5010 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
5011
5012 outline1("MOV BL, [%s]", _index );
5013
5014 outline0("CALL PROTOTHREADUNREG" );
5015
5016}
5017
5018void cpu_protothread_save( Environment * _environment, char * _index, int _step ) {
5019
5020 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
5021
5022 outline1("MOV BL, [%s]", _index );
5023 outline1("MOV AL, 0x%2.2x", ( _step & 0xff ) );
5024
5025 outline0("CALL PROTOTHREADSAVE" );
5026
5027}
5028
5029void cpu_protothread_restore( Environment * _environment, char * _index, char * _step ) {
5030
5031 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
5032
5033 outline1("MOV BL, [%s]", _index );
5034
5035 outline0("CALL PROTOTHREADRESTORE" );
5036
5037 outline1("MOV [%s], AL", _step );
5038
5039}
5040
5041void cpu_protothread_set_state( Environment * _environment, char * _index, int _state ) {
5042
5043 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
5044
5045 outline1("MOV BL, [%s]", _index );
5046 outline1("MOV AL, 0x%2.2x", ( _state & 0xff ) );
5047
5048 outline0("CALL PROTOTHREADSETSTATE" );
5049
5050}
5051
5052void cpu_protothread_get_state( Environment * _environment, char * _index, char * _state ) {
5053
5054 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
5055
5056 outline1("MOV BL, [%s]", _index );
5057 outline0("CALL PROTOTHREADGETSTATE" );
5058 outline1("MOV [%s], AL", _state );
5059
5060}
5061
5062void cpu_protothread_get_address( Environment * _environment, char * _index, char * _address ) {
5063
5064 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
5065
5066 outline1("MOV BL, [%s]", _index );
5067 outline0("CALL PROTOTHREADGETADDRESS" );
5068 outline1("MOV [%s], DI", _address );
5069
5070}
5071
5072void cpu_protothread_current( Environment * _environment, char * _current ) {
5073
5074 deploy_with_vars( protothread, src_hw_8086_protothread_asm, cpu_protothread_vars );
5075
5076 outline0("MOV AL, [PROTOTHREADCT]" );
5077 outline1("MOV [%s], AL", _current );
5078
5079}
5080
5081void cpu_set_callback( Environment * _environment, char * _callback, char * _label ) {
5082
5083 outline1("MOV AX, %s", _label );
5084 outline1("MOV DI, %s", _callback );
5085 outline0("MOV [DI], AX" );
5086
5087}
5088
5089void cpu_msc1_uncompress_direct_direct( Environment * _environment, char * _input, char * _output ) {
5090
5092
5093 inline( cpu_msc1_uncompress )
5094
5095 embedded( cpu_msc1_uncompress, src_hw_8086_msc1_asm );
5096
5097 outline1("MOV SI, %s", _input);
5098 outline1("MOV DI, %s", _output);
5099 outline0("CALL MSC1UNCOMPRESS");
5100
5101 done()
5102
5103}
5104
5105void cpu_msc1_uncompress_direct_indirect( Environment * _environment, char * _input, char * _output ) {
5106
5108
5109 inline( cpu_msc1_uncompress )
5110
5111 embedded( cpu_msc1_uncompress, src_hw_8086_msc1_asm );
5112
5113 outline1("MOV SI, %s", _input);
5114 outline1("MOV DI, [%s]", _output);
5115 outline0("CALL MSC1UNCOMPRESS");
5116
5117 done()
5118
5119}
5120
5121void cpu_msc1_uncompress_indirect_direct( Environment * _environment, char * _input, char * _output ) {
5122
5124
5125 inline( cpu_msc1_uncompress )
5126
5127 embedded( cpu_msc1_uncompress, src_hw_8086_msc1_asm );
5128
5129 outline1("MOV SI, [%s]", _input);
5130 outline1("MOV DI, %s", _output);
5131 outline0("CALL MSC1UNCOMPRESS");
5132
5133 done()
5134
5135}
5136
5137void cpu_msc1_uncompress_indirect_indirect( Environment * _environment, char * _input, char * _output ) {
5138
5140
5141 inline( cpu_msc1_uncompress )
5142
5143 embedded( cpu_msc1_uncompress, src_hw_8086_msc1_asm );
5144
5145 outline1("MOV SI, [%s]", _input);
5146 outline1("MOV DI, [%s]", _output);
5147 outline0("CALL MSC1UNCOMPRESS");
5148
5149 done()
5150
5151}
5152
5153void cpu_out( Environment * _environment, char * _port, char * _value ) {
5154
5155 outline1("MOV AL, [%s]", _value );
5156 outline1("MOV DX, [%s]", _port );
5157 outline0("OUT DX, AL" );
5158
5159}
5160
5161void cpu_in( Environment * _environment, char * _port, char * _value ) {
5162
5163 outline1("MOV DX, [%s]", _port );
5164 outline0("IN AL, DX" );
5165 outline1("MOV [%s], AL", _value );
5166
5167}
5168
5169void cpu_out_direct( Environment * _environment, char * _port, char * _value ) {
5170
5171 outline1("MOV AL, [%s]", _value );
5172 outline1("MOV DX, %s", _port );
5173 outline0("OUT DX, AL" );
5174
5175}
5176
5177void cpu_in_direct( Environment * _environment, char * _port, char * _value ) {
5178
5179 outline1("MOV DX, %s", _port );
5180 outline0("IN AL, DX" );
5181 outline1("MOV [%s], AL", _value );
5182
5183}
5184
5185void cpu_string_sub( Environment * _environment, char * _source, char * _source_size, char * _pattern, char * _pattern_size, char * _destination, char * _destination_size ) {
5186
5188
5189 inline( cpu_string_sub )
5190
5191 embedded( cpu_string_sub, src_hw_8086_cpu_string_sub_asm );
5192
5193 outline1("MOV SI, [%s]", _source);
5194 outline1("MOV CL, [%s]", _source_size);
5195 outline1("MOV DX, [%s]", _pattern);
5196 outline1("MOV CH, [%s]", _pattern_size);
5197 outline1("MOV DI, [%s]", _destination);
5198 outline0("CALL CPUSTRINGSUB");
5199 outline0("MOV AL, CL");
5200 outline1("MOV [%s], AL", _destination_size);
5201
5202 done()
5203}
5204
5205static char CPU8086_BLIT_REGISTER[][2] = {
5206 "DL",
5207 "DH",
5208 "CL",
5209 "CH"
5210};
5211
5212#define CPU8086_BLIT_REGISTER_COUNT ( sizeof( CPU8086_BLIT_REGISTER ) / 2 )
5213
5214void cpu_blit_initialize( Environment * _environment ) {
5215
5216 _environment->blit.freeRegisters = 0;
5217 _environment->blit.usedMemory = 0;
5218
5219 // outline0("; cpu_blit_initialize");
5220
5221 outline0("PUSH SI");
5222 outline0("PUSH DI");
5223
5224}
5225
5226void cpu_blit_finalize( Environment * _environment ) {
5227
5228 // outline0("; cpu_blit_finalize");
5229
5230 _environment->blit.freeRegisters = 0;
5231 _environment->blit.usedMemory = 0;
5232
5233 outline0("POP DI");
5234 outline0("POP SI");
5235
5236}
5237
5238char * cpu_blit_register_name( Environment * _environment, int _register ) {
5239
5240 if ( _register < CPU8086_BLIT_REGISTER_COUNT ) {
5241 return &CPU8086_BLIT_REGISTER[_register][0];
5242 } else {
5243 return &CPU8086_BLIT_REGISTER[ (_register & 0xff00) >> 8][0];
5244 }
5245}
5246
5248
5249 int reg = 0;
5250
5251 for( reg = 0; reg < CPU8086_BLIT_REGISTER_COUNT; ++reg ) {
5252 int registerMask = ( 0x01 << reg );
5253 int isRegisterUsed = _environment->blit.freeRegisters & registerMask;
5254 if ( ! isRegisterUsed ) {
5255 _environment->blit.freeRegisters |= registerMask;
5256 // printf( "cpu_blit_alloc_register() %4.4x -> 0x%4.4x\n", _environment->blit.freeRegisters, reg );
5257 // outline1("; cpu_blit_alloc_register = %d", reg );
5258 return reg;
5259 }
5260 }
5261
5262 int location = _environment->blit.usedMemory++;
5263
5264 if ( location > 0xff ) {
5266 }
5267
5268 for( reg = 0; reg < CPU8086_BLIT_REGISTER_COUNT; ++reg ) {
5269 int registerMask = ( 0x10 << reg );
5270 int isRegisterUsed = _environment->blit.freeRegisters & registerMask;
5271 if ( ! isRegisterUsed ) {
5272 outline1( "MOV AL, %s", &CPU8086_BLIT_REGISTER[reg][0] );
5273 outline2( "MOV [%sbs+0x%2.2x], AL", _environment->blit.realName, location );
5274 _environment->blit.freeRegisters |= registerMask;
5275 // printf( "cpu_blit_alloc_register() -> %4.4x 0x%4.4x\n", _environment->blit.freeRegisters, ( ( reg << 8 ) | location ) );
5276 // outline1("; cpu_blit_alloc_register = %d", ( ( (reg+1) << 8 ) | location ) );
5277 return ( ( (reg+1) << 8 ) | location );
5278 }
5279 }
5280
5282
5283}
5284
5285void cpu_blit_free_register( Environment * _environment, int _register ) {
5286
5287 // outline1("; cpu_blit_free_register = %d", _register );
5288
5289 // printf( "cpu_blit_free_register(0x%4.4x)\n", _register );
5290
5291 int location = _register & 0xff;
5292 int reg;
5293
5294 if ( _register < CPU8086_BLIT_REGISTER_COUNT ) {
5295 int registerMask = ( 0x01 << _register );
5296 int isRegisterUsed = _environment->blit.freeRegisters & registerMask;
5297 if ( isRegisterUsed ) {
5298 _environment->blit.freeRegisters &= ~registerMask;
5299 return;
5300 } else {
5301 CRITICAL_BLIT_INVALID_FREE_REGISTER( _environment->blit.name, _register );
5302 }
5303 } else {
5304 int registerMask = 0x10 << ( ( ( _register >> 8 ) & 0xff ) - 1 );
5305 int isRegisterUsed = _environment->blit.freeRegisters & registerMask;
5306 if ( isRegisterUsed ) {
5307 outline2( "MOV AL, [%sbs+0x%2.2x]", _environment->blit.realName, location );
5308 outline1( "MOV %s, AL", &CPU8086_BLIT_REGISTER[reg][0] );
5309 _environment->blit.freeRegisters &= ~registerMask;
5310 return;
5311 }
5312 }
5313
5314 CRITICAL_BLIT_INVALID_FREE_REGISTER( _environment->blit.name, _register );
5315
5316}
5317
5326void cpu_store_nbit( Environment * _environment, char *_destination, int _n, int _value[] ) {
5327
5328 int i = 0;
5329 while( _n ) {
5330 char destinationAddress[MAX_TEMPORARY_STORAGE]; sprintf( destinationAddress, "%s+%d", _destination, i*4 );
5331 if ( _n <= 32 ) {
5332 switch( _n ) {
5333 case 1: case 2: case 3: case 4:
5334 case 5: case 6: case 7: case 8:
5335 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff>>(8-_n)) ) );
5336 i = i + 1;
5337 break;
5338 case 9: case 10: case 11: case 12:
5339 case 13: case 14: case 15: case 16:
5340 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff) ) );
5341 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
5342 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+1] & (0xff>>(16-_n)) ) );
5343 i = i + 2;
5344 break;
5345 case 17: case 18: case 19: case 20:
5346 case 21: case 22: case 23: case 24:
5347 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff) ) );
5348 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
5349 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+1] & (0xff) ) );
5350 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
5351 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+2] & (0xff>>(24-_n)) ) );
5352 i = i + 3;
5353 break;
5354 case 25: case 26: case 27: case 28:
5355 case 29: case 30: case 31: case 32:
5356 default:
5357 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff) ) );
5358 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
5359 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+1] & (0xff) ) );
5360 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
5361 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+2] & (0xff) ) );
5362 sprintf( destinationAddress, "%s+%d", _destination, i*4+3 );
5363 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+3] & (0xff>>(32-_n)) ) );
5364 i = i + 4;
5365 break;
5366 }
5367 _n = 0;
5368 } else {
5369 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff) ) );
5370 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
5371 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+1] & (0xff) ) );
5372 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
5373 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+2] & (0xff) ) );
5374 sprintf( destinationAddress, "%s+%d", _destination, i*4+3 );
5375 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+3] & (0xff>>(32-_n)) ) );
5376 _n -= 32;
5377 }
5378 ++i;
5379 }
5380
5381}
5382
5391void cpu_move_nbit( Environment * _environment, int _n, char * _source, char *_destination ) {
5392
5393 int i = 0;
5394 while( _n ) {
5395 char sourceAddress[MAX_TEMPORARY_STORAGE]; sprintf( sourceAddress, "%s+%d", _source, i*4 );
5396 char destinationAddress[MAX_TEMPORARY_STORAGE]; sprintf( destinationAddress, "%s+%d", _destination, i*4 );
5397 if ( _n <= 32 ) {
5398 switch( _n ) {
5399 case 1: case 2: case 3: case 4:
5400 case 5: case 6: case 7: case 8:
5401 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5402 break;
5403 case 9: case 10: case 11: case 12:
5404 case 13: case 14: case 15: case 16:
5405 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5406 sprintf( sourceAddress, "%s+%d", _source, i*4+1 );
5407 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
5408 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5409 break;
5410 case 17: case 18: case 19: case 20:
5411 case 21: case 22: case 23: case 24:
5412 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5413 sprintf( sourceAddress, "%s+%d", _source, i*4+1 );
5414 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
5415 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5416 sprintf( sourceAddress, "%s+%d", _source, i*4+2 );
5417 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
5418 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5419 break;
5420 case 25: case 26: case 27: case 28:
5421 case 29: case 30: case 31: case 32:
5422 default:
5423 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5424 sprintf( sourceAddress, "%s+%d", _source, i*4+1 );
5425 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
5426 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5427 sprintf( sourceAddress, "%s+%d", _source, i*4+2 );
5428 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
5429 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5430 sprintf( sourceAddress, "%s+%d", _source, i*4+3 );
5431 sprintf( destinationAddress, "%s+%d", _destination, i*4+3 );
5432 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5433 break;
5434 }
5435 _n = 0;
5436 } else {
5437 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5438 sprintf( sourceAddress, "%s+%d", _source, i*4+1 );
5439 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
5440 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5441 sprintf( sourceAddress, "%s+%d", _source, i*4+2 );
5442 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
5443 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5444 sprintf( sourceAddress, "%s+%d", _source, i*4+3 );
5445 sprintf( destinationAddress, "%s+%d", _destination, i*4+3 );
5446 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
5447 _n -= 32;
5448 }
5449 ++i;
5450 }
5451
5452}
5453
5462
5463void cpu_compare_nbit( Environment * _environment, char *_source, char *_destination, char *_other, int _positive, int _bits ) {
5464
5466
5467 inline( cpu_compare_nbit )
5468
5469 for( int i=0; i<(_bits>>3); ++i ) {
5470 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
5471 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset));
5472 outline1("CMP AL, [%s]", address_displacement(_environment, _destination, offset));
5473 outline1("JNZ %s", label);
5474 }
5475 outline1("MOV AL, 0x%2.2x", 0xff*_positive);
5476 if ( _other ) {
5477 outline1("MOV [%s], AL", _other);
5478 } else {
5479 outline1("MOV [%s], AL", _destination);
5480 }
5481 outline1("JMP %s_2", label);
5482 outhead1("%s:", label);
5483 outline1("MOV AL, 0x%2.2x", 0xff*(1-_positive));
5484 if ( _other ) {
5485 outline1("MOV [%s], AL", _other);
5486 } else {
5487 outline1("MOV [%s], AL", _destination);
5488 }
5489 outhead1("%s_2:", label);
5490
5492
5493}
5494
5495void cpu_compare_nbit_const( Environment * _environment, char *_source, int _destination, char *_other, int _positive, int _bits ) {
5496
5498
5499 inline( cpu_compare_nbit )
5500
5501 for( int i=0; i<(_bits>>3); ++i ) {
5502 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
5503 outline1("MOV AL, [%s]", address_displacement(_environment, _source, offset));
5504 outline1("CMP AL, 0x%2.2x", (unsigned char)((_destination>>(i*8)) && 0xff));
5505 outline1("JNZ %s", label);
5506 }
5507 outline1("MOV AL, 0x%2.2x", 0xff*_positive);
5508 if ( _other ) {
5509 outline1("MOV [%s], AL", _other);
5510 } else {
5511 outline1("MOV [%s], AL", _destination);
5512 }
5513 outline1("JMP %s_2", label);
5514 outhead1("%s:", label);
5515 outline1("MOV AL, 0x%2.2x", 0xff*(1-_positive));
5516 if ( _other ) {
5517 outline1("MOV [%s], AL", _other);
5518 } else {
5519 outline1("MOV [%s], AL", _destination);
5520 }
5521 outhead1("%s_2:", label);
5522
5524
5525}
5526
5527// [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
5528// FAST (24) seeeeeee mmmmmmmm mmmmmmmm
5529
5530void cpu_float_fast_from_double_to_int_array( Environment * _environment, double _value, int _result[] ) {
5531
5532 cpu_float_single_from_double_to_int_array( _environment, _value, _result );
5533
5534}
5535
5536//
5537// [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
5538// SINGLE (32) seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
5539//
5540
5541void cpu_float_single_from_double_to_int_array( Environment * _environment, double _value, int _result[] ) {
5542
5543 double value = 0.0;
5544 double integral = 0.0;
5545 double fractional = 0.0;
5546 int sign = 0;
5547 int left = 0;
5548 int right[3];
5549 int steps = 0;
5550 int exp = 0;
5551 int mantissa_bits = 23;
5552
5553 memset( &right[0], 0, sizeof( int ) * 3 );
5554
5555 // Step 1: Determine Sign
5556 // If the number is positive, then the sign bit will be 0. If the number is negative, then the sign bit
5557 // will be 1. For the number zero, both positive and negative zero are possible, and these are considered
5558 // different values (a quirk of using sign bits).
5559
5560 if ( _value >= 0 ) {
5561 sign = 0;
5562 } else {
5563 sign = 1;
5564 }
5565
5566 value = fabs( _value );
5567
5568 // Step 2: Convert the Integral Portion to Unsigned Binary
5569 // Convert the integral portion of the floating-point value to unsigned binary (not two's complement).
5570 // The integral portion is the part of the number before the decimal point. For example, if the
5571 // number to convert is -0.75, then 0 is the integral portion, and it's unsigned binary representation
5572 // is simply 0. As another example, if the number to convert is 127.99, then the integral portion would
5573 // be 127, and it's unsigned binary representation is 1111111.
5574
5575 fractional = modf(value, &integral);
5576
5577 left = (unsigned int) integral;
5578
5579 // Step 3: Convert the Fractional Portion to Binary
5580 // The fractional portion of the number must also be converted to binary, though the conversion process
5581 // is much different from what you're used to. The algorithm you'll used is based on performing repeated
5582 // multiplications by 2, and then checking if the result is >= 1.0. If the result is >= 1.0, then a 1 is
5583 // recorded for the binary fractional component, and the leading 1 is chopped of the result. If the
5584 // result is < 1.0, then a 0 is recorded for the binary fractional component, and the result is kept
5585 // as-is. The recorded builds are built-up left-to-right. The result keeps getting chained along in this
5586 // way until one of the following is true:
5587 // - The result is exactly 1.0
5588 // - 23 iterations of this process have occurred; i.e. the final converted binary value holds 23 bits
5589 // With the first possible terminating condition (the result is exactly 1.0), this means that the fractional
5590 // component has been represented without any loss of precision. With the second possible terminating
5591 // condition (23 iterations have passed), this means that we ran out of bits in the final result, which
5592 // can never exceed 23. In this case, precision loss occurs (an unfortunate consequence of using a finite
5593 // number of bits).
5594
5595 while( ( fractional != 1.0 ) && ( steps < mantissa_bits ) ) {
5596
5597 // printf("%f %d %2.2x %2.2x %2.2x\n", fractional, steps, (unsigned char) right[0], (unsigned char) right[1], (unsigned char) right[2] );
5598
5599 right[2] = right[2] << 1;
5600 right[1] = right[1] << 1;
5601 right[0] = right[0] << 1;
5602 if ( ( right[2] & 0x100 ) ) {
5603 right[1] = right[1] | 0x1;
5604 }
5605 if ( ( right[1] & 0x100 ) ) {
5606 right[0] = right[0] | 0x1;
5607 }
5608 right[2] = right[2] & 0xff;
5609 right[1] = right[1] & 0xff;
5610 right[0] = right[0] & 0x7f;
5611
5612 fractional = fractional * 2;
5613
5614 if ( fractional >= 1.0 ) {
5615 right[2] |= 1;
5616 fractional = modf(fractional, &integral);
5617 }
5618
5619 ++steps;
5620
5621 }
5622
5623 // Step 4: Normalize the Value via Adjusting the Exponent
5624 // A trick to encode an extra bit is to make it so that the binary scientific representation is always
5625 // of the form 1.XXXX * 2YYYY. That is, a 1 always leads, so there is no need to explicitly encode it.
5626 // In order to encode this properly, we need to move the decimal point to a position where it is
5627 // immediately after the first 1, and then record exactly how we moved it. To see this in action, consider
5628 // again the example of 0.75, which is encoded in binary as such (not IEEE-754 notation):
5629 // 0.11
5630 // In order to make the decimal point be after the first 1, we will need to move it one position to the right, like so:
5631 // 1.1
5632 // Most importantly, we need to record that we moved the decimal point by one position to the right.
5633 // Moves to the right result in negative exponents, and moves to the left result in positive exponents.
5634 // In this case, because we moved the decimal point one position to the right, the recorded exponent should be -1.
5635 // As another example, consider the following binary floating point representation (again, not IEEE-754):
5636 // 1111111.11100
5637 // In this case, we need to move the decimal point six positions to the left to make this begin with a single 1, like so:
5638 // 1.11111111100
5639 // Because this moves six positions to the left, the recorded exponent should be 6.
5640
5641 int mantissa_high_bit = 0x80000000 >> ( 32 - mantissa_bits);
5642 int mantissa_mask = 0xffffffff >> ( 32 - mantissa_bits);
5643
5644 if ( left == 0 ) {
5645
5646 if ( value != 0 ) {
5647
5648 while( left == 0 ) {
5649
5650 // printf("exp = %d left = %2.2x right = %2.2x %2.2x %2.2x\n", exp, (unsigned char) left, (unsigned char) right[0], (unsigned char) right[1], (unsigned char) right[2] );
5651
5652 if ( right[0] & 0x40 ) {
5653 left = 0x1;
5654 }
5655
5656 right[0] = right[0] << 1;
5657 right[1] = right[1] << 1;
5658 right[2] = right[2] << 1;
5659 if ( ( right[1] & 0x100 )) {
5660 right[0] = right[0] | 0x1;
5661 }
5662 if ( ( right[2] & 0x100 )) {
5663 right[1] = right[1] | 0x1;
5664 }
5665 right[0] = right[0] & 0x7f;
5666 right[1] = right[1] & 0xff;
5667 right[2] = right[2] & 0xff;
5668
5669 --exp;
5670 }
5671
5672 } else {
5673
5674 exp = -127;
5675
5676 }
5677
5678 // printf("exp = %d left = %2.2x right = %2.2x %2.2x %2.2x\n", exp, (unsigned char) left, (unsigned char) right[0], (unsigned char) right[1], (unsigned char) right[2] );
5679
5680 } else {
5681
5682 while( left ) {
5683
5684 // printf("left = %8.8x right = %2.2x %2.2x %2.2x\n", left, (unsigned char) right[0], (unsigned char) right[1], (unsigned char) right[2] );
5685
5686 if ( ( right[0] & 0x01 ) ) {
5687 right[1] = right[1] | 0x100;
5688 }
5689 if ( ( right[1] & 0x01 ) ) {
5690 right[2] = right[2] | 0x100;
5691 }
5692 right[0] = right[0] >> 1;
5693 right[1] = right[1] >> 1;
5694 // right[2] = right[2] >> 1;
5695 if ( left & 0x1 ) {
5696 right[0] = right[0] | 0x40;
5697 }
5698 left = left >> 1;
5699 ++exp;
5700 }
5701 --exp;
5702 left = 1;
5703 right[2] = right[2] << 1;
5704 right[1] = right[1] << 1;
5705 right[0] = right[0] << 1;
5706 if ( right[2] & 0x100 ) {
5707 right[1] = right[1] | 0x01;
5708 }
5709 if ( right[1] & 0x100 ) {
5710 right[0] = right[0] | 0x01;
5711 }
5712 right[2] = right[2] & 0xff;
5713 right[1] = right[1] & 0xff;
5714 right[0] = right[0] & 0x7f;
5715
5716 }
5717
5718 // Step 5: Add Bias to the Exponent
5719 // Internally, IEEE-754 values store their exponents in an unsigned representation, which may seem odd considering that
5720 // the exponent can be negative. Negative exponents are accomodated by using a biased representation, wherein a
5721 // pre-set number is always subtracted from the given unsigned number. Because the given unsigned number may be less
5722 // than this number, this allows for negative values to be effectively encoded without resorting to two's complement.
5723 // Specifically, for the binary32 representation, the number 127 will be subtracted from anything encoded in the
5724 // exponent field of the IEEE-754 number. As such, in this step, we need to add 127 to the normalized exponent value
5725 // from the previous step.
5726
5727 exp += 127;
5728
5729 // printf("exp = %2.2x\n", exp );
5730
5731 // Step 6: Convert the Biased Exponent to Unsigned Binary
5732 // The biased exponent value from the previous step must be converted into unsigned binary, using the usual process.
5733 // The result must be exactly 8 bits. It should not be possible to need more than 8 bits. If fewer than 8 bits are
5734 // needed in this conversion process, then leading zeros must be added to the front of the result to produce an
5735 // 8-bit value.
5736
5737 exp = exp & 0xff;
5738
5739 // printf("exp = %2.2x\n", exp );
5740
5741 // Step 7: Determine the Final Bits for the Mantissa
5742 // After step 4, there are a bunch of bits after the normalized decimal point. These bits will become the
5743 // mantissa (note that we ignore the bits to the left of the decimal point - normalization allows us to do this,
5744 // because it should always be just a 1). We need exactly 23 mantissa bits. If less than 23 mantissa bits follow the
5745 // decimal point, and the algorithm in step 3 ended with a result that wasn't 1.0, then follow the algorithm in step 3
5746 // until we can fill enough bits. If that's still not enough (eventually reaching 1.0 before we had enough bits, or
5747 // perhaps it had ended with 1.0 already), then the right side can be padded with zeros until 23 bits is reached.
5748 // If there are more than 23 bits after the decimal point in step 4, then these extra bits are simply cutoff from the
5749 // right. For example, if we had 26 bits to the right of the decimal point, then the last three would need to be cutoff
5750 // to get us to 23 bits. Note that in this case we will necessarily lose some precision.
5751
5752 // Step 8: Put it All Together
5753 // The sign bit from step 1 will be the first bit of the final result. The next 8 bits will be from the exponent from
5754 // step 6. The last 23 bits will be from the mantissa from step 7. The result will be a 32-bit number encoded in
5755 // IEEE-754 binary32 format, assuming no mistakes were made in the process.
5756
5757 // [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
5758 // SINGLE (32) seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
5759
5760 _result[3] = ( sign << 7 ) | ( ( exp >> 1 ) & 0x7f );
5761 _result[2] = ( ( exp & 0x01 ) << 7 ) | ( right[0] );
5762 _result[1] = ( right[1] );
5763 _result[0] = ( right[2] );
5764
5765 // printf( "%2.2x %2.2x %2.2x %2.2x\n", _result[0], _result[1], _result[2], _result[3] );
5766
5767}
5768
5769//
5770// [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
5771// EXTENDED (80) seeeeeee eeeeeeee mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
5772//
5773
5774void cpu_float_double_from_double_to_int_array( Environment * _environment, double _value, int _result[] ) {
5775
5776}
5777
5778void cpu_float_fast_to_string( Environment * _environment, char * _x, char * _string, char * _string_size ) {
5779
5780 cpu_float_single_to_string( _environment, _x, _string, _string_size );
5781
5782}
5783
5784void cpu_float_single_to_string( Environment * _environment, char * _x, char * _string, char * _string_size ) {
5785
5787
5788 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5789 deploy( fp_single_to_string, src_hw_8086_fp_single_to_string_asm );
5790 deploy( numberToString, src_hw_8086_number_to_string_asm );
5791 deploy( duff, src_hw_8086_duff_asm );
5792
5793 outline1( "MOV DI, [%s]", _string );
5794 outline1( "FLD DWORD [%s]", _x );
5795 outline0( "CALL FPSINGLETOA" );
5796 outline1( "MOV [%s], CL", _string_size );
5797
5798}
5799
5800void cpu_float_double_to_string( Environment * _environment, char * _x, char * _string, char * _string_size ) {
5801
5802}
5803
5804void cpu_float_fast_from_16( Environment * _environment, char * _value, char * _result, int _signed ) {
5805
5806 cpu_float_single_from_16( _environment, _value, _result, _signed );
5807
5808}
5809
5810void cpu_float_fast_from_8( Environment * _environment, char * _value, char * _result, int _signed ) {
5811
5812 cpu_float_single_from_8( _environment, _value, _result, _signed );
5813
5814}
5815
5816void cpu_float_fast_to_16( Environment * _environment, char * _value, char * _result, int _signed ) {
5817
5818 cpu_float_single_to_16( _environment, _value, _result, _signed );
5819
5820}
5821
5822void cpu_float_fast_to_8( Environment * _environment, char * _value, char * _result, int _signed ) {
5823
5824 cpu_float_single_to_8( _environment, _value, _result, _signed );
5825
5826}
5827
5828void cpu_float_fast_add( Environment * _environment, char * _x, char * _y, char * _result ) {
5829
5830 cpu_float_single_add( _environment, _x, _y, _result );
5831
5832}
5833
5834void cpu_float_fast_sub( Environment * _environment, char * _x, char * _y, char * _result ) {
5835
5836 cpu_float_single_sub( _environment, _x, _y, _result );
5837
5838}
5839
5840void cpu_float_fast_mul( Environment * _environment, char * _x, char * _y, char * _result ) {
5841
5842 cpu_float_single_mul( _environment, _x, _y, _result );
5843
5844}
5845
5846void cpu_float_fast_div( Environment * _environment, char * _x, char * _y, char * _result ) {
5847
5848 cpu_float_single_div( _environment, _x, _y, _result );
5849
5850}
5851
5852void cpu_float_fast_cmp( Environment * _environment, char * _x, char * _y, char * _result ) {
5853
5854 cpu_float_single_cmp( _environment, _x, _y, _result );
5855
5856}
5857
5858void cpu_float_fast_sin( Environment * _environment, char * _angle, char * _result ) {
5859
5860 cpu_float_single_sin( _environment, _angle, _result );
5861
5862}
5863
5864void cpu_float_fast_cos( Environment * _environment, char * _angle, char * _result ) {
5865
5866 cpu_float_single_cos( _environment, _angle, _result );
5867
5868}
5869
5870void cpu_float_fast_tan( Environment * _environment, char * _angle, char * _result ) {
5871
5872 cpu_float_single_tan( _environment, _angle, _result );
5873
5874}
5875
5876void cpu_float_fast_sqr( Environment * _environment, char * _value, char * _result ) {
5877
5878 cpu_float_fast_sqr( _environment, _value, _result );
5879
5880}
5881
5882void cpu_float_fast_neg( Environment * _environment, char * _value, char * _result ) {
5883
5884 cpu_float_fast_neg( _environment, _value, _result );
5885
5886}
5887
5888void cpu_float_single_from_16( Environment * _environment, char * _value, char * _result, int _signed ) {
5889
5890 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5891
5892 outline1( "FILD WORD [%s]", _value );
5893 outline1( "FSTP DWORD [%s]", _result );
5894
5895}
5896
5897void cpu_float_single_from_8( Environment * _environment, char * _value, char * _result, int _signed ) {
5898
5899 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5900
5901 outline1( "FILD BYTE [%s]", _value );
5902 outline1( "FSTP DWORD [%s]", _result );
5903
5904}
5905
5906void cpu_float_single_to_16( Environment * _environment, char * _value, char * _result, int _signed ) {
5907
5908 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5909
5910 outline1( "FLD DWORD [%s]", _value );
5911 outline1( "FISTP WORD [%s]", _result );
5912
5913}
5914
5915void cpu_float_single_to_8( Environment * _environment, char * _value, char * _result, int _signed ) {
5916
5917 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5918
5919 outline1( "FLD BYTE [%s]", _value );
5920 outline1( "FISTP BYTE [%s]", _result );
5921
5922}
5923
5924void cpu_float_single_add( Environment * _environment, char * _x, char * _y, char * _result ) {
5925
5926 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5927
5928 outline1( "FLD DWORD [%s]", _x );
5929 outline1( "FLD DWORD [%s]", _y );
5930 outline0( "FADD");
5931 outline1( "FSTP DWORD [%s]", _result );
5932
5933}
5934
5935void cpu_float_single_sub( Environment * _environment, char * _x, char * _y, char * _result ) {
5936
5937 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5938
5939 outline1( "FLD DWORD [%s]", _x );
5940 outline1( "FLD DWORD [%s]", _y );
5941 outline0( "FSUB");
5942 outline1( "FSTP DWORD [%s]", _result );
5943
5944}
5945
5946void cpu_float_single_mul( Environment * _environment, char * _x, char * _y, char * _result ) {
5947
5948 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5949
5950 outline1( "FLD DWORD [%s]", _x );
5951 outline1( "FLD DWORD [%s]", _y );
5952 outline0( "FMUL");
5953 outline1( "FSTP DWORD [%s]", _result );
5954
5955}
5956
5957void cpu_float_single_div( Environment * _environment, char * _x, char * _y, char * _result ) {
5958
5959 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5960
5961 outline1( "FLD DWORD [%s]", _x );
5962 outline1( "FLD DWORD [%s]", _y );
5963 outline0( "FDIV");
5964 outline1( "FSTP DWORD [%s]", _result );
5965
5966}
5967
5968void cpu_float_single_cmp( Environment * _environment, char * _x, char * _y, char * _result ) {
5969
5971
5972 deploy( fp_vars, src_hw_8086_fp_vars_asm );
5973
5974 outline1( "FLD DWORD [%s]", _y );
5975 outline1( "FLD DWORD [%s]", _x );
5976 outline0( "FCMP");
5977 outline0( "FSTSW AX");
5978 outline0( "AND AX, %0100011100000000");
5979 outline0( "CMP AX, %0000000000000000");
5980 outline1( "JE %sgreater", label );
5981 outline0( "CMP AX, %0000000100000000B");
5982 outline1( "JE %sless", label );
5983 outline0( "CMP AX, %0100000000000000B");
5984 outline1( "JE %sequal", label );
5985 outhead1( "%sgreater:", label );
5986 outline0( "MOV AL, 1" );
5987 outline1( "MOV [%s], A", _result );
5988 outline1( "JMP %sdone", label );
5989 outhead1( "%sequal:", label );
5990 outline0( "MOV AL, 0" );
5991 outline1( "MOV [%s], AL", _result );
5992 outline1( "JMP %sdone", label );
5993 outhead1( "%sless:", label );
5994 outline0( "MOV AL, 0xff" );
5995 outline1( "MOV [%s], AL", _result );
5996 outline1( "JMP %sdone", label );
5997 outhead1( "%sdone:", label );
5998
5999}
6000
6001void cpu_float_single_neg( Environment * _environment, char * _value, char * _result ) {
6002
6003 deploy( fp_vars, src_hw_8086_fp_vars_asm );
6004
6005 Variable * zero = variable_temporary( _environment, VT_WORD, "()");
6006 variable_store( _environment, zero->realName, 0 );
6007
6008 outline1( "FILD DWORD [%s]", zero->realName );
6009 outline1( "FLD DWORD [%s]", _value );
6010 outline0( "FSUB");
6011 outline1( "FSTP DWORD [%s]", _result );
6012
6013}
6014
6015void cpu_float_single_sin( Environment * _environment, char * _angle, char * _result ) {
6016
6018
6019}
6020
6021void cpu_float_single_cos( Environment * _environment, char * _angle, char * _result ) {
6022
6023 deploy( fp_vars, src_hw_8086_fp_vars_asm );
6024 deploy( fp_single_cos, src_hw_8086_fp_cos_asm );
6025
6026 outline1( "FLD DWORD [%s]", _angle );
6027 outline0( "CALL FPCOS");
6028 outline1( "FSTP DWORD [%s]", _result );
6029
6030}
6031
6032void cpu_float_single_tan( Environment * _environment, char * _angle, char * _result ) {
6033
6034 deploy( fp_vars, src_hw_8086_fp_vars_asm );
6035
6036 outline1( "FLD DWORD [%s]", _angle );
6037 outline0( "FTAN");
6038 outline1( "FSTP DWORD [%s]", _result );
6039
6040}
6041
6042void cpu_float_single_sqr( Environment * _environment, char * _value, char * _result ) {
6043
6045
6046}
6047
6048void cpu_address_table_build( Environment * _environment, char * _table, int * _values, char *_address[], int _count ) {
6049
6050 // outhead1("%s:", _table );
6051 // for( int i=0; i<_count; ++i ) {
6052 // outline2("DEFW 0x%4.4x, %s", _values[i], _address[i] );
6053 // }
6054
6055}
6056
6057void cpu_address_table_lookup( Environment * _environment, char * _table, int _count ) {
6058
6059 // outhead1("LOOKFOR%s:", _table );
6060 // if ( _count ) {
6061 // outline1("MOV HL, %s", _table );
6062 // outline0("MOV C, 0" );
6063 // outhead1("LOOKFOR%sL1:", _table );
6064 // outline0("MOV AL, (HL)" );
6065 // outline0("INC HL" );
6066 // outline0("MOV B, A" );
6067 // outline0("MOV AL, E" );
6068 // outline0("CP B" );
6069 // outline1("JR NZ, LOOKFOR%sNEXT3", _table );
6070 // outline0("MOV AL, (HL)" );
6071 // outline0("INC HL" );
6072 // outline0("MOV B, A" );
6073 // outline0("MOV AL, D" );
6074 // outline0("CP B" );
6075 // outline1("JR NZ, LOOKFOR%sNEXT2", _table );
6076 // outline0("MOV AL, (HL)" );
6077 // outline0("INC HL" );
6078 // outline0("MOV E, A" );
6079 // outline0("MOV AL, (HL)" );
6080 // outline0("INC HL" );
6081 // outline0("MOV D, A" );
6082 // outline0("RET" );
6083 // outhead1("LOOKFOR%sNEXT3:", _table );
6084 // outline0("INC HL" );
6085 // outhead1("LOOKFOR%sNEXT2:", _table );
6086 // outline0("INC HL" );
6087 // outline0("INC HL" );
6088 // outline0("INC C" );
6089 // outline0("MOV AL, C" );
6090 // outline1("CMP AL, 0x%4.4x", (_count+1) );
6091 // outline1("JR NZ, LOOKFOR%sL1", _table );
6092 // }
6093 // outline0("RET" );
6094
6095}
6096
6097void cpu_address_table_call( Environment * _environment, char * _table, char * _value, char * _address ) {
6098
6099 // outline1("MOV DE, [%s]", _value );
6100 // outline1("CALL LOOKFOR%s", _table );
6101 // outline1("MOV [%s], DE", _address );
6102
6103}
6104
6105void cpu_move_8bit_signed_16bit_signed( Environment * _environment, char *_source, char *_destination ) {
6106
6107 outline1("MOV AL, [%s]", _source );
6108 outline0("CBW" );
6109 outline1("MOV [%s], AX", _destination );
6110
6111}
6112
6113void cpu_move_8bit_signed_16bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6114
6115 outline1("MOV AL, [%s]", _source );
6116 outline0("CBW" );
6117 outline1("MOV [%s], AX", _destination );
6118
6119}
6120
6121void cpu_move_8bit_unsigned_16bit_signed( Environment * _environment, char *_source, char *_destination ){
6122
6123 outline1("MOV AL, [%s]", _source );
6124 outline0("MOV AH, 0" );
6125 outline1("MOV [%s], AX", _destination );
6126
6127}
6128
6129void cpu_move_8bit_unsigned_16bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6130
6131 outline1("MOV AL, [%s]", _source );
6132 outline0("MOV AH, 0" );
6133 outline1("MOV [%s], AX", _destination );
6134
6135}
6136
6137void cpu_move_8bit_signed_32bit_signed( Environment * _environment, char *_source, char *_destination ){
6138
6139 outline1("MOV AL, [%s]", _source );
6140 outline0("CBW" );
6141 outline0("CWD" );
6142 outline1("MOV [%s], AX", _destination );
6143 outline1("MOV [%s], DX", address_displacement( _environment, _destination, "+2" ) );
6144
6145}
6146
6147void cpu_move_8bit_signed_32bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6148
6149 outline1("MOV AL, [%s]", _source );
6150 outline0("CBW" );
6151 outline0("CWD" );
6152 outline1("MOV [%s], AX", _destination );
6153 outline1("MOV [%s], DX", address_displacement( _environment, _destination, "+2" ) );
6154
6155}
6156
6157void cpu_move_8bit_unsigned_32bit_signed( Environment * _environment, char *_source, char *_destination ){
6158
6159 outline1("MOV AL, [%s]", _source );
6160 outline0("MOV AH, 0" );
6161 outline1("MOV [%s], AX", _destination );
6162 outline0("MOV AX, 0" );
6163 outline1("MOV [%s], AX", address_displacement( _environment, _destination, "+2" ) );
6164
6165}
6166void cpu_move_8bit_unsigned_32bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6167
6168 outline1("MOV AL, [%s]", _source );
6169 outline0("MOV AH, 0" );
6170 outline1("MOV [%s], AX", _destination );
6171 outline0("MOV AX, 0" );
6172 outline1("MOV [%s], AX", address_displacement( _environment, _destination, "+2" ) );
6173
6174}
6175
6176void cpu_move_16bit_signed_8bit_signed( Environment * _environment, char *_source, char *_destination ){
6177
6178 outline1("MOV AX, [%s]", _source );
6179 outline1("MOV [%s], AL", _destination );
6180
6181}
6182
6183void cpu_move_16bit_signed_8bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6184
6185 outline1("MOV AX, [%s]", _source );
6186 outline1("MOV [%s], AL", _destination );
6187
6188}
6189void cpu_move_16bit_unsigned_8bit_signed( Environment * _environment, char *_source, char *_destination ){
6190
6191 outline1("MOV AX, [%s]", _source );
6192 outline1("MOV [%s], AL", _destination );
6193
6194}
6195void cpu_move_16bit_unsigned_8bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6196
6197 outline1("MOV AX, [%s]", _source );
6198 outline1("MOV [%s], AL", _destination );
6199
6200}
6201
6202void cpu_move_16bit_signed_32bit_signed( Environment * _environment, char *_source, char *_destination ){
6203
6204 outline1("MOV AX, [%s]", _source );
6205 outline0("CWD" );
6206 outline1("MOV [%s], AX", _destination );
6207 outline1("MOV [%s], DX", address_displacement( _environment, _destination, "+2" ) );
6208
6209}
6210
6211void cpu_move_16bit_signed_32bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6212
6213 outline1("MOV AX, [%s]", _source );
6214 outline0("CWD" );
6215 outline1("MOV [%s], AX", _destination );
6216 outline1("MOV [%s], DX", address_displacement( _environment, _destination, "+2" ) );
6217
6218}
6219
6220void cpu_move_16bit_unsigned_32bit_signed( Environment * _environment, char *_source, char *_destination ){
6221
6222 outline1("MOV AX, [%s]", _source );
6223 outline0("MOV DX, 0" );
6224 outline1("MOV [%s], AX", _destination );
6225 outline1("MOV [%s], DX", address_displacement( _environment, _destination, "+2" ) );
6226
6227}
6228void cpu_move_16bit_unsigned_32bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6229
6230 outline1("MOV AX, [%s]", _source );
6231 outline0("MOV DX, 0" );
6232 outline1("MOV [%s], AX", _destination );
6233 outline1("MOV [%s], DX", address_displacement( _environment, _destination, "+2" ) );
6234
6235}
6236
6237void cpu_move_32bit_signed_8bit_signed( Environment * _environment, char *_source, char *_destination ){
6238
6239 outline1("MOV AL, [%s]", _source );
6240 outline1("MOV [%s], AL", _destination );
6241
6242}
6243void cpu_move_32bit_signed_8bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6244
6245 outline1("MOV AL, [%s]", _source );
6246 outline1("MOV [%s], AL", _destination );
6247
6248}
6249void cpu_move_32bit_unsigned_8bit_signed( Environment * _environment, char *_source, char *_destination ){
6250
6251 outline1("MOV AL, [%s]", _source );
6252 outline1("MOV [%s], AL", _destination );
6253
6254}
6255void cpu_move_32bit_unsigned_8bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6256
6257 outline1("MOV AL, [%s]", _source );
6258 outline1("MOV [%s], AL", _destination );
6259
6260}
6261
6262void cpu_move_32bit_signed_16bit_signed( Environment * _environment, char *_source, char *_destination ){
6263
6264 outline1("MOV AX, [%s]", _source );
6265 outline1("MOV [%s], AX", _destination );
6266
6267}
6268
6269void cpu_move_32bit_signed_16bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6270
6271 outline1("MOV AX, [%s]", _source );
6272 outline1("MOV [%s], AX", _destination );
6273
6274}
6275
6276void cpu_move_32bit_unsigned_16bit_signed( Environment * _environment, char *_source, char *_destination ){
6277
6278 outline1("MOV AX, [%s]", _source );
6279 outline1("MOV [%s], AX", _destination );
6280
6281}
6282
6283void cpu_move_32bit_unsigned_16bit_unsigned( Environment * _environment, char *_source, char *_destination ){
6284
6285 outline1("MOV AX, [%s]", _source );
6286 outline1("MOV [%s], AX", _destination );
6287
6288}
6289
6290void cpu_float_fast_log( Environment * _environment, char * _value, char * _result ) {
6291
6293
6294}
6295
6296void cpu_float_single_log( Environment * _environment, char * _value, char * _result ) {
6297
6299
6300}
6301
6302void cpu_float_fast_exp( Environment * _environment, char * _value, char * _result ) {
6303
6305
6306}
6307
6308void cpu_float_single_exp( Environment * _environment, char * _value, char * _result ) {
6309
6311
6312}
6313
6314void cpu_hex_to_bin( Environment * _environment, char * _value_address, char * _value_size, char * _variable_address, char * _variable_size, char * _result ) {
6315
6316 // deploy( hex2bin, src_hw_8086_hex2bin_asm );
6317
6318 // outline1("LD HL, (%s)", _value_address );
6319 // outline1("LD DE, (%s)", _variable_address );
6320 // outline1("LD A, (%s)", _value_size );
6321 // outline0("LD C, A" );
6322 // outline1("LD A, (%s)", _variable_size );
6323 // outline0("LD B, A" );
6324 // outline0("CALL HEX2BIN" );
6325 // outline1("LD (%s), A", _result );
6326
6327}
6328
6329void cpu_dsfill( Environment * _environment, char * _string, char * _value ) {
6330
6331 // deploy_preferred( duff, src_hw_z80_duff_asm );
6332 // deploy( dstring, src_hw_z80_dstring_asm );
6333
6334 // outline1( "LD A, (%s)", _string );
6335 // outline0( "LD B, A" );
6336 // outline1( "LD A, (%s)", _value );
6337 // outline0( "CALL DSFILL" );
6338
6339}
6340
6341void cpu_dsfill_value( Environment * _environment, char * _string, int _value ) {
6342
6343 // deploy_preferred( duff, src_hw_z80_duff_asm );
6344 // deploy( dstring, src_hw_z80_dstring_asm );
6345
6346 // outline1( "LD A, (%s)", _string );
6347 // outline0( "LD B, A" );
6348 // outline1( "LD A, $%2.2x", (unsigned char)(_value&0xff) );
6349 // outline0( "CALL DSFILL" );
6350
6351}
6352#endif
void cpu_combine_nibbles(Environment *_environment, char *_low_nibble, char *_hi_nibble, char *_byte)
Definition 6309.c:3724
void cpu_math_double_32bit(Environment *_environment, char *_source, char *_other, int _signed)
CPU 6309: emit code to double a 32 bit value
Definition 6309.c:3279
void cpu_math_mul2_const_16bit(Environment *_environment, char *_source, int _steps, int _signed)
CPU 6309: emit code to halves for several times a 8 bit value
Definition 6309.c:2461
void cpu_math_mul_16bit_to_32bit(Environment *_environment, char *_source, char *_destination, char *_other, int _signed)
CPU 6309: emit code to multiply two 16 bit values in a 32 bit register
Definition 6309.c:1752
void cpu_bveq(Environment *_environment, char *_value, char *_label)
Definition 6309.c:334
void cpu_bit_check_extended(Environment *_environment, char *_value, char *_position, char *_result, int _bitwidth)
Definition 6309.c:5605
void cpu_math_mul2_const_8bit(Environment *_environment, char *_source, int _steps, int _signed)
CPU 6309: emit code to double for several times a 8 bit value
Definition 6309.c:1397
void cpu_math_mul2_const_32bit(Environment *_environment, char *_source, int _steps, int _signed)
CPU 6309: emit code to double for several times a 32 bit value
Definition 6309.c:3547
void cpu_math_sub_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
CPU 6309: emit code to subtract two 8 bit values
Definition 6309.c:1049
void cpu_math_add_32bit(Environment *_environment, char *_source, char *_destination, char *_other)
CPU 6309: emit code to add two 32 bit values
Definition 6309.c:3219
void cpu_store_char(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 8 bit
Definition 6309.c:785
void cpu_math_complement_const_32bit(Environment *_environment, char *_source, int _value)
CPU 6309: emit code to calculate a 32 bit complement of a number
Definition 6309.c:3352
void cpu_store_16bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 16 bit
Definition 6309.c:1503
void cpu_math_double_16bit(Environment *_environment, char *_source, char *_other, int _signed)
CPU 6309: emit code to double a 16 bit value
Definition 6309.c:1728
void cpu_math_sub_32bit(Environment *_environment, char *_source, char *_destination, char *_other)
CPU 6309: emit code to subtract two 32 bit values
Definition 6309.c:3304
void cpu_math_div2_const_8bit(Environment *_environment, char *_source, int _steps, int _signed, char *_remainder)
CPU 6309: emit code to halves for several times a 8 bit value
Definition 6309.c:1329
void cpu_math_div_nbit_to_nbit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _bits)
Definition 6309.c:2571
void cpu_math_add_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
CPU 6309: emit code to add two 8 bit values
Definition 6309.c:1017
void cpu_string_sub(Environment *_environment, char *_source, char *_source_size, char *_pattern, char *_pattern_size, char *_destination, char *_destination_size)
Definition 6309.c:6370
void cpu_compare_8bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
CPU 6309: emit code to compare two 8 bit values
Definition 6309.c:811
void cpu_math_and_const_32bit(Environment *_environment, char *_source, int _mask)
CPU 6309: emit code to mask with "and" a value of 32 bit
Definition 6309.c:3698
void cpu_addressof_16bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:1485
void cpu_math_complement_const_8bit(Environment *_environment, char *_source, int _value)
CPU 6309: emit code to calculate an 8 bit complement of a number
Definition 6309.c:1432
void cpu_math_complement_const_16bit(Environment *_environment, char *_source, int _value)
CPU 6309: emit code to calculate a 16 bit complement of a number
Definition 6309.c:2337
void cpu_math_mul2_const_nbit(Environment *_environment, char *_source, int _steps, int _bits)
Definition 6309.c:3664
void cpu_move_32bit(Environment *_environment, char *_source, char *_destination)
CPU 6309: emit code to move 32 bit
Definition 6309.c:2520
void cpu_less_than_8bit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _signed)
CPU 6309: emit code to compare two 8 bit values
Definition 6309.c:950
void cpu_dec_32bit(Environment *_environment, char *_variable)
Definition 6309.c:4652
void cpu_math_add_16bit(Environment *_environment, char *_source, char *_destination, char *_other)
CPU 6309: emit code to add two 16 bit values
Definition 6309.c:1661
void cpu_protothread_vars(Environment *_environment)
Definition 6309.c:6143
void cpu_math_add_16bit_with_16bit(Environment *_environment, char *_source, char *_destination, char *_other)
CPU 6309: emit code to add two 16 bit values
Definition 6309.c:1696
void cpu_compare_and_branch_16bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
CPU 6309: emit code to compare two 8 bit values and jump if they are equal/different
Definition 6309.c:1578
void cpu_fill(Environment *_environment, char *_address, char *_bytes, int _bytes_width, char *_pattern)
CPU 6309: emit code to fill up a memory area
Definition 6309.c:534
void cpu_math_mul_8bit_to_16bit(Environment *_environment, char *_source, char *_destination, char *_other, int _signed)
CPU 6309: emit code to multiply two 8bit values in a 16 bit register
Definition 6309.c:1088
void cpu_math_sub_16bit(Environment *_environment, char *_source, char *_destination, char *_other)
CPU 6309: emit code to subtract two 16 bit values
Definition 6309.c:2305
void cpu_compare_and_branch_32bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
CPU 6309: emit code to compare two 32 bit values and jump if they are equal/different
Definition 6309.c:2914
void cpu_math_and_const_16bit(Environment *_environment, char *_source, int _mask)
CPU 6309: emit code to mask with "and" a value of 16 bit
Definition 6309.c:2496
void cpu_less_than_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _bits)
Definition 6309.c:3065
void cpu_math_div2_const_32bit(Environment *_environment, char *_source, int _steps, int _signed, char *_remainder)
CPU 6309: emit code to halves for several times a 32 bit value
Definition 6309.c:3376
void cpu_move_16bit(Environment *_environment, char *_source, char *_destination)
CPU 6309: emit code to move 16 bit
Definition 6309.c:1474
void cpu_bneq(Environment *_environment, char *_label)
CPU 6309: emit code to make long conditional jump
Definition 6309.c:324
void cpu_math_double_8bit(Environment *_environment, char *_source, char *_other, int _signed)
CPU 6309: emit code to double a 8 bit value
Definition 6309.c:1068
void cpu_less_than_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _bits)
Definition 6309.c:3021
void cpu_hex_to_string(Environment *_environment, char *_number, char *_string, char *_size, int _separator)
Definition 6309.c:5865
void cpu_math_add_32bit_const(Environment *_environment, char *_source, int _destination, char *_other)
Definition 6309.c:3257
void cpu_store_8bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 8 bit
Definition 6309.c:761
void cpu_swap_8bit(Environment *_environment, char *_left, char *_right)
Definition 6309.c:4451
void cpu_compare_32bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
CPU 6309: emit code to compare two 32 bit values
Definition 6309.c:2769
void cpu_store_8bit_with_offset2(Environment *_environment, char *_source, char *_offset, int _value)
Definition 6309.c:6029
void cpu_fill_blocks(Environment *_environment, char *_address, char *_blocks, char *_pattern)
CPU 6309: emit code to fill up a memory area
Definition 6309.c:484
void cpu_bvneq(Environment *_environment, char *_value, char *_label)
Definition 6309.c:345
void cpu_compare_and_branch_16bit(Environment *_environment, char *_source, char *_destination, char *_label, int _positive)
Definition 6309.c:1552
void cpu_poke(Environment *_environment, char *_address, char *_source)
Definition 6309.c:377
void cpu_greater_than_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _bits)
Definition 6309.c:3189
void cpu_less_than_16bit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _signed)
CPU 6309: emit code to compare two 8 bit values
Definition 6309.c:1603
void cpu_math_and_const_8bit(Environment *_environment, char *_source, int _mask)
CPU 6309: emit code to mask with "and" a value of 8 bit
Definition 6309.c:1451
void cpu_inc_nbit(Environment *_environment, char *_variable, int _bits)
Definition 6309.c:4613
void cpu_math_div2_const_16bit(Environment *_environment, char *_source, int _steps, int _signed, char *_remainder)
CPU 6309: emit code to halves for several times a 16 bit value
Definition 6309.c:2356
void cpu_compare_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive, int _bits)
Definition 6309.c:2804
void cpu_ztoa(Environment *_environment)
Definition 6309.c:262
void cpu_random(Environment *_environment, char *_entropy)
Definition 6309.c:4075
void cpu_compare_and_branch_8bit(Environment *_environment, char *_source, char *_destination, char *_label, int _positive)
Definition 6309.c:851
void cpu_ctoa(Environment *_environment)
Definition 6309.c:279
void cpu_math_sub_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition 6309.c:3325
void cpu_math_div2_const_nbit(Environment *_environment, char *_source, int _steps, int _bits, char *_remainder)
Definition 6309.c:3503
void cpu_store_8bit_with_offset(Environment *_environment, char *_destination, int _value, int _offset)
Definition 6309.c:6021
void cpu_store_32bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 32 bit
Definition 6309.c:2540
void cpu_flip(Environment *_environment, char *_source, char *_size, char *_destination)
Definition 6309.c:5562
void cpu_move_8bit(Environment *_environment, char *_source, char *_destination)
CPU 6309: emit code to move 8 bit
Definition 6309.c:743
void cpu_beq(Environment *_environment, char *_label)
CPU 6309: emit code to make long conditional jump
Definition 6309.c:308
void cpu_compare_16bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
CPU 6309: emit code to compare two 16 bit values
Definition 6309.c:1523
void cpu_peek(Environment *_environment, char *_address, char *_target)
Definition 6309.c:366
void cpu_convert_string_into_16bit(Environment *_environment, char *_string, char *_len, char *_value)
Definition 6309.c:5502
void cpu_math_add_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition 6309.c:3238
void cpu_compare_and_branch_8bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
CPU 6309: emit code to compare two 8 bit values and jump if they are equal/different
Definition 6309.c:876
void cpu_less_than_32bit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _signed)
CPU 6309: emit code to compare two 32 bit values
Definition 6309.c:2949
#define IS_REGISTER(x)
Definition 6309.h:58
@ REGISTER_NONE
Definition 6309.h:62
@ STACK_NONE
Definition 6309.h:78
@ STACK_BYTE
Definition 6309.h:79
@ STACK_WORD
Definition 6309.h:80
@ STACK_DWORD
Definition 6309.h:81
@ REGISTER_CARRY
Definition 6502.h:76
@ REGISTER_ZERO
Definition 6502.h:77
void cpu_and_32bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3035
void cpu_float_single_cos(Environment *_environment, char *_angle, char *_result)
Definition 8086.c:6021
void cpu_protothread_get_state(Environment *_environment, char *_index, char *_state)
Definition 8086.c:5052
void cpu_float_fast_neg(Environment *_environment, char *_value, char *_result)
Definition 8086.c:5882
void cpu_set_callback(Environment *_environment, char *_callback, char *_label)
Definition 8086.c:5081
void cpu_move_32bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition 8086.c:4071
void cpu_dsfree(Environment *_environment, char *_index)
Definition 8086.c:4743
void cpu_less_than_memory_size(Environment *_environment, char *_source, char *_destination, int _size, char *_result, int _equal)
Definition 8086.c:3667
void cpu_dsresize_size(Environment *_environment, char *_index, int _resize)
Definition 8086.c:4774
void cpu_hex_to_string_calc_string(Environment *_environment, char *_size, int _separator, char *_string_size)
Definition 8086.c:4638
void cpu_move_8bit_signed_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6147
void cpu_float_fast_from_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition 8086.c:5810
void cpu_in(Environment *_environment, char *_port, char *_value)
Definition 8086.c:5161
void cpu_hex_to_string_calc_string_size(Environment *_environment, int _size, int _separator, char *_string_size)
Definition 8086.c:4651
void cpu_pokew(Environment *_environment, char *_address, char *_source)
Definition 8086.c:208
void cpu_move_32bit_signed_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6269
void cpu_combine_nibbles(Environment *_environment, char *_low_nibble, char *_hi_nibble, char *_byte)
Z80: emit code to combine nibbles
Definition 8086.c:2505
char * cpu_blit_register_name(Environment *_environment, int _register)
Definition 8086.c:5238
void cpu_di(Environment *_environment)
Definition 8086.c:3235
void cpu_float_fast_tan(Environment *_environment, char *_angle, char *_result)
Definition 8086.c:5870
void cpu_math_double_32bit(Environment *_environment, char *_source, char *_other, int _signed)
Z80: emit code to double a 32 bit value
Definition 8086.c:2283
void cpu_protothread_restore(Environment *_environment, char *_index, char *_step)
Definition 8086.c:5029
void cpu_msc1_uncompress_indirect_indirect(Environment *_environment, char *_input, char *_output)
Definition 8086.c:5137
void cpu_not_16bit(Environment *_environment, char *_value, char *_result)
Definition 8086.c:3217
void cpu_move_8bit_unsigned_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6157
void cpu_math_mul2_const_16bit(Environment *_environment, char *_source, int _steps, int _signed)
Z80: emit code to halves for several times a 8 bit value
Definition 8086.c:1883
void cpu_math_div_16bit_to_16bit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _signed)
Definition 8086.c:4186
void cpu_move_16bit_signed_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6202
void cpu_move_8bit_unsigned_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6121
void cpu_compare_32bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _positive)
Z80: emit code to compare two 32 bit values
Definition 8086.c:2013
void cpu_math_mul_16bit_to_32bit(Environment *_environment, char *_source, char *_destination, char *_other, int _signed)
Z80: emit code to multiply two 16 bit values in a 32 bit register
Definition 8086.c:1562
void cpu_swap_32bit(Environment *_environment, char *_left, char *_right)
Definition 8086.c:3194
void cpu_float_fast_from_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition 8086.c:5804
void cpu_bveq(Environment *_environment, char *_value, char *_label)
Definition 8086.c:132
void cpu_dsresize(Environment *_environment, char *_index, char *_resize)
Definition 8086.c:4763
void cpu_move_nbit_indirect(Environment *_environment, int _n, char *_source, char *_value)
Definition 8086.c:4006
void cpu_math_div_8bit_to_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _signed)
Definition 8086.c:4242
void cpu_bit_check_extended(Environment *_environment, char *_value, char *_position, char *_result, int _bitwidth)
Definition 8086.c:4441
void cpu_math_div_32bit_to_16bit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _signed)
Definition 8086.c:4148
void cpu_math_mul2_const_8bit(Environment *_environment, char *_source, int _steps, int _signed)
Z80: emit code to double for several times a 8 bit value
Definition 8086.c:1124
void cpu_float_fast_div(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5846
void cpu_move_32bit_signed_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6262
void cpu_move_32bit_unsigned_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6255
void cpu_math_mul2_const_32bit(Environment *_environment, char *_source, int _steps, int _signed)
Z80: emit code to double for several times a 32 bit value
Definition 8086.c:2434
void cpu_uppercase(Environment *_environment, char *_source, char *_size, char *_result)
Definition 8086.c:3747
void cpu_math_add_16bit_with_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Definition 8086.c:3719
void cpu_address_table_build(Environment *_environment, char *_table, int *_values, char *_address[], int _count)
Definition 8086.c:6048
void cpu_mem_move(Environment *_environment, char *_source, char *_destination, char *_size)
Definition 8086.c:3449
void cpu_set_asmio_indirect(Environment *_environment, int _asmio, char *_value)
Definition 8086.c:2694
void cpu_msc1_uncompress_direct_indirect(Environment *_environment, char *_input, char *_output)
Definition 8086.c:5105
void cpu_math_sub_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to subtract two 8 bit values
Definition 8086.c:1007
void cpu_xor_32bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition 8086.c:3155
void cpu_math_add_32bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to add two 32 bit values
Definition 8086.c:2215
void cpu_protothread_save(Environment *_environment, char *_index, int _step)
Definition 8086.c:5018
void cpu_store_char(Environment *_environment, char *_destination, int _value)
Z80: emit code to store 8 bit
Definition 8086.c:605
void cpu_math_complement_const_32bit(Environment *_environment, char *_source, int _value)
Z80: emit code to calculate a 32 bit complement of a number
Definition 8086.c:2351
void cpu_store_16bit(Environment *_environment, char *_destination, int _value)
Z80: emit code to store 16 bit
Definition 8086.c:1222
void cpu_poked(Environment *_environment, char *_address, char *_source)
Definition 8086.c:248
void cpu_and_8bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition 8086.c:3017
void cpu_dsassign(Environment *_environment, char *_original, char *_copy)
Definition 8086.c:4823
void cpu_math_double_16bit(Environment *_environment, char *_source, char *_other, int _signed)
Z80: emit code to double a 16 bit value
Definition 8086.c:1538
void cpu_math_sub_32bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to subtract two 32 bit values
Definition 8086.c:2305
void cpu_complement2_8bit(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:4858
void cpu_msc1_uncompress_indirect_direct(Environment *_environment, char *_input, char *_output)
Definition 8086.c:5121
void cpu_math_div2_const_8bit(Environment *_environment, char *_source, int _steps, int _signed, char *_remainder)
Z80: emit code to halves for several times a 8 bit value
Definition 8086.c:1093
void cpu_less_than_memory(Environment *_environment, char *_source, char *_destination, char *_size, char *_result, int _equal)
Definition 8086.c:3629
void cpu_dsalloc_size(Environment *_environment, int _size, char *_index)
Definition 8086.c:4732
void cpu_get_asmio_indirect(Environment *_environment, int _asmio, char *_value)
Definition 8086.c:2784
void cpu_move_16bit_unsigned_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6195
void cpu_float_fast_cos(Environment *_environment, char *_angle, char *_result)
Definition 8086.c:5864
void cpu_protothread_set_state(Environment *_environment, char *_index, int _state)
Definition 8086.c:5041
void cpu_math_div_nbit_to_nbit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _bits)
Definition 8086.c:4260
void cpu_math_add_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to add two 8 bit values
Definition 8086.c:969
void cpu_float_single_add(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5924
void cpu_float_single_sub(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5935
void cpu_bit_inplace_8bit_extended_indirect(Environment *_environment, char *_address, char *_position, char *_bit)
Definition 8086.c:4487
void cpu_move_8bit_unsigned_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6166
void cpu_move_8bit_indirect(Environment *_environment, char *_source, char *_value)
Definition 8086.c:3908
void cpu_string_sub(Environment *_environment, char *_source, char *_source_size, char *_pattern, char *_pattern_size, char *_destination, char *_destination_size)
Definition 8086.c:5185
void cpu_compare_8bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
Z80: emit code to compare two 8 bit values
Definition 8086.c:648
void cpu_math_and_const_32bit(Environment *_environment, char *_source, int _mask)
Z80: emit code to mask with "and" a value of 32 bit
Definition 8086.c:2487
void cpu_fill_direct_size(Environment *_environment, char *_address, int _bytes, char *_pattern)
Z80: emit code to fill up a memory area
Definition 8086.c:485
void cpu_addressof_16bit(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:1204
void cpu_dec_16bit(Environment *_environment, char *_variable)
Definition 8086.c:3305
void cpu_dsgc(Environment *_environment)
Definition 8086.c:4785
void cpu_move_16bit_signed_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6211
void cpu_inc(Environment *_environment, char *_variable)
Definition 8086.c:3247
void cpu_poke_const(Environment *_environment, char *_address, int _source)
Definition 8086.c:184
void cpu_fill_direct(Environment *_environment, char *_address, char *_bytes, char *_pattern)
Z80: emit code to fill up a memory area
Definition 8086.c:451
void cpu_jump_indirect(Environment *_environment, char *_value)
Definition 8086.c:2546
void cpu_math_complement_const_8bit(Environment *_environment, char *_source, int _value)
Z80: emit code to calculate an 8 bit complement of a number
Definition 8086.c:1150
void cpu_dsdefine(Environment *_environment, char *_string, char *_index)
Definition 8086.c:4710
void cpu_math_complement_const_16bit(Environment *_environment, char *_source, int _value)
Z80: emit code to calculate a 16 bit complement of a number
Definition 8086.c:1824
void cpu_move_16bit_unsigned_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6228
void cpu_math_mul2_const_nbit(Environment *_environment, char *_source, int _steps, int _bits)
Definition 8086.c:1718
void cpu_float_single_exp(Environment *_environment, char *_value, char *_result)
Definition 8086.c:6308
void cpu_move_32bit(Environment *_environment, char *_source, char *_destination)
Z80: emit code to move 32 bit
Definition 8086.c:1928
void cpu_fill_size(Environment *_environment, char *_address, int _bytes, char *_pattern)
Z80: emit code to fill up a memory area
Definition 8086.c:364
void cpu_dsfill(Environment *_environment, char *_string, char *_value)
Definition 8086.c:6329
void cpu_less_than_8bit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _signed)
Z80: emit code to compare two 8 bit values
Definition 8086.c:836
void cpu_fill_direct_size_value(Environment *_environment, char *_address, int _bytes, int _pattern)
Z80: emit code to fill up a memory area
Definition 8086.c:531
void cpu_float_double_to_string(Environment *_environment, char *_x, char *_string, char *_string_size)
Definition 8086.c:5800
void cpu_dec_32bit(Environment *_environment, char *_variable)
Definition 8086.c:3313
void cpu_greater_than_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 8086.c:1473
void cpu_protothread_get_address(Environment *_environment, char *_index, char *_address)
Definition 8086.c:5062
void cpu_math_add_16bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to add two 16 bit values
Definition 8086.c:1488
void cpu_greater_than_16bit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _signed)
Z80: emit code to compare two 8 bit values
Definition 8086.c:1462
void cpu_bit_inplace_8bit(Environment *_environment, char *_value, int _position, int *_bit)
Definition 8086.c:4461
void cpu_math_add_16bit_const(Environment *_environment, char *_source, int _destination, char *_other)
CPU 6502: emit code to add two 16 bit values
Definition 8086.c:1505
void cpu_protothread_vars(Environment *_environment)
Definition 8086.c:4958
void cpu_poked_const(Environment *_environment, char *_address, int _source)
Definition 8086.c:264
void cpu_math_add_16bit_with_16bit(Environment *_environment, char *_source, char *_destination, char *_other)
CPU 6309: emit code to add two 16 bit values
Definition 8086.c:1518
void cpu_compare_and_branch_16bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
Z80: emit code to compare two 16 bit values and jump if they are equal/different
Definition 8086.c:1337
void cpu_move_32bit_indirect(Environment *_environment, char *_source, char *_value)
Definition 8086.c:3994
void cpu_dswrite(Environment *_environment, char *_index)
Definition 8086.c:4753
void cpu_complement2_nbit(Environment *_environment, char *_source, char *_destination, int _bits)
Definition 8086.c:4910
void cpu_greater_than_8bit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _signed)
Z80: emit code to compare two 8 bit values
Definition 8086.c:943
void cpu_or_16bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3087
void cpu_fill(Environment *_environment, char *_address, char *_bytes, int _bytes_width, char *_pattern)
Z80: emit code to fill up a memory area
Definition 8086.c:321
void cpu_move_16bit_indirect(Environment *_environment, char *_source, char *_value)
Definition 8086.c:3966
void cpu_limit_16bit(Environment *_environment, char *_variable, int _value)
Definition 8086.c:2948
void cpu_move_8bit_indirect_with_offset2(Environment *_environment, char *_source, char *_value, char *_offset)
Definition 8086.c:4847
void cpu_less_than_32bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 8086.c:2122
void cpu_move_nbit_indirect2(Environment *_environment, int _n, char *_value, char *_source)
Definition 8086.c:4083
void cpu_and_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3008
void cpu_float_single_log(Environment *_environment, char *_value, char *_result)
Definition 8086.c:6296
void cpu_math_mul_8bit_to_16bit(Environment *_environment, char *_source, char *_destination, char *_other, int _signed)
Z80: emit code to multiply two 8bit values in a 16 bit register
Definition 8086.c:1056
void cpu_compare_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _positive)
Z80: emit code to compare two 16 bit values
Definition 8086.c:1279
void cpu_math_sub_16bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to subtract two 16 bit values
Definition 8086.c:1800
void cpu_compare_and_branch_32bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
Z80: emit code to compare two 32 bit values and jump if they are equal/different
Definition 8086.c:2048
void cpu_store_nbit(Environment *_environment, char *_destination, int _n, int _value[])
CPU Z80: emit code to store n bit
Definition 8086.c:5326
void cpu_mem_move_direct_indirect_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition 8086.c:3536
void cpu_dec_nbit(Environment *_environment, char *_variable, int _bits)
Definition 8086.c:3329
void cpu_math_and_const_16bit(Environment *_environment, char *_source, int _mask)
Z80: emit code to mask with "and" a value of 16 bit
Definition 8086.c:1905
void cpu_move_8bit_indirect2_8bit(Environment *_environment, char *_value, char *_offset, char *_source)
Definition 8086.c:3945
void cpu_float_single_from_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition 8086.c:5888
void cpu_less_than_and_branch_8bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _equal, int _signed)
Definition 8086.c:902
void cpu_fill_indirect(Environment *_environment, char *_address, char *_size, char *_pattern, int _size_size)
Definition 8086.c:3842
void cpu_mem_move_indirect_direct_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition 8086.c:3551
void cpu_compare_and_branch_char_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
Z80: emit code to compare two 8 bit values and jump if they are equal/different
Definition 8086.c:809
void cpu_less_than_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _bits)
Definition 8086.c:3402
void cpu_float_fast_sin(Environment *_environment, char *_angle, char *_result)
Definition 8086.c:5858
void cpu_math_mul_nbit_to_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition 8086.c:1587
void cpu_label(Environment *_environment, char *_label)
Definition 8086.c:156
void cpu_dec(Environment *_environment, char *_variable)
Definition 8086.c:3255
void cpu_and_16bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3026
#define CPU8086_BLIT_REGISTER_COUNT
Definition 8086.c:5212
void cpu_float_fast_log(Environment *_environment, char *_value, char *_result)
Definition 8086.c:6290
void cpu_move_nbit(Environment *_environment, int _n, char *_source, char *_destination)
CPU Z80: emit code to store n bit
Definition 8086.c:5391
void cpu_address_table_call(Environment *_environment, char *_table, char *_value, char *_address)
Definition 8086.c:6097
void cpu_logical_not_8bit(Environment *_environment, char *_value, char *_result)
Definition 8086.c:3201
void cpu_pokew_const(Environment *_environment, char *_address, int _source)
Definition 8086.c:220
void cpu_logical_and_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:2988
void cpu_or_8bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition 8086.c:3078
void cpu_math_div2_const_32bit(Environment *_environment, char *_source, int _steps, int _signed, char *_remainder)
Z80: emit code to halves for several times a 32 bit value
Definition 8086.c:2375
void cpu_halt(Environment *_environment)
Definition 8086.c:2886
void cpu_end(Environment *_environment)
Definition 8086.c:2895
void cpu_float_fast_from_double_to_int_array(Environment *_environment, double _value, int _result[])
Definition 8086.c:5530
void cpu_compare_memory(Environment *_environment, char *_source, char *_destination, char *_size, char *_result, int _equal)
Definition 8086.c:3566
void cpu_greater_than_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 8086.c:954
void cpu_complement2_16bit(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:4873
void cpu_dsinit(Environment *_environment)
Definition 8086.c:4794
void cpu_xor_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3107
void cpu_protothread_unregister(Environment *_environment, char *_index)
Definition 8086.c:5008
void cpu_decrypt(Environment *_environment, char *_data, char *_data_size, char *_key, char *_key_size, char *_output, char *_result)
Definition 8086.c:4695
void cpu_complement2_32bit(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:4888
void cpu_protothread_register_at(Environment *_environment, char *_index, char *_label)
Definition 8086.c:4985
void cpu_blit_free_register(Environment *_environment, int _register)
Definition 8086.c:5285
void cpu_lowercase(Environment *_environment, char *_source, char *_size, char *_result)
Definition 8086.c:3783
void cpu_float_single_to_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition 8086.c:5915
void cpu_move_16bit(Environment *_environment, char *_source, char *_destination)
Z80: emit code to move 16 bit
Definition 8086.c:1193
void cpu_move_8bit_with_offset2(Environment *_environment, char *_source, char *_value, char *_offset)
Definition 8086.c:3916
void cpu_out(Environment *_environment, char *_port, char *_value)
Definition 8086.c:5153
void cpu_move_16bit_unsigned_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6189
void cpu_blit_finalize(Environment *_environment)
Definition 8086.c:5226
void cpu_encrypt(Environment *_environment, char *_data, char *_data_size, char *_key, char *_key_size, char *_output)
Definition 8086.c:4682
void cpu_bneq(Environment *_environment, char *_label)
Z80: emit code to make long conditional jump
Definition 8086.c:122
void cpu_compare_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, int _positive, int _bits)
CPU 6502: emit code to compare two 32 bit values
Definition 8086.c:5495
void cpu_move_16bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition 8086.c:3974
void cpu_float_fast_cmp(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5852
void cpu_math_double_8bit(Environment *_environment, char *_source, char *_other, int _signed)
Z80: emit code to double a 8 bit value
Definition 8086.c:1031
void cpu_float_fast_mul(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5840
void cpu_bits_to_string(Environment *_environment, char *_number, char *_string, char *_string_size, int _bits, char *_zero, char *_one)
Definition 8086.c:4596
void cpu_dsalloc(Environment *_environment, char *_size, char *_index)
Definition 8086.c:4721
void cpu_less_than_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _bits)
Definition 8086.c:3349
void cpu_port_out(Environment *_environment, char *_port, char *_value)
Z80: emit code to send one byte throught a I/O port
Definition 8086.c:2979
void cpu_not_32bit(Environment *_environment, char *_value, char *_result)
Definition 8086.c:3225
void cpu_float_single_from_double_to_int_array(Environment *_environment, double _value, int _result[])
Definition 8086.c:5541
void cpu_float_single_to_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition 8086.c:5906
void cpu_greater_than_memory_size(Environment *_environment, char *_source, char *_destination, int _size, char *_result, int _equal)
Definition 8086.c:3712
void cpu_hex_to_string(Environment *_environment, char *_number, char *_string, char *_size, int _separator)
Definition 8086.c:4664
void cpu_or_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3069
void cpu_store_8bit_with_offset2(Environment *_environment, char *_destination, char *_offset, int _value)
Definition 8086.c:625
void cpu_move_8bit_indirect2_16bit(Environment *_environment, char *_value, char *_offset, char *_source)
Definition 8086.c:3956
void cpu_math_add_32bit_const(Environment *_environment, char *_source, int _destination, char *_other)
Definition 8086.c:2240
void cpu_move_8bit_indirect_with_offset(Environment *_environment, char *_source, char *_value, int _offset)
Definition 8086.c:3927
void cpu_sqroot(Environment *_environment, char *_number, char *_result)
Definition 8086.c:4930
void cpu_number_to_string(Environment *_environment, char *_number, char *_string, char *_string_size, int _bits, int _signed)
Definition 8086.c:4521
void cpu_greater_than_32bit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _signed)
Z80: emit code to compare two 8 bit values
Definition 8086.c:2167
void cpu_peekd(Environment *_environment, char *_address, char *_target)
Definition 8086.c:232
void cpu_in_direct(Environment *_environment, char *_port, char *_value)
Definition 8086.c:5177
void cpu_call_indirect(Environment *_environment, char *_value)
Definition 8086.c:2540
void cpu_call(Environment *_environment, char *_label)
Definition 8086.c:2534
void cpu_random_8bit(Environment *_environment, char *_entropy, char *_result)
Definition 8086.c:2914
void cpu_xor_8bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition 8086.c:3116
void cpu_move_16bit_signed_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6183
void cpu_mem_move_direct(Environment *_environment, char *_source, char *_destination, char *_size)
Definition 8086.c:3472
void cpu_store_8bit(Environment *_environment, char *_destination, int _value)
Z80: emit code to store 8 bit
Definition 8086.c:588
void cpu_swap_8bit(Environment *_environment, char *_left, char *_right)
Definition 8086.c:3166
void cpu_float_fast_to_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition 8086.c:5822
void cpu_mem_move_direct2(Environment *_environment, char *_source, char *_destination, char *_size)
Definition 8086.c:3484
void cpu_init(Environment *_environment)
Definition 8086.c:45
void cpu_dstring_vars(Environment *_environment)
Definition 8086.c:4943
void cpu_protothread_loop(Environment *_environment)
Definition 8086.c:4977
void cpu_float_single_div(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5957
void cpu_hex_to_bin(Environment *_environment, char *_value_address, char *_value_size, char *_variable_address, char *_variable_size, char *_result)
Definition 8086.c:6314
void cpu_out_direct(Environment *_environment, char *_port, char *_value)
Definition 8086.c:5169
void cpu_greater_than_32bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 8086.c:2178
void cpu_protothread_current(Environment *_environment, char *_current)
Definition 8086.c:5072
void cpu_float_fast_to_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition 8086.c:5816
void cpu_mem_move_16bit(Environment *_environment, char *_source, char *_destination, char *_size)
Definition 8086.c:3461
void cpu_compare_32bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
Z80: emit code to compare two 32 bit values
Definition 8086.c:1970
void cpu_set_asmio(Environment *_environment, int _asmio, int _value)
Definition 8086.c:2604
void cpu_float_fast_sqr(Environment *_environment, char *_value, char *_result)
Definition 8086.c:5876
void cpu_jump(Environment *_environment, char *_label)
Definition 8086.c:2522
void cpu_move_16bit_unsigned_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6220
int cpu_blit_alloc_register(Environment *_environment)
Definition 8086.c:5247
void cpu_move_32bit_signed_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6243
void cpu_mem_move_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition 8086.c:3506
void cpu_fill_blocks(Environment *_environment, char *_address, char *_blocks, char *_pattern)
Z80: emit code to fill up a memory area
Definition 8086.c:293
void cpu_bvneq(Environment *_environment, char *_value, char *_label)
Definition 8086.c:144
void cpu_float_single_mul(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5946
void cpu_float_fast_exp(Environment *_environment, char *_value, char *_result)
Definition 8086.c:6302
void cpu_move_16bit_signed_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6176
void cpu_compare_and_branch_16bit(Environment *_environment, char *_source, char *_destination, char *_label, int _positive)
Definition 8086.c:1309
void cpu_fill_size_value(Environment *_environment, char *_address, int _bytes, int _pattern)
Z80: emit code to fill up a memory area
Definition 8086.c:410
void cpu_call_addr(Environment *_environment, int _address)
Definition 8086.c:2528
void cpu_math_div_16bit_to_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _signed)
Definition 8086.c:4205
void cpu_poke(Environment *_environment, char *_address, char *_source)
Definition 8086.c:172
void cpu_bit_check(Environment *_environment, char *_value, int _position, char *_result, int _bitwidth)
Definition 8086.c:4423
void cpu_protothread_register(Environment *_environment, char *_label, char *_index)
Definition 8086.c:4996
void cpu_move_32bit_signed_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6237
void cpu_float_single_to_string(Environment *_environment, char *_x, char *_string, char *_string_size)
Definition 8086.c:5784
void cpu_math_div_nbit_to_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _bits)
Definition 8086.c:4390
void cpu_float_single_tan(Environment *_environment, char *_angle, char *_result)
Definition 8086.c:6032
void cpu_nop(Environment *_environment)
Definition 8086.c:52
void cpu_random_32bit(Environment *_environment, char *_entropy, char *_result)
Definition 8086.c:2936
void cpu_move_32bit_unsigned_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6283
void cpu_less_than_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 8086.c:869
void cpu_greater_than_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _bits)
Definition 8086.c:2185
void cpu_prepare_for_compare_and_branch_8bit(Environment *_environment, char *_source)
Z80: emit code to compare two 8 bit values and jump if they are equal/different
Definition 8086.c:764
void cpu_less_than_16bit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _signed)
Z80: emit code to compare two 8 bit values
Definition 8086.c:1365
void cpu_mem_move_direct2_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition 8086.c:3495
void cpu_math_and_const_8bit(Environment *_environment, char *_source, int _mask)
Z80: emit code to mask with "and" a value of 8 bit
Definition 8086.c:1170
void cpu_move_32bit_unsigned_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6276
void cpu_msc1_uncompress_direct_direct(Environment *_environment, char *_input, char *_output)
Definition 8086.c:5089
void cpu_float_single_sqr(Environment *_environment, char *_value, char *_result)
Definition 8086.c:6042
void cpu_inc_32bit(Environment *_environment, char *_variable)
Definition 8086.c:3271
void cpu_move_8bit_signed_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6105
void cpu_mem_move_direct_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition 8086.c:3521
void cpu_float_fast_sub(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5834
void cpu_xor_32bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3144
void cpu_return(Environment *_environment)
Definition 8086.c:2874
void cpu_move_8bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition 8086.c:3937
void cpu_inc_nbit(Environment *_environment, char *_variable, int _bits)
Definition 8086.c:3286
void cpu_pop(Environment *_environment)
Definition 8086.c:2880
void cpu_math_sub_16bit_with_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Definition 8086.c:3733
void cpu_random_16bit(Environment *_environment, char *_entropy, char *_result)
Definition 8086.c:2925
void cpu_ei(Environment *_environment)
Definition 8086.c:3241
int cpu_register_decode(Environment *_environment, char *_register)
Definition 8086.c:2552
void cpu_or_32bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3096
void cpu_bits_to_string_vars(Environment *_environment)
Definition 8086.c:4589
void cpu_math_div2_const_16bit(Environment *_environment, char *_source, int _steps, int _signed, char *_remainder)
Z80: emit code to halves for several times a 16 bit value
Definition 8086.c:1844
void cpu_convert_string_into_8bit(Environment *_environment, char *_string, char *_len, char *_value)
Definition 8086.c:3819
void cpu_inc_16bit(Environment *_environment, char *_variable)
Definition 8086.c:3263
void cpu_logical_or_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3046
void cpu_compare_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive, int _bits)
CPU Z80: emit code to compare n bit
Definition 8086.c:5463
void cpu_address_table_lookup(Environment *_environment, char *_table, int _count)
Definition 8086.c:6057
void cpu_ztoa(Environment *_environment)
Definition 8086.c:58
void cpu_random(Environment *_environment, char *_entropy)
Definition 8086.c:2901
void cpu_move_32bit_unsigned_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6249
void cpu_compare_and_branch_8bit(Environment *_environment, char *_source, char *_destination, char *_label, int _positive)
Definition 8086.c:708
void cpu_execute_compare_and_branch_8bit_const(Environment *_environment, int _destination, char *_label, int _positive)
Z80: emit code to compare two 8 bit values and jump if they are equal/different
Definition 8086.c:783
void cpu_ctoa(Environment *_environment)
Definition 8086.c:75
void cpu_move_16bit_indirect2_8bit(Environment *_environment, char *_value, char *_offset, char *_source)
Definition 8086.c:3982
void cpu_float_single_from_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition 8086.c:5897
void cpu_math_sub_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition 8086.c:2324
void cpu_float_single_cmp(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5968
void cpu_move_8bit_signed_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6137
void cpu_math_div2_const_nbit(Environment *_environment, char *_source, int _steps, int _bits, char *_remainder)
Definition 8086.c:1749
void cpu_store_8bit_with_offset(Environment *_environment, char *_destination, int _value, int _offset)
Definition 8086.c:615
void cpu_busy_wait(Environment *_environment, char *_timing)
Definition 8086.c:2961
void cpu_greater_than_memory(Environment *_environment, char *_source, char *_destination, char *_size, char *_result, int _equal)
Definition 8086.c:3705
void cpu_store_32bit(Environment *_environment, char *_destination, int _value)
Z80: emit code to store 32 bit
Definition 8086.c:1948
void cpu_peekw(Environment *_environment, char *_address, char *_target)
Definition 8086.c:196
void cpu_flip(Environment *_environment, char *_source, char *_size, char *_destination)
Definition 8086.c:3893
void cpu_move_8bit(Environment *_environment, char *_source, char *_destination)
Z80: emit code to move 8 bit
Definition 8086.c:570
void cpu_beq(Environment *_environment, char *_label)
Z80: emit code to make long conditional jump
Definition 8086.c:106
void cpu_compare_16bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
Z80: emit code to compare two 16 bit values
Definition 8086.c:1241
void cpu_peek(Environment *_environment, char *_address, char *_target)
Definition 8086.c:160
void cpu_float_fast_add(Environment *_environment, char *_x, char *_y, char *_result)
Definition 8086.c:5828
void cpu_convert_string_into_16bit(Environment *_environment, char *_string, char *_len, char *_value)
Definition 8086.c:3827
void cpu_float_single_sin(Environment *_environment, char *_angle, char *_result)
Definition 8086.c:6015
void cpu_not_8bit(Environment *_environment, char *_value, char *_result)
Definition 8086.c:3209
void cpu_math_div_8bit_to_8bit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _signed)
Definition 8086.c:4224
void cpu_dsdescriptor(Environment *_environment, char *_index, char *_address, char *_size)
Definition 8086.c:4803
void cpu_math_add_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition 8086.c:2257
void cpu_compare_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _positive)
Z80: emit code to compare two 8 bit values
Definition 8086.c:687
void cpu_xor_16bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 8086.c:3125
void cpu_xor_16bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition 8086.c:3134
void cpu_float_single_neg(Environment *_environment, char *_value, char *_result)
Definition 8086.c:6001
void cpu_float_double_from_double_to_int_array(Environment *_environment, double _value, int _result[])
Definition 8086.c:5774
void cpu_swap_16bit(Environment *_environment, char *_left, char *_right)
Definition 8086.c:3180
void cpu_compare_and_branch_8bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
Z80: emit code to compare two 8 bit values and jump if they are equal/different
Definition 8086.c:736
void cpu_math_div_32bit_to_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _signed)
Definition 8086.c:4167
void cpu_greater_than_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _bits)
Definition 8086.c:2196
void cpu_number_to_string_vars(Environment *_environment)
Definition 8086.c:4513
void cpu_float_fast_to_string(Environment *_environment, char *_x, char *_string, char *_string_size)
Definition 8086.c:5778
void cpu_less_than_32bit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _signed)
Z80: emit code to compare two 8 bit values
Definition 8086.c:2085
void cpu_dsfill_value(Environment *_environment, char *_string, int _value)
Definition 8086.c:6341
void cpu_dsassign_string(Environment *_environment, char *_string, char *_copy)
Definition 8086.c:4835
void cpu_move_8bit_signed_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6113
void cpu_move_8bit_unsigned_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:6129
void cpu_compare_memory_size(Environment *_environment, char *_source, char *_destination, int _size, char *_result, int _equal)
Definition 8086.c:3594
void cpu_math_add_8bit_const(Environment *_environment, char *_source, int _destination, char *_other)
CPU 6502: emit code to add two 8 bit values
Definition 8086.c:986
void cpu_flip_8bit(Environment *_environment, char *_source, char *_destination)
Definition 8086.c:3873
void cpu_blit_initialize(Environment *_environment)
Definition 8086.c:5214
void cpu_less_than_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 8086.c:1409
enum _CPU8086Stack CPU8086Stack
enum _CPU8086Register CPU8086Register
@ REGISTER_DI
Definition 8086.h:77
@ REGISTER_BH
Definition 8086.h:65
@ REGISTER_BL
Definition 8086.h:64
@ REGISTER_AL
Definition 8086.h:62
@ REGISTER_CH
Definition 8086.h:67
@ REGISTER_CL
Definition 8086.h:66
@ REGISTER_DL
Definition 8086.h:68
@ REGISTER_DH
Definition 8086.h:69
@ REGISTER_DX
Definition 8086.h:73
@ REGISTER_BP
Definition 8086.h:75
@ REGISTER_SI
Definition 8086.h:76
@ REGISTER_CX
Definition 8086.h:72
@ REGISTER_BX
Definition 8086.h:71
@ REGISTER_AX
Definition 8086.h:70
@ REGISTER_SP
Definition 8086.h:74
@ REGISTER_AH
Definition 8086.h:63
Variable * variable_import(Environment *_environment, char *_name, VariableType _type, int _size_or_value)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
Variable * variable_store(Environment *_environment, char *_destination, unsigned int _value)
Store a direct value to a variable.
char * address_displacement(Environment *_environment, char *_address, char *_displacement)
int offset
Definition _optimizer.c:681
#define DSTRING_DEFAULT_SPACE
Definition atari.h:152
#define DSTRING_DEFAULT_COUNT
Definition atari.h:151
Variable * decrypt(Environment *_environment, char *_data, char *_key, char *_var)
Emit code for DECRYPT.
Definition decrypt.c:81
Variable * encrypt(Environment *_environment, char *_data, char *_key)
Emit code for ENCRYPT.
Definition encrypt.c:79
Variable * sign(Environment *_environment, char *_value)
Return the sign of a variable.
Definition sgn.c:85
int usedMemory
Definition ugbc.h:2167
char * name
Definition ugbc.h:2164
int freeRegisters
Definition ugbc.h:2166
char * realName
Definition ugbc.h:2165
int cpu_math_div_nbit_to_nbit_const[32]
Definition ugbc.h:2087
int cpu_math_div_nbit_to_nbit[32]
Definition ugbc.h:2086
int cpu_math_mul_nbit_to_nbit[32]
Definition ugbc.h:2085
int space
Definition ugbc.h:1970
int count
Definition ugbc.h:1969
int stackStartAddress
Definition ugbc.h:3296
int bitmaskNeeded
Definition ugbc.h:2659
DString dstring
Definition ugbc.h:2405
Blit blit
Definition ugbc.h:2474
int stackSize
Definition ugbc.h:3294
ProtothreadConfig protothreadConfig
Definition ugbc.h:2430
int emptyProcedure
Definition ugbc.h:2932
CpuOptimization cpuOptimization
Definition ugbc.h:3267
char * realName
Definition ugbc.h:982
#define no_embedded(s)
Definition ugbc.h:4380
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define embedded(s, e)
Definition ugbc.h:4385
#define deploy_with_vars(s, e, v)
Definition ugbc.h:4320
#define CRITICAL_DEBUG_UNSUPPORTED(v, t)
Definition ugbc.h:3478
#define no_inline(s)
Definition ugbc.h:4376
#define outline3(s, a, b, c)
Definition ugbc.h:4255
#define done()
Definition ugbc.h:4389
#define CRITICAL_BLIT_ALLOC_REGISTER_EXHAUSTED()
Definition ugbc.h:3610
struct _Variable Variable
Structure of a single variable.
#define outline2(s, a, b)
Definition ugbc.h:4254
struct _Environment Environment
Structure of compilation environment.
#define CRITICAL_BLIT_INVALID_FREE_REGISTER(s, r)
Definition ugbc.h:3612
#define CRITICAL_BLIT_ALLOC_MEMORY_EXHAUSTED()
Definition ugbc.h:3611
@ VT_WORD
Definition ugbc.h:455
@ VT_BYTE
Definition ugbc.h:450
#define CRITICAL_UNKNOWN_CPU_REGISTER()
Definition ugbc.h:3624
#define deploy_preferred(s, e)
Definition ugbc.h:4299
#define outhead0(s)
Definition ugbc.h:4246
#define outline0(s)
Definition ugbc.h:4252
#define outhead2(s, a, b)
Definition ugbc.h:4248
#define outline1(s, a)
Definition ugbc.h:4253
#define CRITICAL_UNIMPLEMENTED(v)
Definition ugbc.h:3444
#define deploy(s, e)
Definition ugbc.h:4288
#define MAKE_LABEL
Definition ugbc.h:3351
#define outhead1(s, a)
Definition ugbc.h:4247