ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
z80.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(__zx__) || defined(__msx1__) || defined(__coleco__) || defined(__sc3000__) || defined(__sg1000__) || defined(__cpc__) || defined(__vg5000__) || defined(__c128z__) || defined(__vz200__)
44
45void cpu_init( Environment * _environment ) {
46
47 _environment->stackSize = 0xffff;
48 _environment->stackStartAddress = 0x0000;
49
50 char duffDevice[38] = {
51 // +00
52 0x18, 0x00, 0xED, 0xA0, 0xED, 0xA0, 0xED, 0xA0,
53 // +08
54 0xED, 0xA0, 0xED, 0xA0, 0xED, 0xA0, 0xED, 0xA0,
55 // +16
56 0xED, 0xA0, 0xED, 0xA0, 0xED, 0xA0, 0xED, 0xA0,
57 // +24
58 0xED, 0xA0, 0xED, 0xA0, 0xED, 0xA0, 0xED, 0xA0,
59 // +32
60 0xED, 0xA0, 0xEA, 0x00, 0x00, 0xC9
61 };
62
63 variable_import( _environment, "DUFFDEVICEL0", VT_BUFFER, 36 );
64 variable_global( _environment, "DUFFDEVICEL0" );
65 variable_import( _environment, "DUFFDEVICEL1", VT_ADDRESS, 0 );
66 variable_global( _environment, "DUFFDEVICEL1" );
67
68 variable_retrieve( _environment, "DUFFDEVICEL0" )->readonly = 0;
69
70 variable_store_buffer( _environment, "DUFFDEVICEL0", duffDevice, sizeof( duffDevice ), 0 );
71
72 outline0( "LD HL, DUFFDEVICEL0");
73 outline0( "LD DE, 35");
74 outline0( "ADD HL, DE");
75 outline0( "LD DE, DUFFDEVICEL0");
76 outline0( "INC DE");
77 outline0( "INC DE");
78 outline0( "LD (HL), DE");
79
80 variable_import( _environment, "CALLINDIRECTSAVEHL", VT_ADDRESS, 0 );
81 variable_global( _environment, "CALLINDIRECTSAVEHL" );
82
83 char callIndirect[3] = {
84 // +00
85 0xc3, 0x00, 0x00
86 };
87
88 variable_import( _environment, "CALLINDIRECT", VT_BUFFER, 3 );
89 variable_global( _environment, "CALLINDIRECT" );
90
91 variable_store_buffer( _environment, "CALLINDIRECT", callIndirect, sizeof( callIndirect ), 0 );
92 variable_retrieve( _environment, "CALLINDIRECT" )->readonly = 0;
93
94}
95
96void cpu_nop( Environment * _environment ) {
97
98 outline0("NOP");
99
100}
101
102void cpu_ztoa( Environment * _environment ) {
103
104 inline( cpu_ztoa )
105
107
108 outline1("JR Z, %syes", label );
109 outline0("LD A, 0");
110 outline1("JP %s", label );
111 outhead1("%syes:", label );
112 outline0("LD A, $ff");
113 outhead1("%s:", label );
114
116
117}
118
119void cpu_ctoa( Environment * _environment ) {
120
121 inline( cpu_ctoa )
122
124
125 outline1("JR C, %syes", label );
126 outline0("LD A, 0");
127 outline1("JP %s", label );
128 outhead1("%syes:", label );
129 outline0("LD A, $ff");
130 outhead1("%s:", label );
131
133
134}
135
150void cpu_beq( Environment * _environment, char * _label ) {
151
152 inline( cpu_beq )
153
154 outline1("JP Z, %s", _label);
155
157
158}
159
166void cpu_bneq( Environment * _environment, char * _label ) {
167
168 inline( cpu_bneq )
169
170 outline1("JP NZ, %s", _label);
171
173
174}
175
176void cpu_bveq( Environment * _environment, char * _value, char * _label ) {
177
178 inline( cpu_bveq )
179
180 outline1("LD A, (%s)", _value);
181 outline0("CP 0");
182 cpu_beq( _environment, _label );
183
185
186}
187
188void cpu_bvneq( Environment * _environment, char * _value, char * _label ) {
189
190 inline( cpu_bvneq )
191
192 outline1("LD A, (%s)", _value);
193 outline0("CP 0");
194 cpu_bneq( _environment, _label );
195
197
198}
199
200void cpu_label( Environment * _environment, char * _label ) {
201 outhead1("%s:", _label);
202}
203
204void cpu_peek( Environment * _environment, char * _address, char * _target ) {
205
206 inline( cpu_peek )
207
208 outline1("LD HL, (%s)", _address);
209 outline0("LD A, (HL)");
210 outline1("LD (%s), A", _target);
211
213
214}
215
216void cpu_poke( Environment * _environment, char * _address, char * _source ) {
217
218 inline( cpu_poke )
219
220 outline1("LD A, (%s)", _source);
221 outline1("LD HL, (%s)", _address);
222 outline0("LD (HL), A");
223
225
226}
227
228void cpu_poke_const( Environment * _environment, char * _address, int _source ) {
229
230 // inline( cpu_poke )
231
232 outline1("LD A, $%2.2x", (unsigned char)(_source&0xff));
233 outline1("LD HL, (%s)", _address);
234 outline0("LD (HL), A");
235
236 // no_embedded( cpu_poke )
237
238}
239
240void cpu_peekw( Environment * _environment, char * _address, char * _target ) {
241
242 inline( cpu_peek )
243
244 outline1("LD HL, (%s)", _address);
245 outline0("LD A, (HL)");
246 outline1("LD (%s), A", _target);
247 outline0("INC HL");
248 outline0("LD A, (HL)");
249 outline1("LD (%s), A", address_displacement( _environment, _target, "1" ) );
250
252
253}
254
255void cpu_pokew( Environment * _environment, char * _address, char * _source ) {
256
257 inline( cpu_poke )
258
259 outline1("LD A, (%s)", _source);
260 outline1("LD HL, (%s)", _address);
261 outline0("LD (HL), A");
262 outline1("LD A, (%s)", address_displacement( _environment, _source, "1" ) );
263 outline0("INC HL");
264 outline0("LD (HL), A");
265
267
268}
269
270void cpu_pokew_const( Environment * _environment, char * _address, int _source ) {
271
272 // inline( cpu_poke )
273
274 outline1("LD A, $%2.2x", (unsigned char)(_source&0xff));
275 outline1("LD HL, (%s)", _address);
276 outline0("LD (HL), A");
277 outline1("LD A, $%2.2x", (unsigned char)((_source>>8)&0xff));
278 outline0("INC HL");
279 outline0("LD (HL), A");
280
281 // no_embedded( cpu_poke )
282
283}
284
285void cpu_peekd( Environment * _environment, char * _address, char * _target ) {
286
287 inline( cpu_peek )
288
289 outline1("LD HL, (%s)", _address);
290 outline0("LD A, (HL)");
291 outline1("LD (%s), A", _target);
292 outline0("INC HL");
293 outline0("LD A, (HL)");
294 outline1("LD (%s), A", address_displacement( _environment, _target, "1" ) );
295 outline0("INC HL");
296 outline0("LD A, (HL)");
297 outline1("LD (%s), A", address_displacement( _environment, _target, "2" ) );
298 outline0("INC HL");
299 outline0("LD A, (HL)");
300 outline1("LD (%s), A", address_displacement( _environment, _target, "3" ) );
301
303
304}
305
306void cpu_poked( Environment * _environment, char * _address, char * _source ) {
307
308 inline( cpu_poke )
309
310 outline1("LD A, (%s)", _source);
311 outline1("LD HL, (%s)", _address);
312 outline0("LD (HL), A");
313 outline1("LD A, (%s)", address_displacement( _environment, _source, "1" ) );
314 outline0("INC HL");
315 outline0("LD (HL), A");
316 outline1("LD A, (%s)", address_displacement( _environment, _source, "2" ) );
317 outline0("INC HL");
318 outline0("LD (HL), A");
319 outline1("LD A, (%s)", address_displacement( _environment, _source, "3" ) );
320 outline0("INC HL");
321 outline0("LD (HL), A");
322
324
325}
326
327void cpu_poked_const( Environment * _environment, char * _address, int _source ) {
328
329 // inline( cpu_poke )
330
331 outline1("LD A, $%2.2x", (unsigned char)(_source&0xff));
332 outline1("LD HL, (%s)", _address);
333 outline0("LD (HL), A");
334 outline1("LD A, $%2.2x", (unsigned char)((_source>>8)&0xff));
335 outline0("INC HL");
336 outline0("LD (HL), A");
337 outline1("LD A, $%2.2x", (unsigned char)((_source>>16)&0xff));
338 outline0("INC HL");
339 outline0("LD (HL), A");
340 outline1("LD A, $%2.2x", (unsigned char)((_source>>24)&0xff));
341 outline0("INC HL");
342 outline0("LD (HL), A");
343
344 // no_embedded( cpu_poke )
345
346}
347
361void cpu_fill_blocks( Environment * _environment, char * _address, char * _blocks, char * _pattern ) {
362
363 inline( cpu_fill_blocks )
364
366
367 outline1("LD A, (%s)", _pattern);
368 outline1("LD HL, (%s)", _address);
369 outline0("LD (HL),A")
370 outline0("LD E,L");
371 outline0("LD D,H");
372 outline0("INC DE");
373 outline0("LD (DE),A")
374 outline0("LD C,0");
375 outline1("LD A, (%s)", _blocks);
376 outline0("CP 0");
377 outline1("JR Z, %sdone", label);
378 outline0("DEC A");
379 outline0("LD B,A");
380 outline0("LDIR");
381
382 outline1("LD A, (%s)", _pattern);
383 outline0("LD (HL),A")
384 outline0("LD E,L");
385 outline0("LD D,H");
386 outline0("INC DE");
387 outline0("LD (DE),A")
388 outline0("LD C,255");
389 outline0("LD A,0");
390 outline0("LD B,A");
391 outline0("LDIR");
392 outhead1("%sdone:", label);
393
394 embedded( cpu_fill_blocks, src_hw_z80_cpu_fill_blocks_asm );
395
396 outline1("LD A, (%s)", _blocks);
397 outline0("LD B, A");
398 outline1("LD A, (%s)", _pattern);
399 outline1("LD HL, (%s)", _address);
400 outline0("CALL CPUFILLBLOCKS");
401
402 done( )
403
404}
405
419void cpu_fill( Environment * _environment, char * _address, char * _bytes, int _bytes_width, char * _pattern ) {
420
422
424
425 embedded( cpu_fill, src_hw_z80_cpu_fill_asm );
426
427 if ( _bytes_width == 8 ) {
428 outline1("LD A, (%s)", _bytes);
429 outline0("LD C, A");
430 } else {
431 outline1("LD A, (%s)", _bytes);
432 outline0("LD C, A");
433 outline1("LD A, (%s+1)", _bytes);
434 outline0("LD B, A");
435 }
436
437 if ( _pattern ) {
438 outline1("LD A, (%s)", _pattern);
439 } else {
440 outline0("LD A, 0");
441 }
442
443 outline1("LD HL, (%s)", _address);
444
445 if ( _bytes_width == 8 ) {
446 outline0("CALL CPUFILL8");
447 } else {
448 outline0("CALL CPUFILL16");
449 }
450
451 done( )
452}
453
467void cpu_fill_size( Environment * _environment, char * _address, int _bytes, char * _pattern ) {
468
470
472
473 embedded( cpu_fill, src_hw_z80_cpu_fill_asm );
474
475 outline1("LD A, $%2.2x", (unsigned char) ( _bytes & 0xff ) );
476 outline0("LD C, A");
477
478 if ( _bytes < 256 ) {
479
480 } else {
481 outline1("LD A, $%2.2x", (unsigned char) ( ( _bytes >> 8 ) & 0xff ) );
482 outline0("LD B, A");
483 }
484
485 if ( _pattern ) {
486 outline1("LD A, (%s)", _pattern);
487 } else {
488 outline0("LD A, 0");
489 }
490
491 outline1("LD HL, (%s)", _address);
492 if ( _bytes < 256 ) {
493 outline0("CALL CPUFILL8");
494 } else {
495 outline0("CALL CPUFILL16");
496 }
497
498 done( )
499
500}
501
515void cpu_fill_size_value( Environment * _environment, char * _address, int _bytes, int _pattern ) {
516
518
520
521 embedded( cpu_fill, src_hw_z80_cpu_fill_asm );
522
523 outline1("LD A, $%2.2x", (unsigned char) ( _bytes & 0xff ) );
524 outline0("LD C, A");
525
526 if ( _bytes < 256 ) {
527
528 } else {
529 outline1("LD A, $%2.2x", (unsigned char) ( ( _bytes >> 8 ) & 0xff ) );
530 outline0("LD B, A");
531 }
532
533 outline1("LD A, $%2.2x", (unsigned char)(_pattern&0xff));
534 outline1("LD HL, (%s)", _address);
535 if ( _bytes < 256 ) {
536 outline0("CALL CPUFILL8");
537 } else {
538 outline0("CALL CPUFILL16");
539 }
540
541 done( )
542
543}
544
558void cpu_fill_direct( Environment * _environment, char * _address, char * _bytes, char * _pattern ) {
559
561
563
564 embedded( cpu_fill, src_hw_z80_cpu_fill_asm );
565
566 outline1("LD A, (%s)", _bytes);
567 outline0("LD C, A");
568 outline1("LD A, (%s+1)", _bytes);
569 outline0("LD B, A");
570 if ( _pattern ) {
571 outline1("LD A, (%s)", _pattern);
572 } else {
573 outline0("LD A, 0");
574 }
575 outline1("LD HL, %s", _address);
576 outline0("CALL CPUFILL16");
577
578 done( )
579
580}
581
595void cpu_fill_direct_size( Environment * _environment, char * _address, int _bytes, char * _pattern ) {
596
598
600
601 embedded( cpu_fill, src_hw_z80_cpu_fill_asm );
602
603 outline1("LD A, $%2.2x", (unsigned char) ( _bytes & 0xff ) );
604 outline0("LD C, A");
605
606 if ( _bytes < 256 ) {
607
608 } else {
609 outline1("LD A, $%2.2x", (unsigned char) ( ( _bytes >> 8 ) & 0xff ) );
610 outline0("LD B, A");
611 }
612
613 if ( _pattern ) {
614 outline1("LD A, (%s)", _pattern);
615 } else {
616 outline0("LD A, 0");
617 }
618
619 outline1("LD HL, %s", _address);
620 if ( _bytes < 256 ) {
621 outline0("CALL CPUFILL8");
622 } else {
623 outline0("CALL CPUFILL16");
624 }
625
626 done( )
627
628}
629
643void cpu_fill_direct_size_value( Environment * _environment, char * _address, int _bytes, int _pattern ) {
644
646
648
649 embedded( cpu_fill, src_hw_z80_cpu_fill_asm );
650
651 outline1("LD A, $%2.2x", (unsigned char) ( _bytes & 0xff ) );
652 outline0("LD C, A");
653
654 if ( _bytes < 256 ) {
655
656 } else {
657 outline1("LD A, $%2.2x", (unsigned char) ( ( _bytes >> 8 ) & 0xff ) );
658 outline0("LD B, A");
659 }
660
661 outline1("LD A, $%2.2x", (unsigned char)(_pattern & 0xff));
662 outline1("LD HL, %s", _address);
663 if ( _bytes < 256 ) {
664 outline0("CALL CPUFILL8");
665 } else {
666 outline0("CALL CPUFILL16");
667 }
668
669 done( )
670
671}
672
673/*****************************************************************************
674 * 8 BIT MANIPULATION
675 ****************************************************************************/
676
684void cpu_move_8bit( Environment * _environment, char *_source, char *_destination ) {
685
686 inline( cpu_move_8bit )
687
688 outline1("LD A, (%s)", _source);
689 outline1("LD (%s), A", _destination);
690
692
693}
694
702void cpu_store_8bit( Environment * _environment, char *_destination, int _value ) {
703
704 inline( cpu_store_8bit )
705
706 outline1("LD A, $%2.2x", (unsigned char)( _value & 0xff ) );
707 outline1("LD (%s), A", _destination);
708
710
711}
712
720void cpu_store_char( Environment * _environment, char *_destination, int _value ) {
721
722 inline( cpu_store_char )
723
724 outline1("LD A, '%c'", ( _value & 0xff ) );
725 outline1("LD (%s), A", _destination);
726
728
729}
730
731void cpu_store_8bit_with_offset( Environment * _environment, char *_destination, int _value, int _offset ) {
732
734
735 outline1("LD DE, %s", _destination);
736 outline1("ADD DE, $%2.2x", (unsigned char)( _offset & 0xff ) );
737 outline1("LD A, $%2.2x", (unsigned char)( _value & 0xff ) );
738 outline0("LD (DE), A");
739
741
742}
743
744void cpu_store_8bit_with_offset2( Environment * _environment, char *_destination, char * _offset, int _value ) {
745
747
748 outline1("LD HL, %s", _destination);
749 outline1("LD A, (%s)", _offset);
750 outline0("LD E, A");
751 outline0("LD D, 0");
752 outline0("ADD HL, DE" );
753 outline1("LD A, $%2.2x", (unsigned char)( _value & 0xff ) );
754 outline0("LD (HL), A");
755
757
758}
759
769void cpu_compare_8bit( Environment * _environment, char *_source, char *_destination, char *_other, int _positive ) {
770
772
773 inline( cpu_compare_8bit )
774
775 outline1("LD HL, %s", _destination);
776 outline1("LD A, (%s)", _source);
777 outline0("CP (HL)");
778 outline1("JP NZ, %s", label);
779 outline1("LD A, $%2.2x", 0xff*_positive);
780 if ( _other ) {
781 outline1("LD (%s), A", _other);
782 } else {
783 outline0("LD (HL), A");
784 }
785 outline1("JMP %sb2", label);
786 outhead1("%s:", label);
787 outline1("LD A, $%2.2x", 0xff*(1-_positive));
788 if ( _other ) {
789 outline1("LD (%s), A", _other);
790 } else {
791 outline0("LD (HL), A");
792 }
793 outhead1("%sb2:", label);
794
796
797}
798
808void cpu_compare_8bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _positive ) {
809
811
812 inline( cpu_compare_8bit )
813
814 outline1("LD A, (%s)", _source);
815 outline1("CP $%2.2x", _destination);
816 outline1("JP NZ, %s", label);
817 outline1("LD A, $%2.2x", 0xff*_positive);
818 outline1("LD (%s), A", _other);
819 outline1("JMP %sb2", label);
820 outhead1("%s:", label);
821 outline1("LD A, $%2.2x", 0xff*(1-_positive));
822 outline1("LD (%s), A", _other);
823 outhead1("%sb2:", label);
824
826
827}
828
829void cpu_compare_and_branch_8bit( Environment * _environment, char *_source, char * _destination, char *_label, int _positive ) {
830
832
834
835 outline1("LD A, (%s)", _destination);
836 outline0("LD B, A");
837 outline1("LD A, (%s)", _source);
838 outline1("CP B", _destination );
839 if ( _positive ) {
840 outline1("JP Z, %s", _label);
841 } else {
842 outline1("JP NZ, %s", _label);
843 }
844
846
847}
848
858void cpu_compare_and_branch_8bit_const( Environment * _environment, char *_source, int _destination, char *_label, int _positive ) {
859
861
863
864 outline1("LD A, (%s)", _source);
865 outline1("CP $%2.2x", _destination );
866 if ( _positive ) {
867 outline1("JP Z, %s", _label);
868 } else {
869 outline1("JP NZ, %s", _label);
870 }
871
873
874}
875
885void cpu_prepare_for_compare_and_branch_8bit( Environment * _environment, char *_source ) {
886
888
889 outline1("LD A, (%s)", _source);
890
892
893}
894
904void cpu_execute_compare_and_branch_8bit_const( Environment * _environment, int _destination, char *_label, int _positive ) {
905
907
909
910 outline1("CP $%2.2x", _destination );
911 if ( _positive ) {
912 outline1("JP Z, %s", _label);
913 } else {
914 outline1("JP NZ, %s", _label);
915 }
916
918
919}
920
930void cpu_compare_and_branch_char_const( Environment * _environment, char *_source, int _destination, char *_label, int _positive ) {
931
933
935
936 outline1("LD A, (%s)", _source);
937 outline1("CP '%c'", _destination );
938 if ( _positive ) {
939 outline1("JP Z, %s", _label);
940 } else {
941 outline1("JP NZ, %s", _label);
942 }
943
945
946}
947
957void cpu_less_than_8bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
958
960
961 inline( cpu_less_than_8bit )
962
963 if ( _signed ) {
964
965 outline1("LD A, (%s)", _destination);
966 outline0("LD B, A");
967 outline1("LD A, (%s)", _source);
968 outline0("SUB A, B");
969 if ( _equal ) {
970 outline1("JP Z,%strue", label);
971 }
972 outline1("JP PO,%snoxor", label);
973 outline0("XOR $80");
974 outhead1("%snoxor:", label);
975 outline1("JP M,%strue", label);
976 outline1("JP PE,%sfalse", label);
977 outhead1("%sfalse:", label);
978 outline0("LD A, 0");
979 if ( _other ) {
980 outline1("LD (%s), A", _other);
981 } else {
982 outline1("LD (%s), A", _destination);
983 }
984 outline1("JMP %sb2", label);
985 outhead1("%strue:", label);
986 outline0("LD A, $ff");
987 if ( _other ) {
988 outline1("LD (%s), A", _other);
989 } else {
990 outline1("LD (%s), A", _destination);
991 }
992 outhead1("%sb2:", label);
993
994 } else {
995
996 outline1("LD A, (%s)", _destination);
997 outline0("LD B, A");
998 outline1("LD A, (%s)", _source);
999 outline0("CP B");
1000 outline1("JR C, %s", label);
1001 if ( _equal ) {
1002 outline1("JR Z, %s", label);
1003 }
1004 outline0("LD A, 0");
1005 if ( _other ) {
1006 outline1("LD (%s), A", _other);
1007 } else {
1008 outline1("LD (%s), A", _destination);
1009 }
1010 outline1("JMP %sb2", label);
1011 outhead1("%s:", label);
1012 outline0("LD A, $ff");
1013 if ( _other ) {
1014 outline1("LD (%s), A", _other);
1015 } else {
1016 outline1("LD (%s), A", _destination);
1017 }
1018 outhead1("%sb2:", label);
1019
1020 }
1021
1022 embedded( cpu_less_than_8bit, src_hw_z80_cpu_less_than_8bit_asm );
1023
1024 if ( _signed ) {
1025
1026 outline1("LD A, (%s)", _destination);
1027 outline0("LD B, A");
1028 outline1("LD A, (%s)", _source);
1029 if ( _equal ) {
1030 outline0("CALL CPULTE8S");
1031 } else {
1032 outline0("CALL CPULT8S");
1033 }
1034 if ( _other ) {
1035 outline1("LD (%s), A", _other);
1036 } else {
1037 outline1("LD (%s), A", _destination);
1038 }
1039
1040 } else {
1041
1042 outline1("LD A, (%s)", _destination);
1043 outline0("LD B, A");
1044 outline1("LD A, (%s)", _source);
1045 if ( _equal ) {
1046 outline0("CALL CPULTE8U");
1047 } else {
1048 outline0("CALL CPULT8U");
1049 }
1050 if ( _other ) {
1051 outline1("LD (%s), A", _other);
1052 } else {
1053 outline1("LD (%s), A", _destination);
1054 }
1055
1056 }
1057
1058 done( )
1059
1060}
1061
1062void cpu_less_than_8bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
1063
1065
1066 inline( cpu_less_than_8bit )
1067
1068 if ( _signed ) {
1069
1070 outline1("LD A, $%2.2x", (unsigned char)( _destination & 0xff ) );
1071 outline0("LD B, A");
1072 outline1("LD A, (%s)", _source);
1073 outline0("SUB A, B");
1074 if ( _equal ) {
1075 outline1("JP Z,%strue", label);
1076 }
1077 outline1("JP PO,%snoxor", label);
1078 outline0("XOR $80");
1079 outhead1("%snoxor:", label);
1080 outline1("JP M,%strue", label);
1081 outline1("JP PE,%sfalse", label);
1082 outhead1("%sfalse:", label);
1083 outline0("LD A, 0");
1084 outline1("LD (%s), A", _other);
1085 outline1("JMP %sb2", label);
1086 outhead1("%strue:", label);
1087 outline0("LD A, $ff");
1088 outline1("LD (%s), A", _other);
1089 outhead1("%sb2:", label);
1090
1091 } else {
1092
1093 outline1("LD A, $%2.2x", (unsigned char)( _destination & 0xff ) );
1094 outline0("LD B, A");
1095 outline1("LD A, (%s)", _source);
1096 outline0("CP B");
1097 outline1("JR C, %s", label);
1098 if ( _equal ) {
1099 outline1("JR Z, %s", label);
1100 }
1101 outline0("LD A, 0");
1102 outline1("LD (%s), A", _other);
1103 outline1("JMP %sb2", label);
1104 outhead1("%s:", label);
1105 outline0("LD A, $ff");
1106 outline1("LD (%s), A", _other);
1107 outhead1("%sb2:", label);
1108
1109 }
1110
1111 embedded( cpu_less_than_8bit, src_hw_z80_cpu_less_than_8bit_asm );
1112
1113 if ( _signed ) {
1114
1115 outline1("LD A, $%2.2x", (unsigned char)( _destination & 0xff ));
1116 outline0("LD B, A");
1117 outline1("LD A, (%s)", _source);
1118 if ( _equal ) {
1119 outline0("CALL CPULTE8S");
1120 } else {
1121 outline0("CALL CPULT8S");
1122 }
1123 outline1("LD (%s), A", _other);
1124
1125 } else {
1126
1127 outline1("LD A, $%2.2x", (unsigned char)(_destination & 0xff ));
1128 outline0("LD B, A");
1129 outline1("LD A, (%s)", _source);
1130 if ( _equal ) {
1131 outline0("CALL CPULTE8U");
1132 } else {
1133 outline0("CALL CPULT8U");
1134 }
1135 outline1("LD (%s), A", _other);
1136
1137 }
1138
1139 done( )
1140
1141}
1142
1143void cpu_less_than_and_branch_8bit_const( Environment * _environment, char *_source, int _destination, char *_label, int _equal, int _signed ) {
1144
1146
1147 inline( cpu_less_than_8bit )
1148
1149 if ( _signed ) {
1150
1151 outline1("LD A, $%2.2x", (unsigned char)( _destination & 0xff ) );
1152 outline0("LD B, A");
1153 outline1("LD A, (%s)", _source);
1154 outline0("SUB A, B");
1155 if ( _equal ) {
1156 outline1("JP Z,%strue", label);
1157 }
1158 outline1("JP PO,%snoxor", label);
1159 outline0("XOR $80");
1160 outhead1("%snoxor:", label);
1161 outline1("JP M,%strue", label);
1162 outline1("JP PE,%sfalse", label);
1163 outhead1("%sfalse:", label);
1164 outline1("JP %sb2", label);
1165 outhead1("%strue:", label);
1166 outline1("JP %s", _label);
1167 outhead1("%sb2:", label);
1168
1169 } else {
1170
1171 outline1("LD A, $%2.2x", (unsigned char)( _destination & 0xff ) );
1172 outline0("LD B, A");
1173 outline1("LD A, (%s)", _source);
1174 outline0("CP B");
1175 outline1("JR C, %s", label);
1176 if ( _equal ) {
1177 outline1("JR Z, %s", label);
1178 }
1179 outline1("JP %sb2", label);
1180 outhead1("%s:", label);
1181 outline1("JP %s", _label);
1182 outhead1("%sb2:", label);
1183
1184 }
1185
1186 embedded( cpu_less_than_8bit, src_hw_z80_cpu_less_than_8bit_asm );
1187
1188 if ( _signed ) {
1189
1190 outline1("LD A, $%2.2x", (unsigned char)(_destination&0xff));
1191 outline0("LD B, A");
1192 outline1("LD A, (%s)", _source);
1193 if ( _equal ) {
1194 outline0("CALL CPULTE8S");
1195 } else {
1196 outline0("CALL CPULT8S");
1197 }
1198 outline0("CP 0");
1199 outline1("JR Z, %sno", label);
1200 outline1("JP %s", _label);
1201 outhead1("%sno:", label);
1202
1203 } else {
1204
1205 outline1("LD A, $%2.2x", (unsigned char)(_destination&0xff));
1206 outline0("LD B, A");
1207 outline1("LD A, (%s)", _source);
1208 if ( _equal ) {
1209 outline0("CALL CPULTE8U");
1210 } else {
1211 outline0("CALL CPULT8U");
1212 }
1213 outline0("CP 0");
1214 outline1("JR Z, %sno", label);
1215 outline1("JP %s", _label);
1216 outhead1("%sno:", label);
1217
1218 }
1219
1220 done( )
1221
1222}
1223
1233void cpu_greater_than_8bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
1234
1235 cpu_less_than_8bit( _environment, _source, _destination, _other, !_equal, _signed );
1236 if ( _other ) {
1237 cpu_not_8bit( _environment, _other, _other );
1238 } else {
1239 cpu_not_8bit( _environment, _destination, _destination );
1240 }
1241
1242}
1243
1244void cpu_greater_than_8bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
1245
1246 cpu_less_than_8bit_const( _environment, _source, _destination, _other, !_equal, _signed );
1247 cpu_not_8bit( _environment, _other, _other );
1248
1249}
1250
1259void cpu_math_add_8bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
1260
1261 inline( cpu_math_add_8bit )
1262
1263 outline0("LD B, 0" );
1264 outline1("LD A, (%s)", _source );
1265 outline0("LD B, A" );
1266 outline1("LD A, (%s)", _destination );
1267 outline0("ADD A, B" );
1268 if ( _other ) {
1269 outline1("LD (%s), A", _other );
1270 } else {
1271 outline1("LD (%s), A", _destination );
1272 }
1273
1275
1276}
1277
1278void cpu_math_add_8bit_const( Environment * _environment, char *_source, int _destination, char *_other ) {
1279
1280 inline( cpu_math_add_8bit )
1281
1282 outline0("LD B, 0" );
1283 outline1("LD A, (%s)", _source );
1284 outline0("ADD A, B" );
1285 outline0("LD B, A" );
1286 outline1("LD A, $%2.2x", (unsigned char)( _destination & 0xff ) );
1287 outline0("ADD A, B" );
1288 outline1("LD (%s), A", _other );
1289
1291
1292}
1293
1302void cpu_math_sub_8bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
1303
1304 inline( cpu_math_sub_8bit )
1305
1306 outline0("LD B, 0" );
1307 outline1("LD A, (%s)", _destination );
1308 outline0("SUB A, B" );
1309 outline0("LD B, A" );
1310 outline1("LD A, (%s)", _source );
1311 outline0("SUB A,B" );
1312 if ( _other ) {
1313 outline1("LD (%s), A", _other );
1314 } else {
1315 outline1("LD (%s), A", _destination );
1316 }
1317
1319
1320}
1321
1329void cpu_math_double_8bit( Environment * _environment, char *_source, char *_other, int _signed ) {
1330
1331 inline( cpu_math_double_8bit )
1332
1333 if ( _signed ) {
1334
1335 outline1("LD A, (%s)", _source );
1336 outline0("ADD A, A" );
1337 if ( _other ) {
1338 outline1("LD (%s), A", _other );
1339 } else {
1340 outline1("LD (%s), A", _source );
1341 }
1342
1343 } else {
1344 outline1("LD A, (%s)", _source );
1345 outline0("ADD A, A" );
1346 if ( _other ) {
1347 outline1("LD (%s), A", _other );
1348 } else {
1349 outline1("LD (%s), A", _source );
1350 }
1351 }
1352
1354
1355}
1356
1365
1366void cpu_math_mul_8bit_to_16bit( Environment * _environment, char *_source, char *_destination, char *_other, int _signed ) {
1367
1369
1371
1372 if ( _signed ) {
1373
1374 outline1("LD A, (%s)", _source );
1375 outline0("LD B, A" );
1376 outline1("LD A, (%s)", _destination );
1377 outline0("XOR A, B" );
1378 outline0("AND $80" );
1379 outline0("LD B, A" );
1380 outline0("PUSH B" );
1381
1382 outline1("LD A, (%s)", _source );
1383 outline0("AND $80" );
1384 outline0("CP 0" );
1385 outline1("JR Z, %spositive", label );
1386 outline1("LD A, (%s)", _source );
1387 outline0("XOR $FF" );
1388 outline0("INC A" );
1389 outline1("JMP %sdone1", label );
1390
1391 outhead1("%spositive:", label );
1392 outline1("LD A, (%s)", _source );
1393
1394 outhead1("%sdone1:", label );
1395 outline0("LD H, A" );
1396
1397 outline1("LD A, (%s)", _destination );
1398 outline0("AND $80" );
1399 outline0("CP 0" );
1400 outline1("JR Z, %spositive2", label );
1401 outline1("LD A, (%s)", _destination );
1402 outline0("XOR $FF" );
1403 outline0("INC A" );
1404 outline1("JMP %sdone2", label );
1405 outhead1("%spositive2:", label );
1406 outline1("LD A, (%s)", _destination );
1407
1408 outhead1("%sdone2:", label );
1409 outline0("LD C, A" );
1410
1411 outline0("LD E, A" );
1412
1413 outline0("LD D,0");
1414 outline0("LD L,D");
1415 outline0("LD B,8");
1416
1417 outhead1("%s:", label );
1418 outline0("ADD HL, HL" );
1419 outline1("JR NC,%sb2", label );
1420 outline0("ADD HL, DE" );
1421
1422 outhead1("%sb2:", label );
1423
1424 outline1("DJNZ %s", label );
1425
1426 outline1("LD (%s), HL", _other );
1427 outline0("POP B" );
1428 outline0("LD A, B" );
1429 outline0("AND $80" );
1430 outline0("CP 0" );
1431 outline1("JR Z,%snc", label );
1432 cpu_complement2_16bit( _environment, _other, NULL );
1433 outhead1("%snc:", label );
1434
1435 } else {
1436
1437 outline1("LD A, (%s)", _source );
1438 outline0("LD H, A" );
1439 outline1("LD A, (%s)", _destination );
1440 outline0("LD E, A" );
1441
1442 outline0("LD D,0");
1443 outline0("LD L,D");
1444 outline0("LD B,8");
1445
1446 outhead1("%s:", label );
1447 outline0("ADD HL, HL" );
1448 outline1("JR NC,%sb2", label );
1449 outline0("ADD HL, DE" );
1450
1451 outhead1("%sb2:", label );
1452
1453 outline1("DJNZ %s", label );
1454 outline1("LD (%s), HL", _other );
1455
1456 }
1457
1458 embedded( cpu_math_mul_8bit_to_16bit, src_hw_z80_cpu_math_mul_8bit_to_16bit_asm );
1459
1460 if ( _signed ) {
1461
1462 outline1("LD A, (%s)", _destination);
1463 outline0("LD IYL, A");
1464 outline1("LD A, (%s)", _source);
1465 outline0("LD IXL, A");
1466 outline0("CALL CPUMUL8B8T16S");
1467 outline1("LD (%s), HL", _other);
1468
1469 } else {
1470
1471 outline1("LD A, (%s)", _destination);
1472 outline0("LD IYL, A");
1473 outline1("LD A, (%s)", _source);
1474 outline0("LD IXL, A");
1475 outline0("CALL CPUMUL8B8T16U");
1476 outline1("LD (%s), HL", _other);
1477
1478 }
1479
1480 done( )
1481
1482}
1483
1491void cpu_math_div2_const_8bit( Environment * _environment, char *_source, int _steps, int _signed, char * _remainder ) {
1492
1493 inline( cpu_math_div2_const_8bit )
1494
1496
1497 if ( _remainder ) {
1498 outline1("LD A, (%s)", _source );
1499 outline0("AND $1" );
1500 outline1("LD (%s), A", _remainder );
1501 }
1502 if ( _signed ) {
1503 outline1("LD A, (%s)", _source );
1504 outline0("AND $80" );
1505 outline0("PUSH AF" );
1506 outline0("CP 0" );
1507 outline1("JR Z, %spos", label );
1508 cpu_complement2_16bit( _environment, _source, _source );
1509 outline1("JMP %spos2", label );
1510 outhead1("%spos:", label );
1511 outhead1("%spos2:", label );
1512 outline1("LD A, (%s)", _source );
1513 while( _steps ) {
1514 outline0("SRA A" );
1515 --_steps;
1516 }
1517 outline1("LD (%s), A", _source );
1518 outline0("POP AF" );
1519 outline0("AND $80" );
1520 outline0("CP 0" );
1521 outline1("JR Z, %sdone", label );
1522 cpu_complement2_16bit( _environment, _source, _source );
1523 outhead1("%sdone:", label );
1524 } else {
1525 outline1("LD A, (%s)", _source );
1526 while( _steps ) {
1527 outline0("SRA A" );
1528 --_steps;
1529 }
1530 outline1("LD (%s), A", _source );
1531 }
1532
1533 embedded( cpu_math_div2_const_8bit, src_hw_z80_cpu_math_div2_const_8bit_asm );
1534
1535 if ( _remainder ) {
1536 outline1("LD A, (%s)", _source );
1537 outline0("AND $1" );
1538 outline1("LD (%s), A", _remainder );
1539 }
1540 outline1("LD A, (%s)", _source);
1541 outline0("LD B, A");
1542 outline1("LD A, $%2.2x", (unsigned char)(_steps&0xff));
1543 outline0("LD C, A");
1544 if ( _signed ) {
1545 outline0("CALL CPUDIV2CONST8S");
1546 } else {
1547 outline0("CALL CPUDIV2CONST8U");
1548 }
1549 outline0("LD A, B");
1550 outline1("LD (%s), A", _source);
1551
1552 done( )
1553
1554}
1555
1563void cpu_math_mul2_const_8bit( Environment * _environment, char *_source, int _steps, int _signed ) {
1564
1565 inline( cpu_math_mul2_const_8bit )
1566
1567 if ( _signed ) {
1568 outline1("LD A, (%s)", _source );
1569 outline0("AND $80" );
1570 outline0("PUSH AF" );
1571 outline1("LD A, (%s)", _source );
1572 outline0("AND $7F" );
1573 while( _steps ) {
1574 outline0("SLA A" );
1575 --_steps;
1576 }
1577 outline0("LD B, A" );
1578 outline0("POP AF" );
1579 outline0("OR A, B" );
1580 outline1("LD (%s), A", _source );
1581
1582 } else {
1583 outline1("LD A, (%s)", _source );
1584 while( _steps ) {
1585 outline0("SLA A" );
1586 --_steps;
1587 }
1588 outline1("LD (%s), A", _source );
1589 }
1590
1591 embedded( cpu_math_mul2_const_8bit, src_hw_z80_cpu_math_mul2_const_8bit_asm );
1592
1593 outline1("LD A, (%s)", _source);
1594 outline0("LD B, A");
1595 outline1("LD A, $%2.2x", (unsigned char)(_steps&0xff));
1596 outline0("LD C, A");
1597 if ( _signed ) {
1598 outline0("CALL CPUMUL2CONST8S");
1599 } else {
1600 outline0("CALL CPUMUL2CONST8U");
1601 }
1602 outline0("LD A, B");
1603 outline1("LD (%s), A", _source);
1604
1605 done( )
1606
1607}
1608
1616void cpu_math_complement_const_8bit( Environment * _environment, char *_source, int _value ) {
1617
1619
1620 outline1("LD A, (%s)", _source );
1621 outline0("LD B, A" );
1622 outline1("LD A, $%2.2x", (unsigned char)( _value & 0xff ) );
1623 outline0("SUB A, B" );
1624 outline1("LD (%s), A", _source );
1625
1627
1628}
1629
1637void cpu_math_and_const_8bit( Environment * _environment, char *_source, int _mask ) {
1638
1639 inline( cpu_math_and_const_8bit )
1640
1641 outline1("LD A, (%s)", _source );
1642 outline1("AND $%2.2x", _mask );
1643 outline1("LD (%s), A", _source );
1644
1646
1647}
1648
1649/*****************************************************************************
1650 * 16 BIT MANIPULATION
1651 ****************************************************************************/
1652
1660void cpu_move_16bit( Environment * _environment, char *_source, char *_destination ) {
1661
1662 inline( cpu_move_16bit )
1663
1664 outline1("LD HL, (%s)", _source );
1665 outline1("LD (%s), HL", _destination );
1666
1668
1669}
1670
1671void cpu_addressof_16bit( Environment * _environment, char *_source, char *_destination ) {
1672
1673 inline( cpu_addressof_16bit )
1674
1675 outline1("LD HL, %s", _source );
1676 outline1("LD (%s), HL", _destination );
1677
1679
1680}
1681
1689void cpu_store_16bit( Environment * _environment, char *_destination, int _value ) {
1690
1691 inline( cpu_store_16bit )
1692
1693 outline1("LD HL, $%4.4x", _value & 0xffff );
1694 outline1("LD (%s), HL", _destination );
1695
1697
1698}
1699
1708void cpu_compare_16bit( Environment * _environment, char *_source, char *_destination, char *_other, int _positive ) {
1709
1711
1712 inline( cpu_compare_16bit )
1713
1714 outline1("LD A, (%s)", _source);
1715 outline0("LD B, A");
1716 outline1("LD A, (%s)", _destination);
1717 outline0("CP B");
1718 outline1("JP NZ, %s", label);
1719 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
1720 outline0("LD B, A");
1721 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
1722 outline0("CP B");
1723 outline1("JP NZ, %s", label);
1724 outline1("LD A, $%2.2x", 0xff*_positive);
1725 if ( _other ) {
1726 outline1("LD (%s), A", _other);
1727 } else {
1728 outline1("LD (%s), A", _destination);
1729 }
1730 outline1("JMP %sb2", label);
1731 outhead1("%s:", label);
1732 outline1("LD A, $%2.2x", 0xff*(1-_positive));
1733 if ( _other ) {
1734 outline1("LD (%s), A", _other);
1735 } else {
1736 outline1("LD (%s), A", _destination);
1737 }
1738 outhead1("%sb2:", label);
1739
1740 embedded( cpu_compare_16bit, src_hw_z80_cpu_compare_16bit_asm )
1741
1742 outline1("LD HL, %s", _source);
1743 outline1("LD DE, %s", _destination);
1744 outline1("LD IX, $%4.4x", ( (0xff*_positive) << 8 ) | ( 0xff*(1-_positive)) );
1745 outline0("CALL CPUCOMPARE16");
1746 if ( _other ) {
1747 outline1("LD (%s), A", _other);
1748 } else {
1749 outline1("LD (%s), A", _destination);
1750 }
1751
1752 done( )
1753
1754}
1755
1764void cpu_compare_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _positive ) {
1765
1767
1768 inline( cpu_compare_16bit )
1769
1770 outline1("LD A, (%s)", _source);
1771 outline0("LD B, A");
1772 outline1("LD A, $%2.2x", (unsigned char)(_destination&0xff));
1773 outline0("CP B");
1774 outline1("JP NZ, %s", label);
1775 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
1776 outline0("LD B, A");
1777 outline1("LD A, $%2.2x", (unsigned char)((_destination>>8)&0xff));
1778 outline0("CP B");
1779 outline1("JP NZ, %s", label);
1780 outline1("LD A, $%2.2x", 0xff*_positive);
1781 outline1("LD (%s), A", _other);
1782 outline1("JMP %sb2", label);
1783 outhead1("%s:", label);
1784 outline1("LD A, $%2.2x", 0xff*(1-_positive));
1785 outline1("LD (%s), A", _other);
1786 outhead1("%sb2:", label);
1787
1788 embedded( cpu_compare_16bit, src_hw_z80_cpu_compare_16bit_asm )
1789
1790 outline1("LD HL, %s", _source);
1791 outline1("LD DE, $%4.4x", _destination);
1792 outline1("LD IX, $%4.4x", ( (0xff*_positive) << 8 ) | ( 0xff*(1-_positive)) );
1793 outline0("CALL CPUCOMPARE16CONST");
1794 outline1("LD (%s), A", _other);
1795
1796 done( )
1797
1798}
1799
1800void cpu_compare_and_branch_16bit( Environment * _environment, char *_source, char *_destination, char *_label, int _positive ) {
1801
1803
1805
1806 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
1807 outline0("LD B, A");
1808 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
1809 outline0("CP B");
1810 outline1("JP NZ, %s", label);
1811 outline1("LD A, (%s)", _source);
1812 outline0("LD B, A");
1813 outline1("LD A, (%s)", _destination);
1814 outline0("CP B");
1815 outline1("JP NZ, %s", label);
1816 if ( _positive ) {
1817 outline1("JP %s", _label);
1818 outhead1("%s:", label );
1819 } else {
1820 outline1("JP %snot", label);
1821 outhead1("%s:", label );
1822 outline1("JP %s", _label);
1823 outhead1("%snot:", label );
1824 }
1825
1827
1828}
1829
1839void cpu_compare_and_branch_16bit_const( Environment * _environment, char *_source, int _destination, char *_label, int _positive ) {
1840
1842
1844
1845 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
1846 outline1("CP $%2.2x", ( _destination >> 8 ) & 0xff );
1847 outline1("JP NZ, %s", label);
1848 outline1("LD A, (%s)", _source);
1849 outline1("CP $%2.2x", ( _destination & 0xff ) );
1850 outline1("JP NZ, %s", label);
1851 if ( _positive ) {
1852 outline1("JP %s", _label);
1853 outhead1("%s:", label );
1854 } else {
1855 outline1("JP %snot", label);
1856 outhead1("%s:", label );
1857 outline1("JP %s", _label);
1858 outhead1("%snot:", label );
1859 }
1860
1862
1863}
1864
1874void cpu_less_than_16bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
1875
1877
1878 inline( cpu_less_than_16bit )
1879
1880 if ( _signed ) {
1881
1882 outline1("LD HL, (%s)", _destination);
1883 outline1("LD DE, (%s)", _source);
1884 outline0("LD A, H" );
1885 outline0("XOR D" );
1886 outline1("JP M,%scmpgte2", label );
1887 outline0("SBC HL, DE" );
1888 if ( _equal ) {
1889 outline1("JR Z,%scmpgte3", label );
1890 } else {
1891 outline1("JR Z,%scmpgte1", label );
1892 }
1893 outline1("JR NC,%scmpgte3", label );
1894 outhead1("%scmpgte1:", label );
1895 outline0("LD A, 0");
1896 if ( _other ) {
1897 outline1("LD (%s), A", _other);
1898 } else {
1899 outline1("LD (%s), A", _destination);
1900 }
1901 outline1("JMP %send", label );
1902 outhead1("%scmpgte2:", label );
1903 outline0("BIT 7,D" );
1904 outline1("JR Z, %scmpgte1", label );
1905 outhead1("%scmpgte3:", label );
1906 outline0("LD A, $ff");
1907 if ( _other ) {
1908 outline1("LD (%s), A", _other);
1909 } else {
1910 outline1("LD (%s), A", _destination);
1911 }
1912 outhead1("%send:", label );
1913
1914 } else {
1915
1916 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
1917 outline0("LD B, A");
1918 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
1919 outline0("CP B");
1920 outline1("JR Z, %sl2", label);
1921 outline1("JR C, %s", label);
1922 outline1("JR %s_0", label);
1923 outhead1("%sl2:", label);
1924 outline1("LD A, (%s)", _destination);
1925 outline0("LD B, A");
1926 outline1("LD A, (%s)", _source);
1927 outline0("CP B");
1928 outline1("JR C, %s", label);
1929 if ( _equal ) {
1930 outline1("JR Z, %s", label);
1931 }
1932 outhead1("%s_0:", label);
1933 outline0("LD A, 0");
1934 if ( _other ) {
1935 outline1("LD (%s), A", _other);
1936 } else {
1937 outline1("LD (%s), A", _destination);
1938 }
1939 outline1("JMP %sb2", label);
1940 outhead1("%s:", label);
1941 outline0("LD A, $ff");
1942 if ( _other ) {
1943 outline1("LD (%s), A", _other);
1944 } else {
1945 outline1("LD (%s), A", _destination);
1946 }
1947 outhead1("%sb2:", label);
1948
1949 }
1950
1951 embedded( cpu_less_than_16bit, src_hw_z80_cpu_less_than_16bit_asm );
1952
1953 if ( _signed ) {
1954
1955 outline1("LD HL, (%s)", _destination);
1956 outline1("LD DE, (%s)", _source);
1957 if ( _equal ) {
1958 outline0("CALL CPULTE16S");
1959 } else {
1960 outline0("CALL CPULT16S");
1961 }
1962 if ( _other ) {
1963 outline1("LD (%s), A", _other);
1964 } else {
1965 outline1("LD (%s), A", _destination);
1966 }
1967
1968 } else {
1969
1970 outline1("LD HL, (%s)", _destination);
1971 outline1("LD DE, (%s)", _source);
1972 if ( _equal ) {
1973 outline0("CALL CPULTE16U");
1974 } else {
1975 outline0("CALL CPULT16U");
1976 }
1977 if ( _other ) {
1978 outline1("LD (%s), A", _other);
1979 } else {
1980 outline1("LD (%s), A", _destination);
1981 }
1982
1983 }
1984
1985 done( )
1986
1987}
1988
1989void cpu_less_than_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
1990
1992
1993 inline( cpu_less_than_16bit )
1994
1995 if ( _signed ) {
1996
1997 outline1("LD HL, $%4.4x", ( _destination & 0xffff ) );
1998 outline1("LD DE, (%s)", _source);
1999 outline0("LD A, H" );
2000 outline0("XOR D" );
2001 outline1("JP M,%scmpgte2", label );
2002 outline0("SBC HL, DE" );
2003 if ( _equal ) {
2004 outline1("JR Z,%scmpgte3", label );
2005 } else {
2006 outline1("JR Z,%scmpgte1", label );
2007 }
2008 outline1("JR NC,%scmpgte3", label );
2009 outhead1("%scmpgte1:", label );
2010 outline0("LD A, 0");
2011 outline1("LD (%s), A", _other);
2012 outline1("JMP %send", label );
2013 outhead1("%scmpgte2:", label );
2014 outline0("BIT 7,D" );
2015 outline1("JR Z, %scmpgte1", label );
2016 outhead1("%scmpgte3:", label );
2017 outline0("LD A, $ff");
2018 outline1("LD (%s), A", _other);
2019 outhead1("%send:", label );
2020
2021 } else {
2022
2023 outline1("LD A, $%2.2x", (unsigned char)( ( _destination >> 8 ) & 0xff ) );
2024 outline0("LD B, A");
2025 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
2026 outline0("CP B");
2027 outline1("JR Z, %sl2", label);
2028 outline1("JR C, %s", label);
2029 outline1("JR %s_0", label);
2030 outhead1("%sl2:", label);
2031 outline1("LD A, $%2.2x", (unsigned char)( _destination & 0xff ) );
2032 outline0("LD B, A");
2033 outline1("LD A, (%s)", _source);
2034 outline0("CP B");
2035 outline1("JR C, %s", label);
2036 if ( _equal ) {
2037 outline1("JR Z, %s", label);
2038 }
2039 outhead1("%s_0:", label);
2040 outline0("LD A, 0");
2041 outline1("LD (%s), A", _other);
2042 outline1("JMP %sb2", label);
2043 outhead1("%s:", label);
2044 outline0("LD A, $ff");
2045 outline1("LD (%s), A", _other);
2046 outhead1("%sb2:", label);
2047
2048 }
2049
2050 embedded( cpu_less_than_16bit, src_hw_z80_cpu_less_than_16bit_asm );
2051
2052 if ( _signed ) {
2053
2054 outline1("LD HL, $%4.4x", ( _destination & 0Xffff ) );
2055 outline1("LD DE, (%s)", _source);
2056 if ( _equal ) {
2057 outline0("CALL CPULTE16S");
2058 } else {
2059 outline0("CALL CPULT16S");
2060 }
2061 outline1("LD (%s), A", _other);
2062
2063 } else {
2064
2065 outline1("LD HL, $%4.4x", ( _destination & 0Xffff ) );
2066 outline1("LD DE, (%s)", _source);
2067 if ( _equal ) {
2068 outline0("CALL CPULTE16U");
2069 } else {
2070 outline0("CALL CPULT16U");
2071 }
2072 outline1("LD (%s), A", _other);
2073
2074 }
2075
2076 done( )
2077
2078}
2079
2089void cpu_greater_than_16bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
2090
2091 cpu_less_than_16bit( _environment, _source, _destination, _other, !_equal, _signed );
2092 if ( _other ) {
2093 cpu_not_8bit( _environment, _other, _other );
2094 } else {
2095 cpu_not_8bit( _environment, _destination, _destination );
2096 }
2097
2098}
2099
2100void cpu_greater_than_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
2101
2102 cpu_less_than_16bit_const( _environment, _source, _destination, _other, !_equal, _signed );
2103 cpu_not_8bit( _environment, _other, _other );
2104
2105}
2106
2115void cpu_math_add_16bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
2116
2117 inline( cpu_math_add_16bit )
2118
2119 outline1("LD HL, (%s)", _source );
2120 outline1("LD DE, (%s)", _destination );
2121 outline0("ADD HL, DE" );
2122 if ( _other ) {
2123 outline1("LD (%s), HL", _other );
2124 } else {
2125 outline1("LD (%s), HL", _destination );
2126 }
2127
2129
2130}
2131
2132void cpu_math_add_16bit_const( Environment * _environment, char *_source, int _destination, char *_other ) {
2133
2134 inline( cpu_math_add_16bit )
2135
2136 outline1("LD HL, (%s)", _source );
2137 outline1("LD DE, $%4.4x", ( _destination & 0xffff ) );
2138 outline0("ADD HL, DE" );
2139 outline1("LD (%s), HL", _other );
2140
2142
2143}
2144
2145void cpu_math_add_16bit_with_16bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
2146
2148
2149 outline0("AND $0");
2150 outline1("LD HL, (%s)", _source );
2151 outline1("LD DE, %s", _destination );
2152 outline0("ADD HL, DE" );
2153 outline1("LD (%s), HL", _other );
2154
2156
2157}
2158
2166void cpu_math_double_16bit( Environment * _environment, char *_source, char *_other, int _signed ) {
2167
2168 inline( cpu_math_double_16bit )
2169
2170 outline1("LD DE, (%s)", _source );
2171 outline0("SLA E" );
2172 outline0("RL D" );
2173 if ( _other ) {
2174 outline1("LD (%s), DE", _other );
2175 } else {
2176 outline1("LD (%s), DE", _source );
2177 }
2178
2180
2181}
2182
2191void cpu_math_mul_16bit_to_32bit( Environment * _environment, char *_source, char *_destination, char *_other, int _signed ) {
2192
2194
2196
2197 if ( _signed ) {
2198
2199 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
2200 outline0("AND $80");
2201 outline0("LD B, A");
2202 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
2203 outline0("AND $80");
2204 outline0("XOR A, B");
2205 outline0("PUSH AF");
2206
2207 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
2208 outline0("AND $80");
2209 outline0("PUSH AF");
2210 outline0("CP 0");
2211 outline1("JR Z,%spositive", label);
2212 cpu_complement2_16bit( _environment, _source, NULL );
2213 outhead1("%spositive:", label);
2214
2215 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
2216 outline0("AND $80");
2217 outline0("PUSH AF");
2218 outline0("CP 0");
2219 outline1("JR Z,%spositive2", label);
2220 cpu_complement2_16bit( _environment, _destination, NULL );
2221 outhead1("%spositive2:", label);
2222
2223 outline1("LD BC, (%s)", _source );
2224 outline1("LD DE, (%s)", _destination );
2225 outline0("LD A, C" );
2226 outline0("LD C, B" );
2227 outline0("LD HL, 0" );
2228 outline0("LD B, 16" );
2229 outhead1("%s:", label );
2230 outline0("ADD HL, HL" );
2231 outline0("RLA " );
2232 outline0("RL C" );
2233 outline1("JR NC,%sb2", label );
2234 outline0("ADD HL, DE" );
2235 outline0("ADC A, 0" );
2236 outline1("JP NC,%sb2", label );
2237 outline0("INC C" );
2238 outhead1("%sb2:", label );
2239 outline1("DJNZ %s", label );
2240 outline0("LD B, C" );
2241 outline0("LD C, A" );
2242 outline1("LD (%s), HL", _other );
2243 outline1("LD (%s), BC", address_displacement( _environment, _other, "2" ) );
2244
2245 outline0("POP AF" );
2246 outline1("JR Z, %srepositive", label );
2247 cpu_complement2_16bit( _environment, _destination, NULL );
2248 outhead1("%srepositive:", label);
2249
2250 outline0("POP AF" );
2251 outline1("JR Z, %srepositive2", label );
2252 cpu_complement2_16bit( _environment, _source, NULL );
2253 outhead1("%srepositive2:", label);
2254
2255 outline0("POP AF" );
2256 outline1("JR Z, %srepositive3", label );
2257 cpu_complement2_32bit( _environment, _other, NULL );
2258 outhead1("%srepositive3:", label);
2259
2260 } else {
2261
2262 outline1("LD BC, (%s)", _source );
2263 outline1("LD DE, (%s)", _destination );
2264 outline0("LD A, C" );
2265 outline0("LD C, B" );
2266 outline0("LD HL, 0" );
2267 outline0("LD B, 16" );
2268 outhead1("%s:", label );
2269 outline0("ADD HL, HL" );
2270 outline0("RLA " );
2271 outline0("RL C" );
2272 outline1("JR NC,%sb2", label );
2273 outline0("ADD HL, DE" );
2274 outline0("ADC A, 0" );
2275 outline1("JP NC,%sb2", label );
2276 outline0("INC C" );
2277 outhead1("%sb2:", label );
2278 outline1("DJNZ %s", label );
2279 outline0("LD B, C" );
2280 outline0("LD C, A" );
2281 outline1("LD (%s), HL", _other );
2282 outline1("LD (%s), BC", address_displacement( _environment, _other, "2" ) );
2283
2284 }
2285
2286 embedded( cpu_math_mul_16bit_to_32bit, src_hw_z80_cpu_math_mul_16bit_to_32bit_asm );
2287
2288 if ( _signed ) {
2289
2290 outline1("LD IX, (%s)", _source );
2291 outline1("LD IY, (%s)", _destination );
2292 outline0("CALL CPUMUL16B16T32S")
2293 outline1("LD (%s), HL", _other );
2294 outline1("LD (%s), BC", address_displacement( _environment, _other, "2" ) );
2295
2296 } else {
2297
2298 outline1("LD BC, (%s)", _source );
2299 outline1("LD DE, (%s)", _destination );
2300 outline0("CALL CPUMUL16B16T32U")
2301 outline1("LD (%s), HL", _other );
2302 outline1("LD (%s), BC", address_displacement( _environment, _other, "2" ) );
2303
2304 }
2305
2306 done( )
2307
2308}
2309
2310void cpu_math_mul_nbit_to_nbit( Environment * _environment, char *_source, char *_destination, char *_other, int _bits ) {
2311
2313
2314 int i;
2315
2316 char afterLabel[MAX_TEMPORARY_STORAGE]; sprintf( afterLabel, "%safter", label);
2317 char destination[MAX_TEMPORARY_STORAGE]; sprintf( destination, "CPUMATHMULNBITTONBIT%d_DESTINATION", (_bits>>3));
2318 char source[MAX_TEMPORARY_STORAGE]; sprintf( source, "CPUMATHMULNBITTONBIT%d_SOURCE", (_bits>>3));
2319 char other[MAX_TEMPORARY_STORAGE]; sprintf( other, "CPUMATHMULNBITTONBIT%d_OTHER", (_bits>>3));
2320
2321 // no_inline( cpu_math_mul_nbit_to_nbit )
2322
2323 // embedded( cpu_math_mul_nbit_to_nbit, src_hw_6502_cpu_math_mul_nbit_to_nbit_asm )
2324
2325 if ( ! _environment->cpuOptimization.cpu_math_mul_nbit_to_nbit[_bits>>3] ) {
2326
2327 outline1("JP %s", afterLabel );
2328
2329 outhead2("CPUMATHMULNBITTONBIT%d_SOURCE: defs %d", _bits>>3, _bits>>3 );
2330 outhead2("CPUMATHMULNBITTONBIT%d_DESTINATION: defs %d", _bits>>3, _bits>>3 );
2331 outhead2("CPUMATHMULNBITTONBIT%d_OTHER: defs %d", _bits>>3, _bits>>3 );
2332
2333 outhead1("CPUMATHMULNBITTONBIT%d:", _bits>>3);
2334 outhead0("LD A, $00");
2335 for( i=0; i<(_bits>>3); ++i ) {
2336 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
2337 outline1("LD (%s), A", address_displacement( _environment, other, offset ) );
2338 }
2339 outline1("LD C, $%2.2x", _bits );
2340
2341 outhead1("CPUMATHMULNBITTONBIT%dL1:", _bits>>3);
2342
2343 // The process of multiplying binary numbers is similar and easier to do than
2344 // decimal multiplication as binary numbers consist of only two digits which
2345 // are 0 and 1. The method of multiplying binary numbers is given below. The
2346 // same set of rules also apply to binary numbers with a decimal point. Let
2347 // us take the example of multiplying (11101) and (1001).
2348 //
2349 // The decimal equivalent of (11101) is 29 and the decimal equivalent
2350 // of (1001) is 9. Now let us multiply these numbers.
2351
2352 // Step 1: Write down the multiplicand (11101) and the multiplier (1001)
2353 // one below the other in proper positions.
2354
2355 char multiplyByBit0Label[MAX_TEMPORARY_STORAGE]; sprintf( multiplyByBit0Label, "%sb%dbit0", label, _bits>>3 );
2356
2357 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", (_bits>>3)-1 );
2358
2359 outline1("LD A, (%s)", address_displacement( _environment, destination, offset ) );
2360 outline0("SRA A" );
2361 outline1("LD (%s), A", address_displacement( _environment, destination, offset ) );
2362 for( i=(_bits>>3)-2; i>-1; --i ) {
2363 sprintf( offset, "%d", i );
2364 outline1("LD A, (%s)", address_displacement( _environment, destination, offset ) );
2365 outline0("RR A" );
2366 outline1("LD (%s), A", address_displacement( _environment, destination, offset ) );
2367 }
2368 outline1("JR C, %sx", multiplyByBit0Label );
2369 outline1("JP %s", multiplyByBit0Label );
2370 outhead1("%sx:", multiplyByBit0Label );
2371
2372 // Step 2: Multiply the rightmost digit or the least significant bit (LSB)
2373 // of the multiplier (1) with all the digits of the multiplicand (11101).
2374
2375 outline0("XOR A" );
2376 for( i=0; i<(_bits>>3); ++i ) {
2377 sprintf( offset, "%d", i );
2378 outline1("LD A, (%s)", address_displacement( _environment, source, offset ) );
2379 outline0("LD B, A" );
2380 outline1("LD A, (%s)", address_displacement( _environment, other, offset ) );
2381 outline0("ADC A, B" );
2382 outline1("LD (%s), A", address_displacement( _environment, other, offset ) );
2383 }
2384
2385 // Step 3: Add a place holder of '0' or 'X' before multiplying the next
2386 // higher order digit of the multiplier& with the multiplicand.
2387
2388 outhead1("%s:", multiplyByBit0Label);
2389
2390 outline0("XOR A" );
2391 outline1("LD A, (%s)", address_displacement( _environment, source, "0" ) );
2392 outline0("SLA A" );
2393 outline1("LD (%s), A", address_displacement( _environment, source, "0" ) );
2394 for( i=1; i<(_bits>>3); ++i ) {
2395 sprintf( offset, "%d", i );
2396 outline1("LD A, (%s)", address_displacement( _environment, source, offset ) );
2397 outline0("RL A" );
2398 outline1("LD (%s), A", address_displacement( _environment, source, offset ) );
2399 }
2400
2401 // Step 4: Repeat the same process for all the next higher-order digits
2402 // until we reach the most significant bit (MSB) which is the left-most
2403 // digit of the multiplicand with the multiplier.
2404
2405 outline0("DEC C" );
2406 outline0("LD A, C" );
2407 outline0("CP 0" );
2408 outline1("JP NZ, CPUMATHMULNBITTONBIT%dL1", (_bits>>3) );
2409
2410 outline0("RET" );
2411
2412 // Step 5: The product obtained in each row is called the partial product.
2413 // Finally, add all the partial products. To add all the binary numbers
2414 // use the rules of binary addition.
2415
2416 // (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)
2417 outhead1("%s:", afterLabel );
2418
2419 }
2420
2421 for( i=0; i<(_bits>>3); ++i ) {
2422 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
2423 outline1("LD A, (%s)", address_displacement( _environment, _source, offset ) );
2424 outline1("LD (%s), A", address_displacement( _environment, source, offset ) );
2425 outline1("LD A, (%s)", address_displacement( _environment, _destination, offset ) );
2426 outline1("LD (%s), A", address_displacement( _environment, destination, offset ) );
2427 }
2428 outline1("CALL CPUMATHMULNBITTONBIT%d", _bits >> 3 );
2429 for( i=0; i<(_bits>>3); ++i ) {
2430 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
2431 outline1("LD A, (%s)", address_displacement( _environment, other, offset ) );
2432 if ( _other ) {
2433 outline1("LD (%s), A", address_displacement( _environment, _other, offset ) );
2434 } else {
2435 outline1("LD (%s), A", address_displacement( _environment, _destination, offset ) );
2436 }
2437 }
2438
2439 // done()
2440
2441}
2442
2443void cpu_math_div_16bit_to_16bit( Environment * _environment, char *_source, char *_destination, char *_other, char * _other_remainder, int _signed ) {
2444
2446
2447 if ( _signed ) {
2448
2449 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
2450 outline0("AND $80");
2451 outline0("CP 0" );
2452 outline0("PUSH AF");
2453 outline1("JR Z,%spositive", label);
2454 cpu_complement2_16bit( _environment, _source, NULL );
2455 outhead1("%spositive:", label);
2456 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
2457 outline0("AND $80");
2458 outline0("CP 0" );
2459 outline0("PUSH AF");
2460 outline1("JR Z,%spositive2", label);
2461 cpu_complement2_16bit( _environment, _destination, NULL );
2462 outhead1("%spositive2:", label);
2463
2464 outline1("LD HL, %s", _source);
2465 outline0("LD A, (HL)");
2466 outline0("LD C, A");
2467 outline0("INC HL");
2468 outline0("LD A, (HL)");
2469 outline1("LD DE, (%s)", _destination);
2470
2471 outline0("LD HL, 0");
2472 outline0("LD B, 16");
2473 outhead1("%sloop:", label );
2474 outline0("SLL C");
2475 outline0("RLA");
2476 outline0("ADC HL, HL");
2477 outline0("SBC HL, DE");
2478 outline0("JR NC, $+4");
2479 outline0("ADD HL, DE");
2480 outline0("DEC C");
2481 outline1("DJNZ %sloop", label);
2482 outline1("LD (%s), HL", _other_remainder);
2483 outline1("LD DE, %s", _other);
2484 outline0("LD B, A");
2485 outline0("LD A, C");
2486 outline0("LD (DE), A");
2487 outline0("INC DE");
2488 outline0("LD A, B");
2489 outline0("LD (DE), A");
2490
2491 outline0("POP AF");
2492 outline0("LD B, A");
2493 outline0("CMP $80");
2494 outline1("JR NZ, %srepositive", label);
2495 cpu_complement2_16bit( _environment, _destination, NULL );
2496 outhead1("%srepositive:", label);
2497 outline0("POP AF");
2498 outline0("LD C, A");
2499 outline0("CMP $80");
2500 outline1("JR NZ, %srepositive2", label );
2501 cpu_complement2_16bit( _environment, _source, NULL );
2502 outhead1("%srepositive2:", label);
2503 outline0("LD A, B");
2504 outline0("XOR C");
2505 outline0("AND $80");
2506 outline0("CP $80");
2507 outline1("JR NZ, %srepositive3", label );
2508 cpu_complement2_16bit( _environment, _other, NULL );
2509 outhead1("%srepositive3:", label);
2510
2511 } else {
2512
2513 outline1("LD HL, %s", _source);
2514 outline0("LD A, (HL)");
2515 outline0("LD C, A");
2516 outline0("INC HL");
2517 outline0("LD A, (HL)");
2518 outline1("LD DE, (%s)", _destination);
2519
2520 outline0("LD HL, 0");
2521 outline0("LD B, 16");
2522 outhead1("%sloop:", label );
2523 outline0("SLL C");
2524 outline0("RLA");
2525 outline0("ADC HL, HL");
2526 outline0("SBC HL, DE");
2527 outline0("JR NC, $+4");
2528 outline0("ADD HL, DE");
2529 outline0("DEC C");
2530 outline1("DJNZ %sloop", label);
2531 outline1("LD (%s), HL", _other_remainder);
2532 outline1("LD DE, %s", _other);
2533 outline0("LD B, A");
2534 outline0("LD A, C");
2535 outline0("LD (DE), A");
2536 outline0("INC DE");
2537 outline0("LD A, B");
2538 outline0("LD (DE), A");
2539
2540 }
2541
2542}
2543
2544void cpu_math_div_16bit_to_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, char * _other_remainder, int _signed ) {
2545
2547
2548 if ( _signed ) {
2549
2550 int destination = abs(_destination);
2551
2552 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
2553 outline0("AND $80");
2554 outline0("CP 0" );
2555 outline0("PUSH AF");
2556 outline1("JR Z,%spositive", label);
2557 cpu_complement2_16bit( _environment, _source, NULL );
2558 outhead1("%spositive:", label);
2559 // outline1("LD A, $%2.2x", (unsigned char)( (_destination>>8) & 0xff));
2560 // outline0("AND $80");
2561 // outline0("CP 0" );
2562 // outline0("PUSH AF");
2563 // outline1("JR Z,%spositive2", label);
2564 // cpu_complement2_16bit( _environment, _destination, NULL );
2565 // outhead1("%spositive2:", label);
2566
2567 outline1("LD HL, %s", _source);
2568 outline0("LD A, (HL)");
2569 outline0("LD C, A");
2570 outline0("INC HL");
2571 outline0("LD A, (HL)");
2572 outline1("LD DE, $%4.4x", destination);
2573
2574 outline0("LD HL, 0");
2575 outline0("LD B, 16");
2576 outhead1("%sloop:", label );
2577 outline0("SLL C");
2578 outline0("RLA");
2579 outline0("ADC HL, HL");
2580 outline0("SBC HL, DE");
2581 outline0("JR NC, $+4");
2582 outline0("ADD HL, DE");
2583 outline0("DEC C");
2584 outline1("DJNZ %sloop", label);
2585 outline1("LD (%s), HL", _other_remainder);
2586 outline1("LD DE, %s", _other);
2587 outline0("LD B, A");
2588 outline0("LD A, C");
2589 outline0("LD (DE), A");
2590 outline0("INC DE");
2591 outline0("LD A, B");
2592 outline0("LD (DE), A");
2593
2594 // outline0("POP AF");
2595 outline1("LD B, $%2.2x", _destination < 0 ? 0x80 : 0x00 );
2596 // outline0("CMP $80");
2597 // outline1("JR NZ, %srepositive", label);
2598 // cpu_complement2_16bit( _environment, _destination, NULL );
2599 outhead1("%srepositive:", label);
2600 outline0("POP AF");
2601 outline0("LD C, A");
2602 outline0("CMP $80");
2603 outline1("JR NZ, %srepositive2", label );
2604 cpu_complement2_16bit( _environment, _source, NULL );
2605 outhead1("%srepositive2:", label);
2606 outline0("LD A, B");
2607 outline0("XOR C");
2608 outline0("AND $80");
2609 outline0("CP $80");
2610 outline1("JR NZ, %srepositive3", label );
2611 cpu_complement2_16bit( _environment, _other, NULL );
2612 outhead1("%srepositive3:", label);
2613
2614 } else {
2615
2616 outline1("LD HL, %s", _source);
2617 outline0("LD A, (HL)");
2618 outline0("LD C, A");
2619 outline0("INC HL");
2620 outline0("LD A, (HL)");
2621 outline1("LD DE, $%4.4x", _destination);
2622
2623 outline0("LD HL, 0");
2624 outline0("LD B, 16");
2625 outhead1("%sloop:", label );
2626 outline0("SLL C");
2627 outline0("RLA");
2628 outline0("ADC HL, HL");
2629 outline0("SBC HL, DE");
2630 outline0("JR NC, $+4");
2631 outline0("ADD HL, DE");
2632 outline0("DEC C");
2633 outline1("DJNZ %sloop", label);
2634 outline1("LD (%s), HL", _other_remainder);
2635 outline1("LD DE, %s", _other);
2636 outline0("LD B, A");
2637 outline0("LD A, C");
2638 outline0("LD (DE), A");
2639 outline0("INC DE");
2640 outline0("LD A, B");
2641 outline0("LD (DE), A");
2642
2643 }
2644
2645}
2646
2655void cpu_math_sub_16bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
2656
2657 inline( cpu_math_sub_16bit )
2658
2659 outline1("LD HL, (%s)", _source );
2660 outline1("LD DE, (%s)", _destination );
2661 outline0("AND A" );
2662 outline0("SBC HL, DE" );
2663 if ( _other ) {
2664 outline1("LD (%s), HL", _other );
2665 } else {
2666 outline1("LD (%s), HL", _destination );
2667 }
2668
2670
2671}
2672
2673void cpu_math_sub_16bit_with_8bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
2674
2675 outline1("LD HL, (%s)", _source );
2676 outline0("LD DE, 0" );
2677 outline1("LD A, (%s)", _destination );
2678 outline0("LD E, A" );
2679 outline0("SBC HL, DE" );
2680 if ( _other ) {
2681 outline1("LD (%s), HL", _other );
2682 } else {
2683 outline1("LD (%s), HL", _destination );
2684 }
2685
2686}
2687
2695void cpu_math_complement_const_16bit( Environment * _environment, char *_source, int _value ) {
2696
2698
2699 outline1("LD HL, $%4.4x", _value );
2700 outline1("LD DE, (%s)", _source );
2701 outline0("LD A, E" );
2702 outline0("XOR $FF" );
2703 outline0("LD E, A" );
2704 outline0("LD A, D" );
2705 outline0("XOR $FF" );
2706 outline0("LD D, A" );
2707 outline0("INC DE" );
2708 outline0("ADD HL, DE" );
2709 outline1("LD (%s), HL", _source );
2710
2712
2713}
2714
2722void cpu_math_div2_const_16bit( Environment * _environment, char *_source, int _steps, int _signed, char * _remainder ) {
2723
2725
2727
2728 if ( _remainder ) {
2729 outline1("LD A, (%s)", _source );
2730 outline0("AND $1" );
2731 outline1("LD (%s), A", _remainder );
2732 }
2733 if ( _signed ) {
2734 outline1("LD A, (%s)", address_displacement(_environment, _source, "1") );
2735 outline0("AND $80" );
2736 outline0("CP 0" );
2737 outline0("PUSH AF" );
2738 outline1("JR Z, %spos", label );
2739 cpu_complement2_16bit( _environment, _source, _source );
2740 outline1("JMP %spos2", label );
2741 outhead1("%spos:", label );
2742 outhead1("%spos2:", label );
2743 outline1("LD HL, (%s)", _source );
2744 while( _steps ) {
2745 outline0("SRA H" );
2746 outline0("RR L" );
2747 --_steps;
2748 }
2749 outline1("LD (%s), HL", _source );
2750 outline0("POP AF" );
2751 outline0("AND $80" );
2752 outline0("CP 0" );
2753 outline1("JR Z, %sdone", label );
2754 cpu_complement2_16bit( _environment, _source, _source );
2755 outhead1("%sdone:", label );
2756 } else {
2757 outline1("LD HL, (%s)", _source );
2758 while( _steps ) {
2759 outline0("SRA H" );
2760 outline0("RR L" );
2761 --_steps;
2762 }
2763 outline1("LD (%s), HL", _source );
2764
2765 }
2766
2767 embedded( cpu_math_div2_const_16bit, src_hw_z80_cpu_math_div2_const_16bit_asm )
2768
2769 if ( _remainder ) {
2770 outline1("LD A, (%s)", _source );
2771 outline0("AND $1" );
2772 outline1("LD (%s), A", _remainder );
2773 }
2774 if ( _signed ) {
2775 if ( _steps ) {
2776 outline1("LD HL, (%s)", _source );
2777 outline1("LD A, $%2.2x", (unsigned char)(_steps&0xff) );
2778 outline0("LD C, A" );
2779 outline0("CALL CPUDIV2CONST16S" );
2780 outline1("LD (%s), HL", _source );
2781 }
2782 } else {
2783 if ( _steps ) {
2784 outline1("LD HL, (%s)", _source );
2785 outline1("LD A, $%2.2x", (unsigned char)(_steps&0xff) );
2786 outline0("LD C, A" );
2787 outline0("CALL CPUDIV2CONST16U" );
2788 outline1("LD (%s), HL", _source );
2789 }
2790
2791 }
2792
2793 done( )
2794
2795}
2796
2804void cpu_math_mul2_const_16bit( Environment * _environment, char *_source, int _steps, int _signed ) {
2805
2807
2809
2810 if ( _signed ) {
2811 outline1("LD A, (%s)", address_displacement(_environment, _source, "1") );
2812 outline0("AND $80" );
2813 outline0("PUSH AF" );
2814 outline0("CP 0" );
2815 outline1("JR Z, %spos", label );
2816 cpu_complement2_16bit( _environment, _source, _source );
2817 outline1("JMP %spos2", label );
2818 outhead1("%spos:", label );
2819 outhead1("%spos2:", label );
2820 outline1("LD HL, (%s)", _source );
2821 while( _steps ) {
2822 outline0("SLA L" );
2823 outline0("RL H" );
2824 --_steps;
2825 }
2826 outline1("LD (%s), HL", _source );
2827 outline0("POP AF" );
2828 outline0("AND $80" );
2829 outline0("CP 0" );
2830 outline1("JR Z, %sdone", label );
2831 cpu_complement2_16bit( _environment, _source, _source );
2832 outhead1("%sdone:", label );
2833 } else {
2834 outline1("LD HL, (%s)", _source );
2835 while( _steps ) {
2836 outline0("SLA L" );
2837 outline0("RL H" );
2838 --_steps;
2839 }
2840 outline1("LD (%s), HL", _source );
2841 }
2842
2844
2845}
2846
2854void cpu_math_and_const_16bit( Environment * _environment, char *_source, int _mask ) {
2855
2856 inline( cpu_math_and_const_16bit )
2857
2858 outline1("LD A, (%s)", _source );
2859 outline1("AND $%2.2x", ( _mask & 0xff ) );
2860 outline1("LD (%s), A", _source );
2861 outline1("LD A, (%s)", address_displacement(_environment, _source, "1") );
2862 outline1("AND $%2.2x", ( ( _mask >> 8 ) & 0xff ) );
2863 outline1("LD (%s), A", address_displacement(_environment, _source, "1") );
2864
2866
2867}
2868
2869/*****************************************************************************
2870 * 32 BIT MANIPULATION
2871 ****************************************************************************/
2872
2880void cpu_move_32bit( Environment * _environment, char *_source, char *_destination ) {
2881
2882 inline( cpu_move_32bit )
2883
2884 outline1("LD A, (%s)", _source );
2885 outline1("LD (%s), A", _destination );
2886 outline1("LD A, (%s)", address_displacement(_environment, _source, "1") );
2887 outline1("LD (%s), A", address_displacement(_environment, _destination, "1") );
2888 outline1("LD A, (%s)", address_displacement(_environment, _source, "2") );
2889 outline1("LD (%s), A", address_displacement(_environment, _destination, "2") );
2890 outline1("LD A, (%s)", address_displacement(_environment, _source, "3") );
2891 outline1("LD (%s), A", address_displacement(_environment, _destination, "3") );
2892
2894
2895}
2896
2904void cpu_store_32bit( Environment * _environment, char *_destination, int _value ) {
2905
2906 inline( cpu_store_32bit )
2907
2908 outline1("LD HL, $%4.4x", ( _value & 0xffff ) );
2909 outline1("LD (%s), HL", _destination );
2910 outline1("LD HL, $%4.4x", ( ( _value >> 16 ) & 0xffff ) );
2911 outline1("LD (%s), HL", address_displacement(_environment, _destination, "2") );
2912
2914
2915}
2916
2917void cpu_math_div_32bit_to_16bit( Environment * _environment, char *_source, char *_destination, char *_other, char * _other_remainder, int _signed ) {
2918
2920
2921 if ( _signed ) {
2922
2923 outline1("LD A, (%s)", address_displacement(_environment, _source, "3"));
2924 outline0("AND $80");
2925 outline0("CP 0" );
2926 outline0("PUSH AF");
2927 outline1("JR Z,%spositive", label);
2928 cpu_complement2_32bit( _environment, _source, NULL );
2929 outhead1("%spositive:", label);
2930 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
2931 outline0("AND $80");
2932 outline0("CP 0" );
2933 outline0("PUSH AF");
2934 outline1("JR Z,%spositive2", label);
2935 cpu_complement2_16bit( _environment, _destination, NULL );
2936 outhead1("%spositive2:", label);
2937
2938 // outline1("LD HL, %s", _source);
2939 // outline0("LD A, (HL)");
2940 // outline0("PUSH AF");
2941 // outline0("POP IX");
2942 // outline0("INC HL");
2943 // outline0("INC HL");
2944 // outline0("LD A, (HL)");
2945 // outline0("LD C, A");
2946 // outline0("INC HL");
2947 // outline0("LD A, (HL)");
2948 // outline1("LD DE, (%s)", _destination);
2949
2950 // outline0("LD HL, 0");
2951 // outline0("LD B, 32");
2952 // outhead1("%sloop:", label);
2953 // outline0("ADD IX, IX");
2954 // outline0("RL C");
2955 // outline0("RLA");
2956 // outline0("ADC HL, HL");
2957 // outline1("JR C, %soverflow", label);
2958 // outline0("SBC HL, DE");
2959 // outline1("JR NC, %ssetbit", label);
2960 // outline0("ADD HL, DE");
2961 // outline1("DJNZ %sloop", label);
2962 // outline1("JMP %send", label);
2963 // outhead1("%soverflow:", label);
2964 // outline0("OR A");
2965 // outline0("SBC HL, DE");
2966 // outhead1("%ssetbit:", label);
2967 // outline0("INC IXL");
2968 // outline1("DJNZ %sloop", label);
2969 // outhead1("%send:", label);
2970 // outline1("LD (%s), HL", _other_remainder);
2971 // outline1("LD HL, %s", _other);
2972 // outline0("PUSH AF");
2973 // outline0("PUSH IX");
2974 // outline0("POP AF");
2975 // outline0("LD (HL), A");
2976 // outline0("POP AF");
2977 // outline0("INC HL");
2978 // outline0("INC HL");
2979 // outline0("INC HL");
2980 // outline0("LD (HL), A");
2981 // outline0("DEC HL");
2982 // outline0("LD C, (HL)");
2983
2984 outline1("LD A, (%s)", _destination);
2985 outline0("LD E, A");
2986 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
2987 outline0("LD D, A");
2988 outline1("LD IX, (%s)", _source);
2989 outline1("LD A, (%s)", address_displacement(_environment, _source, "2"));
2990 outline0("LD C, A");
2991 outline1("LD A, (%s)", address_displacement(_environment, _source, "3"));
2992
2993 outline0("LD HL, 0");
2994 outline0("LD B, 32");
2995 outhead1("%sdiv32a:", label);
2996 outline0("ADD IX, IX");
2997 outline0("RL C");
2998 outline0("RLA");
2999 outline0("ADC HL, HL");
3000 outline1("JR C, %sdiv32ov", label);
3001 outline0("SBC HL, DE");
3002 outline1("JR NC, %sdiv32setbit", label);
3003 outline0("ADD HL, DE");
3004 outline1("DJNZ %sdiv32a", label);
3005 outline1("JR %sdiv32end", label);
3006 outhead1("%sdiv32ov:", label);
3007 outline0("OR A");
3008 outline0("SBC HL, DE");
3009 outhead1("%sdiv32setbit:", label);
3010 outline0("INC IX");
3011 outline1("DJNZ %sdiv32a", label);
3012 outhead1("%sdiv32end:", label);
3013
3014 outline1("LD (%s), A", address_displacement(_environment, _other, "3"));
3015 outline0("LD A, C" );
3016 outline1("LD (%s), A", address_displacement(_environment, _other, "2"));
3017 outline1("LD (%s), IX", _other);
3018 outline0("LD A, L");
3019 outline1("LD (%s), A", _other_remainder);
3020 outline0("LD A, H");
3021 outline1("LD (%s), A", address_displacement(_environment, _other_remainder, "1"));
3022
3023 outline0("POP AF");
3024 outline0("LD B, A");
3025 outline0("CMP $80");
3026 outline1("JR NZ, %srepositive", label);
3027 cpu_complement2_16bit( _environment, _destination, NULL );
3028 outhead1("%srepositive:", label);
3029 outline0("POP AF");
3030 outline0("LD C, A");
3031 outline0("CMP $80");
3032 outline1("JR NZ, %srepositive2", label );
3033 cpu_complement2_32bit( _environment, _source, NULL );
3034 outhead1("%srepositive2:", label);
3035 outline0("LD A, B");
3036 outline0("XOR C");
3037 outline0("AND $80");
3038 outline0("CP $80");
3039 outline1("JR NZ, %srepositive3", label );
3040 cpu_complement2_32bit( _environment, _other, NULL );
3041 outhead1("%srepositive3:", label);
3042
3043 } else {
3044
3045 // outline1("LD HL, %s", _source);
3046 // outline0("LD A, (HL)");
3047 // outline0("PUSH AF");
3048 // outline0("POP IX");
3049 // outline0("INC HL");
3050 // outline0("INC HL");
3051 // outline0("LD A, (HL)");
3052 // outline0("LD C, A");
3053 // outline0("INC HL");
3054 // outline0("LD A, (HL)");
3055 // outline1("LD DE, (%s)", _destination);
3056
3057 // outline0("LD HL, 0");
3058 // outline0("LD B, 32");
3059 // outhead1("%sloop:", label);
3060 // outline0("ADD IX, IX");
3061 // outline0("RL C");
3062 // outline0("RLA");
3063 // outline0("ADC HL, HL");
3064 // outline1("JR C, %soverflow", label);
3065 // outline0("SBC HL, DE");
3066 // outline1("JR NC, %ssetbit", label);
3067 // outline0("ADD HL, DE");
3068 // outline1("DJNZ %sloop", label);
3069 // outline1("JMP %send", label);
3070 // outhead1("%soverflow:", label);
3071 // outline0("OR A");
3072 // outline0("SBC HL, DE");
3073 // outhead1("%ssetbit:", label);
3074 // outline0("INC IXL");
3075 // outline1("DJNZ %sloop", label);
3076 // outhead1("%send:", label);
3077 // outline1("LD (%s), HL", _other_remainder);
3078 // outline1("LD HL, %s", _other);
3079 // outline0("PUSH AF");
3080 // outline0("PUSH IX");
3081 // outline0("POP AF");
3082 // outline0("LD (HL), A");
3083 // outline0("POP AF");
3084 // outline0("INC HL");
3085 // outline0("INC HL");
3086 // outline0("INC HL");
3087 // outline0("LD (HL), A");
3088 // outline0("DEC HL");
3089 // outline0("LD C, (HL)");
3090 // ; IN: ACIX=dividend, DE=divisor
3091 // ; OUT: ACIX=quotient, DE=divisor, HL=remainder, B=0
3092
3093 outline1("LD HL, (%s)", _source);
3094 outline0("LD IX, HL");
3095 outline1("LD HL, (%s)", address_displacement(_environment, _source, "2"));
3096 outline0("LD A, L");
3097 outline0("LD C, A");
3098 outline0("LD A, H");
3099 outline1("LD DE, (%s)", _destination);
3100
3101 outline0("LD HL, 0");
3102 outline0("LD B, 32");
3103 outhead1("%sloop1:", label);
3104 outline0("ADD IX, IX");
3105 outline0("RL C");
3106 outline0("RLA");
3107 outline0("ADC HL, HL");
3108 outline1("JR C, %sloop2", label);
3109 outline0("SBC HL, DE");
3110 outline1("JR NC, %sloop3", label);
3111 outline0("ADD HL, DE");
3112 outline1("DJNZ %sloop1", label);
3113 outline1("JR %sdone", label);
3114 outhead1("%sloop2:", label);
3115 outline0("OR A");
3116 outline0("SBC HL, DE");
3117 outhead1("%sloop3:", label);
3118 outline0("INC IXL");
3119 outline1("DJNZ %sloop1", label);
3120 outhead1("%sdone:", label);
3121
3122 outline1("LD (%s), HL", _other_remainder);
3123 outline0("LD H, A");
3124 outline0("LD A, C");
3125 outline0("LD L, C");
3126 outline1("LD (%s), HL", _other);
3127 outline0("LD HL, IX");
3128 outline1("LD (%s), HL", _other);
3129
3130 }
3131
3132}
3133
3134void cpu_math_div_32bit_to_16bit_const( Environment * _environment, char *_source, int _destination, char *_other, char * _other_remainder, int _signed ) {
3135
3137
3138 if ( _signed ) {
3139
3140 int destination = abs(_destination);
3141
3142 outline1("LD A, (%s)", address_displacement(_environment, _source, "3"));
3143 outline0("AND $80");
3144 outline0("CP 0" );
3145 outline0("PUSH AF");
3146 outline1("JR Z,%spositive", label);
3147 cpu_complement2_32bit( _environment, _source, NULL );
3148 outhead1("%spositive:", label);
3149 // outline1("LD A, $%2.2x", (unsigned char)( (_destination >> 8 ) & 0xff ));
3150 // outline0("AND $80");
3151 // outline0("CP 0" );
3152 // outline0("PUSH AF");
3153 // outline1("JR Z,%spositive2", label);
3154 // cpu_complement2_16bit( _environment, _destination, NULL );
3155 // outhead1("%spositive2:", label);
3156
3157 // outline1("LD HL, %s", _source);
3158 // outline0("LD A, (HL)");
3159 // outline0("PUSH AF");
3160 // outline0("POP IX");
3161 // outline0("INC HL");
3162 // outline0("INC HL");
3163 // outline0("LD A, (HL)");
3164 // outline0("LD C, A");
3165 // outline0("INC HL");
3166 // outline0("LD A, (HL)");
3167 // outline1("LD DE, (%s)", _destination);
3168
3169 // outline0("LD HL, 0");
3170 // outline0("LD B, 32");
3171 // outhead1("%sloop:", label);
3172 // outline0("ADD IX, IX");
3173 // outline0("RL C");
3174 // outline0("RLA");
3175 // outline0("ADC HL, HL");
3176 // outline1("JR C, %soverflow", label);
3177 // outline0("SBC HL, DE");
3178 // outline1("JR NC, %ssetbit", label);
3179 // outline0("ADD HL, DE");
3180 // outline1("DJNZ %sloop", label);
3181 // outline1("JMP %send", label);
3182 // outhead1("%soverflow:", label);
3183 // outline0("OR A");
3184 // outline0("SBC HL, DE");
3185 // outhead1("%ssetbit:", label);
3186 // outline0("INC IXL");
3187 // outline1("DJNZ %sloop", label);
3188 // outhead1("%send:", label);
3189 // outline1("LD (%s), HL", _other_remainder);
3190 // outline1("LD HL, %s", _other);
3191 // outline0("PUSH AF");
3192 // outline0("PUSH IX");
3193 // outline0("POP AF");
3194 // outline0("LD (HL), A");
3195 // outline0("POP AF");
3196 // outline0("INC HL");
3197 // outline0("INC HL");
3198 // outline0("INC HL");
3199 // outline0("LD (HL), A");
3200 // outline0("DEC HL");
3201 // outline0("LD C, (HL)");
3202
3203 outline1("LD DE, $%4.4x", destination);
3204 outline1("LD IX, (%s)", _source);
3205 outline1("LD A, (%s)", address_displacement(_environment, _source, "2"));
3206 outline0("LD C, A");
3207 outline1("LD A, (%s)", address_displacement(_environment, _source, "3"));
3208
3209 outline0("LD HL, 0");
3210 outline0("LD B, 32");
3211 outhead1("%sdiv32a:", label);
3212 outline0("ADD IX, IX");
3213 outline0("RL C");
3214 outline0("RLA");
3215 outline0("ADC HL, HL");
3216 outline1("JR C, %sdiv32ov", label);
3217 outline0("SBC HL, DE");
3218 outline1("JR NC, %sdiv32setbit", label);
3219 outline0("ADD HL, DE");
3220 outline1("DJNZ %sdiv32a", label);
3221 outline1("JR %sdiv32end", label);
3222 outhead1("%sdiv32ov:", label);
3223 outline0("OR A");
3224 outline0("SBC HL, DE");
3225 outhead1("%sdiv32setbit:", label);
3226 outline0("INC IX");
3227 outline1("DJNZ %sdiv32a", label);
3228 outhead1("%sdiv32end:", label);
3229
3230 outline1("LD (%s), A", address_displacement(_environment, _other, "3"));
3231 outline0("LD A, C" );
3232 outline1("LD (%s), A", address_displacement(_environment, _other, "2"));
3233 outline1("LD (%s), IX", _other);
3234 outline0("LD A, L");
3235 outline1("LD (%s), A", _other_remainder);
3236 outline0("LD A, H");
3237 outline1("LD (%s), A", address_displacement(_environment, _other_remainder, "1"));
3238
3239 // outline0("POP AF");
3240 outline1("LD B, $%2.2x", (_destination < 0) ? 0x80 : 0x00 );
3241 // outline0("CMP $80");
3242 // outline1("JR NZ, %srepositive", label);
3243 // cpu_complement2_16bit( _environment, _destination, NULL );
3244 outhead1("%srepositive:", label);
3245 outline0("POP AF");
3246 outline0("LD C, A");
3247 outline0("CMP $80");
3248 outline1("JR NZ, %srepositive2", label );
3249 cpu_complement2_32bit( _environment, _source, NULL );
3250 outhead1("%srepositive2:", label);
3251 outline0("LD A, B");
3252 outline0("XOR C");
3253 outline0("AND $80");
3254 outline0("CP $80");
3255 outline1("JR NZ, %srepositive3", label );
3256 cpu_complement2_32bit( _environment, _other, NULL );
3257 outhead1("%srepositive3:", label);
3258
3259 } else {
3260
3261 // outline1("LD HL, %s", _source);
3262 // outline0("LD A, (HL)");
3263 // outline0("PUSH AF");
3264 // outline0("POP IX");
3265 // outline0("INC HL");
3266 // outline0("INC HL");
3267 // outline0("LD A, (HL)");
3268 // outline0("LD C, A");
3269 // outline0("INC HL");
3270 // outline0("LD A, (HL)");
3271 // outline1("LD DE, (%s)", _destination);
3272
3273 // outline0("LD HL, 0");
3274 // outline0("LD B, 32");
3275 // outhead1("%sloop:", label);
3276 // outline0("ADD IX, IX");
3277 // outline0("RL C");
3278 // outline0("RLA");
3279 // outline0("ADC HL, HL");
3280 // outline1("JR C, %soverflow", label);
3281 // outline0("SBC HL, DE");
3282 // outline1("JR NC, %ssetbit", label);
3283 // outline0("ADD HL, DE");
3284 // outline1("DJNZ %sloop", label);
3285 // outline1("JMP %send", label);
3286 // outhead1("%soverflow:", label);
3287 // outline0("OR A");
3288 // outline0("SBC HL, DE");
3289 // outhead1("%ssetbit:", label);
3290 // outline0("INC IXL");
3291 // outline1("DJNZ %sloop", label);
3292 // outhead1("%send:", label);
3293 // outline1("LD (%s), HL", _other_remainder);
3294 // outline1("LD HL, %s", _other);
3295 // outline0("PUSH AF");
3296 // outline0("PUSH IX");
3297 // outline0("POP AF");
3298 // outline0("LD (HL), A");
3299 // outline0("POP AF");
3300 // outline0("INC HL");
3301 // outline0("INC HL");
3302 // outline0("INC HL");
3303 // outline0("LD (HL), A");
3304 // outline0("DEC HL");
3305 // outline0("LD C, (HL)");
3306 // ; IN: ACIX=dividend, DE=divisor
3307 // ; OUT: ACIX=quotient, DE=divisor, HL=remainder, B=0
3308
3309 outline1("LD HL, (%s)", _source);
3310 outline0("LD IX, HL");
3311 outline1("LD HL, (%s)", address_displacement(_environment, _source, "2"));
3312 outline0("LD A, L");
3313 outline0("LD C, A");
3314 outline0("LD A, H");
3315 outline1("LD DE, $%4.4x", _destination);
3316
3317 outline0("LD HL, 0");
3318 outline0("LD B, 32");
3319 outhead1("%sloop1:", label);
3320 outline0("ADD IX, IX");
3321 outline0("RL C");
3322 outline0("RLA");
3323 outline0("ADC HL, HL");
3324 outline1("JR C, %sloop2", label);
3325 outline0("SBC HL, DE");
3326 outline1("JR NC, %sloop3", label);
3327 outline0("ADD HL, DE");
3328 outline1("DJNZ %sloop1", label);
3329 outline1("JR %sdone", label);
3330 outhead1("%sloop2:", label);
3331 outline0("OR A");
3332 outline0("SBC HL, DE");
3333 outhead1("%sloop3:", label);
3334 outline0("INC IXL");
3335 outline1("DJNZ %sloop1", label);
3336 outhead1("%sdone:", label);
3337
3338 outline1("LD (%s), HL", _other_remainder);
3339 outline0("LD H, A");
3340 outline0("LD A, C");
3341 outline0("LD L, C");
3342 outline1("LD (%s), HL", _other);
3343 outline0("LD HL, IX");
3344 outline1("LD (%s), HL", _other);
3345
3346 }
3347
3348}
3349
3350void cpu_math_div_nbit_to_nbit( Environment * _environment, char *_source, char *_destination, char *_other, char * _other_remainder, int _bits ) {
3351
3353
3354 int i;
3355
3357
3358 char afterLabel[MAX_TEMPORARY_STORAGE]; sprintf( afterLabel, "%safter", label );
3359 char skipLabel[MAX_TEMPORARY_STORAGE]; sprintf( skipLabel, "%sskip", label );
3360 char skip2Label[MAX_TEMPORARY_STORAGE]; sprintf( skip2Label, "%sskipb", label );
3361 char skip3Label[MAX_TEMPORARY_STORAGE]; sprintf( skip3Label, "%sskipc", label );
3362 char skip4Label[MAX_TEMPORARY_STORAGE]; sprintf( skip4Label, "%sskipd", label );
3363 char quotient[MAX_TEMPORARY_STORAGE]; sprintf( quotient, "CPUMATHDIVNBITTONBIT%d_QUOTIENT", _bits >> 3 );
3364 char divisor[MAX_TEMPORARY_STORAGE]; sprintf( divisor, "CPUMATHDIVNBITTONBIT%d_DIVISOR", _bits >> 3 );
3365 char dividend[MAX_TEMPORARY_STORAGE]; sprintf( dividend, "CPUMATHDIVNBITTONBIT%d_DIVIDEND", _bits >> 3 );
3366 char result1[MAX_TEMPORARY_STORAGE]; sprintf( result1, "CPUMATHDIVNBITTONBIT%d_RESULT1", _bits >> 3 );
3367 char result2[MAX_TEMPORARY_STORAGE]; sprintf( result2, "CPUMATHDIVNBITTONBIT%d_RESULT2", _bits >> 3 );
3368 char k[MAX_TEMPORARY_STORAGE]; sprintf( k, "CPUMATHDIVNBITTONBIT%d_K", _bits >> 3 );
3369
3370 if ( ! _environment->cpuOptimization.cpu_math_div_nbit_to_nbit[_bits>>3] ) {
3371
3372 cpu_jump( _environment, afterLabel );
3373
3374 outhead2("%s: defs %d", quotient, _bits>>3 );
3375 outhead2("%s: defs %d", divisor, _bits>>3 );
3376 outhead2("%s: defs %d", dividend, _bits>>3 );
3377 outhead1("%s: db 0", k );
3378 outhead1("%s: db 0", result1 );
3379 outhead1("%s: db 0", result2 );
3380
3381 // public static long div(long dividend, long divisor) {
3382 // long quotient = 0;
3383
3384 outhead1("CPUMATHDIVNBITTONBIT%d:", _bits>>3);
3385 outhead0("LD A, $00");
3386 for( i=0; i<(_bits>>3); ++i ) {
3387 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
3388 outline1("LD (%s), A", address_displacement( _environment, quotient, offset ) );
3389 }
3390
3391 // int k = 0;
3392 cpu_store_8bit( _environment, k, 0 );
3393
3394 // while (divisor <= dividend && divisor > 0) {
3395
3396 cpu_label( _environment, label );
3397 cpu_less_than_nbit( _environment, divisor, dividend, result1, 1, _bits );
3398 cpu_greater_than_nbit_const( _environment, divisor, 0, result2, 0, _bits );
3399 cpu_and_8bit( _environment, result1, result2, result1 );
3400 cpu_compare_and_branch_8bit_const( _environment, result1, 0, skipLabel, 1 );
3401
3402 // divisor <<= 1;
3403
3404 cpu_math_mul2_const_nbit( _environment, divisor, 1, _bits );
3405
3406 // k++;
3407
3408 cpu_inc( _environment, k );
3409
3410 // }
3411
3412 cpu_jump( _environment, label );
3413
3414 cpu_label( _environment, skipLabel );
3415
3416 // while (k-- > 0) {
3417
3418 cpu_greater_than_8bit_const( _environment, k, 0, result1, 0, 1 );
3419 cpu_dec( _environment, k );
3420 cpu_compare_and_branch_8bit_const( _environment, result1, 0, skip2Label, 1 );
3421
3422 // divisor >>= 1;
3423
3424 cpu_math_div2_const_nbit( _environment, divisor, 1, _bits, NULL );
3425
3426 // if (divisor <= dividend) {
3427 cpu_less_than_nbit( _environment, divisor, dividend, result1, 1, _bits );
3428 cpu_compare_and_branch_8bit_const( _environment, result1, 0, skip3Label, 1 );
3429
3430 // dividend -= divisor;
3431
3432 cpu_math_sub_nbit( _environment, dividend, divisor, dividend, _bits );
3433
3434 // quotient = (quotient << 1) + 1;
3435 cpu_math_mul2_const_nbit( _environment, quotient, 1, _bits );
3436 cpu_inc_nbit( _environment, quotient, _bits );
3437
3438 // }
3439 cpu_jump( _environment, skip4Label );
3440 cpu_label( _environment, skip3Label );
3441 // else quotient <<= 1;
3442 cpu_math_mul2_const_nbit( _environment, quotient, 1, _bits );
3443 cpu_label( _environment, skip4Label );
3444 cpu_jump( _environment, skipLabel );
3445
3446 // }
3447 cpu_label( _environment, skip2Label );
3448 // return quotient;
3449 cpu_return( _environment );
3450
3451 cpu_label( _environment, afterLabel );
3452
3453 }
3454
3455 for( i=0; i<(_bits>>3); ++i ) {
3456 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
3457 outline1("LD A, (%s)", address_displacement( _environment, _source, offset ) );
3458 outline1("LD (%s), A", address_displacement( _environment, dividend, offset ) );
3459 outline1("LD A, (%s)", address_displacement( _environment, _destination, offset ) );
3460 outline1("LD (%s), A", address_displacement( _environment, divisor, offset ) );
3461 }
3462 outline1("CALL CPUMATHDIVNBITTONBIT%d", _bits>>3);
3463
3464 for( i=0; i<(_bits>>3); ++i ) {
3465 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
3466 if ( _other ) {
3467 outline1("LD A, (%s)", address_displacement( _environment, quotient, offset ) );
3468 outline1("LD (%s), A", address_displacement( _environment, _other, offset ) );
3469 } else {
3470 outline1("LD A, (%s)", address_displacement( _environment, quotient, offset ) );
3471 outline1("LD (%s), A", address_displacement( _environment, _destination, offset ) );
3472 }
3473 }
3474
3475 // }
3477
3478}
3479
3480void cpu_math_div_nbit_to_nbit_const( Environment * _environment, char *_source, int _destination, char *_other, char * _other_remainder, int _bits ) {
3481
3483
3484 int i;
3485
3487
3488 char afterLabel[MAX_TEMPORARY_STORAGE]; sprintf( afterLabel, "%safter", label );
3489 char data[MAX_TEMPORARY_STORAGE]; sprintf( data, "CPUMATHDIVNBITTONBITCONST%d_DATA", _bits >> 3 );
3490
3491 if ( ! _environment->cpuOptimization.cpu_math_div_nbit_to_nbit_const[_bits>>3] ) {
3492
3493 cpu_jump( _environment, afterLabel );
3494
3495 outhead2("%s: defs %d", data, _bits>>3 );
3496
3497 cpu_label( _environment, afterLabel );
3498
3499 }
3500
3501 for( i=0; i<(_bits>>3); ++i ) {
3502 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
3503 outline1("LD A, $%2.2x", (unsigned char)( (_destination >> (i*8)) & 0xff ) );
3504 outline1("LD (%s), A", address_displacement( _environment, data, offset ) );
3505 }
3506 cpu_math_div_nbit_to_nbit( _environment, _source, data, _other, _other_remainder, _bits );
3507
3508 // }
3510
3511}
3512
3522void cpu_compare_32bit( Environment * _environment, char *_source, char *_destination, char *_other, int _positive ) {
3523
3524 inline( cpu_compare_32bit )
3525
3527
3528 outline1("LD A, (%s)", _source);
3529 outline0("LD B, A");
3530 outline1("LD A, (%s)", _destination);
3531 outline0("CP B");
3532 outline1("JP NZ, %s", label);
3533 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
3534 outline0("LD B, A");
3535 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
3536 outline0("CP B");
3537 outline1("JP NZ, %s", label);
3538 outline1("LD A, (%s)", address_displacement(_environment, _source, "2"));
3539 outline0("LD B, A");
3540 outline1("LD A, (%s)", address_displacement(_environment, _destination, "2"));
3541 outline0("CP B");
3542 outline1("JP NZ, %s", label);
3543 outline1("LD A, (%s)", address_displacement(_environment, _source, "3"));
3544 outline0("LD B, A");
3545 outline1("LD A, (%s)", address_displacement(_environment, _destination, "3"));
3546 outline0("CP B");
3547 outline1("JP NZ, %s", label);
3548 outline1("LD A, $%2.2x", 0xff*_positive);
3549 if ( _other ) {
3550 outline1("LD (%s), A", _other);
3551 } else {
3552 outline1("LD (%s), A", _destination);
3553 }
3554 outline1("JMP %s_2", label);
3555 outhead1("%s:", label);
3556 outline1("LD A, $%2.2x", 0xff*(1-_positive));
3557 if ( _other ) {
3558 outline1("LD (%s), A", _other);
3559 } else {
3560 outline1("LD (%s), A", _destination);
3561 }
3562 outhead1("%s_2:", label);
3563
3564 embedded( cpu_compare_32bit, src_hw_z80_cpu_compare_32bit_asm )
3565
3566 outline1("LD HL, %s", _source);
3567 outline1("LD DE, %s", _destination);
3568 outline1("LD IX, $%4.4x", ( (0xff*_positive) << 8 ) | ( 0xff*(1-_positive)) );
3569 outline0("CALL CPUCOMPARE32");
3570 if ( _other ) {
3571 outline1("LD (%s), A", _other);
3572 } else {
3573 outline1("LD (%s), A", _destination);
3574 }
3575
3576 done( )
3577
3578}
3579
3588void cpu_compare_nbit( Environment * _environment, char *_source, char *_destination, char *_other, int _positive, int _bits ) {
3589
3591
3592 inline( cpu_compare_nbit )
3593
3594 for( int i=0; i<(_bits>>3); ++i ) {
3595 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
3596 outline1("LD A, (%s)", address_displacement(_environment, _source, offset));
3597 outline0("LD B, A" );
3598 outline1("LD A, (%s)", address_displacement(_environment, _destination, offset));
3599 outline0("CP B");
3600 outline1("JP NZ, %s", label);
3601 }
3602 outline1("LD A, $%2.2x", 0xff*_positive);
3603 if ( _other ) {
3604 outline1("LD (%s), A", _other);
3605 } else {
3606 outline1("LD (%s), A", _destination);
3607 }
3608 outline1("JP %s_2", label);
3609 outhead1("%s:", label);
3610 outline1("LD A, $%2.2x", 0xff*(1-_positive));
3611 if ( _other ) {
3612 outline1("LD (%s), A", _other);
3613 } else {
3614 outline1("LD (%s), A", _destination);
3615 }
3616 outhead1("%s_2:", label);
3617
3619
3620}
3621
3622void cpu_compare_nbit_const( Environment * _environment, char *_source, int _destination, char *_other, int _positive, int _bits ) {
3623
3625
3626 inline( cpu_compare_nbit )
3627
3628 for( int i=0; i<(_bits>>3); ++i ) {
3629 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
3630 outline1("LD A, (%s)", address_displacement(_environment, _source, offset));
3631 outline1("LD B, $%2.2x", (unsigned char)((_destination>>(i*8))&0xff));
3632 outline0("CP B");
3633 outline1("JP NZ, %s", label);
3634 }
3635 outline1("LD A, $%2.2x", 0xff*_positive);
3636 if ( _other ) {
3637 outline1("LD (%s), A", _other);
3638 } else {
3639 outline1("LD (%s), A", _destination);
3640 }
3641 outline1("JP %s_2", label);
3642 outhead1("%s:", label);
3643 outline1("LD A, $%2.2x", 0xff*(1-_positive));
3644 if ( _other ) {
3645 outline1("LD (%s), A", _other);
3646 } else {
3647 outline1("LD (%s), A", _destination);
3648 }
3649 outhead1("%s_2:", label);
3650
3652
3653}
3654
3664void cpu_compare_32bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _positive ) {
3665
3666 inline( cpu_compare_32bit )
3667
3669
3670 outline1("LD A, (%s)", _source);
3671 outline0("LD B, A");
3672 outline1("LD A, $%2.2x", (unsigned char)(_destination & 0xff));
3673 outline0("CP B");
3674 outline1("JP NZ, %s", label);
3675 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
3676 outline0("LD B, A");
3677 outline1("LD A, $%2.2x", (unsigned char)((_destination>>8) & 0xff));
3678 outline0("CP B");
3679 outline1("JP NZ, %s", label);
3680 outline1("LD A, (%s)", address_displacement(_environment, _source, "2"));
3681 outline0("LD B, A");
3682 outline1("LD A, $%2.2x", (unsigned char)((_destination>>16) & 0xff));
3683 outline0("CP B");
3684 outline1("JP NZ, %s", label);
3685 outline1("LD A, (%s)", address_displacement(_environment, _source, "3"));
3686 outline0("LD B, A");
3687 outline1("LD A, $%2.2x", (unsigned char)((_destination>>24) & 0xff));
3688 outline0("CP B");
3689 outline1("JP NZ, %s", label);
3690 outline1("LD A, $%2.2x", 0xff*_positive);
3691 outline1("LD (%s), A", _other);
3692 outline1("JMP %s_2", label);
3693 outhead1("%s:", label);
3694 outline1("LD A, $%2.2x", 0xff*(1-_positive));
3695 outline1("LD (%s), A", _other);
3696 outhead1("%s_2:", label);
3697
3698 embedded( cpu_compare_32bit, src_hw_z80_cpu_compare_32bit_asm )
3699
3700 outline1("LD HL, %s", _source);
3701 outline1("LD DE, $%4.4x", (unsigned int)(_destination&0xffff));
3702 outline1("LD IY, $%4.4x", (unsigned int)((_destination>>16)&0xffff));
3703 outline1("LD IX, $%4.4x", ( (0xff*_positive) << 8 ) | ( 0xff*(1-_positive)) );
3704 outline0("CALL CPUCOMPARE32CONST");
3705 outline1("LD (%s), A", _other);
3706
3707 done( )
3708
3709}
3710
3720void cpu_compare_and_branch_32bit_const( Environment * _environment, char *_source, int _destination, char *_label, int _positive ) {
3721
3723
3725
3726 outline1("LD A, (%s)", address_displacement(_environment, _source, "3"));
3727 outline1("CP $%2.2x", ( _destination >> 24 ) & 0xff );
3728 outline1("JP NZ, %s", label);
3729 outline1("LD A, (%s)", address_displacement(_environment, _source, "2"));
3730 outline1("CP $%2.2x", ( _destination >> 16 ) & 0xff );
3731 outline1("JP NZ, %s", label);
3732 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
3733 outline1("CP $%2.2x", ( _destination >> 8 ) & 0xff );
3734 outline1("JP NZ, %s", label);
3735 outline1("LD A, (%s)", _source);
3736 outline1("CP $%2.2x", ( _destination & 0xff ) );
3737 outline1("JP NZ, %s", label);
3738
3739 if ( _positive ) {
3740 outline1("JP %s", _label);
3741 outhead1("%s:", label );
3742 } else {
3743 outline1("JP %snot", label);
3744 outhead1("%s:", label );
3745 outline1("JP %s", _label);
3746 outhead1("%snot:", label );
3747 }
3748
3750
3751}
3752
3762void cpu_less_than_32bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
3763
3765
3766 inline( cpu_less_than_32bit )
3767
3768 if ( _signed ) {
3769
3770 outline1("LD IX, %s", _source);
3771 outline1("LD IY, %s", _destination);
3772 outline0("LD B, (IX+3)");
3773 outline0("LD A, B");
3774 outline0("AND $80");
3775 outline0("CP 0" );
3776 outline1("JR NZ,%sNEGM1", label);
3777 outline0("BIT 7, (IY+3)");
3778 outline1("JR NZ,%sdone", label);
3779 outline0("LD A, B");
3780 outline0("CP (IY+3)");
3781 outline1("JR NZ,%sdone", label);
3782 outline0("LD A, (IX+2)");
3783 outline0("CP (IY+2)");
3784 outline1("JR NZ,%sdone", label);
3785 outline0("LD A, (IX+1)");
3786 outline0("CP (IY+1)");
3787 outline1("JR NZ,%sdone", label);
3788 outline0("LD A, (IX)");
3789 outline0("CP (IY)");
3790 outline1("JMP %sdone", label);
3791 outhead1("%sNEGM1:", label);
3792 outline0("XOR (IY+3)");
3793 outline0("RLA");
3794 outline1("JR C,%sdone", label);
3795 outline0("LD A, B");
3796 outline0("CP (IY+3)");
3797 outline1("JR NZ,%sdone", label);
3798 outline0("LD A, (IX+2)");
3799 outline0("CP (IY+2)");
3800 outline1("JR NZ,%sdone", label);
3801 outline0("LD A, (IX+1)");
3802 outline0("CP (IY+1)");
3803 outline1("JR NZ,%sdone", label);
3804 outline0("LD A, (IX)");
3805 outline0("CP (IY)");
3806 outline1("JMP %sdone", label);
3807 outhead1("%sdone:", label);
3808 if ( _equal ) {
3809 outline1("JR Z,%smi", label);
3810 }
3811 outline1("JR C,%smi", label);
3812 outhead1("%spl:", label);
3813 outline0("LD A, 0");
3814 if ( _other ) {
3815 outline1("LD (%s), A", _other);
3816 } else {
3817 outline1("LD (%s), A", _destination);
3818 }
3819 outline1("JMP %sdone2", label);
3820 outhead1("%smi:", label);
3821 outline0("LD A, $ff");
3822 if ( _other ) {
3823 outline1("LD (%s), A", _other);
3824 } else {
3825 outline1("LD (%s), A", _destination);
3826 }
3827 outline1("JMP %sdone2", label);
3828 outhead1("%sdone2:", label);
3829
3830 } else {
3831
3832 outline1("LD A, (%s)", address_displacement(_environment, _source, "3"));
3833 outline0("LD B, A");
3834 outline1("LD A, (%s)", address_displacement(_environment, _destination, "3"));
3835 outline0("CP B");
3836 outline1("JR Z, %s_2", label);
3837 outline1("JR C, %s", label);
3838 outline1("JR %s_ok", label);
3839 outhead1("%s_2:", label);
3840 outline1("LD A, (%s)", address_displacement(_environment, _source, "2"));
3841 outline0("LD B, A");
3842 outline1("LD A, (%s)", address_displacement(_environment, _destination, "2"));
3843 outline0("CP B");
3844 outline1("JR Z, %s_1", label);
3845 outline1("JR C, %s", label);
3846 outline1("JR %s_ok", label);
3847 outhead1("%s_1:", label);
3848 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
3849 outline0("LD B, A");
3850 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
3851 outline0("CP B");
3852 outline1("JR Z, %s_0", label);
3853 outline1("JR C, %s", label);
3854 outline1("JR %s_ok", label);
3855 outhead1("%s_0:", label);
3856 outline1("LD A, (%s)", _source);
3857 outline0("LD B, A");
3858 outline1("LD A, (%s)", _destination);
3859 outline0("CP B");
3860 if ( _equal ) {
3861 outline1("JR Z, %s_ok", label);
3862 } else {
3863 outline1("JR Z, %s", label);
3864 }
3865 outline1("JR C, %s", label);
3866 outhead1("%s_ok:", label);
3867 outline0("LD A, $ff");
3868 if ( _other ) {
3869 outline1("LD (%s), A", _other);
3870 } else {
3871 outline1("LD (%s), A", _destination);
3872 }
3873 outline1("JMP %s_xx", label);
3874 outhead1("%s:", label);
3875 outline0("LD A, $0");
3876 if ( _other ) {
3877 outline1("LD (%s), A", _other);
3878 } else {
3879 outline1("LD (%s), A", _destination);
3880 }
3881 outhead1("%s_xx:", label);
3882
3883 }
3884
3885 embedded( cpu_less_than_32bit, src_hw_z80_cpu_less_than_32bit_asm );
3886
3887 if ( _signed ) {
3888
3889 outline1("LD IY, %s", _destination);
3890 outline1("LD IX, %s", _source);
3891 if ( _equal ) {
3892 outline0("CALL CPULTE32S");
3893 } else {
3894 outline0("CALL CPULT32S");
3895 }
3896 if ( _other ) {
3897 outline1("LD (%s), A", _other);
3898 } else {
3899 outline1("LD (%s), A", _destination);
3900 }
3901
3902 } else {
3903
3904 outline1("LD IY, %s", _destination);
3905 outline1("LD IX, %s", _source);
3906 if ( _equal ) {
3907 outline0("CALL CPULTE32U");
3908 } else {
3909 outline0("CALL CPULT32U");
3910 }
3911 if ( _other ) {
3912 outline1("LD (%s), A", _other);
3913 } else {
3914 outline1("LD (%s), A", _destination);
3915 }
3916
3917 }
3918
3919 done( )
3920
3921
3922}
3923
3924void cpu_less_than_32bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
3925
3927
3928 inline( cpu_less_than_32bit )
3929
3930 if ( _signed ) {
3931
3932 // outline1("LD IX, %s", _source);
3933 // outline1("LD IY, %s", _destination);
3934 // outline0("LD B, (IX+3)");
3935 // outline0("LD A, B");
3936 // outline0("AND $80");
3937 // outline1("JR NZ,%sNEGM1", label);
3938 // outline0("BIT 7, (IY+3)");
3939 // outline1("JR NZ,%sdone", label);
3940 // outline0("LD A, B");
3941 // outline0("CP (IY+3)");
3942 // outline1("JR NZ,%sdone", label);
3943 // outline0("LD A, (IX+2)");
3944 // outline0("CP (IY+2)");
3945 // outline1("JR NZ,%sdone", label);
3946 // outline0("LD A, (IX+1)");
3947 // outline0("CP (IY+1)");
3948 // outline1("JR NZ,%sdone", label);
3949 // outline0("LD A, (IX)");
3950 // outline0("CP (IY)");
3951 // outline1("JMP %sdone", label);
3952 // outhead1("%sNEGM1:", label);
3953 // outline0("XOR (IY+3)");
3954 // outline0("RLA");
3955 // outline1("JR C,%sdone", label);
3956 // outline0("LD A, B");
3957 // outline0("CP (IY+3)");
3958 // outline1("JR NZ,%sdone", label);
3959 // outline0("LD A, (IX+2)");
3960 // outline0("CP (IY+2)");
3961 // outline1("JR NZ,%sdone", label);
3962 // outline0("LD A, (IX+1)");
3963 // outline0("CP (IY+1)");
3964 // outline1("JR NZ,%sdone", label);
3965 // outline0("LD A, (IX)");
3966 // outline0("CP (IY)");
3967 // outline1("JMP %sdone", label);
3968 // outhead1("%sdone:", label);
3969 // if ( _equal ) {
3970 // outline1("JR Z,%smi", label);
3971 // }
3972 // outline1("JR C,%smi", label);
3973 // outhead1("%spl:", label);
3974 // outline0("LD A, 0");
3975 // if ( _other ) {
3976 // outline1("LD (%s), A", _other);
3977 // } else {
3978 // outline1("LD (%s), A", _destination);
3979 // }
3980 // outline1("JMP %sdone2", label);
3981 // outhead1("%smi:", label);
3982 // outline0("LD A, $ff");
3983 // if ( _other ) {
3984 // outline1("LD (%s), A", _other);
3985 // } else {
3986 // outline1("LD (%s), A", _destination);
3987 // }
3988 // outline1("JMP %sdone2", label);
3989 // outhead1("%sdone2:", label);
3990
3991 } else {
3992
3993 outline1("LD A, (%s)", address_displacement(_environment, _source, "3"));
3994 outline0("LD B, A");
3995 outline1("LD A, $%2.2x", (unsigned char)( ( _destination >> 24 ) && 0xff ) );
3996 outline0("CP B");
3997 outline1("JR Z, %s_2", label);
3998 outline1("JR C, %s", label);
3999 outline1("JR %s_ok", label);
4000 outhead1("%s_2:", label);
4001 outline1("LD A, (%s)", address_displacement(_environment, _source, "2"));
4002 outline0("LD B, A");
4003 outline1("LD A, $%2.2x", (unsigned char)( ( _destination >> 16 ) && 0xff ) );
4004 outline0("CP B");
4005 outline1("JR Z, %s_1", label);
4006 outline1("JR C, %s", label);
4007 outline1("JR %s_ok", label);
4008 outhead1("%s_1:", label);
4009 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
4010 outline0("LD B, A");
4011 outline1("LD A, $%2.2x", (unsigned char)( ( _destination >> 8 ) && 0xff ) );
4012 outline0("CP B");
4013 outline1("JR Z, %s_0", label);
4014 outline1("JR C, %s", label);
4015 outline1("JR %s_ok", label);
4016 outhead1("%s_0:", label);
4017 outline1("LD A, (%s)", _source);
4018 outline0("LD B, A");
4019 outline1("LD A, $%2.2x", (unsigned char)( _destination && 0xff ) );
4020 outline0("CP B");
4021 outline1("JR C, %s", label);
4022 if ( _equal ) {
4023 outline1("JR Z, %s", label);
4024 }
4025 outhead1("%s_ok:", label);
4026 outline0("LD A, $ff");
4027 outline1("LD (%s), A", _other);
4028 outline1("JMP %s_xx", label);
4029 outhead1("%s:", label);
4030 outline0("LD A, $0");
4031 outline1("LD (%s), A", _other);
4032 outhead1("%s_xx:", label);
4033
4034 }
4035
4036 embedded( cpu_less_than_32bit, src_hw_z80_cpu_less_than_32bit_asm );
4037
4038 if ( _signed ) {
4039
4040 outline1("LD DE, $%4.4x", ( ( _destination >> 16 ) & 0xffff ) );
4041 outline0("PUSH DE" );
4042 outline1("LD DE, $%4.4x", ( _destination & 0xffff ) );
4043 outline0("PUSH DE" );
4044 outline0("LD DE, SP" );
4045 outline0("LD IY, DE" );
4046 outline1("LD IX, %s", _source);
4047 if ( _equal ) {
4048 outline0("CALL CPULTE32S");
4049 } else {
4050 outline0("CALL CPULT32S");
4051 }
4052 outline1("LD (%s), A", _other);
4053 outline0("POP DE" );
4054 outline0("POP DE" );
4055
4056 } else {
4057
4058 outline1("LD DE, $%4.4x", ( ( _destination >> 16 ) & 0xffff ) );
4059 outline0("PUSH DE" );
4060 outline1("LD DE, $%4.4x", ( _destination & 0xffff ) );
4061 outline0("PUSH DE" );
4062 outline0("LD DE, SP" );
4063 outline0("LD IY, DE" );
4064 outline1("LD IX, %s", _source);
4065 if ( _equal ) {
4066 outline0("CALL CPULTE32U");
4067 } else {
4068 outline0("CALL CPULT32U");
4069 }
4070 outline1("LD (%s), A", _other);
4071 outline0("POP DE" );
4072 outline0("POP DE" );
4073
4074 }
4075
4076 done( )
4077
4078}
4079
4080void cpu_less_than_nbit( Environment * _environment, char *_source, char * _destination, char *_other, int _equal, int _bits ) {
4081
4083
4084 int i;
4085
4086 inline( cpu_less_than_nbit )
4087
4088 for( i=(_bits>>3)-1; i>-1; --i ) {
4089 char offset[MAX_TEMPORARY_STORAGE]; sprintf(offset, "%d", i );
4090 outline1("LD A, (%s)", address_displacement(_environment, _destination, offset ) );
4091 outline0("LD B, A");
4092 outline1("LD A, (%s)", address_displacement(_environment, _source, offset ) );
4093 outline0("CP B");
4094 outline2("JR Z, %snext%dx", label, i );
4095 outline1("JP C, %sbga", label );
4096 outline1("JP %sagb", label );
4097 outhead2("%snext%dx:", label, i );
4098 }
4099
4100 outhead1("%sbge:", label );
4101 if ( _equal ) {
4102 outline0("LD A, 0xff" );
4103 } else {
4104 outline0("LD A, 0x00" );
4105 }
4106 outline1("LD (%s), A", _other );
4107 outline1("JR %sdone", label );
4108
4109 outhead1("%sbga:", label );
4110 outline0("LD A, 0xff" );
4111 outline1("LD (%s), A", _other );
4112 outline1("JR %sdone", label );
4113
4114 outhead1("%sagb:", label );
4115 outline0("LD A, 0x00" );
4116 outline1("LD (%s), A", _other );
4117 outline1("JR %sdone", label );
4118
4119 outhead1("%sdone:", label );
4120
4122
4123}
4124
4125void cpu_less_than_nbit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _bits ) {
4126
4128
4129 int i;
4130
4131 inline( cpu_less_than_nbit_const )
4132
4133 for( i=(_bits>>3)-2; i>-1; --i ) {
4134 char offset[MAX_TEMPORARY_STORAGE]; sprintf(offset, "%d", i );
4135 outline1("LD B, $%2.2x", (unsigned char)((_destination>>(i*8))&0xff) );
4136 outline1("LD A, (%s)", address_displacement(_environment, _source, offset ) );
4137 outline0("CP B");
4138 outline2("JR Z, %snext%dx", label, i );
4139 outline1("JP C, %sbga", label );
4140 outline1("JP %sagb", label );
4141 outhead2("%snext%dx:", label, i );
4142 }
4143
4144 outhead1("%sbge:", label );
4145 if ( _equal ) {
4146 outline0("LD A, 0xff" );
4147 } else {
4148 outline0("LD A, 0x00" );
4149 }
4150 outline1("LD (%s), A", _other );
4151 outline1("JR %sdone", label );
4152
4153 outhead1("%sbga:", label );
4154 outline0("LD A, 0xff" );
4155 outline1("LD (%s), A", _other );
4156 outline1("JR %sdone", label );
4157
4158 outhead1("%sagb:", label );
4159 outline0("LD A, 0x00" );
4160 outline1("LD (%s), A", _other );
4161 outline1("JR %sdone", label );
4162
4163 outhead1("%sdone:", label );
4164
4166
4167}
4168
4178void cpu_greater_than_32bit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _signed ) {
4179
4180 cpu_less_than_32bit( _environment, _source, _destination, _other, !_equal, _signed );
4181 if ( _other ) {
4182 cpu_not_8bit( _environment, _other, _other );
4183 } else {
4184 cpu_not_8bit( _environment, _destination, _destination );
4185 }
4186
4187}
4188
4189void cpu_greater_than_32bit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _signed ) {
4190
4191 cpu_less_than_32bit_const( _environment, _source, _destination, _other, !_equal, _signed );
4192 cpu_not_8bit( _environment, _other, _other );
4193
4194}
4195
4196
4197
4198void cpu_greater_than_nbit( Environment * _environment, char *_source, char *_destination, char *_other, int _equal, int _bits ) {
4199
4200 inline( cpu_greater_than_nbit )
4201
4202 cpu_less_than_nbit( _environment, _source, _destination, _other, !_equal, _bits );
4203 if ( _other ) {
4204 cpu_not_8bit( _environment, _other, _other );
4205 } else {
4206 cpu_not_8bit( _environment, _destination, _destination );
4207 }
4208
4210
4211}
4212
4213void cpu_greater_than_nbit_const( Environment * _environment, char *_source, int _destination, char *_other, int _equal, int _bits ) {
4214
4215 inline( cpu_greater_than_nbit )
4216
4217 cpu_less_than_nbit_const( _environment, _source, _destination, _other, !_equal, _bits );
4218 cpu_not_8bit( _environment, _other, _other );
4219
4221
4222}
4223
4232void cpu_math_add_32bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
4233
4234 inline( cpu_math_add_32bit )
4235
4236 outline1("LD HL, (%s)", _source );
4237 outline1("LD DE, (%s)", _destination );
4238 outline0("EXX" );
4239 outline1("LD HL, (%s)", address_displacement(_environment, _source, "2") );
4240 outline1("LD DE, (%s)", address_displacement(_environment, _destination, "2") );
4241 outline0("EXX" );
4242 outline0("ADD HL, DE" );
4243 outline0("EXX" );
4244 outline0("ADC HL, DE" );
4245 outline0("EXX" );
4246 if ( _other ) {
4247 outline1("LD (%s), HL", _other );
4248 outline0("EXX" );
4249 outline1("LD (%s), HL", address_displacement( _environment, _other, "2" ) );
4250 } else {
4251 outline1("LD (%s), HL", _destination );
4252 outline0("EXX" );
4253 outline1("LD (%s), HL", address_displacement( _environment, _destination, "2" ) );
4254 }
4255
4257
4258}
4259
4260void cpu_math_add_32bit_const( Environment * _environment, char *_source, int _destination, char *_other ) {
4261
4262 inline( cpu_math_add_32bit_const )
4263
4264 outline1("LD HL, (%s)", _source );
4265 outline1("LD DE, $%4.4x", ( _destination & 0xffff ) );
4266 outline0("EXX" );
4267 outline1("LD HL, (%s)", address_displacement(_environment, _source, "2") );
4268 outline1("LD DE, $%4.4x", ( ( _destination >> 16 ) & 0xffff ) );
4269 outline0("EXX" );
4270 outline0("ADD HL, DE" );
4271 outline0("EXX" );
4272 outline0("ADC HL, DE" );
4273 outline0("EXX" );
4274 outline1("LD (%s), HL", _other );
4275 outline0("EXX" );
4276 outline1("LD (%s), HL", address_displacement( _environment, _other, "2" ) );
4277
4279
4280}
4281
4282void cpu_math_add_nbit( Environment * _environment, char *_source, char *_destination, char *_other, int _bits ) {
4283
4284 inline( cpu_math_add_nbit )
4285
4286 outline0("XOR A");
4287 for( int i=0; i<(_bits>>3); ++i ) {
4288 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
4289 outline1("LD A, (%s)", address_displacement(_environment, _source, offset));
4290 outline0("LD B, A");
4291 outline1("LD A, (%s)", address_displacement(_environment, _destination, offset));
4292 outline0("ADC A, B");
4293 if ( _other ) {
4294 outline1("LD (%s), A", address_displacement(_environment, _other, offset));
4295 } else {
4296 outline1("LD (%s), A", address_displacement(_environment, _destination, offset));
4297 }
4298 }
4300
4301}
4302
4303void cpu_math_add_nbit_const( Environment * _environment, char *_source, int _destination, char *_other, int _bits ) {
4304
4305 int i;
4306
4307 inline( cpu_math_add_nbit_const )
4308
4309 outline0("CLC");
4310 for( i=0; i<(_bits>>3); ++i ) {
4311 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
4312 outline1("LD A, (%s)", address_displacement(_environment, _source, offset));
4313 outline1("ADC #$%2.2x", (unsigned char)( ( _destination >> (i*8) ) & 0xff ) ); outline0("ADC A, B");
4314 outline1("LD (%s), A", address_displacement(_environment, _other, offset));
4315 }
4316
4318
4319}
4320
4328void cpu_math_double_32bit( Environment * _environment, char *_source, char *_other, int _signed ) {
4329
4330 inline( cpu_math_double_32bit )
4331
4332 if ( _other ) {
4333 cpu_math_add_32bit( _environment, _source, _source, _other );
4334 } else {
4335 cpu_math_add_32bit( _environment, _source, _source, _source );
4336 }
4337
4339
4340}
4341
4350void cpu_math_sub_32bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
4351
4352 inline( cpu_math_sub_32bit )
4353
4355
4356 outline1("LD HL, (%s)", _source );
4357 outline1("LD DE, (%s)", _destination );
4358 outline0("LD A, E" );
4359 outline0("XOR $FF" );
4360 outline0("LD E, A" );
4361 outline0("LD A, D" );
4362 outline0("XOR $FF" );
4363 outline0("LD D, A" );
4364 outline0("INC DE" );
4365 outline0("LD A, D" );
4366 outline0("OR E" );
4367 outline0("PUSH AF" );
4368 outline0("EXX" );
4369 outline1("LD HL, (%s)", address_displacement(_environment, _source, "2") );
4370 outline1("LD DE, (%s)", address_displacement(_environment, _destination, "2") );
4371 outline0("LD A, E" );
4372 outline0("XOR $FF" );
4373 outline0("LD E, A" );
4374 outline0("LD A, D" );
4375 outline0("XOR $FF" );
4376 outline0("LD D, A" );
4377 outline0("POP AF" );
4378 outline0("CP 0" );
4379 outline1("JR NZ, %snoincde", label );
4380 outline0("INC DE" );
4381 outline1("%snoincde:", label );
4382 outline0("EXX" );
4383 outline0("ADD HL, DE" );
4384 outline0("EXX" );
4385 outline0("ADC HL, DE" );
4386 outline0("EXX" );
4387 if ( _other ) {
4388 outline1("LD (%s), HL", _other );
4389 outline0("EXX" );
4390 outline1("LD (%s), HL", address_displacement( _environment, _other, "2" ) );
4391 } else {
4392 outline1("LD (%s), HL", _destination );
4393 outline0("EXX" );
4394 outline1("LD (%s), HL", address_displacement( _environment, _destination, "2" ) );
4395 }
4396
4398
4399}
4400
4401void cpu_math_sub_nbit( Environment * _environment, char *_source, char *_destination, char *_other, int _bits ) {
4402
4403 inline( cpu_math_sub_nbit )
4404
4405 outline0("XOR A");
4406 for( int i=0; i<(_bits)>>3; ++i ) {
4407 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
4408 outline1("LD A, (%s)", address_displacement(_environment, _destination, offset));
4409 outline0("LD B, A");
4410 outline1("LD A, (%s)", address_displacement(_environment, _source, offset));
4411 outline0("SBC A, B");
4412 if ( _other ) {
4413 outline1("LD (%s), A", address_displacement(_environment, _other, offset));
4414 } else {
4415 outline1("LD (%s), A", address_displacement(_environment, _destination, offset));
4416 }
4417 }
4418
4420
4421}
4422
4430void cpu_math_complement_const_32bit( Environment * _environment, char *_source, int _value ) {
4431
4433
4434 outline1("LD HL, $%4.4x", ( _value & 0xffff ) );
4435 outline1("LD DE, (%s)", _source );
4436 outline0("LD A, E" );
4437 outline0("XOR $FF" );
4438 outline0("LD E, A" );
4439 outline0("LD A, D" );
4440 outline0("XOR $FF" );
4441 outline0("LD D, A" );
4442 outline0("INC DE" );
4443 outline0("EXX" );
4444 outline1("LD HL, $%4.4x", ( ( _value >> 16 ) & 0xffff ) );
4445 outline1("LD DE, (%s)", address_displacement(_environment, _source, "2") );
4446 outline0("LD A, E" );
4447 outline0("XOR $FF" );
4448 outline0("LD E, A" );
4449 outline0("LD A, D" );
4450 outline0("XOR $FF" );
4451 outline0("LD D, A" );
4452 outline0("INC DE" );
4453 outline0("EXX" );
4454 outline0("ADD HL, DE" );
4455 outline0("EXX" );
4456 outline0("ADC HL, DE" );
4457 outline0("EXX" );
4458 outline1("LD (%s), HL", _source );
4459 outline0("EXX" );
4460 outline1("LD (%s), HL", address_displacement( _environment, _source, "2" ) );
4461
4463
4464}
4465
4473void cpu_math_div2_const_32bit( Environment * _environment, char *_source, int _steps, int _signed, char * _remainder ) {
4474
4476
4478
4479 if ( _remainder ) {
4480 outline1("LD A, (%s)", _source );
4481 outline0("AND $1" );
4482 outline1("LD (%s), A", _remainder );
4483 }
4484 if ( _signed ) {
4485 outline1("LD A, (%s)", address_displacement(_environment, _source, "3") );
4486 outline0("AND $80" );
4487 outline0("CP 0" );
4488 outline0("PUSH AF" );
4489 outline1("JR Z, %spos", label );
4490 cpu_complement2_32bit( _environment, _source, _source );
4491 outline1("JMP %spos2", label );
4492 outhead1("%spos:", label );
4493 outhead1("%spos2:", label );
4494 outline1("LD DE, (%s)", _source );
4495 outline1("LD BC, (%s)", address_displacement(_environment, _source, "2") );
4496 while( _steps ) {
4497 outline0("SRA B" );
4498 outline0("RR C" );
4499 outline0("RR D" );
4500 outline0("RR E" );
4501 --_steps;
4502 }
4503 outline1("LD (%s),DE", _source );
4504 outline1("LD (%s),BC", address_displacement( _environment, _source, "2" ) );
4505 outline0("POP AF" );
4506 outline0("AND $80" );
4507 outline0("CP 0" );
4508 outline1("JR Z, %sdone", label );
4509 cpu_complement2_32bit( _environment, _source, _source );
4510 outhead1("%sdone:", label );
4511 } else {
4512 outline1("LD DE, (%s)", _source );
4513 outline1("LD BC, (%s)", address_displacement(_environment, _source, "2") );
4514 while( _steps ) {
4515 outline0("SRA B" );
4516 outline0("RR C" );
4517 outline0("RR D" );
4518 outline0("RR E" );
4519 --_steps;
4520 }
4521 outline1("LD (%s), DE", _source );
4522 outline1("LD (%s), BC", address_displacement( _environment, _source, "2" ) );
4523 }
4524
4526
4527}
4528
4529void cpu_math_div2_const_nbit( Environment * _environment, char *_source, int _steps, int _bits, char * _remainder ) {
4530
4531 inline( cpu_math_div2_const_nbit )
4532
4534
4535 if ( _remainder ) {
4536 outline1("LD A, (%s)", _source);
4537 outline0("AND $01" );
4538 outline1("LD (%s), A", _remainder);
4539 }
4540 char offsetMsb[MAX_TEMPORARY_STORAGE]; sprintf( offsetMsb, "%d", (_bits>>3)-1 );
4541
4542 outline1("LD A, (%s)", address_displacement(_environment, _source, offsetMsb));
4543 outline0("AND $80");
4544 outline0("LD B, A");
4545 outline0("CP $00");
4546 outline1("JP Z, %snocomplement", label );
4547 cpu_complement2_nbit( _environment, _source, _source, _bits );
4548 outhead1("%snocomplement:", label );
4549 while( _steps ) {
4550 outline0("XOR A");
4551 outline1("LD A, (%s)", address_displacement(_environment, _source, offsetMsb));
4552 outline0("SRA A");
4553 outline1("LD (%s), A", address_displacement(_environment, _source, offsetMsb));
4554 for( int i=(_bits>>3)-2; i>-1; --i ) {
4555 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
4556 outline1("LD A, (%s)", address_displacement(_environment, _source, offset));
4557 outline0("RR A");
4558 outline1("LD (%s), A", address_displacement(_environment, _source, offset));
4559 }
4560 --_steps;
4561 }
4562 outline0("LD A, B");
4563 outline0("CP $00");
4564 outline1("JP Z, %snocomplement2", label );
4565 cpu_complement2_nbit( _environment, _source, _source, _bits );
4566 outhead1("%snocomplement2:", label );
4567
4569
4570}
4571
4579void cpu_math_mul2_const_32bit( Environment * _environment, char *_source, int _steps, int _signed ) {
4580
4582
4584
4585 if ( _signed ) {
4586 outline1("LD A, (%s)", address_displacement(_environment, _source, "3") );
4587 outline0("AND $80" );
4588 outline0("CP 0" );
4589 outline0("PUSH AF" );
4590 outline1("JR Z, %spos", label );
4591 cpu_complement2_32bit( _environment, _source, _source );
4592 outline1("JMP %spos2", label );
4593 outhead1("%spos:", label );
4594 outhead1("%spos2:", label );
4595 outline1("LD HL, (%s)", _source );
4596 outline1("LD DE, (%s)", address_displacement(_environment, _source, "2") );
4597 while( _steps ) {
4598 outline0("SLA L" );
4599 outline0("RL H" );
4600 outline0("RL E" );
4601 outline0("RL D" );
4602 --_steps;
4603 }
4604 outline1("LD (%s), HL", _source );
4605 outline1("LD (%s), DE", address_displacement( _environment, _source, "2" ) );
4606 outline0("POP AF" );
4607 outline0("AND $80" );
4608 outline0("CP 0" );
4609 outline1("JR Z, %sdone", label );
4610 cpu_complement2_32bit( _environment, _source, _source );
4611 outhead1("%sdone:", label );
4612 } else {
4613 outline1("LD HL, (%s)", _source );
4614 outline1("LD DE, (%s)", address_displacement(_environment, _source, "2") );
4615 while( _steps ) {
4616 outline0("SLA L" );
4617 outline0("RL H" );
4618 outline0("RL D" );
4619 outline0("RL E" );
4620 --_steps;
4621 }
4622 outline1("LD (%s), HL", _source );
4623 outline1("LD (%s), DE", address_displacement( _environment, _source, "2" ) );
4624 }
4625
4627
4628}
4629
4630void cpu_math_mul2_const_nbit( Environment * _environment, char *_source, int _steps, int _bits ) {
4631
4632 int i;
4633
4634 inline( cpu_math_mul2_const_nbit )
4635
4636 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", (_bits>>3)-1 );
4637 outline1("LD A, (%s)", address_displacement(_environment, _source, offset));
4638 outline0("AND $80");
4639 outline0("LD B, A");
4640 while( _steps ) {
4641 outline0("SCF")
4642 outline0("CCF");
4643 outline1("LD A, (%s)", address_displacement(_environment, _source, "0"));
4644 outline0("SLA A");
4645 outline1("LD (%s), A", address_displacement(_environment, _source, "0"));
4646 for( i=1; i<(_bits>>3); ++i ) {
4647 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i);
4648 outline1("LD A, (%s)", address_displacement(_environment, _source, offset));
4649 outline0("RL A");
4650 outline1("LD (%s), A", address_displacement(_environment, _source, offset));
4651 }
4652 --_steps;
4653 }
4654 outline1("LD A, (%s)", address_displacement(_environment, _source, offset));
4655 outline0("OR B");
4656 outline1("LD (%s), A", address_displacement(_environment, _source, offset));
4657
4659
4660}
4661
4662
4670void cpu_math_and_const_32bit( Environment * _environment, char *_source, int _mask ) {
4671
4672 inline( cpu_math_and_const_32bit )
4673
4674 outline1("LD A, (%s)", _source );
4675 outline1("AND $%2.2x", ( _mask & 0xff ) );
4676 outline1("LD (%s), A", _source );
4677 outline1("LD A, (%s)", address_displacement(_environment, _source, "1") );
4678 outline1("AND $%2.2x", ( ( _mask >> 8 ) & 0xff ) );
4679 outline1("LD (%s), A", address_displacement(_environment, _source, "1") );
4680 outline1("LD A, (%s)", address_displacement(_environment, _source, "2") );
4681 outline1("AND $%2.2x", ( ( _mask >> 16 ) & 0xff ) );
4682 outline1("LD (%s), A", address_displacement(_environment, _source, "2") );
4683 outline1("LD A, (%s)", address_displacement(_environment, _source, "3") );
4684 outline1("AND $%2.2x", ( ( _mask >> 24 ) & 0xff ) );
4685 outline1("LD (%s), A", address_displacement(_environment, _source, "3") );
4686
4688
4689}
4690
4694void cpu_combine_nibbles( Environment * _environment, char * _low_nibble, char * _hi_nibble, char * _byte ) {
4695
4697
4698 embedded( cpu_combine_nibbles, src_hw_z80_cpu_combine_nibbles_asm );
4699
4700 outline1("LD A, (%s)", _low_nibble );
4701 outline1("LD HL, %s", _hi_nibble );
4702 outline1("LD DE, %s", _byte );
4703 outline0("CALL CPUCOMBINENIBBLES" );
4704
4705 done( )
4706
4707}
4708
4709void cpu_jump( Environment * _environment, char * _label ) {
4710
4711 outline1("jp %s", _label );
4712
4713}
4714
4715void cpu_call_addr( Environment * _environment, int _address ) {
4716
4717 outline1("call $%4.4x", _address );
4718
4719}
4720
4721void cpu_call( Environment * _environment, char * _label ) {
4722
4723 outline1("call %s", _label );
4724
4725}
4726
4727void cpu_call_indirect( Environment * _environment, char * _value ) {
4728
4730
4731 char indirectLabel[MAX_TEMPORARY_STORAGE]; sprintf( indirectLabel, "%sindirect", label );
4732
4733 outline0( "LD (CALLINDIRECTSAVEHL), HL" )
4734 outline1( "LD HL, (%s)", _value )
4735 outline0( "LD (CALLINDIRECT+1), HL" )
4736 outline0( "LD HL, (CALLINDIRECTSAVEHL)" )
4737 outline0( "CALL CALLINDIRECT" );
4738
4739}
4740
4741void cpu_jump_indirect( Environment * _environment, char * _value ) {
4742
4743 outline1( "LD HL, (%s)", _value )
4744 outline0( "JP (HL)" );
4745
4746}
4747
4748int cpu_register_decode( Environment * _environment, char * _register ) {
4749
4750 Z80Register result = REGISTER_NONE;
4751
4752 if ( !_environment->emptyProcedure ) {
4753
4754 if ( strcmp( _register, "A" ) == 0 ) {
4755 result = REGISTER_A;
4756 } else if ( strcmp( _register, "B" ) == 0 ) {
4757 result = REGISTER_B;
4758 } else if ( strcmp( _register, "C" ) == 0 ) {
4759 result = REGISTER_C;
4760 } else if ( strcmp( _register, "D" ) == 0 ) {
4761 result = REGISTER_D;
4762 } else if ( strcmp( _register, "E" ) == 0 ) {
4763 result = REGISTER_E;
4764 } else if ( strcmp( _register, "H" ) == 0 ) {
4765 result = REGISTER_H;
4766 } else if ( strcmp( _register, "L" ) == 0 ) {
4767 result = REGISTER_L;
4768 } else if ( strcmp( _register, "F" ) == 0 ) {
4769 if ( !_environment->emptyProcedure ) {
4771 }
4772 // result = REGISTER_F;
4773 } else if ( strcmp( _register, "I" ) == 0 ) {
4774 if ( !_environment->emptyProcedure ) {
4776 }
4777 // result = REGISTER_I;
4778 } else if ( strcmp( _register, "R" ) == 0 ) {
4779 if ( !_environment->emptyProcedure ) {
4781 }
4782 // result = REGISTER_R;
4783 } else if ( strcmp( _register, "SP" ) == 0 ) {
4784 if ( !_environment->emptyProcedure ) {
4786 }
4787 // result = REGISTER_SP;
4788 } else if ( strcmp( _register, "PC" ) == 0 ) {
4789 if ( !_environment->emptyProcedure ) {
4791 }
4792 // result = REGISTER_PC;
4793 } else if ( strcmp( _register, "IX" ) == 0 ) {
4794 result = REGISTER_IX;
4795 } else if ( strcmp( _register, "IY" ) == 0 ) {
4796 result = REGISTER_IY;
4797 } else if ( strcmp( _register, "AF" ) == 0 ) {
4798 if ( !_environment->emptyProcedure ) {
4800 }
4801 // result = REGISTER_AF;
4802 } else if ( strcmp( _register, "BC" ) == 0 ) {
4803 result = REGISTER_BC;
4804 } else if ( strcmp( _register, "DE" ) == 0 ) {
4805 result = REGISTER_DE;
4806 } else if ( strcmp( _register, "HL" ) == 0 ) {
4807 result = REGISTER_HL;
4808 } else if ( strcmp( _register, "IXL" ) == 0 ) {
4809 result = REGISTER_IXL;
4810 } else if ( strcmp( _register, "IXH" ) == 0 ) {
4811 result = REGISTER_IXH;
4812 } else if ( strcmp( _register, "IYL" ) == 0 ) {
4813 result = REGISTER_IYL;
4814 } else if ( strcmp( _register, "IYH" ) == 0 ) {
4815 result = REGISTER_IYH;
4816 } else if ( strcmp( _register, "CARRY" ) == 0 ) {
4817 result = REGISTER_CARRY;
4818 } else if ( strcmp( _register, "ZERO" ) == 0 ) {
4819 result = REGISTER_ZERO;
4820 } else if ( strcmp( _register, "HLA" ) == 0 ) {
4821 result = REGISTER_HLA;
4822 } else {
4823
4824 }
4825
4826 }
4827
4828 return (int)result;
4829
4830}
4831
4832void cpu_set_asmio( Environment * _environment, int _asmio, int _value ) {
4833
4834 if ( IS_REGISTER( _asmio ) ) {
4835
4837
4838 Z80Register reg = (Z80Register) _asmio;
4839
4840 switch ( reg ) {
4841 case REGISTER_NONE:
4843 break;
4844 case REGISTER_F:
4845 case REGISTER_I:
4846 case REGISTER_R:
4847 case REGISTER_SP:
4848 case REGISTER_PC:
4849 case REGISTER_AF:
4850 break;
4851 case REGISTER_A:
4852 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4853 break;
4854 case REGISTER_B:
4855 outline0( "PUSH AF" );
4856 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4857 outline0( "LD B, A" );
4858 outline0( "POP AF" );
4859 break;
4860 case REGISTER_C:
4861 outline0( "PUSH AF" );
4862 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4863 outline0( "LD C, A" );
4864 outline0( "POP AF" );
4865 break;
4866 case REGISTER_D:
4867 outline0( "PUSH AF" );
4868 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4869 outline0( "LD D, A" );
4870 outline0( "POP AF" );
4871 break;
4872 case REGISTER_E:
4873 outline0( "PUSH AF" );
4874 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4875 outline0( "LD E, A" );
4876 outline0( "POP AF" );
4877 break;
4878 case REGISTER_H:
4879 outline0( "PUSH AF" );
4880 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4881 outline0( "LD H, A" );
4882 outline0( "POP AF" );
4883 break;
4884 case REGISTER_L:
4885 outline0( "PUSH AF" );
4886 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4887 outline0( "LD L, A" );
4888 outline0( "POP AF" );
4889 break;
4890 case REGISTER_IX:
4891 outline1( "LD IX, $%4.4x", (unsigned short)(_value & 0xffff) );
4892 break;
4893 case REGISTER_IY:
4894 outline1( "LD IY, $%4.4x", (unsigned short)(_value & 0xffff) );
4895 break;
4896 case REGISTER_BC:
4897 outline0( "PUSH HL" );
4898 outline1( "LD HL, $%4.4x", (unsigned short)(_value & 0xffff) );
4899 outline0( "LD BC, HL" );
4900 outline0( "POP HL" );
4901 break;
4902 case REGISTER_DE:
4903 outline0( "PUSH HL" );
4904 outline1( "LD HL, $%4.4x", (unsigned short)(_value & 0xffff) );
4905 outline0( "LD DE, HL" );
4906 outline0( "POP HL" );
4907 break;
4908 case REGISTER_HL:
4909 outline1( "LD HL, $%4.4x", (unsigned short)(_value & 0xffff) );
4910 break;
4911 case REGISTER_IXL:
4912 outline0( "PUSH AF" );
4913 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4914 outline0( "LD IXL, A" );
4915 outline0( "POP AF" );
4916 break;
4917 case REGISTER_IXH:
4918 outline0( "PUSH AF" );
4919 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4920 outline0( "LD IXH, A" );
4921 outline0( "POP AF" );
4922 break;
4923 case REGISTER_IYL:
4924 outline0( "PUSH AF" );
4925 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4926 outline0( "LD IYL, A" );
4927 outline0( "POP AF" );
4928 break;
4929 case REGISTER_IYH:
4930 outline0( "PUSH AF" );
4931 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4932 outline0( "LD IYH, A" );
4933 outline0( "POP AF" );
4934 break;
4935 case REGISTER_CARRY:
4936 outline0( "PUSH AF" );
4937 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4938 outline0( "CP 0" );
4939 outline1( "JR Z, %snoc", label );
4940 outline0( "LD A, $1" );
4941 outline0( "SRL A" );
4942 outline1( "JP %sdone", label );
4943 outhead1( "%snoc:", label );
4944 outline0( "SRL A" );
4945 outhead1( "%sdone:", label );
4946 outline0( "POP AF" );
4947 break;
4948 case REGISTER_ZERO:
4949 outline0( "PUSH AF" );
4950 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4951 outline0( "CP 0" );
4952 outline0( "POP AF" );
4953 break;
4954 case REGISTER_HLA:
4955 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4956 outline1( "LD HL, $%4.4x", (unsigned char)((_value >> 8 ) & 0xffff ) );
4957 break;
4958 }
4959
4960 } else {
4961
4962 Z80Stack stk = (Z80Stack) _asmio;
4963
4964 switch ( stk ) {
4965 case STACK_NONE:
4966 break;
4967 case STACK_BYTE:
4968 outline1( "LD A, $%2.2x", (unsigned char)(_value & 0xff ) );
4969 outline0( "PUSH A" );
4970 break;
4971 case STACK_WORD:
4972 outline1( "LD HL, $%4.4x", (unsigned short)(_value & 0xffff) );
4973 outline0( "PUSH HL" );
4974 break;
4975 case STACK_DWORD:
4976 outline1( "LD HL, $%4.4x", (unsigned short)(_value & 0xffff) );
4977 outline0( "PUSH HL" );
4978 outline1( "LD HL, $%4.4x", (unsigned short)((_value>>16) & 0xffff) );
4979 outline0( "PUSH HL" );
4980 break;
4981 }
4982
4983 }
4984
4985}
4986
4987void cpu_set_asmio_indirect( Environment * _environment, int _asmio, char * _value ) {
4988
4989 if ( IS_REGISTER( _asmio ) ) {
4990
4992
4993 Z80Register reg = (Z80Register) _asmio;
4994
4995 switch ( reg ) {
4996 case REGISTER_NONE:
4998 break;
4999 case REGISTER_F:
5000 case REGISTER_I:
5001 case REGISTER_R:
5002 case REGISTER_SP:
5003 case REGISTER_PC:
5004 case REGISTER_AF:
5005 break;
5006 case REGISTER_A:
5007 outline1( "LD A, (%s)", _value );
5008 break;
5009 case REGISTER_B:
5010 outline0( "PUSH AF" );
5011 outline1( "LD A, (%s)", _value );
5012 outline0( "LD B, A" );
5013 outline0( "POP AF" );
5014 break;
5015 case REGISTER_C:
5016 outline0( "PUSH AF" );
5017 outline1( "LD A, (%s)", _value );
5018 outline0( "LD C, A" );
5019 outline0( "POP AF" );
5020 break;
5021 case REGISTER_D:
5022 outline0( "PUSH AF" );
5023 outline1( "LD A, (%s)", _value );
5024 outline0( "LD D, A" );
5025 outline0( "POP AF" );
5026 break;
5027 case REGISTER_E:
5028 outline0( "PUSH AF" );
5029 outline1( "LD A, (%s)", _value );
5030 outline0( "LD E, A" );
5031 outline0( "POP AF" );
5032 break;
5033 case REGISTER_H:
5034 outline0( "PUSH AF" );
5035 outline1( "LD A, (%s)", _value );
5036 outline0( "LD H, A" );
5037 outline0( "POP AF" );
5038 break;
5039 case REGISTER_L:
5040 outline0( "PUSH AF" );
5041 outline1( "LD A, (%s)", _value );
5042 outline0( "LD L, A" );
5043 outline0( "POP AF" );
5044 break;
5045 case REGISTER_IX:
5046 outline1( "LD IX, (%s)", _value );
5047 break;
5048 case REGISTER_IY:
5049 outline1( "LD IY, (%s)", _value );
5050 break;
5051 case REGISTER_BC:
5052 outline0( "PUSH HL" );
5053 outline1( "LD HL, (%s)", _value );
5054 outline0( "LD BC, HL" );
5055 outline0( "POP HL" );
5056 break;
5057 case REGISTER_DE:
5058 outline0( "PUSH HL" );
5059 outline1( "LD HL, (%s)", _value );
5060 outline0( "LD DE, HL" );
5061 outline0( "POP HL" );
5062 break;
5063 case REGISTER_HL:
5064 outline1( "LD HL, (%s)", _value );
5065 break;
5066 case REGISTER_IXL:
5067 outline0( "PUSH AF" );
5068 outline1( "LD A, (%s)", _value );
5069 outline0( "LD IXL, A" );
5070 outline0( "POP AF" );
5071 break;
5072 case REGISTER_IXH:
5073 outline0( "PUSH AF" );
5074 outline1( "LD A, (%s)", _value );
5075 outline0( "LD IXH, A" );
5076 outline0( "POP AF" );
5077 break;
5078 case REGISTER_IYL:
5079 outline0( "PUSH AF" );
5080 outline1( "LD A, (%s)", _value );
5081 outline0( "LD IYL, A" );
5082 outline0( "POP AF" );
5083 break;
5084 case REGISTER_IYH:
5085 outline0( "PUSH AF" );
5086 outline1( "LD A, (%s)", _value );
5087 outline0( "LD IYH, A" );
5088 outline0( "POP AF" );
5089 break;
5090 case REGISTER_CARRY:
5091 outline0( "PUSH AF" );
5092 outline1( "LD A, (%s)", _value );
5093 outline0( "CP 0" );
5094 outline1( "JR Z, %snoc", label );
5095 outline0( "LD A, $1" );
5096 outline0( "SRL A" );
5097 outline1( "JP %sdone", label );
5098 outhead1( "%snoc:", label );
5099 outline0( "SRL A" );
5100 outhead1( "%sdone:", label );
5101 outline0( "POP AF" );
5102 break;
5103 case REGISTER_ZERO:
5104 outline0( "PUSH AF" );
5105 outline1( "LD A, (%s)", _value );
5106 outline0( "CP 0" );
5107 outline0( "POP AF" );
5108 break;
5109 case REGISTER_HLA:
5110 outline1( "LD A, (%s)", address_displacement( _environment, _value, "2" ) );
5111 outline0( "LD H, A" );
5112 outline1( "LD A, (%s)", address_displacement( _environment, _value, "1" ) );
5113 outline0( "LD L, A" );
5114 outline1( "LD A, (%s)", _value );
5115 break;
5116 }
5117
5118 } else {
5119
5120 Z80Stack stk = (Z80Stack) _asmio;
5121
5122 switch ( stk ) {
5123 case STACK_NONE:
5124 break;
5125 case STACK_BYTE:
5126 outline1( "LD A, (%s)", _value );
5127 outline0( "PUSH A" );
5128 break;
5129 case STACK_WORD:
5130 outline1( "LD HL, (%s)", _value );
5131 outline0( "PUSH HL" );
5132 break;
5133 case STACK_DWORD:
5134 outline1( "LD HL, (%s)", address_displacement( _environment, _value, "0" ) );
5135 outline0( "PUSH HL" );
5136 outline1( "LD HL, (%s)", address_displacement( _environment, _value, "2" ) );
5137 outline0( "PUSH HL" );
5138 break;
5139 }
5140
5141 }
5142
5143}
5144
5145void cpu_get_asmio_indirect( Environment * _environment, int _asmio, char * _value ) {
5146
5147 if ( IS_REGISTER( _asmio ) ) {
5148
5150
5151 Z80Register reg = (Z80Register) _asmio;
5152
5153 switch ( reg ) {
5154 case REGISTER_NONE:
5156 break;
5157 case REGISTER_F:
5158 case REGISTER_I:
5159 case REGISTER_R:
5160 case REGISTER_SP:
5161 case REGISTER_PC:
5162 case REGISTER_AF:
5163 break;
5164 case REGISTER_A:
5165 outline1( "LD (%s), A", _value );
5166 break;
5167 case REGISTER_B:
5168 outline0( "PUSH AF" );
5169 outline0( "LD A, B" );
5170 outline1( "LD (%s), A", _value );
5171 outline0( "POP AF" );
5172 break;
5173 case REGISTER_C:
5174 outline0( "PUSH AF" );
5175 outline0( "LD A, C" );
5176 outline1( "LD (%s), A", _value );
5177 outline0( "POP AF" );
5178 break;
5179 case REGISTER_D:
5180 outline0( "PUSH AF" );
5181 outline0( "LD A, D" );
5182 outline1( "LD (%s), A", _value );
5183 outline0( "POP AF" );
5184 break;
5185 case REGISTER_E:
5186 outline0( "PUSH AF" );
5187 outline0( "LD A, E" );
5188 outline1( "LD (%s), A", _value );
5189 outline0( "POP AF" );
5190 break;
5191 case REGISTER_H:
5192 outline0( "PUSH AF" );
5193 outline0( "LD A, H" );
5194 outline1( "LD (%s), A", _value );
5195 outline0( "POP AF" );
5196 break;
5197 case REGISTER_L:
5198 outline0( "PUSH AF" );
5199 outline0( "LD A, L" );
5200 outline1( "LD (%s), A", _value );
5201 outline0( "POP AF" );
5202 break;
5203 case REGISTER_IX:
5204 outline1( "LD (%s), IX", _value );
5205 break;
5206 case REGISTER_IY:
5207 outline1( "LD (%s), IY", _value );
5208 break;
5209 case REGISTER_BC:
5210 outline0( "PUSH HL" );
5211 outline0( "LD HL, BC" );
5212 outline1( "LD (%s), HL", _value );
5213 outline0( "POP HL" );
5214 break;
5215 case REGISTER_DE:
5216 outline0( "PUSH HL" );
5217 outline0( "LD HL, DE" );
5218 outline1( "LD (%s), HL", _value );
5219 outline0( "POP HL" );
5220 break;
5221 case REGISTER_HL:
5222 outline1( "LD (%s), HL", _value );
5223 break;
5224 case REGISTER_IXL:
5225 outline0( "PUSH AF" );
5226 outline0( "LD A, IXL" );
5227 outline1( "LD (%s), A", _value );
5228 outline0( "POP AF" );
5229 break;
5230 case REGISTER_IXH:
5231 outline0( "PUSH AF" );
5232 outline0( "LD A, IXH" );
5233 outline1( "LD (%s), A", _value );
5234 outline0( "POP AF" );
5235 break;
5236 case REGISTER_IYL:
5237 outline0( "PUSH AF" );
5238 outline0( "LD A, IYL" );
5239 outline1( "LD (%s), A", _value );
5240 outline0( "POP AF" );
5241 break;
5242 case REGISTER_IYH:
5243 outline0( "PUSH AF" );
5244 outline0( "LD A, IYH" );
5245 outline1( "LD (%s), A", _value );
5246 outline0( "POP AF" );
5247 break;
5248 case REGISTER_CARRY:
5249 outline0( "PUSH AF" );
5250 outline1( "JR NC, %snoc", label );
5251 outline0( "LD A, $1" );
5252 outline1( "LD (%s), A", _value );
5253 outline1( "JP %sdone", label );
5254 outhead1( "%snoc:", label );
5255 outline0( "LD A, $0" );
5256 outline1( "LD (%s), A", _value );
5257 outhead1( "%sdone:", label );
5258 outline0( "POP AF" );
5259 break;
5260 case REGISTER_ZERO:
5261 outline0( "PUSH AF" );
5262 outline1( "JR NZ, %snoz", label );
5263 outline0( "LD A, $1" );
5264 outline1( "LD (%s), A", _value );
5265 outline1( "JP %sdone", label );
5266 outhead1( "%snoz:", label );
5267 outline0( "LD A, $0" );
5268 outline1( "LD (%s), A", _value );
5269 outhead1( "%sdone:", label );
5270 outline0( "POP AF" );
5271 break;
5272 case REGISTER_HLA:
5273 outline1( "LD (%s), A", _value );
5274 outline0( "LD A, L" );
5275 outline1( "LD (%s), A", address_displacement( _environment, _value, "1" ) );
5276 outline0( "LD A, H" );
5277 outline1( "LD (%s), A", address_displacement( _environment, _value, "2" ) );
5278 break;
5279 }
5280
5281 } else {
5282
5283 Z80Stack stk = (Z80Stack) _asmio;
5284
5285 switch ( stk ) {
5286 case STACK_NONE:
5287 break;
5288 case STACK_BYTE:
5289 outline0( "POP AF" );
5290 outline1( "LD (%s), A", _value );
5291 break;
5292 case STACK_WORD:
5293 outline0( "POP HL" );
5294 outline1( "LD (%s), HL", _value );
5295 break;
5296 case STACK_DWORD:
5297 outline0( "POP HL" );
5298 outline1( "LD (%s), HL", address_displacement( _environment, _value, "0" ) );
5299 outline0( "POP HL" );
5300 outline1( "LD (%s), HL", address_displacement( _environment, _value, "2" ) );
5301 break;
5302 }
5303
5304 }
5305
5306}
5307
5308void cpu_return( Environment * _environment ) {
5309
5310 outline0("RET" );
5311
5312}
5313
5314void cpu_pop( Environment * _environment ) {
5315
5316 outline0("POP IX" );
5317
5318}
5319
5320void cpu_halt( Environment * _environment ) {
5321
5323
5324 outhead1("%s:", label );
5325 outline1("jp %s", label );
5326
5327}
5328
5329void cpu_end( Environment * _environment ) {
5330
5331 outline0("DI");
5332 outline0("HLT");
5333
5334}
5335
5336void cpu_random( Environment * _environment, char * _entropy ) {
5337
5339
5340 inline( cpu_random )
5341
5342 if ( _entropy ) {
5343 outline0("LD HL, (CPURANDOM_SEED)");
5344 outline0("LD B, (HL)");
5345 outline0("INC HL");
5346 outline0("LD A, (HL)");
5347 outline0("XOR B");
5348 outline1("LD DE, (%s)", _entropy);
5349 // outline0("LD B, H");
5350 outline0("LD C, L");
5351 outline0("ADD HL, HL");
5352 outline0("RL E");
5353 outline0("RL D");
5354 outline0("ADD HL, DE");
5355 outline0("RL E");
5356 outline0("RL D");
5357 outline0("INC L");
5358 outline0("ADD HL, BC");
5359 outline0("LD (CPURANDOM_SEED), HL");
5360 outline0("LD HL, (CPURANDOM_SEED+2)");
5361 outline0("ADD HL, DE");
5362 outline0("LD (CPURANDOM_SEED+1), HL");
5363 outline0("EX DE, HL");
5364 outline0("LD HL, (CPURANDOM_SEED)");
5365 outline1("LD DE, (%s)", _entropy);
5366 outline0("ADD HL, HL");
5367 outline0("RL C");
5368 outline0("RL B");
5369 outline0("LD (CPURANDOM_SEED+1), BC");
5370 outline0("SBC A, A");
5371 outline0("AND %11000101");
5372 outline0("XOR L");
5373 outline0("LD L, A");
5374 outline0("LD (CPURANDOM_SEED+1), HL");
5375 outline0("EX DE, HL");
5376 outline0("ADD HL, BC");
5377 }
5378
5379 embedded( cpu_random, src_hw_z80_cpu_random_asm );
5380
5381 done()
5382
5383
5384}
5385
5386void cpu_random_8bit( Environment * _environment, char * _entropy, char * _result ) {
5387
5388 cpu_random( _environment, _entropy );
5389
5390 if ( _result ) {
5391 outline0("CALL CPURANDOM16" );
5392 outline0("LD A, H" );
5393 outline1("LD (%s), A", _result );
5394 }
5395
5396}
5397
5398void cpu_random_16bit( Environment * _environment, char * _entropy, char * _result ) {
5399
5400 cpu_random( _environment, _entropy );
5401
5402 if ( _result ) {
5403 outline0("CALL CPURANDOM16" );
5404 outline1("LD (%s), HL", _result );
5405 }
5406
5407}
5408
5409void cpu_random_32bit( Environment * _environment, char * _entropy, char * _result ) {
5410
5411 cpu_random( _environment, _entropy );
5412
5413 if ( _result ) {
5414 outline0("CALL CPURANDOM32" );
5415 outline1("LD (%s), HL", _result );
5416 outline1("LD (%s), BC", address_displacement( _environment, _result, "2" ) );
5417 }
5418
5419}
5420
5421void cpu_limit_16bit( Environment * _environment, char * _variable, int _value ) {
5422
5424
5425 outline1( "LD A, (%s)", _variable );
5426 outline1( "CP $%2.2x", _value );
5427 outline1( "JR C, %s", label );
5428 outline1( "SUB $%2.2x", _value );
5429 outline1( "LD (%s), A", _variable );
5430 outhead1( "%s:", label );
5431
5432}
5433
5434void cpu_busy_wait( Environment * _environment, char * _timing ) {
5435
5437
5438 outline1("LD A, (%s)", _timing );
5439 outhead1("%s:", label );
5440 outline0("DEC A");
5441 outline1("JR NZ, %s", label);
5442
5443}
5444
5452void cpu_port_out( Environment * _environment, char * _port, char * _value ) {
5453
5454 outline1("LD A, (%s)", _value );
5455 outline1("OUT (%s), A", _port );
5456
5457}
5458
5459void cpu_logical_and_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5460
5462
5463 outline1("LD A, (%s)", _left );
5464 outline0("CMP 0" );
5465 outline1("JR Z, %s", label );
5466 outline1("LD A, (%s)", _right );
5467 outline0("CMP 0" );
5468 outline1("JR Z, %s", label );
5469 outline0("LD A, $ff" );
5470 outline1("LD (%s), A", _result );
5471 outline1("JMP %s_2", label );
5472 outhead1("%s:", label );
5473 outline0("LD A, 0" );
5474 outline1("LD (%s), A", _result );
5475 outhead1("%s_2:", label );
5476
5477
5478}
5479
5480void cpu_and_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5481
5483
5484 outline1("LD HL, %s", _left );
5485 outline1("LD IX, %s", _right );
5486 outline1("LD DE, %s", _result );
5487 outline0("LD A, (HL)" );
5488 outline0("AND (IX)" );
5489 outline0("LD (DE), A" );
5490
5491}
5492
5493void cpu_and_8bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
5494
5496
5497 outline1("LD A, (%s)", _left );
5498 outline1("AND $%2.2x", _right );
5499 outline1("LD (%s), A", _result );
5500
5501}
5502
5503void cpu_and_16bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5504
5506
5507 outline1("LD HL, %s", _left );
5508 outline1("LD IX, %s", _right );
5509 outline1("LD DE, %s", _result );
5510 outline0("LD A, (HL)" );
5511 outline0("AND (IX)" );
5512 outline0("LD (DE), A" );
5513 outline0("INC HL" );
5514 outline0("INC DE" );
5515 outline0("LD A, (HL)" );
5516 outline0("AND (IX+1)" );
5517 outline0("LD (DE), A" );
5518
5519}
5520
5521void cpu_and_32bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5522
5524
5525 outline1("LD HL, %s", _left );
5526 outline1("LD IX, %s", _right );
5527 outline1("LD DE, %s", _result );
5528 outline0("LD A, (HL)" );
5529 outline0("AND (IX)" );
5530 outline0("LD (DE), A" );
5531 outline0("INC HL" );
5532 outline0("INC DE" );
5533 outline0("LD A, (HL)" );
5534 outline0("AND (IX+1)" );
5535 outline0("LD (DE), A" );
5536 outline0("INC HL" );
5537 outline0("INC DE" );
5538 outline0("LD A, (HL)" );
5539 outline0("AND (IX+2)" );
5540 outline0("LD (DE), A" );
5541 outline0("INC HL" );
5542 outline0("INC DE" );
5543 outline0("LD A, (HL)" );
5544 outline0("AND (IX+3)" );
5545 outline0("LD (DE), A" );
5546
5547}
5548
5549void cpu_logical_or_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5550
5552
5553 outline1("LD A, (%s)", _left );
5554 outline1("JR NZ, %sd1", label );
5555 outline1("LD A, (%s)", _right );
5556 outline1("JR NZ, %sd1", label );
5557 outhead1("%s0:", label );
5558 outline0("LD A, 0" );
5559 outline1("LD (%s), A", _result );
5560 outline1("JMP %sx", label );
5561 outhead1("%sd1:", label );
5562 outline0("LD A, $ff" );
5563 outline1("LD (%s), A", _result );
5564 outhead1("%sx:", label );
5565
5566}
5567
5568void cpu_or_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5569
5571
5572 outline1("LD HL, %s", _left );
5573 outline1("LD IX, %s", _right );
5574 outline1("LD DE, %s", _result );
5575 outline0("LD A, (HL)" );
5576 outline0("OR (IX)" );
5577 outline0("LD (DE), A" );
5578
5579}
5580
5581void cpu_or_8bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
5582
5584
5585 outline1("LD A, (%s)", _left );
5586 outline1("OR $%2.2x", _right );
5587 outline1("LD (%s), A", _result );
5588
5589}
5590
5591
5592void cpu_or_16bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5593
5595
5596 outline1("LD HL, %s", _left );
5597 outline1("LD IX, %s", _right );
5598 outline1("LD DE, %s", _result );
5599 outline0("LD A, (HL)" );
5600 outline0("OR (IX)" );
5601 outline0("LD (DE), A" );
5602 outline0("INC HL" );
5603 outline0("INC DE" );
5604 outline0("LD A, (HL)" );
5605 outline0("OR (IX+1)" );
5606 outline0("LD (DE), A" );
5607 outline0("INC HL" );
5608 outline0("INC DE" );
5609
5610}
5611
5612void cpu_or_32bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5613
5615
5616 outline1("LD HL, %s", _left );
5617 outline1("LD IX, %s", _right );
5618 outline1("LD DE, %s", _result );
5619 outline0("LD A, (HL)" );
5620 outline0("OR (IX)" );
5621 outline0("LD (DE), A" );
5622 outline0("INC HL" );
5623 outline0("INC DE" );
5624 outline0("LD A, (HL)" );
5625 outline0("OR (IX+1)" );
5626 outline0("LD (DE), A" );
5627 outline0("INC HL" );
5628 outline0("INC DE" );
5629 outline0("LD A, (HL)" );
5630 outline0("OR (IX+2)" );
5631 outline0("LD (DE), A" );
5632 outline0("INC HL" );
5633 outline0("INC DE" );
5634 outline0("LD A, (HL)" );
5635 outline0("OR (IX+3)" );
5636 outline0("LD (DE), A" );
5637
5638}
5639
5640void cpu_xor_8bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5641
5643
5644 outline1("LD HL, %s", _left );
5645 outline1("LD IX, %s", _right );
5646 outline1("LD DE, %s", _result );
5647 outline0("LD A, (HL)" );
5648 outline0("XOR (IX)" );
5649 outline0("LD (DE), A" );
5650
5651}
5652
5653void cpu_xor_8bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
5654
5656
5657 outline1("LD HL, %s", _left );
5658 outline1("LD DE, %s", _result );
5659 outline0("LD A, (HL)" );
5660 outline1("XOR $%2.2x", (unsigned char)(_right&0xff) );
5661 outline0("LD (DE), A" );
5662
5663}
5664
5665void cpu_xor_16bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5666
5668
5669 outline1("LD HL, %s", _left );
5670 outline1("LD IX, %s", _right );
5671 outline1("LD DE, %s", _result );
5672 outline0("LD A, (HL)" );
5673 outline0("XOR (IX)" );
5674 outline0("LD (DE), A" );
5675 outline0("INC HL" );
5676 outline0("INC DE" );
5677 outline0("LD A, (HL)" );
5678 outline0("XOR (IX+1)" );
5679 outline0("LD (DE), A" );
5680 outline0("INC HL" );
5681 outline0("INC DE" );
5682
5683}
5684
5685void cpu_xor_16bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
5686
5688
5689 outline1("LD HL, %s", _left );
5690 outline1("LD DE, %s", _result );
5691 outline0("LD A, (HL)" );
5692 outline1("XOR $%2.2x", (unsigned char)((_right) & 0xff) );
5693 outline0("LD (DE), A" );
5694 outline0("INC HL" );
5695 outline0("INC DE" );
5696 outline0("LD A, (HL)" );
5697 outline1("XOR $%2.2x", (unsigned char)((_right>>8) & 0xff) );
5698 outline0("LD (DE), A" );
5699 outline0("INC HL" );
5700 outline0("INC DE" );
5701
5702}
5703
5704
5705void cpu_xor_32bit( Environment * _environment, char * _left, char * _right, char * _result ) {
5706
5708
5709 outline1("LD HL, %s", _left );
5710 outline1("LD IX, %s", _right );
5711 outline1("LD DE, %s", _result );
5712 outline0("LD A, (HL)" );
5713 outline0("XOR (IX)" );
5714 outline0("LD (DE), A" );
5715 outline0("INC HL" );
5716 outline0("INC DE" );
5717 outline0("LD A, (HL)" );
5718 outline0("XOR (IX+1)" );
5719 outline0("LD (DE), A" );
5720 outline0("INC HL" );
5721 outline0("INC DE" );
5722 outline0("LD A, (HL)" );
5723 outline0("XOR (IX+2)" );
5724 outline0("LD (DE), A" );
5725 outline0("INC HL" );
5726 outline0("INC DE" );
5727 outline0("LD A, (HL)" );
5728 outline0("XOR (IX+3)" );
5729 outline0("LD (DE), A" );
5730
5731}
5732
5733void cpu_xor_32bit_const( Environment * _environment, char * _left, int _right, char * _result ) {
5734
5736
5737 outline1("LD HL, %s", _left );
5738 outline1("LD DE, %s", _result );
5739 outline0("LD A, (HL)" );
5740 outline1("XOR $%2.2x", (unsigned char)(_right & 0xff ) );
5741 outline0("LD (DE), A" );
5742 outline0("INC HL" );
5743 outline0("INC DE" );
5744 outline0("LD A, (HL)" );
5745 outline1("XOR $%2.2x", (unsigned char)((_right>>8) & 0xff ) );
5746 outline0("LD (DE), A" );
5747 outline0("INC HL" );
5748 outline0("INC DE" );
5749 outline0("LD A, (HL)" );
5750 outline1("XOR $%2.2x", (unsigned char)((_right>>16) & 0xff ) );
5751 outline0("LD (DE), A" );
5752 outline0("INC HL" );
5753 outline0("INC DE" );
5754 outline0("LD A, (HL)" );
5755 outline1("XOR $%2.2x", (unsigned char)((_right>>24) & 0xff ) );
5756 outline0("LD (DE), A" );
5757
5758}
5759
5760void cpu_swap_8bit( Environment * _environment, char * _left, char * _right ) {
5761
5763
5764 embedded( cpu_swap_8bit, src_hw_z80_cpu_swap_asm ) // it is not an error: swap 8/16/32 shares code
5765
5766 outline1("LD HL, %s", _right );
5767 outline1("LD DE, %s", _left );
5768 outline0("LD B, 1" );
5769 outline0("CALL CPUSWAP" );
5770
5771 done( )
5772
5773}
5774
5775void cpu_swap_16bit( Environment * _environment, char * _left, char * _right ) {
5776
5778
5779 embedded( cpu_swap_8bit, src_hw_z80_cpu_swap_asm ) // it is not an error: swap 8/16/32 shares code
5780
5781 outline1("LD HL, %s", _right );
5782 outline1("LD DE, %s", _left );
5783 outline0("LD B, 2" );
5784 outline0("CALL CPUSWAP" );
5785
5786 done( )
5787
5788}
5789
5790void cpu_swap_32bit( Environment * _environment, char * _left, char * _right ) {
5791
5793
5794 embedded( cpu_swap_8bit, src_hw_z80_cpu_swap_asm ) // it is not an error: swap 8/16/32 shares code
5795
5796 outline1("LD HL, %s", _right );
5797 outline1("LD DE, %s", _left );
5798 outline0("LD B, 4" );
5799 outline0("CALL CPUSWAP" );
5800
5801 done( )
5802
5803}
5804
5805void cpu_logical_not_8bit( Environment * _environment, char * _value, char * _result ) {
5806
5807 outline1("LD A, (%s)", _value );
5808 outline0("XOR $FF" );
5809 outline1("LD (%s), A", _result );
5810
5811}
5812
5813void cpu_not_8bit( Environment * _environment, char * _value, char * _result ) {
5814
5815 outline1("LD A, (%s)", _value );
5816 outline0("XOR $FF" );
5817 outline1("LD (%s), A", _result );
5818
5819}
5820
5821void cpu_not_16bit( Environment * _environment, char * _value, char * _result ) {
5822
5823 outline1("LD HL, %s", _value );
5824 outline1("LD DE, %s", _result );
5825 outline0("LD A, (HL)" );
5826 outline0("XOR $FF" );
5827 outline0("LD (DE), A" );
5828 outline0("INC HL" );
5829 outline0("INC DE" );
5830 outline0("LD A, (HL)" );
5831 outline0("XOR $FF" );
5832 outline0("LD (DE), A" );
5833
5834}
5835
5836void cpu_not_32bit( Environment * _environment, char * _value, char * _result ) {
5837
5838 outline1("LD HL, %s", _value );
5839 outline1("LD DE, %s", _result );
5840 outline0("LD A, (HL)" );
5841 outline0("XOR $FF" );
5842 outline0("LD (DE), A" );
5843 outline0("INC HL" );
5844 outline0("INC DE" );
5845 outline0("LD A, (HL)" );
5846 outline0("XOR $FF" );
5847 outline0("LD (DE), A" );
5848 outline0("INC HL" );
5849 outline0("INC DE" );
5850 outline0("LD A, (HL)" );
5851 outline0("XOR $FF" );
5852 outline0("LD (DE), A" );
5853 outline0("INC HL" );
5854 outline0("INC DE" );
5855 outline0("LD A, (HL)" );
5856 outline0("XOR $FF" );
5857 outline0("LD (DE), A" );
5858
5859}
5860
5861void cpu_di( Environment * _environment ) {
5862
5863 outline0("DI" );
5864
5865}
5866
5867void cpu_ei( Environment * _environment ) {
5868
5869 outline0("EI" );
5870
5871}
5872
5873void cpu_inc( Environment * _environment, char * _variable ) {
5874
5875 outline1("LD A, (%s)", _variable );
5876 outline0("INC A" );
5877 outline1("LD (%s), A", _variable );
5878
5879}
5880
5881void cpu_dec( Environment * _environment, char * _variable ) {
5882
5883 outline1("LD A, (%s)", _variable );
5884 outline0("DEC A" );
5885 outline1("LD (%s), A", _variable );
5886
5887}
5888
5889void cpu_inc_16bit( Environment * _environment, char * _variable ) {
5890
5891 outline1("LD HL, (%s)", _variable );
5892 outline0("INC HL" );
5893 outline1("LD (%s), HL", _variable );
5894
5895}
5896
5897void cpu_inc_32bit( Environment * _environment, char * _variable ) {
5898
5900
5901 outline1("LD HL, (%s)", _variable );
5902 outline0("INC HL" );
5903 outline1("LD (%s), HL", _variable );
5904 outline0("LD A, L" );
5905 outline0("CMP 0" );
5906 outline1("JR NZ, %s", label );
5907 outline0("LD A, h" );
5908 outline0("CMP 0" );
5909 outline1("JR NZ, %s", label );
5910 outline1("LD HL, (%s)", address_displacement(_environment, _variable, "2") );
5911 outline0("INC HL" );
5912 outline1("LD (%s), HL", address_displacement( _environment, _variable, "2" ) );
5913 outhead1("%s:", label );
5914
5915}
5916
5917void cpu_inc_nbit( Environment * _environment, char * _variable, int _bits ) {
5918
5920
5921 inline( cpu_inc_nbit )
5922
5923 for( int i=0; i<(_bits>>3);++i ) {
5924 char offset[MAX_TEMPORARY_STORAGE]; sprintf(offset, "%d", i );
5925 outline1("LD A, (%s)", address_displacement(_environment, _variable, offset ) );
5926 outline0("INC A");
5927 outline1("LD (%s), A", address_displacement(_environment, _variable, offset ) );
5928 outline1("JP NZ, %s", label );
5929 }
5930 outhead1("%s:", label );
5931
5933
5934}
5935
5936void cpu_dec_16bit( Environment * _environment, char * _variable ) {
5937
5938 outline1("LD HL, (%s)", _variable );
5939 outline0("DEC HL" );
5940 outline1("LD (%s), HL", _variable );
5941
5942}
5943
5944void cpu_dec_32bit( Environment * _environment, char * _variable ) {
5945
5947
5948 outline1("LD HL, (%s)", _variable );
5949 outline0("DEC HL" );
5950 outline1("LD (%s), HL", _variable );
5951 outline0("LD A, L" );
5952 outline0("AND H" );
5953 outline0("CP $FF" );
5954 outline1("JR NZ, %s", label );
5955 outline1("LD HL, (%s)", _variable );
5956 outline0("DEC HL" );
5957 outline1("LD (%s), HL", _variable );
5958 outhead1("%s:", label );
5959
5960}
5961
5962void cpu_dec_nbit( Environment * _environment, char * _variable, int _bits ) {
5963
5965
5966 inline( cpu_dec_32bit )
5967
5968 for( int i=0; i<(_bits>>3); ++i ) {
5969 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
5970 outline1("LD A, (%s)", address_displacement(_environment, _variable, offset) );
5971 outline0("DEC A" );
5972 outline1("LD (%s), A", address_displacement(_environment, _variable, offset) );
5973 outline0("CP $FF" );
5974 outline1("JP NZ, %s", label );
5975 }
5976 outhead1("%s:", label );
5977
5979
5980}
5981
5982void cpu_mem_move( Environment * _environment, char *_source, char *_destination, char *_size ) {
5983
5984 deploy( duff, src_hw_z80_duff_asm );
5985
5986 outline1("LD HL, (%s)", _source);
5987 outline1("LD DE, (%s)", _destination);
5988 outline1("LD A, (%s)", _size);
5989 outline0("LD C, A");
5990 outline0("LD B, 0");
5991 outline0("CALL DUFFDEVICE");
5992
5993}
5994
5995void cpu_mem_move_16bit( Environment * _environment, char *_source, char *_destination, char *_size ) {
5996
5997 deploy( duff, src_hw_z80_duff_asm );
5998
5999 outline1("LD HL, (%s)", _source);
6000 outline1("LD DE, (%s)", _destination);
6001 outline1("LD BC, (%s)", _size);
6002 outline0("CALL DUFFDEVICE");
6003
6004}
6005
6006void cpu_mem_move_direct( Environment * _environment, char *_source, char *_destination, char *_size ) {
6007
6008 deploy( duff, src_hw_z80_duff_asm );
6009
6010 outline1("LD HL, %s", _source);
6011 outline1("LD DE, %s", _destination);
6012 outline1("LD A, (%s)", _size);
6013 outline0("LD C, A");
6014 outline0("LD B, 0");
6015 outline0("CALL DUFFDEVICE");
6016
6017}
6018
6019void cpu_mem_move_direct2( Environment * _environment, char *_source, char *_destination, char *_size ) {
6020
6021 deploy( duff, src_hw_z80_duff_asm );
6022
6023 outline1("LD HL, (%s)", _source);
6024 outline1("LD DE, %s", _destination);
6025 outline1("LD BC, (%s)", _size);
6026 outline0("CALL DUFFDEVICE");
6027
6028}
6029
6030void cpu_mem_move_direct2_size( Environment * _environment, char *_source, char *_destination, int _size ) {
6031
6032 deploy( duff, src_hw_z80_duff_asm );
6033
6034 outline1("LD HL, (%s)", _source);
6035 outline1("LD DE, %s", _destination);
6036 outline1("LD BC, $%4.4x", _size);
6037 outline0("CALL DUFFDEVICE");
6038
6039}
6040
6041void cpu_mem_move_size( Environment * _environment, char *_source, char *_destination, int _size ) {
6042
6043 if ( _size > 0 ) {
6044
6045 deploy( duff, src_hw_z80_duff_asm );
6046
6047 outline1("LD HL, (%s)", _source);
6048 outline1("LD DE, (%s)", _destination);
6049 outline1("LD A, $%2.2x", (unsigned char)( _size & 0xff ) );
6050 outline0("LD C, A");
6051 outline1("LD B, $%2.2x", (unsigned char)(( _size >> 8 ) & 0xff) );
6052 outline0("CALL DUFFDEVICE");
6053
6054 }
6055
6056}
6057
6058void cpu_mem_move_direct_size( Environment * _environment, char *_source, char *_destination, int _size ) {
6059
6060 if ( _size > 0 ) {
6061
6062 deploy( duff, src_hw_z80_duff_asm );
6063
6064 outline1("LD HL, %s", _source);
6065 outline1("LD DE, %s", _destination);
6066 outline1("LD A, $%2.2x", (unsigned char)( _size & 0xff ) );
6067 outline0("LD C, A");
6068 outline1("LD B, $%2.2x", (unsigned char)(( _size >> 8 ) & 0xff) );
6069 outline0("CALL DUFFDEVICE");
6070 }
6071
6072}
6073
6074void cpu_mem_move_direct_indirect_size( Environment * _environment, char *_source, char *_destination, int _size ) {
6075
6076 if ( _size ) {
6077
6078 deploy( duff, src_hw_z80_duff_asm );
6079
6080 outline1("LD HL, %s", _source);
6081 outline1("LD DE, (%s)", _destination);
6082 outline1("LD A, $%2.2x", (unsigned char)( _size & 0xff ) );
6083 outline0("LD C, A");
6084 outline1("LD B, $%2.2x", (unsigned char)(( _size >> 8 ) & 0xff) );
6085 outline0("CALL DUFFDEVICE");
6086 }
6087
6088}
6089
6090void cpu_mem_move_indirect_direct_size( Environment * _environment, char *_source, char *_destination, int _size ) {
6091
6092 if ( _size ) {
6093
6094 deploy( duff, src_hw_z80_duff_asm );
6095
6096 outline1("LD HL, (%s)", _source);
6097 outline1("LD DE, %s", _destination);
6098 outline1("LD A, $%2.2x", (unsigned char)( _size & 0xff ) );
6099 outline0("LD C, A");
6100 outline1("LD B, $%2.2x", (unsigned char)(( _size >> 8 ) & 0xff) );
6101 outline0("CALL DUFFDEVICE");
6102 }
6103
6104}
6105
6106void cpu_compare_memory( Environment * _environment, char *_source, char *_destination, char *_size, char * _result, int _equal ) {
6107
6109
6110 outline1("LD A, (%s)", _size);
6111 outline0("CP 0");
6112 outline1("JR Z, %sequal", label);
6113 outline0("LD C, A");
6114 outline1("LD HL, (%s)", _source);
6115 outline1("LD DE, (%s)", _destination);
6116 outhead1("%s:", label );
6117 outline0("LD A, (HL)");
6118 outline0("LD B, A");
6119 outline0("LD A, (DE)");
6120 outline0("CP B");
6121 outline1("JR NZ, %sdiff", label);
6122 outline0("INC DE");
6123 outline0("INC HL");
6124 outline0("DEC C");
6125 outline1("JR NZ, %s", label);
6126 outhead1("%sequal:", label );
6127 outline1("LD A, $%2.2x", _equal ? 255 : 0 );
6128 outline1("LD (%s), A", _result );
6129 outline1("JMP %sfinal", label );
6130 outhead1("%sdiff:", label );
6131 outline1("LD A, $%2.2x", _equal ? 0 : 255 );
6132 outline1("LD (%s), A", _result );
6133 outhead1("%sfinal:", label );
6134
6135}
6136
6137void cpu_compare_memory_size( Environment * _environment, char *_source, char *_destination, int _size, char * _result, int _equal ) {
6138
6140
6141 outline1("LD HL, (%s)", _source);
6142 outline1("LD DE, (%s)", _destination);
6143 outline1("LD A, $%2.2x", (unsigned char)( _size & 0xff ) );
6144 outline0("LD C, A");
6145 outhead1("%s:", label );
6146 outline0("LD A, (HL)");
6147 outline0("LD B, A");
6148 outline0("LD A, (DE)");
6149 outline0("CP B");
6150 outline1("JR NZ, %sdiff", label);
6151 outline0("INC DE");
6152 outline0("INC HL");
6153 outline0("DEC C");
6154 outline1("JR NZ, %s", label);
6155 outline1("LD A, $%2.2x", _equal ? 255 : 0 );
6156 outline1("LD (%s), A", _result );
6157 outline1("JMP %sfinal", label );
6158 outhead1("%sdiff:", label );
6159 outline1("LD A, $%2.2x", _equal ? 0 : 255 );
6160 outline1("LD (%s), A", _result );
6161 outhead1("%sfinal:", label );
6162
6163}
6164
6165void cpu_less_than_memory( Environment * _environment, char *_source, char *_destination, char *_size, char * _result, int _equal ) {
6166
6168
6169 outline1("LD HL, (%s)", _source);
6170 outline1("LD DE, (%s)", _destination);
6171 outline1("LD A, (%s)", _size);
6172 outline0("LD C, A");
6173 outhead1("%s:", label );
6174 outline0("LD A, (DE)");
6175 outline0("LD B, A");
6176 outline0("LD A, (HL)");
6177 outline0("CP B");
6178 if ( _equal ) {
6179 outline1("JR Z, %seq", label);
6180 }
6181 outline1("JR NC, %sdiff", label);
6182 if ( ! _equal ) {
6183 outline1("JR Z, %sdiff", label);
6184 }
6185 outhead1("%seq:", label );
6186 outline0("INC DE");
6187 outline0("INC HL");
6188 outline0("DEC C");
6189 outline1("JR NZ, %s", label);
6190 outline0("LD A, $ff" );
6191 outline1("LD (%s), A", _result );
6192 outline1("JMP %sfinal", label );
6193 outhead1("%sdiff:", label );
6194 outline0("LD A, 0" );
6195 outline1("LD (%s), A", _result );
6196 outhead1("%sfinal:", label );
6197
6198}
6199
6200void cpu_less_than_memory_size( Environment * _environment, char *_source, char *_destination, int _size, char * _result, int _equal ) {
6201
6203
6204 outline1("LD HL, (%s)", _source);
6205 outline1("LD DE, (%s)",_destination);
6206 outline1("LD A, $%2.2x", (unsigned char)( _size & 0xff ) );
6207 outline0("LD C, A");
6208 outhead1("%s:", label );
6209 outline0("LD A, (DE)");
6210 outline0("LD B, A");
6211 outline0("LD A, (HL)");
6212 outline0("CP B");
6213 if ( _equal ) {
6214 outline1("JR Z, %seq", label);
6215 }
6216 outline1("JR NC, %sdiff", label);
6217 if ( ! _equal ) {
6218 outline1("JR Z, %sdiff", label);
6219 }
6220 outhead1("%seq:", label );
6221 outline0("INC DE");
6222 outline0("INC HL");
6223 outline0("DEC C");
6224 outline1("JR NZ, %s", label);
6225 outline0("LD A, $ff" );
6226 outline1("LD (%s), A", _result );
6227 outline1("JMP %sfinal", label );
6228 outhead1("%sdiff:", label );
6229 outline0("LD A, 0" );
6230 outline1("LD (%s), A", _result );
6231 outhead1("%sfinal:", label );
6232
6233}
6234
6235void cpu_greater_than_memory( Environment * _environment, char *_source, char *_destination, char *_size, char * _result, int _equal ) {
6236
6238
6239 outline1("LD HL, (%s)", _source);
6240 outline1("LD DE, (%s)", _destination);
6241 outline1("LD A, (%s)", _size);
6242 outline0("LD C, A");
6243 outhead1("%s:", label );
6244 outline0("LD A, (DE)");
6245 outline0("LD B, A");
6246 outline0("LD A, (HL)");
6247 outline0("CP B");
6248 if ( !_equal ) {
6249 outline1("JR Z, %sdiff", label);
6250 }
6251 outline1("JR C, %sdiff", label);
6252 outline0("INC DE");
6253 outline0("INC HL");
6254 outline0("DEC C");
6255 outline1("JR NZ, %s", label);
6256 outline1("LD A, $%2.2x", 255 );
6257 outline1("LD (%s), A", _result );
6258 outline1("JMP %sfinal", label );
6259 outhead1("%sdiff:", label );
6260 outline1("LD A, $%2.2x", 0 );
6261 outline1("LD (%s), A", _result );
6262 outhead1("%sfinal:", label );
6263
6264}
6265
6266void cpu_greater_than_memory_size( Environment * _environment, char *_source, char *_destination, int _size, char * _result, int _equal ) {
6267
6269
6270 outline1("LD HL, (%s)", _source);
6271 outline1("LD DE, (%s)", _destination);
6272 outline1("LD A, $%2.2x", (unsigned char)( _size & 0xff ) );
6273 outline0("LD C, A");
6274 outhead1("%s:", label );
6275 outline0("LD A, (DE)");
6276 outline0("LD B, A");
6277 outline0("LD A, (HL)");
6278 outline0("CP B");
6279 if ( ! _equal ) {
6280 outline1("JR Z, %sdiff", label);
6281 }
6282 outline1("JR C, %sdiff", label);
6283 outline0("INC DE");
6284 outline0("INC HL");
6285 outline0("DEC C");
6286 outline1("JR NZ, %s", label);
6287 outline1("LD A, $%2.2x", 255 );
6288 outline1("LD (%s), A", _result );
6289 outline1("JMP %sfinal", label );
6290 outhead1("%sdiff:", label );
6291 outline1("LD A, $%2.2x", 0 );
6292 outline1("LD (%s), A", _result );
6293 outhead1("%sfinal:", label );
6294
6295}
6296
6297void cpu_math_add_16bit_with_8bit( Environment * _environment, char *_source, char *_destination, char *_other ) {
6298
6299 outline1("LD HL, (%s)", _source );
6300 outline0("LD DE, 0" );
6301 outline1("LD A, (%s)", _destination );
6302 outline0("LD E, A" );
6303 outline0("ADD HL, DE" );
6304 if ( _other ) {
6305 outline1("LD (%s), HL", _other );
6306 } else {
6307 outline1("LD (%s), HL", _destination );
6308 }
6309
6310}
6311
6312void cpu_uppercase( Environment * _environment, char *_source, char *_size, char *_result ) {
6313
6315
6316 outline1("LD A, (%s)", _size);
6317 outline0("LD C, A" );
6318 outline1("LD HL, (%s)", _source );
6319 if ( _result ) {
6320 outline1("LD DE, (%s)", _result );
6321 } else {
6322 outline1("LD DE, (%s)", _source );
6323 }
6324 outhead1("%supper:", label );
6325 outline0("LD A, (HL)" );
6326
6327 outline0("CP 97");
6328 outline1("JR C, %snext", label);
6329
6330 outline0("CP 122");
6331 outline1("JR NC, %snext", label);
6332
6333 outline0("SUB A, 32");
6334 outline0("LD (DE), A" );
6335 outline1("JP %sdone", label );
6336
6337 outhead1("%snext:", label );
6338 outline0("LD (DE), A" );
6339 outhead1("%sdone:", label );
6340 outline0("INC HL" );
6341 outline0("INC DE" );
6342 outline0("DEC C" );
6343 outline0("LD A, C" );
6344 outline0("CP 0" );
6345 outline1("JR NZ, %supper", label);
6346
6347}
6348
6349void cpu_lowercase( Environment * _environment, char *_source, char *_size, char *_result ) {
6350
6352
6353 outline1("LD A, (%s)", _size);
6354 outline0("LD C, A" );
6355 outline1("LD HL, (%s)", _source );
6356 if ( _result ) {
6357 outline1("LD DE, (%s)", _result );
6358 } else {
6359 outline1("LD DE, (%s)", _source );
6360 }
6361 outhead1("%slower:", label );
6362 outline0("LD A, (HL)" );
6363
6364 outline0("CP 65");
6365 outline1("JR C, %snext", label);
6366
6367 outline0("CP 91");
6368 outline1("JR NC, %snext", label);
6369
6370 outline0("ADC A, 31");
6371 outline0("LD (DE), A" );
6372 outline1("JP %sdone", label );
6373 outhead1("%snext:", label );
6374 outline0("LD (DE), A" );
6375 outhead1("%sdone:", label );
6376 outline0("INC HL" );
6377 outline0("INC DE" );
6378 outline0("DEC C" );
6379 outline0("LD A, C" );
6380 outline0("CP 0" );
6381 outline1("JR NZ, %slower", label);
6382
6383}
6384
6385void cpu_convert_string_into_8bit( Environment * _environment, char * _string, char * _len, char * _value ) {
6386
6387 Variable * temp = variable_temporary( _environment, VT_WORD, "(temp)" );
6388
6389 cpu_convert_string_into_16bit( _environment, _string, _len, temp->realName );
6390
6391 cpu_move_8bit( _environment, temp->realName, _value );
6392
6393}
6394
6395void cpu_convert_string_into_16bit( Environment * _environment, char * _string, char * _len, char * _value ) {
6396
6398
6399 outline1("LD A, (%s)", _len );
6400 outline0("LD IX, 0" );
6401 outline0("LD IXL, A" );
6402
6403 outline0("LD A, 0" );
6404 outline1("LD (%s), A", _value );
6405 outline1("LD (%s+1), A", _value );
6406
6407 outline1("LD HL, (%s)", _string );
6408
6409 outhead1("%srepeat:", label );
6410
6411 outline0("LD A, (HL)" );
6412 outline0("CP $40" );
6413 outline1("JR NC, %send", label);
6414 outline0("CP $30" );
6415 outline1("JR C, %send", label);
6416 outline0("SBC A, $30" );
6417
6418 outline0("PUSH AF" );
6419 outline1("LD A, (%s)", address_displacement(_environment, _value, "1") );
6420 outline0("LD B, A" );
6421 outline1("LD A, (%s)", _value );
6422 outline0("LD C, A" );
6423 outline0("POP AF" );
6424 outline0("LD E, A" );
6425 outline0("LD D, 0" );
6426 outline0("PUSH HL" );
6427 outline0("LD HL, 0" );
6428 outline0("ADC HL, DE" );
6429 outline0("ADC HL, BC" );
6430 outline1("LD (%s), HL", _value );
6431 outline0("POP HL" );
6432
6433
6434 // MULT x 10
6435
6436 outline0("INC HL" );
6437 outline0("DEC IX" );
6438 outline0("LD A, 0" );
6439 outline0("CP IXL" );
6440 outline1("JR Z,%send", label );
6441
6442 outline0("PUSH HL" );
6443
6444 outline1("LD DE, (%s)", _value );
6445 outline0("LD A, 10" );
6446 outline0("LD B, 8" );
6447 outline0("LD HL, 0" );
6448 outline0("ADD HL, HL" );
6449 outline0("RLCA" );
6450 outline0("JR NC,$+3" );
6451 outline0("ADD HL, DE" );
6452 outline0("DJNZ $-5" );
6453 outline1("LD (%s), HL", _value );
6454
6455 outline0("POP HL" );
6456
6457 outline1("JMP %srepeat", label );
6458
6459 outhead1("%send:", label );
6460
6461}
6462
6463void cpu_fill_indirect( Environment * _environment, char * _address, char * _size, char * _pattern, int _size_size ) {
6464
6466
6467 // Use the current bitmap address as starting address for filling routine.
6468 outline1("LD DE, (%s)", _address);
6469 outline1("LD HL, (%s)", _pattern);
6470
6471 // Fill the bitmap with the given pattern.
6472 if ( _size_size >= 16 ) {
6473 outline1("LD A, (%s)", _size);
6474 outline0("LD C, A" );
6475 outline1("LD A, (%s+1)", _size);
6476 outline0("LD B, A" );
6477 outhead1("%sx:", label);
6478 outline0("LD A, (HL)");
6479 outline0("LD (DE),A");
6480 outline0("INC DE");
6481 outline0("DEC BC");
6482 outline0("LD A, B");
6483 outline0("OR C");
6484 outline1("JR NZ,%sx", label);
6485 } else {
6486 outline1("LD A, (%s)", _size);
6487 outline0("LD C, A" );
6488 outhead1("%sx:", label);
6489 outline0("LD A, (HL)");
6490 outline0("LD (DE),A");
6491 outline0("INC DE");
6492 outline0("DEC C");
6493 outline1("JR NZ,%sx", label);
6494 }
6495
6496}
6497
6498void cpu_flip_8bit( Environment * _environment, char * _source, char * _destination ) {
6499
6501
6502 embedded( cpu_flip, src_hw_z80_cpu_flip_asm );
6503
6504 outline1("LD A, (%s)", _source);
6505 outline0("CALL CPUFLIP8");
6506 if ( _destination ) {
6507 outline1("LD (%s), A", _destination);
6508 } else {
6509 outline1("LD (%s), A", _source);
6510 }
6511
6512 done( )
6513
6514}
6515
6516void cpu_flip( Environment * _environment, char * _source, char * _size, char * _destination ) {
6517
6519
6520 embedded( cpu_flip, src_hw_z80_cpu_flip_asm );
6521
6522 outline1("LD HL, (%s)", _source);
6523 outline1("LD DE, (%s)", _destination);
6524 outline1("LD A, (%s)", _size);
6525 outline0("CALL CPUFLIP");
6526
6527 done( )
6528
6529}
6530
6531void cpu_move_8bit_indirect( Environment * _environment, char *_source, char * _value ) {
6532
6533 outline1("LD DE, (%s)", _value);
6534 outline1("LD A, (%s)", _source);
6535 outline0("LD (DE), A");
6536
6537}
6538
6539void cpu_move_8bit_with_offset2( Environment * _environment, char *_source, char * _value, char * _offset ) {
6540
6541 outline1("LD HL, %s", _value);
6542 outline1("LD A, (%s)", _offset );
6543 outline0("LD E, A" );
6544 outline0("LD D, 0" );
6545 outline0("ADD HL, DE" );
6546 outline1("LD A, (%s)", _source);
6547 outline0("LD (HL), A");
6548
6549}
6550
6551void cpu_move_8bit_indirect_with_offset( Environment * _environment, char *_source, char * _value, int _offset ) {
6552
6553 outline1("LD HL, (%s)", _value);
6554 outline1("LD DE, $%2.2x", ( _offset & 0xff ) );
6555 outline0("ADD HL, DE" );
6556 outline1("LD A, (%s)", _source);
6557 outline0("LD (HL), A");
6558
6559}
6560
6561void cpu_move_8bit_indirect2( Environment * _environment, char * _value, char *_source ) {
6562
6563 outline1("LD DE, (%s)", _value);
6564 outline0("LD A, (DE)");
6565 outline1("LD (%s), A", _source);
6566
6567}
6568
6569void cpu_move_8bit_indirect2_8bit( Environment * _environment, char * _value, char * _offset, char *_source ) {
6570
6571 outline1("LD HL, %s", _value);
6572 outline1("LD A, (%s)", _offset);
6573 outline0("LD E, A");
6574 outline0("LD D, 0");
6575 outline0("ADD HL, DE");
6576 outline0("LD A, (HL)");
6577 outline1("LD (%s), A", _source );
6578
6579}
6580
6581void cpu_move_8bit_indirect2_16bit( Environment * _environment, char * _value, char * _offset, char *_source ) {
6582
6583 outline1("LD HL, %s", _value);
6584 outline1("LD DE, (%s)", _offset);
6585 outline0("ADD HL, DE");
6586 outline0("LD A, (HL)");
6587 outline1("LD (%s), A", _source );
6588
6589}
6590
6591void cpu_move_16bit_indirect( Environment * _environment, char *_source, char * _value ) {
6592
6593 outline1("LD DE, (%s)", _value);
6594 outline1("LD HL, (%s)", _source);
6595 outline0("LD A, L");
6596 outline0("LD (DE), A");
6597 outline0("INC DE");
6598 outline0("LD A, H");
6599 outline0("LD (DE), A");
6600
6601}
6602
6603void cpu_move_16bit_indirect2( Environment * _environment, char * _value, char *_source ) {
6604
6605 outline1("LD DE, (%s)", _value);
6606 outline0("LD A, (DE)");
6607 outline1("LD (%s), A", _source);
6608 outline0("INC DE");
6609 outline0("LD A, (DE)");
6610 outline1("LD (%s), A", address_displacement(_environment, _source, "1"));
6611
6612}
6613
6614void cpu_move_16bit_indirect2_8bit( Environment * _environment, char * _value, char * _offset, char *_source ) {
6615
6616 outline1("LD HL, %s", _value);
6617 outline1("LD A, (%s)", _offset);
6618 outline0("LD E, A");
6619 outline0("LD A, 0");
6620 outline0("LD D, A");
6621 outline0("ADD HL, DE");
6622 outline0("ADD HL, DE");
6623 outline0("LD A, (HL)");
6624 outline1("LD (%s), A", _source );
6625 outline0("INC HL");
6626 outline0("LD A, (HL)");
6627 outline1("LD (%s), A", address_displacement(_environment, _source, "1") );
6628
6629}
6630
6631void cpu_move_32bit_indirect( Environment * _environment, char *_source, char * _value ) {
6632
6633 outline1("LD DE, (%s)", _value);
6634 outline1("LD HL, (%s)", _source);
6635 outline0("LD A, L");
6636 outline0("LD (DE), A");
6637 outline0("INC DE");
6638 outline0("LD A, H");
6639 outline0("LD (DE), A");
6640 outline0("INC DE");
6641 outline1("LD HL, (%s)", address_displacement(_environment, _source, "2"));
6642 outline0("LD A, L");
6643 outline0("LD (DE), A");
6644 outline0("INC DE");
6645 outline0("LD A, H");
6646 outline0("LD (DE), A");
6647 outline0("INC DE");
6648
6649}
6650
6651void cpu_move_nbit_indirect( Environment * _environment, int _n, char *_source, char * _value ) {
6652
6653 outline1("LD DE, (%s)", _value);
6654
6655 char step[MAX_TEMPORARY_STORAGE];
6656 char step2[MAX_TEMPORARY_STORAGE];
6657
6658 int stepIndex = 0;
6659 while( _n ) {
6660 sprintf( step, "%d", stepIndex );
6661 sprintf( step2, "%d", stepIndex+2 );
6662 if ( _n >= 32 ) {
6663 outline1("LD HL, (%s)", address_displacement(_environment, _source, step));
6664 outline0("LD A, L");
6665 outline0("LD (DE), A");
6666 outline0("INC DE");
6667 outline0("LD A, H");
6668 outline0("LD (DE), A");
6669 outline0("INC DE");
6670 outline1("LD HL, (%s)", address_displacement(_environment, _source, step2));
6671 outline0("LD A, L");
6672 outline0("LD (DE), A");
6673 outline0("INC DE");
6674 outline0("LD A, H");
6675 outline0("LD (DE), A");
6676 outline0("INC DE");
6677 stepIndex += 4;
6678 _n -= 32;
6679 } else {
6680 switch( _n ) {
6681 case 32: case 31: case 30: case 29:
6682 case 28: case 27: case 26: case 25:
6683 outline1("LD HL, (%s)", address_displacement(_environment, _source, step));
6684 outline0("LD A, L");
6685 outline0("LD (DE), A");
6686 outline0("INC DE");
6687 outline0("LD A, H");
6688 outline0("LD (DE), A");
6689 outline0("INC DE");
6690 outline1("LD HL, (%s)", address_displacement(_environment, _source, step2));
6691 outline0("LD A, L");
6692 outline0("LD (DE), A");
6693 outline0("INC DE");
6694 outline0("LD A, H");
6695 outline0("LD (DE), A");
6696 outline0("INC DE");
6697 break;
6698 case 24: case 23: case 22: case 21:
6699 case 20: case 19: case 18: case 17:
6700 outline1("LD HL, (%s)", address_displacement(_environment, _source, step));
6701 outline0("LD A, L");
6702 outline0("LD (DE), A");
6703 outline0("INC DE");
6704 outline0("LD A, H");
6705 outline0("LD (DE), A");
6706 outline0("INC DE");
6707 outline1("LD A, (%s)", address_displacement(_environment, _source, step2));
6708 outline0("LD (DE), A");
6709 outline0("INC DE");
6710 break;
6711 case 16: case 15: case 14: case 13:
6712 case 12: case 11: case 10: case 9:
6713 outline1("LD HL, (%s)", address_displacement(_environment, _source, step));
6714 outline0("LD A, L");
6715 outline0("LD (DE), A");
6716 outline0("INC DE");
6717 outline0("LD A, H");
6718 outline0("LD (DE), A");
6719 outline0("INC DE");
6720 break;
6721 case 8: case 7: case 6: case 5:
6722 case 4: case 3: case 2: case 1:
6723 outline1("LD A, (%s)", address_displacement(_environment, _source, step));
6724 outline0("LD (DE), A");
6725 outline0("INC DE");
6726 break;
6727 }
6728 _n = 0;
6729 }
6730 }
6731}
6732
6733void cpu_move_32bit_indirect2( Environment * _environment, char * _value, char *_source ) {
6734
6735 outline1("LD DE, (%s)", _value);
6736 outline0("LD A, (DE)");
6737 outline0("LD L, A");
6738 outline0("INC DE");
6739 outline0("LD A, (DE)");
6740 outline0("LD H, A");
6741 outline0("INC DE");
6742 outline1("LD (%s), HL", _source);
6743 outline0("LD A, (DE)");
6744 outline0("LD L, A");
6745 outline0("INC DE");
6746 outline0("LD A, (DE)");
6747 outline0("LD H, A");
6748 outline0("INC DE");
6749 outline1("LD (%s), HL", address_displacement( _environment, _source, "2" ) );
6750
6751}
6752
6753void cpu_move_nbit_indirect2( Environment * _environment, int _n, char * _value, char *_source ) {
6754
6755 outline1("LD DE, (%s)", _value);
6756
6757 char step[MAX_TEMPORARY_STORAGE];
6758 char step2[MAX_TEMPORARY_STORAGE];
6759
6760 int stepIndex = 0;
6761 while( _n ) {
6762 sprintf( step, "%d", stepIndex );
6763 sprintf( step2, "%d", stepIndex+2 );
6764 if ( _n >= 32 ) {
6765 outline0("LD A, (DE)");
6766 outline0("LD L, A");
6767 outline0("INC DE");
6768 outline0("LD A, (DE)");
6769 outline0("LD H, A");
6770 outline0("INC DE");
6771 outline1("LD (%s), HL", address_displacement( _environment, _source, step ) );
6772 outline0("LD A, (DE)");
6773 outline0("LD L, A");
6774 outline0("INC DE");
6775 outline0("LD A, (DE)");
6776 outline0("LD H, A");
6777 outline0("INC DE");
6778 outline1("LD (%s), HL", address_displacement( _environment, _source, step2 ) );
6779 stepIndex += 4;
6780 _n -= 32;
6781 } else {
6782 switch( _n ) {
6783 case 32: case 31: case 30: case 29:
6784 case 28: case 27: case 26: case 25:
6785 outline0("LD A, (DE)");
6786 outline0("LD L, A");
6787 outline0("INC DE");
6788 outline0("LD A, (DE)");
6789 outline0("LD H, A");
6790 outline0("INC DE");
6791 outline1("LD (%s), HL", address_displacement( _environment, _source, step ) );
6792 outline0("LD A, (DE)");
6793 outline0("LD L, A");
6794 outline0("INC DE");
6795 outline0("LD A, (DE)");
6796 outline0("LD H, A");
6797 outline0("INC DE");
6798 outline1("LD (%s), HL", address_displacement( _environment, _source, step2 ) );
6799 break;
6800 case 24: case 23: case 22: case 21:
6801 case 20: case 19: case 18: case 17:
6802 outline0("LD A, (DE)");
6803 outline0("LD L, A");
6804 outline0("INC DE");
6805 outline0("LD A, (DE)");
6806 outline0("LD H, A");
6807 outline0("INC DE");
6808 outline1("LD (%s), HL", address_displacement( _environment, _source, step ) );
6809 outline0("LD A, (DE)");
6810 outline0("INC DE");
6811 outline1("LD (%s), A", address_displacement( _environment, _source, step2 ) );
6812 break;
6813 case 16: case 15: case 14: case 13:
6814 case 12: case 11: case 10: case 9:
6815 outline0("LD A, (DE)");
6816 outline0("LD L, A");
6817 outline0("INC DE");
6818 outline0("LD A, (DE)");
6819 outline0("LD H, A");
6820 outline0("INC DE");
6821 outline1("LD (%s), HL", address_displacement( _environment, _source, step ) );
6822 break;
6823 case 8: case 7: case 6: case 5:
6824 case 4: case 3: case 2: case 1:
6825 outline0("LD A, (DE)");
6826 outline0("INC DE");
6827 outline1("LD (%s), A", address_displacement( _environment, _source, step ) );
6828 break;
6829 }
6830 _n = 0;
6831 }
6832 }
6833
6834}
6835
6836
6837
6838void cpu_math_div_8bit_to_8bit( Environment * _environment, char *_source, char *_destination, char *_other, char * _other_remainder, int _signed ) {
6839
6841
6842 if ( _signed ) {
6843
6844 outline1("LD A, (%s)", _source );
6845 outline0("LD B, A" );
6846 outline1("LD A, (%s)", _destination );
6847 outline0("XOR A, B" );
6848 outline0("AND $80" );
6849 outline0("PUSH AF" );
6850 outline1("LD A, (%s)", _source );
6851 outline0("AND $80" );
6852 outline0("CP 0" );
6853 outline1("JR Z,%spos", label );
6854 outline1("LD A, (%s)", _source );
6855 outline0("XOR $FF" );
6856 outline0("ADC $1" );
6857 outline1("JMP %spos2", label );
6858 outhead1("%spos:", label );
6859 outline1("LD A, (%s)", _source );
6860 outhead1("%spos2:", label );
6861 outline0("LD D, A");
6862
6863 outline1("LD A, (%s)", _destination );
6864 outline0("AND $80" );
6865 outline0("CP 0" );
6866 outline1("JR Z,%sposx", label );
6867 outline1("LD A, (%s)", _destination );
6868 outline0("XOR $FF" );
6869 outline0("ADC $1" );
6870 outline1("JMP %sposx2", label );
6871 outhead1("%sposx:", label );
6872 outline1("LD A, (%s)", _destination );
6873 outhead1("%sposx2:", label );
6874 outline0("LD E, A");
6875
6876 outline0("XOR A");
6877 outline0("AND A");
6878 outline0("LD B, 8");
6879 outhead1("%sloop:", label);
6880 outline0("SLA D");
6881 outline0("RLA");
6882 outline0("CP E");
6883 outline0("JR C, $+4");
6884 outline0("SUB E");
6885 outline0("INC D");
6886 outline1("DJNZ %sloop", label );
6887
6888 outline1("LD (%s), A", _other_remainder);
6889 outline0("LD A, D");
6890 outline1("LD (%s), A", _other);
6891
6892 outline0("POP AF" );
6893 outline0("AND $80" );
6894 outline0("CP 0" );
6895 outline1("JR Z,%spos3", label );
6896 outline1("LD A, (%s)", _other );
6897 outline0("XOR $FF" );
6898 outline0("ADC $1" );
6899 outline1("LD (%s), A", _other );
6900 outhead1("%spos3:", label );
6901
6902 } else {
6903
6904 outline1("LD A, (%s)", _source);
6905 outline0("LD D, A");
6906 outline1("LD A, (%s)", _destination);
6907 outline0("LD E, A");
6908
6909 outline0("XOR A");
6910 outline0("LD B, 8");
6911 outhead1("%sloop:", label);
6912
6913 outline0("SLA D");
6914 outline0("RLA");
6915 outline0("CP E");
6916 outline0("JR C, $+4");
6917 outline0("SUB E");
6918 outline0("INC D");
6919 outline1("DJNZ %sloop", label );
6920
6921 outline1("LD (%s), A", _other_remainder);
6922 outline0("LD A, D");
6923 outline1("LD (%s), A", _other);
6924
6925 }
6926}
6927
6928void cpu_math_div_8bit_to_8bit_const( Environment * _environment, char *_source, int _destination, char *_other, char * _other_remainder, int _signed ) {
6929
6931
6932 if ( _signed ) {
6933
6934 outline1("LD A, (%s)", _source );
6935 outline0("LD B, A" );
6936 outline1("LD A, $%2.2x", (unsigned char)(_destination&0xff) );
6937 outline0("XOR A, B" );
6938 outline0("AND $80" );
6939 outline0("PUSH AF" );
6940 outline1("LD A, (%s)", _source );
6941 outline0("AND $80" );
6942 outline0("CP 0" );
6943 outline1("JR Z,%spos", label );
6944 outline1("LD A, (%s)", _source );
6945 outline0("XOR $FF" );
6946 outline0("ADC $1" );
6947 outline1("JMP %spos2", label );
6948 outhead1("%spos:", label );
6949 outline1("LD A, (%s)", _source );
6950 outhead1("%spos2:", label );
6951 outline0("LD D, A");
6952
6953 outline1("LD A, $%2.2x", (unsigned char)(_destination&0xff) );
6954 outline0("AND $80" );
6955 outline0("CP 0" );
6956 outline1("JR Z,%sposx", label );
6957 outline1("LD A, $%2.2x", (unsigned char)(_destination&0xff) );
6958 outline0("XOR $FF" );
6959 outline0("ADC $1" );
6960 outline1("JMP %sposx2", label );
6961 outhead1("%sposx:", label );
6962 outline1("LD A, $%2.2x", (unsigned char)(_destination&0xff) );
6963 outhead1("%sposx2:", label );
6964 outline0("LD E, A");
6965
6966 outline0("XOR A");
6967 outline0("AND A");
6968 outline0("LD B, 8");
6969 outhead1("%sloop:", label);
6970 outline0("SLA D");
6971 outline0("RLA");
6972 outline0("CP E");
6973 outline0("JR C, $+4");
6974 outline0("SUB E");
6975 outline0("INC D");
6976 outline1("DJNZ %sloop", label );
6977
6978 outline1("LD (%s), A", _other_remainder);
6979 outline0("LD A, D");
6980 outline1("LD (%s), A", _other);
6981
6982 outline0("POP AF" );
6983 outline0("AND $80" );
6984 outline0("CP 0" );
6985 outline1("JR Z,%spos3", label );
6986 outline1("LD A, (%s)", _other );
6987 outline0("XOR $FF" );
6988 outline0("ADC $1" );
6989 outline1("LD (%s), A", _other );
6990 outhead1("%spos3:", label );
6991
6992 } else {
6993
6994 outline1("LD A, (%s)", _source);
6995 outline0("LD D, A");
6996 outline1("LD A, $%2.2x", (unsigned char)(_destination&0xff));
6997 outline0("LD E, A");
6998
6999 outline0("XOR A");
7000 outline0("LD B, 8");
7001 outhead1("%sloop:", label);
7002
7003 outline0("SLA D");
7004 outline0("RLA");
7005 outline0("CP E");
7006 outline0("JR C, $+4");
7007 outline0("SUB E");
7008 outline0("INC D");
7009 outline1("DJNZ %sloop", label );
7010
7011 outline1("LD (%s), A", _other_remainder);
7012 outline0("LD A, D");
7013 outline1("LD (%s), A", _other);
7014
7015 }
7016}
7017
7018void cpu_bit_check( Environment * _environment, char *_value, int _position, char * _result, int _bitwidth ) {
7019
7021
7022 embedded( cpu_bit_check_extended, src_hw_z80_cpu_bit_check_extended_asm );
7023
7024 outline1("LD DE, %s", _value);
7025 outline1("LD A, $%2.2x", (unsigned char)(_position&0xff) );
7026 outline0("CALL CPUBITCHECKEXTENDED" );
7027
7028 if ( _result ) {
7029 outline1("LD (%s), A", _result);
7030 }
7031
7032 done( )
7033
7034}
7035
7036void cpu_bit_check_extended( Environment * _environment, char *_value, char * _position, char * _result, int _bitwidth ) {
7037
7039
7041
7042 embedded( cpu_bit_check_extended, src_hw_z80_cpu_bit_check_extended_asm );
7043
7044 outline1("LD DE, %s", _value);
7045 outline1("LD A, (%s)", _position );
7046 outline0("CALL CPUBITCHECKEXTENDED" );
7047
7048 if ( _result ) {
7049 outline1("LD (%s), A", _result);
7050 }
7051
7052 done( )
7053
7054}
7055
7056void cpu_bit_inplace_8bit( Environment * _environment, char * _value, int _position, int * _bit ) {
7057
7058 _environment->bitmaskNeeded = 1;
7059
7061
7062 no_inline( cpu_bit_inplace )
7063
7064 embedded( cpu_bit_inplace, src_hw_z80_cpu_bit_inplace_asm );
7065
7066 if ( _bit ) {
7067 if ( * _bit ) {
7068 outline0("LD A, $ff" );
7069 } else {
7070 outline0("LD A, $0" );
7071 }
7072 outline0("SRL A" );
7073 }
7074 outline1("LD DE, %s", _value );
7075 outline1("LD A, $%2.2x", (unsigned char)(_position&0xff));
7076 outline0("CALL CPUBITINPLACE");
7077
7078 done( )
7079
7080}
7081
7082void cpu_bit_inplace_8bit_extended_indirect( Environment * _environment, char * _address, char * _position, char * _bit ) {
7083
7084 _environment->bitmaskNeeded = 1;
7085
7087
7088 no_inline( cpu_bit_inplace )
7089
7090 embedded( cpu_bit_inplace, src_hw_z80_cpu_bit_inplace_asm );
7091
7092 if ( _bit ) {
7093 outline1("LD A, (%s)", _bit );
7094 outline0("CP $0" );
7095 outline1("JR Z, %s", label );
7096 outline0("LD A, 1" );;
7097 outline0("SRL A" );
7098 outhead1("%s:", label );
7099 }
7100 outline1("LD DE, (%s)", _address );
7101 outline1("LD A, (%s)", _position);
7102 outline0("CALL CPUBITINPLACE");
7103
7104 done( )
7105
7106}
7107
7109
7110 variable_import( _environment, "N2DINV", VT_BUFFER, _environment->numberConfig.maxBytes );
7111 variable_import( _environment, "N2DBUF", VT_BUFFER, _environment->numberConfig.maxDigits );
7112 variable_import( _environment, "N2DEND", VT_BUFFER, 1 );
7113
7114}
7115
7116void cpu_number_to_string( Environment * _environment, char * _number, char * _string, char * _string_size, int _bits, int _signed ) {
7117
7119
7120 deploy_with_vars( numberToString, src_hw_z80_number_to_string_asm, cpu_number_to_string_vars );
7121
7122 cpu_fill_direct_size_value( _environment, "N2DINV", _environment->numberConfig.maxBytes, 0 );
7123
7124 outline0("LD IXH, 0");
7125 switch( _bits ) {
7126 case 8:
7127 outline1("LD A, (%s)", _number);
7128 outline0("LD (N2DINV), A");
7129 if ( _signed ) {
7130 outline0("AND $80");
7131 outline0("CP 0");
7132 outline1("JR Z, %sp81", label);
7133 cpu_complement2_8bit( _environment, "N2DINV", NULL );
7134 outline0("LD IXH, 0xff");
7135 outhead1("%sp81:", label);
7136 }
7137 outline0("CALL N2D8");
7138 break;
7139 case 16:
7140 outline1("LD HL, (%s)", _number);
7141 outline0("LD (N2DINV), HL");
7142 if ( _signed ) {
7143 outline0("LD A, H");
7144 outline0("AND $80");
7145 outline0("CP 0");
7146 outline1("JR Z, %sp81", label);
7147 cpu_complement2_16bit( _environment, "N2DINV", NULL );
7148 outline0("LD IXH, 0xff");
7149 outhead1("%sp81:", label);
7150 }
7151 outline0("CALL N2D16");
7152 break;
7153 case 32:
7154 outline1("LD HL, (%s)", _number);
7155 outline0("LD (N2DINV), HL");
7156 outline1("LD HL, (%s)", address_displacement(_environment, _number, "2"));
7157 outline0("LD (N2DINV+2), HL");
7158 if ( _signed ) {
7159 outline0("LD A, H");
7160 outline0("AND $80");
7161 outline0("CP 0");
7162 outline1("JR Z, %sp81", label);
7163 cpu_complement2_32bit( _environment, "N2DINV", NULL );
7164 outline0("LD IXH, 0xff");
7165 outhead1("%sp81:", label);
7166 }
7167 outline0("CALL N2D32");
7168 break;
7169 case 0:
7170 CRITICAL_DEBUG_UNSUPPORTED( _number, "unknown");
7171 default:
7172 cpu_mem_move_direct_size( _environment, _number, "N2DINV", _bits >> 3 );
7173 if ( _signed ) {
7174 outline1("LD A, (N2DINV+%d)", (_bits >> 3)-1 );
7175 outline0("AND $80");
7176 outline0("CP 0");
7177 outline1("JP Z, %sp81", label);
7178 cpu_complement2_nbit( _environment, "N2DINV", NULL, _bits );
7179 outline0("LD IXH, 0xff");
7180 outhead1("%sp81:", label);
7181 }
7182 outline0("CALL N2STRING");
7183 break;
7184 }
7185
7186 outline1("LD DE, (%s)", _string);
7187 outline0("LD A, IXH");
7188 outline0("CP 0");
7189 outline1("JR Z, %spos", label);
7190 outline0("LD A, '-'");
7191 outline0("LD (DE), A");
7192 outline0("INC DE");
7193 outline0("INC C");
7194 outhead1("%spos:", label);
7195 outline0("LD A, C");
7196 outline1("LD (%s), A", _string_size);
7197 outline0("LDIR");
7198
7199}
7200
7201void cpu_bits_to_string_vars( Environment * _environment ) {
7202 variable_import( _environment, "BINSTRBUF", VT_BUFFER, 32 );
7203 variable_import( _environment, "BINTOSTRDIGIT0", VT_BYTE, '0' );
7204 variable_import( _environment, "BINTOSTRDIGIT1", VT_BYTE, '1' );
7205}
7206
7207void cpu_bits_to_string( Environment * _environment, char * _number, char * _string, char * _string_size, int _bits, char * _zero, char * _one ) {
7208
7209 deploy_with_vars( bitsToString,src_hw_z80_bits_to_string_asm, cpu_bits_to_string_vars );
7210
7211 if ( _zero ) {
7212 outline1("LD A, (%s)", _zero);
7213 } else {
7214 outline0("LD A, '0'" );
7215 }
7216 outline0("LD (BINTOSTRDIGIT0), A" );
7217
7218 if ( _one ) {
7219 outline1("LD A, (%s)", _one);
7220 } else {
7221 outline0("LD A, '1'" );
7222 }
7223 outline0("LD (BINTOSTRDIGIT1), A" );
7224
7225 switch( _bits ) {
7226 case 32:
7227 outline1("LD BC, (%s)", address_displacement(_environment, _number, "2") );
7228 outline1("LD DE, (%s)", _number );
7229 break;
7230 case 16:
7231 outline0("LD BC, 0" );
7232 outline1("LD DE, (%s)", _number );
7233 break;
7234 case 8:
7235 outline0("LD BC, 0" );
7236 outline0("LD D, 0" );
7237 outline1("LD A, (%s)", _number );
7238 outline0("LD E, A" );
7239 outline0("LD A, 0" );
7240 break;
7241 }
7242
7243 outline1("LD A, $%2.2x", (unsigned char)( _bits & 0xff ) );
7244 outline0("CALL BINSTR");
7245
7246 outline1("LD DE, (%s)", _string);
7247 outline1("LD A, $%2.2x", (unsigned char)( (_bits) & 0xff ) );
7248 outline0("LD C, A");
7249 outline0("LD B, 0");
7250 outline0("LDIR");
7251
7252 outline1("LD A, $%2.2x", (unsigned char)( _bits & 0xff ) );
7253 outline1("LD HL, %s", _string_size );
7254 outline0("LD (HL), A" );
7255
7256}
7257
7258void cpu_hex_to_string_calc_string( Environment * _environment, char * _size, int _separator, char * _string_size ) {
7259
7261
7262 deploy_embedded( cpu_math_mul_8bit_to_16bit, src_hw_z80_cpu_math_mul_8bit_to_16bit_asm );
7263
7264 outline1("LD A, (%s)", _size );
7265 outline0("LD IYL, A");
7266 outline1("LD A, $%2.2x", 2 + (_separator?1:0));
7267 outline0("LD IXL, A");
7268 outline0("CALL CPUMUL8B8T16U");
7269 outline0("LD A, L");
7270 outline1("LD (%s), A", _string_size);
7271
7272}
7273
7274void cpu_hex_to_string_calc_string_size( Environment * _environment, int _size, int _separator, char * _string_size ) {
7275
7277
7278 deploy_embedded( cpu_math_mul_8bit_to_16bit, src_hw_z80_cpu_math_mul_8bit_to_16bit_asm );
7279
7280 outline1("LD A, $%2.2x", (unsigned char)(_size) );
7281 outline0("LD IYL, A");
7282 outline1("LD A, $%2.2x", 2 + (_separator?1:0));
7283 outline0("LD IXL, A");
7284 outline0("CALL CPUMUL8B8T16U");
7285 outline0("LD A, L");
7286 outline1("LD (%s), A", _string_size);
7287
7288}
7289
7290void cpu_hex_to_string( Environment * _environment, char * _number, char * _string, char * _size, int _separator ) {
7291
7293
7294 inline( cpu_hex_to_string )
7295
7296 embedded( cpu_hex_to_string, src_hw_z80_cpu_hex_to_string_asm );
7297
7298 outline1("LD A, (%s)", _size);
7299 outline0("LD C, A");
7300 outline1("LD B, $%2.2x", (unsigned char)(_separator * 3));
7301 outline1("LD HL, (%s)", _number );
7302 outline1("LD DE, (%s)", _string );
7303 outline0("CALL H2STRING" );
7304
7305 done()
7306
7307}
7308
7309
7310void cpu_dsdefine( Environment * _environment, char * _string, char * _index ) {
7311
7312 deploy( duff, src_hw_z80_duff_asm );
7313 deploy( dstring,src_hw_z80_dstring_asm );
7314
7315 outline1( "LD HL, %s", _string );
7316 outline0( "CALL DSDEFINE" );
7317 outline0( "LD A, B" );
7318 outline1( "LD (%s), A", _index );
7319
7320}
7321
7322void cpu_dsalloc( Environment * _environment, char * _size, char * _index ) {
7323
7324 deploy( duff, src_hw_z80_duff_asm );
7325 deploy( dstring,src_hw_z80_dstring_asm );
7326
7327 outline1( "LD A, (%s)", _size );
7328 outline0( "LD C, A" );
7329 outline0( "CALL DSALLOC" );
7330 outline0( "LD A, B" );
7331 outline1( "LD (%s), A", _index );
7332
7333}
7334
7335void cpu_dsalloc_size( Environment * _environment, int _size, char * _index ) {
7336
7337 deploy( duff, src_hw_z80_duff_asm );
7338 deploy( dstring,src_hw_z80_dstring_asm );
7339
7340 outline1( "LD A, $%2.2x", (unsigned char)( _size & 0xff ) );
7341 outline0( "LD C, A" );
7342 outline0( "CALL DSALLOC" );
7343 outline0( "LD A, B" );
7344 outline1( "LD (%s), A", _index );
7345
7346}
7347
7348void cpu_dsfree( Environment * _environment, char * _index ) {
7349
7350 deploy( duff, src_hw_z80_duff_asm );
7351 deploy( dstring,src_hw_z80_dstring_asm );
7352
7353 outline1( "LD A, (%s)", _index );
7354 outline0( "LD B, A" );
7355 outline0( "CALL DSFREE" );
7356
7357}
7358
7359void cpu_dswrite( Environment * _environment, char * _index ) {
7360
7361 deploy( duff, src_hw_z80_duff_asm );
7362 deploy( dstring,src_hw_z80_dstring_asm );
7363
7364 outline1( "LD A, (%s)", _index );
7365 outline0( "LD B, A" );
7366 outline0( "CALL DSWRITE" );
7367
7368}
7369
7370void cpu_dsresize( Environment * _environment, char * _index, char * _resize ) {
7371
7372 deploy( duff, src_hw_z80_duff_asm );
7373 deploy( dstring,src_hw_z80_dstring_asm );
7374
7375 outline1( "LD A, (%s)", _index );
7376 outline0( "LD B, A" );
7377 outline1( "LD A, (%s)", _resize );
7378 outline0( "LD C, A" );
7379 outline0( "CALL DSRESIZE" );
7380
7381}
7382
7383void cpu_dsresize_size( Environment * _environment, char * _index, int _resize ) {
7384
7385 deploy( duff, src_hw_z80_duff_asm );
7386 deploy( dstring,src_hw_z80_dstring_asm );
7387
7388 outline1( "LD A, (%s)", _index );
7389 outline0( "LD B, A" );
7390 outline1( "LD A, $%2.2x", (unsigned char)( _resize & 0xff ) );
7391 outline0( "LD C, A" );
7392 outline0( "CALL DSRESIZE" );
7393
7394}
7395
7396void cpu_dsgc( Environment * _environment ) {
7397
7398 deploy( duff, src_hw_z80_duff_asm );
7399 deploy( dstring,src_hw_z80_dstring_asm );
7400
7401 outline0( "CALL DSGC" );
7402
7403}
7404
7405void cpu_dsinit( Environment * _environment ) {
7406
7407 deploy( duff, src_hw_z80_duff_asm );
7408 deploy( dstring,src_hw_z80_dstring_asm );
7409
7410 outline0( "CALL DSINIT" );
7411
7412}
7413
7414void cpu_dsdescriptor( Environment * _environment, char * _index, char * _address, char * _size ) {
7415
7416 deploy( duff, src_hw_z80_duff_asm );
7417 deploy( dstring,src_hw_z80_dstring_asm );
7418
7419 if ( _address || _size ) {
7420 outline1( "LD A, (%s)", _index );
7421 outline0( "LD B, A" );
7422 outline0( "CALL DSDESCRIPTOR" );
7423 if ( _size ) {
7424 outline0( "LD A, (IX)" );
7425 outline1( "LD (%s), A", _size );
7426 }
7427 if ( _address ) {
7428 outline0( "LD A, (IX+1)" );
7429 outline1( "LD (%s), A", _address );
7430 outline0( "LD A, (IX+2)" );
7431 outline1( "LD (%s), A", address_displacement(_environment, _address, "1") );
7432 }
7433 }
7434
7435}
7436
7437void cpu_dsassign( Environment * _environment, char * _original, char * _copy ) {
7438
7439 deploy( duff, src_hw_z80_duff_asm );
7440 deploy( dstring,src_hw_z80_dstring_asm );
7441
7442 outline1( "LD A, (%s)", _copy );
7443 outline0( "LD B, A");
7444 outline1( "LD A, (%s)", _original );
7445 outline0( "CALL DSASSIGN" );
7446 outline0( "LD A, B" );
7447 outline1( "LD (%s), A", _copy );
7448
7449}
7450
7451void cpu_dsassign_string( Environment * _environment, char * _string, char * _copy ) {
7452
7453 deploy( duff, src_hw_z80_duff_asm );
7454 deploy( dstring,src_hw_z80_dstring_asm );
7455
7456 outline1( "LD A, (%s)", _copy );
7457 outline0( "LD B, A");
7458 outline1( "LD HL, %s", _string );
7459 outline0( "CALL DSASSIGNSTR" );
7460 outline0( "LD A, B" );
7461 outline1( "LD (%s), A", _copy );
7462
7463}
7464
7465void cpu_move_8bit_indirect_with_offset2( Environment * _environment, char *_source, char * _value, char * _offset ) {
7466
7467 outline1("LD HL, (%s)", _value);
7468 outline1("LD A, (%s)", _offset );
7469 outline0("LD E, A" );
7470 outline0("LD A, 0" );
7471 outline0("LD D, A" );
7472 outline0("ADD HL, DE" );
7473 outline1("LD A, (%s)", _source);
7474 outline0("LD (HL), A");
7475
7476}
7477
7478void cpu_complement2_8bit( Environment * _environment, char * _source, char * _destination ) {
7479 outline1( "LD A, (%s)", _source );
7480 outline0( "XOR $FF" );
7481 if ( _destination ) {
7482 outline1( "LD (%s), A", _destination );
7483 } else {
7484 outline1( "LD (%s), A", _source );
7485 }
7486 if ( _destination ) {
7487 cpu_inc( _environment, _destination );
7488 } else {
7489 cpu_inc( _environment, _source );
7490 }
7491}
7492
7493void cpu_complement2_16bit( Environment * _environment, char * _source, char * _destination ) {
7494 outline1( "LD A, (%s)", _source );
7495 outline0( "XOR $FF" );
7496 if ( _destination ) {
7497 outline1( "LD (%s), A", _destination );
7498 } else {
7499 outline1( "LD (%s), A", _source );
7500 }
7501 outline1( "LD A, (%s)", address_displacement(_environment, _source, "1") );
7502 outline0( "XOR $FF" );
7503 if ( _destination ) {
7504 outline1( "LD (%s), A", address_displacement(_environment, _destination, "1") );
7505 } else {
7506 outline1( "LD (%s), A", address_displacement(_environment, _source, "1") );
7507 }
7508 if ( _destination ) {
7509 cpu_inc_16bit( _environment, _destination );
7510 } else {
7511 cpu_inc_16bit( _environment, _source );
7512 }
7513}
7514
7515void cpu_complement2_32bit( Environment * _environment, char * _source, char * _destination ) {
7516 outline1( "LD A, (%s)", _source );
7517 outline0( "XOR $FF" );
7518 if ( _destination ) {
7519 outline1( "LD (%s), A", _destination );
7520 } else {
7521 outline1( "LD (%s), A", _source );
7522 }
7523 outline1( "LD A, (%s)", address_displacement(_environment, _source, "1") );
7524 outline0( "XOR $FF" );
7525 if ( _destination ) {
7526 outline1( "LD (%s), A", address_displacement(_environment, _destination, "1") );
7527 } else {
7528 outline1( "LD (%s), A", address_displacement(_environment, _source, "1") );
7529 }
7530 outline1( "LD A, (%s)", address_displacement(_environment, _source, "2") );
7531 outline0( "XOR $FF" );
7532 if ( _destination ) {
7533 outline1( "LD (%s), A", address_displacement(_environment, _destination, "2") );
7534 } else {
7535 outline1( "LD (%s), A", address_displacement(_environment, _source, "2") );
7536 }
7537 outline1( "LD A, (%s)", address_displacement(_environment, _source, "3") );
7538 outline0( "XOR $FF" );
7539 if ( _destination ) {
7540 outline1( "LD (%s), A", address_displacement(_environment, _destination, "3") );
7541 } else {
7542 outline1( "LD (%s), A", address_displacement(_environment, _source, "3") );
7543 }
7544 if ( _destination ) {
7545 cpu_inc_32bit( _environment, _destination );
7546 } else {
7547 cpu_inc_32bit( _environment, _source );
7548 }
7549}
7550
7551void cpu_complement2_nbit( Environment * _environment, char * _source, char * _destination, int _bits ) {
7552
7553 for( int i=0; i<(_bits>>3); ++i ) {
7554 char offset[MAX_TEMPORARY_STORAGE]; sprintf( offset, "%d", i );
7555 outline1( "LD A, (%s)", address_displacement(_environment, _source, offset) );
7556 outline0( "XOR $FF" );
7557 if ( _destination ) {
7558 outline1( "LD (%s), A", address_displacement(_environment, _destination, "1") );
7559 } else {
7560 outline1( "LD (%s), A", address_displacement(_environment, _source, "1") );
7561 }
7562 }
7563 if ( _destination ) {
7564 cpu_inc_nbit( _environment, _destination, _bits );
7565 } else {
7566 cpu_inc_nbit( _environment, _source, _bits );
7567 }
7568
7569}
7570
7571void cpu_sqroot( Environment * _environment, char * _number, char * _result ) {
7572
7573 deploy( sqr, src_hw_z80_sqr_asm );
7574
7575 outline1("LD HL, (%s)", _number );
7576
7577 outline0("CALL SQROOT" );
7578
7579 outline1("LD (%s),A", _result );
7580
7581}
7582
7583void cpu_dstring_vars( Environment * _environment ) {
7584
7585 int count = _environment->dstring.count == 0 ? DSTRING_DEFAULT_COUNT : _environment->dstring.count;
7586 int space = _environment->dstring.space == 0 ? DSTRING_DEFAULT_SPACE : _environment->dstring.space;
7587
7588#if !defined(__vg5000__) && !defined(__cpc__) && !defined(__c128z__) && !defined(__zx__) && !defined(__vz200__)
7589 outhead0("section data_user" );
7590#endif
7591 outhead1("stringscount = %d", count );
7592 outhead1("stringsspace = %d", space );
7593 outhead0("MAXSTRINGS: DB stringscount" );
7594 outhead0("DESCRIPTORS: DEFS stringscount*4" );
7595 outhead0("WORKING: DEFS stringsspace" );
7596 outhead0("TEMPORARY: DEFS stringsspace" );
7597 outhead0("FREE_STRING: DW (stringsspace-1)" );
7598#if !defined(__vg5000__) && !defined(__cpc__) && !defined(__c128z__) && !defined(__zx__) && !defined(__vz200__)
7599 outhead0("section code_user" );
7600#endif
7601
7602}
7603
7604void cpu_protothread_vars( Environment * _environment ) {
7605
7606 int count = _environment->protothreadConfig.count;
7607
7608 variable_import( _environment, "PROTOTHREADLC", VT_BUFFER, count );
7609 // outhead1("PROTOTHREADLC: DEFS %d", count );
7610 variable_import( _environment, "PROTOTHREADST", VT_BUFFER, count );
7611 // outhead1("PROTOTHREADST: DEFS %d", count );
7612 variable_import( _environment, "PROTOTHREADCT", VT_BYTE, 0 );
7613 // outhead0("PROTOTHREADCT: DEFB 0" );
7614 variable_import( _environment, "PROTOTHREADLOOP", VT_BUFFER, 1 + count * 8 );
7615 variable_import( _environment, "PROTOTHREADCOUNT", VT_BYTE, count );
7616
7617}
7618
7619
7620void cpu_protothread_loop( Environment * _environment ) {
7621
7622 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7623
7624 outline0("CALL PROTOTHREADLOOP" );
7625
7626}
7627
7628void cpu_protothread_register_at( Environment * _environment, char * _index, char * _label ) {
7629
7630 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7631
7632 outline1("LD HL, %s", _label );
7633 outline1("LD A, (%s)", _index );
7634 outline0("LD B, A");
7635
7636 outline0("CALL PROTOTHREADREGAT" );
7637
7638}
7639
7640void cpu_protothread_register( Environment * _environment, char * _label, char * _index ) {
7641
7642 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7643
7644 outline1("LD HL, %s", _label );
7645
7646 outline0("CALL PROTOTHREADREG" );
7647
7648 outline0("LD A, B" );
7649 outline1("LD (%s), A", _index );
7650
7651}
7652
7653void cpu_protothread_unregister( Environment * _environment, char * _index ) {
7654
7655 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7656
7657 outline1("LD A, (%s)", _index );
7658 outline0("LD B, A" );
7659
7660 outline0("CALL PROTOTHREADUNREG" );
7661
7662}
7663
7664void cpu_protothread_save( Environment * _environment, char * _index, int _step ) {
7665
7666 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7667
7668 outline1("LD A, (%s)", _index );
7669 outline0("LD B, A" );
7670 outline1("LD A, $%2.2x", (unsigned char)( _step & 0xff ) );
7671
7672 outline0("CALL PROTOTHREADSAVE" );
7673
7674}
7675
7676void cpu_protothread_restore( Environment * _environment, char * _index, char * _step ) {
7677
7678 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7679
7680 outline1("LD A, (%s)", _index );
7681 outline0("LD B, A" );
7682
7683 outline0("CALL PROTOTHREADRESTORE" );
7684
7685 outline1("LD (%s), A", _step );
7686
7687}
7688
7689void cpu_protothread_set_state( Environment * _environment, char * _index, int _state ) {
7690
7691 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7692
7693 outline1("LD A, (%s)", _index );
7694 outline0("LD B, A" );
7695 outline1("LD A, $%2.2x", (unsigned char)( _state & 0xff ) );
7696
7697 outline0("CALL PROTOTHREADSETSTATE" );
7698
7699}
7700
7701void cpu_protothread_get_state( Environment * _environment, char * _index, char * _state ) {
7702
7703 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7704
7705 outline1("LD A, (%s)", _index );
7706 outline0("LD B, A" );
7707
7708 outline0("CALL PROTOTHREADGETSTATE" );
7709
7710 outline1("LD (%s), A", _state );
7711
7712}
7713
7714void cpu_protothread_get_address( Environment * _environment, char * _index, char * _address ) {
7715
7716 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7717
7718 outline1("LD A, (%s)", _index );
7719 outline0("LD B, A" );
7720
7721 outline0("CALL PROTOTHREADGETADDRESS" );
7722
7723 outline1("LD (%s), DE", _address );
7724
7725}
7726
7727void cpu_protothread_current( Environment * _environment, char * _current ) {
7728
7729 deploy_with_vars( protothread, src_hw_z80_protothread_asm, cpu_protothread_vars );
7730
7731 outline0("LD A, (PROTOTHREADCT)" );
7732 outline1("LD (%s), A", _current );
7733
7734}
7735
7736void cpu_set_callback( Environment * _environment, char * _callback, char * _label ) {
7737
7738 outline1("LD DE, %s", _label );
7739 outline1("LD HL, %s", _callback );
7740 outline0("INC HL" );
7741 outline0("LD (HL), E" );
7742 outline0("INC HL" );
7743 outline0("LD (HL), D" );
7744
7745}
7746
7747void cpu_msc1_uncompress_direct_direct( Environment * _environment, char * _input, char * _output ) {
7748
7750
7751 inline( cpu_msc1_uncompress )
7752
7753 embedded( cpu_msc1_uncompress, src_hw_z80_msc1_asm );
7754
7755 outline1("LD HL, %s", _input);
7756 outline1("LD DE, %s", _output);
7757 outline0("CALL MSC1UNCOMPRESS");
7758
7759 done()
7760
7761}
7762
7763void cpu_msc1_uncompress_direct_indirect( Environment * _environment, char * _input, char * _output ) {
7764
7766
7767 inline( cpu_msc1_uncompress )
7768
7769 embedded( cpu_msc1_uncompress, src_hw_z80_msc1_asm );
7770
7771 outline1("LD HL, %s", _input);
7772 outline1("LD DE, (%s)", _output);
7773 outline0("CALL MSC1UNCOMPRESS");
7774
7775 done()
7776
7777}
7778
7779void cpu_msc1_uncompress_indirect_direct( Environment * _environment, char * _input, char * _output ) {
7780
7782
7783 inline( cpu_msc1_uncompress )
7784
7785 embedded( cpu_msc1_uncompress, src_hw_z80_msc1_asm );
7786
7787 outline1("LD HL, (%s)", _input);
7788 outline1("LD DE, %s", _output);
7789 outline0("CALL MSC1UNCOMPRESS");
7790
7791 done()
7792
7793}
7794
7795void cpu_msc1_uncompress_indirect_indirect( Environment * _environment, char * _input, char * _output ) {
7796
7798
7799 inline( cpu_msc1_uncompress )
7800
7801 embedded( cpu_msc1_uncompress, src_hw_z80_msc1_asm );
7802
7803 outline1("LD HL, (%s)", _input);
7804 outline1("LD DE, (%s)", _output);
7805 outline0("CALL MSC1UNCOMPRESS");
7806
7807 done()
7808
7809}
7810
7811void cpu_out( Environment * _environment, char * _port, char * _value ) {
7812
7813 outline1("LD A, (%s)", _value );
7814 outline1("LD BC, (%s)", _port );
7815 outline0("OUT (C), A" );
7816
7817}
7818
7819void cpu_in( Environment * _environment, char * _port, char * _value ) {
7820
7821 outline1("LD BC, (%s)", _port );
7822 outline0("IN A, (C)" );
7823 outline1("LD (%s), A", _value );
7824
7825}
7826
7827void cpu_out_direct( Environment * _environment, char * _port, char * _value ) {
7828
7829 outline1("LD A, (%s)", _value );
7830 outline1("LD BC, %s", _port );
7831 outline0("OUT (C), A" );
7832
7833}
7834
7835void cpu_in_direct( Environment * _environment, char * _port, char * _value ) {
7836
7837 outline1("LD BC, %s", _port );
7838 outline0("IN A, (C)" );
7839 outline1("LD (%s), A", _value );
7840
7841}
7842
7843void cpu_string_sub( Environment * _environment, char * _source, char * _source_size, char * _pattern, char * _pattern_size, char * _destination, char * _destination_size ) {
7844
7846
7847 inline( cpu_string_sub )
7848
7849 embedded( cpu_string_sub, src_hw_z80_cpu_string_sub_asm );
7850
7851 outline1("LD A, (%s)", _source);
7852 outline0("LD L, A");
7853 outline1("LD A, (%s)", address_displacement(_environment, _source, "1"));
7854 outline0("LD H, A");
7855 outline1("LD A, (%s)", _source_size);
7856 outline0("LD IYL, A");
7857
7858 outline1("LD A, (%s)", _pattern);
7859 outline0("LD IXL, A");
7860 outline1("LD A, (%s)", address_displacement(_environment, _pattern, "1"));
7861 outline0("LD IXH, A");
7862 outline1("LD A, (%s)", _pattern_size);
7863 outline0("LD IYH, A");
7864
7865 outline1("LD A, (%s)", _destination);
7866 outline0("LD E, A");
7867 outline1("LD A, (%s)", address_displacement(_environment, _destination, "1"));
7868 outline0("LD D, A");
7869
7870 outline0("CALL CPUSTRINGSUB");
7871
7872 outline0("LD A, IYL");
7873 outline1("LD (%s), A", _destination_size);
7874
7875 done()
7876}
7877
7878static char Z80_BLIT_REGISTER[][2] = {
7879 "L",
7880 "H",
7881 "E",
7882 "D"
7883};
7884
7885#define Z80_BLIT_REGISTER_COUNT ( sizeof( Z80_BLIT_REGISTER ) / 2 )
7886
7887void cpu_blit_initialize( Environment * _environment ) {
7888
7889 _environment->blit.freeRegisters = 0;
7890 _environment->blit.usedMemory = 0;
7891
7892 // outline0("; cpu_blit_initialize");
7893
7894 outline0("PUSH HL");
7895 outline0("PUSH DE");
7896
7897}
7898
7899void cpu_blit_finalize( Environment * _environment ) {
7900
7901 // outline0("; cpu_blit_finalize");
7902
7903 _environment->blit.freeRegisters = 0;
7904 _environment->blit.usedMemory = 0;
7905
7906 outline0("POP DE");
7907 outline0("POP HL");
7908
7909}
7910
7911char * cpu_blit_register_name( Environment * _environment, int _register ) {
7912
7913 if ( _register < Z80_BLIT_REGISTER_COUNT ) {
7914 return &Z80_BLIT_REGISTER[_register][0];
7915 } else {
7916 return &Z80_BLIT_REGISTER[ (_register & 0xff00) >> 8][0];
7917 }
7918}
7919
7921
7922 int reg = 0;
7923
7924 for( reg = 0; reg < Z80_BLIT_REGISTER_COUNT; ++reg ) {
7925 int registerMask = ( 0x01 << reg );
7926 int isRegisterUsed = _environment->blit.freeRegisters & registerMask;
7927 if ( ! isRegisterUsed ) {
7928 _environment->blit.freeRegisters |= registerMask;
7929 // printf( "cpu_blit_alloc_register() %4.4x -> $%4.4x\n", _environment->blit.freeRegisters, reg );
7930 // outline1("; cpu_blit_alloc_register = %d", reg );
7931 return reg;
7932 }
7933 }
7934
7935 int location = _environment->blit.usedMemory++;
7936
7937 if ( location > 0xff ) {
7939 }
7940
7941 for( reg = 0; reg < Z80_BLIT_REGISTER_COUNT; ++reg ) {
7942 int registerMask = ( 0x10 << reg );
7943 int isRegisterUsed = _environment->blit.freeRegisters & registerMask;
7944 if ( ! isRegisterUsed ) {
7945 outline1( "LD A, %s", &Z80_BLIT_REGISTER[reg][0] );
7946 outline2( "LD (%sbs+$%2.2x), A", _environment->blit.realName, location );
7947 _environment->blit.freeRegisters |= registerMask;
7948 // printf( "cpu_blit_alloc_register() -> %4.4x $%4.4x\n", _environment->blit.freeRegisters, ( ( reg << 8 ) | location ) );
7949 // outline1("; cpu_blit_alloc_register = %d", ( ( (reg+1) << 8 ) | location ) );
7950 return ( ( (reg+1) << 8 ) | location );
7951 }
7952 }
7953
7955
7956}
7957
7958void cpu_blit_free_register( Environment * _environment, int _register ) {
7959
7960 // outline1("; cpu_blit_free_register = %d", _register );
7961
7962 // printf( "cpu_blit_free_register($%4.4x)\n", _register );
7963
7964 int location = _register & 0xff;
7965 int reg;
7966
7967 if ( _register < Z80_BLIT_REGISTER_COUNT ) {
7968 int registerMask = ( 0x01 << _register );
7969 int isRegisterUsed = _environment->blit.freeRegisters & registerMask;
7970 if ( isRegisterUsed ) {
7971 _environment->blit.freeRegisters &= ~registerMask;
7972 return;
7973 } else {
7974 CRITICAL_BLIT_INVALID_FREE_REGISTER( _environment->blit.name, _register );
7975 }
7976 } else {
7977 int registerMask = 0x10 << ( ( ( _register >> 8 ) & 0xff ) - 1 );
7978 int isRegisterUsed = _environment->blit.freeRegisters & registerMask;
7979 if ( isRegisterUsed ) {
7980 outline2( "LD A, (%sbs+$%2.2x)", _environment->blit.realName, location );
7981 outline1( "LD %s, A", &Z80_BLIT_REGISTER[reg][0] );
7982 _environment->blit.freeRegisters &= ~registerMask;
7983 return;
7984 }
7985 }
7986
7987 CRITICAL_BLIT_INVALID_FREE_REGISTER( _environment->blit.name, _register );
7988
7989}
7990
7999void cpu_store_nbit( Environment * _environment, char *_destination, int _n, int _value[] ) {
8000
8001 int i = 0;
8002 while( _n ) {
8003 char destinationAddress[MAX_TEMPORARY_STORAGE]; sprintf( destinationAddress, "%s+%d", _destination, i*4 );
8004 if ( _n <= 32 ) {
8005 switch( _n ) {
8006 case 1: case 2: case 3: case 4:
8007 case 5: case 6: case 7: case 8:
8008 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff>>(8-_n)) ) );
8009 break;
8010 case 9: case 10: case 11: case 12:
8011 case 13: case 14: case 15: case 16:
8012 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff) ) );
8013 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
8014 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+1] & (0xff>>(16-_n)) ) );
8015 break;
8016 case 17: case 18: case 19: case 20:
8017 case 21: case 22: case 23: case 24:
8018 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff) ) );
8019 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
8020 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+1] & (0xff) ) );
8021 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
8022 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+2] & (0xff>>(24-_n)) ) );
8023 break;
8024 case 25: case 26: case 27: case 28:
8025 case 29: case 30: case 31: case 32:
8026 default:
8027 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff) ) );
8028 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
8029 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+1] & (0xff) ) );
8030 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
8031 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+2] & (0xff) ) );
8032 sprintf( destinationAddress, "%s+%d", _destination, i*4+3 );
8033 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+3] & (0xff>>(32-_n)) ) );
8034 break;
8035 }
8036 _n = 0;
8037 } else {
8038 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)] & (0xff) ) );
8039 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
8040 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+1] & (0xff) ) );
8041 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
8042 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+2] & (0xff) ) );
8043 sprintf( destinationAddress, "%s+%d", _destination, i*4+3 );
8044 cpu_store_8bit( _environment, destinationAddress, ( _value[(i*4)+3] & (0xff>>(32-_n)) ) );
8045 _n -= 32;
8046 }
8047 ++i;
8048 }
8049
8050}
8051
8060void cpu_move_nbit( Environment * _environment, int _n, char * _source, char *_destination ) {
8061
8062 int i = 0;
8063 while( _n ) {
8064 char sourceAddress[MAX_TEMPORARY_STORAGE]; sprintf( sourceAddress, "%s+%d", _source, i*4 );
8065 char destinationAddress[MAX_TEMPORARY_STORAGE]; sprintf( destinationAddress, "%s+%d", _destination, i*4 );
8066 if ( _n <= 32 ) {
8067 switch( _n ) {
8068 case 1: case 2: case 3: case 4:
8069 case 5: case 6: case 7: case 8:
8070 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8071 break;
8072 case 9: case 10: case 11: case 12:
8073 case 13: case 14: case 15: case 16:
8074 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8075 sprintf( sourceAddress, "%s+%d", _source, i*4+1 );
8076 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
8077 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8078 break;
8079 case 17: case 18: case 19: case 20:
8080 case 21: case 22: case 23: case 24:
8081 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8082 sprintf( sourceAddress, "%s+%d", _source, i*4+1 );
8083 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
8084 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8085 sprintf( sourceAddress, "%s+%d", _source, i*4+2 );
8086 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
8087 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8088 break;
8089 case 25: case 26: case 27: case 28:
8090 case 29: case 30: case 31: case 32:
8091 default:
8092 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8093 sprintf( sourceAddress, "%s+%d", _source, i*4+1 );
8094 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
8095 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8096 sprintf( sourceAddress, "%s+%d", _source, i*4+2 );
8097 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
8098 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8099 sprintf( sourceAddress, "%s+%d", _source, i*4+3 );
8100 sprintf( destinationAddress, "%s+%d", _destination, i*4+3 );
8101 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8102 break;
8103 }
8104 _n = 0;
8105 } else {
8106 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8107 sprintf( sourceAddress, "%s+%d", _source, i*4+1 );
8108 sprintf( destinationAddress, "%s+%d", _destination, i*4+1 );
8109 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8110 sprintf( sourceAddress, "%s+%d", _source, i*4+2 );
8111 sprintf( destinationAddress, "%s+%d", _destination, i*4+2 );
8112 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8113 sprintf( sourceAddress, "%s+%d", _source, i*4+3 );
8114 sprintf( destinationAddress, "%s+%d", _destination, i*4+3 );
8115 cpu_move_8bit( _environment, sourceAddress, destinationAddress );
8116 _n -= 32;
8117 }
8118 ++i;
8119 }
8120
8121}
8122
8123
8124// [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
8125// FAST (24) seeeeeee mmmmmmmm mmmmmmmm
8126
8127void cpu_float_fast_from_double_to_int_array( Environment * _environment, double _value, int _result[] ) {
8128
8129 double value = 0.0;
8130 double integral = 0.0;
8131 double fractional = 0.0;
8132 int sign = 0;
8133 int left = 0;
8134 int right[2];
8135 int steps = 0;
8136 int exp = 0;
8137 int mantissa_bits = 16;
8138
8139 memset( &right[0], 0, sizeof( int ) * 2 );
8140
8141 // Step 1: Determine Sign
8142 // If the number is positive, then the sign bit will be 0. If the number is negative, then the sign bit
8143 // will be 1. For the number zero, both positive and negative zero are possible, and these are considered
8144 // different values (a quirk of using sign bits).
8145
8146 if ( _value >= 0 ) {
8147 sign = 0;
8148 } else {
8149 sign = 1;
8150 }
8151
8152 value = fabs( _value );
8153
8154 // Step 2: Convert the Integral Portion to Unsigned Binary
8155 // Convert the integral portion of the floating-point value to unsigned binary (not two's complement).
8156 // The integral portion is the part of the number before the decimal point. For example, if the
8157 // number to convert is -0.75, then 0 is the integral portion, and it's unsigned binary representation
8158 // is simply 0. As another example, if the number to convert is 127.99, then the integral portion would
8159 // be 127, and it's unsigned binary representation is 1111111.
8160
8161 fractional = modf(value, &integral);
8162
8163 left = (unsigned int) integral;
8164
8165 // Step 3: Convert the Fractional Portion to Binary
8166 // The fractional portion of the number must also be converted to binary, though the conversion process
8167 // is much different from what you're used to. The algorithm you'll used is based on performing repeated
8168 // multiplications by 2, and then checking if the result is >= 1.0. If the result is >= 1.0, then a 1 is
8169 // recorded for the binary fractional component, and the leading 1 is chopped of the result. If the
8170 // result is < 1.0, then a 0 is recorded for the binary fractional component, and the result is kept
8171 // as-is. The recorded builds are built-up left-to-right. The result keeps getting chained along in this
8172 // way until one of the following is true:
8173 // - The result is exactly 1.0
8174 // - 23 iterations of this process have occurred; i.e. the final converted binary value holds 23 bits
8175 // With the first possible terminating condition (the result is exactly 1.0), this means that the fractional
8176 // component has been represented without any loss of precision. With the second possible terminating
8177 // condition (23 iterations have passed), this means that we ran out of bits in the final result, which
8178 // can never exceed 23. In this case, precision loss occurs (an unfortunate consequence of using a finite
8179 // number of bits).
8180
8181 while( ( fractional != 1.0 ) && ( steps < mantissa_bits ) ) {
8182
8183 // printf("%f %d %2.2x %2.2x\n", fractional, steps, (unsigned char) right[0], (unsigned char) right[1] );
8184
8185 right[1] = right[1] << 1;
8186 right[0] = right[0] << 1;
8187 if ( ( right[1] & 0x100 ) ) {
8188 right[0] = right[0] | 0x1;
8189 }
8190 right[1] = right[1] & 0xff;
8191 right[0] = right[0] & 0xff;
8192
8193 fractional = fractional * 2;
8194
8195 if ( fractional >= 1.0 ) {
8196 right[1] |= 1;
8197 fractional = modf(fractional, &integral);
8198 }
8199
8200 ++steps;
8201
8202 }
8203
8204 // Step 4: Normalize the Value via Adjusting the Exponent
8205 // A trick to encode an extra bit is to make it so that the binary scientific representation is always
8206 // of the form 1.XXXX * 2YYYY. That is, a 1 always leads, so there is no need to explicitly encode it.
8207 // In order to encode this properly, we need to move the decimal point to a position where it is
8208 // immediately after the first 1, and then record exactly how we moved it. To see this in action, consider
8209 // again the example of 0.75, which is encoded in binary as such (not IEEE-754 notation):
8210 // 0.11
8211 // 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:
8212 // 1.1
8213 // Most importantly, we need to record that we moved the decimal point by one position to the right.
8214 // Moves to the right result in negative exponents, and moves to the left result in positive exponents.
8215 // In this case, because we moved the decimal point one position to the right, the recorded exponent should be -1.
8216 // As another example, consider the following binary floating point representation (again, not IEEE-754):
8217 // 1111111.11100
8218 // 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:
8219 // 1.11111111100
8220 // Because this moves six positions to the left, the recorded exponent should be 6.
8221
8222 int mantissa_high_bit = 0x80000000 >> ( 32 - mantissa_bits);
8223 int mantissa_mask = 0xffffffff >> ( 32 - mantissa_bits);
8224
8225 if ( left == 0 ) {
8226
8227 if ( value != 0 ) {
8228
8229 while( left == 0 ) {
8230
8231 // printf("exp = %d left = %2.2x right = %2.2x %2.2x\n", exp, (unsigned char) left, (unsigned char) right[0], (unsigned char) right[1] );
8232
8233 if ( ! right[0] && ! right[1] && ! right[2] ) {
8234 left = 0x1;
8235 }
8236
8237 if ( right[0] & 0x80 ) {
8238 left = 0x1;
8239 }
8240
8241 right[0] = right[0] << 1;
8242 right[1] = right[1] << 1;
8243 if ( ( right[1] & 0x100 )) {
8244 right[0] = right[0] | 0x1;
8245 }
8246 right[0] = right[0] & 0xff;
8247 right[1] = right[1] & 0xff;
8248
8249 --exp;
8250 }
8251
8252 } else {
8253
8254 exp = -63;
8255
8256 }
8257
8258 // printf("exp = %d left = %2.2x right = %2.2x %2.2x\n", exp, (unsigned char) left, (unsigned char) right[0], (unsigned char) right[1] );
8259
8260 } else {
8261
8262 while( left ) {
8263
8264 // printf("left = %8.8x right = %2.2x %2.2x\n", left, (unsigned char) right[0], (unsigned char) right[1] );
8265
8266 if ( ( right[0] & 0x01 ) ) {
8267 right[1] = right[1] | 0x100;
8268 }
8269 right[0] = right[0] >> 1;
8270 right[1] = right[1] >> 1;
8271 if ( left & 0x1 ) {
8272 right[0] = right[0] | 0x80;
8273 }
8274 left = left >> 1;
8275 ++exp;
8276 }
8277 --exp;
8278 left = 1;
8279 right[1] = right[1] << 1;
8280 right[0] = right[0] << 1;
8281 if ( right[1] & 0x100 ) {
8282 right[0] = right[0] | 0x01;
8283 }
8284 right[1] = right[1] & 0xff;
8285 right[0] = right[0] & 0xff;
8286
8287 }
8288
8289 // Step 5: Add Bias to the Exponent
8290 // Internally, IEEE-754 values store their exponents in an unsigned representation, which may seem odd considering that
8291 // the exponent can be negative. Negative exponents are accomodated by using a biased representation, wherein a
8292 // pre-set number is always subtracted from the given unsigned number. Because the given unsigned number may be less
8293 // than this number, this allows for negative values to be effectively encoded without resorting to two's complement.
8294 // Specifically, for the binary32 representation, the number 127 will be subtracted from anything encoded in the
8295 // exponent field of the IEEE-754 number. As such, in this step, we need to add 127 to the normalized exponent value
8296 // from the previous step.
8297
8298 exp += 63;
8299
8300 // printf("exp = %2.2x\n", exp );
8301
8302 // Step 6: Convert the Biased Exponent to Unsigned Binary
8303 // The biased exponent value from the previous step must be converted into unsigned binary, using the usual process.
8304 // The result must be exactly 8 bits. It should not be possible to need more than 8 bits. If fewer than 8 bits are
8305 // needed in this conversion process, then leading zeros must be added to the front of the result to produce an
8306 // 8-bit value.
8307
8308 exp = exp & 0xff;
8309
8310 // printf("exp = %2.2x\n", exp );
8311
8312 // Step 7: Determine the Final Bits for the Mantissa
8313 // After step 4, there are a bunch of bits after the normalized decimal point. These bits will become the
8314 // mantissa (note that we ignore the bits to the left of the decimal point - normalization allows us to do this,
8315 // because it should always be just a 1). We need exactly 23 mantissa bits. If less than 23 mantissa bits follow the
8316 // decimal point, and the algorithm in step 3 ended with a result that wasn't 1.0, then follow the algorithm in step 3
8317 // until we can fill enough bits. If that's still not enough (eventually reaching 1.0 before we had enough bits, or
8318 // perhaps it had ended with 1.0 already), then the right side can be padded with zeros until 23 bits is reached.
8319 // If there are more than 23 bits after the decimal point in step 4, then these extra bits are simply cutoff from the
8320 // right. For example, if we had 26 bits to the right of the decimal point, then the last three would need to be cutoff
8321 // to get us to 23 bits. Note that in this case we will necessarily lose some precision.
8322
8323 // Step 8: Put it All Together
8324 // 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
8325 // step 6. The last 23 bits will be from the mantissa from step 7. The result will be a 32-bit number encoded in
8326 // IEEE-754 binary32 format, assuming no mistakes were made in the process.
8327
8328 // [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
8329 // FAST (24) seeeeeee mmmmmmmm mmmmmmmm
8330
8331 _result[0] = ( sign << 7 ) | ( exp & 0x7f );
8332 _result[1] = ( right[0] );
8333 _result[2] = ( right[1] );
8334
8335 // printf( "%2.2x %2.2x %2.2x\n", _result[0], _result[1], _result[2] );
8336
8337}
8338
8339//
8340// [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
8341// SINGLE (32) seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
8342//
8343
8344void cpu_float_single_from_double_to_int_array( Environment * _environment, double _value, int _result[] ) {
8345
8346 double value = 0.0;
8347 double integral = 0.0;
8348 double fractional = 0.0;
8349 int sign = 0;
8350 int left = 0;
8351 int right[3];
8352 int steps = 0;
8353 int exp = 0;
8354 int mantissa_bits = 23;
8355
8356 memset( &right[0], 0, sizeof( int ) * 3 );
8357
8358 // Step 1: Determine Sign
8359 // If the number is positive, then the sign bit will be 0. If the number is negative, then the sign bit
8360 // will be 1. For the number zero, both positive and negative zero are possible, and these are considered
8361 // different values (a quirk of using sign bits).
8362
8363 if ( _value >= 0 ) {
8364 sign = 0;
8365 } else {
8366 sign = 1;
8367 }
8368
8369 value = fabs( _value );
8370
8371 // Step 2: Convert the Integral Portion to Unsigned Binary
8372 // Convert the integral portion of the floating-point value to unsigned binary (not two's complement).
8373 // The integral portion is the part of the number before the decimal point. For example, if the
8374 // number to convert is -0.75, then 0 is the integral portion, and it's unsigned binary representation
8375 // is simply 0. As another example, if the number to convert is 127.99, then the integral portion would
8376 // be 127, and it's unsigned binary representation is 1111111.
8377
8378 fractional = modf(value, &integral);
8379
8380 left = (unsigned int) integral;
8381
8382 // Step 3: Convert the Fractional Portion to Binary
8383 // The fractional portion of the number must also be converted to binary, though the conversion process
8384 // is much different from what you're used to. The algorithm you'll used is based on performing repeated
8385 // multiplications by 2, and then checking if the result is >= 1.0. If the result is >= 1.0, then a 1 is
8386 // recorded for the binary fractional component, and the leading 1 is chopped of the result. If the
8387 // result is < 1.0, then a 0 is recorded for the binary fractional component, and the result is kept
8388 // as-is. The recorded builds are built-up left-to-right. The result keeps getting chained along in this
8389 // way until one of the following is true:
8390 // - The result is exactly 1.0
8391 // - 23 iterations of this process have occurred; i.e. the final converted binary value holds 23 bits
8392 // With the first possible terminating condition (the result is exactly 1.0), this means that the fractional
8393 // component has been represented without any loss of precision. With the second possible terminating
8394 // condition (23 iterations have passed), this means that we ran out of bits in the final result, which
8395 // can never exceed 23. In this case, precision loss occurs (an unfortunate consequence of using a finite
8396 // number of bits).
8397
8398 while( ( fractional != 1.0 ) && ( steps < mantissa_bits ) ) {
8399
8400 // printf("%f %d %2.2x %2.2x %2.2x\n", fractional, steps, (unsigned char) right[0], (unsigned char) right[1], (unsigned char) right[2] );
8401
8402 right[2] = right[2] << 1;
8403 right[1] = right[1] << 1;
8404 right[0] = right[0] << 1;
8405 if ( ( right[2] & 0x100 ) ) {
8406 right[1] = right[1] | 0x1;
8407 }
8408 if ( ( right[1] & 0x100 ) ) {
8409 right[0] = right[0] | 0x1;
8410 }
8411 right[2] = right[2] & 0xff;
8412 right[1] = right[1] & 0xff;
8413 right[0] = right[0] & 0x7f;
8414
8415 fractional = fractional * 2;
8416
8417 if ( fractional >= 1.0 ) {
8418 right[2] |= 1;
8419 fractional = modf(fractional, &integral);
8420 }
8421
8422 ++steps;
8423
8424 }
8425
8426 // Step 4: Normalize the Value via Adjusting the Exponent
8427 // A trick to encode an extra bit is to make it so that the binary scientific representation is always
8428 // of the form 1.XXXX * 2YYYY. That is, a 1 always leads, so there is no need to explicitly encode it.
8429 // In order to encode this properly, we need to move the decimal point to a position where it is
8430 // immediately after the first 1, and then record exactly how we moved it. To see this in action, consider
8431 // again the example of 0.75, which is encoded in binary as such (not IEEE-754 notation):
8432 // 0.11
8433 // 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:
8434 // 1.1
8435 // Most importantly, we need to record that we moved the decimal point by one position to the right.
8436 // Moves to the right result in negative exponents, and moves to the left result in positive exponents.
8437 // In this case, because we moved the decimal point one position to the right, the recorded exponent should be -1.
8438 // As another example, consider the following binary floating point representation (again, not IEEE-754):
8439 // 1111111.11100
8440 // 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:
8441 // 1.11111111100
8442 // Because this moves six positions to the left, the recorded exponent should be 6.
8443
8444 int mantissa_high_bit = 0x80000000 >> ( 32 - mantissa_bits);
8445 int mantissa_mask = 0xffffffff >> ( 32 - mantissa_bits);
8446
8447 if ( left == 0 ) {
8448
8449 if ( value != 0 ) {
8450
8451 while( left == 0 ) {
8452
8453 // 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] );
8454
8455 if ( right[0] & 0x40 ) {
8456 left = 0x1;
8457 }
8458
8459 right[0] = right[0] << 1;
8460 right[1] = right[1] << 1;
8461 right[2] = right[2] << 1;
8462 if ( ( right[1] & 0x100 )) {
8463 right[0] = right[0] | 0x1;
8464 }
8465 if ( ( right[2] & 0x100 )) {
8466 right[1] = right[1] | 0x1;
8467 }
8468 right[0] = right[0] & 0x7f;
8469 right[1] = right[1] & 0xff;
8470 right[2] = right[2] & 0xff;
8471
8472 --exp;
8473 }
8474
8475 } else {
8476
8477 exp = -127;
8478
8479 }
8480
8481 // 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] );
8482
8483 } else {
8484
8485 while( left ) {
8486
8487 // 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] );
8488
8489 if ( ( right[0] & 0x01 ) ) {
8490 right[1] = right[1] | 0x100;
8491 }
8492 if ( ( right[1] & 0x01 ) ) {
8493 right[2] = right[2] | 0x100;
8494 }
8495 right[0] = right[0] >> 1;
8496 right[1] = right[1] >> 1;
8497 // right[2] = right[2] >> 1;
8498 if ( left & 0x1 ) {
8499 right[0] = right[0] | 0x40;
8500 }
8501 left = left >> 1;
8502 ++exp;
8503 }
8504 --exp;
8505 left = 1;
8506 right[2] = right[2] << 1;
8507 right[1] = right[1] << 1;
8508 right[0] = right[0] << 1;
8509 if ( right[2] & 0x100 ) {
8510 right[1] = right[1] | 0x01;
8511 }
8512 if ( right[1] & 0x100 ) {
8513 right[0] = right[0] | 0x01;
8514 }
8515 right[2] = right[2] & 0xff;
8516 right[1] = right[1] & 0xff;
8517 right[0] = right[0] & 0x7f;
8518
8519 }
8520
8521 // Step 5: Add Bias to the Exponent
8522 // Internally, IEEE-754 values store their exponents in an unsigned representation, which may seem odd considering that
8523 // the exponent can be negative. Negative exponents are accomodated by using a biased representation, wherein a
8524 // pre-set number is always subtracted from the given unsigned number. Because the given unsigned number may be less
8525 // than this number, this allows for negative values to be effectively encoded without resorting to two's complement.
8526 // Specifically, for the binary32 representation, the number 127 will be subtracted from anything encoded in the
8527 // exponent field of the IEEE-754 number. As such, in this step, we need to add 127 to the normalized exponent value
8528 // from the previous step.
8529
8530 exp += 127;
8531
8532 // printf("exp = %2.2x\n", exp );
8533
8534 // Step 6: Convert the Biased Exponent to Unsigned Binary
8535 // The biased exponent value from the previous step must be converted into unsigned binary, using the usual process.
8536 // The result must be exactly 8 bits. It should not be possible to need more than 8 bits. If fewer than 8 bits are
8537 // needed in this conversion process, then leading zeros must be added to the front of the result to produce an
8538 // 8-bit value.
8539
8540 exp = exp & 0xff;
8541
8542 // printf("exp = %2.2x\n", exp );
8543
8544 // Step 7: Determine the Final Bits for the Mantissa
8545 // After step 4, there are a bunch of bits after the normalized decimal point. These bits will become the
8546 // mantissa (note that we ignore the bits to the left of the decimal point - normalization allows us to do this,
8547 // because it should always be just a 1). We need exactly 23 mantissa bits. If less than 23 mantissa bits follow the
8548 // decimal point, and the algorithm in step 3 ended with a result that wasn't 1.0, then follow the algorithm in step 3
8549 // until we can fill enough bits. If that's still not enough (eventually reaching 1.0 before we had enough bits, or
8550 // perhaps it had ended with 1.0 already), then the right side can be padded with zeros until 23 bits is reached.
8551 // If there are more than 23 bits after the decimal point in step 4, then these extra bits are simply cutoff from the
8552 // right. For example, if we had 26 bits to the right of the decimal point, then the last three would need to be cutoff
8553 // to get us to 23 bits. Note that in this case we will necessarily lose some precision.
8554
8555 // Step 8: Put it All Together
8556 // 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
8557 // step 6. The last 23 bits will be from the mantissa from step 7. The result will be a 32-bit number encoded in
8558 // IEEE-754 binary32 format, assuming no mistakes were made in the process.
8559
8560 // [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
8561 // SINGLE (32) seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
8562
8563 _result[3] = ( sign << 7 ) | ( ( exp >> 1 ) & 0x7f );
8564 _result[2] = ( ( exp & 0x01 ) << 7 ) | ( right[0] );
8565 _result[1] = ( right[1] );
8566 _result[0] = ( right[2] );
8567
8568 // printf( "%2.2x %2.2x %2.2x %2.2x\n", _result[0], _result[1], _result[2], _result[3] );
8569
8570}
8571
8572//
8573// [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
8574// EXTENDED (80) seeeeeee eeeeeeee mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
8575//
8576
8577void cpu_float_double_from_double_to_int_array( Environment * _environment, double _value, int _result[] ) {
8578
8579}
8580
8581void cpu_float_fast_to_string( Environment * _environment, char * _x, char * _string, char * _string_size ) {
8582
8584
8585 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8586 deploy( fp_mul16, src_hw_z80_fp_mul16_asm );
8587 deploy( fp_fast_mul, src_hw_z80_fp_fast_mul_asm );
8588 deploy( fp_fast_pow10_lut, src_hw_z80_fp_fast_pow10_lut_asm );
8589 deploy( fp_format_str, src_hw_z80_fp_format_str_asm );
8590 deploy( fp_fast_to_string, src_hw_z80_fp_fast_to_string_asm );
8591
8592 // ;converts a 24-bit float to a string
8593
8594 // ;Inputs:
8595 // ; AHL is the float to convert
8596
8597 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+2" ) );
8598 outline0( "LD L, A" );
8599 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+1" ) );
8600 outline0( "LD H, A" );
8601 outline1( "LD A, (%s)", _x );
8602
8603 // ; DE points to where to write the string
8604 outline1( "LD DE, (%s)", _string );
8605
8606 outline0( "CALL FPFASTTOA" );
8607
8608 // ;Output:
8609 // ; HL pointing to the string
8610 outline0( "PUSH HL" );
8611 outline0( "POP DE" );
8612 outhead1( "%s:", label );
8613 outline0( "LD A, (DE)" );
8614 outline0( "CP 0" );
8615 outline1( "JR Z, %sdone", label );
8616 outline0( "INC DE" );
8617 outline0( "INC C" );
8618 outline1( "JR %s", label );
8619 outhead1( "%sdone:", label );
8620 outline0( "LD A, C" );
8621 outline1( "LD (%s), A", _string_size );
8622
8623 // ;Destroys:
8624 // ; A,DE,BC
8625 // ;Notes:
8626 // ; Uses up to 12 bytes to store the string
8627
8628}
8629
8630void cpu_float_single_to_string( Environment * _environment, char * _x, char * _string, char * _string_size ) {
8631
8633
8634 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8635 deploy( fp_pushpop, src_hw_z80_fp_pushpop_asm );
8636 deploy( fp_c_times_bde, src_hw_z80_fp_c_times_bde_asm );
8637 deploy( fp_mul24_stack_based, src_hw_z80_fp_mul24_stack_based_asm );
8638 deploy( fp_single_pow10_lut, src_hw_z80_fp_single_pow10_lut_asm );
8639 deploy( fp_single_mul, src_hw_z80_fp_single_mul_asm );
8640 deploy( fp_mov4, src_hw_z80_fp_mov4_asm );
8641 deploy( fp_common_str, src_hw_z80_fp_common_str_asm );
8642 deploy( fp_format_str, src_hw_z80_fp_format_str_asm );
8643 deploy( fp_single_to_string, src_hw_z80_fp_single_to_string_asm );
8644
8645 // ;converts a 32-bit float to a string
8646
8647 // ;Inputs:
8648 // ; HL points to the input float
8649 // ; BC points to where the string gets written.
8650
8651 outline1( "LD HL, %s", _x );
8652
8653 outline1( "LD BC, (%s)", _string );
8654
8655 outline0( "CALL FPSINGLETOA" );
8656
8657 // ;Output:
8658 // ; HL pointing to the string
8659 outline0( "PUSH HL" );
8660 outline0( "POP DE" );
8661 outhead1( "%s:", label );
8662 outline0( "LD A, (DE)" );
8663 outline0( "CP 0" );
8664 outline1( "JR Z, %sdone", label );
8665 outline0( "INC DE" );
8666 outline0( "INC C" );
8667 outline1( "JR %s", label );
8668 outhead1( "%sdone:", label );
8669 outline0( "LD A, C" );
8670 outline1( "LD (%s), A", _string_size );
8671
8672}
8673
8674void cpu_float_double_to_string( Environment * _environment, char * _x, char * _string, char * _string_size ) {
8675
8676}
8677
8678void cpu_float_fast_from_16( Environment * _environment, char * _value, char * _result, int _signed ) {
8679
8680 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8681 deploy( fp_fast_from_16, src_hw_z80_fp_fast_from_16_asm );
8682
8683 outline1( "LD HL, (%s)", _value );
8684 if ( _signed ) {
8685 outline0( "CALL FPFASTFROM16S");
8686 } else {
8687 outline0( "CALL FPFASTFROM16U");
8688 }
8689 outline1( "LD (%s), A", _result );
8690 outline0( "LD A, H" );
8691 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
8692 outline0( "LD A, L" );
8693 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
8694
8695}
8696
8697void cpu_float_fast_from_8( Environment * _environment, char * _value, char * _result, int _signed ) {
8698
8699 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8700 deploy( fp_fast_from_8, src_hw_z80_fp_fast_from_8_asm );
8701
8702 outline1( "LD A, (%s)", _value );
8703 if ( _signed ) {
8704 outline0( "CALL FPFASTFROM8S");
8705 } else {
8706 outline0( "CALL FPFASTFROM8U");
8707 }
8708 outline1( "LD (%s), A", _result );
8709 outline0( "LD A, H" );
8710 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
8711 outline0( "LD A, L" );
8712 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
8713
8714}
8715
8716void cpu_float_fast_to_16( Environment * _environment, char * _value, char * _result, int _signed ) {
8717
8718 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8719 deploy( fp_fast_to_16, src_hw_z80_fp_fast_to_16_asm );
8720
8721 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+2" ) );
8722 outline0( "LD L, A" );
8723 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+1" ) );
8724 outline0( "LD H, A" );
8725 outline1( "LD A, (%s)", _value );
8726 if ( _signed ) {
8727 outline0( "CALL FPFASTTOS16");
8728 } else {
8729 outline0( "CALL FPFASTTOU16");
8730 }
8731 outline1( "LD (%s), HL", _result );
8732
8733}
8734
8735void cpu_float_fast_to_8( Environment * _environment, char * _value, char * _result, int _signed ) {
8736
8737 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8738 deploy( fp_fast_to_8, src_hw_z80_fp_fast_to_8_asm );
8739
8740 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+2" ) );
8741 outline0( "LD L, A" );
8742 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+1" ) );
8743 outline0( "LD H, A" );
8744 outline1( "LD A, (%s)", _value );
8745 if ( _signed ) {
8746 outline0( "CALL FPFASTTOS8");
8747 } else {
8748 outline0( "CALL FPFASTTOU8");
8749 }
8750 outline1( "LD (%s), A", _result );
8751
8752}
8753
8754void cpu_float_fast_add( Environment * _environment, char * _x, char * _y, char * _result ) {
8755
8756 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8757 deploy( fp_fast_add, src_hw_z80_fp_fast_add_asm );
8758
8759 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+2" ) );
8760 outline0( "LD E, A" );
8761 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+1" ) );
8762 outline0( "LD D, A" );
8763 outline1( "LD A, (%s)", _y );
8764 outline0( "LD C, A" );
8765
8766 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+2" ) );
8767 outline0( "LD L, A" );
8768 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+1" ) );
8769 outline0( "LD H, A" );
8770 outline1( "LD A, (%s)", _x );
8771 outline0( "CALL FPFASTADD");
8772 outline1( "LD (%s), A", _result );
8773 outline0( "LD A, H" );
8774 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
8775 outline0( "LD A, L" );
8776 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
8777
8778}
8779
8780void cpu_float_fast_sub( Environment * _environment, char * _x, char * _y, char * _result ) {
8781
8782 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8783 deploy( fp_fast_add, src_hw_z80_fp_fast_add_asm );
8784 deploy( fp_fast_sub, src_hw_z80_fp_fast_sub_asm );
8785
8786 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+2" ) );
8787 outline0( "LD E, A" );
8788 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+1" ) );
8789 outline0( "LD D, A" );
8790 outline1( "LD A, (%s)", _y );
8791 outline0( "LD C, A" );
8792
8793 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+2" ) );
8794 outline0( "LD L, A" );
8795 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+1" ) );
8796 outline0( "LD H, A" );
8797 outline1( "LD A, (%s)", _x );
8798 outline0( "CALL FPFASTSUB");
8799 outline1( "LD (%s), A", _result );
8800 outline0( "LD A, H" );
8801 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
8802 outline0( "LD A, L" );
8803 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
8804
8805}
8806
8807void cpu_float_fast_mul( Environment * _environment, char * _x, char * _y, char * _result ) {
8808
8809 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8810 deploy( fp_mul16, src_hw_z80_fp_mul16_asm );
8811 deploy( fp_fast_mul, src_hw_z80_fp_fast_mul_asm );
8812
8813 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+2" ) );
8814 outline0( "LD E, A" );
8815 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+1" ) );
8816 outline0( "LD D, A" );
8817 outline1( "LD A, (%s)", _y );
8818 outline0( "LD C, A" );
8819 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+2" ) );
8820 outline0( "LD L, A" );
8821 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+1" ) );
8822 outline0( "LD H, A" );
8823 outline1( "LD A, (%s)", _x );
8824 outline0( "CALL FPFASTMUL");
8825 outline1( "LD (%s), A", _result );
8826 outline0( "LD A, H" );
8827 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
8828 outline0( "LD A, L" );
8829 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
8830
8831}
8832
8833void cpu_float_fast_div( Environment * _environment, char * _x, char * _y, char * _result ) {
8834
8835 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8836 deploy( fp_fast_div, src_hw_z80_fp_fast_div_asm );
8837
8838 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+2" ) );
8839 outline0( "LD E, A" );
8840 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+1" ) );
8841 outline0( "LD D, A" );
8842 outline1( "LD A, (%s)", _y );
8843 outline0( "LD C, A" );
8844 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+2" ) );
8845 outline0( "LD L, A" );
8846 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+1" ) );
8847 outline0( "LD H, A" );
8848 outline1( "LD A, (%s)", _x );
8849 outline0( "CALL FPFASTDIV");
8850 outline1( "LD (%s), A", _result );
8851 outline0( "LD A, H" );
8852 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
8853 outline0( "LD A, L" );
8854 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
8855
8856}
8857
8858void cpu_float_fast_cmp( Environment * _environment, char * _x, char * _y, char * _result ) {
8859
8861
8862 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8863 deploy( fp_fast_add, src_hw_z80_fp_fast_add_asm );
8864 deploy( fp_fast_sub, src_hw_z80_fp_fast_sub_asm );
8865 deploy( fp_fast_cmp, src_hw_z80_fp_fast_cmp_asm );
8866
8867 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+2" ) );
8868 outline0( "LD E, A" );
8869 outline1( "LD A, (%s)", address_displacement( _environment, _y, "+1" ) );
8870 outline0( "LD D, A" );
8871 outline1( "LD A, (%s)", _y );
8872 outline0( "LD C, A" );
8873 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+2" ) );
8874 outline0( "LD L, A" );
8875 outline1( "LD A, (%s)", address_displacement( _environment, _x, "+1" ) );
8876 outline0( "LD H, A" );
8877 outline1( "LD A, (%s)", _x );
8878 outline0( "CALL FPFASTCMP");
8879
8880 outline1( "JR Z, %sequal", label );
8881 outline1( "JR C, %sless", label );
8882 outline0( "LD A, 1" );
8883 outline1( "LD (%s), A", _result );
8884 outline1( "JP %sdone", label );
8885 outhead1( "%sequal:", label );
8886 outline0( "LD A, 0" );
8887 outline1( "LD (%s), A", _result );
8888 outline1( "JP %sdone", label );
8889 outhead1( "%sless:", label );
8890 outline0( "LD A, $ff" );
8891 outline1( "LD (%s), A", _result );
8892 outline1( "JP %sdone", label );
8893 outhead1( "%sdone:", label );
8894
8895}
8896
8897void cpu_float_fast_sin( Environment * _environment, char * _angle, char * _result ) {
8898
8900
8901 deploy( fp_mul16, src_hw_z80_fp_mul16_asm );
8902 deploy( fp_fast_add, src_hw_z80_fp_fast_add_asm );
8903 deploy( fp_fast_sub, src_hw_z80_fp_fast_sub_asm );
8904 deploy( fp_fast_mod1, src_hw_z80_fp_fast_mod1_asm );
8905 deploy( fp_fast_sin, src_hw_z80_fp_fast_sin_asm );
8906 deploy( fp_fast_mul, src_hw_z80_fp_fast_mul_asm );
8907 deploy( fp_fast_sqr, src_hw_z80_fp_fast_sqr_asm );
8908 deploy( fp_fast_cos, src_hw_z80_fp_fast_cos_asm );
8909 deploy( fp_fast_div, src_hw_z80_fp_fast_div_asm );
8910
8911 outline1( "LD A, (%s)", address_displacement( _environment, _angle, "+2" ) );
8912 outline0( "LD L, A" );
8913 outline1( "LD A, (%s)", address_displacement( _environment, _angle, "+1" ) );
8914 outline0( "LD H, A" );
8915 outline1( "LD A, (%s)", _angle );
8916
8917 outline0( "CALL FPFASTSIN");
8918
8919 outline1( "LD (%s), A", _result );
8920 outline0( "LD A, H" );
8921 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
8922 outline0( "LD A, L" );
8923 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
8924
8925}
8926
8927void cpu_float_fast_cos( Environment * _environment, char * _angle, char * _result ) {
8928
8930
8931 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8932 deploy( fp_mul16, src_hw_z80_fp_mul16_asm );
8933 deploy( fp_fast_add, src_hw_z80_fp_fast_add_asm );
8934 deploy( fp_fast_sub, src_hw_z80_fp_fast_sub_asm );
8935 deploy( fp_fast_mod1, src_hw_z80_fp_fast_mod1_asm );
8936 deploy( fp_fast_mul, src_hw_z80_fp_fast_mul_asm );
8937 deploy( fp_fast_sqr, src_hw_z80_fp_fast_sqr_asm );
8938 deploy( fp_fast_sin, src_hw_z80_fp_fast_cos_asm );
8939 deploy( fp_fast_cos, src_hw_z80_fp_fast_sin_asm );
8940
8941 outline1( "LD A, (%s)", address_displacement( _environment, _angle, "+2" ) );
8942 outline0( "LD L, A" );
8943 outline1( "LD A, (%s)", address_displacement( _environment, _angle, "+1" ) );
8944 outline0( "LD H, A" );
8945 outline1( "LD A, (%s)", _angle );
8946
8947 outline0( "CALL FPFASTCOS");
8948
8949 outline1( "LD (%s), A", _result );
8950 outline0( "LD A, H" );
8951 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
8952 outline0( "LD A, L" );
8953 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
8954
8955}
8956
8957void cpu_float_fast_tan( Environment * _environment, char * _angle, char * _result ) {
8958
8960
8961 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8962 deploy( fp_fast_add, src_hw_z80_fp_fast_add_asm );
8963 deploy( fp_fast_tan, src_hw_z80_fp_fast_tan_asm );
8964 deploy( fp_fast_sin, src_hw_z80_fp_fast_sin_asm );
8965 deploy( fp_fast_cos, src_hw_z80_fp_fast_cos_asm );
8966 deploy( fp_fast_div, src_hw_z80_fp_fast_div_asm );
8967 deploy( fp_fast_mod1, src_hw_z80_fp_fast_mod1_asm );
8968 deploy( fp_fast_add, src_hw_z80_fp_fast_add_asm );
8969 deploy( fp_fast_sub, src_hw_z80_fp_fast_sub_asm );
8970 deploy( fp_fast_sqr, src_hw_z80_fp_fast_sqr_asm );
8971
8972 outline1( "LD A, (%s)", address_displacement( _environment, _angle, "+2" ) );
8973 outline0( "LD L, A" );
8974 outline1( "LD A, (%s)", address_displacement( _environment, _angle, "+1" ) );
8975 outline0( "LD H, A" );
8976 outline1( "LD A, (%s)", _angle );
8977
8978 outline0( "CALL FPFASTTAN");
8979
8980 outline1( "LD (%s), A", _result );
8981 outline0( "LD A, H" );
8982 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
8983 outline0( "LD A, L" );
8984 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
8985
8986}
8987
8988void cpu_float_fast_sqr( Environment * _environment, char * _value, char * _result ) {
8989
8991
8992 deploy( fp_vars, src_hw_z80_fp_vars_asm );
8993 deploy( fp_mul16, src_hw_z80_fp_mul16_asm );
8994 deploy( fp_fast_mul, src_hw_z80_fp_fast_mul_asm );
8995 deploy( fp_fast_sqr, src_hw_z80_fp_fast_sqr_asm );
8996
8997 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+2" ) );
8998 outline0( "LD L, A" );
8999 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+1" ) );
9000 outline0( "LD H, A" );
9001 outline1( "LD A, (%s)", _value );
9002
9003 outline0( "CALL FPFASTSQR");
9004
9005 outline1( "LD (%s), A", _result );
9006 outline0( "LD A, H" );
9007 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
9008 outline0( "LD A, L" );
9009 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
9010
9011}
9012
9013void cpu_float_fast_mod1( Environment * _environment, char * _value, char * _result ) {
9014
9016
9017 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9018 deploy( fp_fast_mod1, src_hw_z80_fp_fast_mod1_asm );
9019
9020 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+2" ) );
9021 outline0( "LD L, A" );
9022 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+1" ) );
9023 outline0( "LD H, A" );
9024 outline1( "LD A, (%s)", _value );
9025
9026 outline0( "CALL FPFASTMOD1");
9027
9028 outline1( "LD (%s), A", _result );
9029 outline0( "LD A, H" );
9030 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
9031 outline0( "LD A, L" );
9032 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
9033
9034}
9035
9036void cpu_float_fast_neg( Environment * _environment, char * _value, char * _result ) {
9037
9039
9040 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9041 deploy( fp_fast_neg, src_hw_z80_fp_fast_neg_asm );
9042
9043 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+2" ) );
9044 outline0( "LD L, A" );
9045 outline1( "LD A, (%s)", address_displacement( _environment, _value, "+1" ) );
9046 outline0( "LD H, A" );
9047 outline1( "LD A, (%s)", _value );
9048
9049 outline0( "CALL FPFASTNEG");
9050
9051 outline1( "LD (%s), A", _result );
9052 outline0( "LD A, H" );
9053 outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
9054 outline0( "LD A, L" );
9055 outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
9056
9057}
9058
9059void cpu_float_single_from_16( Environment * _environment, char * _value, char * _result, int _signed ) {
9060
9061 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9062 deploy( fp_pushpop, src_hw_z80_fp_pushpop_asm );
9063 deploy( fp_single_from_16, src_hw_z80_fp_single_from_16_asm );
9064
9065 outline1( "LD HL, (%s)", _value );
9066 outline1( "LD BC, %s", _result );
9067 if ( _signed ) {
9068 outline0( "CALL FPSINGLEFROM16S");
9069 } else {
9070 outline0( "CALL FPSINGLEFROM16U");
9071 }
9072
9073}
9074
9075void cpu_float_single_from_8( Environment * _environment, char * _value, char * _result, int _signed ) {
9076
9077 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9078 deploy( fp_single_from_8, src_hw_z80_fp_single_from_8_asm );
9079
9080 outline1( "LD A, (%s)", _value );
9081 outline1( "LD BC, %s", _result );
9082 if ( _signed ) {
9083 outline0( "CALL FPSINGLEFROM8S");
9084 } else {
9085 outline0( "CALL FPSINGLEFROM8U");
9086 }
9087
9088}
9089
9090
9091void cpu_float_single_to_16( Environment * _environment, char * _value, char * _result, int _signed ) {
9092
9093 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9094 deploy( fp_single_to_16, src_hw_z80_fp_single_to_16_asm );
9095
9096 outline1( "LD HL, %s", _value );
9097 if ( _signed ) {
9098 outline0( "CALL FPSINGLETO16S");
9099 } else {
9100 outline0( "CALL FPSINGLETO16U");
9101 }
9102 outline1( "LD (%s), HL", _result );
9103
9104}
9105
9106void cpu_float_single_to_8( Environment * _environment, char * _value, char * _result, int _signed ) {
9107
9108 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9109 deploy( fp_single_to_8, src_hw_z80_fp_single_to_8_asm );
9110
9111 outline1( "LD HL, %s", _value );
9112 if ( _signed ) {
9113 outline0( "CALL FPSINGLETO8S");
9114 } else {
9115 outline0( "CALL FPSINGLETO8U");
9116 }
9117 outline1( "LD (%s), A", _result );
9118
9119}
9120
9121void cpu_float_single_add( Environment * _environment, char * _x, char * _y, char * _result ) {
9122
9123 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9124 deploy( fp_pushpop, src_hw_z80_fp_pushpop_asm );
9125 deploy( fp_single_add, src_hw_z80_fp_single_add_asm );
9126
9127 outline1( "LD DE, %s", _y );
9128 outline1( "LD HL, %s", _x );
9129 outline1( "LD BC, %s", _result );
9130 outline0( "CALL FPSINGLEADD");
9131
9132}
9133
9134void cpu_float_single_sub( Environment * _environment, char * _x, char * _y, char * _result ) {
9135
9136 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9137 deploy( fp_pushpop, src_hw_z80_fp_pushpop_asm );
9138 deploy( fp_single_sub, src_hw_z80_fp_single_sub_asm );
9139 deploy( fp_single_add, src_hw_z80_fp_single_add_asm );
9140
9141 outline1( "LD DE, %s", _y );
9142 outline1( "LD HL, %s", _x );
9143 outline1( "LD BC, %s", _result );
9144 outline0( "CALL FPSINGLESUB");
9145
9146}
9147
9148void cpu_float_single_mul( Environment * _environment, char * _x, char * _y, char * _result ) {
9149
9150 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9151 deploy( fp_pushpop, src_hw_z80_fp_pushpop_asm );
9152 deploy( fp_c_times_bde, src_hw_z80_fp_c_times_bde_asm );
9153 deploy( fp_mul24_stack_based, src_hw_z80_fp_mul24_stack_based_asm );
9154 deploy( fp_single_mul, src_hw_z80_fp_single_mul_asm );
9155
9156 outline1( "LD DE, %s", _y );
9157 outline1( "LD HL, %s", _x );
9158 outline1( "LD BC, %s", _result );
9159 outline0( "CALL FPSINGLEMUL");
9160
9161}
9162
9163void cpu_float_single_div( Environment * _environment, char * _x, char * _y, char * _result ) {
9164
9165 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9166 deploy( fp_pushpop, src_hw_z80_fp_pushpop_asm );
9167 deploy( fp_div24_24, src_hw_z80_fp_div24_24_asm );
9168 deploy( fp_single_div, src_hw_z80_fp_single_div_asm );
9169
9170 outline1( "LD DE, %s", _y );
9171 outline1( "LD HL, %s", _x );
9172 outline1( "LD BC, %s", _result );
9173 outline0( "CALL FPSINGLEDIV");
9174
9175}
9176
9177void cpu_float_single_cmp( Environment * _environment, char * _x, char * _y, char * _result ) {
9178
9180
9181 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9182 deploy( fp_pushpop, src_hw_z80_fp_pushpop_asm );
9183 deploy( fp_single_sub, src_hw_z80_fp_single_sub_asm );
9184 deploy( fp_single_cmp, src_hw_z80_fp_single_cmp_asm );
9185
9186 outline1( "LD DE, %s", _y );
9187 outline1( "LD HL, %s", _x );
9188 outline0( "CALL FPSINGLECMP");
9189
9190 outline1( "JR Z, %sequal", label );
9191 outline1( "JR C, %sless", label );
9192 outline0( "LD A, 1" );
9193 outline1( "LD (%s), A", _result );
9194 outline1( "JP %sdone", label );
9195 outhead1( "%sequal:", label );
9196 outline0( "LD A, 0" );
9197 outline1( "LD (%s), A", _result );
9198 outline1( "JP %sdone", label );
9199 outhead1( "%sless:", label );
9200 outline0( "LD A, $ff" );
9201 outline1( "LD (%s), A", _result );
9202 outline1( "JP %sdone", label );
9203 outhead1( "%sdone:", label );
9204
9205}
9206
9207void cpu_float_single_neg( Environment * _environment, char * _value, char * _result ) {
9208
9209 // MAKE_LABEL
9210
9211 // deploy( fp_single_sub, src_hw_z80_fp_single_sub_asm );
9212 // deploy( fp_single_mod1, src_hw_z80_fp_single_mod1_asm );
9213 // deploy( fp_single_sin, src_hw_z80_fp_single_sin_asm );
9214 // deploy( fp_single_mul, src_hw_z80_fp_single_mul_asm );
9215 // deploy( fp_single_sqr, src_hw_z80_fp_single_sqr_asm );
9216 // deploy( fp_single_cos, src_hw_z80_fp_single_cos_asm );
9217 // deploy( fp_single_div, src_hw_z80_fp_single_div_asm );
9218
9219 // outline1( "LD A, (%s)", address_displacement( _environment, _angle, "+2" ) );
9220 // outline0( "LD L, A" );
9221 // outline1( "LD A, (%s)", address_displacement( _environment, _angle, "+1" ) );
9222 // outline0( "LD H, A" );
9223 // outline1( "LD A, (%s)", _angle );
9224
9225 // outline0( "CALL FPFSINGLESIN");
9226
9227 // outline1( "LD (%s), A", _result );
9228 // outline0( "LD A, H" );
9229 // outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
9230 // outline0( "LD A, L" );
9231 // outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
9232
9233}
9234
9235void cpu_float_single_sin( Environment * _environment, char * _angle, char * _result ) {
9236
9238
9239 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9240 deploy( fp_c_times_bde, src_hw_z80_fp_c_times_bde_asm );
9241 deploy( fp_mul24_stack_based, src_hw_z80_fp_mul24_stack_based_asm );
9242 deploy( fp_single_vars, src_hw_z80_fp_single_vars_asm );
9243 deploy( fp_single_sin, src_hw_z80_fp_single_sin_asm );
9244 deploy( fp_single_cos, src_hw_z80_fp_single_cos_asm );
9245 deploy( fp_single_sub, src_hw_z80_fp_single_sub_asm );
9246 deploy( fp_single_mul, src_hw_z80_fp_single_mul_asm );
9247 deploy( fp_single_add, src_hw_z80_fp_single_add_asm );
9248 deploy( fp_single_neg, src_hw_z80_fp_single_neg_asm );
9249 deploy( fp_single_mod1, src_hw_z80_fp_single_mod1_asm );
9250 deploy( fp_single_abs, src_hw_z80_fp_single_abs_asm );
9251 deploy( fp_single_horner_step, src_hw_z80_fp_single_horner_step_asm );
9252
9253 outline1( "LD HL, %s", _angle );
9254 outline1( "LD BC, %s", _result );
9255 outline0( "CALL FPSINGLESIN");
9256 // outline0( "LD A, (HL)" );
9257 // outline1( "LD (%s), A", _result );
9258 // outline0( "INC HL" );
9259 // outline0( "LD A, (HL)" );
9260 // outline1( "LD (%s), A", _result );
9261 // outline0( "INC HL" );
9262 // outline0( "LD A, (HL)" );
9263 // outline1( "LD (%s), A", _result );
9264 // outline0( "INC HL" );
9265 // outline0( "LD A, (HL)" );
9266 // outline1( "LD (%s), A", _result );
9267 // outline0( "INC HL" );
9268
9269}
9270
9271void cpu_float_single_cos( Environment * _environment, char * _angle, char * _result ) {
9272
9274
9275 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9276 deploy( fp_c_times_bde, src_hw_z80_fp_c_times_bde_asm );
9277 deploy( fp_mul24_stack_based, src_hw_z80_fp_mul24_stack_based_asm );
9278 deploy( fp_mov4, src_hw_z80_fp_mov4_asm );
9279 deploy( fp_single_vars, src_hw_z80_fp_single_vars_asm );
9280 deploy( fp_single_sin, src_hw_z80_fp_single_sin_asm );
9281 deploy( fp_single_cos, src_hw_z80_fp_single_cos_asm );
9282 deploy( fp_single_sub, src_hw_z80_fp_single_sub_asm );
9283 deploy( fp_single_mul, src_hw_z80_fp_single_mul_asm );
9284 deploy( fp_single_add, src_hw_z80_fp_single_add_asm );
9285 deploy( fp_single_neg, src_hw_z80_fp_single_neg_asm );
9286 deploy( fp_single_mod1, src_hw_z80_fp_single_mod1_asm );
9287 deploy( fp_single_abs, src_hw_z80_fp_single_abs_asm );
9288 deploy( fp_single_horner_step, src_hw_z80_fp_single_horner_step_asm );
9289
9290 outline1( "LD HL, %s", _angle );
9291 outline1( "LD BC, %s", _result );
9292 outline0( "CALL FPSINGLECOS");
9293 outline0( "LD A, (HL)" );
9294 outline1( "LD (%s), A", _result );
9295 outline0( "INC HL" );
9296 outline0( "LD A, (HL)" );
9297 outline1( "LD (%s), A", _result );
9298 outline0( "INC HL" );
9299 outline0( "LD A, (HL)" );
9300 outline1( "LD (%s), A", _result );
9301 outline0( "INC HL" );
9302 outline0( "LD A, (HL)" );
9303 outline1( "LD (%s), A", _result );
9304 outline0( "INC HL" );
9305
9306}
9307
9308void cpu_float_single_tan( Environment * _environment, char * _angle, char * _result ) {
9309
9311
9312 deploy( fp_vars, src_hw_z80_fp_vars_asm );
9313 deploy( fp_c_times_bde, src_hw_z80_fp_c_times_bde_asm );
9314 deploy( fp_mul24_stack_based, src_hw_z80_fp_mul24_stack_based_asm );
9315 deploy( fp_single_vars, src_hw_z80_fp_single_vars_asm );
9316 deploy( fp_single_sin, src_hw_z80_fp_single_sin_asm );
9317 deploy( fp_single_cos, src_hw_z80_fp_single_cos_asm );
9318 deploy( fp_single_div, src_hw_z80_fp_single_div_asm );
9319 deploy( fp_single_sin, src_hw_z80_fp_single_tan_asm );
9320 deploy( fp_single_tan, src_hw_z80_fp_single_tan_asm );
9321 deploy( fp_single_neg, src_hw_z80_fp_single_neg_asm );
9322 deploy( fp_single_sub, src_hw_z80_fp_single_sub_asm );
9323 deploy( fp_single_mul, src_hw_z80_fp_single_mul_asm );
9324 deploy( fp_single_add, src_hw_z80_fp_single_add_asm );
9325 deploy( fp_single_mod1, src_hw_z80_fp_single_mod1_asm );
9326 deploy( fp_single_abs, src_hw_z80_fp_single_abs_asm );
9327 deploy( fp_single_horner_step, src_hw_z80_fp_single_horner_step_asm );
9328
9329
9330 outline1( "LD HL, %s", _angle );
9331 outline1( "LD BC, %s", _result );
9332 outline0( "CALL FPSINGLETAN");
9333 // outline0( "LD A, (HL)" );
9334 // outline1( "LD (%s), A", _result );
9335 // outline0( "INC HL" );
9336 // outline0( "LD A, (HL)" );
9337 // outline1( "LD (%s), A", _result );
9338 // outline0( "INC HL" );
9339 // outline0( "LD A, (HL)" );
9340 // outline1( "LD (%s), A", _result );
9341 // outline0( "INC HL" );
9342 // outline0( "LD A, (HL)" );
9343 // outline1( "LD (%s), A", _result );
9344 // outline0( "INC HL" );
9345
9346}
9347
9348void cpu_float_single_sqr( Environment * _environment, char * _value, char * _result ) {
9349
9350 // MAKE_LABEL
9351
9352 // deploy( fp_single_mul, src_hw_z80_fp_single_mul_asm );
9353 // deploy( fp_single_sqr, src_hw_z80_fp_single_sqr_asm );
9354
9355 // outline1( "LD A, (%s)", address_displacement( _environment, _value, "+2" ) );
9356 // outline0( "LD L, A" );
9357 // outline1( "LD A, (%s)", address_displacement( _environment, _value, "+1" ) );
9358 // outline0( "LD H, A" );
9359 // outline1( "LD A, (%s)", _value );
9360
9361 // outline0( "CALL FPsingleSQR");
9362
9363 // outline1( "LD (%s), A", _result );
9364 // outline0( "LD A, H" );
9365 // outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
9366 // outline0( "LD A, L" );
9367 // outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
9368
9369}
9370
9371void cpu_float_single_mod1( Environment * _environment, char * _value, char * _result ) {
9372
9373 // MAKE_LABEL
9374
9375 // deploy( fp_single_mod1, src_hw_z80_fp_single_mod1_asm );
9376
9377 // outline1( "LD A, (%s)", address_displacement( _environment, _value, "+2" ) );
9378 // outline0( "LD L, A" );
9379 // outline1( "LD A, (%s)", address_displacement( _environment, _value, "+1" ) );
9380 // outline0( "LD H, A" );
9381 // outline1( "LD A, (%s)", _value );
9382
9383 // outline0( "CALL FPsingleMOD1");
9384
9385 // outline1( "LD (%s), A", _result );
9386 // outline0( "LD A, H" );
9387 // outline1( "LD (%s), A", address_displacement( _environment, _result, "+1" ) );
9388 // outline0( "LD A, L" );
9389 // outline1( "LD (%s), A", address_displacement( _environment, _result, "+2" ) );
9390
9391}
9392
9393void cpu_address_table_build( Environment * _environment, char * _table, int * _values, char *_address[], int _count ) {
9394
9395 outhead1("%s:", _table );
9396 for( int i=0; i<_count; ++i ) {
9397 outline2("DEFW $%4.4x, %s", _values[i], _address[i] );
9398 }
9399
9400}
9401
9402void cpu_address_table_lookup( Environment * _environment, char * _table, int _count ) {
9403
9404 outhead1("LOOKFOR%s:", _table );
9405 if ( _count ) {
9406 outline1("LD HL, %s", _table );
9407 outline0("LD C, 0" );
9408 outhead1("LOOKFOR%sL1:", _table );
9409 outline0("LD A, (HL)" );
9410 outline0("INC HL" );
9411 outline0("LD B, A" );
9412 outline0("LD A, E" );
9413 outline0("CP B" );
9414 outline1("JR NZ, LOOKFOR%sNEXT3", _table );
9415 outline0("LD A, (HL)" );
9416 outline0("INC HL" );
9417 outline0("LD B, A" );
9418 outline0("LD A, D" );
9419 outline0("CP B" );
9420 outline1("JR NZ, LOOKFOR%sNEXT2", _table );
9421 outline0("LD A, (HL)" );
9422 outline0("INC HL" );
9423 outline0("LD E, A" );
9424 outline0("LD A, (HL)" );
9425 outline0("INC HL" );
9426 outline0("LD D, A" );
9427 outline0("RET" );
9428 outhead1("LOOKFOR%sNEXT3:", _table );
9429 outline0("INC HL" );
9430 outhead1("LOOKFOR%sNEXT2:", _table );
9431 outline0("INC HL" );
9432 outline0("INC HL" );
9433 outline0("INC C" );
9434 outline0("LD A, C" );
9435 outline1("CP $%4.4x", (_count+1) );
9436 outline1("JR NZ, LOOKFOR%sL1", _table );
9437 }
9438 outline0("RET" );
9439
9440}
9441
9442void cpu_address_table_call( Environment * _environment, char * _table, char * _value, char * _address ) {
9443
9444 outline1("LD DE, (%s)", _value );
9445 outline1("CALL LOOKFOR%s", _table );
9446 outline1("LD (%s), DE", _address );
9447
9448}
9449
9450void cpu_move_8bit_signed_16bit_signed( Environment * _environment, char *_source, char *_destination ) {
9451
9452 outline1("LD DE, %s", _destination );
9453 outline1("LD A, (%s)", _source );
9454 outline0("LD (DE), A" );
9455 outline0("INC DE" );
9456 outline0("ADD A, A" );
9457 outline0("SBC A" );
9458 outline0("LD (DE), A" );
9459
9460}
9461
9462void cpu_move_8bit_signed_16bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9463
9464 outline1("LD DE, %s", _destination );
9465 outline1("LD A, (%s)", _source );
9466 outline0("LD (DE), A" );
9467 outline0("INC DE" );
9468 outline0("ADD A, A" );
9469 outline0("SBC A" );
9470 outline0("LD (DE), A" );
9471
9472}
9473
9474void cpu_move_8bit_unsigned_16bit_signed( Environment * _environment, char *_source, char *_destination ){
9475
9476 outline1("LD DE, %s", _destination );
9477 outline1("LD A, (%s)", _source );
9478 outline0("LD (DE), A" );
9479 outline0("INC DE" );
9480 outline0("LD A, 0" );
9481 outline0("LD (DE), A" );
9482
9483}
9484
9485void cpu_move_8bit_unsigned_16bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9486
9487 outline1("LD DE, %s", _destination );
9488 outline1("LD A, (%s)", _source );
9489 outline0("LD (DE), A" );
9490 outline0("INC DE" );
9491 outline0("LD A, 0" );
9492 outline0("LD (DE), A" );
9493
9494}
9495
9496void cpu_move_8bit_signed_32bit_signed( Environment * _environment, char *_source, char *_destination ){
9497
9498 outline1("LD DE, %s", _destination );
9499 outline1("LD A, (%s)", _source );
9500 outline0("LD (DE), A" );
9501 outline0("INC DE" );
9502 outline0("ADD A, A" );
9503 outline0("SBC A" );
9504 outline0("LD (DE), A" );
9505 outline0("INC DE" );
9506 outline0("LD (DE), A" );
9507 outline0("INC DE" );
9508 outline0("LD (DE), A" );
9509
9510}
9511
9512void cpu_move_8bit_signed_32bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9513
9514 outline1("LD DE, %s", _destination );
9515 outline1("LD A, (%s)", _source );
9516 outline0("LD (DE), A" );
9517 outline0("INC DE" );
9518 outline0("ADD A, A" );
9519 outline0("SBC A" );
9520 outline0("LD (DE), A" );
9521 outline0("INC DE" );
9522 outline0("LD (DE), A" );
9523 outline0("INC DE" );
9524 outline0("LD (DE), A" );
9525
9526}
9527
9528void cpu_move_8bit_unsigned_32bit_signed( Environment * _environment, char *_source, char *_destination ){
9529
9530 outline1("LD DE, %s", _destination );
9531 outline1("LD A, (%s)", _source );
9532 outline0("LD (DE), A" );
9533 outline0("INC DE" );
9534 outline0("LD A, 0" );
9535 outline0("LD (DE), A" );
9536 outline0("INC DE" );
9537 outline0("LD A, 0" );
9538 outline0("LD (DE), A" );
9539 outline0("INC DE" );
9540 outline0("LD A, 0" );
9541 outline0("LD (DE), A" );
9542
9543}
9544void cpu_move_8bit_unsigned_32bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9545
9546 outline1("LD DE, %s", _destination );
9547 outline1("LD A, (%s)", _source );
9548 outline0("LD (DE), A" );
9549 outline0("INC DE" );
9550 outline0("LD A, 0" );
9551 outline0("LD (DE), A" );
9552 outline0("INC DE" );
9553 outline0("LD A, 0" );
9554 outline0("LD (DE), A" );
9555 outline0("INC DE" );
9556 outline0("LD A, 0" );
9557 outline0("LD (DE), A" );
9558
9559}
9560
9561void cpu_move_16bit_signed_8bit_signed( Environment * _environment, char *_source, char *_destination ){
9562
9563 outline1("LD HL, (%s)", _source );
9564 outline0("LD A, L" );
9565 outline1("LD (%s), A", _destination );
9566
9567}
9568void cpu_move_16bit_signed_8bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9569
9570 outline1("LD HL, (%s)", _source );
9571 outline0("LD A, L" );
9572 outline1("LD (%s), A", _destination );
9573
9574}
9575void cpu_move_16bit_unsigned_8bit_signed( Environment * _environment, char *_source, char *_destination ){
9576
9577 outline1("LD HL, (%s)", _source );
9578 outline0("LD A, L" );
9579 outline1("LD (%s), A", _destination );
9580
9581}
9582void cpu_move_16bit_unsigned_8bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9583
9584 outline1("LD HL, (%s)", _source );
9585 outline0("LD A, L" );
9586 outline1("LD (%s), A", _destination );
9587
9588}
9589
9590void cpu_move_16bit_signed_32bit_signed( Environment * _environment, char *_source, char *_destination ){
9591
9592 outline1("LD DE, %s", _destination );
9593 outline1("LD A, (%s)", _source );
9594 outline0("LD (DE), A" );
9595 outline0("INC DE" );
9596 outline1("LD A, (%s)", address_displacement( _environment, _source, "1" ) );
9597 outline0("LD (DE), A" );
9598 outline0("INC DE" );
9599 outline0("ADD A, A" );
9600 outline0("SBC A" );
9601 outline0("LD (DE), A" );
9602 outline0("INC DE" );
9603 outline0("LD (DE), A" );
9604
9605}
9606
9607void cpu_move_16bit_signed_32bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9608
9609 outline1("LD DE, %s", _destination );
9610 outline1("LD A, (%s)", _source );
9611 outline0("LD (DE), A" );
9612 outline0("INC DE" );
9613 outline1("LD A, (%s)", address_displacement( _environment, _source, "1" ) );
9614 outline0("LD (DE), A" );
9615 outline0("INC DE" );
9616 outline0("ADD A, A" );
9617 outline0("SBC A" );
9618 outline0("LD (DE), A" );
9619 outline0("INC DE" );
9620 outline0("LD (DE), A" );
9621
9622}
9623
9624void cpu_move_16bit_unsigned_32bit_signed( Environment * _environment, char *_source, char *_destination ){
9625
9626 outline1("LD DE, %s", _destination );
9627 outline1("LD A, (%s)", _source );
9628 outline0("LD (DE), A" );
9629 outline0("INC DE" );
9630 outline1("LD A, (%s)", address_displacement( _environment, _source, "1" ) );
9631 outline0("LD (DE), A" );
9632 outline0("INC DE" );
9633 outline0("LD A, 0" );
9634 outline0("LD (DE), A" );
9635 outline0("INC DE" );
9636 outline0("LD (DE), A" );
9637
9638}
9639void cpu_move_16bit_unsigned_32bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9640
9641 outline1("LD DE, %s", _destination );
9642 outline1("LD A, (%s)", _source );
9643 outline0("LD (DE), A" );
9644 outline0("INC DE" );
9645 outline1("LD A, (%s)", address_displacement( _environment, _source, "1" ) );
9646 outline0("LD (DE), A" );
9647 outline0("INC DE" );
9648 outline0("LD A, 0" );
9649 outline0("LD (DE), A" );
9650 outline0("INC DE" );
9651 outline0("LD (DE), A" );
9652
9653}
9654
9655void cpu_move_32bit_signed_8bit_signed( Environment * _environment, char *_source, char *_destination ){
9656
9657 outline1("LD A, (%s)", _source );
9658 outline1("LD (%s), A", _destination );
9659
9660}
9661void cpu_move_32bit_signed_8bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9662
9663 outline1("LD A, (%s)", _source );
9664 outline1("LD (%s), A", _destination );
9665
9666}
9667void cpu_move_32bit_unsigned_8bit_signed( Environment * _environment, char *_source, char *_destination ){
9668
9669 outline1("LD A, (%s)", _source );
9670 outline1("LD (%s), A", _destination );
9671
9672}
9673void cpu_move_32bit_unsigned_8bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9674
9675 outline1("LD A, (%s)", _source );
9676 outline1("LD (%s), A", _destination );
9677
9678}
9679
9680void cpu_move_32bit_signed_16bit_signed( Environment * _environment, char *_source, char *_destination ){
9681
9682 outline1("LD HL, (%s)", _source );
9683 outline1("LD (%s), HL", _destination );
9684
9685}
9686
9687void cpu_move_32bit_signed_16bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9688
9689 outline1("LD HL, (%s)", _source );
9690 outline1("LD (%s), HL", _destination );
9691
9692}
9693
9694void cpu_move_32bit_unsigned_16bit_signed( Environment * _environment, char *_source, char *_destination ){
9695
9696 outline1("LD HL, (%s)", _source );
9697 outline1("LD (%s), HL", _destination );
9698
9699}
9700
9701void cpu_move_32bit_unsigned_16bit_unsigned( Environment * _environment, char *_source, char *_destination ){
9702
9703 outline1("LD HL, (%s)", _source );
9704 outline1("LD (%s), HL", _destination );
9705
9706}
9707
9708void cpu_float_fast_log( Environment * _environment, char * _value, char * _result ) {
9709
9711
9712}
9713
9714void cpu_float_single_log( Environment * _environment, char * _value, char * _result ) {
9715
9717
9718}
9719
9720void cpu_float_fast_exp( Environment * _environment, char * _value, char * _result ) {
9721
9723
9724}
9725
9726void cpu_float_single_exp( Environment * _environment, char * _value, char * _result ) {
9727
9729
9730}
9731
9732void cpu_encrypt( Environment * _environment, char * _data, char * _data_size, char * _key, char * _key_size, char * _output ) {
9733
9734 deploy( encrypt, src_hw_z80_encrypt_asm );
9735
9736 outline1("LD HL, (%s)", _data );
9737 outline1("LD IX, (%s)", _key );
9738 outline1("LD DE, (%s)", _output );
9739 outline1("LD A, (%s)", _data_size );
9740 outline0("LD C, A" );
9741 outline1("LD A, (%s)", _key_size );
9742 outline0("LD B, A" );
9743 outline0("CALL ENCRYPT" );
9744
9745}
9746
9747void cpu_decrypt( Environment * _environment, char * _data, char * _data_size, char * _key, char * _key_size, char * _output, char * _result ) {
9748
9749 deploy( decrypt, src_hw_z80_decrypt_asm );
9750
9751 outline1("LD HL, (%s)", _data );
9752 outline1("LD IX, (%s)", _key );
9753 outline1("LD DE, (%s)", _output );
9754 outline1("LD A, (%s)", _data_size );
9755 outline0("LD C, A" );
9756 outline1("LD A, (%s)", _key_size );
9757 outline0("LD B, A" );
9758 outline0("CALL DECRYPT" );
9759 cpu_ztoa( _environment );
9760 outline1("LD (%s), A", _result );
9761
9762}
9763
9764void cpu_hex_to_bin( Environment * _environment, char * _value_address, char * _value_size, char * _variable_address, char * _variable_size, char * _result ) {
9765
9766 deploy( hex2bin, src_hw_z80_hex2bin_asm );
9767
9768 outline1("LD HL, (%s)", _value_address );
9769 outline1("LD DE, (%s)", _variable_address );
9770 outline1("LD A, (%s)", _value_size );
9771 outline0("LD C, A" );
9772 outline1("LD A, (%s)", _variable_size );
9773 outline0("LD B, A" );
9774 outline0("CALL HEX2BIN" );
9775 outline1("LD (%s), A", _result );
9776
9777}
9778
9779void cpu_dsfill( Environment * _environment, char * _string, char * _value ) {
9780
9781 deploy_preferred( duff, src_hw_z80_duff_asm );
9782 deploy( dstring, src_hw_z80_dstring_asm );
9783
9784 outline1( "LD A, (%s)", _string );
9785 outline0( "LD B, A" );
9786 outline1( "LD A, (%s)", _value );
9787 outline0( "CALL DSFILL" );
9788
9789}
9790
9791void cpu_dsfill_value( Environment * _environment, char * _string, int _value ) {
9792
9793 deploy_preferred( duff, src_hw_z80_duff_asm );
9794 deploy( dstring, src_hw_z80_dstring_asm );
9795
9796 outline1( "LD A, (%s)", _string );
9797 outline0( "LD B, A" );
9798 outline1( "LD A, $%2.2x", (unsigned char)(_value&0xff) );
9799 outline0( "CALL DSFILL" );
9800
9801}
9802
9803#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_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_B
Definition 6309.h:64
@ REGISTER_D
Definition 6309.h:72
@ REGISTER_A
Definition 6309.h:63
@ REGISTER_NONE
Definition 6309.h:62
@ REGISTER_PC
Definition 6309.h:71
@ STACK_NONE
Definition 6309.h:78
@ STACK_BYTE
Definition 6309.h:79
@ STACK_WORD
Definition 6309.h:80
@ STACK_DWORD
Definition 6309.h:81
void cpu_math_add_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, int _bits)
Definition 6502.c:4242
@ REGISTER_CARRY
Definition 6502.h:76
@ REGISTER_ZERO
Definition 6502.h:77
void cpu_bits_to_string_vars(Environment *_environment)
Definition 8086.c:4589
void cpu_number_to_string_vars(Environment *_environment)
Definition 8086.c:4513
@ REGISTER_SP
Definition 8086.h:74
Variable * variable_retrieve(Environment *_environment, char *_name)
Variable * variable_import(Environment *_environment, char *_name, VariableType _type, int _size_or_value)
void variable_global(Environment *_environment, char *_pattern)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
char * address_displacement(Environment *_environment, char *_address, char *_displacement)
Variable * variable_store_buffer(Environment *_environment, char *_destination, unsigned char *_buffer, int _size, int _at)
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
@ REGISTER_I
Definition sc61860.h:62
@ REGISTER_L
Definition sc61860.h:71
Variable * sign(Environment *_environment, char *_value)
Return the sign of a variable.
Definition sgn.c:85
#define abs(ticks)
Definition sidreloc.c:338
enum _Z80Stack Z80Stack
@ REGISTER_DE
Definition sm83.h:78
@ REGISTER_IX
Definition sm83.h:74
@ REGISTER_IYH
Definition sm83.h:83
@ REGISTER_IYL
Definition sm83.h:82
@ REGISTER_IXH
Definition sm83.h:81
@ REGISTER_F
Definition sm83.h:69
@ REGISTER_AF
Definition sm83.h:76
@ REGISTER_C
Definition sm83.h:64
@ REGISTER_H
Definition sm83.h:67
@ REGISTER_R
Definition sm83.h:71
@ REGISTER_IXL
Definition sm83.h:80
@ REGISTER_BC
Definition sm83.h:77
@ REGISTER_E
Definition sm83.h:66
@ REGISTER_IY
Definition sm83.h:75
@ REGISTER_HL
Definition sm83.h:79
@ REGISTER_HLA
Definition sm83.h:84
enum _Z80Register Z80Register
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
NumberConfig numberConfig
Definition ugbc.h:2410
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
int maxBytes
Definition ugbc.h:2261
int maxDigits
Definition ugbc.h:2262
int readonly
Definition ugbc.h:1195
char * realName
Definition ugbc.h:982
#define no_embedded(s)
Definition ugbc.h:4380
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define CRITICAL_UNSETTABLE_CPU_REGISTER(v)
Definition ugbc.h:3625
#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 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
@ VT_BUFFER
Definition ugbc.h:477
@ VT_ADDRESS
Definition ugbc.h:465
#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 deploy_embedded(s, e)
Definition ugbc.h:4339
#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
void cpu_and_32bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5521
void cpu_float_single_cos(Environment *_environment, char *_angle, char *_result)
Definition z80.c:9271
void cpu_protothread_get_state(Environment *_environment, char *_index, char *_state)
Definition z80.c:7701
void cpu_float_fast_neg(Environment *_environment, char *_value, char *_result)
Definition z80.c:9036
void cpu_set_callback(Environment *_environment, char *_callback, char *_label)
Definition z80.c:7736
void cpu_move_32bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition z80.c:6733
void cpu_dsfree(Environment *_environment, char *_index)
Definition z80.c:7348
void cpu_less_than_memory_size(Environment *_environment, char *_source, char *_destination, int _size, char *_result, int _equal)
Definition z80.c:6200
void cpu_dsresize_size(Environment *_environment, char *_index, int _resize)
Definition z80.c:7383
void cpu_hex_to_string_calc_string(Environment *_environment, char *_size, int _separator, char *_string_size)
Definition z80.c:7258
void cpu_move_8bit_signed_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9512
void cpu_float_fast_from_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition z80.c:8697
void cpu_in(Environment *_environment, char *_port, char *_value)
Definition z80.c:7819
void cpu_hex_to_string_calc_string_size(Environment *_environment, int _size, int _separator, char *_string_size)
Definition z80.c:7274
void cpu_pokew(Environment *_environment, char *_address, char *_source)
Definition z80.c:255
void cpu_move_32bit_signed_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9687
void cpu_combine_nibbles(Environment *_environment, char *_low_nibble, char *_hi_nibble, char *_byte)
Z80: emit code to combine nibbles
Definition z80.c:4694
char * cpu_blit_register_name(Environment *_environment, int _register)
Definition z80.c:7911
void cpu_di(Environment *_environment)
Definition z80.c:5861
void cpu_float_fast_tan(Environment *_environment, char *_angle, char *_result)
Definition z80.c:8957
void cpu_math_double_32bit(Environment *_environment, char *_source, char *_other, int _signed)
Z80: emit code to double a 32 bit value
Definition z80.c:4328
void cpu_protothread_restore(Environment *_environment, char *_index, char *_step)
Definition z80.c:7676
void cpu_msc1_uncompress_indirect_indirect(Environment *_environment, char *_input, char *_output)
Definition z80.c:7795
void cpu_not_16bit(Environment *_environment, char *_value, char *_result)
Definition z80.c:5821
void cpu_move_8bit_unsigned_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9528
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 z80.c:2804
void cpu_math_div_16bit_to_16bit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _signed)
Definition z80.c:2443
void cpu_move_16bit_signed_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9590
void cpu_move_8bit_unsigned_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9474
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 z80.c:3664
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 z80.c:2191
void cpu_swap_32bit(Environment *_environment, char *_left, char *_right)
Definition z80.c:5790
void cpu_float_fast_from_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition z80.c:8678
void cpu_bveq(Environment *_environment, char *_value, char *_label)
Definition z80.c:176
void cpu_dsresize(Environment *_environment, char *_index, char *_resize)
Definition z80.c:7370
void cpu_move_nbit_indirect(Environment *_environment, int _n, char *_source, char *_value)
Definition z80.c:6651
void cpu_math_div_8bit_to_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _signed)
Definition z80.c:6928
void cpu_bit_check_extended(Environment *_environment, char *_value, char *_position, char *_result, int _bitwidth)
Definition z80.c:7036
void cpu_math_div_32bit_to_16bit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _signed)
Definition z80.c:2917
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 z80.c:1563
void cpu_float_fast_div(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:8833
void cpu_move_32bit_signed_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9680
void cpu_move_32bit_unsigned_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9673
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 z80.c:4579
void cpu_uppercase(Environment *_environment, char *_source, char *_size, char *_result)
Definition z80.c:6312
void cpu_math_add_16bit_with_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Definition z80.c:6297
void cpu_address_table_build(Environment *_environment, char *_table, int *_values, char *_address[], int _count)
Definition z80.c:9393
void cpu_mem_move(Environment *_environment, char *_source, char *_destination, char *_size)
Definition z80.c:5982
void cpu_set_asmio_indirect(Environment *_environment, int _asmio, char *_value)
Definition z80.c:4987
void cpu_msc1_uncompress_direct_indirect(Environment *_environment, char *_input, char *_output)
Definition z80.c:7763
void cpu_math_sub_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to subtract two 8 bit values
Definition z80.c:1302
void cpu_xor_32bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition z80.c:5733
void cpu_math_add_32bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to add two 32 bit values
Definition z80.c:4232
void cpu_protothread_save(Environment *_environment, char *_index, int _step)
Definition z80.c:7664
void cpu_store_char(Environment *_environment, char *_destination, int _value)
Z80: emit code to store 8 bit
Definition z80.c:720
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 z80.c:4430
void cpu_store_16bit(Environment *_environment, char *_destination, int _value)
Z80: emit code to store 16 bit
Definition z80.c:1689
void cpu_poked(Environment *_environment, char *_address, char *_source)
Definition z80.c:306
void cpu_and_8bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition z80.c:5493
void cpu_dsassign(Environment *_environment, char *_original, char *_copy)
Definition z80.c:7437
void cpu_math_double_16bit(Environment *_environment, char *_source, char *_other, int _signed)
Z80: emit code to double a 16 bit value
Definition z80.c:2166
void cpu_math_sub_32bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to subtract two 32 bit values
Definition z80.c:4350
void cpu_complement2_8bit(Environment *_environment, char *_source, char *_destination)
Definition z80.c:7478
void cpu_msc1_uncompress_indirect_direct(Environment *_environment, char *_input, char *_output)
Definition z80.c:7779
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 z80.c:1491
void cpu_less_than_memory(Environment *_environment, char *_source, char *_destination, char *_size, char *_result, int _equal)
Definition z80.c:6165
void cpu_dsalloc_size(Environment *_environment, int _size, char *_index)
Definition z80.c:7335
void cpu_get_asmio_indirect(Environment *_environment, int _asmio, char *_value)
Definition z80.c:5145
void cpu_move_16bit_unsigned_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9582
void cpu_float_fast_cos(Environment *_environment, char *_angle, char *_result)
Definition z80.c:8927
void cpu_protothread_set_state(Environment *_environment, char *_index, int _state)
Definition z80.c:7689
void cpu_math_div_nbit_to_nbit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _bits)
Definition z80.c:3350
void cpu_math_add_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to add two 8 bit values
Definition z80.c:1259
void cpu_float_single_add(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:9121
void cpu_float_single_sub(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:9134
void cpu_bit_inplace_8bit_extended_indirect(Environment *_environment, char *_address, char *_position, char *_bit)
Definition z80.c:7082
void cpu_move_8bit_unsigned_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9544
void cpu_move_8bit_indirect(Environment *_environment, char *_source, char *_value)
Definition z80.c:6531
void cpu_string_sub(Environment *_environment, char *_source, char *_source_size, char *_pattern, char *_pattern_size, char *_destination, char *_destination_size)
Definition z80.c:7843
void cpu_compare_8bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
Z80: emit code to compare two 8 bit values
Definition z80.c:769
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 z80.c:4670
void cpu_fill_direct_size(Environment *_environment, char *_address, int _bytes, char *_pattern)
Z80: emit code to fill up a memory area
Definition z80.c:595
void cpu_addressof_16bit(Environment *_environment, char *_source, char *_destination)
Definition z80.c:1671
void cpu_dec_16bit(Environment *_environment, char *_variable)
Definition z80.c:5936
void cpu_dsgc(Environment *_environment)
Definition z80.c:7396
void cpu_move_16bit_signed_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9607
void cpu_inc(Environment *_environment, char *_variable)
Definition z80.c:5873
void cpu_poke_const(Environment *_environment, char *_address, int _source)
Definition z80.c:228
void cpu_fill_direct(Environment *_environment, char *_address, char *_bytes, char *_pattern)
Z80: emit code to fill up a memory area
Definition z80.c:558
void cpu_jump_indirect(Environment *_environment, char *_value)
Definition z80.c:4741
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 z80.c:1616
void cpu_dsdefine(Environment *_environment, char *_string, char *_index)
Definition z80.c:7310
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 z80.c:2695
void cpu_move_16bit_unsigned_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9639
void cpu_math_mul2_const_nbit(Environment *_environment, char *_source, int _steps, int _bits)
Definition z80.c:4630
void cpu_float_single_exp(Environment *_environment, char *_value, char *_result)
Definition z80.c:9726
void cpu_move_32bit(Environment *_environment, char *_source, char *_destination)
Z80: emit code to move 32 bit
Definition z80.c:2880
void cpu_fill_size(Environment *_environment, char *_address, int _bytes, char *_pattern)
Z80: emit code to fill up a memory area
Definition z80.c:467
void cpu_dsfill(Environment *_environment, char *_string, char *_value)
Definition z80.c:9779
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 z80.c:957
void cpu_fill_direct_size_value(Environment *_environment, char *_address, int _bytes, int _pattern)
Z80: emit code to fill up a memory area
Definition z80.c:643
void cpu_float_double_to_string(Environment *_environment, char *_x, char *_string, char *_string_size)
Definition z80.c:8674
void cpu_dec_32bit(Environment *_environment, char *_variable)
Definition z80.c:5944
void cpu_greater_than_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition z80.c:2100
void cpu_protothread_get_address(Environment *_environment, char *_index, char *_address)
Definition z80.c:7714
void cpu_math_add_16bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to add two 16 bit values
Definition z80.c:2115
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 z80.c:2089
void cpu_bit_inplace_8bit(Environment *_environment, char *_value, int _position, int *_bit)
Definition z80.c:7056
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 z80.c:2132
void cpu_protothread_vars(Environment *_environment)
Definition z80.c:7604
void cpu_poked_const(Environment *_environment, char *_address, int _source)
Definition z80.c:327
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 z80.c:2145
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 z80.c:1839
void cpu_move_32bit_indirect(Environment *_environment, char *_source, char *_value)
Definition z80.c:6631
void cpu_dswrite(Environment *_environment, char *_index)
Definition z80.c:7359
void cpu_complement2_nbit(Environment *_environment, char *_source, char *_destination, int _bits)
Definition z80.c:7551
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 z80.c:1233
void cpu_or_16bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5592
void cpu_fill(Environment *_environment, char *_address, char *_bytes, int _bytes_width, char *_pattern)
Z80: emit code to fill up a memory area
Definition z80.c:419
void cpu_move_16bit_indirect(Environment *_environment, char *_source, char *_value)
Definition z80.c:6591
void cpu_limit_16bit(Environment *_environment, char *_variable, int _value)
Definition z80.c:5421
void cpu_move_8bit_indirect_with_offset2(Environment *_environment, char *_source, char *_value, char *_offset)
Definition z80.c:7465
void cpu_less_than_32bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition z80.c:3924
void cpu_move_nbit_indirect2(Environment *_environment, int _n, char *_value, char *_source)
Definition z80.c:6753
void cpu_and_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5480
#define Z80_BLIT_REGISTER_COUNT
Definition z80.c:7885
void cpu_float_single_log(Environment *_environment, char *_value, char *_result)
Definition z80.c:9714
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 z80.c:1366
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 z80.c:1764
void cpu_math_sub_16bit(Environment *_environment, char *_source, char *_destination, char *_other)
Z80: emit code to subtract two 16 bit values
Definition z80.c:2655
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 z80.c:3720
void cpu_store_nbit(Environment *_environment, char *_destination, int _n, int _value[])
CPU Z80: emit code to store n bit
Definition z80.c:7999
void cpu_mem_move_direct_indirect_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition z80.c:6074
void cpu_dec_nbit(Environment *_environment, char *_variable, int _bits)
Definition z80.c:5962
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 z80.c:2854
void cpu_move_8bit_indirect2_8bit(Environment *_environment, char *_value, char *_offset, char *_source)
Definition z80.c:6569
void cpu_float_single_from_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition z80.c:9059
void cpu_less_than_and_branch_8bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _equal, int _signed)
Definition z80.c:1143
void cpu_fill_indirect(Environment *_environment, char *_address, char *_size, char *_pattern, int _size_size)
Definition z80.c:6463
void cpu_mem_move_indirect_direct_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition z80.c:6090
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 z80.c:930
void cpu_less_than_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _bits)
Definition z80.c:4125
void cpu_float_fast_sin(Environment *_environment, char *_angle, char *_result)
Definition z80.c:8897
void cpu_math_mul_nbit_to_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition z80.c:2310
void cpu_label(Environment *_environment, char *_label)
Definition z80.c:200
void cpu_dec(Environment *_environment, char *_variable)
Definition z80.c:5881
void cpu_and_16bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5503
void cpu_float_fast_log(Environment *_environment, char *_value, char *_result)
Definition z80.c:9708
void cpu_move_nbit(Environment *_environment, int _n, char *_source, char *_destination)
CPU Z80: emit code to store n bit
Definition z80.c:8060
void cpu_address_table_call(Environment *_environment, char *_table, char *_value, char *_address)
Definition z80.c:9442
void cpu_logical_not_8bit(Environment *_environment, char *_value, char *_result)
Definition z80.c:5805
void cpu_pokew_const(Environment *_environment, char *_address, int _source)
Definition z80.c:270
void cpu_logical_and_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5459
void cpu_or_8bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition z80.c:5581
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 z80.c:4473
void cpu_halt(Environment *_environment)
Definition z80.c:5320
void cpu_end(Environment *_environment)
Definition z80.c:5329
void cpu_float_fast_from_double_to_int_array(Environment *_environment, double _value, int _result[])
Definition z80.c:8127
void cpu_compare_memory(Environment *_environment, char *_source, char *_destination, char *_size, char *_result, int _equal)
Definition z80.c:6106
void cpu_greater_than_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition z80.c:1244
void cpu_complement2_16bit(Environment *_environment, char *_source, char *_destination)
Definition z80.c:7493
void cpu_dsinit(Environment *_environment)
Definition z80.c:7405
void cpu_xor_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5640
void cpu_protothread_unregister(Environment *_environment, char *_index)
Definition z80.c:7653
void cpu_decrypt(Environment *_environment, char *_data, char *_data_size, char *_key, char *_key_size, char *_output, char *_result)
Definition z80.c:9747
void cpu_complement2_32bit(Environment *_environment, char *_source, char *_destination)
Definition z80.c:7515
void cpu_protothread_register_at(Environment *_environment, char *_index, char *_label)
Definition z80.c:7628
void cpu_blit_free_register(Environment *_environment, int _register)
Definition z80.c:7958
void cpu_lowercase(Environment *_environment, char *_source, char *_size, char *_result)
Definition z80.c:6349
void cpu_float_single_to_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition z80.c:9106
void cpu_move_16bit(Environment *_environment, char *_source, char *_destination)
Z80: emit code to move 16 bit
Definition z80.c:1660
void cpu_move_8bit_with_offset2(Environment *_environment, char *_source, char *_value, char *_offset)
Definition z80.c:6539
void cpu_out(Environment *_environment, char *_port, char *_value)
Definition z80.c:7811
void cpu_move_16bit_unsigned_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9575
void cpu_blit_finalize(Environment *_environment)
Definition z80.c:7899
void cpu_encrypt(Environment *_environment, char *_data, char *_data_size, char *_key, char *_key_size, char *_output)
Definition z80.c:9732
void cpu_bneq(Environment *_environment, char *_label)
Z80: emit code to make long conditional jump
Definition z80.c:166
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 z80.c:3622
void cpu_float_single_mod1(Environment *_environment, char *_value, char *_result)
Definition z80.c:9371
void cpu_move_16bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition z80.c:6603
void cpu_float_fast_cmp(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:8858
void cpu_math_double_8bit(Environment *_environment, char *_source, char *_other, int _signed)
Z80: emit code to double a 8 bit value
Definition z80.c:1329
void cpu_float_fast_mul(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:8807
void cpu_bits_to_string(Environment *_environment, char *_number, char *_string, char *_string_size, int _bits, char *_zero, char *_one)
Definition z80.c:7207
void cpu_dsalloc(Environment *_environment, char *_size, char *_index)
Definition z80.c:7322
void cpu_less_than_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _bits)
Definition z80.c:4080
void cpu_port_out(Environment *_environment, char *_port, char *_value)
Z80: emit code to send one byte throught a I/O port
Definition z80.c:5452
void cpu_not_32bit(Environment *_environment, char *_value, char *_result)
Definition z80.c:5836
void cpu_float_single_from_double_to_int_array(Environment *_environment, double _value, int _result[])
Definition z80.c:8344
void cpu_float_single_to_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition z80.c:9091
void cpu_greater_than_memory_size(Environment *_environment, char *_source, char *_destination, int _size, char *_result, int _equal)
Definition z80.c:6266
void cpu_hex_to_string(Environment *_environment, char *_number, char *_string, char *_size, int _separator)
Definition z80.c:7290
void cpu_or_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5568
void cpu_store_8bit_with_offset2(Environment *_environment, char *_destination, char *_offset, int _value)
Definition z80.c:744
void cpu_move_8bit_indirect2_16bit(Environment *_environment, char *_value, char *_offset, char *_source)
Definition z80.c:6581
void cpu_math_add_32bit_const(Environment *_environment, char *_source, int _destination, char *_other)
Definition z80.c:4260
void cpu_move_8bit_indirect_with_offset(Environment *_environment, char *_source, char *_value, int _offset)
Definition z80.c:6551
void cpu_sqroot(Environment *_environment, char *_number, char *_result)
Definition z80.c:7571
void cpu_number_to_string(Environment *_environment, char *_number, char *_string, char *_string_size, int _bits, int _signed)
Definition z80.c:7116
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 z80.c:4178
void cpu_peekd(Environment *_environment, char *_address, char *_target)
Definition z80.c:285
void cpu_in_direct(Environment *_environment, char *_port, char *_value)
Definition z80.c:7835
void cpu_call_indirect(Environment *_environment, char *_value)
Definition z80.c:4727
void cpu_call(Environment *_environment, char *_label)
Definition z80.c:4721
void cpu_random_8bit(Environment *_environment, char *_entropy, char *_result)
Definition z80.c:5386
void cpu_xor_8bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition z80.c:5653
void cpu_move_16bit_signed_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9568
void cpu_mem_move_direct(Environment *_environment, char *_source, char *_destination, char *_size)
Definition z80.c:6006
void cpu_store_8bit(Environment *_environment, char *_destination, int _value)
Z80: emit code to store 8 bit
Definition z80.c:702
void cpu_swap_8bit(Environment *_environment, char *_left, char *_right)
Definition z80.c:5760
void cpu_float_fast_to_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition z80.c:8735
void cpu_mem_move_direct2(Environment *_environment, char *_source, char *_destination, char *_size)
Definition z80.c:6019
void cpu_init(Environment *_environment)
Definition z80.c:45
void cpu_dstring_vars(Environment *_environment)
Definition z80.c:7583
void cpu_protothread_loop(Environment *_environment)
Definition z80.c:7620
void cpu_float_single_div(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:9163
void cpu_hex_to_bin(Environment *_environment, char *_value_address, char *_value_size, char *_variable_address, char *_variable_size, char *_result)
Definition z80.c:9764
void cpu_out_direct(Environment *_environment, char *_port, char *_value)
Definition z80.c:7827
void cpu_greater_than_32bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition z80.c:4189
void cpu_protothread_current(Environment *_environment, char *_current)
Definition z80.c:7727
void cpu_float_fast_to_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition z80.c:8716
void cpu_mem_move_16bit(Environment *_environment, char *_source, char *_destination, char *_size)
Definition z80.c:5995
void cpu_compare_32bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
Z80: emit code to compare two 32 bit values
Definition z80.c:3522
void cpu_set_asmio(Environment *_environment, int _asmio, int _value)
Definition z80.c:4832
void cpu_float_fast_sqr(Environment *_environment, char *_value, char *_result)
Definition z80.c:8988
void cpu_jump(Environment *_environment, char *_label)
Definition z80.c:4709
void cpu_move_16bit_unsigned_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9624
int cpu_blit_alloc_register(Environment *_environment)
Definition z80.c:7920
void cpu_move_32bit_signed_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9661
void cpu_mem_move_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition z80.c:6041
void cpu_fill_blocks(Environment *_environment, char *_address, char *_blocks, char *_pattern)
Z80: emit code to fill up a memory area
Definition z80.c:361
void cpu_bvneq(Environment *_environment, char *_value, char *_label)
Definition z80.c:188
void cpu_float_single_mul(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:9148
void cpu_float_fast_exp(Environment *_environment, char *_value, char *_result)
Definition z80.c:9720
void cpu_move_16bit_signed_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9561
void cpu_compare_and_branch_16bit(Environment *_environment, char *_source, char *_destination, char *_label, int _positive)
Definition z80.c:1800
void cpu_fill_size_value(Environment *_environment, char *_address, int _bytes, int _pattern)
Z80: emit code to fill up a memory area
Definition z80.c:515
void cpu_call_addr(Environment *_environment, int _address)
Definition z80.c:4715
void cpu_math_div_16bit_to_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _signed)
Definition z80.c:2544
void cpu_poke(Environment *_environment, char *_address, char *_source)
Definition z80.c:216
void cpu_bit_check(Environment *_environment, char *_value, int _position, char *_result, int _bitwidth)
Definition z80.c:7018
void cpu_protothread_register(Environment *_environment, char *_label, char *_index)
Definition z80.c:7640
void cpu_move_32bit_signed_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9655
void cpu_float_single_to_string(Environment *_environment, char *_x, char *_string, char *_string_size)
Definition z80.c:8630
void cpu_math_div_nbit_to_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _bits)
Definition z80.c:3480
void cpu_float_single_tan(Environment *_environment, char *_angle, char *_result)
Definition z80.c:9308
void cpu_nop(Environment *_environment)
Definition z80.c:96
void cpu_random_32bit(Environment *_environment, char *_entropy, char *_result)
Definition z80.c:5409
void cpu_move_32bit_unsigned_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9701
void cpu_less_than_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition z80.c:1062
void cpu_greater_than_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _bits)
Definition z80.c:4198
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 z80.c:885
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 z80.c:1874
void cpu_mem_move_direct2_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition z80.c:6030
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 z80.c:1637
void cpu_move_32bit_unsigned_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9694
void cpu_msc1_uncompress_direct_direct(Environment *_environment, char *_input, char *_output)
Definition z80.c:7747
void cpu_float_single_sqr(Environment *_environment, char *_value, char *_result)
Definition z80.c:9348
void cpu_inc_32bit(Environment *_environment, char *_variable)
Definition z80.c:5897
void cpu_move_8bit_signed_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9450
void cpu_mem_move_direct_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition z80.c:6058
void cpu_float_fast_sub(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:8780
void cpu_xor_32bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5705
void cpu_return(Environment *_environment)
Definition z80.c:5308
void cpu_move_8bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition z80.c:6561
void cpu_inc_nbit(Environment *_environment, char *_variable, int _bits)
Definition z80.c:5917
void cpu_pop(Environment *_environment)
Definition z80.c:5314
void cpu_math_sub_16bit_with_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Definition z80.c:2673
void cpu_random_16bit(Environment *_environment, char *_entropy, char *_result)
Definition z80.c:5398
void cpu_ei(Environment *_environment)
Definition z80.c:5867
int cpu_register_decode(Environment *_environment, char *_register)
Definition z80.c:4748
void cpu_or_32bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5612
void cpu_bits_to_string_vars(Environment *_environment)
Definition z80.c:7201
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 z80.c:2722
void cpu_convert_string_into_8bit(Environment *_environment, char *_string, char *_len, char *_value)
Definition z80.c:6385
void cpu_inc_16bit(Environment *_environment, char *_variable)
Definition z80.c:5889
void cpu_logical_or_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5549
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 z80.c:3588
void cpu_address_table_lookup(Environment *_environment, char *_table, int _count)
Definition z80.c:9402
void cpu_ztoa(Environment *_environment)
Definition z80.c:102
void cpu_random(Environment *_environment, char *_entropy)
Definition z80.c:5336
void cpu_move_32bit_unsigned_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9667
void cpu_compare_and_branch_8bit(Environment *_environment, char *_source, char *_destination, char *_label, int _positive)
Definition z80.c:829
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 z80.c:904
void cpu_ctoa(Environment *_environment)
Definition z80.c:119
void cpu_move_16bit_indirect2_8bit(Environment *_environment, char *_value, char *_offset, char *_source)
Definition z80.c:6614
void cpu_float_single_from_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition z80.c:9075
void cpu_math_sub_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition z80.c:4401
void cpu_float_single_cmp(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:9177
void cpu_move_8bit_signed_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9496
void cpu_math_div2_const_nbit(Environment *_environment, char *_source, int _steps, int _bits, char *_remainder)
Definition z80.c:4529
void cpu_store_8bit_with_offset(Environment *_environment, char *_destination, int _value, int _offset)
Definition z80.c:731
void cpu_busy_wait(Environment *_environment, char *_timing)
Definition z80.c:5434
void cpu_greater_than_memory(Environment *_environment, char *_source, char *_destination, char *_size, char *_result, int _equal)
Definition z80.c:6235
void cpu_store_32bit(Environment *_environment, char *_destination, int _value)
Z80: emit code to store 32 bit
Definition z80.c:2904
void cpu_peekw(Environment *_environment, char *_address, char *_target)
Definition z80.c:240
void cpu_flip(Environment *_environment, char *_source, char *_size, char *_destination)
Definition z80.c:6516
void cpu_move_8bit(Environment *_environment, char *_source, char *_destination)
Z80: emit code to move 8 bit
Definition z80.c:684
void cpu_beq(Environment *_environment, char *_label)
Z80: emit code to make long conditional jump
Definition z80.c:150
void cpu_compare_16bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
Z80: emit code to compare two 16 bit values
Definition z80.c:1708
void cpu_peek(Environment *_environment, char *_address, char *_target)
Definition z80.c:204
void cpu_float_fast_add(Environment *_environment, char *_x, char *_y, char *_result)
Definition z80.c:8754
void cpu_convert_string_into_16bit(Environment *_environment, char *_string, char *_len, char *_value)
Definition z80.c:6395
void cpu_float_single_sin(Environment *_environment, char *_angle, char *_result)
Definition z80.c:9235
void cpu_not_8bit(Environment *_environment, char *_value, char *_result)
Definition z80.c:5813
void cpu_math_div_8bit_to_8bit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _signed)
Definition z80.c:6838
void cpu_dsdescriptor(Environment *_environment, char *_index, char *_address, char *_size)
Definition z80.c:7414
void cpu_math_add_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition z80.c:4282
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 z80.c:808
void cpu_xor_16bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition z80.c:5665
void cpu_xor_16bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition z80.c:5685
void cpu_float_single_neg(Environment *_environment, char *_value, char *_result)
Definition z80.c:9207
void cpu_float_double_from_double_to_int_array(Environment *_environment, double _value, int _result[])
Definition z80.c:8577
void cpu_swap_16bit(Environment *_environment, char *_left, char *_right)
Definition z80.c:5775
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 z80.c:858
void cpu_math_div_32bit_to_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _signed)
Definition z80.c:3134
void cpu_greater_than_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _bits)
Definition z80.c:4213
void cpu_number_to_string_vars(Environment *_environment)
Definition z80.c:7108
void cpu_float_fast_to_string(Environment *_environment, char *_x, char *_string, char *_string_size)
Definition z80.c:8581
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 z80.c:3762
void cpu_dsfill_value(Environment *_environment, char *_string, int _value)
Definition z80.c:9791
void cpu_dsassign_string(Environment *_environment, char *_string, char *_copy)
Definition z80.c:7451
void cpu_move_8bit_signed_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9462
void cpu_move_8bit_unsigned_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition z80.c:9485
void cpu_compare_memory_size(Environment *_environment, char *_source, char *_destination, int _size, char *_result, int _equal)
Definition z80.c:6137
void cpu_float_fast_mod1(Environment *_environment, char *_value, char *_result)
Definition z80.c:9013
void cpu_math_add_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, int _bits)
Definition z80.c:4303
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 z80.c:1278
void cpu_flip_8bit(Environment *_environment, char *_source, char *_destination)
Definition z80.c:6498
void cpu_blit_initialize(Environment *_environment)
Definition z80.c:7887
void cpu_less_than_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition z80.c:1989