ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
_infrastructure.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#ifdef _WIN32
36 #include <windows.h>
37 #include <fileapi.h>
38 #include <sysinfoapi.h>
39 #include <errhandlingapi.h>
40#endif
41
42#include <math.h>
43#include <ctype.h>
44#include <errno.h>
45#include <stdio.h>
46#include <stdarg.h>
47
48#include "../../ugbc.h"
49
50/****************************************************************************
51 * CODE SECTION
52 ****************************************************************************/
53
54#if defined(__atari__)
55 char targetName[] = "atari";
56#elif defined(__atarixl__)
57 char targetName[] = "atarixl";
58#elif defined(__c64__)
59 char targetName[] = "c64";
60#elif defined(__plus4__)
61 char targetName[] = "plus4";
62#elif defined(__c16__)
63 char targetName[] = "c16";
64#elif defined(__zx__)
65 char targetName[] = "zx";
66#elif defined(__coco__)
67 char targetName[] = "coco";
68#elif defined(__cocob__)
69 char targetName[] = "cocob";
70#elif defined(__coco3__)
71 char targetName[] = "coco3";
72#elif defined(__coco3b__)
73 char targetName[] = "coco3b";
74#elif defined(__d32__)
75 char targetName[] = "d32";
76#elif defined(__d32b__)
77 char targetName[] = "d32b";
78#elif defined(__d64__)
79 char targetName[] = "d64";
80#elif defined(__d64b__)
81 char targetName[] = "d64b";
82#elif defined(__gb__)
83 char targetName[] = "gb";
84#elif defined(__pc128op__)
85 char targetName[] = "pc128op";
86#elif defined(__to8__)
87 char targetName[] = "to8";
88#elif defined(__mo5__)
89 char targetName[] = "mo5";
90#elif defined(__vic20__)
91 char targetName[] = "vic20";
92#elif defined(__msx1__)
93 char targetName[] = "msx1";
94#elif defined(__coleco__)
95 char targetName[] = "coleco";
96#elif defined(__pccga__)
97 char targetName[] = "pccga";
98#elif defined(__sc3000__)
99 char targetName[] = "sc3000";
100#elif defined(__sg1000__)
101 char targetName[] = "sg1000";
102#elif defined(__cpc__)
103 char targetName[] = "cpc";
104#elif defined(__c128__)
105 char targetName[] = "c128";
106#elif defined(__c128z__)
107 char targetName[] = "c128z";
108#elif defined(__vg5000__)
109 char targetName[] = "vg5000";
110#elif defined(__c64reu__)
111 char targetName[] = "c64reu";
112#elif defined(__pc1403__)
113 char targetName[] = "pc1403";
114#elif defined(__vz200__)
115 char targetName[] = "vz200";
116#endif
117
118#define strcmp_nocase strcasecmp
119
120extern RGBi SYSTEM_PALETTE[];
121
126 "CODE",
127 "VARIABLES",
128 "TEMPORARY",
129 "DATA",
130 "STRINGS"
131};
132
133char DATATYPE_AS_STRING[][16] = {
134 "(undef)",
135 "BYTE",
136 "SBYTE",
137 "WORD",
138 "SWORD",
139 "DWORD",
140 "SDWORD",
141 "ADDRESS",
142 "POSITION",
143 "COLOR",
144 "STRING",
145 "BUFFER",
146 "ARRAY",
147 "DSTRING",
148 "MOB",
149 "IMAGE",
150 "THREAD",
151 "IMAGES",
152 "CHAR",
153 "SPRITE",
154 "TILE",
155 "TILES",
156 "TILESET",
157 "SEQUENCE",
158 "MUSIC",
159 "BLIT",
160 "FLOAT",
161 "TILEMAP",
162 "BIT",
163 "MSPRITE",
164 "DOJOKA",
165 "IMAGEREF",
166 "PATH",
167 "VECTOR",
168 "TYPE",
169 "NUMBER"
170};
171
173 "bin",
174 "prg",
175 "xex",
176 "k7 (original)",
177 "k7 (new)",
178 "tap",
179 "cas",
180 "rom",
181 "d64",
182 "dsk",
183 "atr",
184 "reu",
185 "ram",
186 "sddrive"
187};
188
189void memory_area_assign( MemoryArea * _first, Variable * _variable ) {
190
191 int neededSpace = 0;
192
193 if ( _variable->type == VT_TARRAY ) {
194 neededSpace = _variable->size;
195 } else if ( _variable->type == VT_DSTRING ) {
196 neededSpace = 1;
197 } else if ( _variable->type == VT_IMAGEREF ) {
198 neededSpace = 14;
199 } else {
200 neededSpace = VT_BITWIDTH( _variable->type ) ? ( VT_BITWIDTH( _variable->type ) >> 3 ) : _variable->size;
201 }
202
203 if ( neededSpace == 0 ) return;
204
205 MemoryArea * actual = _first;
206 while( actual ) {
207 int enoughSpace = actual->size > neededSpace;
208 if ( actual->type == MAT_RAM ) {
209 if ( _variable->type == VT_STRING || _variable->type == VT_BUFFER || _variable->type == VT_IMAGE || _variable->type == VT_IMAGES || _variable->type == VT_SEQUENCE || _variable->type == VT_MUSIC ) {
210 enoughSpace = 0;
211 }
212 }
213 if ( enoughSpace ) {
214 actual->size -= neededSpace;
215 _variable->memoryArea = actual;
216 _variable->absoluteAddress = actual->current;
217 actual->current += neededSpace;
218 break;
219 }
220 actual = actual->next;
221 }
222
223}
224
225void memory_area_unassign( MemoryArea * _first, Variable * _variable ) {
226
227 int neededSpace = 0;
228
229 if ( _variable->type == VT_TARRAY ) {
230 neededSpace = _variable->size;
231 } else if ( _variable->type == VT_DSTRING ) {
232 neededSpace = 1;
233 } else {
234 neededSpace = VT_BITWIDTH( _variable->type ) ? ( VT_BITWIDTH( _variable->type ) >> 3 ) : _variable->size;
235 }
236
237 if ( neededSpace == 0 ) return;
238
239 MemoryArea * actual = _variable->memoryArea;
240
241 if ( actual ) {
242 if ( ( actual->current - neededSpace ) == _variable->absoluteAddress ) {
243 actual->size += neededSpace;
244 _variable->memoryArea = NULL;
245 _variable->absoluteAddress = 0;
246 actual->current -= neededSpace;
247 }
248 }
249}
250
251Bank * bank_find( Bank * _first, char * _name ) {
252 Bank * actual = _first;
253 while( actual ) {
254 if ( strcmp( actual->name, _name ) == 0 ) {
255 break;
256 }
257 actual = actual->next;
258 }
259 return actual;
260}
261
262static void variable_reset_pool( Environment * _environment, Variable * _pool ) {
263 Variable * actual = _pool;
264 while( actual ) {
265 if ( actual->locked == 0 ) {
266 if ( actual->used && actual->type != VT_DSTRING ) {
267 actual->used = 0;
268 if ( actual->initializedByConstant ) {
269 outline1("; V %s", actual->realName );
270 } else {
271 outline1("; Q %s", actual->realName );
272 }
273 }
274 }
275 actual = actual->next;
276 }
277}
278
279static Variable * variable_find_by_realname( Variable * _first, char * _name ) {
280
281 Variable * actual = _first;
282 while( actual ) {
283 if ( strcmp( actual->realName, _name ) == 0 ) {
284 break;
285 }
286 actual = actual->next;
287 }
288 return actual;
289}
290
291static Variable * variable_find( Variable * _first, char * _name ) {
292
293 Variable * actual = _first;
294 while( actual ) {
295 if ( strcmp( actual->name, _name ) == 0 ) {
296 break;
297 }
298 actual = actual->next;
299 }
300 return actual;
301}
302
303static void variable_remove( Variable * _first, char * _name ) {
304
305 Variable * previous = NULL;
306 Variable * actual = _first;
307 while( actual ) {
308 if ( strcmp( actual->name, _name ) == 0 ) {
309 break;
310 }
311 previous = actual;
312 actual = actual->next;
313 }
314 if ( previous ) {
315 previous->next = actual->next;
316 } else {
317 _first->next = actual->next;
318 }
319
320}
321
322static Variable * variable_find_first_unused( Variable * _first, VariableType _type, FloatTypePrecision _precision ) {
323 Variable * actual = _first;
324 while( actual ) {
325 if ( actual->used || ( actual->type != _type ) ) {
326 actual = actual->next;
327 } else if ( actual->type == VT_FLOAT && ( actual->precision != _precision ) ) {
328 actual = actual->next;
329 } else {
330 break;
331 }
332 }
333 return actual;
334}
335
336static Constant * constant_find_by_realname( Constant * _first, char * _name ) {
337
338 Constant * actual = _first;
339 while( actual ) {
340 if ( strcmp( actual->realName, _name ) == 0 ) {
341 break;
342 }
343 actual = actual->next;
344 }
345 return actual;
346}
347
348Constant * constant_create( Environment * _environment, char * _name ) {
349 Constant * c3 = malloc( sizeof( Constant ) );
350 memset( c3, 0, sizeof( Constant ) );
352 memset( c3->name, 0, MAX_TEMPORARY_STORAGE );
353 if ( _name ) {
354 c3->name = strdup( _name );
355 } else {
356 sprintf( c3->name, "tempconst%d", UNIQUE_ID );
357 }
358 c3->realName = strdup( c3->name );
359
360 Constant * constLast = ((Environment *)_environment)->constants;
361 if ( constLast ) {
362 while( constLast->next ) {
363 constLast = constLast->next;
364 }
365 constLast->next = c3;
366 } else {
367 ((Environment *)_environment)->constants = c3;
368 }
369
370 return c3;
371}
372
373Constant * constant_find( Environment * _environment, char * _name ) {
374
375 Constant * actual = ((Environment *)_environment)->constants;
376 while( actual ) {
377 if ( strcmp( actual->name, _name ) == 0 ) {
378 break;
379 }
380 actual = actual->next;
381 }
382 return actual;
383}
384
385static Offsetting * offsetting_by_size( Offsetting * _first, int _size ) {
386
387 Offsetting * actual = _first;
388 while( actual ) {
389 if ( actual->size == _size ) {
390 break;
391 }
392 actual = actual->next;
393 }
394 return actual;
395}
396
397Offsetting * offsetting_size_count( Environment * _environment, int _size, int _count ) {
398
399 Offsetting * actual = offsetting_by_size( _environment->offsetting, _size );
400 if ( ! actual ) {
401 actual = malloc( sizeof( Offsetting ) );
402 memset( actual, 0, sizeof( Offsetting ) );
403 actual->size = _size;
404 actual->count = _count;
405 actual->next = _environment->offsetting;
406 _environment->offsetting = actual;
407 } else {
408 if ( actual->count < _count ) {
409 actual->count = _count;
410 }
411 }
412
413 return actual;
414
415}
416
417static void error_out_of_boundary( Environment * _environment ) {
418
419 Variable * message = variable_temporary( _environment, VT_STRING, "(message)" );
420 variable_store_string( _environment, message->name, "Out of boundary access" );
421 error( _environment, message->name );
422
423}
424
425static int calculate_cast_type_best_fit( Environment * _environment, int _type1, int _type2 ) {
426
427 if ( _type1 == VT_FLOAT || _type2 == VT_FLOAT ) {
428 return VT_FLOAT;
429 } else if ( _type1 == VT_NUMBER || _type2 == VT_NUMBER ) {
430 return VT_NUMBER;
431 } else {
432 if ( VT_SIGNED( _type1 ) != VT_SIGNED( _type2 ) ) {
433 int bits1 = VT_BITWIDTH( _type1 ) - VT_SIGNED( _type1 );
434 int bits2 = VT_BITWIDTH( _type2 ) - VT_SIGNED( _type2 );
435 int type = 0;
436 if ( bits1 < bits2 ) {
437 type = VT_SIGN( _type2 );
438 } else if ( bits2 < bits1 ) {
439 type = VT_SIGN( _type1 );
440 } else {
441 return VT_SIGN( VT_MAX_BITWIDTH_TYPE( _type1, _type2 ) );
442 }
443 return type;
444 } else {
445 if ( VT_SIGNED( _type1 ) || VT_SIGNED( _type2 ) ) {
446 return VT_SIGN( VT_MAX_BITWIDTH_TYPE( _type1, _type2 ) );
447 } else {
448 return VT_MAX_BITWIDTH_TYPE( _type1, _type2 );
449 }
450 }
451 }
452
453}
454
455void offsetting_add_variable_reference( Environment * _environment, Offsetting * _first, Variable * _var, int _sequence ) {
456
457 OffsettingVariable * offsettingVariable = malloc( sizeof( OffsettingVariable ) );
458 memset( offsettingVariable, 0, sizeof( OffsettingVariable ) );
459 offsettingVariable->variable = _var;
460 offsettingVariable->sequence = _sequence;
461
462 offsettingVariable->next = _first->variables;
463 _first->variables = offsettingVariable;
464
465}
466
467void variable_global( Environment * _environment, char * _pattern ) {
468
469 Pattern * pattern = malloc( sizeof( Pattern ) ) ;
470 memset( pattern, 0, sizeof( Pattern ) );
471
472 pattern->pattern = strdup( _pattern );
473 pattern->next = _environment->globalVariablePatterns;
474 _environment->globalVariablePatterns = pattern;
475
476}
477
478static int variable_is_global( Environment * _environment, char * _name ) {
479
480 int isGlobal = 0;
481
482 // Has the variable the "form" of a parameter?
483 // In that case, it is global by definition.
484
485 if ( strstr( _name, "__" ) != NULL ) {
486 isGlobal = 1;
487 }
488
489 if ( !isGlobal ) {
490
491 // Has the variable a "global" pattern?
492
493 Pattern * current = _environment->globalVariablePatterns;
494
495 while( current ) {
496 if ( pattern_match( current->pattern, _name ) ) {
497 isGlobal = 1;
498 break;
499 }
500 current = current->next;
501 }
502
503 }
504
505 return isGlobal;
506
507}
508
521Variable * variable_retrieve_internal( Environment * _environment, char * _name, int _mandatory ) {
522
523 // Try to retrieve a variable in a rational way.
524
525 Variable * var = NULL;
526
527 // Check if the variable is global or not.
528
529 int isGlobal = variable_is_global( _environment, _name );
530
531 // If the variable is not global and we are inside a procedure...
532
533 if ( _environment->procedureName && !isGlobal ) {
534
535 // Look for parameters
536
537 char parameterName[MAX_TEMPORARY_STORAGE]; sprintf( parameterName, "%s__%s", _environment->procedureName, _name );
538 var = variable_find( _environment->variables, parameterName );
539
540 // If not found, look for variable inside the set of temporary variables
541 // for this specific procedure.
542
543 if ( !var ) {
544 var = variable_find( _environment->tempVariables[_environment->currentProcedure], _name );
545 }
546
547 // If not found, take a look to the resident ones.
548
549 if ( !var ) {
550 var = variable_find( _environment->tempResidentVariables, _name );
551 }
552
553 // Again, if not found, take a look into the variables for this specific procedure.
554
555 if ( !var ) {
556 var = variable_find( _environment->procedureVariables, _name );
557 }
558
559 } else {
560
561 // Look for parameters (allso if global, since it can be overloaded)
562
563 if ( _environment->procedureName ) {
564
565 char parameterName[MAX_TEMPORARY_STORAGE]; sprintf( parameterName, "%s__%s", _environment->procedureName, _name );
566 var = variable_find( _environment->variables, parameterName );
567
568 }
569
570 // If not found, look for variable inside the set of temporary variables
571 // for this specific procedure.
572
573 if ( !var ) {
574 var = variable_find( _environment->tempVariables[_environment->currentProcedure], _name );
575 }
576
577 // If not found, take a look to the resident ones.
578
579 if ( !var ) {
580 var = variable_find( _environment->tempResidentVariables, _name );
581 }
582
583 // Look for variable inside the set of temporary variables
584 // for the main program.
585
586 if ( !var ) {
587 var = variable_find( _environment->tempVariables[0], _name );
588 }
589
590 // Again, if not found, take a look into the variables
591 // for the program.
592
593 if ( !var ) {
594 var = variable_find( _environment->variables, _name );
595 }
596
597 }
598
599 // If the variable has been found, we will convert it into the target
600 // data type if it is different from the source one.
601
602 if ( !var && _mandatory ) {
603 CRITICAL_VARIABLE( _name );
604 }
605
606 return var;
607
608}
609
610static Variable * variable_define_internal( Environment * _environment, Variable ** _variables, char * _name, char * _procedure_name, VariableType _type, int _value ) {
611
612 Variable * var = malloc( sizeof( Variable ) );
613 memset( var, 0, sizeof( Variable ) );
614 var->name = strdup( _name );
615 var->bankAssigned = -1;
616
617 if ( _procedure_name ) {
618 var->realName = malloc( strlen( _name ) + strlen( _procedure_name ) + 3 );
619 strcopy( var->realName, "_" );
620 strcat( var->realName, _procedure_name );
621 strcat( var->realName, "_" );
622 strcat( var->realName, var->name );
623 } else {
624 var->realName = malloc( strlen( _name ) + 2 );
625 strcopy( var->realName, "_" );
626 strcat( var->realName, var->name );
627 }
628
629 var->type = _type;
630 var->value = _value;
631 var->initialValue = _value;
632 var->bank = _environment->banks[BT_VARIABLES];
633 var->used = 1;
634 var->locked = 0;
635 var->precision = _environment->floatType.precision;
636
637 if ( var->type == VT_BIT ) {
638 var->bitPosition = _environment->bitPosition;
639 var->bitByte = _environment->bitByte;
640 ++_environment->bitPosition;
641 if ( _environment->bitPosition == 8 ) {
642 _environment->bitPosition = 0;
643 ++_environment->bitByte;
644 }
645 }
646
647 Variable * varLast = *_variables;
648 if ( varLast ) {
649 while( varLast->next ) {
650 varLast = varLast->next;
651 }
652 varLast->next = var;
653 } else {
654 *_variables = var;
655 }
656
657 if ( var->type == VT_TARRAY ) {
658 memcpy( var->arrayDimensionsEach, ((struct _Environment *)_environment)->arrayDimensionsEach, sizeof( int ) * MAX_ARRAY_DIMENSIONS );
659 var->arrayDimensions = ((struct _Environment *)_environment)->arrayDimensions;
660 }
661 if ( !_environment->disableMemoryAreas ) {
662 memory_area_assign( _environment->memoryAreas, var );
663 }
664
665 return var;
666
667}
668
702/* <usermanual>
703@keyword VAR
704
705@english
706
707@italian
708
709@syntax VAR variable [AS datatype] [, variable [AS datatype] [ , variable [AS datatype] ] ]
710@syntax VAR variable [AS datatype] = constant
711
712@example VAR x = 42
713
714@alias DIM
715
716@target all
717</usermanual> */
718Variable * variable_define( Environment * _environment, char * _name, VariableType _type, int _value ) {
719
720 // Let's manage the variable definition in a more rational way.
721
722 int isGlobal = 0;
723
724 // First of all, avoid to define a variable if a constant with the same
725 // name already exists.
726
727 if (_environment->constants) {
728 Constant * c = constant_find( _environment, _name );
729 if ( c ) {
731 }
732 }
733
734 isGlobal = variable_is_global( _environment, _name );
735
736 // Now, we have to look if the variable is already defined in the
737 // correct context.
738
739 Variable * var = variable_retrieve_internal( _environment, _name, 0 );
740
741 // If the variable already exists, we can use it if it is of the
742 // very same type. This is allowed in BASIC programs.
743
744 if ( var ) {
745 if ( ( var->type != _type ) || ( var->type == VT_TARRAY && var->arrayType != _type ) ) {
747 } else {
748 return var;
749 }
750 }
751
752 // Now, you can define a variable of STRING type, but it will be
753 // always a dynamic string. Static string cannot be variables.
754 // if ( _type == VT_STRING ) {
755 // _type = VT_DSTRING;
756 // }
757
758 // Global variable must be defined in a different way from local variables.
759
760 if ( _environment->procedureName && !isGlobal ) {
761
762 var = variable_define_internal( _environment, &_environment->procedureVariables, _name, _environment->procedureName, _type, _value );
763
764 }
765
766 // Here we define a local variable
767
768 else {
769
770 var = variable_define_internal( _environment, &_environment->variables, _name, NULL, _type, _value );
771
772 }
773
774 return var;
775
776}
777
778Variable * variable_import( Environment * _environment, char * _name, VariableType _type, int _size_or_value ) {
779
780 if (_environment->constants) {
781 Constant * c = constant_find( _environment, _name );
782 if ( c ) {
784 }
785 }
786
787 Variable * var = variable_find( _environment->variables, _name );
788 if ( var ) {
789 if ( var->type != _type ) {
791 }
792 } else {
793 var = malloc( sizeof( Variable ) );
794 memset( var, 0, sizeof( Variable ) );
795 var->name = strdup( _name );
796 var->bankAssigned = -1;
797#if defined(cpu6809)||defined(cpu6309)
798 if (
799 strcmp( _name, "PEN" ) == 0 ||
800 strcmp( _name, "XCURSYS" ) == 0 ||
801 strcmp( _name, "YCURSYS" ) == 0
802 ) {
803 var->realName = malloc( strlen( _name ) + 2 );
804 strcopy( var->realName, "<" );
805 strcat( var->realName, var->name );
806 } else {
807 var->realName = strdup( _name );
808 }
809#else
810 var->realName = strdup( _name );
811#endif
812
813 var->type = _type;
814 if ( var->type == VT_BUFFER ) {
815 var->size = _size_or_value;
816 } else {
817 var->value = _size_or_value;
818 var->initialValue = _size_or_value;
819 }
820 var->precision = _environment->floatType.precision;
821
822 if ( var->type == VT_BIT ) {
823 var->bitPosition = _environment->bitPosition;
824 var->bitByte = _environment->bitByte;
825 ++_environment->bitPosition;
826 if ( _environment->bitPosition == 8 ) {
827 _environment->bitPosition = 0;
828 ++_environment->bitByte;
829 }
830 }
831
832 var->bank = NULL;
833 Variable * varLast = _environment->variables;
834 if ( varLast ) {
835 while( varLast->next ) {
836 varLast = varLast->next;
837 }
838 varLast->next = var;
839 } else {
840 _environment->variables = var;
841 }
842 }
843 var->imported = 1;
844 var->used = 1;
845 var->locked = 1;
846 return var;
847}
848
849Variable * variable_export( Environment * _environment, char * _name, VariableType _type, int _size_or_value ) {
850
851 Variable * var = variable_find( _environment->variables, _name );
852 if ( var ) {
853 if ( var->type != _type ) {
855 }
856 } else {
857 var = malloc( sizeof( Variable ) );
858 memset( var, 0, sizeof( Variable ) );
859 var->name = strdup( _name );
860 var->bankAssigned = -1;
861#if defined(cpu6809)||defined(cpu6309)
862 if (
863 strcmp( _name, "PEN" ) == 0 ||
864 strcmp( _name, "XCURSYS" ) == 0 ||
865 strcmp( _name, "YCURSYS" ) == 0
866 ) {
867 var->realName = malloc( strlen( _name ) + 2 );
868 strcopy( var->realName, "<" );
869 strcat( var->realName, var->name );
870 } else {
871 var->realName = strdup( _name );
872 }
873#else
874 var->realName = strdup( _name );
875#endif
876
877 var->type = _type;
878 if ( var->type == VT_BUFFER ) {
879 var->size = _size_or_value;
880 } else {
881 var->value = _size_or_value;
882 }
883 var->precision = _environment->floatType.precision;
884
885 if ( var->type == VT_BIT ) {
886 var->bitPosition = _environment->bitPosition;
887 var->bitByte = _environment->bitByte;
888 ++_environment->bitPosition;
889 if ( _environment->bitPosition == 8 ) {
890 _environment->bitPosition = 0;
891 ++_environment->bitByte;
892 }
893 }
894
895 var->bank = NULL;
896 Variable * varLast = _environment->variables;
897 if ( varLast ) {
898 while( varLast->next ) {
899 varLast = varLast->next;
900 }
901 varLast->next = var;
902 } else {
903 _environment->variables = var;
904 }
905 }
906 var->imported = 0;
907 var->used = 1;
908 var->locked = 1;
909 return var;
910}
911
912Variable * variable_define_no_init( Environment * _environment, char * _name, VariableType _type ) {
913
914 if (_environment->constants) {
915 Constant * c = constant_find( _environment, _name );
916 if ( c ) {
918 }
919 }
920
921 Variable * var = variable_find( _environment->variables, _name );
922 if ( var ) {
923 if ( var->type != _type ) {
925 }
926 } else {
927 var = malloc( sizeof( Variable ) );
928 memset( var, 0, sizeof( Variable ) );
929 var->name = strdup( _name );
930 var->bankAssigned = -1;
931 var->realName = malloc( strlen( _name ) + strlen( var->name ) + 2 ); strcopy( var->realName, "_" ); strcat( var->realName, var->name );
932 var->type = _type;
933
934 if ( var->type == VT_BIT ) {
935 var->bitPosition = _environment->bitPosition;
936 var->bitByte = _environment->bitByte;
937 ++_environment->bitPosition;
938 if ( _environment->bitPosition == 8 ) {
939 _environment->bitPosition = 0;
940 ++_environment->bitByte;
941 }
942 }
943
944 var->bank = _environment->banks[BT_VARIABLES];
945 Variable * varLast = _environment->variables;
946 if ( varLast ) {
947 while( varLast->next ) {
948 varLast = varLast->next;
949 }
950 varLast->next = var;
951 } else {
952 _environment->variables = var;
953 }
954 if ( var->type == VT_TARRAY ) {
955 memcpy( var->arrayDimensionsEach, ((struct _Environment *)_environment)->arrayDimensionsEach, sizeof( int ) * MAX_ARRAY_DIMENSIONS );
956 var->arrayDimensions = ((struct _Environment *)_environment)->arrayDimensions;
957 }
958 if ( !_environment->disableMemoryAreas ) {
959 memory_area_assign( _environment->memoryAreas, var );
960 }
961 }
962 var->used = 1;
963 var->locked = 0;
964 return var;
965}
966
967Variable * variable_retrieve_by_realname( Environment * _environment, char * _name ) {
968
969 Variable * var = NULL;
970 if ( _environment->procedureName ) {
971 var = variable_find_by_realname( _environment->tempVariables[_environment->currentProcedure], _name );
972 } else {
973 var = variable_find_by_realname( _environment->tempVariables[0], _name );
974 }
975
976 if ( ! var ) {
977 var = variable_find_by_realname( _environment->tempResidentVariables, _name );
978 }
979 if ( ! var ) {
980 var = variable_find_by_realname( _environment->procedureVariables, _name );
981 }
982 if ( ! var ) {
983 var = variable_find_by_realname( _environment->variables, _name );
984 }
985 return var;
986}
987
988Variable * variable_retrieve( Environment * _environment, char * _name ) {
989
990 return variable_retrieve_internal( _environment, _name, 1 );
991
992}
993
994int variable_exists( Environment * _environment, char * _name ) {
995
996 return variable_retrieve_internal( _environment, _name, 0 ) != NULL;
997
998}
999
1000int variable_exists_by_realname( Environment * _environment, char * _name ) {
1001
1002 return variable_retrieve_by_realname( _environment, _name ) != NULL;
1003
1004}
1005
1006int variable_delete( Environment * _environment, char * _name ) {
1007
1008 Variable * var = NULL;
1009 if ( _environment->procedureName ) {
1010 var = variable_find( _environment->tempVariables[_environment->currentProcedure], _name );
1011 if ( var ) {
1012 variable_remove( _environment->tempVariables[_environment->currentProcedure], _name );
1013 return 1;
1014 }
1015 } else {
1016 var = variable_find( _environment->tempVariables[0], _name );
1017 if ( var ) {
1018 variable_remove( _environment->tempVariables[0], _name );
1019 return 1;
1020 }
1021 }
1022 if ( ! var ) {
1023 var = variable_find( _environment->tempResidentVariables, _name );
1024 if ( var ) {
1025 variable_remove( _environment->tempResidentVariables, _name );
1026 return 1;
1027 }
1028 }
1029 if ( ! var ) {
1030 var = variable_find( _environment->variables, _name );
1031 if ( var ) {
1032 variable_remove( _environment->variables, _name );
1033 return 1;
1034 }
1035 }
1036 return 0;
1037
1038}
1039
1040Variable * variable_retrieve_or_define( Environment * _environment, char * _name, VariableType _type, int _value ) {
1041
1042 // Try to retrieve / create a variable in a rational way.
1043
1044 // Check if the variable is global or not.
1045
1046 int isGlobal = variable_is_global( _environment, _name );
1047
1048 Variable * var = variable_retrieve_internal( _environment, _name, 0 );
1049
1050 // If the variable has been found, we will convert it into the target
1051 // data type if it is different from the source one.
1052
1053 if ( var ) {
1054
1055 if ( var->initializedByConstant && ( _type != VT_DSTRING && _type != VT_STRING && _type != VT_FLOAT && _type != VT_BIT && _type != VT_NUMBER ) ) {
1056 if (
1057 ( VT_BITWIDTH( var->type ) != VT_BITWIDTH( _type ) )
1058 ) {
1059 Variable * varNew = variable_temporary( _environment, _type, "(temp)");
1060 variable_store( _environment, varNew->name, var->value );
1061 varNew->initializedByConstant = 1;
1062 var = varNew;
1063 }
1064 } else {
1065 if (
1066 ( VT_BITWIDTH( var->type ) != VT_BITWIDTH( _type ) )
1067 &&
1068 ( ( VT_BITWIDTH( _type ) > 0 ) || ( _type == VT_FLOAT ) )
1069 &&
1070 ( ( VT_BITWIDTH( var->type ) > 0 ) || ( var->type == VT_FLOAT ) )
1071 ) {
1072 var = variable_cast( _environment, var->name, _type );
1073 }
1074 }
1075 return var;
1076 }
1077
1078 // When retrieving a variable of type STRING, ad it does not exists,
1079 // we are going to redefine it as a dynamic string.
1080
1081 if ( _type == VT_STRING ) {
1082 _type = VT_DSTRING;
1083 }
1084
1085 // If the variables has been detected as global,
1086 // we must define it. But, if we are inside a procedure,
1087 // we have to define it without initialization.
1088 if ( _environment->procedureName && !isGlobal ) {
1089
1090 // If OPTION EXPLICIT is on, we cannot define a (local) variable
1091 // if it is not already defined.
1092
1093 if ( !_environment->optionExplicit ) {
1094 var = variable_define_internal( _environment, &_environment->procedureVariables, _name, _environment->procedureName, _type, _value );
1095 } else {
1097 }
1098
1099 } else {
1100
1101 // If OPTION EXPLICIT is on, we cannot define a variable
1102 // if it is not already defined.
1103
1104 if ( !_environment->optionExplicit ) {
1105 if ( _environment->procedureName ) {
1106 var = variable_define_no_init( _environment, _name, _type );
1107 } else {
1108 var = variable_define_internal( _environment, &_environment->variables, _name, _environment->procedureName, _type, _value );
1109 }
1110 } else {
1112 }
1113
1114 }
1115
1116 return var;
1117
1118}
1119
1128void variable_reset( Environment * _environment ) {
1129 if ( _environment->procedureName ) {
1130 variable_reset_pool( _environment, _environment->tempVariables[_environment->currentProcedure] );
1131 } else {
1132 variable_reset_pool( _environment, _environment->tempVariables[0] );
1133 }
1134 outline0("; VSP" );
1135}
1136
1137// @bit2: ok
1138Variable * variable_array_type( Environment * _environment, char *_name, VariableType _type ) {
1139
1140 if (_environment->constants) {
1141 Constant * c = constant_find( _environment, _name );
1142 if ( c ) {
1144 }
1145 }
1146
1147 Variable * var = variable_retrieve( _environment, _name );
1148 if ( ! var ) {
1149 CRITICAL_VARIABLE( _name );
1150 }
1151 var->arrayType = _type;
1152 var->arrayPrecision = _environment->floatType.precision;
1153 int i=0,size=1;
1154 for( i=0; i<var->arrayDimensions; ++i ) {
1155 size *= var->arrayDimensionsEach[i];
1156 }
1157 if ( VT_BITWIDTH( var->arrayType ) > 1 ) {
1158 size *= ( VT_BITWIDTH( var->arrayType ) >> 3 );
1159 } else if ( var->arrayType == VT_DSTRING ) {
1160 size *= 1;
1161 } else if ( var->arrayType == VT_SPRITE ) {
1162 size *= 1;
1163 } else if ( var->arrayType == VT_MSPRITE ) {
1164 size *= 2;
1165 } else if ( var->arrayType == VT_DOJOKA ) {
1166 size *= 4;
1167 } else if ( var->arrayType == VT_IMAGEREF ) {
1168 size *= 16; // real: 14
1169 } else if ( var->arrayType == VT_PATH ) {
1170 size *= 16; // real: 16
1171 } else if ( var->arrayType == VT_VECTOR2 ) {
1172 size *= 4;
1173 } else if ( var->arrayType == VT_TILE ) {
1174 size *= 1;
1175 } else if ( var->arrayType == VT_TILES ) {
1176 size *= 4;
1177 } else if ( var->arrayType == VT_TYPE ) {
1178 int os = VT_OPTIMAL_SHIFT( var->typeType->size );
1179 size *= (1 << os);
1180 } else if ( var->arrayType == VT_BIT ) {
1181 size >>= 3 ;
1182 if ( _environment->bitPosition ) {
1183 _environment->bitPosition = 0;
1184 ++_environment->bitByte;
1185 }
1186 var->bitByte = _environment->bitByte;
1187 var->bitPosition = _environment->bitPosition;
1188 ++size;
1189 _environment->bitByte += size;
1190 _environment->bitPosition = 0;
1191 } else if ( var->arrayType == VT_FLOAT ) {
1193 } else if ( var->arrayType == VT_NUMBER ) {
1194 int os = VT_OPTIMAL_SHIFT( _environment->numberConfig.maxBytes );
1195 size *= (1 << os);
1196 } else {
1198 }
1199 var->size = size;
1200
1201}
1202
1203// @bit2: ok
1204static Variable * calculate_offset_in_array( Environment * _environment, char * _array ) {
1205
1206 Variable * array = variable_retrieve( _environment, _array );
1207
1208 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
1209 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
1210 }
1211
1212 Variable * base = variable_temporary( _environment, VT_WORD, "(base in array)");
1213 Variable * offset = variable_temporary( _environment, VT_WORD, "(offset in array)");
1214
1215 variable_store( _environment, offset->name, 0 );
1216
1217 int i,j;
1218
1219 if ( _environment->arrayIndexes[_environment->arrayNestedIndex] == 1 ) {
1220 if ( _environment->arrayIndexesEach[_environment->arrayNestedIndex][0] == NULL ) {
1221 if ( _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][0] >= array->arrayDimensionsEach[0] ) {
1223 }
1224 variable_add_inplace( _environment, offset->name, _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][0] );
1225 } else {
1226 Variable * index = variable_retrieve( _environment, _environment->arrayIndexesEach[_environment->arrayNestedIndex][0]);
1227 if ( _environment->checkBoundary ) {
1229 char checkBoundaryOk[MAX_TEMPORARY_STORAGE]; sprintf( checkBoundaryOk, "%s", label );
1230 Variable * checkBoundary = variable_less_than_const( _environment, index->name, array->arrayDimensionsEach[0], 0 );
1231 cpu_compare_and_branch_8bit_const( _environment, checkBoundary->realName, 0xff, checkBoundaryOk, 1 );
1232 error_out_of_boundary( _environment );
1233 cpu_label( _environment, checkBoundaryOk );
1234 }
1235 variable_add_inplace_vars( _environment, offset->name, index->name );
1236 }
1237 } else {
1238 for( i = 0; i<_environment->arrayIndexes[_environment->arrayNestedIndex]; ++i ) {
1239 int baseValue = 1;
1240 for( j=0; j<(_environment->arrayIndexes[_environment->arrayNestedIndex]-i-1); ++j ) {
1241 baseValue *= array->arrayDimensionsEach[j];
1242 }
1243 if ( _environment->arrayIndexesEach[_environment->arrayNestedIndex][array->arrayDimensions-i-1] == NULL ) {
1244 if ( _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][array->arrayDimensions-i-1] >= array->arrayDimensionsEach[array->arrayDimensions-i-1] ) {
1246 }
1247 variable_add_inplace( _environment, offset->name, _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][array->arrayDimensions-i-1] * baseValue );
1248 } else {
1249 Variable * index = variable_retrieve( _environment, _environment->arrayIndexesEach[_environment->arrayNestedIndex][array->arrayDimensions-i-1]);
1250 if(baseValue!=1) {
1251 variable_store( _environment, base->name, baseValue );
1252 Variable * additionalOffset = variable_mul( _environment, index->name, base->name );
1253 variable_add_inplace_vars( _environment, offset->name, additionalOffset->name );
1254 } else {
1255 variable_add_inplace_vars( _environment, offset->name, index->name );
1256 }
1257 }
1258 }
1259 }
1260
1261 return offset;
1262
1263}
1264
1265static Variable * variable_move_from_array_get_address( Environment * _environment, char * _array, char * _field ) {
1266
1268
1269 Variable * array = variable_retrieve( _environment, _array );
1270
1271 if ( array->type != VT_TARRAY ) {
1272 CRITICAL_NOT_ARRAY( _array );
1273 }
1274 Field * field = NULL;
1275 if ( _field ) {
1276 if ( array->arrayType != VT_TYPE ) {
1278 }
1279 if ( !array->typeType ) {
1281 }
1282 field = field_find( array->typeType, _field );
1283 if ( ! field ) {
1285 }
1286 }
1287
1288 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
1289 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
1290 }
1291
1292 Variable * offset = calculate_offset_in_array( _environment, array->name);
1293
1294 switch( array->arrayType ) {
1295 case VT_TYPE:
1296 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT(array->typeType->size) );
1297 break;
1298 case VT_PATH:
1299 offset = variable_sl_const( _environment, offset->name, 4 );
1300 break;
1301 case VT_VECTOR2:
1302 offset = variable_sl_const( _environment, offset->name, 2 );
1303 break;
1304 case VT_IMAGEREF:
1305 offset = variable_sl_const( _environment, offset->name, 4 );
1306 break;
1307 case VT_FLOAT:
1308 offset = variable_sl_const( _environment, offset->name, VT_FLOAT_NORMALIZED_POW2_WIDTH( array->arrayPrecision ) );
1309 break;
1310 case VT_NUMBER: {
1311 int os = VT_OPTIMAL_SHIFT( _environment->numberConfig.maxBytes );
1312 offset = variable_sl_const( _environment, offset->name, os );
1313 }
1314 break;
1315 case VT_STRING:
1316 CRITICAL_DATATYPE_UNSUPPORTED("array(a)", DATATYPE_AS_STRING[array->arrayType]);
1317 case VT_TILE:
1318 case VT_TILESET:
1319 case VT_SPRITE:
1320 case VT_DSTRING:
1321 offset = variable_sl_const( _environment, offset->name, 0 );
1322 break;
1323 case VT_MSPRITE:
1324 offset = variable_sl_const( _environment, offset->name, 1 );
1325 break;
1326 case VT_TILES:
1327 offset = variable_sl_const( _environment, offset->name, 2 );
1328 break;
1329 default:
1330 offset = variable_sl_const( _environment, offset->name, ( VT_BITWIDTH( array->arrayType ) >> 3 ) - 1 );
1331 break;
1332 }
1333
1334 if ( field ) {
1335 variable_add_inplace( _environment, offset->name, field->offset );
1336 }
1337
1338 if ( array->bankAssigned == -1 ) {
1339
1340 cpu_math_add_16bit_with_16bit( _environment, offset->realName, array->realName, offset->realName );
1341
1342 } else {
1343
1344 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
1345
1346 }
1347
1348 return offset;
1349
1350}
1351
1388Variable * variable_temporary( Environment * _environment, VariableType _type, char * _meaning ) {
1389
1390 // Make a rational way to define temporary variables.
1391
1392 Variable * var = NULL;
1393
1394 // The set of temporary.
1395
1396 Variable ** variableSet = NULL;
1397
1398 // We have a different set of temporary variables if we are inside
1399 // a procedure or outside.
1400
1401 if ( _environment->procedureName ) {
1402
1403 // Take the set of temporary variables inside the procedure.
1404
1405 variableSet = &_environment->tempVariables[_environment->currentProcedure];
1406
1407 } else {
1408
1409 // Take the set of temporary variables inside the program.
1410
1411 variableSet = &_environment->tempVariables[0];
1412
1413 }
1414
1415 // Take a look at the temporary variable, to see if any
1416 // temporary variable is available, inside the procedure.
1417
1418 var = variable_find_first_unused( *variableSet, _type, _environment->floatType.precision );
1419
1420 // If the var has been found, we change its meaning.
1421
1422 if ( var ) {
1423
1424 var->reflected = NULL;
1425 var->meaningName = ( _meaning) ? strdup( _meaning ) : NULL;
1426
1427 } else {
1428
1429 // Calculate the name of the temporary variable.
1430
1432 if ( _type == VT_STRING ) {
1433 sprintf(name, "Tstr%d", UNIQUE_ID);
1434 } else if ( _type == VT_BUFFER ) {
1435 sprintf(name, "Tbuf%d", UNIQUE_ID);
1436 } else if ( _type == VT_DOJOKA ) {
1437 sprintf(name, "Tdoj%d", UNIQUE_ID);
1438 } else if ( _type == VT_IMAGEREF ) {
1439 sprintf(name, "Timr%d", UNIQUE_ID);
1440 } else if ( _type == VT_PATH ) {
1441 sprintf(name, "Tpat%d", UNIQUE_ID);
1442 } else if ( _type == VT_VECTOR2 ) {
1443 sprintf(name, "Tvec%d", UNIQUE_ID);
1444 } else if ( _type == VT_IMAGE ) {
1445 sprintf(name, "Timg%d", UNIQUE_ID);
1446 } else if ( _type == VT_IMAGES ) {
1447 sprintf(name, "Timgs%d", UNIQUE_ID);
1448 } else if ( _type == VT_SEQUENCE ) {
1449 sprintf(name, "Tseq%d", UNIQUE_ID);
1450 } else if ( _type == VT_MUSIC ) {
1451 sprintf(name, "Tmus%d", UNIQUE_ID);
1452 } else if ( _type == VT_FLOAT ) {
1453 sprintf(name, "Tflt%d", UNIQUE_ID);
1454 } else if ( _type == VT_NUMBER ) {
1455 sprintf(name, "Tnum%d", UNIQUE_ID);
1456 } else if ( _type == VT_BIT ) {
1457 sprintf(name, "Tbit%d", UNIQUE_ID);
1458 } else {
1459 sprintf(name, "Ttmp%d", UNIQUE_ID);
1460 }
1461
1462 // Allocate the variable.
1463
1464 var = variable_define_internal( _environment, variableSet, name, _environment->procedureName, _type, 0 );
1465
1466 // Make it "locked" if the correct type.
1467
1468 if ( _type == VT_STRING ) {
1469 var->locked = 1;
1470 } else if ( _type == VT_BUFFER ) {
1471 var->locked = 1;
1472 } else if ( _type == VT_DOJOKA ) {
1473 var->locked = 1;
1474 } else if ( _type == VT_IMAGEREF ) {
1475 var->locked = 1;
1476 } else if ( _type == VT_PATH ) {
1477 var->locked = 1;
1478 } else if ( _type == VT_VECTOR2 ) {
1479 var->locked = 1;
1480 } else if ( _type == VT_IMAGE ) {
1481 var->locked = 1;
1482 } else if ( _type == VT_IMAGES ) {
1483 var->locked = 1;
1484 } else if ( _type == VT_SEQUENCE ) {
1485 var->locked = 1;
1486 } else if ( _type == VT_MUSIC ) {
1487 var->locked = 1;
1488 } else {
1489
1490 }
1491
1492 // Update the meaning of this temporary variable.
1493
1494 var->meaningName = _meaning ? strdup( _meaning ) : NULL;
1495
1496 // Assign the correct bank.
1497
1498 var->bank = _environment->banks[BT_TEMPORARY];
1499
1500 // Assign the correct memory ara.
1501
1502 if ( !_environment->disableMemoryAreas ) {
1503 memory_area_assign( _environment->memoryAreas, var );
1504 }
1505
1506 }
1507
1508 // Mark this variable as used and temporary.
1509
1510 var->used = 1;
1511 var->temporary = 1;
1512 var->initializedByConstant = 0;
1513
1514 return var;
1515
1516}
1517
1518Variable * variable_resident( Environment * _environment, VariableType _type, char * _meaning ) {
1519
1520 // Make a rational way to define resident variables.
1521
1522 Variable * var = NULL;
1523
1524 // The set of resident.
1525
1526 Variable ** variableSet = NULL;
1527
1528 // Take the set of resident variables inside the program.
1529
1530 variableSet = &_environment->tempResidentVariables;
1531
1532 // Calculate the name of the resident variable.
1533
1535 if ( _type == VT_STRING ) {
1536 sprintf(name, "Tstr%d", UNIQUE_ID);
1537 } else if ( _type == VT_BUFFER ) {
1538 sprintf(name, "Tbuf%d", UNIQUE_ID);
1539 } else if ( _type == VT_DOJOKA ) {
1540 sprintf(name, "Tdoj%d", UNIQUE_ID);
1541 } else if ( _type == VT_IMAGEREF ) {
1542 sprintf(name, "Timr%d", UNIQUE_ID);
1543 } else if ( _type == VT_PATH ) {
1544 sprintf(name, "Tpat%d", UNIQUE_ID);
1545 } else if ( _type == VT_VECTOR2 ) {
1546 sprintf(name, "Tvec%d", UNIQUE_ID);
1547 } else if ( _type == VT_IMAGE ) {
1548 sprintf(name, "Timg%d", UNIQUE_ID);
1549 } else if ( _type == VT_IMAGES ) {
1550 sprintf(name, "Timgs%d", UNIQUE_ID);
1551 } else if ( _type == VT_SEQUENCE ) {
1552 sprintf(name, "Tseq%d", UNIQUE_ID);
1553 } else if ( _type == VT_MUSIC ) {
1554 sprintf(name, "Tmus%d", UNIQUE_ID);
1555 } else if ( _type == VT_FLOAT ) {
1556 sprintf(name, "Tflt%d", UNIQUE_ID);
1557 } else if ( _type == VT_NUMBER ) {
1558 sprintf(name, "Tnum%d", UNIQUE_ID);
1559 } else if ( _type == VT_BIT ) {
1560 sprintf(name, "Tbit%d", UNIQUE_ID);
1561 } else {
1562 sprintf(name, "TRtmp%d", UNIQUE_ID);
1563 }
1564
1565 // Allocate the variable.
1566
1567 var = variable_define_internal( _environment, variableSet, name, NULL, _type, 0 );
1568
1569 // Make it "locked" if the correct type.
1570
1571 if ( _type == VT_STRING ) {
1572 var->locked = 1;
1573 } else if ( _type == VT_BUFFER ) {
1574 var->locked = 1;
1575 } else if ( _type == VT_DOJOKA ) {
1576 var->locked = 1;
1577 } else if ( _type == VT_IMAGEREF ) {
1578 var->locked = 1;
1579 } else if ( _type == VT_PATH ) {
1580 var->locked = 1;
1581 } else if ( _type == VT_VECTOR2 ) {
1582 var->locked = 1;
1583 } else if ( _type == VT_IMAGE ) {
1584 var->locked = 1;
1585 } else if ( _type == VT_IMAGES ) {
1586 var->locked = 1;
1587 } else if ( _type == VT_SEQUENCE ) {
1588 var->locked = 1;
1589 } else if ( _type == VT_MUSIC ) {
1590 var->locked = 1;
1591 } else {
1592
1593 }
1594
1595 // Update the meaning of this temporary variable.
1596
1597 var->meaningName = _meaning ? strdup( _meaning ) : NULL;
1598
1599 // Assign the correct bank.
1600
1601 var->bank = _environment->banks[BT_TEMPORARY];
1602
1603 // Assign the correct memory ara.
1604
1605 if ( !_environment->disableMemoryAreas ) {
1606 memory_area_assign( _environment->memoryAreas, var );
1607 }
1608
1609 // Mark this variable as used and temporary.
1610
1611 var->used = 1;
1612 var->temporary = 1;
1613 var->initializedByConstant = 0;
1614
1615 return var;
1616
1617}
1618
1636Variable * variable_cast( Environment * _environment, char * _source, VariableType _type ) {
1637
1638 Variable * source = variable_retrieve( _environment, _source );
1639
1640 if ( _type == VT_STRING ) {
1641 _type = VT_DSTRING;
1642 }
1643
1644 if ( source->type == _type ) {
1645 return source;
1646 }
1647
1648 Variable * target = variable_temporary( _environment, _type, "(generated for cast)" );
1649
1650 variable_move( _environment, source->name, target->name );
1651
1652 if ( source->initializedByConstant && VT_BITWIDTH( source->type ) > 1 && VT_BITWIDTH( target->type ) > 1 ) {
1653
1654 target->initializedByConstant = source->initializedByConstant;
1655
1656 switch( VT_BITWIDTH( source->type ) ) {
1657 case 32:
1658 switch( VT_BITWIDTH( target->type ) ) {
1659 case 32:
1660 target->value = source->value;
1661 break;
1662 case 16:
1663 target->value = ( source->value & 0xffff );
1664 break;
1665 case 8:
1666 target->value = ( source->value & 0xff );
1667 break;
1668 default:
1669 target->initializedByConstant = 0;
1670 }
1671 break;
1672 case 16:
1673 switch( VT_BITWIDTH( target->type ) ) {
1674 case 32:
1675 case 16:
1676 target->value = source->value;
1677 break;
1678 case 8:
1679 target->value = ( source->value & 0xff );
1680 break;
1681 default:
1682 target->initializedByConstant = 0;
1683 }
1684 break;
1685 case 8:
1686 switch( VT_BITWIDTH( target->type ) ) {
1687 case 32:
1688 case 16:
1689 case 8:
1690 target->value = source->value;
1691 break;
1692 default:
1693 target->initializedByConstant = 0;
1694 }
1695 break;
1696 default:
1697 target->initializedByConstant = 0;
1698 }
1699 }
1700
1701 return target;
1702
1703}
1704
1720Variable * variable_store( Environment * _environment, char * _destination, unsigned int _value ) {
1721
1722 Variable * destination = variable_retrieve( _environment, _destination );
1723
1724 destination->value = _value;
1725
1726 switch( VT_BITWIDTH( destination->type ) ) {
1727 case 32:
1728 cpu_store_32bit( _environment, destination->realName, VT_ESIGN_32BIT( destination->type, _value ) );
1729 break;
1730 case 16:
1731 cpu_store_16bit( _environment, destination->realName, VT_ESIGN_16BIT( destination->type, _value ) );
1732 break;
1733 case 8:
1734 if ( destination->type == VT_CHAR ) {
1735 if ( _value >= 20 && _value <= 127 ) {
1736 cpu_store_char( _environment, destination->realName, VT_ESIGN_8BIT( destination->type, _value ) );
1737 } else {
1738 cpu_store_8bit( _environment, destination->realName, VT_ESIGN_8BIT( destination->type, _value ) );
1739 }
1740 } else {
1741 cpu_store_8bit( _environment, destination->realName, VT_ESIGN_8BIT( destination->type, _value ) );
1742 }
1743 break;
1744 case 1:
1745 cpu_bit_inplace_8bit( _environment, destination->realName, destination->bitPosition, &_value );
1746 break;
1747 case 0:
1748 if ( destination->type == VT_TARRAY ) {
1749 int i=0,size=1;
1750 for( i=0; i<destination->arrayDimensions; ++i ) {
1751 size *= destination->arrayDimensionsEach[i];
1752 }
1753 if ( VT_BITWIDTH( destination->arrayType ) > 0 ) {
1754 size *= ( VT_BITWIDTH( destination->arrayType ) >> 3 );
1755 } else if ( destination->arrayType == VT_DSTRING ) {
1756 size *= 1;
1757 } else if ( destination->arrayType == VT_SPRITE ) {
1758 size *= 1;
1759 } else if ( destination->arrayType == VT_MSPRITE ) {
1760 size *= 2;
1761 } else if ( destination->arrayType == VT_DOJOKA ) {
1762 size *= 4;
1763 } else if ( destination->arrayType == VT_IMAGEREF ) {
1764 size *= 16; // Real: 14
1765 } else if ( destination->arrayType == VT_PATH ) {
1766 size *= 16; // Real: 16
1767 } else if ( destination->arrayType == VT_VECTOR2 ) {
1768 size *= 4;
1769 } else if ( destination->arrayType == VT_TILE ) {
1770 size *= 1;
1771 } else if ( destination->arrayType == VT_TILESET ) {
1772 size *= 1;
1773 } else if ( destination->arrayType == VT_TILES ) {
1774 size *= 4;
1775 } else if ( destination->arrayType == VT_FLOAT ) {
1776 size *= ( VT_FLOAT_NORMALIZED_BITWIDTH( destination->arrayPrecision ) >> 3 );
1777 } else if ( destination->arrayType == VT_NUMBER ) {
1778 int os = VT_OPTIMAL_SHIFT( _environment->numberConfig.maxBytes );
1779 size *= ( 1 << os );
1780 } else if ( destination->arrayType == VT_TYPE ) {
1781 size *= ( destination->typeType->size );
1782 } else {
1784 }
1785 cpu_fill_direct_size_value( _environment, destination->realName, size, _value );
1786 } else if ( destination->type == VT_TILE ) {
1787 cpu_store_8bit( _environment, destination->realName, _value );
1788 } else if ( destination->type == VT_NUMBER ) {
1789 int * value = malloc( _environment->numberConfig.maxBytes * sizeof(int) );
1790 memset( value, 0, _environment->numberConfig.maxBytes * sizeof(int) );
1791 value[0] = (unsigned char)((_value) & 0xff );
1792 value[1] = (unsigned char)((_value>>8) & 0xff );
1793 value[2] = (unsigned char)((_value>>16) & 0xff );
1794 value[3] = (unsigned char)((_value>>24) & 0xff );
1795 // value[4] = (unsigned char)((_value>>32) & 0xff );
1796 // value[5] = (unsigned char)((_value>>40) & 0xff );
1797 // value[6] = (unsigned char)((_value>>48) & 0xff );
1798 // value[7] = (unsigned char)((_value>>56) & 0xff );
1799 cpu_store_nbit( _environment, destination->realName, _environment->numberConfig.maxBytes << 3, value );
1800 } else {
1802 }
1803 break;
1804 }
1805 return destination;
1806}
1807
1808Variable * variable_store_type( Environment * _environment, char * _destination, char * _field, unsigned int _value ) {
1809
1810 Variable * destination = variable_retrieve( _environment, _destination );
1811
1812 if ( destination->type != VT_TYPE ) {
1813 CRITICAL_VARIABLE_TYPE_NEEDED( _destination );
1814 }
1815 Field * field = field_find( destination->typeType, _field );
1816 if ( ! field ) {
1818 }
1819
1820 char offsetAsString[MAX_TEMPORARY_STORAGE];
1821 sprintf( offsetAsString, "%d", field->offset );
1822 switch( VT_BITWIDTH( field->type ) ) {
1823 case 32:
1824 cpu_store_32bit( _environment, address_displacement( _environment, destination->realName, offsetAsString), VT_ESIGN_32BIT( field->type, _value ) );
1825 break;
1826 case 16:
1827 cpu_store_16bit( _environment, address_displacement( _environment, destination->realName, offsetAsString), VT_ESIGN_16BIT( field->type, _value ) );
1828 break;
1829 case 8:
1830 if ( field->type == VT_CHAR ) {
1831 if ( _value >= 20 && _value <= 127 ) {
1832 cpu_store_char( _environment, address_displacement( _environment, destination->realName, offsetAsString), VT_ESIGN_8BIT( field->type, _value ) );
1833 } else {
1834 cpu_store_8bit( _environment, address_displacement( _environment, destination->realName, offsetAsString), VT_ESIGN_8BIT( field->type, _value ) );
1835 }
1836 } else {
1837 cpu_store_8bit( _environment, address_displacement( _environment, destination->realName, offsetAsString), VT_ESIGN_8BIT( field->type, _value ) );
1838 }
1839 break;
1840 case 1:
1841 case 0:
1843 break;
1844 }
1845 return destination;
1846}
1847
1848Variable * variable_by_constant( Environment * _environment, VariableType _type, int _value ) {
1849 Variable * result = variable_temporary( _environment, _type, "()" );
1850 variable_store( _environment, result->name, _value );
1851 result->initializedByConstant = 1;
1852 return result;
1853}
1854
1855#define UNESCAPE_COLOR( c, d ) \
1856 else if ( strcmp_nocase( word, c ) == 0 ) { \
1857 int c2 = COLOR_##d;\
1858 if ( ! c2 ) { \
1859 c2 = 0xff; \
1860 } \
1861 if ( _printing ) { \
1862 *q = '*'; \
1863 } else { \
1864 *q = 1; \
1865 } \
1866 ++q; \
1867 if ( _printing ) { \
1868 *q = '*'; \
1869 } else { \
1870 *q = c2; \
1871 } \
1872 ++q; \
1873 }
1874
1875char * unescape_string( Environment * _environment, char * _value, int _printing, int * _final_size ) {
1876
1877 char * newValue = malloc( strlen( _value ) + 1 );
1878
1879 memset( newValue, 0, strlen( _value ) + 1 );
1880
1881 char * p = _value, * q = newValue;
1882 int c = 0;
1883
1884 if ( _final_size ) {
1885 *_final_size = 0;
1886 }
1887
1888 while( *p ) {
1889 if ( *p == '{' ) {
1890 ++p;
1891 if ( isdigit(*p) ) {
1892 c = 0;
1893 while( *p && *p != '}' ) {
1894 c = 10 * c + ( *p - '0' );
1895 ++p;
1896 }
1897 if ( _printing ) {
1898 *q = '*';
1899 } else {
1900 *q = c;
1901 }
1902 ++q;
1903 ++p;
1904 if ( _final_size ) {
1905 ++*_final_size;
1906 }
1907 } else {
1908 char * p2 = strchr(p+1, '}' );
1909 if ( p2 ) {
1911 memset( word, 0, MAX_TEMPORARY_STORAGE );
1912 memcpy( word, p, p2-p );
1913 p = p2+1;
1914
1915 if ( strcmp_nocase( word, "clear" ) == 0 ) {
1916 if ( _printing ) {
1917 *q = '*';
1918 } else {
1919 *q = 5;
1920 }
1921 ++q;
1922 if ( _final_size ) {
1923 ++*_final_size;
1924 }
1925 }
1926 UNESCAPE_COLOR( "black", BLACK )
1927 UNESCAPE_COLOR( "white", WHITE )
1928 UNESCAPE_COLOR( "red", RED )
1929 UNESCAPE_COLOR( "cyan", CYAN )
1930 UNESCAPE_COLOR( "violet", VIOLET )
1931 UNESCAPE_COLOR( "green", GREEN )
1932 UNESCAPE_COLOR( "blue", BLUE )
1933 UNESCAPE_COLOR( "yellow", YELLOW )
1934 UNESCAPE_COLOR( "orange", ORANGE )
1935 UNESCAPE_COLOR( "brown", BROWN )
1936 UNESCAPE_COLOR( "lt red", LIGHT_RED )
1937 UNESCAPE_COLOR( "light red", LIGHT_RED )
1938 UNESCAPE_COLOR( "dk grey", DARK_GREY )
1939 UNESCAPE_COLOR( "dark grey", DARK_GREY )
1940 UNESCAPE_COLOR( "dk gray", DARK_GREY )
1941 UNESCAPE_COLOR( "dark gray", DARK_GREY )
1942 UNESCAPE_COLOR( "grey", GREY )
1943 UNESCAPE_COLOR( "gray", GREY )
1944 UNESCAPE_COLOR( "lt green", LIGHT_GREEN )
1945 UNESCAPE_COLOR( "light green", LIGHT_GREEN )
1946 UNESCAPE_COLOR( "lt blue", LIGHT_BLUE )
1947 UNESCAPE_COLOR( "light blue", LIGHT_BLUE )
1948 UNESCAPE_COLOR( "lt grey", LIGHT_GREY )
1949 UNESCAPE_COLOR( "light grey", LIGHT_GREY )
1950 UNESCAPE_COLOR( "lt gray", LIGHT_GREY )
1951 UNESCAPE_COLOR( "light gray", LIGHT_GREY )
1952 UNESCAPE_COLOR( "dk blue", DARK_BLUE )
1953 UNESCAPE_COLOR( "dark blue", DARK_BLUE )
1954 UNESCAPE_COLOR( "magenta", MAGENTA )
1955 UNESCAPE_COLOR( "purple", PURPLE )
1956 UNESCAPE_COLOR( "lavender", LAVENDER )
1957 UNESCAPE_COLOR( "gold", GOLD )
1958 UNESCAPE_COLOR( "turquoise", TURQUOISE )
1959 UNESCAPE_COLOR( "tan", TAN )
1960 UNESCAPE_COLOR( "yellow green", YELLOW_GREEN )
1961 UNESCAPE_COLOR( "olive green", OLIVE_GREEN )
1962 UNESCAPE_COLOR( "pink", PINK )
1963 UNESCAPE_COLOR( "peach", PEACH )
1964 } else {
1965 *q = *p;
1966 ++p;
1967 ++q;
1968 if ( _final_size ) {
1969 ++*_final_size;
1970 }
1971 }
1972 }
1973 } else {
1974 *q = *p;
1975 ++q;
1976 ++p;
1977 if ( _final_size ) {
1978 ++*_final_size;
1979 }
1980 }
1981 }
1982
1983 return newValue;
1984
1985}
1986
1995Variable * variable_store_string( Environment * _environment, char * _destination, char * _value ) {
1996
1997 Variable * destination = variable_retrieve( _environment, _destination );
1998
1999 switch( destination->type ) {
2000 case VT_STRING: {
2001 if ( !_environment->emptyProcedure ) {
2002
2003 if ( _environment->vestigialConfig.rchack_4gravity_1164 ) {
2004 if ( strcmp( _value, " 1 2 3 4 5 6 7" ) == 0 ) {
2005 _value = strdup( "Press 1-9 key to play" );
2006 }
2007 }
2008
2009 destination->valueString = string_reserve( _environment, _value );
2010 destination->size = strlen( destination->valueString->value ) + 1;
2011 // memory_area_assign( _environment->memoryAreas, destination );
2012 } else {
2013 destination->valueString = string_reserve( _environment, "" );
2014 }
2015 break;
2016 }
2017 case VT_DSTRING: {
2018 Variable * temporary = variable_temporary( _environment, VT_STRING, "(temporary)");
2019 variable_store_string( _environment, temporary->name, _value );
2020 cpu_dsfree( _environment, destination->realName );
2021 cpu_dsdefine( _environment, temporary->realName, destination->realName );
2022 break;
2023 }
2024 default:
2026 }
2027 return destination;
2028}
2029
2038Variable * variable_store_float( Environment * _environment, char * _destination, double _value ) {
2039
2040 int result[8];
2041
2042 Variable * destination = variable_retrieve( _environment, _destination );
2043
2044 destination->valueFloating = _value;
2045
2046 outline1("; value = %f", _value );
2047
2048 switch( destination->type ) {
2049 case VT_FLOAT: {
2050 switch( destination->precision ) {
2051 case FT_FAST:
2052 cpu_float_fast_from_double_to_int_array( _environment, _value, result );
2053 break;
2054 case FT_SINGLE:
2055 cpu_float_single_from_double_to_int_array( _environment, _value, result );
2056 break;
2057 }
2058
2059#if defined(__atari__) || defined(__atarixl__) || defined(__c64__) || \
2060 defined(__c64reu__) || defined(__c128__) || defined(__vic20__)
2061 double integral;
2062 double fractional = modf( _value, &integral);
2063 if ( fractional == 0.0 ) {
2064 // n > 65535 -> q | n / 10^q < 65535
2065 // M1 <- n/q
2066 // FLOAT
2067 // M1 MUL 10^q
2068 // STORE
2069 double q = fabs( _value ), n = 0;
2070 int s = _value >= 0 ? 1 : -1;
2071 while ( q > 32767 ) {
2072 q = q / pow( 10, n );
2073 n = n + 1;
2074 if ( n >= 4 ) {
2075 break;
2076 }
2077 }
2078 if ( n >= 4 ) {
2079 WARNING_BITWIDTH( destination->name, destination->name );
2080 }
2081 Variable * word = variable_temporary( _environment, VT_SWORD, "(tmp)");
2082 variable_store( _environment, word->name, (int)(q) * s);
2083 Variable * scale = variable_temporary( _environment, VT_WORD, "(tmp)");
2084 variable_store( _environment, scale->name, (int)(pow(10, n)));
2085 Variable * scalefp = variable_temporary( _environment, VT_FLOAT, "(scalefp)");
2086 switch( destination->precision ) {
2087 case FT_FAST:
2088 cpu_float_fast_from_16( _environment, word->realName, destination->realName, 1 );
2089 cpu_float_fast_from_16( _environment, scale->realName, scalefp->realName, 1 );
2090 cpu_float_fast_mul( _environment, destination->realName, scalefp->realName, destination->realName );
2091 break;
2092 case FT_SINGLE:
2093 cpu_float_single_from_16( _environment, word->realName, destination->realName, 1 );
2094 cpu_float_single_from_16( _environment, scale->realName, scalefp->realName, 1 );
2095 cpu_float_single_mul( _environment, destination->realName, scalefp->realName, destination->realName );
2096 break;
2097 default:
2098 CRITICAL_CANNOT_CAST( DATATYPE_AS_STRING[destination->type], "FLOAT" );
2099 }
2100 } else {
2101 // n != INT(n) -> q | INT(n * 10^q) == n * 10^q
2102 // M1 <- n*10^q
2103 // FLOAT
2104 // M1 DIV 10^q
2105 // STORE
2106 double q = fabs( _value ), n = 0;
2107 int s = _value >= 0 ? 1 : -1;
2108 do {
2109 q = q * 10;
2110 n = n + 1;
2111 double integral;
2112 double fractional = modf(q, &integral);
2113 if ( fractional == 0.0 ) {
2114 break;
2115 }
2116 } while( n < 4 );
2117 if ( n >= 4 ) {
2118 WARNING_BITWIDTH( destination->name, destination->name );
2119 }
2120 Variable * word = variable_temporary( _environment, VT_SWORD, "(tmp)");
2121 variable_store( _environment, word->name, (int)(q) * s);
2122 Variable * scale = variable_temporary( _environment, VT_WORD, "(tmp)");
2123 variable_store( _environment, scale->name, (int)(pow(10, n)));
2124 Variable * scalefp = variable_temporary( _environment, VT_FLOAT, "(scalefp)");
2125 switch( destination->precision ) {
2126 case FT_FAST:
2127 cpu_float_fast_from_16( _environment, word->realName, destination->realName, 1 );
2128 cpu_float_fast_from_16( _environment, scale->realName, scalefp->realName, 1 );
2129 cpu_float_fast_div( _environment, destination->realName, scalefp->realName, destination->realName );
2130 break;
2131 case FT_SINGLE:
2132 cpu_float_single_from_16( _environment, word->realName, destination->realName, 1 );
2133 cpu_float_single_from_16( _environment, scale->realName, scalefp->realName, 1 );
2134 cpu_float_single_div( _environment, destination->realName, scalefp->realName, destination->realName );
2135 break;
2136 default:
2137 CRITICAL_CANNOT_CAST( DATATYPE_AS_STRING[destination->type], "FLOAT" );
2138 }
2139 }
2140
2141
2142#else
2143 cpu_store_nbit( _environment, destination->realName, VT_FLOAT_BITWIDTH( destination->precision ), result );
2144#endif
2145
2146 break;
2147 }
2148 default:
2150 }
2151 return destination;
2152}
2153
2162Variable * variable_resize_buffer( Environment * _environment, char * _destination, int _size ) {
2163 Variable * destination = variable_retrieve( _environment, _destination );
2164 switch( destination->type ) {
2165 case VT_BUFFER: {
2166 destination->size = _size;
2167 break;
2168 }
2169 default:
2171 }
2172 return destination;
2173}
2174
2175Variable * variable_store_buffer( Environment * _environment, char * _destination, unsigned char * _buffer, int _size, int _at ) {
2176 Variable * destination = variable_retrieve( _environment, _destination );
2177 switch( destination->type ) {
2178 case VT_IMAGE:
2179 case VT_IMAGES:
2180 case VT_SEQUENCE:
2181 case VT_MUSIC:
2182 case VT_BUFFER:
2183 case VT_TYPE:
2184 if ( ! destination->valueBuffer ) {
2185 destination->valueBuffer = malloc( _size );
2186 memcpy( destination->valueBuffer, _buffer, _size );
2187 destination->size = _size;
2188 if ( _at ) {
2189 destination->absoluteAddress = _at;
2190 char bufferCopy[MAX_TEMPORARY_STORAGE]; sprintf( bufferCopy, "%scopy", destination->realName );
2191 cpu_mem_move_direct_size( _environment, bufferCopy, destination->realName, _size );
2192 } else {
2193 if ( !_environment->disableMemoryAreas ) {
2194 memory_area_assign( _environment->memoryAreas, destination );
2195 }
2196 }
2197 } else {
2198 Variable * temporary = variable_temporary( _environment, destination->type, "(copy of buffer/image)");
2199 temporary->typeType = destination->typeType;
2200 temporary->valueBuffer = malloc( _size );
2201 memcpy( temporary->valueBuffer, _buffer, _size );
2202 temporary->size = _size;
2203 if ( !_environment->disableMemoryAreas ) {
2204 memory_area_assign( _environment->memoryAreas, temporary );
2205 }
2206 if ( destination->size < _size ) {
2207 destination->valueBuffer = realloc( destination->valueBuffer, _size );
2208 memset( destination->valueBuffer + destination->size, 0, ( _size - destination->size ) );
2209 destination->size = _size;
2210 if ( !_environment->disableMemoryAreas ) {
2211 memory_area_assign( _environment->memoryAreas, destination );
2212 }
2213 }
2214 variable_move_naked( _environment, temporary->name, destination->name );
2215 }
2216 break;
2217 default:
2219 }
2220 return destination;
2221}
2222
2223// @bit2: ok
2224Variable * variable_store_array( Environment * _environment, char * _destination, unsigned char * _buffer, int _size, int _at ) {
2225 Variable * destination = variable_retrieve( _environment, _destination );
2226 switch( destination->type ) {
2227 case VT_TARRAY:
2228 if ( ! destination->valueBuffer ) {
2229 destination->valueBuffer = malloc( _size );
2230 memcpy( destination->valueBuffer, _buffer, _size );
2231 destination->size = _size;
2232 if ( _at ) {
2233 destination->absoluteAddress = _at;
2234 char bufferCopy[MAX_TEMPORARY_STORAGE]; sprintf( bufferCopy, "%scopy", destination->realName );
2235 cpu_mem_move_direct_size( _environment, bufferCopy, destination->realName, _size );
2236 }
2237 } else {
2238 Variable * temporary = variable_temporary( _environment, destination->type, "(copy of buffer/image)");
2239 temporary->valueBuffer = malloc( _size );
2240 memcpy( temporary->valueBuffer, _buffer, _size );
2241 temporary->size = _size;
2242 if ( destination->size < _size ) {
2243 destination->valueBuffer = realloc( destination->valueBuffer, _size );
2244 memset( destination->valueBuffer + destination->size, 0, ( _size - destination->size ) );
2245 destination->size = _size;
2246 }
2247 variable_move_naked( _environment, temporary->name, destination->name );
2248 }
2249 break;
2250 default:
2252 }
2253 return destination;
2254}
2255
2263static void variable_move_32bit_32bit( Environment * _environment, Variable * _source, Variable * _target ) {
2264
2265 cpu_move_32bit( _environment, _source->realName, _target->realName );
2266
2267}
2268
2269static void variable_move_32bit_signed_16bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2270
2271 cpu_move_32bit_signed_16bit_signed( _environment, _source->realName, _target->realName );
2272
2273}
2274
2275static void variable_move_32bit_signed_16bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2276
2277 cpu_move_32bit_signed_16bit_unsigned( _environment, _source->realName, _target->realName );
2278
2279}
2280
2281static void variable_move_32bit_unsigned_16bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2282
2283 cpu_move_32bit_unsigned_16bit_signed( _environment, _source->realName, _target->realName );
2284
2285}
2286
2287static void variable_move_32bit_unsigned_16bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2288
2289 cpu_move_32bit_unsigned_16bit_unsigned( _environment, _source->realName, _target->realName );
2290
2291}
2292
2300static void variable_move_32bit_16bit( Environment * _environment, Variable * _source, Variable * _target ) {
2301
2302 WARNING_BITWIDTH( _source->name, _target->name );
2303
2304 if ( VT_SIGNED( _source->type ) ) {
2305
2306 if ( VT_SIGNED( _target->type ) ) {
2307
2308 variable_move_32bit_signed_16bit_signed( _environment, _source, _target );
2309
2310 } else {
2311
2312 variable_move_32bit_signed_16bit_unsigned( _environment, _source, _target );
2313
2314 }
2315
2316 } else {
2317
2318 if ( VT_SIGNED( _target->type ) ) {
2319
2320 // 32 BIT (unsigned) -> 16 BIT (signed)
2321
2322 // copy lower 15 bits, then put bit 15 to zero
2323
2324 variable_move_32bit_unsigned_16bit_signed( _environment, _source, _target );
2325
2326 } else {
2327
2328 // 32 BIT (unsigned) -> 16 BIT (unsigned)
2329
2330 variable_move_32bit_unsigned_16bit_unsigned( _environment, _source, _target );
2331
2332 }
2333
2334 }
2335
2336}
2337
2338static void variable_move_32bit_signed_8bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2339
2340 cpu_move_32bit_signed_8bit_signed( _environment, _source->realName, _target->realName );
2341
2342}
2343
2344static void variable_move_32bit_signed_8bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2345
2346 cpu_move_32bit_signed_8bit_unsigned( _environment, _source->realName, _target->realName );
2347
2348}
2349
2350static void variable_move_32bit_unsigned_8bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2351
2352 cpu_move_32bit_unsigned_8bit_signed( _environment, _source->realName, _target->realName );
2353
2354}
2355
2356static void variable_move_32bit_unsigned_8bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2357
2358 cpu_move_32bit_unsigned_8bit_unsigned( _environment, _source->realName, _target->realName );
2359
2360}
2361
2369static void variable_move_32bit_8bit( Environment * _environment, Variable * _source, Variable * _target ) {
2370
2371 WARNING_BITWIDTH( _source->name, _target->name );
2372
2373 if ( VT_SIGNED( _source->type ) ) {
2374
2375 if ( VT_SIGNED( _target->type ) ) {
2376
2377 variable_move_32bit_signed_8bit_signed( _environment, _source, _target );
2378
2379 } else {
2380
2381 variable_move_32bit_signed_8bit_unsigned( _environment, _source, _target );
2382
2383 }
2384
2385 } else {
2386
2387 if ( VT_SIGNED( _target->type ) ) {
2388
2389 // 32 BIT (unsigned) -> 8 BIT (signed)
2390
2391 // copy lower 8 bits, then put bit 8 to zero
2392
2393 variable_move_32bit_unsigned_8bit_signed( _environment, _source, _target );
2394
2395 } else {
2396
2397 // 32 BIT (unsigned) -> 8 BIT (unsigned)
2398
2399 variable_move_32bit_unsigned_8bit_unsigned( _environment, _source, _target );
2400
2401 }
2402
2403 }
2404
2405}
2406
2414static void variable_move_32bit_1bit( Environment * _environment, Variable * _source, Variable * _target ) {
2415
2416 WARNING_BITWIDTH( _source->name, _target->name );
2417
2418 // 32 BIT (signed) -> 1 BIT
2419
2421
2422 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneLabel, "%sdone", label );
2423
2424 cpu_compare_and_branch_32bit_const( _environment, _source->realName, 0, label, 1 );
2425
2426 int one = 1;
2427 cpu_bit_inplace_8bit( _environment, _target->realName, _target->bitPosition, &one );
2428
2429 cpu_jump( _environment, doneLabel );
2430
2431 cpu_label( _environment, label );
2432
2433 int zero = 0;
2434 cpu_bit_inplace_8bit( _environment, _target->realName, _target->bitPosition, &zero );
2435
2436 cpu_label( _environment, doneLabel );
2437
2438}
2439
2440static void variable_move_16bit_signed_32bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2441
2442 cpu_move_16bit_signed_32bit_signed( _environment, _source->realName, _target->realName );
2443
2444}
2445
2446static void variable_move_16bit_signed_32bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2447
2448 cpu_move_16bit_signed_32bit_unsigned( _environment, _source->realName, _target->realName );
2449
2450}
2451
2452static void variable_move_16bit_unsigned_32bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2453
2454 cpu_move_16bit_unsigned_32bit_signed( _environment, _source->realName, _target->realName );
2455
2456}
2457
2458static void variable_move_16bit_unsigned_32bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2459
2460 cpu_move_16bit_unsigned_32bit_unsigned( _environment, _source->realName, _target->realName );
2461
2462}
2463
2471static void variable_move_16bit_32bit( Environment * _environment, Variable * _source, Variable * _target ) {
2472
2473 Variable * sign = variable_temporary( _environment, VT_BYTE, "(sign)" );
2474
2475 if ( VT_SIGNED( _source->type ) ) {
2476
2477 if ( VT_SIGNED( _target->type ) ) {
2478
2479 // 16 BIT (signed) -> 32 BIT (signed)
2480
2481 variable_move_16bit_signed_32bit_signed( _environment, _source, _target );
2482
2483 } else {
2484
2485 // 16 BIT (signed) -> 32 BIT (unsigned)
2486
2487 variable_move_16bit_signed_32bit_unsigned( _environment, _source, _target );
2488
2489 }
2490
2491 } else {
2492
2493 if ( VT_SIGNED( _target->type ) ) {
2494
2495 // 16 BIT (unsigned) -> 32 BIT (signed)
2496
2497 variable_move_16bit_unsigned_32bit_signed( _environment, _source, _target );
2498
2499 } else {
2500
2501 // 16 BIT (unsigned) -> 32 BIT (signed)
2502
2503 variable_move_16bit_unsigned_32bit_unsigned( _environment, _source, _target );
2504
2505 }
2506
2507 }
2508
2509}
2510
2518static void variable_move_16bit_16bit( Environment * _environment, Variable * _source, Variable * _target ) {
2519
2520 cpu_move_16bit( _environment, _source->realName, _target->realName );
2521
2522}
2523
2524static void variable_move_16bit_signed_8bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2525
2526 cpu_move_16bit_signed_8bit_signed( _environment, _source->realName, _target->realName );
2527
2528}
2529
2530static void variable_move_16bit_signed_8bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2531
2532 cpu_move_16bit_signed_8bit_unsigned( _environment, _source->realName, _target->realName );
2533
2534}
2535
2536static void variable_move_16bit_unsigned_8bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2537
2538 cpu_move_16bit_unsigned_8bit_signed( _environment, _source->realName, _target->realName );
2539
2540}
2541
2542static void variable_move_16bit_unsigned_8bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2543
2544 cpu_move_16bit_unsigned_8bit_unsigned( _environment, _source->realName, _target->realName );
2545
2546}
2547
2555static void variable_move_16bit_8bit( Environment * _environment, Variable * _source, Variable * _target ) {
2556
2557 WARNING_BITWIDTH( _source->name, _target->name );
2558
2559 if ( VT_SIGNED( _source->type ) ) {
2560
2561 if ( VT_SIGNED( _target->type ) ) {
2562
2563 variable_move_16bit_signed_8bit_signed( _environment, _source, _target );
2564
2565 } else {
2566
2567 variable_move_16bit_signed_8bit_unsigned( _environment, _source, _target );
2568
2569 }
2570
2571 } else {
2572
2573 if ( VT_SIGNED( _target->type ) ) {
2574
2575 // 16 BIT (unsigned) -> 8 BIT (signed)
2576
2577 // copy lower 8 bits, then put bit 8 to zero
2578
2579 variable_move_16bit_unsigned_8bit_signed( _environment, _source, _target );
2580
2581 } else {
2582
2583 // 16 BIT (unsigned) -> 8 BIT (unsigned)
2584
2585 variable_move_16bit_unsigned_8bit_unsigned( _environment, _source, _target );
2586
2587 }
2588
2589 }
2590
2591}
2592
2600static void variable_move_16bit_1bit( Environment * _environment, Variable * _source, Variable * _target ) {
2601
2602 WARNING_BITWIDTH( _source->name, _target->name );
2603
2604 // 16 BIT (signed) -> 1 BIT
2605
2607
2608 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneLabel, "%sdone", label );
2609
2610 cpu_compare_and_branch_16bit_const( _environment, _source->realName, 0, label, 1 );
2611
2612 int one = 1;
2613 cpu_bit_inplace_8bit( _environment, _target->realName, _target->bitPosition, &one );
2614
2615 cpu_jump( _environment, doneLabel );
2616
2617 cpu_label( _environment, label );
2618
2619 int zero = 0;
2620 cpu_bit_inplace_8bit( _environment, _target->realName, _target->bitPosition, &zero );
2621
2622 cpu_label( _environment, doneLabel );
2623
2624}
2625
2626static void variable_move_8bit_signed_32bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2627
2628 cpu_move_8bit_signed_32bit_signed( _environment, _source->realName, _target->realName );
2629
2630}
2631
2632static void variable_move_8bit_signed_32bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2633
2634 cpu_move_8bit_signed_32bit_unsigned( _environment, _source->realName, _target->realName );
2635
2636}
2637
2638static void variable_move_8bit_unsigned_32bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2639
2640 cpu_move_8bit_unsigned_32bit_signed( _environment, _source->realName, _target->realName );
2641
2642}
2643
2644static void variable_move_8bit_unsigned_32bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2645
2646 cpu_move_8bit_unsigned_32bit_unsigned( _environment, _source->realName, _target->realName );
2647
2648}
2649
2657static void variable_move_8bit_32bit( Environment * _environment, Variable * _source, Variable * _target ) {
2658
2659 if ( VT_SIGNED( _source->type ) ) {
2660
2661 if ( VT_SIGNED( _target->type ) ) {
2662
2663 // 8 BIT (signed) -> 32 BIT (signed)
2664
2665 variable_move_8bit_signed_32bit_signed( _environment, _source, _target );
2666
2667 } else {
2668
2669 // 8 BIT (signed) -> 32 BIT (unsigned)
2670
2671 variable_move_8bit_signed_32bit_unsigned( _environment, _source, _target );
2672
2673 }
2674
2675 } else {
2676
2677 if ( VT_SIGN( _target->type ) ) {
2678
2679 // 8 BIT (unsigned) -> 32 BIT (signed)
2680
2681 variable_move_8bit_unsigned_32bit_signed( _environment, _source, _target );
2682
2683 } else {
2684
2685 // 8 BIT (unsigned) -> 32 BIT (unsigned)
2686
2687 variable_move_8bit_unsigned_32bit_unsigned( _environment, _source, _target );
2688
2689 // Generic algorithm:
2690 //
2691 // put 0 to target
2692
2693 }
2694
2695 }
2696
2697}
2698
2699static void variable_move_8bit_signed_16bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2700
2701 cpu_move_8bit_signed_16bit_signed( _environment, _source->realName, _target->realName );
2702
2703}
2704
2705static void variable_move_8bit_signed_16bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2706
2707 cpu_move_8bit_signed_16bit_unsigned( _environment, _source->realName, _target->realName );
2708
2709}
2710
2711static void variable_move_8bit_unsigned_16bit_signed( Environment * _environment, Variable * _source, Variable * _target ) {
2712
2713 cpu_move_8bit_unsigned_16bit_signed( _environment, _source->realName, _target->realName );
2714
2715}
2716
2717static void variable_move_8bit_unsigned_16bit_unsigned( Environment * _environment, Variable * _source, Variable * _target ) {
2718
2719 cpu_move_8bit_unsigned_16bit_unsigned( _environment, _source->realName, _target->realName );
2720
2721}
2722
2730static void variable_move_8bit_16bit( Environment * _environment, Variable * _source, Variable * _target ) {
2731
2732 if ( VT_SIGNED( _source->type ) ) {
2733
2734 if ( VT_SIGNED( _target->type ) ) {
2735
2736 variable_move_8bit_signed_16bit_signed( _environment, _source, _target );
2737
2738 } else {
2739
2740 variable_move_8bit_signed_16bit_unsigned( _environment, _source, _target );
2741
2742 // 8 BIT (signed) -> 16 BIT (unsigned)
2743
2744 }
2745
2746 } else {
2747
2748 if ( VT_SIGNED( _target->type ) ) {
2749
2750 // 8 BIT (unsigned) -> 16 BIT (signed)
2751
2752 variable_move_8bit_unsigned_16bit_signed( _environment, _source, _target );
2753
2754 } else {
2755
2756 // 8 BIT (unsigned) -> 16 BIT (unsigned)
2757
2758 variable_move_8bit_unsigned_16bit_unsigned( _environment, _source, _target );
2759
2760 }
2761
2762 }
2763
2764}
2765
2773static void variable_move_8bit_8bit( Environment * _environment, Variable * _source, Variable * _target ) {
2774
2775 cpu_move_8bit( _environment, _source->realName, _target->realName );
2776
2777}
2778
2786static void variable_move_8bit_1bit( Environment * _environment, Variable * _source, Variable * _target ) {
2787
2788 WARNING_BITWIDTH( _source->name, _target->name );
2789
2790 // 8 BIT (signed) -> 1 BIT
2791
2793
2794 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneLabel, "%sdone", label );
2795
2796 cpu_compare_and_branch_8bit_const( _environment, _source->realName, 0, label, 1 );
2797
2798 int one = 1;
2799 cpu_bit_inplace_8bit( _environment, _target->realName, _target->bitPosition, &one );
2800
2801 cpu_jump( _environment, doneLabel );
2802
2803 cpu_label( _environment, label );
2804
2805 int zero = 0;
2806 cpu_bit_inplace_8bit( _environment, _target->realName, _target->bitPosition, &zero );
2807
2808 cpu_label( _environment, doneLabel );
2809
2810}
2811
2819static void variable_move_1bit_32bit( Environment * _environment, Variable * _source, Variable * _target ) {
2820
2821 // 1 BIT -> 32 BIT
2822
2823 Variable * tmp = variable_temporary( _environment, VT_BYTE, "(tmp)" );
2824
2825 cpu_bit_check( _environment, _source->realName, _source->bitPosition, tmp->realName, 8 );
2826
2827 cpu_move_8bit( _environment, tmp->realName, _target->realName );
2828 cpu_move_8bit( _environment, tmp->realName, address_displacement( _environment, _target->realName, "1" ) );
2829 cpu_move_8bit( _environment, tmp->realName, address_displacement( _environment, _target->realName, "2" ) );
2830 cpu_move_8bit( _environment, tmp->realName, address_displacement( _environment, _target->realName, "3" ) );
2831
2832}
2833
2841static void variable_move_1bit_16bit( Environment * _environment, Variable * _source, Variable * _target ) {
2842
2843 // 1 BIT -> 16 BIT
2844
2845 Variable * tmp = variable_temporary( _environment, VT_BYTE, "(tmp)" );
2846
2847 cpu_bit_check( _environment, _source->realName, _source->bitPosition, tmp->realName, 8 );
2848
2849 cpu_move_8bit( _environment, tmp->realName, _target->realName );
2850 cpu_move_8bit( _environment, tmp->realName, address_displacement( _environment, _target->realName, "1" ) );
2851
2852}
2853
2861static void variable_move_1bit_8bit( Environment * _environment, Variable * _source, Variable * _target ) {
2862
2863 // 1 BIT -> 8 BIT
2864
2865 cpu_bit_check( _environment, _source->realName, _source->bitPosition, _target->realName, 8 );
2866
2867}
2868
2876static void variable_move_1bit_1bit( Environment * _environment, Variable * _source, Variable * _target ) {
2877
2878 WARNING_BITWIDTH( _source->name, _target->name );
2879
2880 // 1 BIT -> 1 BIT
2881
2882 cpu_bit_check( _environment, _source->realName, _source->bitPosition, NULL, 8 );
2883 cpu_bit_inplace_8bit( _environment, _target->realName, _target->bitPosition, NULL );
2884
2885}
2886
2894static void variable_move_higher_32bit_16bit( Environment * _environment, Variable * _source, Variable * _target ) {
2895
2896 Variable * temp = variable_temporary( _environment, _target->type, "(temp)");
2897
2898#if CPU_BIG_ENDIAN
2899 cpu_move_16bit( _environment, _source->realName, temp->realName );
2900#else
2901 cpu_move_16bit( _environment, address_displacement( _environment, _source->realName, "2" ), temp->realName );
2902#endif
2903 variable_move_16bit_16bit( _environment, temp, _target );
2904
2905}
2906
2907static void variable_move_32bit_number( Environment * _environment, Variable * _source, Variable * _target ) {
2908
2910
2911 Variable * sign = variable_temporary( _environment, VT_SBYTE, "(sign)");
2912
2913 #ifdef CPU_BIG_ENDIAN
2914 {
2915 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 4 );
2916 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, _target->realName, offsetAsString ) );
2917 cpu_move_32bit( _environment, _source->realName, targetRealName );
2918 cpu_move_8bit( _environment, _source->realName, sign->realName );
2919 cpu_and_8bit_const( _environment, sign->realName, 0x80, sign->realName );
2920 cpu_bveq( _environment, sign->realName, label );
2921 for( int i=0; i<(_environment->numberConfig.maxBytes - 4); ++i ) {
2922 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", i );
2923 cpu_store_8bit( _environment, address_displacement( _environment, _target->realName, offsetAsString ), 0xff );
2924 }
2925 cpu_label( _environment, label );
2926 }
2927 #else
2928 cpu_move_32bit( _environment, _source->realName, _target->realName );
2929 cpu_move_8bit( _environment, address_displacement( _environment, _source->realName, "4" ), sign->realName );
2930 cpu_and_8bit_const( _environment, sign->realName, 0x80, sign->realName );
2931 cpu_bveq( _environment, sign->realName, label );
2932 for( int i=4; i<(_environment->numberConfig.maxBytes); ++i ) {
2933 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", i );
2934 cpu_store_8bit( _environment, address_displacement( _environment, _target->realName, offsetAsString ), 0xff );
2935 }
2936 cpu_label( _environment, label );
2937 #endif
2938
2939}
2940
2941static void variable_move_16bit_number( Environment * _environment, Variable * _source, Variable * _target ) {
2942
2944
2945 Variable * sign = variable_temporary( _environment, VT_SBYTE, "(sign)");
2946
2947 #ifdef CPU_BIG_ENDIAN
2948 {
2949 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 2 );
2950 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, _target->realName, offsetAsString ) );
2951 cpu_move_16bit( _environment, _source->realName, targetRealName );
2952 cpu_move_8bit( _environment, _source->realName, sign->realName );
2953 cpu_and_8bit_const( _environment, sign->realName, 0x80, sign->realName );
2954 cpu_bveq( _environment, sign->realName, label );
2955 for( int i=0; i<(_environment->numberConfig.maxBytes - 2); ++i ) {
2956 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", i );
2957 cpu_store_8bit( _environment, address_displacement( _environment, _target->realName, offsetAsString ), 0xff );
2958 }
2959 cpu_label( _environment, label );
2960 }
2961 #else
2962 cpu_move_16bit( _environment, _source->realName, _target->realName );
2963 cpu_move_8bit( _environment, address_displacement( _environment, _source->realName, "2" ), sign->realName );
2964 cpu_and_8bit_const( _environment, sign->realName, 0x80, sign->realName );
2965 cpu_bveq( _environment, sign->realName, label );
2966 for( int i=2; i<(_environment->numberConfig.maxBytes); ++i ) {
2967 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", i );
2968 cpu_store_8bit( _environment, address_displacement( _environment, _target->realName, offsetAsString ), 0xff );
2969 }
2970 cpu_label( _environment, label );
2971 #endif
2972
2973}
2974
2975static void variable_move_8bit_number( Environment * _environment, Variable * _source, Variable * _target ) {
2976
2978
2979 Variable * sign = variable_temporary( _environment, VT_SBYTE, "(sign)");
2980
2981 #ifdef CPU_BIG_ENDIAN
2982 {
2983 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 1 );
2984 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, _target->realName, offsetAsString ) );
2985 cpu_move_8bit( _environment, _source->realName, targetRealName );
2986 cpu_move_8bit( _environment, _source->realName, sign->realName );
2987 cpu_and_8bit_const( _environment, sign->realName, 0x80, sign->realName );
2988 cpu_bveq( _environment, sign->realName, label );
2989 for( int i=0; i<(_environment->numberConfig.maxBytes - 1); ++i ) {
2990 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", i );
2991 cpu_store_8bit( _environment, address_displacement( _environment, _target->realName, offsetAsString ), 0xff );
2992 }
2993 cpu_label( _environment, label );
2994 }
2995 #else
2996 cpu_move_8bit( _environment, _source->realName, _target->realName );
2997 cpu_move_8bit( _environment, address_displacement( _environment, _source->realName, "1" ), sign->realName );
2998 cpu_and_8bit_const( _environment, sign->realName, 0x80, sign->realName );
2999 cpu_bveq( _environment, sign->realName, label );
3000 for( int i=1; i<(_environment->numberConfig.maxBytes); ++i ) {
3001 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", i );
3002 cpu_store_8bit( _environment, address_displacement( _environment, _target->realName, offsetAsString ), 0xff );
3003 }
3004 cpu_label( _environment, label );
3005 #endif
3006
3007}
3008
3009static void variable_move_1bit_number( Environment * _environment, Variable * _source, Variable * _target ) {
3010
3011 Variable * byte = variable_temporary( _environment, VT_BYTE, "(1bit)");
3012 cpu_bit_check( _environment, _source->realName, _source->bitPosition, byte->realName, 8 );
3013 variable_move_8bit_number( _environment, byte, _target );
3014
3015}
3016
3017static void variable_move_number_number( Environment * _environment, Variable * _source, Variable * _target ) {
3018
3019 cpu_move_nbit( _environment, _environment->numberConfig.maxBytes << 3, _source->realName, _target->realName );
3020
3021}
3022
3023static void variable_move_number_32bit( Environment * _environment, Variable * _source, Variable * _target ) {
3024
3025 #ifdef CPU_BIG_ENDIAN
3026 {
3027 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 4 );
3028 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, _source->realName, offsetAsString ) );
3029 cpu_move_32bit( _environment, sourceRealName, _target->realName );
3030 }
3031 #else
3032 cpu_move_32bit( _environment, _source->realName, _target->realName );
3033 #endif
3034
3035}
3036
3037static void variable_move_number_16bit( Environment * _environment, Variable * _source, Variable * _target ) {
3038
3039 #ifdef CPU_BIG_ENDIAN
3040 {
3041 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 2 );
3042 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, _source->realName, offsetAsString ) );
3043 cpu_move_16bit( _environment, sourceRealName, _target->realName );
3044 }
3045 #else
3046 cpu_move_16bit( _environment, _source->realName, _target->realName );
3047 #endif
3048
3049}
3050
3051static void variable_move_number_8bit( Environment * _environment, Variable * _source, Variable * _target ) {
3052
3053 #ifdef CPU_BIG_ENDIAN
3054 {
3055 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 1 );
3056 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, _source->realName, offsetAsString ) );
3057 cpu_move_8bit( _environment, sourceRealName, _target->realName );
3058 }
3059 #else
3060 cpu_move_8bit( _environment, _source->realName, _target->realName );
3061 #endif
3062
3063}
3064
3065static void variable_move_number_1bit( Environment * _environment, Variable * _source, Variable * _target ) {
3066
3067 Variable * sourceByte = variable_temporary( _environment, VT_BYTE, "()");
3068 variable_move_number_8bit( _environment, _source, sourceByte );
3069 variable_move_8bit_1bit( _environment, sourceByte, _target );
3070
3071}
3072
3089Variable * variable_move( Environment * _environment, char * _source, char * _destination ) {
3090
3091 Variable * source = variable_retrieve( _environment, _source );
3092 Variable * sign = variable_temporary( _environment, VT_BYTE, "(sign)" );
3093
3094 Variable * target = variable_retrieve( _environment, _destination );
3095
3096 if ( target->bankAssigned != -1 ) {
3097 CRITICAL_CANNOT_COPY_TO_BANKED(_destination);
3098 }
3099
3100 switch( VT_BITWIDTH( source->type ) ) {
3101
3105
3106 case 32:
3107
3108 switch( VT_BITWIDTH( target->type ) ) {
3109
3110 // 32 BIT -> 32 BIT
3111 case 32:
3112
3113 variable_move_32bit_32bit( _environment, source, target );
3114
3115 break;
3116
3117 case 16:
3118
3119 variable_move_32bit_16bit( _environment, source, target );
3120
3121 break;
3122
3123 case 8:
3124
3125 variable_move_32bit_8bit( _environment, source, target );
3126
3127 break;
3128
3129 case 1:
3130
3131 variable_move_32bit_1bit( _environment, source, target );
3132
3133 break;
3134
3135 case 0:
3136
3137 switch( target->type ) {
3138 case VT_TILE:
3139 WARNING_DOWNCAST( _source, target->name );
3140 #ifdef CPU_BIG_ENDIAN
3141 {
3142 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "3") );
3143 cpu_move_8bit( _environment, sourceRealName, target->realName );
3144 }
3145 #else
3146 cpu_move_8bit( _environment, source->realName, target->realName );
3147 #endif
3148 break;
3149 case VT_FLOAT:
3150 WARNING_DOWNCAST( _source, target->name );
3151 if ( ! VT_SIGNED( source->type ) ) {
3153 }
3154 Variable * word = variable_temporary( _environment, VT_SWORD, "(word)");
3155 Variable * scale = variable_temporary( _environment, VT_FLOAT, "(scale)");
3156 variable_move( _environment, source->name, word->name );
3157 switch( target->precision ) {
3158 case FT_FAST:
3159 cpu_float_fast_from_16( _environment, word->realName, target->realName, VT_SIGNED( source->type ) );
3160 break;
3161 case FT_SINGLE:
3162 cpu_float_single_from_16( _environment, word->realName, target->realName, VT_SIGNED( source->type ) );
3163 break;
3164 default:
3166 }
3167 break;
3168 case VT_NUMBER:
3169 variable_move_32bit_number( _environment, source, target );
3170 break;
3171 default:
3173 break;
3174 }
3175 break;
3176 }
3177 break;
3178
3179 case 16:
3180
3181 switch( VT_BITWIDTH( target->type ) ) {
3182
3183 case 32:
3184
3185 variable_move_16bit_32bit( _environment, source, target );
3186
3187 break;
3188 case 16:
3189
3190 variable_move_16bit_16bit( _environment, source, target );
3191
3192 break;
3193 case 8:
3194
3195 variable_move_16bit_8bit( _environment, source, target );
3196
3197 break;
3198
3199 case 1:
3200
3201 variable_move_16bit_1bit( _environment, source, target );
3202
3203 break;
3204
3205 case 0:
3206
3207 switch( target->type ) {
3208 case VT_TILE:
3209 WARNING_DOWNCAST( _source, target->name );
3210 #ifdef CPU_BIG_ENDIAN
3211 {
3212 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "1") );
3213 cpu_move_8bit( _environment, sourceRealName, target->realName );
3214 }
3215 #else
3216 cpu_move_8bit( _environment, source->realName, target->realName );
3217 #endif
3218 break;
3219 case VT_FLOAT:
3220 switch( target->precision ) {
3221 case FT_FAST:
3222 cpu_float_fast_from_16( _environment, source->realName, target->realName, VT_SIGNED( source->type ) );
3223 break;
3224 case FT_SINGLE:
3225 cpu_float_single_from_16( _environment, source->realName, target->realName, VT_SIGNED( source->type ) );
3226 break;
3227 default:
3229 }
3230 break;
3231 case VT_NUMBER:
3232 variable_move_16bit_number( _environment, source, target );
3233 break;
3234 default:
3236 }
3237
3238 break;
3239
3240 }
3241
3242 break;
3243
3244 case 8:
3245
3246 switch( VT_BITWIDTH( target->type ) ) {
3247
3248 case 32:
3249
3250 variable_move_8bit_32bit( _environment, source, target );
3251
3252 break;
3253
3254 case 16:
3255
3256 variable_move_8bit_16bit( _environment, source, target );
3257
3258 break;
3259
3260 case 8:
3261
3262 variable_move_8bit_8bit( _environment, source, target );
3263
3264 break;
3265
3266 case 1:
3267
3268 variable_move_8bit_1bit( _environment, source, target );
3269
3270 break;
3271
3272
3273 case 0:
3274 switch( target->type ) {
3275 case VT_TILE:
3276 cpu_move_8bit( _environment, source->realName, target->realName );
3277 break;
3278 case VT_FLOAT:
3279 switch( target->precision ) {
3280 case FT_FAST:
3281 cpu_float_fast_from_8( _environment, source->realName, target->realName, VT_SIGNED( source->type ) );
3282 break;
3283 case FT_SINGLE:
3284 cpu_float_single_from_8( _environment, source->realName, target->realName, VT_SIGNED( source->type ) );
3285 break;
3286 default:
3288 }
3289 break;
3290 case VT_NUMBER:
3291 variable_move_8bit_number( _environment, source, target );
3292 break;
3293 default:
3295 }
3296
3297 break;
3298
3299 }
3300
3301 break;
3302
3303 case 1:
3304
3305 switch( VT_BITWIDTH( target->type ) ) {
3306
3307 case 32:
3308
3309 variable_move_1bit_32bit( _environment, source, target );
3310
3311 break;
3312
3313 case 16:
3314
3315 variable_move_1bit_16bit( _environment, source, target );
3316
3317 break;
3318
3319 case 8:
3320
3321 variable_move_1bit_8bit( _environment, source, target );
3322
3323 break;
3324
3325 case 1:
3326
3327 variable_move_1bit_1bit( _environment, source, target );
3328
3329 break;
3330
3331
3332 case 0:
3333 switch( target->type ) {
3334 case VT_TILE:
3335 cpu_move_8bit( _environment, source->realName, target->realName );
3336 break;
3337 case VT_FLOAT:
3338 switch( target->precision ) {
3339 case FT_FAST:
3340 cpu_float_fast_from_8( _environment, source->realName, target->realName, VT_SIGNED( source->type ) );
3341 break;
3342 case FT_SINGLE:
3343 cpu_float_single_from_8( _environment, source->realName, target->realName, VT_SIGNED( source->type ) );
3344 break;
3345 default:
3347 }
3348 break;
3349 case VT_NUMBER:
3350 variable_move_1bit_number( _environment, source, target );
3351 break;
3352 default:
3354 }
3355
3356 break;
3357
3358 }
3359
3360 break;
3361
3362 case 0:
3363
3364 switch( VT_BITWIDTH( target->type ) ) {
3365 case 32:
3366 switch( source->type ) {
3367 case VT_FLOAT:
3369 break;
3370 case VT_NUMBER:
3371 variable_move_number_32bit( _environment, source, target );
3372 break;
3373 default:
3375 break;
3376 }
3377 break;
3378 case 16:
3379 switch( source->type ) {
3380 case VT_FLOAT:
3381 switch( source->precision ) {
3382 case FT_FAST:
3383 cpu_float_fast_to_16( _environment, source->realName, target->realName, VT_SIGNED( target->type ) );
3384 break;
3385 case FT_SINGLE:
3386 cpu_float_single_to_16( _environment, source->realName, target->realName, VT_SIGNED( target->type ) );
3387 break;
3388 default:
3390 }
3391 break;
3392 case VT_NUMBER:
3393 variable_move_number_16bit( _environment, source, target );
3394 break;
3395 default:
3397 break;
3398 }
3399 break;
3400 case 8:
3401 switch( source->type ) {
3402 case VT_FLOAT:
3403 switch( source->precision ) {
3404 case FT_FAST:
3405 cpu_float_fast_to_8( _environment, source->realName, target->realName, VT_SIGNED( target->type ) );
3406 break;
3407 case FT_SINGLE:
3408 cpu_float_single_to_8( _environment, source->realName, target->realName, VT_SIGNED( target->type ) );
3409 break;
3410 default:
3412 }
3413 break;
3414 case VT_NUMBER:
3415 variable_move_number_8bit( _environment, source, target );
3416 break;
3417 default:
3419 break;
3420 }
3421 break;
3422 case 1:
3423 switch( source->type ) {
3424 case VT_NUMBER:
3425 variable_move_number_1bit( _environment, source, target );
3426 break;
3427 default:
3429 break;
3430 }
3431 break;
3432 case 0:
3433 switch( source->type ) {
3434 case VT_STRING:
3435 switch( target->type ) {
3436 case VT_DSTRING: {
3437 cpu_dsfree( _environment, target->realName );
3438 cpu_dsdefine( _environment, source->realName, target->realName );
3439 break;
3440 }
3441 default:
3443 break;
3444 }
3445 break;
3446 case VT_DSTRING:
3447 switch( target->type ) {
3448 case VT_DSTRING: {
3449
3450 // Variable * sourceAddress = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
3451 // Variable * sourceSize = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
3452 // Variable * targetAddress = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
3453 // Variable * targetSize = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
3454 // cpu_dsdescriptor( _environment, source->realName, sourceAddress->realName, sourceSize->realName );
3455 // cpu_dsfree( _environment, target->realName );
3456 // cpu_dsalloc( _environment, sourceSize->realName, target->realName );
3457 // cpu_dsdescriptor( _environment, target->realName, targetAddress->realName, targetSize->realName );
3458 // cpu_mem_move( _environment, sourceAddress->realName, targetAddress->realName, sourceSize->realName );
3459
3460 cpu_dsassign( _environment, source->realName, target->realName );
3461 break;
3462 }
3463 default:
3465 break;
3466 }
3467 break;
3468 case VT_SPRITE:
3469 switch( target->type ) {
3470 case VT_SPRITE: {
3471 cpu_move_8bit( _environment, source->realName, target->realName );
3472 break;
3473 }
3474 default:
3476 break;
3477 }
3478 break;
3479 case VT_MSPRITE:
3480 switch( target->type ) {
3481 case VT_MSPRITE: {
3482 cpu_move_16bit( _environment, source->realName, target->realName );
3483 break;
3484 }
3485 default:
3487 break;
3488 }
3489 break;
3490 case VT_TILE:
3491 switch( target->type ) {
3492 case VT_TILE: {
3493 cpu_move_8bit( _environment, source->realName, target->realName );
3494 break;
3495 }
3496 default:
3498 break;
3499 }
3500 break;
3501 case VT_FLOAT:
3502 switch( target->type ) {
3503 case VT_FLOAT: {
3504 if ( source->precision != target->precision ) {
3506 }
3507 cpu_mem_move_direct_size( _environment, source->realName, target->realName, VT_FLOAT_BITWIDTH( source->precision ) >> 3 );
3508 break;
3509 }
3510 default:
3511 fprintf(stderr, "%s %d %s %d\n", source->name, source->type, target->name, target->type );
3513 break;
3514 }
3515 break;
3516 case VT_NUMBER:
3517 variable_move_number_number( _environment, source, target );
3518 break;
3519 case VT_TILESET:
3520 switch( target->type ) {
3521 case VT_TILESET: {
3522 cpu_move_8bit( _environment, source->realName, target->realName );
3523 break;
3524 }
3525 default:
3527 break;
3528 }
3529 break;
3530 case VT_TILEMAP:
3531 switch( target->type ) {
3532 case VT_TILEMAP: {
3533 if ( source->size != target->size ) {
3535 }
3536 target->mapWidth = source->mapWidth;
3537 target->mapHeight = source->mapHeight;
3538 target->mapLayers = source->mapLayers;
3539 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
3540 break;
3541 }
3542 default:
3544 break;
3545 }
3546 break;
3547 case VT_TILES:
3548 switch( target->type ) {
3549 case VT_TILES: {
3550 target->originalWidth = source->originalWidth;
3551 target->originalHeight = source->originalHeight;
3552 target->originalDepth = source->originalDepth;
3553 cpu_move_32bit( _environment, source->realName, target->realName );
3554 break;
3555 }
3556 default:
3558 break;
3559 }
3560 break;
3561 case VT_IMAGEREF:
3562 switch( target->type ) {
3563 case VT_IMAGEREF: {
3564 cpu_mem_move_direct_size( _environment, source->realName, target->realName, 14 );
3565 break;
3566 }
3567 default:
3569 break;
3570 }
3571 break;
3572 case VT_PATH:
3573 switch( target->type ) {
3574 case VT_PATH: {
3575 cpu_mem_move_direct_size( _environment, source->realName, target->realName, 16 );
3576 break;
3577 }
3578 default:
3580 break;
3581 }
3582 break;
3583 case VT_VECTOR2:
3584 switch( target->type ) {
3585 case VT_VECTOR2: {
3586 cpu_mem_move_direct_size( _environment, source->realName, target->realName, 4 );
3587 break;
3588 }
3589 default:
3591 break;
3592 }
3593 break;
3594 case VT_IMAGE:
3595 switch( target->type ) {
3596 case VT_IMAGE:
3597 if ( ! source->valueBuffer ) {
3599 }
3600 target->originalBitmap = source->originalBitmap;
3601 target->originalWidth = source->originalWidth;
3602 target->originalHeight = source->originalHeight;
3603 target->originalColors = source->originalColors;
3604 target->originalDepth = source->originalDepth;
3605 memcpy( target->originalPalette, source->originalPalette, MAX_PALETTE * sizeof( RGBi ) );
3606 case VT_BUFFER: {
3607 char bankWindowName[MAX_TEMPORARY_STORAGE];
3608 int realSize = 0;
3609 int realAllocationSize = 0;
3610 if ( source->bankAssigned != -1 ) {
3611
3613
3614 char alreadyLoadedLabel[MAX_TEMPORARY_STORAGE];
3615 sprintf(alreadyLoadedLabel, "%salready", label );
3616
3617 char bankWindowId[MAX_TEMPORARY_STORAGE];
3618 sprintf( bankWindowId, "BANKWINDOWID%2.2x", source->residentAssigned );
3619
3620 sprintf( bankWindowName, "BANKWINDOW%2.2x", source->residentAssigned );
3621
3622 realAllocationSize = _environment->maxExpansionBankSize[source->residentAssigned];
3623
3624 if ( _environment->residentDetectionEnabled ) {
3625 cpu_compare_and_branch_16bit_const( _environment, bankWindowId, source->variableUniqueId, alreadyLoadedLabel, 1 );
3626 }
3627 if ( source->uncompressedSize ) {
3628 bank_uncompress_semi_var( _environment, source->bankAssigned, source->absoluteAddress, bankWindowName );
3629 realSize = source->uncompressedSize;
3630 } else {
3631 bank_read_semi_var( _environment, source->bankAssigned, source->absoluteAddress, bankWindowName, source->size );
3632 realSize = source->size;
3633 }
3634 if ( _environment->residentDetectionEnabled ) {
3635 cpu_store_16bit(_environment, bankWindowId, source->variableUniqueId );
3636 cpu_label( _environment, alreadyLoadedLabel );
3637 }
3638 } else {
3639 strcopy( bankWindowName, source->realName );
3640 realSize = source->size;
3641 realAllocationSize = realSize;
3642 }
3643
3644 if ( target->size == 0 ) {
3645 target->size = realAllocationSize;
3646 target->valueBuffer = malloc( target->size );
3647 memset( target->valueBuffer, 0, target->size );
3648 }
3649 if ( source->size <= target->size ) {
3650 cpu_mem_move_direct_size( _environment, bankWindowName, target->realName, realSize );
3651 } else {
3653 }
3654 break;
3655
3656 }
3657 default:
3659 }
3660 break;
3661 case VT_IMAGES:
3662 switch( target->type ) {
3663 case VT_IMAGES:
3664 target->frameWidth = source->frameWidth;
3665 target->frameHeight = source->frameHeight;
3666 target->originalTileset = source->originalTileset;
3667 case VT_BUFFER:
3668 if ( target->size == 0 ) {
3669 target->size = source->size;
3670 target->valueBuffer = malloc( target->size );
3671 memset( target->valueBuffer, 0, target->size );
3672 }
3673 if ( source->size <= target->size ) {
3674 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
3675 } else {
3677 }
3678 break;
3679 default:
3681 }
3682 break;
3683 case VT_SEQUENCE:
3684 switch( target->type ) {
3685 case VT_SEQUENCE:
3686 target->frameWidth = source->frameWidth;
3687 target->frameHeight = source->frameHeight;
3688 case VT_BUFFER:
3689 if ( target->size == 0 ) {
3690 target->size = source->size;
3691 target->valueBuffer = malloc( target->size );
3692 memset( target->valueBuffer, 0, target->size );
3693 }
3694 if ( source->size <= target->size ) {
3695 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
3696 } else {
3698 }
3699 break;
3700 default:
3702 }
3703 break;
3704 case VT_MUSIC:
3705 if ( source->sidFile ) {
3707 }
3708 switch( target->type ) {
3709 case VT_MUSIC:
3710 case VT_BUFFER:
3711 if ( target->size == 0 ) {
3712 target->size = source->size;
3713 target->valueBuffer = malloc( target->size );
3714 memset( target->valueBuffer, 0, target->size );
3715 }
3716 if ( source->size <= target->size ) {
3717 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
3718 } else {
3720 }
3721 break;
3722 default:
3724 }
3725 break;
3726 case VT_DOJOKA:
3727 switch( target->type ) {
3728 case VT_DOJOKA:
3729 if ( target->size == 0 ) {
3730 target->size = source->size;
3731 target->valueBuffer = malloc( 4 );
3732 memset( target->valueBuffer, 0, 4 );
3733 }
3734 cpu_mem_move_direct_size( _environment, source->realName, target->realName, 4 );
3735 break;
3736 case VT_DSTRING: {
3737 Variable * dojokaHandle = variable_temporary( _environment, VT_DWORD, "(dojoka)");
3738 cpu_mem_move_direct_size( _environment, source->realName, dojokaHandle->realName, 4 );
3739 // #if CPU_BIG_ENDIAN
3740 cpu_swap_8bit( _environment, dojokaHandle->realName, address_displacement( _environment, dojokaHandle->realName, "3" ) );
3741 cpu_swap_8bit( _environment, address_displacement( _environment, dojokaHandle->realName, "1" ), address_displacement( _environment, dojokaHandle->realName, "2" ) );
3742 // #endif
3743 cpu_dsfree( _environment, target->realName );
3744 cpu_move_8bit( _environment, variable_hex( _environment, dojokaHandle->name, 0 )->realName, target->realName );
3745 break;
3746 }
3747 case VT_DWORD: {
3748 cpu_mem_move_direct_size( _environment, source->realName, target->realName, 4 );
3749 #if CPU_BIG_ENDIAN
3750 cpu_swap_8bit( _environment, target->realName, address_displacement( _environment, target->realName, "3" ) );
3751 cpu_swap_8bit( _environment, address_displacement( _environment, target->realName, "1" ), address_displacement( _environment, target->realName, "2" ) );
3752 #endif
3753 break;
3754 }
3755 default:
3757 }
3758 break;
3759 case VT_TYPE:
3760 switch( target->type ) {
3761 case VT_TYPE:
3762 if ( strcmp( source->typeType->name, target->typeType->name ) != 0 ) {
3763 CRITICAL_CANNOT_CAST( source->typeType->name, source->typeType->name );
3764 }
3765 if ( target->size == 0 ) {
3766 target->size = source->size;
3767 target->valueBuffer = malloc( source->size );
3768 memset( target->valueBuffer, 0, source->size );
3769 }
3770
3771 Type * type = source->typeType;
3772 Field * first = type->first;
3773 while( first ) {
3774 if ( first->type == VT_DSTRING ) {
3775 break;
3776 }
3777 first = first->next;
3778 }
3779
3780 if ( !first ) {
3781 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
3782 } else {
3783 first = type->first;
3784 while( first ) {
3785 Variable * value = variable_temporary( _environment, first->type, "(field)" );
3786 variable_move_from_type_inplace( _environment, source->name, first->name, value->name );
3787 variable_move_type( _environment, target->name, first->name, value->name );
3788 first = first->next;
3789 }
3790 }
3791
3792 break;
3793 default:
3794 CRITICAL_CANNOT_CAST( source->typeType->name, DATATYPE_AS_STRING[target->type]);
3795 }
3796 break;
3797 case VT_BUFFER:
3798 case VT_TARRAY:
3799 switch( target->type ) {
3800 case VT_DSTRING: {
3801 if ( source->size > 255 ) {
3803 }
3804 outline1("; LINE: %d", __LINE__);
3805 cpu_dsfree( _environment, target->realName );
3806 cpu_dsalloc_size( _environment, source->size, target->realName );
3807 Variable * targetAddress = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
3808 Variable * targetSize = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
3809 cpu_dsdescriptor( _environment, target->realName, targetAddress->realName, targetSize->realName );
3810 cpu_mem_move_direct_indirect_size( _environment, source->realName, targetAddress->realName, source->size );
3811 break;
3812 }
3813 case VT_STRING:
3815 case VT_MUSIC:
3816 if ( target->sidFile ) {
3818 }
3819 case VT_IMAGE:
3820 case VT_IMAGES:
3821 case VT_SEQUENCE:
3822 case VT_BUFFER:
3823 if ( target->size == 0 ) {
3824 target->size = source->size;
3825 target->valueBuffer = malloc( target->size );
3826 memset( target->valueBuffer, 0, target->size );
3827 }
3828 if ( source->size <= target->size ) {
3829 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
3830 } else {
3832 }
3833 break;
3834 case VT_TARRAY:
3835 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
3836 break;
3837 }
3838 break;
3839 default:
3841 }
3842 break;
3843
3844 }
3845 break;
3846 }
3847
3848
3849 return target;
3850}
3851
3868Variable * variable_add_const( Environment * _environment, char * _source, int _destination ) {
3869
3870 Variable * source = variable_retrieve( _environment, _source );
3871
3872 Variable * result;
3873
3874 switch( VT_BITWIDTH( source->type ) ) {
3875 case 32:
3876 result = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SDWORD : VT_DWORD, "(result of sum)" );
3877 cpu_math_add_32bit_const( _environment, source->realName, _destination, result->realName );
3878 break;
3879 case 16:
3880 result = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_SWORD, "(result of sum)" );
3881 cpu_math_add_16bit_const( _environment, source->realName, _destination, result->realName );
3882 break;
3883 case 8:
3884 result = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SBYTE : VT_BYTE, "(result of sum)" );
3885 cpu_math_add_8bit_const( _environment, source->realName, _destination, result->realName );
3886 break;
3887 case 1:
3889 break;
3890 case 0:
3891 switch( source->type ) {
3892 case VT_VECTOR2: {
3893 result = create_vector( _environment, vector_get_x( _environment, source->name )->name, vector_get_y( _environment, source->name )->name );
3894 cpu_math_add_16bit_const( _environment, result->realName, _destination, result->realName );
3895 cpu_math_add_16bit_const( _environment, address_displacement( _environment, result->realName, "2" ), _destination, address_displacement( _environment, result->realName, "2" ) );
3896 break;
3897 }
3898 }
3900 break;
3901 }
3902
3903 return result;
3904}
3905
3922Variable * variable_move_naked( Environment * _environment, char * _source, char * _destination ) {
3923 Variable * source = variable_retrieve( _environment, _source );
3924 Variable * target = variable_retrieve( _environment, _destination );
3925
3926 if ( source->type != target->type ) {
3928 }
3929 switch( VT_BITWIDTH( source->type ) ) {
3930 case 32:
3931 cpu_move_32bit( _environment, source->realName, target->realName );
3932 break;
3933 case 16:
3934 cpu_move_16bit( _environment, source->realName, target->realName );
3935 break;
3936 case 8:
3937 cpu_move_8bit( _environment, source->realName, target->realName );
3938 break;
3939 case 1: {
3940 cpu_bit_check( _environment, source->realName, source->bitPosition, NULL, 8 );
3941 cpu_bit_inplace_8bit( _environment, target->realName, target->bitPosition, NULL );
3942 break;
3943 }
3944 case 0:
3945 switch( target->type ) {
3946 case VT_DSTRING: {
3947 // Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
3948 // Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
3949 // Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
3950 // Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
3951 // cpu_dsdescriptor( _environment, source->realName, address->realName, size->realName );
3952 // cpu_dsfree( _environment, target->realName );
3953 // cpu_dsalloc( _environment, size->realName, target->realName );
3954 // cpu_dsdescriptor( _environment, target->realName, address2->realName, size2->realName );
3955 // cpu_mem_move( _environment, address->realName, address2->realName, size->realName );
3956 cpu_dsassign( _environment, source->realName, target->realName );
3957 break;
3958 }
3959 case VT_SPRITE:
3960 switch( target->type ) {
3961 case VT_SPRITE: {
3962 cpu_move_8bit( _environment, source->realName, target->realName );
3963 break;
3964 }
3965 default:
3967 break;
3968 }
3969 break;
3970 case VT_MSPRITE:
3971 switch( target->type ) {
3972 case VT_MSPRITE: {
3973 cpu_move_16bit( _environment, source->realName, target->realName );
3974 break;
3975 }
3976 default:
3978 break;
3979 }
3980 break;
3981 case VT_TILE:
3982 switch( target->type ) {
3983 case VT_TILE: {
3984 cpu_move_8bit( _environment, source->realName, target->realName );
3985 break;
3986 }
3987 default:
3989 break;
3990 }
3991 break;
3992 case VT_FLOAT:
3993 switch( target->type ) {
3994 case VT_FLOAT: {
3995 if ( source->precision != target->precision ) {
3997 }
3998 cpu_move_nbit( _environment, VT_FLOAT_BITWIDTH( source->precision ), source->realName, target->realName );
3999 break;
4000 }
4001 default:
4003 break;
4004 }
4005 break;
4006 case VT_TILESET:
4007 switch( target->type ) {
4008 case VT_TILESET: {
4009 cpu_move_8bit( _environment, source->realName, target->realName );
4010 break;
4011 }
4012 default:
4014 break;
4015 }
4016 break;
4017 case VT_TILEMAP:
4018 switch( target->type ) {
4019 case VT_TILEMAP: {
4020 if ( source->size != target->size ) {
4022 }
4023 target->mapWidth = source->mapWidth;
4024 target->mapHeight = source->mapHeight;
4025 target->mapLayers = source->mapLayers;
4026 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
4027 break;
4028 }
4029 default:
4031 break;
4032 }
4033 break;
4034 case VT_TILES:
4035 switch( target->type ) {
4036 case VT_TILES: {
4037 target->originalWidth = source->originalWidth;
4038 target->originalHeight = source->originalHeight;
4039 target->originalDepth = source->originalDepth;
4040 cpu_move_16bit( _environment, source->realName, target->realName );
4041 break;
4042 }
4043 default:
4045 break;
4046 }
4047 break;
4048 case VT_IMAGE:
4049 target->originalBitmap = source->originalBitmap;
4050 target->originalWidth = source->originalWidth;
4051 target->originalHeight = source->originalHeight;
4052 target->originalDepth = source->originalDepth;
4053 target->originalColors = source->originalColors;
4054 memcpy( target->originalPalette, source->originalPalette, MAX_PALETTE * sizeof( RGBi ) );
4055 target->originalTileset = source->originalTileset;
4056 target->bankAssigned = source->bankAssigned;
4057 target->residentAssigned = source->residentAssigned;
4058 target->uncompressedSize = source->uncompressedSize;
4059 if ( target->bankAssigned != -1 ) {
4060 target->absoluteAddress = source->absoluteAddress;
4061 target->variableUniqueId = source->variableUniqueId;
4062 }
4063 case VT_IMAGES: {
4064 target->frameWidth = source->frameWidth;
4065 target->frameHeight = source->frameHeight;
4066 target->bankAssigned = source->bankAssigned;
4067 target->originalTileset = source->originalTileset;
4068 if ( target->size == 0 ) {
4069 target->size = source->size;
4070 }
4071 if ( source->size > target->size ) {
4072 CRITICAL_BUFFER_SIZE_MISMATCH(_source, _destination);
4073 }
4074 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
4075 break;
4076 }
4077 case VT_DOJOKA: {
4078 if ( target->size == 0 ) {
4079 target->size = 4;
4080 }
4081 cpu_mem_move_direct_size( _environment, source->realName, target->realName, 4 );
4082 break;
4083 }
4084 case VT_IMAGEREF: {
4085 if ( target->size == 0 ) {
4086 target->size = 14;
4087 }
4088 cpu_mem_move_direct_size( _environment, source->realName, target->realName, 14 );
4089 break;
4090 }
4091 case VT_PATH: {
4092 if ( target->size == 0 ) {
4093 target->size = 16;
4094 }
4095 cpu_mem_move_direct_size( _environment, source->realName, target->realName, 16 );
4096 break;
4097 }
4098 case VT_VECTOR2: {
4099 if ( target->size == 0 ) {
4100 target->size = 4;
4101 }
4102 cpu_mem_move_direct_size( _environment, source->realName, target->realName, 4 );
4103 break;
4104 }
4105 case VT_MUSIC:
4106 if ( target->sidFile ) {
4108 }
4109 case VT_TARRAY:
4110 case VT_SEQUENCE:
4111 case VT_TYPE:
4112 case VT_NUMBER:
4113 case VT_BUFFER: {
4114 if ( target->size == 0 ) {
4115 target->size = source->size;
4116 }
4117 if ( source->size > target->size ) {
4118 CRITICAL_BUFFER_SIZE_MISMATCH(_source, _destination);
4119 }
4120 cpu_mem_move_direct_size( _environment, source->realName, target->realName, source->size );
4121 target->bankAssigned = source->bankAssigned;
4122 break;
4123 }
4124 default:
4126 }
4127 }
4128 return source;
4129}
4130
4147Variable * variable_add( Environment * _environment, char * _source, char * _destination ) {
4148
4149 Variable * source = variable_retrieve( _environment, _source );
4150 if ( source->type == VT_STRING ) {
4151 source = variable_cast( _environment, _source, VT_DSTRING );
4152 }
4153
4154 Variable * target = variable_retrieve( _environment, _destination );
4155 if ( target->type == VT_STRING ) {
4156 target = variable_cast( _environment, _destination, VT_DSTRING );
4157 }
4158 if ( ! target ) {
4159 CRITICAL_VARIABLE(_destination);
4160 }
4161
4162 if ( source->type == VT_STRING || source->type == VT_DSTRING || source->type == VT_VECTOR2 ) {
4163
4164 } else {
4165
4166 int best = calculate_cast_type_best_fit( _environment, source->type, target->type );
4167 source = variable_cast( _environment, source->name, best );
4168 target = variable_cast( _environment, target->name, best );
4169
4170 }
4171
4172 Variable * result;
4173
4174 switch( VT_BITWIDTH( source->type ) ) {
4175 case 32:
4176 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SDWORD : VT_DWORD, "(result of sum)" );
4177 cpu_math_add_32bit( _environment, source->realName, target->realName, result->realName );
4178 break;
4179 case 16:
4180 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SWORD : VT_WORD, "(result of sum)" );
4181 cpu_math_add_16bit( _environment, source->realName, target->realName, result->realName );
4182 break;
4183 case 8:
4184 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SBYTE : VT_BYTE, "(result of sum)" );
4185 cpu_math_add_8bit( _environment, source->realName, target->realName, result->realName );
4186 break;
4187 case 1:
4189 break;
4190 case 0:
4191 switch( source->type ) {
4192 case VT_DSTRING: {
4193 result = variable_temporary( _environment, VT_DSTRING, "(result of sum)" );
4194 Variable * address1 = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING1)");
4195 Variable * size1 = variable_temporary( _environment, VT_BYTE, "(size of DSTRING1)");
4196 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING2)");
4197 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of DSTRING2)");
4198 Variable * address= variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
4199 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
4200 cpu_dsdescriptor( _environment, source->realName, address1->realName, size1->realName );
4201 cpu_dsdescriptor( _environment, target->realName, address2->realName, size2->realName );
4202 cpu_math_add_8bit( _environment, size1->realName, size2->realName, size->realName );
4203 cpu_dsfree( _environment, result->realName );
4204 cpu_dsalloc( _environment, size->realName, result->realName );
4205 cpu_dsdescriptor( _environment, result->realName, address->realName, size->realName );
4206 cpu_mem_move( _environment, address1->realName, address->realName, size1->realName );
4207 cpu_math_add_16bit_with_8bit( _environment, address->realName, size1->realName, address->realName );
4208 cpu_mem_move( _environment, address2->realName, address->realName, size2->realName );
4209 break;
4210 }
4211 case VT_STRING: {
4212 result = variable_temporary( _environment, VT_DSTRING, "(result of sum)" );
4213 Variable * address1 = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING1)");
4214 Variable * size1 = variable_temporary( _environment, VT_BYTE, "(size of DSTRING1)");
4215 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING2)");
4216 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of DSTRING2)");
4217 Variable * address= variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
4218 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
4219 cpu_move_8bit( _environment, source->realName, size1->realName );
4220 cpu_addressof_16bit( _environment, source->realName, address1->realName );
4221 cpu_inc_16bit( _environment, address1->realName );
4222 cpu_math_add_8bit( _environment, size1->realName, size2->realName, size->realName );
4223 cpu_dsfree( _environment, result->realName );
4224 cpu_dsalloc( _environment, size->realName, result->realName );
4225 cpu_mem_move( _environment, address1->realName, address->realName, size1->realName );
4226 cpu_math_add_16bit_with_8bit( _environment, address->realName, size1->realName, address->realName );
4227 cpu_mem_move( _environment, address2->realName, address->realName, size2->realName );
4228 break;
4229 }
4230 case VT_VECTOR2: {
4231 switch( VT_BITWIDTH( target->type ) ) {
4232 case 32:
4233 case 16:
4234 case 8: {
4235 Variable * x = vector_get_x( _environment, source->name );
4236 Variable * y = vector_get_y( _environment, source->name );
4237 result = create_vector( _environment,
4238 variable_add( _environment, x->name, target->name )->name,
4239 variable_add( _environment, y->name, target->name )->name
4240 );
4241 break;
4242 }
4243 case 1:
4244 CRITICAL_ADD_UNSUPPORTED( _destination, DATATYPE_AS_STRING[target->type]);
4245 case 0:
4246 switch( target->type ) {
4247 case VT_VECTOR2:
4248 result = create_vector( _environment, vector_get_x( _environment, source->name )->name, vector_get_y( _environment, source->name )->name );
4249 cpu_math_add_16bit( _environment, result->realName, target->realName, result->realName );
4250 cpu_math_add_16bit( _environment, address_displacement( _environment, result->realName, "2" ), address_displacement( _environment, target->realName, "2" ), address_displacement( _environment, result->realName, "2" ) );
4251 break;
4252 default:
4253 CRITICAL_ADD_UNSUPPORTED( _destination, DATATYPE_AS_STRING[target->type]);
4254 }
4255 break;
4256 }
4257 break;
4258 }
4259 case VT_FLOAT:
4260 result = variable_temporary( _environment, VT_FLOAT, "(result of sum)" );
4261 switch( target->precision ) {
4262 case FT_FAST: {
4263 cpu_float_fast_add( _environment, source->realName, target->realName, result->realName );
4264 break;
4265 }
4266 case FT_SINGLE: {
4267 cpu_float_single_add( _environment, source->realName, target->realName, result->realName );
4268 break;
4269 }
4270 default:
4272 break;
4273 }
4274 break;
4275 case VT_NUMBER:
4276 result = variable_temporary( _environment, VT_NUMBER, "(result of sum)" );
4277 cpu_math_add_nbit( _environment, source->realName, target->realName, result->realName, _environment->numberConfig.maxBytes << 3 );
4278 break;
4279 default: {
4281 }
4282 }
4283 }
4284
4285 return result;
4286}
4287
4288void variable_add_inplace( Environment * _environment, char * _source, int _destination ) {
4289
4290 if ( _destination ) {
4291
4292 Variable * source = variable_retrieve( _environment, _source );
4293 if ( source->type == VT_STRING ) {
4294 source = variable_cast( _environment, _source, VT_DSTRING );
4295 }
4296
4297 switch( VT_BITWIDTH( source->type ) ) {
4298 case 32:
4299 cpu_math_add_32bit_const( _environment, source->realName, _destination, source->realName );
4300 break;
4301 case 16:
4302 cpu_math_add_16bit_const( _environment, source->realName, _destination, source->realName );
4303 break;
4304 case 8:
4305 cpu_math_add_8bit_const( _environment, source->realName, _destination, source->realName );
4306 break;
4307 case 0: {
4308 switch( source->type ) {
4309 case VT_VECTOR2:
4310 cpu_math_add_16bit_const( _environment, source->realName, _destination, source->realName );
4311 cpu_math_add_16bit_const( _environment, address_displacement( _environment, source->realName, "2" ), _destination, address_displacement( _environment, source->realName, "2" ) );
4312 break;
4313 default:
4315 }
4316
4317 }
4318 case 1:
4319 default:
4321 }
4322
4323 }
4324}
4325
4326void variable_add_inplace_type( Environment * _environment, char * _source, char * _field, int _destination ) {
4327
4328 if ( _destination ) {
4329
4330
4331 Variable * source = variable_retrieve( _environment, _source );
4332
4333 if ( source->type != VT_TYPE ) {
4335 }
4336 Field * field = field_find( source->typeType, _field );
4337 if ( ! field ) {
4339 }
4340
4341 char offsetAsString[MAX_TEMPORARY_STORAGE];
4342 sprintf( offsetAsString, "%d", field->offset );
4343 switch( VT_BITWIDTH( field->type ) ) {
4344 case 32:
4345 cpu_math_add_32bit_const( _environment, address_displacement( _environment, source->realName, offsetAsString ), _destination, address_displacement( _environment, source->realName, offsetAsString ) );
4346 break;
4347 case 16:
4348 cpu_math_add_16bit_const( _environment, address_displacement( _environment, source->realName, offsetAsString ), _destination, address_displacement( _environment, source->realName, offsetAsString ) );
4349 break;
4350 case 8:
4351 cpu_math_add_8bit_const( _environment, address_displacement( _environment, source->realName, offsetAsString ), _destination, address_displacement( _environment, source->realName, offsetAsString ) );
4352 break;
4353 case 1:
4354 case 0:
4355 default:
4357 }
4358
4359 }
4360}
4361
4377void variable_add_inplace_vars( Environment * _environment, char * _source, char * _destination ) {
4378
4379 Variable * source = variable_retrieve( _environment, _source );
4380 if ( source->type == VT_STRING ) {
4381 source = variable_cast( _environment, _source, VT_DSTRING );
4382 }
4383
4384 Variable * target = variable_retrieve( _environment, _destination );
4385 if ( target->type == VT_STRING ) {
4386 target = variable_cast( _environment, _destination, VT_DSTRING );
4387 }
4388
4389 if ( source->type != VT_VECTOR2 ) {
4390 if ( source->type != target->type ) {
4391 target = variable_cast( _environment, _destination, source->type );
4392 if ( ! target ) {
4393 CRITICAL_VARIABLE(_destination);
4394 }
4395 }
4396 } else {
4397 target = variable_cast( _environment, _destination, VT_POSITION );
4398 }
4399
4400 switch( VT_BITWIDTH( source->type ) ) {
4401 case 32:
4402 cpu_math_add_32bit( _environment, source->realName, target->realName, source->realName );
4403 break;
4404 case 16:
4405 cpu_math_add_16bit( _environment, source->realName, target->realName, source->realName );
4406 break;
4407 case 8:
4408 cpu_math_add_8bit( _environment, source->realName, target->realName, source->realName );
4409 break;
4410 case 1:
4412 case 0:
4413 switch( source->type ) {
4414 case VT_VECTOR2:
4415 cpu_math_add_16bit( _environment, source->realName, target->realName, source->realName );
4416 cpu_math_add_16bit( _environment, address_displacement( _environment, source->realName, "2" ), target->realName, address_displacement( _environment, source->realName, "2" ) );
4417 break;
4418 case VT_NUMBER:
4419 cpu_math_add_nbit( _environment, source->realName, target->realName, source->realName, _environment->numberConfig.maxBytes << 3 );
4420 break;
4421 case VT_FLOAT:
4422 switch( target->precision ) {
4423 case FT_FAST: {
4424 cpu_float_fast_add( _environment, source->realName, target->realName, source->realName );
4425 break;
4426 }
4427 case FT_SINGLE: {
4428 cpu_float_single_add( _environment, source->realName, target->realName, source->realName );
4429 break;
4430 }
4431 default:
4433 break;
4434 }
4435 break;
4436 default:
4438 }
4439 }
4440
4441}
4442
4443void variable_add_inplace_type_vars( Environment * _environment, char * _source, char * _field, char * _destination ) {
4444
4445 Variable * source = variable_retrieve( _environment, _source );
4446
4447 if ( source->type != VT_TYPE ) {
4449 }
4450 Field * field = field_find( source->typeType, _field );
4451 if ( ! field ) {
4453 }
4454
4455 Variable * target = variable_retrieve_or_define( _environment, _destination, field->type, 0 );
4456
4457 char offsetAsString[MAX_TEMPORARY_STORAGE];
4458 sprintf( offsetAsString, "%d", field->offset );
4459 switch( VT_BITWIDTH( field->type ) ) {
4460 case 32:
4461 cpu_math_add_32bit( _environment, address_displacement( _environment, source->realName, offsetAsString ), target->realName, address_displacement( _environment, source->realName, offsetAsString ) );
4462 break;
4463 case 16:
4464 cpu_math_add_16bit( _environment, address_displacement( _environment, source->realName, offsetAsString ), target->realName, address_displacement( _environment, source->realName, offsetAsString ) );
4465 break;
4466 case 8:
4467 cpu_math_add_8bit( _environment, address_displacement( _environment, source->realName, offsetAsString ), target->realName, address_displacement( _environment, source->realName, offsetAsString ) );
4468 break;
4469 case 1:
4470 case 0:
4472 }
4473
4474}
4475
4483void variable_add_inplace_array( Environment * _environment, char * _source, char * _destination ) {
4484
4485 Variable * array = variable_retrieve( _environment, _source );
4486 if ( array->type != VT_TARRAY ) {
4487 CRITICAL_NOT_ARRAY( _source );
4488 }
4489 Variable * value = variable_move_from_array( _environment, array->name );
4490
4491 variable_add_inplace_vars( _environment, value->name, _destination );
4492
4493 variable_move_array( _environment, array->name, value->name );
4494
4495}
4496
4497
4513void variable_add_inplace_mt( Environment * _environment, char * _source, char * _destination ) {
4514
4515 parser_array_init( _environment );
4516 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
4517 Variable * array = variable_retrieve( _environment, _source );
4518 if ( array->type != VT_TARRAY ) {
4519 CRITICAL_NOT_ARRAY( _source );
4520 }
4521 Variable * value = variable_move_from_array( _environment, array->name );
4522 parser_array_cleanup( _environment );
4523
4524 variable_add_inplace_vars( _environment, value->name, _destination );
4525
4526 parser_array_init( _environment );
4527 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
4528 array = variable_retrieve( _environment, _source );
4529 if ( array->type != VT_TARRAY ) {
4530 CRITICAL_NOT_ARRAY( _source );
4531 }
4532 variable_move_array( _environment, array->name, value->name );
4533 parser_array_cleanup( _environment );
4534
4535}
4536
4537void variable_xor_inplace( Environment * _environment, char * _source, int _destination ) {
4538
4539 if ( _destination ) {
4540
4541 Variable * source = variable_retrieve( _environment, _source );
4542
4543 switch( VT_BITWIDTH( source->type ) ) {
4544 case 32:
4545 cpu_xor_32bit_const( _environment, source->realName, _destination, source->realName );
4546 break;
4547 case 16:
4548 cpu_xor_16bit_const( _environment, source->realName, _destination, source->realName );
4549 break;
4550 case 8:
4551 cpu_xor_8bit_const( _environment, source->realName, _destination, source->realName );
4552 break;
4553 case 1:
4554 case 0:
4556 }
4557
4558 }
4559}
4560
4576void variable_xor_inplace_vars( Environment * _environment, char * _source, char * _destination ) {
4577
4578 Variable * source = variable_retrieve( _environment, _source );
4579 Variable * target = variable_retrieve( _environment, _destination );
4580
4581 if ( source->type != target->type ) {
4582 target = variable_cast( _environment, _destination, source->type );
4583 if ( ! target ) {
4584 CRITICAL_VARIABLE(_destination);
4585 }
4586 }
4587
4588 switch( VT_BITWIDTH( source->type ) ) {
4589 case 32:
4590 cpu_xor_32bit( _environment, source->realName, target->realName, source->realName );
4591 break;
4592 case 16:
4593 cpu_xor_16bit( _environment, source->realName, target->realName, source->realName );
4594 break;
4595 case 8:
4596 cpu_xor_8bit( _environment, source->realName, target->realName, source->realName );
4597 break;
4598 case 1:
4599 case 0:
4601 }
4602
4603}
4604
4620void variable_xor_inplace_mt( Environment * _environment, char * _source, char * _destination ) {
4621
4622 parser_array_init( _environment );
4623 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
4624 Variable * array = variable_retrieve( _environment, _source );
4625 if ( array->type != VT_TARRAY ) {
4626 CRITICAL_NOT_ARRAY( _source );
4627 }
4628 Variable * value = variable_move_from_array( _environment, array->name );
4629 parser_array_cleanup( _environment );
4630
4631 variable_xor_inplace_vars( _environment, value->name, _destination );
4632
4633 parser_array_init( _environment );
4634 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
4635 array = variable_retrieve( _environment, _source );
4636 if ( array->type != VT_TARRAY ) {
4637 CRITICAL_NOT_ARRAY( _source );
4638 }
4639 variable_move_array( _environment, array->name, value->name );
4640 parser_array_cleanup( _environment );
4641
4642}
4643
4660Variable * variable_sub( Environment * _environment, char * _source, char * _dest ) {
4661 Variable * source = variable_retrieve( _environment, _source );
4662 Variable * target = variable_retrieve( _environment, _dest );
4663
4664 Variable * result;
4665 if (
4666 ( source->type == VT_STRING || source->type == VT_DSTRING ) &&
4667 ( target->type == VT_STRING || target->type == VT_DSTRING )
4668 ) {
4669
4670 Variable * source = variable_cast( _environment, _source, VT_DSTRING );
4671 Variable * target = variable_cast( _environment, _dest, VT_DSTRING );
4672 result = variable_temporary( _environment, VT_DSTRING, "(result of subtracting)" );
4673
4674 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
4675 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
4676 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
4677 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
4678 Variable * address3 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
4679 Variable * size3 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
4680 cpu_dsdescriptor( _environment, source->realName, address->realName, size->realName );
4681 cpu_dsdescriptor( _environment, target->realName, address2->realName, size2->realName );
4682 cpu_dsalloc( _environment, size->realName, result->realName );
4683 cpu_dsdescriptor( _environment, result->realName, address3->realName, size3->realName );
4684 cpu_string_sub( _environment, address->realName, size->realName, address2->realName, size2->realName, address3->realName, size3->realName );
4685 cpu_dsresize( _environment, result->realName, size3->realName );
4686 } else {
4687
4688 if ( source->type == VT_VECTOR2 ) {
4689
4690 } else {
4691
4692 int best = calculate_cast_type_best_fit( _environment, source->type, target->type );
4693 source = variable_cast( _environment, source->name, best );
4694 target = variable_cast( _environment, target->name, best );
4695 result = variable_temporary( _environment, VT_SIGN( best ), "(result of subtracting)" );
4696
4697 }
4698
4699 switch( VT_BITWIDTH( source->type ) ) {
4700 case 32:
4701 cpu_math_sub_32bit( _environment, source->realName, target->realName, result->realName );
4702 break;
4703 case 16:
4704 cpu_math_sub_16bit( _environment, source->realName, target->realName, result->realName );
4705 break;
4706 case 8:
4707 cpu_math_sub_8bit( _environment, source->realName, target->realName, result->realName );
4708 break;
4709 case 1:
4711 break;
4712 case 0:
4713 switch( source->type ) {
4714 case VT_FLOAT:
4715 switch( target->precision ) {
4716 case FT_FAST: {
4717 cpu_float_fast_sub( _environment, source->realName, target->realName, result->realName );
4718 break;
4719 }
4720 case FT_SINGLE: {
4721 cpu_float_single_sub( _environment, source->realName, target->realName, result->realName );
4722 break;
4723 }
4724 default:
4726 break;
4727 }
4728 break;
4729 case VT_NUMBER:
4730 cpu_math_sub_nbit( _environment, source->realName, target->realName, result->realName, _environment->numberConfig.maxBytes << 3 );
4731 break;
4732 case VT_VECTOR2: {
4733 switch( VT_BITWIDTH( target->type ) ) {
4734 case 32:
4735 case 16:
4736 case 8: {
4737 Variable * x = vector_get_x( _environment, source->name );
4738 Variable * y = vector_get_y( _environment, source->name );
4739 result = create_vector( _environment,
4740 variable_sub( _environment, x->name, target->name )->name,
4741 variable_sub( _environment, y->name, target->name )->name
4742 );
4743 break;
4744 }
4745 case 1:
4747 case 0:
4748 switch( target->type ) {
4749 case VT_VECTOR2:
4750 result = create_vector( _environment, vector_get_x( _environment, source->name )->name, vector_get_y( _environment, source->name )->name );
4751 cpu_math_sub_16bit( _environment, result->realName, target->realName, result->realName );
4752 cpu_math_sub_16bit( _environment, address_displacement( _environment, result->realName, "2" ), address_displacement( _environment, target->realName, "2" ), address_displacement( _environment, result->realName, "2" ) );
4753 break;
4754 default:
4756 }
4757 break;
4758 }
4759 break;
4760 }
4761
4762 default:
4764 }
4765 }
4766 }
4767 return result;
4768}
4769
4786Variable * variable_sub_const( Environment * _environment, char * _source, int _destination ) {
4787 Variable * source = variable_retrieve( _environment, _source );
4788
4789 Variable * result = variable_temporary( _environment, source->type, "(result of subtracting)" );
4790
4791 switch( VT_BITWIDTH( source->type ) ) {
4792 case 32:
4793 cpu_math_add_32bit_const( _environment, source->realName, VT_ESIGN_32BIT( source->type, -_destination ), result->realName );
4794 break;
4795 case 16:
4796 cpu_math_add_16bit_const( _environment, source->realName, VT_ESIGN_16BIT( source->type, -_destination ), result->realName );
4797 break;
4798 case 8:
4799 cpu_math_add_8bit_const( _environment, source->realName, VT_ESIGN_8BIT( source->type, -_destination ), result->realName );
4800 break;
4801 case 1:
4803 break;
4804 case 0:
4805 switch( source->type ) {
4806 case VT_VECTOR2: {
4807 result = create_vector( _environment, vector_get_x( _environment, source->name )->name, vector_get_y( _environment, source->name )->name );
4808 cpu_math_add_16bit_const( _environment, result->realName, VT_SIGN_16BIT( -_destination ), result->realName );
4809 cpu_math_add_16bit_const( _environment, address_displacement( _environment, result->realName, "2" ), VT_SIGN_16BIT( -_destination ), address_displacement( _environment, result->realName, "2" ) );
4810 break;
4811 }
4812 }
4814 }
4815
4816 return result;
4817}
4818
4834void variable_sub_inplace( Environment * _environment, char * _source, char * _dest ) {
4835 Variable * source = variable_retrieve( _environment, _source );
4836 Variable * target;
4837 if ( source->type == VT_VECTOR2 ) {
4838 target = variable_cast( _environment, _dest, VT_POSITION );
4839 } else {
4840 target = variable_cast( _environment, _dest, source->type );
4841 }
4842 switch( VT_BITWIDTH( source->type ) ) {
4843 case 32:
4844 cpu_math_sub_32bit( _environment, source->realName, target->realName, source->realName );
4845 break;
4846 case 16:
4847 cpu_math_sub_16bit( _environment, source->realName, target->realName, source->realName );
4848 break;
4849 case 8:
4850 cpu_math_sub_8bit( _environment, source->realName, target->realName, source->realName );
4851 break;
4852 case 1:
4854 break;
4855 case 0:
4856 switch( source->type ) {
4857 case VT_VECTOR2:
4858 cpu_math_sub_16bit( _environment, source->realName, target->realName, source->realName );
4859 cpu_math_sub_16bit( _environment, address_displacement( _environment, source->realName, "2" ), target->realName, address_displacement( _environment, source->realName, "2" ) );
4860 break;
4861 case VT_FLOAT:
4862 switch( target->precision ) {
4863 case FT_FAST: {
4864 cpu_float_fast_sub( _environment, source->realName, target->realName, source->realName );
4865 break;
4866 }
4867 case FT_SINGLE: {
4868 cpu_float_single_sub( _environment, source->realName, target->realName, source->realName );
4869 break;
4870 }
4871 default:
4873 break;
4874 }
4875 break;
4876 case VT_NUMBER:
4877 cpu_math_sub_nbit( _environment, source->realName, target->realName, source->realName, _environment->numberConfig.maxBytes << 3 );
4878 break;
4879 default:
4881 }
4882 break;
4883 }
4884
4885}
4886
4897
4898/* <usermanual>
4899@keyword AT (instruction)
4900
4901@english
4902
4903The ''AT'' command is used to swap the values of two string variables. In practice,
4904the reference of the first variable are assigned to the second and vice versa,
4905in a single operation, and without memory movement. Infact, the ''AT''
4906command actually performs a similar operation at the machine level,
4907but more efficiently and hidden from the programmer.
4908
4909The ''AT'' command makes code more concise and readable by avoiding the use of a
4910temporary variable for swapping. Using this command is a fundamental operation
4911in many sorting algorithms with array of strings, such as bubble sort. In general,
4912swapping strings is a common operation in many programs, and ''AT'' provides a
4913simple and efficient way to do it. This command can only be used with variables of
4914the type string.
4915
4916@italian
4917
4918Il comando ''AT'' viene utilizzato per scambiare i valori di due variabili
4919stringa. In pratica, il riferimento della prima variabile viene assegnato
4920alla seconda e viceversa, in un'unica operazione e senza spostamento di memoria.
4921Infatti, il comando ''AT'' esegue effettivamente un'operazione simile a livello
4922assembly, ma in modo più efficiente e nascosto al programmatore.
4923
4924Il comando ''AT'' rende il codice più conciso e leggibile evitando l'uso
4925di una variabile temporanea per lo scambio. L'uso di questo comando è
4926un'operazione fondamentale in molti algoritmi di ordinamento con array di
4927stringhe, come il bubble sort. In generale, lo scambio di stringhe è
4928un'operazione comune in molti programmi e ''AT'' fornisce un modo semplice ed
4929efficiente per farlo. Questo comando può essere utilizzato solo con
4930variabili di tipo stringa.
4931
4932@syntax AT var1, var2
4933
4934@example a$ = "primo" : b$ = "secondo"
4935@example AT a$, b$
4936@example PRINT a$, b$
4937
4938@seeAlso SWAP
4939
4940</usermanual> */
4941/* <usermanual>
4942@keyword SWAP
4943
4944@english
4945
4946The ''SWAP'' command is used to swap the values of two variables. In practice,
4947the contents of the first variable are assigned to the second and vice versa,
4948in a single operation.
4949
4950The ''SWAP'' command makes code more concise and readable by avoiding the use
4951of a temporary variable for swapping. Since swapping elements is a fundamental
4952operation in many sorting algorithms, such as bubble sort, it is important
4953that it is an efficient operation. Infact, actually performs a similar operation
4954at the assembly level, more efficiently and hidden from the programmer.
4955
4956The ''SWAP'' operation can only be used with variables of the same
4957bit width (in case of numeric type) or the same type (if strings).
4958
4959@italian
4960
4961Il comando ''SWAP'' serve per scambiare i valori di due variabili.
4962In pratica, il contenuto della prima variabile viene assegnato alla seconda
4963e viceversa, in un'unica operazione.
4964
4965Il comando ''SWAP'' rende il codice più conciso e leggibile evitando
4966l'uso di una variabile temporanea per lo scambio. Poiché lo scambio
4967di elementi è un'operazione fondamentale in molti algoritmi di ordinamento,
4968come il bubble sort, è importante che sia un'operazione efficiente. Infatti,
4969esegue efficacemente un'operazione simile a livello di assembly, in modo più
4970efficiente e nascosto al programmatore.
4971
4972L'operazione ''SWAP'' può essere utilizzata solo con variabili della stessa
4973larghezza di bit (in caso di tipo numerico) o dello stesso tipo (in caso di stringhe).
4974
4975@syntax SWAP var1, var2
4976
4977@example a = 42 : b = 84
4978@example SWAP a, b
4979@example PRINT a, b
4980
4981@seeAlso AT
4982
4983</usermanual> */
4984void variable_swap( Environment * _environment, char * _source, char * _dest ) {
4985
4986 Variable * source = variable_retrieve( _environment, _source );
4987 Variable * target = variable_retrieve( _environment, _dest );
4988
4989 if ( source->type != target->type ) {
4991 }
4992
4993 if ( VT_BITWIDTH( source->type ) != VT_BITWIDTH( target->type ) ) {
4995 }
4996
4997 switch( VT_BITWIDTH( source->type ) ) {
4998 case 32:
4999 cpu_swap_32bit( _environment, source->realName, target->realName );
5000 break;
5001 case 16:
5002 cpu_swap_16bit( _environment, source->realName, target->realName );
5003 break;
5004 case 8:
5005 cpu_swap_8bit( _environment, source->realName, target->realName );
5006 break;
5007 case 1: {
5008 Variable * b = variable_temporary( _environment, VT_BIT, "(swap)") ;
5009 variable_move( _environment, source->name, b->name );
5010 variable_move( _environment, target->name, source->name );
5011 variable_move( _environment, b->name, target->name );
5012 break;
5013 }
5014 case 0:
5015 switch( source->type ) {
5016 case VT_DSTRING: {
5017 cpu_xor_8bit( _environment, source->realName, target->realName, source->realName );
5018 cpu_xor_8bit( _environment, source->realName, target->realName, target->realName );
5019 cpu_xor_8bit( _environment, source->realName, target->realName, source->realName );
5020 break;
5021 }
5022 case VT_FLOAT: {
5023 Variable * temp = variable_temporary( _environment, VT_FLOAT, "(temp)" );
5024 cpu_move_nbit( _environment, VT_FLOAT_BITWIDTH( source->precision ), source->realName, temp->realName );
5025 cpu_move_nbit( _environment, VT_FLOAT_BITWIDTH( source->precision ), target->realName, source->realName );
5026 cpu_move_nbit( _environment, VT_FLOAT_BITWIDTH( source->precision ), temp->realName, target->realName );
5027 break;
5028 }
5029 case VT_NUMBER: {
5030 Variable * temp = variable_temporary( _environment, VT_NUMBER, "(temp)" );
5031 cpu_move_nbit( _environment, _environment->numberConfig.maxBytes << 3, source->realName, temp->realName );
5032 cpu_move_nbit( _environment, _environment->numberConfig.maxBytes << 3, target->realName, source->realName );
5033 cpu_move_nbit( _environment, _environment->numberConfig.maxBytes << 3, temp->realName, target->realName );
5034 break;
5035 }
5036 default:
5038 }
5039 break;
5040 }
5041
5042}
5043
5060Variable * variable_complement_const( Environment * _environment, char * _source, int _value ) {
5061 Variable * source = variable_retrieve( _environment, _source );
5062 Variable * destination = variable_temporary( _environment, source->type, "(destination)" );
5063 variable_move_naked( _environment, source->name, destination->name );
5064 switch( VT_BITWIDTH( destination->type ) ) {
5065 case 32:
5066 cpu_math_complement_const_32bit( _environment, destination->realName, _value );
5067 break;
5068 case 16:
5069 cpu_math_complement_const_16bit( _environment, destination->realName, _value );
5070 break;
5071 case 8:
5072 cpu_math_complement_const_8bit( _environment, destination->realName, _value );
5073 break;
5074 case 1:
5075 case 0:
5077 }
5078 return destination;
5079}
5080
5097Variable * variable_mul( Environment * _environment, char * _source, char * _destination ) {
5098
5099 Variable * source = variable_retrieve( _environment, _source );
5100 Variable * target = variable_retrieve( _environment, _destination );
5101
5102 if ( VT_BITWIDTH(source->type) > 1 && VT_BITWIDTH(target->type) > 1 && target->initializedByConstant && ( log2(target->value) == (int)log2(target->value) ) ) {
5103 return variable_mul2_const( _environment, _source, target->value );
5104 }
5105
5106 Variable * result = NULL;
5107 if ( source->type != VT_VECTOR2 && target->type != VT_VECTOR2 ) {
5108 int best = calculate_cast_type_best_fit( _environment, source->type, target->type );
5109 source = variable_cast( _environment, source->name, best );
5110 target = variable_cast( _environment, target->name, best );
5111
5112 switch( VT_BITWIDTH( VT_MAX_BITWIDTH_TYPE( source->type, target->type ) ) ) {
5113 case 32:
5114 WARNING_BITWIDTH(_source, _destination );
5115 result = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SDWORD : VT_DWORD, "(result of multiplication)" );
5116 #ifdef CPU_BIG_ENDIAN
5117 {
5118 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "2") );
5119 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "2") );
5120 cpu_math_mul_16bit_to_32bit( _environment, sourceRealName, targetRealName, result->realName, VT_SIGNED( source->type ) );
5121 }
5122 #else
5123 cpu_math_mul_16bit_to_32bit( _environment, source->realName, target->realName, result->realName, VT_SIGNED( source->type ) );
5124 #endif
5125 break;
5126 case 16:
5127 result = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SDWORD : VT_DWORD, "(result of multiplication)" );
5128 cpu_math_mul_16bit_to_32bit( _environment, source->realName, target->realName, result->realName, VT_SIGNED( source->type ) );
5129 break;
5130 case 8:
5131 result = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(result of multiplication)" );
5132 cpu_math_mul_8bit_to_16bit( _environment, source->realName, target->realName, result->realName, VT_SIGNED( source->type ) );
5133 break;
5134 case 0:
5135 switch( source->type ) {
5136 case VT_FLOAT:
5137 result = variable_temporary( _environment, VT_FLOAT, "(result of multiplication)" );
5138 switch( target->precision ) {
5139 case FT_FAST: {
5140 cpu_float_fast_mul( _environment, source->realName, target->realName, result->realName );
5141 break;
5142 }
5143 case FT_SINGLE: {
5144 cpu_float_single_mul( _environment, source->realName, target->realName, result->realName );
5145 break;
5146 }
5147 default:
5149 break;
5150 }
5151 break;
5152 case VT_NUMBER:
5153 result = variable_temporary( _environment, VT_NUMBER, "(result of multiplication)" );
5154 cpu_math_mul_nbit_to_nbit( _environment, source->realName, target->realName, result->realName, _environment->numberConfig.maxBytes << 3 );
5155 break;
5156 default:
5158 }
5159 break;
5160 }
5161 } else {
5162 if ( source->type != VT_VECTOR2 ) {
5163 source = variable_cast( _environment, source->name, VT_POSITION );
5164 }
5165 if ( target->type != VT_VECTOR2 ) {
5166 target = variable_cast( _environment, target->name, VT_POSITION );
5167 }
5168
5169 switch( VT_BITWIDTH( source->type ) ) {
5170 case 16: {
5171 Variable * tmp = variable_temporary( _environment, VT_SDWORD, "(result of multiplication)" );
5172 Variable * posx = variable_temporary( _environment, VT_POSITION, "(result of multiplication)" );
5173 Variable * posy = variable_temporary( _environment, VT_POSITION, "(result of multiplication)" );
5174 cpu_math_mul_16bit_to_32bit( _environment, target->realName, source->realName, tmp->realName, 1 );
5175 variable_move( _environment, tmp->name, posx->name );
5176 cpu_math_mul_16bit_to_32bit( _environment, address_displacement( _environment, target->realName, "2" ), source->realName, tmp->realName, 1 );
5177 variable_move( _environment, tmp->name, posy->name );
5178 result = create_vector( _environment, posx->name, posy->name );
5179 break;
5180 }
5181 case 0:
5182 switch( target->type ) {
5183 case VT_POSITION: {
5184 Variable * tmp = variable_temporary( _environment, VT_SDWORD, "(result of multiplication)" );
5185 Variable * posx = variable_temporary( _environment, VT_POSITION, "(result of multiplication)" );
5186 Variable * posy = variable_temporary( _environment, VT_POSITION, "(result of multiplication)" );
5187 cpu_math_mul_16bit_to_32bit( _environment, source->realName, target->realName, tmp->realName, 1 );
5188 variable_move( _environment, tmp->name, posx->name );
5189 cpu_math_mul_16bit_to_32bit( _environment, address_displacement( _environment, source->realName, "2" ), target->realName, tmp->realName, 1 );
5190 variable_move( _environment, tmp->name, posy->name );
5191 result = create_vector( _environment, posx->name, posy->name );
5192 break;
5193 }
5194 default:
5195 CRITICAL_MUL_UNSUPPORTED(_destination, DATATYPE_AS_STRING[target->type]);
5196 }
5197 break;
5198 default:
5200 }
5201
5202 }
5203 return result;
5204}
5205
5214/* <usermanual>
5215@keyword DIV
5216
5217@english
5218
5219The ''DIV'' statement allows you to make a division using the dividend
5220as a variable where the result will be stored. Optionally, and only with
5221integer types, it is possible to indicate a variable where to store the
5222remainder of the division operation.
5223
5224@italian
5225
5226L'istruzione ''DIV'' consente di effettuare una divisione utilizzando il
5227dividendo come variabile dove sarà memorizzato il risultato. In opzione,
5228ma solo per i tipi interi, è possibile indicare una variabile dove
5229memorizzare il resto dell'operazione di divisione.
5230
5231@syntax DIV var, divisor[, remainder]
5232
5233@example DIV a,2
5234@example DIV a,3,q
5235
5236@usedInExample contrib_sierpinski3.bas
5237</usermanual> */
5238Variable * variable_div( Environment * _environment, char * _source, char * _destination, char * _remainder ) {
5239 Variable * source = variable_retrieve( _environment, _source );
5240 Variable * target = variable_retrieve( _environment, _destination );
5241 Variable * remainder = NULL;
5242
5243 if ( VT_BITWIDTH(source->type) > 1 && VT_BITWIDTH(target->type) > 1 && target->initializedByConstant ) {
5244 if ( log2(target->value) == (int)log2(target->value) ) {
5245 return variable_div2_const( _environment, _source, target->value, _remainder );
5246 } else {
5247 return variable_div_const( _environment, _source, target->value, _remainder );
5248 }
5249 }
5250
5251 if ( source->type == VT_FLOAT || target->type == VT_FLOAT ) {
5252 source = variable_cast( _environment, source->name, VT_FLOAT );
5253 target = variable_cast( _environment, target->name, VT_FLOAT );
5254 }
5255
5256 Variable * result = NULL;
5257 Variable * realTarget = NULL;
5258 Variable * realSource = NULL;
5259
5260 switch( VT_BITWIDTH( source->type ) ) {
5261 case 32:
5262 switch( VT_BITWIDTH( target->type ) ) {
5263 case 32:
5264 WARNING_BITWIDTH( _source, _destination );
5265 realTarget = variable_cast( _environment, target->name, VT_SIGNED( target->type ) ? VT_SWORD : VT_WORD );
5266 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SWORD : VT_WORD, "(result of division)" );
5267 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5268 cpu_math_div_32bit_to_16bit( _environment, source->realName, realTarget->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5269 break;
5270 case 16:
5271 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SWORD : VT_WORD, "(result of division)" );
5272 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5273 cpu_math_div_32bit_to_16bit( _environment, source->realName, target->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5274 break;
5275 case 8:
5276 realTarget = variable_cast( _environment, target->name, VT_SIGNED( target->type ) ? VT_SWORD : VT_WORD );
5277 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SWORD : VT_WORD, "(result of division)" );
5278 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5279 cpu_math_div_32bit_to_16bit( _environment, source->realName, realTarget->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5280 break;
5281 case 1:
5282 case 0:
5284 break;
5285 }
5286 break;
5287 case 16:
5288 switch( VT_BITWIDTH( target->type ) ) {
5289 case 32:
5290 realSource = variable_cast( _environment, source->name, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD );
5291 realTarget = variable_cast( _environment, target->name, VT_SIGNED( target->type ) ? VT_SWORD : VT_WORD );
5292 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SWORD : VT_WORD, "(result of division)" );
5293 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5294 cpu_math_div_16bit_to_16bit( _environment, realSource->realName, realTarget->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5295 break;
5296 case 16:
5297 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SWORD : VT_WORD, "(result of division)" );
5298 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5299 cpu_math_div_16bit_to_16bit( _environment, source->realName, target->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5300 break;
5301 case 8:
5302 realSource = variable_cast( _environment, source->name, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD );
5303 realTarget = variable_cast( _environment, target->name, VT_SIGNED( target->type ) ? VT_SWORD : VT_WORD );
5304 result = variable_temporary( _environment, ( VT_SIGNED( realSource->type ) || VT_SIGNED( realTarget->type ) ) ? VT_SWORD : VT_WORD, "(result of division)" );
5305 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5306 cpu_math_div_16bit_to_16bit( _environment, realSource->realName, realTarget->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5307 break;
5308 case 1:
5309 case 0:
5311 break;
5312 }
5313 break;
5314 case 8:
5315 switch( VT_BITWIDTH( target->type ) ) {
5316 case 32:
5317 realTarget = variable_cast( _environment, target->name, VT_SIGNED( target->type ) ? VT_SBYTE : VT_BYTE );
5318 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SBYTE : VT_BYTE, "(result of division)" );
5319 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5320 cpu_math_div_8bit_to_8bit( _environment, source->realName, realTarget->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5321 break;
5322 case 16:
5323 realTarget = variable_cast( _environment, target->name, VT_SIGNED( target->type ) ? VT_SBYTE : VT_BYTE );
5324 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SBYTE : VT_BYTE, "(result of division)" );
5325 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5326 cpu_math_div_8bit_to_8bit( _environment, source->realName, realTarget->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5327 break;
5328 case 8:
5329 result = variable_temporary( _environment, ( VT_SIGNED( source->type ) || VT_SIGNED( target->type ) ) ? VT_SBYTE : VT_BYTE, "(result of division)" );
5330 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SBYTE : VT_BYTE, "(remainder of division)" );
5331 cpu_math_div_8bit_to_8bit( _environment, source->realName, target->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5332 break;
5333 case 1:
5334 case 0:
5336 break;
5337 }
5338 break;
5339 case 1:
5341 case 0:
5342 switch( target->type ) {
5343 case VT_FLOAT:
5344
5345 if ( _remainder ) {
5346 remainder = variable_retrieve( _environment, _remainder );
5347 CRITICAL_DIV_UNSUPPORTED(_remainder, DATATYPE_AS_STRING[remainder->type]);
5348 }
5349
5350 result = variable_temporary( _environment, VT_FLOAT, "(result of division)" );
5351
5352 switch( target->precision ) {
5353 case FT_FAST: {
5354 cpu_float_fast_div( _environment, source->realName, target->realName, result->realName );
5355 break;
5356 }
5357 case FT_SINGLE: {
5358 cpu_float_single_div( _environment, source->realName, target->realName, result->realName );
5359 break;
5360 }
5361 default:
5363 break;
5364 }
5365 break;
5366 case VT_NUMBER:
5367 realTarget = variable_cast( _environment, target->name, VT_NUMBER );
5368 result = variable_temporary( _environment, VT_NUMBER, "(result of division)" );
5369 remainder = variable_temporary( _environment, VT_NUMBER, "(remainder of division)" );
5370 cpu_math_div_nbit_to_nbit( _environment, source->realName, realTarget->realName, result->realName, remainder->realName, _environment->numberConfig.maxBytes << 3 );
5371 break;
5372 default:
5374 }
5375 break;
5376 }
5377
5378 if ( _remainder ) {
5379 variable_move( _environment, remainder->name, _remainder );
5380 }
5381
5382 return result;
5383}
5384
5385Variable * variable_div_const( Environment * _environment, char * _source, int _destination, char * _remainder ) {
5386
5387 Variable * source = variable_retrieve( _environment, _source );
5388
5389 Variable * result = NULL;
5390 Variable * remainder = NULL;
5391 Variable * realTarget = NULL;
5392 Variable * realSource = NULL;
5393
5394 switch( VT_BITWIDTH( source->type ) ) {
5395 case 32:
5396 result = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(result of division)" );
5397 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5398 cpu_math_div_32bit_to_16bit_const( _environment, source->realName, _destination, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5399 break;
5400 case 16:
5401 result = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(result of division)" );
5402 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SWORD : VT_WORD, "(remainder of division)" );
5403 cpu_math_div_16bit_to_16bit_const( _environment, source->realName, _destination, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5404 break;
5405 case 8:
5406 result = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SBYTE : VT_BYTE, "(result of division)" );
5407 remainder = variable_temporary( _environment, VT_SIGNED( source->type ) ? VT_SBYTE : VT_BYTE, "(remainder of division)" );
5408 cpu_math_div_8bit_to_8bit_const( _environment, source->realName, _destination, result->realName, remainder->realName, VT_SIGNED( source->type ) );
5409 break;
5410 case 1:
5412 case 0:
5413 switch( source->type ) {
5414 case VT_FLOAT:
5415 result = variable_temporary( _environment, VT_FLOAT, "(result of division)" );
5416 Variable * target = variable_temporary( _environment, VT_FLOAT, "(target)" );
5417 variable_store_float( _environment, target->name, _destination );
5418 switch( target->precision ) {
5419 case FT_FAST: {
5420 cpu_float_fast_div( _environment, source->realName, target->realName, result->realName );
5421 break;
5422 }
5423 case FT_SINGLE: {
5424 cpu_float_single_div( _environment, source->realName, target->realName, result->realName );
5425 break;
5426 }
5427 default:
5429 break;
5430 }
5431 break;
5432 case VT_NUMBER:
5433 result = variable_temporary( _environment, VT_NUMBER, "(result of division)" );
5434 remainder = variable_temporary( _environment, VT_NUMBER, "(remainder of division)" );
5435 cpu_math_div_nbit_to_nbit_const( _environment, source->realName, _destination, result->realName, remainder->realName, _environment->numberConfig.maxBytes << 3 );
5436 break;
5437 default:
5439 }
5440 break;
5441 }
5442
5443 if ( _remainder ) {
5444 variable_move( _environment, remainder->name, _remainder );
5445 }
5446
5447 return result;
5448}
5449
5457/* <usermanual>
5458@keyword INC
5459
5460@english
5461
5462The ''INC'' command is used to increment (i.e. increase) the value
5463of a numeric variable by one. It is a quick and concise way to add
54641 from the value contained in a variable. In place of ''variable'', enter the
5465name of the numeric variable you want to increment.
5466
5467The ''INC'' command is actually a shorthand for the adding operation, as
5468writing ''num=num+1''. However, ''DEC'' is often preferred because of its
5469more concise syntax and its specific increment function. The ''INC'' command
5470can only be applied to numeric variables (integer).
5471
5472@italian
5473
5474Il comando ''INC'' viene utilizzato per incrementare (ovvero aumentare) il valore
5475di una variabile numerica di uno. È un modo rapido e conciso per aggiungere 1
5476al valore contenuto in una variabile. Invece di ''variabile'', inserisci il nome
5477della variabile numerica che vuoi incrementare.
5478
5479Il comando ''INC'' è in realtà una scorciatoia per l'operazione di addizione,
5480come scrivere ''num=num+1''. Tuttavia, ''DEC'' è spesso preferito per la sua
5481sintassi più concisa e la sua specifica funzione di incremento. Il comando ''INC''
5482può essere applicato solo a variabili numeriche (intere).
5483
5484@syntax INC var
5485
5486@example INC score
5487
5488@usedInExample contrib_sierpinski3.bas
5489
5490@seeAlso DEC
5491
5492@target all
5493</usermanual> */
5494void variable_increment( Environment * _environment, char * _source ) {
5495
5496 if ( _environment->emptyProcedure ) {
5497 return;
5498 }
5499
5500 Variable * source = variable_retrieve( _environment, _source );
5501
5502 switch( VT_BITWIDTH( source->type ) ) {
5503 case 0:
5504 switch( source->type ) {
5505 case VT_NUMBER:
5506 cpu_inc_nbit( _environment, source->realName, _environment->numberConfig.maxBytes << 3 );
5507 default:
5509 }
5510 case 32:
5511 case 1:
5513 break;
5514 case 16:
5515 cpu_inc_16bit( _environment, source->realName );
5516 break;
5517 case 8:
5518 cpu_inc( _environment, source->realName );
5519 break;
5520 }
5521 return;
5522}
5523
5524void variable_increment_type( Environment * _environment, char * _source, char * _field ) {
5525
5526 if ( _environment->emptyProcedure ) {
5527 return;
5528 }
5529
5530 Variable * source = variable_retrieve( _environment, _source );
5531
5532 if ( source->type != VT_TYPE ) {
5534 }
5535 Field * field = field_find( source->typeType, _field );
5536 if ( ! field ) {
5538 }
5539
5540 char offsetAsString[MAX_TEMPORARY_STORAGE];
5541 sprintf( offsetAsString, "%d", field->offset );
5542 switch( VT_BITWIDTH( field->type ) ) {
5543 case 32:
5544 case 1:
5545 case 0:
5547 break;
5548 case 16:
5549 cpu_inc_16bit( _environment, address_displacement( _environment, source->realName, offsetAsString ) );
5550 break;
5551 case 8:
5552 cpu_inc( _environment, address_displacement( _environment, source->realName, offsetAsString ) );
5553 break;
5554 }
5555 return;
5556}
5557
5565static void variable_increment_decrement_array( Environment * _environment, char * _source, int _direction ) {
5566
5567 if ( _environment->emptyProcedure ) {
5568 return;
5569 }
5570
5571 Variable * source = variable_retrieve( _environment, _source );
5572 Variable * offset = variable_move_from_array_get_address( _environment, _source, NULL );
5573
5574 Variable * value = NULL;
5575
5576 if ( source->bankAssigned == -1 ) {
5577
5578 value = variable_temporary( _environment, source->arrayType, "(temp)" );
5579
5580 switch( VT_BITWIDTH( value->type ) ) {
5581 case 32:
5582 cpu_move_32bit_indirect2( _environment, offset->realName, value->realName );
5583 break;
5584 case 16:
5585 cpu_move_16bit_indirect2( _environment, offset->realName, value->realName);
5586 break;
5587 case 8:
5588 cpu_move_8bit_indirect2( _environment, offset->realName, value->realName );
5589 break;
5590 case 1:
5592 case 0:
5594
5595 }
5596
5597 } else {
5598
5599 value = source;
5600 value->type = source->arrayType;
5601
5602 switch( VT_BITWIDTH( value->type ) ) {
5603 case 32:
5604 bank_read_vars_bank_direct_size( _environment, source->bankAssigned, offset->name, value->name, 4 );
5605 break;
5606 case 16:
5607 bank_read_vars_bank_direct_size( _environment, source->bankAssigned, offset->name, value->name, 2 );
5608 break;
5609 case 8:
5610 bank_read_vars_bank_direct_size( _environment, source->bankAssigned, offset->name, value->name, 1 );
5611 break;
5612 case 0:
5613 case 1:
5615 }
5616
5617 }
5618
5619 if ( _direction > 0 ) {
5620 variable_increment( _environment, value->name );
5621 } else if ( _direction < 0 ) {
5622 variable_decrement( _environment, value->name );
5623 }
5624
5625 if ( source->bankAssigned == -1 ) {
5626
5627 switch( VT_BITWIDTH( value->type ) ) {
5628 case 32:
5629 cpu_move_32bit_indirect( _environment, value->realName, offset->realName );
5630 break;
5631 case 16:
5632 cpu_move_16bit_indirect( _environment, value->realName, offset->realName );
5633 break;
5634 case 8:
5635 cpu_move_8bit_indirect( _environment, value->realName, offset->realName );
5636 break;
5637 case 1:
5638 case 0:
5640 }
5641
5642 } else {
5643
5644 switch( VT_BITWIDTH( value->type ) ) {
5645 case 32:
5646 bank_write_vars_bank_direct_size( _environment, value->name, source->bankAssigned, offset->name, 4 );
5647 break;
5648 case 16:
5649 bank_write_vars_bank_direct_size( _environment, value->name, source->bankAssigned, offset->name, 2 );
5650 break;
5651 case 8:
5652 bank_write_vars_bank_direct_size( _environment, value->name, source->bankAssigned, offset->name, 1 );
5653 break;
5654 case 1:
5655 case 0:
5657 }
5658
5659 value->type = VT_TARRAY;
5660
5661 }
5662
5663 return;
5664
5665}
5666
5674// @bit2: ok
5675void variable_store_mt( Environment * _environment, char * _source, unsigned int _value ) {
5676
5677 parser_array_init( _environment );
5678 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
5679 Variable * array = variable_retrieve( _environment, _source );
5680 if ( array->type != VT_TARRAY ) {
5681 CRITICAL_NOT_ARRAY( _source );
5682 }
5683 variable_store_array_const( _environment, array->name, _value );
5684 parser_array_cleanup( _environment );
5685
5686}
5687
5695// @bit2: ok
5696Variable * variable_move_from_mt( Environment * _environment, char * _source, char * _destination ) {
5697
5698 parser_array_init( _environment );
5699 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
5700 Variable * array = variable_retrieve( _environment, _source );
5701 if ( array->type != VT_TARRAY ) {
5702 CRITICAL_NOT_ARRAY( _source );
5703 }
5704 Variable * value = variable_move_from_array( _environment, array->name );
5705 parser_array_cleanup( _environment );
5706
5707 Variable * destination = variable_retrieve( _environment, _destination );
5708
5709 variable_move( _environment, value->name, destination->name );
5710
5711 return destination;
5712
5713}
5714
5715// @bit2: ok
5716Variable * variable_move_to_mt( Environment * _environment, char * _source, char * _destination ) {
5717
5718 Variable * source = variable_retrieve( _environment, _source );
5719
5720 parser_array_init( _environment );
5721 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
5722 Variable * array = variable_retrieve( _environment, _destination );
5723 if ( array->type != VT_TARRAY ) {
5724 CRITICAL_NOT_ARRAY( _destination );
5725 }
5726 variable_move_array( _environment, array->name, source->name );
5727 parser_array_cleanup( _environment );
5728
5729 return source;
5730
5731}
5732
5740void variable_increment_mt( Environment * _environment, char * _source ) {
5741
5742 if ( _environment->emptyProcedure ) {
5743 return;
5744 }
5745
5746 parser_array_init( _environment );
5747 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
5748 Variable * array = variable_retrieve( _environment, _source );
5749 if ( array->type != VT_TARRAY ) {
5750 CRITICAL_NOT_ARRAY( _source );
5751 }
5752 Variable * value = variable_move_from_array( _environment, array->name );
5753 parser_array_cleanup( _environment );
5754
5755 variable_increment( _environment, value->name );
5756
5757 parser_array_init( _environment );
5758 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
5759 array = variable_retrieve( _environment, _source );
5760 if ( array->type != VT_TARRAY ) {
5761 CRITICAL_NOT_ARRAY( _source );
5762 }
5763 variable_move_array( _environment, array->name, value->name );
5764 parser_array_cleanup( _environment );
5765
5766 return;
5767
5768}
5769
5777
5778/* <usermanual>
5779@keyword DEC
5780
5781@english
5782
5783The ''DEC'' command is used to decrement (i.e. decrease) the value
5784of a numeric variable by one. It is a quick and concise way to subtract
57851 from the value contained in a variable. In place of ''variable'', enter the
5786name of the numeric variable you want to decrement.
5787
5788The ''DEC'' command is actually a shorthand for the subtraction operation, as
5789writing ''num=num-1''. However, ''DEC'' is often preferred because of its
5790more concise syntax and its specific decrement function. The ''DEC'' command
5791can only be applied to numeric variables (integer).
5792
5793@italian
5794
5795Il comando ''DEC'' viene utilizzato per decrementare (cioè diminuire) il
5796valore di una variabile numerica di uno. È un modo rapido e conciso per
5797sottrarre 1 dal valore contenuto in una variabile. Al posto di ''variabile'',
5798inserisci il nome della variabile numerica che vuoi decrementare.
5799
5800Il comando ''DEC'' è in realtà una scorciatoia per l'operazione di sottrazione,
5801come scrivere ''num=num-1''. Tuttavia, ''DEC'' è spesso preferito per la sua
5802sintassi più concisa e la sua specifica funzione di decremento. Il comando
5803''DEC'' può essere applicato solo a variabili numeriche (intere).
5804
5805@syntax DEC variable
5806
5807@example x = 43
5808@example DEC x
5809@example PRINT x: ' It prints "42"
5810
5811@seeAlso INC
5812
5813</usermanual> */
5814void variable_decrement( Environment * _environment, char * _source ) {
5815
5816 if ( _environment->emptyProcedure ) {
5817 return;
5818 }
5819
5820 Variable * source = variable_retrieve( _environment, _source );
5821
5822 switch( VT_BITWIDTH( source->type ) ) {
5823 case 0:
5824 switch( source->type ) {
5825 case VT_NUMBER:
5826 cpu_dec_nbit( _environment, source->realName, _environment->numberConfig.maxBytes << 3 );
5827 default:
5829 }
5830 case 1:
5832 break;
5833 case 32:
5834 cpu_dec_32bit( _environment, source->realName );
5835 break;
5836 case 16:
5837 cpu_dec_16bit( _environment, source->realName );
5838 break;
5839 case 8:
5840 cpu_dec( _environment, source->realName );
5841 break;
5842 }
5843 return;
5844}
5845
5846void variable_decrement_type( Environment * _environment, char * _source, char * _field ) {
5847
5848 if ( _environment->emptyProcedure ) {
5849 return;
5850 }
5851
5852 Variable * source = variable_retrieve( _environment, _source );
5853
5854 if ( source->type != VT_TYPE ) {
5856 }
5857 Field * field = field_find( source->typeType, _field );
5858 if ( ! field ) {
5860 }
5861
5862 char offsetAsString[MAX_TEMPORARY_STORAGE];
5863 sprintf( offsetAsString, "%d", field->offset );
5864
5865 switch( VT_BITWIDTH( field->type ) ) {
5866 case 1:
5867 case 0:
5869 break;
5870 case 32:
5871 cpu_dec_32bit( _environment, address_displacement( _environment, source->realName, offsetAsString ) );
5872 break;
5873 case 16:
5874 cpu_dec_16bit( _environment, address_displacement( _environment, source->realName, offsetAsString ) );
5875 break;
5876 case 8:
5877 cpu_dec( _environment, address_displacement( _environment, source->realName, offsetAsString ) );
5878 break;
5879 }
5880 return;
5881}
5882
5890void variable_decrement_mt( Environment * _environment, char * _source ) {
5891
5892 if ( _environment->emptyProcedure ) {
5893 return;
5894 }
5895
5896 parser_array_init( _environment );
5897 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
5898 Variable * array = variable_retrieve( _environment, _source );
5899 if ( array->type != VT_TARRAY ) {
5900 CRITICAL_NOT_ARRAY( _source );
5901 }
5902 Variable * value = variable_move_from_array( _environment, array->name );
5903 parser_array_cleanup( _environment );
5904
5905 variable_decrement( _environment, value->name );
5906
5907 parser_array_init( _environment );
5908 parser_array_index_symbolic( _environment, "PROTOTHREADCT" );
5909 array = variable_retrieve( _environment, _source );
5910 if ( array->type != VT_TARRAY ) {
5911 CRITICAL_NOT_ARRAY( _source );
5912 }
5913 variable_move_array( _environment, array->name, value->name );
5914 parser_array_cleanup( _environment );
5915
5916 return;
5917
5918}
5919
5920void variable_compare_and_branch_const( Environment * _environment, char *_source, int _destination, char *_name, int _positive ) {
5921
5922 Variable * source = variable_retrieve( _environment, _source );
5923
5925
5926 switch( VT_BITWIDTH( source->type ) ) {
5927 case 32:
5928 cpu_compare_and_branch_32bit_const( _environment, source->realName, _destination, _name, _positive );
5929 break;
5930 case 16:
5931 cpu_compare_and_branch_16bit_const( _environment, source->realName, _destination, _name, _positive );
5932 break;
5933 case 8:
5934 cpu_compare_and_branch_8bit_const( _environment, source->realName, _destination, _name, _positive );
5935 break;
5936 case 1: {
5937 Variable * bcheck = variable_temporary( _environment, VT_BYTE, "(bcheck)" );
5938 if ( _positive ) {
5939 if ( _destination ) {
5940 cpu_bit_check( _environment, source->realName, source->bitPosition, bcheck->realName, 8 );
5941 cpu_compare_and_branch_8bit_const( _environment, bcheck->realName, 0xff, _name, 1 );
5942 } else {
5943 cpu_bit_check( _environment, source->realName, source->bitPosition, bcheck->realName, 8 );
5944 cpu_compare_and_branch_8bit_const( _environment, bcheck->realName, 0, _name, 1 );
5945 }
5946 } else {
5947 if ( _destination ) {
5948 cpu_bit_check( _environment, source->realName, source->bitPosition, bcheck->realName, 8 );
5949 cpu_compare_and_branch_8bit_const( _environment, bcheck->realName, 0, _name, 1 );
5950 } else {
5951 cpu_bit_check( _environment, source->realName, source->bitPosition, bcheck->realName, 8 );
5952 cpu_compare_and_branch_8bit_const( _environment, bcheck->realName, 0xff, _name, 1 );
5953 }
5954 }
5955 break;
5956 }
5957 case 0:
5959 }
5960
5961}
5962
5979Variable * variable_compare( Environment * _environment, char * _source, char * _destination ) {
5980
5981 Variable * source = variable_retrieve( _environment, _source );
5982 Variable * target = variable_retrieve( _environment, _destination );
5983
5984 if ( VT_SIGNED( source->type ) != VT_SIGNED( target->type ) ) {
5985 source = variable_cast( _environment, _source, VT_SIGN( source->type ) );
5986 target = variable_cast( _environment, _destination, VT_SIGN( target->type ) );
5987 }
5988
5990
5991 Variable * result = variable_temporary( _environment, VT_SBYTE, "(result of compare)" );
5992 switch( VT_BITWIDTH( source->type ) ) {
5993 case 32:
5994 switch( VT_BITWIDTH( target->type ) ) {
5995 case 32:
5996 cpu_compare_32bit( _environment, source->realName, target->realName, result->realName, 1 );
5997 break;
5998 case 16:
5999 WARNING_BITWIDTH( _source, _destination );
6000 #ifdef CPU_BIG_ENDIAN
6001 {
6002 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "2") );
6003 cpu_compare_16bit( _environment, sourceRealName, target->realName, result->realName, 1 );
6004 }
6005 #else
6006 cpu_compare_16bit( _environment, source->realName, target->realName, result->realName, 1 );
6007 #endif
6008 break;
6009 case 8:
6010 WARNING_BITWIDTH( _source, _destination );
6011 #ifdef CPU_BIG_ENDIAN
6012 {
6013 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "3") );
6014 cpu_compare_8bit( _environment, sourceRealName, target->realName, result->realName, 1 );
6015 }
6016 #else
6017 cpu_compare_8bit( _environment, source->realName, target->realName, result->realName, 1 );
6018 #endif
6019 break;
6020 case 1: {
6021 WARNING_BITWIDTH( _source, _destination );
6022 Variable * converted = variable_temporary( _environment, VT_BYTE, "(byte)" );
6023 variable_move_1bit_8bit( _environment, target, converted );
6024 #ifdef CPU_BIG_ENDIAN
6025 {
6026 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "3") );
6027 cpu_compare_8bit( _environment, sourceRealName, converted->realName, result->realName, 1 );
6028 }
6029 #else
6030 cpu_compare_8bit( _environment, source->realName, converted->realName, result->realName, 1 );
6031 #endif
6032 break;
6033 }
6034 case 0:
6035 switch( target->type ) {
6036 // 32 bit <-> FLOAT
6037 case VT_FLOAT: {
6038 Variable * floatToInteger = variable_temporary( _environment, VT_SDWORD, "(floatToInteger)" );
6039 variable_move( _environment, target->name, floatToInteger->name );
6040 return variable_compare( _environment, source->name, floatToInteger->name );
6041 }
6042 break;
6043 case VT_NUMBER: {
6044 #ifdef CPU_BIG_ENDIAN
6045 {
6046 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 4 );
6047 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, offsetAsString) );
6048 cpu_compare_32bit( _environment, sourceRealName, target->realName, result->realName, 1 );
6049 }
6050 #else
6051 cpu_compare_32bit( _environment, source->realName, target->realName, result->realName, 1 );
6052 #endif
6053 break;
6054 }
6055 default:
6057 }
6058 break;
6059 }
6060 break;
6061 case 16:
6062 switch( VT_BITWIDTH( target->type ) ) {
6063 case 32:
6064 WARNING_BITWIDTH( _source, _destination );
6065 #ifdef CPU_BIG_ENDIAN
6066 {
6067 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "2") );
6068 cpu_compare_16bit( _environment, source->realName, targetRealName, result->realName, 1 );
6069 }
6070 #else
6071 cpu_compare_16bit( _environment, source->realName, target->realName, result->realName, 1 );
6072 #endif
6073 break;
6074 case 16:
6075 cpu_compare_16bit( _environment, source->realName, target->realName, result->realName, 1 );
6076 break;
6077 case 8:
6078 WARNING_BITWIDTH( _source, _destination );
6079 #ifdef CPU_BIG_ENDIAN
6080 {
6081 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "1") );
6082 cpu_compare_8bit( _environment, sourceRealName, target->realName, result->realName, 1 );
6083 }
6084 #else
6085 cpu_compare_8bit( _environment, source->realName, target->realName, result->realName, 1 );
6086 #endif
6087 break;
6088 case 1: {
6089 WARNING_BITWIDTH( _source, _destination );
6090 Variable * converted = variable_temporary( _environment, VT_BYTE, "(byte)" );
6091 variable_move_1bit_8bit( _environment, target, converted );
6092 #ifdef CPU_BIG_ENDIAN
6093 {
6094 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "1") );
6095 cpu_compare_8bit( _environment, sourceRealName, target->realName, result->realName, 1 );
6096 }
6097 #else
6098 cpu_compare_8bit( _environment, source->realName, target->realName, result->realName, 1 );
6099 #endif
6100 break;
6101 }
6102 case 0:
6103 switch( target->type ) {
6104 // 16 bit <-> FLOAT
6105 case VT_FLOAT: {
6106 Variable * floatToInteger = variable_temporary( _environment, VT_SWORD, "(floatToInteger)" );
6107 variable_move( _environment, target->name, floatToInteger->name );
6108 return variable_compare( _environment, source->name, floatToInteger->name );
6109 }
6110 break;
6111 case VT_NUMBER: {
6112 #ifdef CPU_BIG_ENDIAN
6113 {
6114 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 2 );
6115 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, offsetAsString) );
6116 cpu_compare_16bit( _environment, sourceRealName, target->realName, result->realName, 1 );
6117 }
6118 #else
6119 cpu_compare_16bit( _environment, source->realName, target->realName, result->realName, 1 );
6120 #endif
6121 break;
6122 }
6123 default:
6125 }
6126 break;
6127 }
6128 break;
6129 case 8:
6130 switch( VT_BITWIDTH( target->type ) ) {
6131 case 32:
6132 WARNING_BITWIDTH( _source, _destination );
6133 #ifdef CPU_BIG_ENDIAN
6134 {
6135 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "3") );
6136 cpu_compare_8bit( _environment, source->realName, targetRealName, result->realName, 1 );
6137 }
6138 #else
6139 cpu_compare_8bit( _environment, source->realName, target->realName, result->realName, 1 );
6140 #endif
6141 break;
6142 case 16:
6143 WARNING_BITWIDTH( _source, _destination );
6144 #ifdef CPU_BIG_ENDIAN
6145 {
6146 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "1") );
6147 cpu_compare_8bit( _environment, source->realName, targetRealName, result->realName, 1 );
6148 }
6149 #else
6150 cpu_compare_8bit( _environment, source->realName, target->realName, result->realName, 1 );
6151 #endif
6152 break;
6153 case 8:
6154 cpu_compare_8bit( _environment, source->realName, target->realName, result->realName, 1 );
6155 break;
6156 case 1: {
6157 WARNING_BITWIDTH( _source, _destination );
6158 Variable * converted = variable_temporary( _environment, VT_BYTE, "(byte)" );
6159 variable_move_1bit_8bit( _environment, target, converted );
6160 cpu_compare_8bit( _environment, source->realName, converted->realName, result->realName, 1 );
6161 break;
6162 }
6163 case 0:
6164 switch( target->type ) {
6165 // 8 bit <-> FLOAT
6166 case VT_FLOAT: {
6167 Variable * floatToInteger = variable_temporary( _environment, VT_SBYTE, "(floatToInteger)" );
6168 variable_move( _environment, target->name, floatToInteger->name );
6169 return variable_compare( _environment, source->name, floatToInteger->name );
6170 }
6171 break;
6172 case VT_NUMBER: {
6173 #ifdef CPU_BIG_ENDIAN
6174 {
6175 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 1 );
6176 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, offsetAsString) );
6177 cpu_compare_8bit( _environment, sourceRealName, target->realName, result->realName, 1 );
6178 }
6179 #else
6180 cpu_compare_8bit( _environment, source->realName, target->realName, result->realName, 1 );
6181 #endif
6182 break;
6183 }
6184 default:
6186 }
6187 break;
6188 }
6189 break;
6190 case 1: {
6191 Variable * converted = variable_temporary( _environment, VT_BYTE, "(byte)" );
6192 variable_move_1bit_8bit( _environment, source, converted );
6193 switch( VT_BITWIDTH( target->type ) ) {
6194 case 32:
6195 WARNING_BITWIDTH( _source, _destination );
6196 #ifdef CPU_BIG_ENDIAN
6197 {
6198 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "3") );
6199 cpu_compare_8bit( _environment, converted->realName, targetRealName, result->realName, 1 );
6200 }
6201 #else
6202 cpu_compare_8bit( _environment, converted->realName, target->realName, result->realName, 1 );
6203 #endif
6204 break;
6205 case 16:
6206 WARNING_BITWIDTH( _source, _destination );
6207 #ifdef CPU_BIG_ENDIAN
6208 {
6209 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "1") );
6210 cpu_compare_8bit( _environment, converted->realName, targetRealName, result->realName, 1 );
6211 }
6212 #else
6213 cpu_compare_8bit( _environment, converted->realName, target->realName, result->realName, 1 );
6214 #endif
6215 break;
6216 case 8:
6217 cpu_compare_8bit( _environment, converted->realName, target->realName, result->realName, 1 );
6218 break;
6219 case 1: {
6220 WARNING_BITWIDTH( _source, _destination );
6221 Variable * converted2 = variable_temporary( _environment, VT_BYTE, "(byte)" );
6222 variable_move_1bit_8bit( _environment, target, converted2 );
6223 cpu_compare_8bit( _environment, converted->realName, converted2->realName, result->realName, 1 );
6224 break;
6225 }
6226 case 0:
6228 }
6229 break;
6230 }
6231 case 0:
6232 switch( source->type ) {
6233 case VT_STRING:
6234 switch( target->type ) {
6235 case VT_STRING: {
6236 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%s", label );
6237 cpu_store_8bit( _environment, result->realName, 0 );
6238 cpu_compare_and_branch_8bit( _environment, source->realName, target->realName, differentLabel, 0 );
6239 cpu_store_8bit( _environment, result->realName, 0xff );
6240 cpu_compare_and_branch_8bit_const( _environment, source->realName, 0, differentLabel, 1 );
6241 cpu_compare_memory( _environment, source->realName, target->realName, source->realName, result->realName, 1 );
6242 cpu_label( _environment, differentLabel );
6243 break;
6244 }
6245 case VT_DSTRING: {
6246 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%s", label );
6247 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
6248 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
6249 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
6250 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
6251 cpu_move_8bit( _environment, source->realName, size->realName );
6252 cpu_dsdescriptor( _environment, target->realName, address2->realName, size2->realName );
6253 cpu_store_8bit( _environment, result->realName, 0 );
6254 cpu_compare_and_branch_8bit( _environment, size->realName, size2->realName, differentLabel, 0 );
6255 cpu_compare_and_branch_8bit_const( _environment, size->realName, 0, differentLabel, 1 );
6256 cpu_store_8bit( _environment, result->realName, 0xff );
6257 cpu_compare_8bit( _environment, size->realName, size2->realName, result->realName, 1 );
6258 cpu_addressof_16bit( _environment, source->realName, address->realName );
6259 cpu_inc_16bit( _environment, address->realName );
6260 cpu_compare_memory( _environment, address->realName, address2->realName, size->realName, result->realName, 1 );
6261 cpu_label( _environment, differentLabel );
6262 break;
6263 }
6264 case VT_IMAGE:
6265 case VT_IMAGES:
6266 case VT_SEQUENCE:
6267 case VT_MUSIC:
6268 case VT_TYPE:
6269 case VT_BUFFER:
6270 default:
6272 break;
6273 }
6274 break;
6275 case VT_DSTRING:
6276 switch( target->type ) {
6277 case VT_STRING: {
6278 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%s", label );
6279 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
6280 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
6281 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
6282 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
6283 cpu_move_8bit( _environment, target->realName, size2->realName );
6284 cpu_dsdescriptor( _environment, source->realName, address->realName, size->realName );
6285 cpu_store_8bit( _environment, result->realName, 0 );
6286 cpu_compare_and_branch_8bit( _environment, size->realName, size2->realName, differentLabel, 0 );
6287 cpu_store_8bit( _environment, result->realName, 0xff );
6288 cpu_compare_and_branch_8bit_const( _environment, size->realName, 0, differentLabel, 1 );
6289 cpu_addressof_16bit( _environment, target->realName, address2->realName );
6290 cpu_inc_16bit( _environment, address2->realName );
6291 cpu_compare_memory( _environment, address->realName, address2->realName, size->realName, result->realName, 1 );
6292 cpu_label( _environment, differentLabel );
6293 break;
6294 }
6295 case VT_DSTRING: {
6296 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%s", label );
6297 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
6298 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
6299 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
6300 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
6301 cpu_dsdescriptor( _environment, source->realName, address->realName, size->realName );
6302 cpu_dsdescriptor( _environment, target->realName, address2->realName, size2->realName );
6303 cpu_store_8bit( _environment, result->realName, 0 );
6304 cpu_compare_and_branch_8bit( _environment, size->realName, size2->realName, differentLabel, 0 );
6305 cpu_store_8bit( _environment, result->realName, 0xff );
6306 cpu_compare_and_branch_8bit_const( _environment, size->realName, 0, differentLabel, 1 );
6307 cpu_compare_memory( _environment, address->realName, address2->realName, size->realName, result->realName, 1 );
6308 cpu_label( _environment, differentLabel );
6309 break;
6310 }
6311 default:
6313 break;
6314 }
6315 break;
6316 case VT_MUSIC:
6317 if ( source->sidFile ) {
6319 }
6320 case VT_NUMBER:
6321 switch( target->type ) {
6322 case VT_NUMBER:
6323 cpu_compare_memory_size( _environment, source->realName, target->realName, _environment->numberConfig.maxBytes, result->realName, 1 );
6324 break;
6325 default:
6327 break;
6328 }
6329 break;
6330 case VT_IMAGE:
6331 case VT_IMAGES:
6332 case VT_SEQUENCE:
6333 case VT_TYPE:
6334 case VT_BUFFER:
6335 switch( target->type ) {
6336 case VT_MUSIC:
6337 if ( target->sidFile ) {
6339 }
6340 case VT_BUFFER:
6341 case VT_IMAGE:
6342 case VT_IMAGES:
6343 case VT_TYPE:
6344 case VT_SEQUENCE:
6345 cpu_compare_memory_size( _environment, source->realName, target->realName, source->size, result->realName, 1 );
6346 break;
6347 default:
6348 case VT_DSTRING:
6349 case VT_STRING:
6351 break;
6352 }
6353 break;
6354 case VT_FLOAT:
6355 switch( source->type ) {
6356 case VT_FLOAT: {
6358 if ( source->precision != target->precision ) {
6360 }
6361 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf( differentLabel, "%sdifferent", label );
6362 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneLabel, "%sdone", label );
6363 switch( source->precision ) {
6364 case FT_FAST:
6365 cpu_float_fast_cmp( _environment, source->realName, target->realName, result->realName );
6366 break;
6367 case FT_SINGLE:
6368 cpu_float_single_cmp( _environment, source->realName, target->realName, result->realName );
6369 break;
6370 default:
6372 }
6373 cpu_compare_and_branch_8bit_const( _environment, result->realName, 0, differentLabel, 0 );
6374 cpu_store_8bit( _environment, result->realName, 255 );
6375 cpu_jump( _environment, doneLabel );
6376 cpu_label( _environment, differentLabel );
6377 cpu_store_8bit( _environment, result->realName, 0 );
6378 cpu_label( _environment, doneLabel );
6379 break;
6380 }
6381 default:
6383 }
6384 break;
6385 default:
6387 }
6388 break;
6389 }
6390 return result;
6391}
6392
6409Variable * variable_compare_const( Environment * _environment, char * _source, int _destination ) {
6410 Variable * source = variable_retrieve( _environment, _source );
6411
6413
6414 Variable * result = variable_temporary( _environment, VT_SBYTE, "(result of compare)" );
6415 switch( VT_BITWIDTH( source->type ) ) {
6416 case 32:
6417 cpu_compare_32bit_const( _environment, source->realName, _destination, result->realName, 1 );
6418 break;
6419 case 16:
6420 cpu_compare_16bit_const( _environment, source->realName, _destination, result->realName, 1 );
6421 break;
6422 case 8:
6423 cpu_compare_8bit_const( _environment, source->realName, _destination, result->realName, 1 );
6424 break;
6425 case 1:
6426 case 0:
6428 break;
6429 }
6430 return result;
6431}
6432
6449Variable * variable_compare_not_const( Environment * _environment, char * _source, int _destination ) {
6450 Variable * source = variable_retrieve( _environment, _source );
6451
6453
6454 Variable * result = variable_temporary( _environment, VT_SBYTE, "(result of compare)" );
6455 switch( VT_BITWIDTH( source->type ) ) {
6456 case 32:
6457 cpu_compare_32bit_const( _environment, source->realName, _destination, result->realName, 1 );
6458 break;
6459 case 16:
6460 cpu_compare_16bit_const( _environment, source->realName, _destination, result->realName, 1 );
6461 break;
6462 case 8:
6463 cpu_compare_8bit_const( _environment, source->realName, _destination, result->realName, 1 );
6464 break;
6465 case 1:
6466 case 0:
6468 break;
6469 }
6470 return variable_not( _environment, result->name );
6471}
6472
6489Variable * variable_compare_not( Environment * _environment, char * _source, char * _destination ) {
6490 return variable_not( _environment, variable_compare( _environment, _source, _destination)->name );
6491}
6492
6508Variable * variable_mul2_const( Environment * _environment, char * _destination, int _steps ) {
6509
6510 if ( _steps < 0 ) {
6511 CRITICAL_MUL2_INVALID_STEPS( _destination );
6512 }
6513
6514 Variable * destination = variable_retrieve( _environment, _destination );
6515
6516 if ( _steps == 0 ) {
6517 return destination;
6518 }
6519
6520 Variable * result = variable_temporary( _environment, destination->type, "(mul2)" );
6521 variable_move_naked( _environment, destination->name, result->name );
6522
6523 switch( VT_BITWIDTH( destination->type ) ) {
6524 case 32:
6525 if ( (int)log2(_steps) > 0 ) {
6526 cpu_math_mul2_const_32bit( _environment, result->realName, (int)log2(_steps), VT_SIGNED( destination->type ) );
6527 }
6528 break;
6529 case 16:
6530 if ( (int)log2(_steps) > 0 ) {
6531 cpu_math_mul2_const_16bit( _environment, result->realName, (int)log2(_steps), VT_SIGNED( destination->type ) );
6532 }
6533 break;
6534 case 8:
6535 if ( (int)log2(_steps) > 0 ) {
6536 cpu_math_mul2_const_8bit( _environment, result->realName, (int)log2(_steps), VT_SIGNED( destination->type ) );
6537 }
6538 break;
6539 case 1:
6540 case 0:
6541 switch( destination->type ) {
6542 case VT_NUMBER:
6543 cpu_math_mul2_const_nbit( _environment, result->realName, (int)log2(_steps), _environment->numberConfig.maxBytes << 3 );
6544 break;
6545 default:
6546 CRITICAL_MUL2_UNSUPPORTED( _destination, DATATYPE_AS_STRING[destination->type] );
6547 }
6548 break;
6549 }
6550 return result;
6551}
6552
6553Variable * variable_sl_const( Environment * _environment, char * _destination, int _steps ) {
6554
6555 if ( _steps < 0 ) {
6556 CRITICAL_MUL2_INVALID_STEPS( _destination );
6557 }
6558
6559 Variable * destination = variable_retrieve( _environment, _destination );
6560
6561 if ( _steps == 0 ) {
6562 return destination;
6563 }
6564
6565 Variable * result = variable_temporary( _environment, destination->type, "(mul2)" );
6566 variable_move_naked( _environment, destination->name, result->name );
6567
6568 switch( VT_BITWIDTH( destination->type ) ) {
6569 case 32:
6570 cpu_math_mul2_const_32bit( _environment, result->realName, _steps, VT_SIGNED( destination->type ) );
6571 break;
6572 case 16:
6573 cpu_math_mul2_const_16bit( _environment, result->realName, _steps, VT_SIGNED( destination->type ) );
6574 break;
6575 case 8:
6576 cpu_math_mul2_const_8bit( _environment, result->realName, _steps, VT_SIGNED( destination->type ) );
6577 break;
6578 case 1:
6579 case 0:
6580 switch( destination->type ) {
6581 case VT_NUMBER:
6582 cpu_math_mul2_const_nbit( _environment, result->realName, _steps, _environment->numberConfig.maxBytes << 3 );
6583 break;
6584 default:
6585 CRITICAL_MUL2_UNSUPPORTED( _destination, DATATYPE_AS_STRING[destination->type] );
6586 }
6587 break;
6588 }
6589 return result;
6590}
6591
6608Variable * variable_div2_const( Environment * _environment, char * _destination, int _bits, char * _remainder ) {
6609 Variable * destination = variable_retrieve( _environment, _destination );
6610 Variable * result = variable_temporary( _environment, destination->type, "(div2)" );
6611 variable_move_naked( _environment, destination->name, result->name );
6612 Variable * remainder = NULL;
6613 if ( _remainder ) {
6614 remainder = variable_retrieve_or_define( _environment, _remainder, destination->type, 0 );
6615 }
6616
6617 switch( VT_BITWIDTH( destination->type ) ) {
6618 case 32:
6619 if ( (int)log2(_bits) > 0 ) {
6620 cpu_math_div2_const_32bit( _environment, result->realName, (int)(log2(_bits)), VT_SIGNED( destination->type ), remainder ? remainder->realName : NULL );
6621 }
6622 break;
6623 case 16:
6624 if ( (int)log2(_bits) > 0 ) {
6625 cpu_math_div2_const_16bit( _environment, result->realName, (int)(log2(_bits)), VT_SIGNED( destination->type ), remainder ? remainder->realName : NULL );
6626 }
6627 break;
6628 case 8:
6629 if ( (int)log2(_bits) > 0 ) {
6630 cpu_math_div2_const_8bit( _environment, result->realName, (int)(log2(_bits)), VT_SIGNED( destination->type ), remainder ? remainder->realName : NULL );
6631 }
6632 break;
6633 case 1:
6634 case 0:
6635 switch( destination->type ) {
6636 case VT_NUMBER:
6637 cpu_math_div2_const_nbit( _environment, result->realName, (int)(log2(_bits)), _environment->numberConfig.maxBytes << 3, remainder ? remainder->realName : NULL );
6638 break;
6639 default:
6640 CRITICAL_DIV2_UNSUPPORTED( _destination, DATATYPE_AS_STRING[destination->type] );
6641 }
6642 break;
6643 }
6644 return result;
6645}
6646
6647Variable * variable_sr_const( Environment * _environment, char * _destination, int _bits ) {
6648 Variable * destination = variable_retrieve( _environment, _destination );
6649 Variable * result = variable_temporary( _environment, destination->type, "(div2)" );
6650 variable_move_naked( _environment, destination->name, result->name );
6651
6652 switch( VT_BITWIDTH( destination->type ) ) {
6653 case 32:
6654 cpu_math_div2_const_32bit( _environment, result->realName, _bits, VT_SIGNED( destination->type ), NULL );
6655 break;
6656 case 16:
6657 cpu_math_div2_const_16bit( _environment, result->realName, _bits, VT_SIGNED( destination->type ), NULL );
6658 break;
6659 case 8:
6660 cpu_math_div2_const_8bit( _environment, result->realName, _bits, VT_SIGNED( destination->type ), NULL );
6661 break;
6662 case 1:
6663 case 0:
6664 switch( destination->type ) {
6665 case VT_NUMBER:
6666 cpu_math_div2_const_nbit( _environment, result->realName, _bits, _environment->numberConfig.maxBytes << 3, NULL );
6667 break;
6668 default:
6669 CRITICAL_DIV2_UNSUPPORTED( _destination, DATATYPE_AS_STRING[destination->type] );
6670 }
6671 break;
6672 }
6673 return result;
6674}
6675
6692/* <usermanual>
6693@keyword AND
6694
6695@english
6696Performs a logical conjunction on two expressions, as a bitwise conjunction. For comparisons managed
6697as a boolean result (''TRUE'' or ''FALSE''), result is ''TRUE'' if, and
6698only if, both expresions evaluate to ''TRUE''. The following table shows how result is determined:
6699
6700'''TRUE AND TRUE = TRUE'''
6701'''TRUE AND FALSE = FALSE'''
6702'''FALSE AND TRUE = FALSE'''
6703'''FALSE AND FALSE = FALSE'''
6704
6705Generally speaking, the ''AND'' operator performs a bitwise comparison of the bits of two numeric
6706expressions and sets the corresponding bit in result according to the previous table.
6707
6708Note that ugBASIC uses the convention, very common in BASICs of the 1970s and 1980s,
6709of considering Boolean logic as implemented through the so-called "two's complement".
6710
6711In other words, the value ''FALSE'' is associated with a number composed of
6712all ''0''s, in terms of bits. The value ''TRUE'' is, instead,
6713associated with a number composed of all ''1''s, again in terms of bits.
6714According to the 2's complement representation, a number composed of all ones is
6715always equivalent to the number ''-1'', regardless of how many bits the
6716number is composed of, while a number composed of all zeros is always equivalent to zero.
6717
6718According to this convention, there is a coincidence between bitwise and logical
6719operations: in fact, a bitwise ''AND'', applied to all the bits of the number,
6720will be equivalent to the logical operation. Note tha the ''AND'' operator always evaluates
6721both expressions, which can include executing routine calls.
6722
6723Because the logical and bitwise operators have lower precedence than other arithmetic and relational
6724operators, all bitwise operations must be enclosed in parentheses to ensure accurate results.
6725
6726If the operands consist of a ''SIGNED BYTE'' expression and a numeric expression, converts the
6727''SIGNED BYTE'' expression to a numeric value (''-1'' for ''TRUE'' and 0 for ''FALSE'') and
6728performs a bitwise operation. So, the data type of the result is a numeric type appropriate
6729for the data types of both expressions.
6730
6731@italian
6732
6733Esegue una congiunzione logica su due espressioni, come congiunzione bit a bit. Per
6734i confronti gestiti come risultato booleano (''TRUE'' o ''FALSE''), result è ''TRUE''
6735se, e solo se, entrambe le espressioni vengono valutate come ''TRUE''. La seguente
6736tabella mostra come viene determinato il risultato:
6737
6738'''TRUE AND TRUE = TRUE'''
6739'''TRUE AND FALSE = FALSE'''
6740'''FALSE AND TRUE = FALSE'''
6741'''FALSE AND FALSE = FALSE'''
6742
6743In generale, l'operatore ''AND'' esegue un confronto bit a bit dei bit di due espressioni
6744numeriche e imposta il bit corrispondente in result in base alla tabella precedente.
6745
6746Nota che ugBASIC utilizza la convenzione, molto comune nei BASIC degli anni '70 e '80,
6747di considerare la logica booleana come implementata tramite il cosiddetto "complemento a due".
6748
6749In altre parole, il valore ''FALSE'' è associato a un numero composto da tutti ''0'',
6750in termini di bit. Il valore ''TRUE'' è, invece, associato a un numero composto da tutti ''1'',
6751sempre in termini di bit.
6752
6753Secondo la rappresentazione del complemento a 2, un numero composto da tutti 1 è sempre
6754equivalente al numero ''-1'', indipendentemente dal numero di bit di cui è composto, mentre
6755un numero composto da tutti 0 è sempre equivalente a zero.
6756
6757Secondo questa convenzione, c'è una coincidenza tra operazioni bit a bit e logiche: infatti,
6758un ''AND'' bit a bit, applicato a tutti i bit del numero, sarà equivalente all'operazione
6759logica. Nota che l'operatore ''AND'' valuta sempre entrambe le espressioni, il che può
6760includere l'esecuzione di chiamate di routine.
6761
6762Poiché gli operatori logici e bitwise hanno una precedenza inferiore rispetto ad altri
6763operatori aritmetici e relazionali, tutte le operazioni bitwise devono essere racchiuse
6764tra parentesi per garantire risultati accurati.
6765
6766Se gli operandi sono costituiti da un'espressione ''SIGNED BYTE'' e da un'espressione
6767numerica, converte l'espressione ''SIGNED BYTE'' in un valore numerico (''-1'' per
6768''TRUE'' e 0 per ''FALSE'') ed esegue un'operazione bitwise. Quindi, il tipo di dati
6769del risultato è un tipo numerico appropriato per i tipi di dati di entrambe le espressioni.
6770
6771@syntax = x AND y
6772
6773@example IF x AND 1 THEN
6774@example PRINT "x is odd"
6775@example ELSE
6776@example PRINT "x is even"
6777@example ENDIF
6778
6779@target all
6780</usermanual> */
6781Variable * variable_and_const( Environment * _environment, char * _destination, int _mask ) {
6782 Variable * destination = variable_retrieve( _environment, _destination );
6783 Variable * result = variable_temporary( _environment, destination->type, "(result)");
6784 variable_move( _environment, destination->name, result->name );
6785 switch( VT_BITWIDTH( result->type ) ) {
6786 case 32:
6787 cpu_math_and_const_32bit( _environment, result->realName, _mask );
6788 break;
6789 case 16:
6790 cpu_math_and_const_16bit( _environment, result->realName, _mask );
6791 break;
6792 case 8:
6793 cpu_math_and_const_8bit( _environment, result->realName, _mask );
6794 break;
6795 case 1:
6796 case 0:
6797 CRITICAL_AND_UNSUPPORTED( _destination, DATATYPE_AS_STRING[destination->type] );
6798 break;
6799
6800 }
6801 return result;
6802}
6803
6816Variable * variable_and( Environment * _environment, char * _left, char * _right ) {
6817
6818 Variable * source = variable_retrieve( _environment, _left );
6819 Variable * target = variable_cast( _environment, _right, source->type );
6820 if ( ! target ) {
6821 CRITICAL_VARIABLE(_right);
6822 }
6823
6824 Variable * result = variable_temporary( _environment, source->type, "(result of OR)" );
6825
6826 switch( VT_BITWIDTH( source->type ) ) {
6827 case 32:
6828 cpu_and_32bit( _environment, source->realName, target->realName, result->realName );
6829 break;
6830 case 16:
6831 cpu_and_16bit( _environment, source->realName, target->realName, result->realName );
6832 break;
6833 case 8:
6834 cpu_and_8bit( _environment, source->realName, target->realName, result->realName );
6835 break;
6836 case 1:
6837 case 0:
6839 }
6840
6841 return result;
6842}
6843
6856/* <usermanual>
6857@keyword XOR
6858
6859@english
6860Performs a logical exclusion on two expressions, as a bitwise exclusion. For
6861comparisons managed as a boolean result (''TRUE'' or ''FALSE''), result is ''TRUE''
6862if both expresions evaluate differently each other. The following table shows how result
6863is determined:
6864
6865'''TRUE XOR TRUE = FALSE'''
6866'''TRUE XOR FALSE = TRUE'''
6867'''FALSE XOR TRUE = TRUE'''
6868'''FALSE XOR FALSE = FALSE'''
6869
6870Generally speaking, the ''XOR'' operator performs a bitwise comparison of the bits of
6871two numeric expressions and sets the corresponding bit in result according to the
6872previous table.
6873
6874Note that ugBASIC uses the convention, very common in BASICs of the 1970s and 1980s,
6875of considering Boolean logic as implemented through the so-called "two's complement".
6876
6877In other words, the value ''FALSE'' is associated with a number composed of
6878all ''0''s, in terms of bits. The value ''TRUE'' is, instead,
6879associated with a number composed of all ''1''s, again in terms of bits.
6880According to the 2's complement representation, a number composed of all ones is
6881always equivalent to the number ''-1'', regardless of how many bits the
6882number is composed of, while a number composed of all zeros is always equivalent to zero.
6883
6884According to this convention, there is a coincidence between bitwise and logical
6885operations: in fact, a bitwise ''XOR'', applied to all the bits of the number,
6886will be equivalent to the logical operation. Note that the ''XOR'' operator always evaluates
6887both expressions, which can include executing routine calls.
6888
6889Because the logical and bitwise operators have lower precedence than other arithmetic and relational
6890operators, all bitwise operations must be enclosed in parentheses to ensure accurate results.
6891
6892If the operands consist of a ''SIGNED BYTE'' expression and a numeric expression, converts the
6893''SIGNED BYTE'' expression to a numeric value (''-1'' for ''TRUE'' and 0 for ''FALSE'') and
6894performs a bitwise operation. So, the data type of the result is a numeric type appropriate
6895for the data types of both expressions.
6896
6897@italian
6898
6899Esegue una esclusione logica su due espressioni, come esclusione bit a bit. Per
6900i confronti gestiti come risultato booleano (''TRUE'' o ''FALSE''), result è ''TRUE''
6901se entrambe le espressioni sono valutate in modo diverso. La seguente
6902tabella mostra come viene determinato il risultato:
6903
6904'''TRUE XOR TRUE = FALSE'''
6905'''TRUE XOR FALSE = TRUE'''
6906'''FALSE XOR TRUE = TRUE'''
6907'''FALSE XOR FALSE = FALSE'''
6908
6909In generale, l'operatore ''XOR'' esegue un confronto bit a bit dei bit di due espressioni
6910numeriche e imposta il bit corrispondente in result in base alla tabella precedente.
6911
6912Nota che ugBASIC utilizza la convenzione, molto comune nei BASIC degli anni '70 e '80,
6913di considerare la logica booleana come implementata tramite il cosiddetto "complemento a due".
6914
6915In altre parole, il valore ''FALSE'' è associato a un numero composto da tutti ''0'',
6916in termini di bit. Il valore ''TRUE'' è, invece, associato a un numero composto da tutti ''1'',
6917sempre in termini di bit.
6918
6919Secondo la rappresentazione del complemento a 2, un numero composto da tutti 1 è sempre
6920equivalente al numero ''-1'', indipendentemente dal numero di bit di cui è composto, mentre
6921un numero composto da tutti 0 è sempre equivalente a zero.
6922
6923Secondo questa convenzione, c'è una coincidenza tra operazioni bit a bit e logiche: infatti,
6924un ''XOR'' bit a bit, applicato a tutti i bit del numero, sarà equivalente all'operazione
6925logica. Nota che l'operatore ''XOR'' valuta sempre entrambe le espressioni, il che può
6926includere l'esecuzione di chiamate di routine.
6927
6928Poiché gli operatori logici e bitwise hanno una precedenza inferiore rispetto ad altri
6929operatori aritmetici e relazionali, tutte le operazioni bitwise devono essere racchiuse
6930tra parentesi per garantire risultati accurati.
6931
6932Se gli operandi sono costituiti da un'espressione ''SIGNED BYTE'' e da un'espressione
6933numerica, converte l'espressione ''SIGNED BYTE'' in un valore numerico (''-1'' per
6934''TRUE'' e 0 per ''FALSE'') ed esegue un'operazione bitwise. Quindi, il tipo di dati
6935del risultato è un tipo numerico appropriato per i tipi di dati di entrambe le espressioni.
6936
6937@syntax = x OR y
6938
6939@example IF x XOR x THEN: PRINT "never executed" : ELSE : PRINT "always executed": ENDIF
6940
6941@target all
6942</usermanual> */
6943Variable * variable_xor( Environment * _environment, char * _left, char * _right ) {
6944
6945 Variable * source = variable_retrieve( _environment, _left );
6946 Variable * target = variable_cast( _environment, _right, source->type );
6947 if ( ! target ) {
6948 CRITICAL_VARIABLE(_right);
6949 }
6950
6951 Variable * result = variable_temporary( _environment, source->type, "(result of OR)" );
6952
6953 switch( VT_BITWIDTH( source->type ) ) {
6954 case 32:
6955 cpu_xor_32bit( _environment, source->realName, target->realName, result->realName );
6956 break;
6957 case 16:
6958 cpu_xor_16bit( _environment, source->realName, target->realName, result->realName );
6959 break;
6960 case 8:
6961 cpu_xor_8bit( _environment, source->realName, target->realName, result->realName );
6962 break;
6963 case 1:
6964 case 0:
6966 }
6967
6968 return result;
6969}
6970
6983/* <usermanual>
6984@keyword OR
6985
6986@english
6987Performs a logical disjunction on two expressions, as a bitwise disjunction. For
6988comparisons managed as a boolean result (''TRUE'' or ''FALSE''), result is ''TRUE''
6989if just one expresions evaluate to ''TRUE''. The following table shows how result
6990is determined:
6991
6992'''TRUE OR TRUE = TRUE'''
6993'''TRUE OR FALSE = TRUE'''
6994'''FALSE OR TRUE = TRUE'''
6995'''FALSE OR FALSE = FALSE'''
6996
6997Generally speaking, the ''OR'' operator performs a bitwise comparison of the bits of
6998two numeric expressions and sets the corresponding bit in result according to the
6999previous table.
7000
7001Note that ugBASIC uses the convention, very common in BASICs of the 1970s and 1980s,
7002of considering Boolean logic as implemented through the so-called "two's complement".
7003
7004In other words, the value ''FALSE'' is associated with a number composed of
7005all ''0''s, in terms of bits. The value ''TRUE'' is, instead,
7006associated with a number composed of all ''1''s, again in terms of bits.
7007According to the 2's complement representation, a number composed of all ones is
7008always equivalent to the number ''-1'', regardless of how many bits the
7009number is composed of, while a number composed of all zeros is always equivalent to zero.
7010
7011According to this convention, there is a coincidence between bitwise and logical
7012operations: in fact, a bitwise ''OR'', applied to all the bits of the number,
7013will be equivalent to the logical operation. Note that the ''OR'' operator always evaluates
7014both expressions, which can include executing routine calls.
7015
7016Because the logical and bitwise operators have lower precedence than other arithmetic and relational
7017operators, all bitwise operations must be enclosed in parentheses to ensure accurate results.
7018
7019If the operands consist of a ''SIGNED BYTE'' expression and a numeric expression, converts the
7020''SIGNED BYTE'' expression to a numeric value (''-1'' for ''TRUE'' and 0 for ''FALSE'') and
7021performs a bitwise operation. So, the data type of the result is a numeric type appropriate
7022for the data types of both expressions.
7023
7024@italian
7025
7026Esegue una disgiunzione logica su due espressioni, come disgiunzione bit a bit. Per
7027i confronti gestiti come risultato booleano (''TRUE'' o ''FALSE''), result è ''TRUE''
7028se solo una espressione viene valutata come ''TRUE''. La seguente
7029tabella mostra come viene determinato il risultato:
7030
7031'''TRUE OR TRUE = TRUE'''
7032'''TRUE OR FALSE = TRUE'''
7033'''FALSE OR TRUE = TRUE'''
7034'''FALSE OR FALSE = FALSE'''
7035
7036In generale, l'operatore ''OR'' esegue un confronto bit a bit dei bit di due espressioni
7037numeriche e imposta il bit corrispondente in result in base alla tabella precedente.
7038
7039Nota che ugBASIC utilizza la convenzione, molto comune nei BASIC degli anni '70 e '80,
7040di considerare la logica booleana come implementata tramite il cosiddetto "complemento a due".
7041
7042In altre parole, il valore ''FALSE'' è associato a un numero composto da tutti ''0'',
7043in termini di bit. Il valore ''TRUE'' è, invece, associato a un numero composto da tutti ''1'',
7044sempre in termini di bit.
7045
7046Secondo la rappresentazione del complemento a 2, un numero composto da tutti 1 è sempre
7047equivalente al numero ''-1'', indipendentemente dal numero di bit di cui è composto, mentre
7048un numero composto da tutti 0 è sempre equivalente a zero.
7049
7050Secondo questa convenzione, c'è una coincidenza tra operazioni bit a bit e logiche: infatti,
7051un ''OR'' bit a bit, applicato a tutti i bit del numero, sarà equivalente all'operazione
7052logica. Nota che l'operatore ''OR'' valuta sempre entrambe le espressioni, il che può
7053includere l'esecuzione di chiamate di routine.
7054
7055Poiché gli operatori logici e bitwise hanno una precedenza inferiore rispetto ad altri
7056operatori aritmetici e relazionali, tutte le operazioni bitwise devono essere racchiuse
7057tra parentesi per garantire risultati accurati.
7058
7059Se gli operandi sono costituiti da un'espressione ''SIGNED BYTE'' e da un'espressione
7060numerica, converte l'espressione ''SIGNED BYTE'' in un valore numerico (''-1'' per
7061''TRUE'' e 0 per ''FALSE'') ed esegue un'operazione bitwise. Quindi, il tipo di dati
7062del risultato è un tipo numerico appropriato per i tipi di dati di entrambe le espressioni.
7063
7064@syntax = x OR y
7065
7066@example IF x OR 1 THEN: PRINT "always executed" : ELSE : PRINT "never executed": ENDIF
7067
7068@target all
7069</usermanual> */
7070Variable * variable_or( Environment * _environment, char * _left, char * _right ) {
7071
7072 Variable * source = variable_retrieve( _environment, _left );
7073 Variable * target = variable_cast( _environment, _right, source->type );
7074 if ( ! target ) {
7075 CRITICAL_VARIABLE(_right);
7076 }
7077
7078 Variable * result = variable_temporary( _environment, source->type, "(result of OR)" );
7079
7080 switch( VT_BITWIDTH( source->type ) ) {
7081 case 32:
7082 cpu_or_32bit( _environment, source->realName, target->realName, result->realName );
7083 break;
7084 case 16:
7085 cpu_or_16bit( _environment, source->realName, target->realName, result->realName );
7086 break;
7087 case 8:
7088 cpu_or_8bit( _environment, source->realName, target->realName, result->realName );
7089 break;
7090 case 1:
7091 case 0:
7093 }
7094
7095 return result;
7096
7097}
7098
7110 /* <usermanual>
7111@keyword NOT
7112
7113@english
7114Performs a logical negation on an expression, as a bitwise negation. For
7115comparisons managed as a boolean result (''TRUE'' or ''FALSE''), result is ''TRUE''
7116if expresions evaluate as ''FALSE''. The following table shows how result
7117is determined:
7118
7119'''NOT TRUE = FALSE'''
7120'''NOT FALSE = TRUE'''
7121
7122Generally speaking, the ''NOT'' operator performs a bitwise negation of the bits of
7123the expression and sets the corresponding bit in result according to the
7124previous table.
7125
7126Note that ugBASIC uses the convention, very common in BASICs of the 1970s and 1980s,
7127of considering Boolean logic as implemented through the so-called "two's complement".
7128
7129In other words, the value ''FALSE'' is associated with a number composed of
7130all ''0''s, in terms of bits. The value ''TRUE'' is, instead,
7131associated with a number composed of all ''1''s, again in terms of bits.
7132According to the 2's complement representation, a number composed of all ones is
7133always equivalent to the number ''-1'', regardless of how many bits the
7134number is composed of, while a number composed of all zeros is always equivalent to zero.
7135
7136According to this convention, there is a coincidence between bitwise and logical
7137operations: in fact, a bitwise ''NOT'', applied to all the bits of the number,
7138will be equivalent to the logical operation.
7139
7140Because the logical and bitwise operators have lower precedence than other arithmetic and relational
7141operators, all bitwise operations must be enclosed in parentheses to ensure accurate results.
7142
7143@italian
7144
7145Esegue una negazione logica su due espressioni, come negazione bit a bit. Per
7146i confronti gestiti come risultato booleano (''TRUE'' o ''FALSE''), result è ''TRUE''
7147se entrambe le espressioni sono valutate in modo diverso. La seguente
7148tabella mostra come viene determinato il risultato:
7149
7150'''NOT TRUE = FALSE'''
7151'''NOT FALSE = TRUE'''
7152
7153In generale, l'operatore ''NOT'' esegue una negazione bit a bit dei bit dell'espressione
7154numerica e imposta il bit corrispondente in base alla tabella precedente.
7155
7156Nota che ugBASIC utilizza la convenzione, molto comune nei BASIC degli anni '70 e '80,
7157di considerare la logica booleana come implementata tramite il cosiddetto "complemento a due".
7158
7159In altre parole, il valore ''FALSE'' è associato a un numero composto da tutti ''0'',
7160in termini di bit. Il valore ''TRUE'' è, invece, associato a un numero composto da tutti ''1'',
7161sempre in termini di bit.
7162
7163Secondo la rappresentazione del complemento a 2, un numero composto da tutti 1 è sempre
7164equivalente al numero ''-1'', indipendentemente dal numero di bit di cui è composto, mentre
7165un numero composto da tutti 0 è sempre equivalente a zero.
7166
7167Secondo questa convenzione, c'è una coincidenza tra operazioni bit a bit e logiche: infatti,
7168un ''NOT'' bit a bit, applicato a tutti i bit del numero, sarà equivalente all'operazione
7169logica.
7170
7171Poiché gli operatori logici e bitwise hanno una precedenza inferiore rispetto ad altri
7172operatori aritmetici e relazionali, tutte le operazioni bitwise devono essere racchiuse
7173tra parentesi per garantire risultati accurati.
7174
7175@syntax = NOT x
7176
7177@example IF NOT x THEN
7178@example PRINT "x is FALSE"
7179@example ELSE
7180@example PRINT "x is TRUE"
7181@example ENDIF
7182</usermanual> */
7183Variable * variable_not( Environment * _environment, char * _value ) {
7184
7185 Variable * source = variable_retrieve( _environment, _value );
7186
7187 Variable * result = variable_temporary( _environment, source->type, "(result of OR)" );
7188
7189 switch( VT_BITWIDTH( source->type ) ) {
7190 case 32:
7191 cpu_not_32bit( _environment, source->realName, result->realName );
7192 break;
7193 case 16:
7194 cpu_not_16bit( _environment, source->realName, result->realName );
7195 break;
7196 case 8:
7197 cpu_not_8bit( _environment, source->realName, result->realName );
7198 break;
7199 case 1:
7200 case 0:
7202 }
7203
7204 return result;
7205
7206}
7207
7225Variable * variable_less_than( Environment * _environment, char * _source, char * _destination, int _equal ) {
7226
7228
7229 Variable * source = variable_retrieve( _environment, _source );
7230 Variable * target = variable_retrieve( _environment, _destination );
7231
7232 int best = calculate_cast_type_best_fit( _environment, source->type, target->type );
7233 source = variable_cast( _environment, source->name, best );
7234 target = variable_cast( _environment, target->name, best );
7235
7236 Variable * result = variable_temporary( _environment, VT_SBYTE, "(result of compare)" );
7237 switch( VT_BITWIDTH( source->type ) ) {
7238 case 32:
7239 switch( VT_BITWIDTH( target->type ) ) {
7240 case 32:
7241 cpu_less_than_32bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7242 break;
7243 case 16:
7244 WARNING_BITWIDTH( _source, _destination );
7245 #ifdef CPU_BIG_ENDIAN
7246 {
7247 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "2") );
7248 cpu_less_than_16bit( _environment, sourceRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7249 }
7250 #else
7251 cpu_less_than_16bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7252 #endif
7253 break;
7254 case 8:
7255 WARNING_BITWIDTH( _source, _destination );
7256 #ifdef CPU_BIG_ENDIAN
7257 {
7258 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "3") );
7259 cpu_less_than_8bit( _environment, sourceRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7260 }
7261 #else
7262 cpu_less_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7263 #endif
7264 break;
7265 case 1:
7266 case 0:
7267 switch( target->type ) {
7268 case VT_NUMBER:
7269 #ifdef CPU_BIG_ENDIAN
7270 {
7271 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 4 );
7272 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, offsetAsString) );
7273 cpu_less_than_32bit( _environment, targetRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7274 }
7275 #else
7276 cpu_less_than_32bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7277 #endif
7278 break;
7279 default:
7280
7282 }
7283 }
7284 break;
7285 case 16:
7286 switch( VT_BITWIDTH( target->type ) ) {
7287 case 32:
7288 WARNING_BITWIDTH( _source, _destination );
7289 #ifdef CPU_BIG_ENDIAN
7290 {
7291 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "2") );
7292 cpu_less_than_16bit( _environment, source->realName, targetRealName, result->realName, _equal, VT_SIGNED( source->type ) );
7293 }
7294 #else
7295 cpu_less_than_16bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7296 #endif
7297 break;
7298 case 16:
7299 cpu_less_than_16bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7300 break;
7301 case 8:
7302 WARNING_BITWIDTH( _source, _destination );
7303 #ifdef CPU_BIG_ENDIAN
7304 {
7305 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "1") );
7306 cpu_less_than_8bit( _environment, sourceRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7307 }
7308 #else
7309 cpu_less_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7310 #endif
7311 break;
7312 case 1:
7313 case 0:
7314 switch( target->type ) {
7315 case VT_NUMBER:
7316 #ifdef CPU_BIG_ENDIAN
7317 {
7318 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 2 );
7319 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, offsetAsString) );
7320 cpu_less_than_16bit( _environment, targetRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7321 }
7322 #else
7323 cpu_less_than_16bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7324 #endif
7325 break;
7326 default:
7327
7329 }
7330 }
7331 break;
7332 case 8:
7333 switch( VT_BITWIDTH( target->type ) ) {
7334 case 32:
7335 case 16:
7336 WARNING_BITWIDTH( _source, _destination );
7337 if ( VT_SIGNED( source->type ) ) {
7339 }
7340 cpu_less_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7341 break;
7342 case 8:
7343 cpu_less_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7344 break;
7345 case 1:
7346 case 0:
7347 switch( target->type ) {
7348 case VT_NUMBER:
7349 #ifdef CPU_BIG_ENDIAN
7350 {
7351 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 1 );
7352 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, offsetAsString) );
7353 cpu_less_than_8bit( _environment, targetRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7354 }
7355 #else
7356 cpu_less_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7357 #endif
7358 break;
7359 default:
7360
7362 }
7363 }
7364 break;
7365 case 1:
7367 case 0:
7368 switch( source->type ) {
7369 case VT_STRING:
7370 switch( target->type ) {
7371 case VT_STRING: {
7372 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%sdiff", label );
7373 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7374 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7375 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7376 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7377 cpu_move_8bit( _environment, source->realName, size->realName );
7378 cpu_move_8bit( _environment, target->realName, size2->realName );
7379 cpu_compare_8bit( _environment, size->realName, size2->realName, result->realName, 1 );
7380 cpu_bveq( _environment, result->realName, differentLabel );
7381 cpu_addressof_16bit( _environment, source->realName, address->realName );
7382 cpu_inc_16bit( _environment, address->realName );
7383 cpu_addressof_16bit( _environment, target->realName, address2->realName );
7384 cpu_inc_16bit( _environment, address2->realName );
7385 cpu_less_than_memory( _environment, address->realName, address2->realName, size->realName, result->realName, _equal );
7386 cpu_jump( _environment, label );
7387 cpu_label( _environment, differentLabel );
7388 cpu_less_than_8bit( _environment, size->realName, size2->realName, result->realName, _equal, 0 );
7389 cpu_label( _environment, label );
7390 break;
7391 }
7392 case VT_DSTRING: {
7393 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%sdiff", label );
7394 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
7395 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
7396 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7397 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7398 cpu_move_8bit( _environment, source->realName, size->realName );
7399 cpu_dsdescriptor( _environment, target->realName, address2->realName, size2->realName );
7400 cpu_compare_8bit( _environment, size->realName, size2->realName, result->realName, 1 );
7401 cpu_bveq( _environment, result->realName, differentLabel );
7402 cpu_addressof_16bit( _environment, source->realName, address->realName );
7403 cpu_inc_16bit( _environment, address->realName );
7404 cpu_less_than_memory( _environment, address->realName, address2->realName, size->realName, result->realName, _equal );
7405 cpu_jump( _environment, label );
7406 cpu_label( _environment, differentLabel );
7407 cpu_less_than_8bit( _environment, size->realName, size2->realName, result->realName, _equal, 0 );
7408 cpu_label( _environment, label );
7409 break;
7410 }
7411 default:
7413 }
7414 break;
7415 case VT_DSTRING:
7416 switch( target->type ) {
7417 case VT_STRING: {
7418 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%sdiff", label );
7419 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
7420 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
7421 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7422 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7423 cpu_move_8bit( _environment, target->realName, size2->realName );
7424 cpu_dsdescriptor( _environment, source->realName, address->realName, size->realName );
7425 cpu_compare_8bit( _environment, size->realName, size2->realName, result->realName, 1 );
7426 cpu_bveq( _environment, result->realName, differentLabel );
7427 cpu_addressof_16bit( _environment, target->realName, address2->realName );
7428 cpu_inc_16bit( _environment, address2->realName );
7429 cpu_less_than_memory( _environment, address->realName, address2->realName, size->realName, result->realName, _equal );
7430 cpu_jump( _environment, label );
7431 cpu_label( _environment, differentLabel );
7432 cpu_less_than_8bit( _environment, size->realName, size2->realName, result->realName, _equal, 0 );
7433 cpu_label( _environment, label );
7434 break;
7435 }
7436 case VT_DSTRING: {
7437 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%sdiff", label );
7438 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7439 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7440 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7441 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7442 cpu_dsdescriptor( _environment, source->realName, address->realName, size->realName );
7443 cpu_dsdescriptor( _environment, target->realName, address2->realName, size2->realName );
7444 cpu_compare_8bit( _environment, size->realName, size2->realName, result->realName, 1 );
7445 cpu_bveq( _environment, result->realName, differentLabel );
7446 cpu_less_than_memory( _environment, address->realName, address2->realName, size->realName, result->realName, _equal );
7447 cpu_jump( _environment, label );
7448 cpu_label( _environment, differentLabel );
7449 cpu_less_than_8bit( _environment, size->realName, size2->realName, result->realName, _equal, 0 );
7450 cpu_label( _environment, label );
7451 break;
7452 }
7453 default:
7455 }
7456 break;
7457 case VT_MUSIC:
7458 if ( source->sidFile ) {
7460 }
7461 case VT_NUMBER:
7462 switch( target->type ) {
7463 case VT_NUMBER:
7464 cpu_less_than_nbit( _environment, source->realName, target->realName, result->realName, _equal, _environment->numberConfig.maxBytes << 3 );
7465 break;
7466 default:
7468 }
7469 break;
7470 case VT_IMAGE:
7471 case VT_IMAGES:
7472 case VT_SEQUENCE:
7473 case VT_BUFFER:
7474 case VT_TYPE:
7475 switch( target->type ) {
7476 case VT_MUSIC:
7477 if ( target->sidFile ) {
7479 }
7480 case VT_BUFFER:
7481 case VT_TYPE:
7482 case VT_IMAGE:
7483 case VT_IMAGES:
7484 case VT_SEQUENCE:
7485 cpu_less_than_memory_size( _environment, source->realName, target->realName, source->size, result->realName, _equal );
7486 break;
7487 default:
7489 }
7490 break;
7491 case VT_FLOAT:
7492 switch( source->type ) {
7493 case VT_FLOAT: {
7495 if ( source->precision != target->precision ) {
7497 }
7498 char greaterLabel[MAX_TEMPORARY_STORAGE]; sprintf( greaterLabel, "%sgreater", label );
7499 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneLabel, "%sdone", label );
7500 switch( source->precision ) {
7501 case FT_FAST:
7502 cpu_float_fast_cmp( _environment, source->realName, target->realName, result->realName );
7503 break;
7504 case FT_SINGLE:
7505 cpu_float_single_cmp( _environment, source->realName, target->realName, result->realName );
7506 break;
7507 default:
7509 }
7510 cpu_compare_and_branch_8bit_const( _environment, result->realName, 1, greaterLabel, 1 );
7511 if ( !_equal ) {
7512 cpu_compare_and_branch_8bit_const( _environment, result->realName, 0, greaterLabel, 1 );
7513 }
7514 cpu_store_8bit( _environment, result->realName, 255 );
7515 cpu_jump( _environment, doneLabel );
7516 cpu_label( _environment, greaterLabel );
7517 cpu_store_8bit( _environment, result->realName, 0 );
7518 cpu_label( _environment, doneLabel );
7519 break;
7520 }
7521 default:
7523 }
7524 break;
7525 default:
7527 }
7528 break;
7529 }
7530 return result;
7531}
7532
7533Variable * variable_less_than_const( Environment * _environment, char * _source, int _destination, int _equal ) {
7534
7536
7537 Variable * source = variable_retrieve( _environment, _source );
7538
7539 Variable * result = variable_temporary( _environment, VT_SBYTE, "(result of compare)" );
7540 switch( VT_BITWIDTH( source->type ) ) {
7541 case 32:
7542 cpu_less_than_32bit_const( _environment, source->realName, _destination, result->realName, _equal, VT_SIGNED( source->type ) );
7543 break;
7544 case 16:
7545 cpu_less_than_16bit_const( _environment, source->realName, _destination, result->realName, _equal, VT_SIGNED( source->type ) );
7546 break;
7547 case 8:
7548 cpu_less_than_8bit_const( _environment, source->realName, _destination, result->realName, _equal, VT_SIGNED( source->type ) );
7549 break;
7550 default:
7551 switch( source->type ) {
7552 case VT_NUMBER:
7553 cpu_less_than_nbit_const( _environment, source->realName, _destination, result->realName, _equal, _environment->numberConfig.maxBytes << 3 );
7554 break;
7555 default:
7557 }
7558 break;
7559 }
7560 return result;
7561}
7562
7580Variable * variable_greater_than( Environment * _environment, char * _source, char * _destination, int _equal ) {
7581
7583
7584 Variable * source = variable_retrieve( _environment, _source );
7585 Variable * target = variable_retrieve( _environment, _destination );
7586
7587 int best = calculate_cast_type_best_fit( _environment, source->type, target->type );
7588 source = variable_cast( _environment, source->name, best );
7589 target = variable_cast( _environment, target->name, best );
7590
7591 Variable * result = variable_temporary( _environment, VT_SBYTE, "(result of compare)" );
7592 switch( VT_BITWIDTH( source->type ) ) {
7593 case 32:
7594 switch( VT_BITWIDTH( target->type) ) {
7595 case 32:
7596 cpu_greater_than_32bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7597 break;
7598 case 16:
7599 WARNING_BITWIDTH( _source, _destination );
7600 #ifdef CPU_BIG_ENDIAN
7601 {
7602 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "2") );
7603 cpu_greater_than_16bit( _environment, sourceRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7604 }
7605 #else
7606 cpu_greater_than_16bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7607 #endif
7608 break;
7609 case 8:
7610 WARNING_BITWIDTH( _source, _destination );
7611 #ifdef CPU_BIG_ENDIAN
7612 {
7613 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "3") );
7614 cpu_greater_than_8bit( _environment, sourceRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7615 }
7616 #else
7617 cpu_greater_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7618 #endif
7619 break;
7620 case 1:
7621 case 0: {
7622 switch( target->type ) {
7623 case VT_NUMBER:
7624 #ifdef CPU_BIG_ENDIAN
7625 {
7626 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 4 );
7627 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, offsetAsString) );
7628 cpu_greater_than_32bit( _environment, targetRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7629 }
7630 #else
7631 cpu_greater_than_32bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7632 #endif
7633 break;
7634 default:
7635
7637 }
7638 }
7639 }
7640 break;
7641 case 16:
7642 switch( VT_BITWIDTH( target->type) ) {
7643 case 32:
7644 WARNING_BITWIDTH( _source, _destination );
7645 #ifdef CPU_BIG_ENDIAN
7646 {
7647 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "2") );
7648 cpu_greater_than_16bit( _environment, source->realName, targetRealName, result->realName, _equal, VT_SIGNED( source->type ) );
7649 }
7650 #else
7651 cpu_greater_than_16bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7652 #endif
7653 break;
7654 case 16:
7655 cpu_greater_than_16bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7656 break;
7657 case 8:
7658 WARNING_BITWIDTH( _source, _destination );
7659 #ifdef CPU_BIG_ENDIAN
7660 {
7661 char sourceRealName[MAX_TEMPORARY_STORAGE]; sprintf( sourceRealName, "%s", address_displacement(_environment, source->realName, "1") );
7662 cpu_greater_than_8bit( _environment, sourceRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7663 }
7664 #else
7665 cpu_greater_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7666 #endif
7667 break;
7668 case 1:
7669 case 0: {
7670 switch( target->type ) {
7671 case VT_NUMBER:
7672 #ifdef CPU_BIG_ENDIAN
7673 {
7674 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 2 );
7675 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, offsetAsString) );
7676 cpu_greater_than_16bit( _environment, targetRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7677 }
7678 #else
7679 cpu_greater_than_16bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7680 #endif
7681 break;
7682 default:
7683
7685 }
7686 }
7687
7688 }
7689 break;
7690 case 8:
7691 switch( VT_BITWIDTH( target->type) ) {
7692 case 32:
7693 WARNING_BITWIDTH( _source, _destination );
7694 #ifdef CPU_BIG_ENDIAN
7695 {
7696 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "3") );
7697 cpu_greater_than_8bit( _environment, source->realName, targetRealName, result->realName, _equal, VT_SIGNED( source->type ) );
7698 }
7699 #else
7700 cpu_greater_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7701 #endif
7702 break;
7703 case 16:
7704 #ifdef CPU_BIG_ENDIAN
7705 {
7706 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, "1") );
7707 cpu_greater_than_8bit( _environment, source->realName, targetRealName, result->realName, _equal, VT_SIGNED( source->type ) );
7708 }
7709 #else
7710 cpu_greater_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7711 #endif
7712 break;
7713 case 8:
7714 cpu_greater_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7715 break;
7716 case 1:
7717 case 0: {
7718 switch( target->type ) {
7719 case VT_NUMBER:
7720 #ifdef CPU_BIG_ENDIAN
7721 {
7722 char offsetAsString[MAX_TEMPORARY_STORAGE]; sprintf( offsetAsString, "%d", _environment->numberConfig.maxBytes - 1 );
7723 char targetRealName[MAX_TEMPORARY_STORAGE]; sprintf( targetRealName, "%s", address_displacement(_environment, target->realName, offsetAsString) );
7724 cpu_greater_than_8bit( _environment, targetRealName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7725 }
7726 #else
7727 cpu_greater_than_8bit( _environment, source->realName, target->realName, result->realName, _equal, VT_SIGNED( source->type ) );
7728 #endif
7729 break;
7730 default:
7731
7733 }
7734 }
7735 }
7736 break;
7737 case 0:
7738 switch( source->type ) {
7739 case VT_STRING:
7740 switch( target->type ) {
7741 case VT_STRING: {
7742 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%s", label );
7743 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf(doneLabel, "%sdone", label );
7744 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7745 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7746 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7747 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7748 cpu_move_8bit( _environment, source->realName, size->realName );
7749 cpu_move_8bit( _environment, target->realName, size2->realName );
7750 cpu_compare_8bit( _environment, size->realName, size2->realName, result->realName, 1 );
7751 cpu_bveq( _environment, result->realName, differentLabel );
7752
7753 cpu_addressof_16bit( _environment, source->realName, address->realName );
7754 cpu_inc_16bit( _environment, address->realName );
7755 cpu_addressof_16bit( _environment, target->realName, address2->realName );
7756 cpu_inc_16bit( _environment, address2->realName );
7757 cpu_greater_than_memory( _environment, address->realName, address2->realName, size->realName, result->realName, _equal );
7758 cpu_jump( _environment, doneLabel );
7759
7760 cpu_label( _environment, differentLabel );
7761 cpu_greater_than_8bit( _environment, size->realName, size2->realName, result->realName, _equal, 0 );
7762 cpu_label( _environment, doneLabel );
7763 break;
7764 }
7765 case VT_DSTRING: {
7766 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%s", label );
7767 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf(doneLabel, "%sdone", label );
7768 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
7769 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
7770 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7771 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7772 cpu_move_8bit( _environment, source->realName, size->realName );
7773 cpu_dsdescriptor( _environment, target->realName, address2->realName, size2->realName );
7774 cpu_compare_8bit( _environment, size->realName, size2->realName, result->realName, 1 );
7775 cpu_bveq( _environment, result->realName, differentLabel );
7776
7777 cpu_addressof_16bit( _environment, source->realName, address->realName );
7778 cpu_inc_16bit( _environment, address->realName );
7779 cpu_greater_than_memory( _environment, address->realName, address2->realName, size->realName, result->realName, 1 );
7780 cpu_jump( _environment, doneLabel );
7781
7782 cpu_label( _environment, differentLabel );
7783 cpu_greater_than_8bit( _environment, size->realName, size2->realName, result->realName, 1, 0 );
7784 cpu_label( _environment, doneLabel );
7785 }
7786
7787 default:
7789 }
7790 break;
7791 case VT_DSTRING:
7792 switch( target->type ) {
7793 case VT_STRING: {
7794 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%s", label );
7795 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf(doneLabel, "%sdone", label );
7796 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
7797 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
7798 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7799 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7800 cpu_move_8bit( _environment, target->realName, size->realName );
7801 cpu_dsdescriptor( _environment, source->realName, address->realName, size->realName );
7802 cpu_compare_8bit( _environment, size->realName, size2->realName, result->realName, 1 );
7803 cpu_bveq( _environment, result->realName, differentLabel );
7804
7805 cpu_addressof_16bit( _environment, target->realName, address2->realName );
7806 cpu_inc_16bit( _environment, address2->realName );
7807 cpu_greater_than_memory( _environment, address->realName, address2->realName, size->realName, result->realName, 1 );
7808 cpu_jump( _environment, doneLabel );
7809
7810 cpu_label( _environment, differentLabel );
7811 cpu_greater_than_8bit( _environment, size->realName, size2->realName, result->realName, 1, 0 );
7812 cpu_label( _environment, doneLabel );
7813 break;
7814 }
7815 case VT_DSTRING: {
7816 char differentLabel[MAX_TEMPORARY_STORAGE]; sprintf(differentLabel, "%s", label );
7817 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf(doneLabel, "%sdone", label );
7818 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
7819 Variable * size = variable_temporary( _environment, VT_BYTE, "(size of DSTRING)");
7820 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(address of STRING)");
7821 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(size of STRING)");
7822 cpu_dsdescriptor( _environment, source->realName, address->realName, size->realName );
7823 cpu_dsdescriptor( _environment, target->realName, address2->realName, size2->realName );
7824 cpu_compare_8bit( _environment, size->realName, size2->realName, result->realName, 1 );
7825 cpu_bveq( _environment, result->realName, differentLabel );
7826
7827 cpu_greater_than_memory( _environment, address->realName, address2->realName, size->realName, result->realName, 1 );
7828 cpu_jump( _environment, doneLabel );
7829
7830 cpu_label( _environment, differentLabel );
7831 cpu_greater_than_8bit( _environment, size->realName, size2->realName, result->realName, 1, 0 );
7832 cpu_label( _environment, doneLabel );
7833
7834 break;
7835 }
7836 default:
7838 }
7839 break;
7840 case VT_MUSIC:
7841 if ( source->sidFile ) {
7843 }
7844 case VT_NUMBER:
7845 switch( target->type ) {
7846 case VT_NUMBER:
7847 cpu_greater_than_nbit( _environment, source->realName, target->realName, result->realName, _equal, _environment->numberConfig.maxBytes << 3 );
7848 break;
7849 default:
7851 }
7852 break;
7853 case VT_IMAGE:
7854 case VT_IMAGES:
7855 case VT_SEQUENCE:
7856 case VT_BUFFER:
7857 case VT_TYPE:
7858 switch( target->type ) {
7859 case VT_MUSIC:
7860 if ( target->sidFile ) {
7862 }
7863 case VT_BUFFER:
7864 case VT_TYPE:
7865 case VT_IMAGE:
7866 case VT_IMAGES:
7867 case VT_SEQUENCE:
7868 cpu_greater_than_memory_size( _environment, source->realName, target->realName, source->size, result->realName, _equal );
7869 break;
7870 default:
7872 }
7873 break;
7874 case VT_FLOAT:
7875 switch( target->type ) {
7876 case VT_FLOAT: {
7878 if ( source->precision != target->precision ) {
7880 }
7881 char greaterLabel[MAX_TEMPORARY_STORAGE]; sprintf( greaterLabel, "%sgreater", label );
7882 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneLabel, "%sdone", label );
7883 switch( source->precision ) {
7884 case FT_FAST:
7885 cpu_float_fast_cmp( _environment, source->realName, target->realName, result->realName );
7886 break;
7887 case FT_SINGLE:
7888 cpu_float_single_cmp( _environment, source->realName, target->realName, result->realName );
7889 break;
7890 default:
7892 }
7893 cpu_compare_and_branch_8bit_const( _environment, result->realName, 1, greaterLabel, 1 );
7894 if ( _equal ) {
7895 cpu_compare_and_branch_8bit_const( _environment, result->realName, 0, greaterLabel, 1 );
7896 }
7897 cpu_store_8bit( _environment, result->realName, 0 );
7898 cpu_jump( _environment, doneLabel );
7899 cpu_label( _environment, greaterLabel );
7900 cpu_store_8bit( _environment, result->realName, 255 );
7901 cpu_jump( _environment, doneLabel );
7902 cpu_label( _environment, doneLabel );
7903 break;
7904 }
7905 default:
7907 }
7908 break;
7909 default:
7911 }
7912 break;
7913 }
7914 return result;
7915}
7916
7917Variable * variable_greater_than_const( Environment * _environment, char * _source, int _destination, int _equal ) {
7918
7920
7921 Variable * source = variable_retrieve( _environment, _source );
7922
7923 Variable * result = variable_temporary( _environment, VT_SBYTE, "(result of compare)" );
7924 switch( VT_BITWIDTH( source->type ) ) {
7925 case 32:
7926 cpu_greater_than_32bit_const( _environment, source->realName, _destination, result->realName, _equal, VT_SIGNED( source->type ) );
7927 break;
7928 case 16:
7929 cpu_greater_than_16bit_const( _environment, source->realName, _destination, result->realName, _equal, VT_SIGNED( source->type ) );
7930 break;
7931 case 8:
7932 cpu_greater_than_8bit_const( _environment, source->realName, _destination, result->realName, _equal, VT_SIGNED( source->type ) );
7933 break;
7934 default:
7935 CRITICAL_CANNOT_COMPARE( DATATYPE_AS_STRING[source->type], "(const integer)" );
7936 break;
7937 }
7938 return result;
7939}
7940
7949/* <usermanual>
7950@keyword LEFT (function)
7951
7952@english
7953
7954The ''LEFT$'' function lets you extract a portion of characters from a string,
7955starting from the beginning. In other words, it lets you "cut" a string
7956from the left.
7957
7958You can get prefixes, codes, or any other initial part of a string, to
7959combine ''LEFT$'' with other functions to manipulate, format, and parse strings,
7960to use ''LEFT$'' to check the length or initial content of a string.
7961
7962The numbering of characters in a string always starts at 1. If the specified
7963number_of_characters is greater than the length of the string, ''LEFT$'' will
7964return the entire string.
7965
7966@italian
7967
7968La funzione ''LEFT$'' consente di estrarre una porzione di caratteri da
7969una stringa, partendo dall'inizio. In altre parole, consente di "tagliare"
7970una stringa da sinistra.
7971
7972È possibile ottenere prefissi, codici o qualsiasi altra parte iniziale di
7973una stringa, combinare ''LEFT$'' con altre funzioni per manipolare,
7974formattare e analizzare stringhe, utilizzare ''LEFT$'' per controllare
7975la lunghezza o il contenuto iniziale di una stringa.
7976
7977La numerazione dei caratteri in una stringa inizia sempre da 1. Se
7978il numero_di_caratteri specificato è maggiore della lunghezza della stringa,
7979''LEFT$'' restituirà l'intera stringa.
7980
7981@syntax = LEFT( text, position )
7982
7983@example x = LEFT( "TEST", 2 )
7984
7985@usedInExample strings_left_01.bas
7986
7987@seeAlso RIGHT (function)
7988@seeAlso RIGHT (instruction)
7989@seeAlso MID (function)
7990@seeAlso MID (instruction)
7991@seeAlso LEN
7992
7993 </usermanual> */
7994Variable * variable_string_left( Environment * _environment, char * _string, char * _position ) {
7995
7996 Variable * string = variable_retrieve( _environment, _string );
7997 Variable * position = variable_retrieve_or_define( _environment, _position, VT_BYTE, 0 );
7998 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of left)" );
7999 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of left)" );
8000 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of left)" );
8001
8002 cpu_dsfree( _environment, result->realName );
8003 cpu_dsalloc( _environment, position->realName, result->realName );
8004 cpu_dsdescriptor( _environment, result->realName, address->realName, size->realName );
8005
8006 switch( string->type ) {
8007 case VT_STRING: {
8008 Variable * temporary = variable_temporary( _environment, VT_DSTRING, "(temporary)");
8009 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of left)" );
8010 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of left)" );
8011 cpu_dsdefine( _environment, string->realName, temporary->realName );
8012 cpu_dsdescriptor( _environment, temporary->realName, address2->realName, size2->realName );
8013 cpu_mem_move( _environment, address2->realName, address->realName, size->realName );
8014 break;
8015 }
8016 case VT_DSTRING: {
8017 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of left)" );
8018 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of left)" );
8019 cpu_dsdescriptor( _environment, string->realName, address2->realName, size2->realName );
8020 cpu_mem_move( _environment, address2->realName, address->realName, size->realName );
8021 break;
8022 }
8023 default:
8025 break;
8026 }
8027 return result;
8028}
8029
8038/* <usermanual>
8039@keyword LEFT (instruction)
8040
8041@english
8042
8043The ''LEFT'' command replaces the leftmost characters in the
8044destination string with the equivalent characters from the given
8045strings. The command has two parameters.
8046
8047The first parameter is the string expression to change.
8048
8049The second parameter is a numeric expression, indicating how
8050many characters to replace. If 0, no characters will be replaced.
8051On the other hand, if greater than or equal to the number of characters
8052in string, the entire string is replaced, up to the characters in ''expression''.
8053If ''position'' is greater than lenght of ''expression'', only the
8054characters of ''expression'' will be replaced.
8055
8056@italian
8057
8058Il comando ''LEFT'' sostituisce i caratteri più a sinistra nella
8059stringa di destinazione con i caratteri equivalenti dalle stringhe
8060fornite. Il comando ha due parametri.
8061
8062Il primo parametro è l'espressione stringa da modificare.
8063
8064Il secondo parametro è un'espressione numerica che indica quanti
8065caratteri restituire. Se 0, viene restituita una stringa vuota (''""'').
8066D'altra parte, se è maggiore o uguale al numero di caratteri
8067nella stringa, viene restituita l'intera stringa, intatta.
8068
8069Per determinare il numero di caratteri nella stringa, dovresti
8070usare la funzione ''LEN''.
8071
8072@syntax LEFT( text, position ) = expression
8073
8074@example LEFT( x, 2 ) = "TE"
8075
8076@usedInExample strings_left_01.bas
8077
8078@seeAlso RIGHT (function)
8079@seeAlso RIGHT (instruction)
8080@seeAlso MID (function)
8081@seeAlso MID (instruction)
8082@seeAlso LEN
8083
8084 </usermanual> */
8085void variable_string_left_assign( Environment * _environment, char * _string, char * _position, char * _expression ) {
8086 Variable * string = variable_retrieve( _environment, _string );
8087 Variable * position = variable_retrieve_or_define( _environment, _position, VT_BYTE, 0 );
8088 Variable * expression = variable_cast( _environment, _expression, VT_DSTRING );
8089
8090 switch( string->type ) {
8091 case VT_STRING: {
8093 break;
8094 }
8095 case VT_DSTRING: {
8096
8097 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of left)" );
8098 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of left)" );
8099 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of left)" );
8100 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of left)" );
8101
8102 cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
8103
8104 cpu_dsdescriptor( _environment, expression->realName, address2->realName, size2->realName );
8105
8107
8108 char labelLesser[MAX_TEMPORARY_STORAGE]; sprintf( labelLesser, "%slesser", label );
8109 char labelDone[MAX_TEMPORARY_STORAGE]; sprintf( labelDone, "%sdone", label );
8110
8111 Variable * flag = variable_temporary( _environment, VT_BYTE, "(flag)" );
8112
8113 if ( _environment->leftReplace ) {
8114
8115 cpu_dswrite( _environment, string->realName );
8116
8117 cpu_less_than_8bit( _environment, size2->realName, position->realName, flag->realName, 0, 0 );
8118 cpu_compare_and_branch_8bit_const( _environment, flag->realName, 0xff, labelLesser, 1 );
8119 cpu_mem_move( _environment, address2->realName, address->realName, position->realName );
8120 cpu_jump( _environment, labelDone );
8121 cpu_label( _environment, labelLesser );
8122 cpu_mem_move( _environment, address2->realName, address->realName, size2->realName );
8123 cpu_label( _environment, labelDone );
8124
8125 } else {
8126
8127 Variable * left = variable_string_left( _environment, expression->name, position->name );
8128 Variable * right = variable_string_mid( _environment, string->name, variable_add_const( _environment, position->name, 1 )->name, NULL );
8129 variable_move( _environment, variable_add( _environment, left->name, right->name )->name, string->name );
8130
8131 }
8132 break;
8133 }
8134 default:
8136 break;
8137 }
8138}
8139
8148/* <usermanual>
8149@keyword RIGHT (function)
8150
8151@english
8152
8153The ''RIGHT'' function returns a (dynamic) string containing a specified
8154number of characters, from the right side of a given string. The function
8155has two parameters.
8156
8157The first parameter is the string expression from which the
8158rightmost characters are returned. If string is empty, an empty string is
8159returned.
8160
8161The second parameter is a numeric expression, indicating how
8162many characters to return. If 0, an empty string (''""'') is returned.
8163On the other hand, if greater than or equal to the number of characters
8164in string, the entire string is returned, untouched.
8165
8166To determine the number of characters in string, you should use
8167the ''LEN'' function.
8168
8169@italian
8170
8171La funzione ''RIGHT'' restituisce una stringa (dinamica) contenente un
8172numero specificato di caratteri, dal lato destro di una determinata
8173stringa. La funzione ha due parametri.
8174
8175Il primo parametro è l'espressione stringa da cui vengono restituiti
8176i caratteri più a destra. Se la stringa è vuota, viene restituita
8177una stringa vuota.
8178
8179Il secondo parametro è un'espressione numerica, che indica quanti
8180caratteri restituire. Se 0, viene restituita una stringa vuota (''""'').
8181D'altra parte, se maggiore o uguale al numero di caratteri nella stringa,
8182viene restituita l'intera stringa, intatta.
8183
8184Per determinare il numero di caratteri in una stringa, è necessario
8185utilizzare la funzione ''LEN''.
8186
8187@syntax = RIGHT( text, position )
8188
8189@example x = RIGHT( "TEST", 2 )
8190
8191@usedInExample strings_right_01.bas
8192
8193@seeAlso RIGHT (instruction)
8194@seeAlso LEFT (function)
8195@seeAlso LEFT (instruction)
8196@seeAlso MID (function)
8197@seeAlso MID (instruction)
8198@seeAlso LEN
8199
8200</usermanual> */
8201Variable * variable_string_right( Environment * _environment, char * _string, char * _position ) {
8202 Variable * string = variable_retrieve( _environment, _string );
8203 Variable * position = variable_retrieve_or_define( _environment, _position, VT_BYTE, 0 );
8204 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of right)" );
8205
8206 switch( string->type ) {
8207 case VT_STRING: {
8208 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of right)" );
8209 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of right)" );
8210 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of right)" );
8211 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of right)" );
8212 cpu_move_8bit( _environment, string->realName, size->realName );
8213 cpu_addressof_16bit( _environment, string->realName, address->realName );
8214 cpu_inc_16bit( _environment, address->realName );
8215 cpu_move_8bit( _environment, position->realName, size2->realName );
8216 cpu_dsfree( _environment, result->realName );
8217 cpu_dsalloc( _environment, size2->realName, result->realName );
8218 cpu_dsdescriptor( _environment, result->realName, address2->realName, size2->realName );
8219 cpu_math_add_16bit_with_8bit( _environment, address->realName, size->realName, address->realName );
8220 cpu_math_sub_16bit_with_8bit( _environment, address->realName, position->realName, address->realName );
8221 cpu_mem_move( _environment, address->realName, address2->realName, size2->realName );
8222 break;
8223 }
8224 case VT_DSTRING: {
8225 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of right)" );
8226 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of right)" );
8227 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of right)" );
8228 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of right)" );
8229 cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
8230 cpu_move_8bit( _environment, position->realName, size2->realName );
8231 cpu_dsfree( _environment, result->realName );
8232 cpu_dsalloc( _environment, size2->realName, result->realName );
8233 cpu_dsdescriptor( _environment, result->realName, address2->realName, size2->realName );
8234 cpu_math_add_16bit_with_8bit( _environment, address->realName, size->realName, address->realName );
8235 cpu_math_sub_16bit_with_8bit( _environment, address->realName, position->realName, address->realName );
8236 cpu_mem_move( _environment, address->realName, address2->realName, size2->realName );
8237 break;
8238 }
8239 case VT_IMAGE:
8240 case VT_IMAGES:
8241 case VT_SEQUENCE:
8242 case VT_MUSIC:
8243 case VT_BUFFER:
8244 case VT_TYPE:
8245 default:
8247 break;
8248 }
8249 return result;
8250}
8251
8260/* <usermanual>
8261@keyword RIGHT (instruction)
8262
8263@english
8264
8265The ''RIGHT'' command replaces the rightmost characters in the
8266destination string with the equivalent characters from the given
8267strings. The command has two parameters.
8268
8269The first parameter is the string expression to change.
8270
8271The second parameter is a numeric expression, indicating how
8272many characters to return. If 0, an empty string (''""'') is returned.
8273On the other hand, if greater than or equal to the number of characters
8274in string, the entire string is returned, untouched.
8275
8276To determine the number of characters in string, you should use
8277the ''LEN'' function.
8278
8279@italian
8280
8281Il comando ''RIGHT'' sostituisce i caratteri più a destra nella stringa
8282di destinazione con i caratteri equivalenti dalle stringhe fornite.
8283Il comando ha due parametri.
8284
8285Il primo parametro è l'espressione stringa da modificare.
8286
8287Il secondo parametro è un'espressione numerica che indica quanti caratteri
8288restituire. Se 0, viene restituita una stringa vuota (''""'').
8289
8290D'altra parte, se è maggiore o uguale al numero di caratteri nella stringa,
8291viene restituita l'intera stringa, intatta.
8292
8293Per determinare il numero di caratteri nella stringa, dovresti usare la funzione ''LEN''.
8294
8295@syntax RIGHT(text,position) = expression
8296
8297@example RIGHT( "TEST", 2 ) = "AM"
8298
8299@seeAlso RIGHT (function)
8300@seeAlso LEFT (function)
8301@seeAlso LEFT (instruction)
8302@seeAlso MID (function)
8303@seeAlso MID (instruction)
8304@seeAlso LEN
8305
8306 </usermanual> */
8307void variable_string_right_assign( Environment * _environment, char * _string, char * _position, char * _expression ) {
8308 Variable * string = variable_retrieve( _environment, _string );
8309 Variable * position = variable_retrieve_or_define( _environment, _position, VT_BYTE, 0 );
8310 Variable * expression = variable_cast( _environment, _expression, VT_DSTRING );
8311 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of right)" );
8312 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of right)" );
8313 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of right)" );
8314 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of right)" );
8315
8316 switch( string->type ) {
8317 case VT_DSTRING: {
8318 cpu_dswrite( _environment, string->realName );
8319 cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
8320 cpu_dsdescriptor( _environment, expression->realName, address2->realName, size2->realName );
8321 cpu_move_8bit( _environment, size->realName, size2->realName );
8322 cpu_math_sub_8bit( _environment, size2->realName, position->realName, size2->realName );
8323 cpu_math_add_16bit_with_8bit( _environment, address->realName, size->realName, address->realName );
8324 cpu_math_sub_16bit_with_8bit( _environment, address->realName, position->realName, address->realName );
8325 cpu_mem_move( _environment, address2->realName, address->realName, size2->realName );
8326 break;
8327 }
8328 default:
8330 break;
8331 }
8332}
8333
8343/* <usermanual>
8344@keyword MID (function)
8345
8346@english
8347
8348The ''MID'' function returns a (dynamic) string containing a specified number
8349of characters from a string. It has three parameters.
8350
8351The first parameter is the string expression from which characters are returned.
8352If string is empty, an empty string is returned.
8353
8354The second parameter is the character position in string at which the part to
8355be taken begins. If start is greater than the number of characters in string,
8356''MID'' returns a zero-length string ("").
8357
8358The third parameter is optional, and gives the number of characters to return.
8359If omitted or if there are fewer than length characters in the text (including
8360the character at start), all characters from the start position to the end of the
8361string are returned.
8362
8363@italian
8364
8365La funzione ''MID'' restituisce una stringa (dinamica) contenente un numero
8366specificato di caratteri da una stringa. Ha tre parametri.
8367
8368Il primo parametro è l'espressione stringa da cui vengono restituiti i
8369caratteri. Se la stringa è vuota, viene restituita una stringa vuota.
8370
8371Il secondo parametro è la posizione del carattere nella stringa in cui inizia
8372la parte da riprendere. Se tale parametro è maggiore del numero di caratteri
8373nella stringa, ''MID'' restituisce una stringa di lunghezza zero ("").
8374
8375Il terzo parametro è facoltativo e fornisce il numero di caratteri da
8376restituire. Se omesso o se nel testo sono presenti meno caratteri della
8377lunghezza (incluso il carattere iniziale), vengono restituiti tutti i
8378caratteri dalla posizione iniziale alla fine della stringa.
8379
8380@syntax = MID( text, position[, len] )
8381
8382@example x = MID( "TEST", 2 ): ' x = "TE"
8383@example y = MID( "TEST", 2, 1 ): ' y = "T"
8384
8385@usedInExample strings_mid_01.bas
8386
8387@seeAlso LEFT (function)
8388@seeAlso LEFT (instruction)
8389@seeAlso MID (instruction)
8390@seeAlso RIGHT (function)
8391@seeAlso RIGHT (instruction)
8392@seeAlso LEN
8393
8394@target all
8395@verified
8396 </usermanual> */
8397Variable * variable_string_mid( Environment * _environment, char * _string, char * _position, char * _len ) {
8398 Variable * string = variable_retrieve( _environment, _string );
8399 Variable * position = variable_retrieve_or_define( _environment, _position, VT_BYTE, 0 );
8400 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of mid)" );
8401 Variable * len;
8402 Variable * copyofLen = variable_temporary( _environment, VT_BYTE, "(copy of len)" );
8403
8405
8406 char emptyResultLabel[MAX_TEMPORARY_STORAGE]; sprintf( emptyResultLabel, "%sempty", label );
8407
8408 cpu_compare_and_branch_8bit_const( _environment, position->realName, 0, emptyResultLabel, 1 );
8409
8410 switch( string->type ) {
8411 case VT_STRING: {
8412 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of mid)" );
8413 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of mid)" );
8414 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of mid)" );
8415 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of mid)" );
8416 cpu_move_8bit( _environment, string->realName, size->realName );
8417
8418 if ( _len ) {
8419 len = variable_retrieve_or_define( _environment, _len, VT_BYTE, 0 );
8420 cpu_move_8bit( _environment, len->realName, copyofLen->realName );
8421 } else {
8422 cpu_move_8bit( _environment, size->realName, copyofLen->realName );
8423 }
8424
8425 Variable * temp = variable_temporary( _environment, VT_BYTE, "(checker)");
8426 cpu_move_8bit( _environment, copyofLen->realName, temp->realName );
8427 cpu_math_add_8bit( _environment, position->realName, temp->realName, temp->realName );
8428 cpu_greater_than_8bit( _environment, temp->realName, size->realName, temp->realName, 0, 0 );
8429
8430 char unlimitedLenLabel[MAX_TEMPORARY_STORAGE]; sprintf( unlimitedLenLabel, "%sunlim", label );
8431 cpu_compare_and_branch_8bit_const( _environment, temp->realName, 0, unlimitedLenLabel, 1 );
8432 cpu_move_8bit( _environment, size->realName, temp->realName );
8433 cpu_math_sub_8bit( _environment, temp->realName, position->realName, copyofLen->realName );
8434 cpu_inc( _environment, copyofLen->realName );
8435 cpu_label( _environment, unlimitedLenLabel );
8436
8437 cpu_greater_than_8bit( _environment, position->realName, size->realName, size2->realName, 0, 0 );
8438 cpu_compare_and_branch_8bit_const( _environment, size2->realName, (unsigned char) 0xff, emptyResultLabel, 1 );
8439
8440 cpu_addressof_16bit( _environment, string->realName, address->realName );
8441 cpu_inc_16bit( _environment, address->realName );
8442 cpu_math_add_16bit_with_8bit( _environment, address->realName, position->realName, address->realName );
8443 cpu_dec_16bit( _environment, address->realName );
8444
8445 cpu_dsfree( _environment, result->realName );
8446 cpu_dsalloc( _environment, copyofLen->realName, result->realName );
8447 cpu_dsdescriptor( _environment, result->realName, address2->realName, size2->realName );
8448 cpu_mem_move( _environment, address->realName, address2->realName, copyofLen->realName );
8449
8450 break;
8451 }
8452 case VT_DSTRING: {
8453
8454 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of mid)" );
8455 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of mid)" );
8456 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of mid)" );
8457 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of mid)" );
8458 cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
8459
8460 cpu_greater_than_8bit( _environment, position->realName, size->realName, size2->realName, 0, 0 );
8461 cpu_compare_and_branch_8bit_const( _environment, size2->realName, 0, emptyResultLabel, 0 );
8462
8463 cpu_math_add_16bit_with_8bit( _environment, address->realName, position->realName, address->realName );
8464 cpu_dec_16bit( _environment, address->realName );
8465
8466 if ( _len ) {
8467 len = variable_retrieve_or_define( _environment, _len, VT_BYTE, 0 );
8468 cpu_move_8bit( _environment, len->realName, copyofLen->realName );
8469 Variable * temp = variable_temporary( _environment, VT_BYTE, "(checker)");
8470 cpu_move_8bit( _environment, len->realName, temp->realName );
8471 cpu_math_add_8bit( _environment, position->realName, temp->realName, temp->realName );
8472 cpu_greater_than_8bit( _environment, temp->realName, size->realName, temp->realName, 0, 0 );
8473 char unlimitedLenLabel[MAX_TEMPORARY_STORAGE]; sprintf( unlimitedLenLabel, "%sunlim", label );
8474 cpu_compare_and_branch_8bit_const( _environment, temp->realName, 0, unlimitedLenLabel, 1 );
8475 cpu_move_8bit( _environment, size->realName, temp->realName );
8476 cpu_math_sub_8bit( _environment, temp->realName, position->realName, copyofLen->realName );
8477 cpu_inc( _environment, copyofLen->realName );
8478 cpu_label( _environment, unlimitedLenLabel );
8479 } else {
8480 cpu_move_8bit( _environment, size->realName, copyofLen->realName );
8481 cpu_math_sub_8bit( _environment, copyofLen->realName, position->realName, copyofLen->realName );
8482 cpu_inc( _environment, copyofLen->realName );
8483 }
8484
8485 cpu_greater_than_8bit( _environment, position->realName, size->realName, size2->realName, 0, 0 );
8486 cpu_compare_and_branch_8bit_const( _environment, size2->realName, (unsigned char) 0xff, emptyResultLabel, 1 );
8487
8488 cpu_dsfree( _environment, result->realName );
8489 cpu_dsalloc( _environment, copyofLen->realName, result->realName );
8490 cpu_dsdescriptor( _environment, result->realName, address2->realName, size2->realName );
8491 cpu_mem_move( _environment, address->realName, address2->realName, copyofLen->realName );
8492 break;
8493 }
8494 default:
8496 break;
8497 }
8498
8499 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneLabel, "%sdone", label );
8500
8501 cpu_jump( _environment, doneLabel );
8502
8503 cpu_label( _environment, emptyResultLabel );
8504
8505 cpu_dsfree( _environment, result->realName );
8506 cpu_dsalloc_size( _environment, 0, result->realName );
8507
8508 cpu_label( _environment, doneLabel );
8509
8510 return result;
8511}
8512
8522/* <usermanual>
8523@keyword SUBSTRING (function)
8524
8525@english
8526
8527The ''SUBSTRING'' allows you to extract a specific portion of a text string
8528(i.e. a sequence of characters). The first parameter, ''string'', is
8529the entire text from which you want to extract the substring. The starting position
8530is given by ''start'' and the ending position is given by ''end''.
8531If you try to extract a substring that is longer than the original string,
8532the original string is retrieved. Moreover, if the start position is after
8533the ending position, an empty string will be returned.
8534
8535There are many applications for ''SUBSTRING'': you can extract keywords, titles,
8536authors from documents, change the appearance of a text, for example by extracting
8537only the initials of a name, check whether a string contains a specific substring,
8538such as whether a zip code is formatted correctly and, finally, concatenate multiple
8539substrings to create new strings.
8540
8541@italian
8542
8543''SUBSTRING'' consente di estrarre una porzione specifica di una stringa di testo
8544(ad esempio una sequenza di caratteri). Il primo parametro, ''string'', è l'intero
8545testo da cui si desidera estrarre la sottostringa. La posizione iniziale è data da
8546''start'' e la posizione finale è data da ''end''. Se si tenta di estrarre una
8547sottostringa più lunga della stringa originale, viene recuperata la stringa originale.
8548Inoltre, se la posizione di partenza è successiva alla posizione di arrivo, verrà
8549restituita una stringa vuota.
8550
8551Esistono molte applicazioni per ''SUBSTRING'': è possibile estrarre parole chiave,
8552titoli, autori da documenti, modificare l'aspetto di un testo, ad esempio estraendo
8553solo le iniziali di un nome, verificare se una stringa contiene una sottostringa
8554specifica, ad esempio se un codice postale è formattato correttamente e, infine,
8555concatenare più sottostringhe per creare nuove stringhe.
8556
8557@syntax = SUBSTRING( text, start, end )
8558
8559@example x = SUBSTRING( "TEST", 2, 3 )
8560
8561@seeAlso MID (function)
8562
8563@target all
8564@verified
8565 </usermanual> */
8566Variable * variable_string_substring( Environment * _environment, char * _string, char * _start, char * _end ) {
8567
8568 Variable * start = variable_retrieve_or_define( _environment, _start, VT_BYTE, 0 );
8569 Variable * len = NULL;
8570 if ( _end ) {
8571 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result)");
8572
8573 Variable * end = variable_retrieve_or_define( _environment, _end, VT_BYTE, 0 );
8574 Variable * lessThanStart = variable_less_than( _environment, end->name, start->name, 0 );
8575
8577
8578 char lessThanLabel[MAX_TEMPORARY_STORAGE];
8579 sprintf( lessThanLabel, "%slessthan", label );
8580
8581 cpu_compare_and_branch_8bit_const( _environment, lessThanStart->realName, 0xff, lessThanLabel, 1 );
8582 len = variable_sub( _environment, end->name, start->name );
8583 cpu_inc( _environment, len->realName );
8584 variable_move( _environment, variable_string_mid( _environment, _string, start->name, len->name )->name, result->name );
8585 cpu_jump( _environment, label );
8586 cpu_label( _environment, lessThanLabel );
8587 variable_store_string( _environment, result->name, "" );
8588 cpu_label( _environment, label );
8589
8590 return result;
8591 } else {
8592 return variable_string_mid( _environment, _string, start->name, NULL );
8593 }
8594
8595}
8596
8606/* <usermanual>
8607@keyword MID (instruction)
8608
8609@english
8610
8611The ''MID'' statement allows to change a (dynamic) string containing a specified number
8612of characters from a string. It has three parameters.
8613
8614The first parameter is the string expression to modify.
8615
8616The second parameter is the character position in string at which the part to
8617be taken begins. If start is greater than the number of characters in string,
8618''MID'' replace at the end of the string.
8619
8620The third parameter is optional, and gives the number of characters to replace.
8621If omitted or if there are fewer than length characters in the text (including
8622the character at start), all characters from the start position to the end of the
8623string are replaced.
8624
8625@italian
8626
8627L'istruzione ''MID'' consente di modificare una stringa (dinamica) contenente
8628un numero specificato di caratteri da una stringa. Ha tre parametri.
8629
8630Il primo parametro è l'espressione stringa da modificare.
8631
8632Il secondo parametro è la posizione del carattere nella stringa in cui inizia
8633la parte da riprendere. Se inizio è maggiore del numero di caratteri nella stringa,
8634''MID'' sostituisce alla fine della stringa.
8635
8636Il terzo parametro è facoltativo e fornisce il numero di caratteri da sostituire.
8637Se omesso o se nel testo sono presenti meno caratteri della lunghezza (incluso il
8638carattere iniziale), tutti i caratteri dalla posizione iniziale alla fine della
8639stringa vengono sostituiti.
8640
8641@syntax MID( string, pos[, len] ) = value
8642
8643@example a$ = "PUNTO": MID( a$, 1, 3 ) = "PON": PRINT a$: REM prints "PONTO"
8644
8645@usedInExample strings_mid_01.bas
8646
8647@seeAlso LEFT (function)
8648@seeAlso LEFT (instruction)
8649@seeAlso MID (function)
8650@seeAlso RIGHT (function)
8651@seeAlso RIGHT (instruction)
8652@seeAlso LEN
8653
8654@target all
8655@verified
8656 </usermanual> */
8657void variable_string_mid_assign( Environment * _environment, char * _string, char * _position, char * _len, char * _expression ) {
8658 Variable * string = variable_retrieve( _environment, _string );
8659 Variable * position = variable_retrieve_or_define( _environment, _position, VT_BYTE, 0 );
8660 Variable * expression = variable_cast( _environment, _expression, VT_DSTRING );
8661 Variable * len;
8662 if ( _len ) {
8663 len = variable_retrieve_or_define( _environment, _len, VT_BYTE, 0 );
8664 } else {
8665 len = variable_temporary( _environment, VT_BYTE, "(calculated MID len)");
8666 variable_store( _environment, len->name, 0 );
8667 }
8668 switch( string->type ) {
8669 case VT_STRING: {
8671 }
8672 case VT_DSTRING: {
8673 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of mid)" );
8674 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of mid)" );
8675 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of mid)" );
8676 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of mid)" );
8677
8678 cpu_dswrite( _environment, string->realName );
8679 cpu_dsdescriptor( _environment, string->realName, address2->realName, size2->realName );
8680 cpu_dsdescriptor( _environment, expression->realName, address->realName, size->realName );
8681
8682 if ( _len ) {
8683
8684 } else {
8685 cpu_move_8bit( _environment, size->realName, len->realName );
8686 // cpu_math_sub_8bit( _environment, len->realName, position->realName, len->realName );
8687 }
8688
8690
8691 char emptyLabel[MAX_TEMPORARY_STORAGE]; sprintf( emptyLabel, "%sempty", label );
8692 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneLabel, "%sdone", label );
8693
8694 Variable * flag = variable_temporary( _environment, VT_BYTE, "(flag for resizing)");
8695 cpu_less_than_8bit( _environment, size2->realName, len->realName, flag->realName, 1, 0 );
8696 if ( _environment->midReplace ) {
8697 cpu_bveq( _environment, flag->realName, doneLabel );
8698 } else {
8699 cpu_bveq( _environment, flag->realName, emptyLabel );
8700 }
8701
8702 Variable * tmp = variable_temporary( _environment, VT_DSTRING, "(tmp)");
8703 Variable * addressTmp = variable_temporary( _environment, VT_ADDRESS, "(result of mid)" );
8704 Variable * sizeTmp = variable_temporary( _environment, VT_BYTE, "(result of mid)" );
8705
8706 cpu_dsalloc( _environment, len->realName, tmp->realName );
8707 cpu_dsdescriptor( _environment, tmp->realName, addressTmp->realName, sizeTmp->realName );
8708 cpu_mem_move( _environment, address2->realName, addressTmp->realName, size2->realName );
8709 cpu_dsfree( _environment, string->realName );
8710 cpu_move_8bit( _environment, tmp->realName, string->realName );
8711 cpu_dsdescriptor( _environment, string->realName, address2->realName, size2->realName );
8712
8713 cpu_label( _environment, emptyLabel );
8714
8715 cpu_math_add_16bit_with_8bit( _environment, address2->realName, position->realName, address2->realName );
8716 cpu_dec_16bit( _environment, address2->realName );
8717
8718 cpu_mem_move( _environment, address->realName, address2->realName, len->realName );
8719
8720 cpu_label( _environment, doneLabel );
8721
8722 break;
8723 }
8724 default:
8726 break;
8727 }
8728}
8729
8739/* <usermanual>
8740@keyword INSTR
8741
8742@english
8743
8744This function can be called to search through strings for individual characters or sub-strings:
8745it allows you to search for all instances of one string inside another. The string is searched
8746for the first occurrence of the second strings. If it is found, its location will be reported
8747in the form of the number of characters from the left-hand side of the searched string.
8748If the search is unsuccessful, a result of zero will be given.
8749
8750Normally, the search will begin from the first character at the extreme left-hand side of the
8751host string, but you can specify an (optional) number of characters from the beginning of the
8752searched string. The optional start-of-search position can range from one to the maximum
8753number of characters in the searched string to be searched.
8754
8755@italian
8756
8757Questa funzione può essere chiamata per cercare nelle stringhe singoli caratteri o sottostringhe:
8758permette di cercare tutte le istanze di una stringa all'interno di un'altra.
8759La stringa viene ricercata per la prima occorrenza della seconda stringa. Se viene trovato,
8760la sua posizione verrà riportata sotto forma di numero di caratteri dall'inizio della
8761stringa cercata. Se la ricerca ha esito negativo, verrà fornito un risultato pari a zero.
8762
8763Normalmente, la ricerca inizierà dal primo carattere all'estrema sinistra della stringa host,
8764ma è possibile specificare un numero (facoltativo) di caratteri dall'inizio della stringa
8765cercata. La posizione di inizio ricerca opzionale può variare da uno al massimo
8766numero di caratteri nella stringa da cercare.
8767
8768@syntax = INSTR( text, searched [, start] )
8769
8770@example x = INSTR( "ugBASIC", "A" )
8771@example x = INSTR( "ugBASIC", "A", 2 )
8772
8773@usedInExample strings_instr_01.bas
8774@usedInExample strings_instr_02.bas
8775
8776@alias PLACE
8777</usermanual> */
8778
8779/* <usermanual>
8780@keyword PLACE
8781
8782@english
8783
8784@italian
8785
8786@syntax = PLACE( text, searched [, start] )
8787
8788@example x = PLACE( "ugBASIC", "A" )
8789@example x = PLACE( "ugBASIC", "A", 2 )
8790
8791@alias INSTR
8792</usermanual> */
8793
8794
8795Variable * variable_string_instr( Environment * _environment, char * _search, char * _searched, char * _start ) {
8796 Variable * search = variable_retrieve( _environment, _search );
8797 Variable * searched = variable_retrieve( _environment, _searched );
8798 Variable * start = NULL;
8799 if ( _start ) {
8800 start = variable_retrieve_or_define( _environment, _start, VT_BYTE, 0 );
8801 variable_decrement( _environment, start->name );
8802 }
8803 Variable * result = variable_temporary( _environment, VT_BYTE, "(result of INSTR)" );
8804
8805 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of INSTR)" );
8806 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of INSTR)" );
8807 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of INSTR)" );
8808 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of INSTR)" );
8809
8810 switch( search->type ) {
8811 case VT_STRING:
8812 cpu_move_8bit( _environment, search->realName, size->realName );
8813 cpu_addressof_16bit( _environment, search->realName, address->realName );
8814 cpu_inc_16bit( _environment, address->realName );
8815 break;
8816 case VT_DSTRING:
8817 cpu_dsdescriptor( _environment, search->realName, address->realName, size->realName );
8818 break;
8819 default:
8821 }
8822 switch( searched->type ) {
8823 case VT_STRING:
8824 cpu_move_8bit( _environment, searched->realName, size2->realName );
8825 cpu_addressof_16bit( _environment, searched->realName, address2->realName );
8826 cpu_inc_16bit( _environment, address2->realName );
8827 break;
8828 case VT_DSTRING:
8829 cpu_dsdescriptor( _environment, searched->realName, address2->realName, size2->realName );
8830 break;
8831 default:
8832 CRITICAL_INSTR_UNSUPPORTED( _searched, DATATYPE_AS_STRING[searched->type]);
8833 }
8834
8836
8837 Variable * found = variable_temporary( _environment, VT_BYTE, "(found flag)" );
8838
8839 char repeatLabel[MAX_TEMPORARY_STORAGE]; sprintf( repeatLabel, "%srep", label );
8840 char foundLabel[MAX_TEMPORARY_STORAGE]; sprintf( foundLabel, "%sfnd", label );
8841 char notFoundLabel[MAX_TEMPORARY_STORAGE]; sprintf( notFoundLabel, "%snfnd", label );
8842
8843 if ( start ) {
8844 cpu_math_add_16bit_with_8bit( _environment, address->realName, start->realName, address->realName );
8845 cpu_move_8bit( _environment, start->realName, result->realName );
8846 } else {
8847 cpu_store_8bit( _environment, result->realName, 0 );
8848 }
8849
8850 cpu_label( _environment, repeatLabel );
8851
8852 cpu_compare_8bit( _environment, result->realName, size->realName, found->realName, 1 );
8853
8854 cpu_bvneq( _environment, found->realName, notFoundLabel );
8855
8856 cpu_compare_memory( _environment, address->realName, address2->realName, size2->realName, found->realName, 1 );
8857
8858 cpu_inc_16bit( _environment, address->realName );
8859 cpu_inc( _environment, result->realName );
8860
8861 cpu_bvneq( _environment, found->realName, foundLabel );
8862
8863 cpu_jump( _environment, repeatLabel );
8864
8865 cpu_label( _environment, notFoundLabel );
8866 cpu_store_8bit( _environment, result->realName, 0 );
8867
8868 cpu_label( _environment, foundLabel );
8869
8870 return result;
8871}
8872
8880/* <usermanual>
8881@keyword LOWER
8882
8883@english
8884
8885The ''LOWER'' function converts all uppercase characters in a string to lowercase.
8886In other words, it takes a string as input and returns a new string that is
8887identical to the first, but with all the letters lowercase.
8888
8889The ''LOWER'' function examines each character in the input string. If the
8890character is an uppercase letter, it is converted to its lowercase equivalent.
8891All other characters (numbers, symbols, spaces) remain unchanged.
8892
8893Before comparing or searching strings, it is often useful to convert all
8894strings to lowercase or uppercase to avoid case-sensitive problems.
8895It can be used to make user input less case-sensitive, such as to check
8896whether a keyword was entered correctly regardless of case. To perform search
8897and replace, text parsing, and other string manipulation, the ''LOWER''
8898command is ideal.
8899
8900@italian
8901
8902La funzione ''LOWER'' converte tutti i caratteri maiuscoli in una stringa
8903in minuscoli. In altre parole, accetta una stringa come input e restituisce
8904una nuova stringa identica alla prima, ma con tutte le lettere minuscole.
8905
8906La funzione ''LOWER'' esamina ogni carattere nella stringa di input. Se
8907il carattere è una lettera maiuscola, viene convertito nel suo equivalente
8908minuscolo. Tutti gli altri caratteri (numeri, simboli, spazi) rimangono invariati.
8909
8910Prima di confrontare o cercare stringhe, è spesso utile convertire tutte le
8911stringhe in minuscolo o maiuscolo per evitare problemi di distinzione tra
8912maiuscole e minuscole. Può essere utilizzato per rendere l'input dell'utente
8913meno sensibile alle maiuscole e minuscole, ad esempio per verificare
8914se una parola chiave è stata immessa correttamente indipendentemente dalle
8915maiuscole e dalle minuscole. Per eseguire la ricerca e la sostituzione,
8916l'analisi del testo e altre manipolazioni di stringhe, il comando ''LOWER''
8917è l'ideale.
8918
8919@syntax = LOWER( text )
8920
8921@example x = LOWER( "ugBASIC" )
8922
8923@usedInExample strings_cases_01.bas
8924
8925@alias LCASE
8926
8927 </usermanual> */
8928
8929 /* <usermanual>
8930@keyword LCASE
8931
8932@english
8933
8934@italian
8935
8936@syntax = LCASE( text )
8937
8938@example x = LCASE( "ugBASIC" )
8939
8940@alias LOWER
8941
8942 </usermanual> */
8943
8944Variable * variable_string_lower( Environment * _environment, char * _string ) {
8945 Variable * string = variable_retrieve( _environment, _string );
8946 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of LOWER)" );
8947
8948 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of LOWER)" );
8949 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of LOWER)" );
8950 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of LOWER)" );
8951 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of LOWER)" );
8952
8953 switch( string->type ) {
8954 case VT_STRING:
8955 cpu_move_8bit( _environment, string->realName, size->realName );
8956 cpu_addressof_16bit( _environment, string->realName, address->realName );
8957 cpu_inc_16bit( _environment, address->realName );
8958 break;
8959 case VT_DSTRING:
8960 cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
8961 break;
8962 default:
8964 }
8965
8966 cpu_dsfree( _environment, result->realName );
8967 cpu_dsalloc( _environment, size->realName, result->realName );
8968 cpu_dsdescriptor( _environment, result->realName, address2->realName, size2->realName );
8969
8971
8972 cpu_lowercase( _environment, address->realName, size->realName, address2->realName );
8973
8974 return result;
8975
8976}
8977
8985/* <usermanual>
8986@keyword UPPER
8987
8988@english
8989
8990The UPPER command (short for "Upper Case") is a function that converts all lowercase
8991letters in a string to uppercase. In other words, it takes any string and returns a
8992new string that is identical to the first, but with all letters in uppercase.
8993
8994If you want to compare two strings without regard to case, you can convert both
8995strings to uppercase before performing the comparison. You can use this command
8996to standardize user input, for example to ensure that all names are uppercase.
8997You can use it to make the output more readable or to conform to specific
8998formatting conventions.
8999
9000@italian
9001
9002Il comando ''UPPER'' (abbreviazione di "Upper Case") è una funzione che converte
9003tutte le lettere minuscole in una stringa in maiuscolo. In altre parole, prende
9004una stringa qualsiasi e restituisce una nuova stringa identica alla prima, ma
9005con tutte le lettere in maiuscolo.
9006
9007Se vuoi confrontare due stringhe senza considerare le maiuscole e le minuscole,
9008puoi convertire entrambe le stringhe in maiuscolo prima di eseguire il confronto.
9009Puoi usare questo comando per standardizzare l'input dell'utente, ad esempio per
9010assicurarti che tutti i nomi siano in maiuscolo.
9011
9012Puoi usarlo per rendere l'output più leggibile o per conformarti a specifiche
9013convenzioni di formattazione.
9014
9015@syntax = UPPER(text)
9016
9017@example x = UPPER( "ugBASIC" )
9018@usedInExample strings_cases_01.bas
9019
9020@alias UCASE
9021
9022 </usermanual> */
9023 /* <usermanual>
9024@keyword UCASE
9025
9026@english
9027
9028@italian
9029
9030@syntax = UCASE(text)
9031
9032@example x = UCASE( "ugBASIC" )
9033
9034@usedInExample strings_cases_01.bas
9035
9036@alias UPPER
9037
9038 </usermanual> */
9039Variable * variable_string_upper( Environment * _environment, char * _string ) {
9040 Variable * string = variable_retrieve( _environment, _string );
9041 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of LOWER)" );
9042
9043 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of LOWER)" );
9044 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of LOWER)" );
9045 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of LOWER)" );
9046 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of LOWER)" );
9047
9048 switch( string->type ) {
9049 case VT_STRING:
9050 cpu_move_8bit( _environment, string->realName, size->realName );
9051 cpu_addressof_16bit( _environment, string->realName, address->realName );
9052 cpu_inc_16bit( _environment, address->realName );
9053 break;
9054 case VT_DSTRING:
9055 cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
9056 break;
9057 default:
9059 }
9060
9061 cpu_dsfree( _environment, result->realName );
9062 cpu_dsalloc( _environment, size->realName, result->realName );
9063 cpu_dsdescriptor( _environment, result->realName, address2->realName, size2->realName );
9064
9066
9067 cpu_uppercase( _environment, address->realName, size->realName, address2->realName );
9068
9069 return result;
9070
9071}
9072
9080/* <usermanual>
9081@keyword STR
9082
9083@english
9084This function converts numbers into strings. This can be used to overcome some
9085limitations posed by functions which does not accept numbers as parameters,
9086but will work happily with parameters in the form of strings.
9087Also, when string adding is performed, all operand must be strings,
9088so this function is really useful.
9089
9090@italian
9091Questa funzione converte i numeri in stringhe. Può essere usata per superare
9092alcune limitazioni poste dalle funzioni che non accettano numeri come parametri,
9093ma che funzionano bene con parametri sotto forma di stringhe. Inoltre, quando
9094viene eseguita l'aggiunta di stringhe, tutti gli operandi devono essere stringhe,
9095quindi questa funzione è davvero utile.
9096
9097@syntax = STR(number)
9098
9099@example x = STR(42)
9100
9101@usedInExample strings_str_01.bas
9102
9103</usermanual> */
9104Variable * variable_string_str( Environment * _environment, char * _value ) {
9105 Variable * value = variable_retrieve( _environment, _value );
9106 Variable * dword = variable_temporary( _environment, VT_DWORD, "(bcd result of STR)" );
9107 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of STR)" );
9108 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of STR)" );
9109 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of STR)" );
9110
9111 switch( VT_BITWIDTH( value->type ) ) {
9112 case 1:
9113 case 0:
9114 switch( value->type ) {
9115 case VT_DOJOKA: {
9116 Variable * dojokaHandle = variable_temporary( _environment, VT_DWORD, "(dojoka)");
9117 cpu_mem_move_direct_size( _environment, value->realName, dojokaHandle->realName, 4 );
9118 #if CPU_BIG_ENDIAN
9119 cpu_swap_8bit( _environment, dojokaHandle->realName, address_displacement( _environment, dojokaHandle->realName, "3" ) );
9120 cpu_swap_8bit( _environment, address_displacement( _environment, dojokaHandle->realName, "1" ), address_displacement( _environment, dojokaHandle->realName, "2" ) );
9121 #endif
9122 cpu_dsfree( _environment, result->realName );
9123 cpu_move_8bit( _environment, variable_hex( _environment, dojokaHandle->name, 0 )->realName, result->realName );
9124 value = NULL;
9125 }
9126 break;
9127 default:
9129 break;
9130 }
9131 break;
9132 case 32:
9133 case 16:
9134 case 8:
9135 break;
9136 }
9137
9138 if ( value ) {
9139 variable_store_string( _environment, result->name, " " );
9140 cpu_dswrite( _environment, result->realName );
9141 cpu_dsdescriptor( _environment, result->realName, address->realName, size->realName );
9142
9143 cpu_number_to_string( _environment, value->realName, address->realName, size->realName, VT_BITWIDTH( value->type ), VT_SIGNED( value->type ) );
9144
9145 cpu_dsresize( _environment, result->realName, size->realName );
9146 }
9147
9148 return result;
9149
9150}
9151
9159/* <usermanual>
9160@keyword VAL
9161
9162@english
9163
9164The ''VAL'' command is a function that allows you to convert a string that represents
9165a number into a integer numeric value. In other words, it takes a string that contains
9166numbers and returns the corresponding numeric value.
9167
9168The ''VAL'' command is very useful when working with user input, because the user
9169often enters numbers as strings. For example, if we ask the user to enter their age,
9170the input will be a string. In order to perform calculations with this age, we must
9171first convert it to a number.
9172
9173The ''VAL'' function reads the string from left to right and stops at the first
9174character that is not a number. The ''VAL'' function ignores spaces at the beginning
9175of the string. If the string does not begin with a number or contains only
9176non-numeric characters, the ''VAL'' function returns zero.
9177
9178@italian
9179
9180Il comando ''VAL'' è una funzione che consente di convertire una stringa che
9181rappresenta un numero in un valore numerico intero. In altre parole, prende
9182una stringa che contiene numeri e restituisce il valore numerico corrispondente.
9183
9184Il comando ''VAL'' è molto utile quando si lavora con l'input dell'utente,
9185perché l'utente spesso inserisce i numeri come stringhe. Ad esempio, se
9186chiediamo all'utente di inserire la sua età, l'input sarà una stringa. Per
9187eseguire calcoli con questa età, dobbiamo prima convertirla in un numero.
9188
9189La funzione ''VAL'' legge la stringa da sinistra a destra e si ferma al primo
9190carattere che non è un numero. La funzione ''VAL'' ignora gli spazi all'inizio
9191della stringa. Se la stringa non inizia con un numero o contiene solo caratteri
9192non numerici, la funzione ''VAL'' restituisce zero.
9193
9194@syntax = VAL(string)
9195
9196@example PRINT VAL("123")
9197@usedInExample strings_val_01.bas
9198
9199@seeAlso STR
9200 </usermanual> */
9201Variable * variable_string_val( Environment * _environment, char * _value ) {
9202
9204
9205 Variable * value = variable_retrieve( _environment, _value );
9206 Variable * result = variable_temporary( _environment, VT_SWORD, "(result of val)" );
9207 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of val)" );
9208 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of val)" );
9209
9210 cpu_store_16bit( _environment, result->realName, 0 );
9211
9212 switch( value->type ) {
9213 case VT_STRING: {
9214 cpu_move_8bit( _environment, value->realName, size->realName );
9215 cpu_addressof_16bit( _environment, value->realName, address->realName );
9216 cpu_inc_16bit( _environment, address->realName );
9217 cpu_convert_string_into_16bit( _environment, address->realName, size->realName, result->realName );
9218 break;
9219 }
9220 case VT_DSTRING: {
9221 cpu_dsdescriptor( _environment, value->realName, address->realName, size->realName );
9222 cpu_compare_and_branch_8bit_const( _environment, size->realName, 0, label, 1 );
9223 cpu_convert_string_into_16bit( _environment, address->realName, size->realName, result->realName );
9224 cpu_label( _environment, label );
9225 break;
9226 }
9227 default:
9228 CRITICAL_VAL_UNSUPPORTED( _value, DATATYPE_AS_STRING[value->type]);
9229 break;
9230 }
9231
9232 return result;
9233
9234}
9235
9243/* <usermanual>
9244@keyword HEX
9245
9246@english
9247The ''HEX'' statement is used to convert a decimal number to a hexadecimal number.
9248Hexadecimal, or base 16, is a numbering system that uses 16 digits (0 through 9 and
9249the letters A through F) to represent numbers.
9250
9251This system is widely used in
9252computing, especially to represent memory addresses, colors, and character codes.
9253Moreover, it is a concise way of representing binary numbers, which are the basis
9254of how computers work, and bit-level operations are often easier to display and
9255manipulate in hexadecimal.
9256
9257The ''expression'' is the value you want to convert to hexadecimal, and it must
9258be an integer value. The ''HEX'' statement will return a string representing
9259the hexadecimal value corresponding to the input number. The length of the
9260returned string depends on the size (in bytes) of ''expression''.
9261
9262@italian
9263L'istruzione ''HEX'' viene utilizzata per convertire un numero decimale in
9264un numero esadecimale. L'esadecimale, o base 16, è un sistema di numerazione
9265che utilizza 16 cifre (da 0 a 9 e le lettere da A a F) per rappresentare i numeri.
9266
9267Questo sistema è ampiamente utilizzato nell'informatica, in particolare per
9268rappresentare indirizzi di memoria, colori e codici di carattere. Inoltre, è un modo
9269conciso di rappresentare i numeri binari, che sono la base del funzionamento
9270dei computer, e le operazioni a livello di bit sono spesso più facili da visualizzare
9271e manipolare in esadecimale.
9272
9273Il parametro ''expression'' è il valore che si desidera convertire in esadecimale e
9274deve essere un valore intero. L'istruzione ''HEX'' restituirà una stringa che
9275rappresenta il valore esadecimale corrispondente al numero di input. La
9276lunghezza della stringa restituita dipende dalla dimensione (in byte) di ''expression''.
9277
9278@syntax = HEX(expression)
9279
9280@example x = HEX( 42 )
9281@example PRINT HEX( y )
9282
9283@alias $$
9284
9285@target all
9286 </usermanual> */
9287/* <usermanual>
9288@keyword $$
9289
9290@english
9291
9292@italian
9293
9294@syntax = $$(expression)
9295
9296@example x = $$( 42 )
9297@example PRINT $$( y )
9298
9299@alias HEX
9300
9301@target all
9302 </usermanual> */
9303Variable * variable_hex( Environment * _environment, char * _value, int _separator ) {
9304
9306
9307 Variable * originalValue = variable_retrieve( _environment, _value );
9308 Variable * digits = NULL;
9309 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of BIN)" );
9310 Variable * pad = variable_temporary( _environment, VT_BYTE, "(is padding needed?)");
9311
9312 Variable * originalAddress = variable_temporary( _environment, VT_ADDRESS, "(result of LOWER)" );
9313 Variable * originalSize = variable_temporary( _environment, VT_BYTE, "(result of hex)" );
9314 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of hex)" );
9315
9316 switch( VT_BITWIDTH( originalValue->type ) ) {
9317 case 0: {
9318 switch( originalValue->type ) {
9319 case VT_STRING: {
9320 cpu_move_8bit( _environment, originalValue->realName, originalSize->realName );
9321 cpu_addressof_16bit( _environment, originalValue->realName, originalAddress->realName );
9322 cpu_inc_16bit( _environment, originalAddress->realName );
9323 cpu_hex_to_string_calc_string( _environment, originalSize->realName, _separator, size->realName );
9324 break;
9325 }
9326 case VT_DSTRING: {
9327 cpu_dsdescriptor( _environment, originalValue->realName, originalAddress->realName, originalSize->realName );
9328 cpu_hex_to_string_calc_string( _environment, originalSize->realName, _separator, size->realName );
9329 break;
9330 }
9331 }
9332 break;
9333 }
9334 case 32:
9335 case 16:
9336 case 8:
9337 cpu_hex_to_string_calc_string_size( _environment, VT_BITWIDTH( originalValue->type ) >> 3, _separator, size->realName );
9338 cpu_store_8bit( _environment, originalSize->realName, VT_BITWIDTH( originalValue->type ) >> 3 );
9339 cpu_addressof_16bit( _environment, originalValue->realName, originalAddress->realName );
9340 break;
9341 default:
9342 CRITICAL_HEX_UNSUPPORTED( _value, DATATYPE_AS_STRING[originalValue->type]);
9343 break;
9344 }
9345
9346 char finishedLabel[MAX_TEMPORARY_STORAGE]; sprintf(finishedLabel, "%send", label);
9347 char padLabel[MAX_TEMPORARY_STORAGE]; sprintf(padLabel, "%spad", label);
9348 char truncateLabel[MAX_TEMPORARY_STORAGE]; sprintf(truncateLabel, "%strunc", label);
9349
9350 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of hex)" );
9351 cpu_dsalloc( _environment, size->realName, result->realName );
9352 cpu_dsdescriptor( _environment, result->realName, address->realName, NULL );
9353
9354 cpu_hex_to_string( _environment, originalAddress->realName, address->realName, originalSize->realName, _separator );
9355
9356 return result;
9357
9358}
9359
9367/* <usermanual>
9368@keyword HEX2BIN
9369
9370@english
9371
9372The ''HEX2BIN'' command is a fundamental function for low-level data manipulation.
9373Its purpose is to interpret a readable string (consisting of hexadecimal characters)
9374and convert it to its original binary representation (a byte array or "buffer").
9375It takes a string like ''48454C4C4F'' and converts it to the binary buffer
9376containing the corresponding byte values.
9377
9378@italian
9379
9380Il comando ''HEX2BIN'' è una funzione fondamentale per la manipolazione di dati a basso livello.
9381Il suo scopo è interpretare una stringa leggibile (composta da caratteri esadecimali)
9382e convertirla nella sua rappresentazione binaria originale (un array di byte o "buffer").
9383Accetta una stringa come ''48454C4C4F'' e la converte nel buffer binario
9384contenente i valori di byte corrispondenti.
9385
9386@syntax = HEX2BIN(expression TO var)
9387
9388@example DIM v AS INTEGER
9389@example IF HEX2BIB("002A" TO v) THEN: PRINT "OK!": ENDIF
9390
9391@target all
9392 </usermanual> */
9393Variable * variable_hex2bin( Environment * _environment, char * _value, char * _variable ) {
9394
9396
9397 Variable * value = variable_retrieve( _environment, _value );
9398 Variable * variable = variable_retrieve( _environment, _variable );
9399
9400 Variable * valueAddress = variable_temporary( _environment, VT_ADDRESS, "(result of LOWER)" );
9401 Variable * valueSize = variable_temporary( _environment, VT_BYTE, "(result of hex)" );
9402 Variable * variableAddress = variable_temporary( _environment, VT_ADDRESS, "(result of LOWER)" );
9403 Variable * variableSize = variable_temporary( _environment, VT_BYTE, "(result of hex)" );
9404
9405 Variable * result = variable_temporary( _environment, VT_SBYTE, "(result of hex)" );
9406
9407 switch( value->type ) {
9408 case VT_STRING: {
9409 cpu_move_8bit( _environment, value->realName, valueSize->realName );
9410 cpu_addressof_16bit( _environment, value->realName, valueAddress->realName );
9411 cpu_inc_16bit( _environment, valueAddress->realName );
9412 break;
9413 }
9414 case VT_DSTRING: {
9415 cpu_dsdescriptor( _environment, value->realName, valueAddress->realName, valueSize->realName );
9416 break;
9417 }
9418 default:
9420 }
9421
9422 if ( VT_BITWIDTH( variable->type ) ) {
9423 cpu_store_8bit( _environment, variableSize->realName, VT_BITWIDTH( variable->type ) >> 3 );
9424 cpu_addressof_16bit( _environment, variable->realName, variableAddress->realName );
9425 } else {
9426 switch( variable->type ) {
9427 case VT_TARRAY:
9428 case VT_TYPE:
9429 case VT_BUFFER: {
9430 cpu_store_8bit( _environment, variableSize->realName, variable->size );
9431 cpu_addressof_16bit( _environment, variable->realName, variableAddress->realName );
9432 break;
9433 };
9434 case VT_DSTRING: {
9435 cpu_dsdescriptor( _environment, variable->realName, variableAddress->realName, variableSize->realName );
9436 break;
9437 };
9438 case VT_STRING:
9440 }
9441 }
9442
9443 cpu_hex_to_bin( _environment, valueAddress->realName, valueSize->realName, variableAddress->realName, variableSize->realName, result->realName );
9444
9445 return result;
9446
9447}
9448
9457/* <usermanual>
9458@keyword STRING (function)
9459
9460@english
9461
9462The ''STRING'' function is used to create a string by repeating a single
9463character a certain number of times. This is very useful
9464for creating fixed-length strings, such as borders, padding, or separators.
9465If a string of more than one character is given, only the first character will be used.
9466
9467The ''STRING'' function has several applications: it can be used to create
9468borders for your tables or to delimit sections of text, and spaces to align
9469text or to create fixed-width columns. You can create lines of special
9470characters to separate different sections of an output, or a create
9471repeating patterns of characters.
9472
9473@italian
9474
9475La funzione ''STRING'' viene utilizzata per creare una stringa ripetendo
9476un singolo carattere un certo numero di volte. Ciò è molto
9477utile per creare stringhe di lunghezza fissa, come bordi, padding o separatori.
9478Se viene usata una stringa formata da più caratteri, solo il primo carattere sarà
9479utilizzato per generare la sequenza.
9480
9481La funzione ''STRING'' ha diverse applicazioni: può essere utilizzata per
9482creare bordi per le tabelle o per delimitare sezioni di testo e spazi per
9483allineare il testo o per creare colonne di larghezza fissa. È possibile
9484creare righe di caratteri speciali per separare diverse sezioni di un output
9485o per creare modelli ripetuti di caratteri.
9486
9487@syntax = STRING( text, repetitions )
9488
9489@example x = STRING( "A", 42 )
9490
9491@seeAlso DUP
9492@usedInExample strings_string_01.bas
9493
9494 </usermanual> */
9495Variable * variable_string_string( Environment * _environment, char * _string, char * _repetitions ) {
9496
9498
9499 Variable * string = variable_retrieve( _environment, _string );
9500 Variable * repetitions = variable_retrieve_or_define( _environment, _repetitions, VT_BYTE, 0 );
9501 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of STRING)");
9502
9503 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of LOWER)" );
9504 Variable * pattern = variable_temporary( _environment, VT_BYTE, "(result of LOWER)" );
9505
9506 cpu_dsfree( _environment, result->realName );
9507 cpu_dsalloc( _environment, repetitions->realName, result->realName );
9508
9509 cpu_compare_and_branch_8bit_const( _environment, repetitions->realName, 0, label, 1 );
9510
9511 switch( string->type ) {
9512 case VT_STRING: {
9513 cpu_addressof_16bit( _environment, string->realName, address->realName );
9514 cpu_inc_16bit( _environment, address->realName );
9515 cpu_peek( _environment, address->realName, pattern->realName );
9516 break;
9517 }
9518 case VT_DSTRING: {
9519 cpu_dsdescriptor( _environment, string->realName, address->realName, NULL );
9520 cpu_peek( _environment, address->realName, pattern->realName );
9521 break;
9522 }
9523 default:
9524 CRITICAL_STRING_UNSUPPORTED( _string, DATATYPE_AS_STRING[string->type]);
9525 }
9526
9527 cpu_dsfill( _environment, result->realName, pattern->realName );
9528
9529 cpu_label( _environment, label );
9530
9531 return result;
9532
9533}
9534
9535
9536/* <usermanual>
9537@keyword DUP
9538
9539@english
9540
9541The ''DUP'' command allows you to duplicate portions of text
9542within a program. This feature is especially useful when you
9543need to repeat a sequence of characters multiple times, without
9544having to retype it manually.
9545
9546The ''DUP'' command can be combined with other commands to create
9547more complex effects. You can concatenate the result of ''DUP'' with
9548other strings to form sentences or paragraphs. You can assign the
9549result of ''DUP'' to a variable for later use. You can combine it
9550with other string manipulation functions to create even more customized
9551effects. Displaying an increasing number of characters in a bar can use ''DUP'',
9552as well as to write tables or reports with fixed-width columns.
9553
9554@italian
9555
9556Il comando ''DUP'' consente di duplicare porzioni di testo
9557all'interno di un programma. Questa funzionalità è
9558particolarmente utile quando è necessario ripetere una sequenza
9559di caratteri più volte, senza doverla riscrivere manualmente.
9560
9561Il comando ''DUP'' può essere combinato con altri comandi per creare
9562effetti più complessi. È possibile concatenare il risultato di
9563''DUP'' con altre stringhe per formare frasi o paragrafi.
9564È possibile assegnare il risultato di ''DUP'' a una variabile
9565per un uso successivo. È possibile combinarlo con altre funzioni
9566di manipolazione delle stringhe per creare effetti ancora più
9567personalizzati. La visualizzazione di un numero crescente di
9568caratteri in una barra può utilizzare ''DUP'', nonché per
9569scrivere tabelle o report con colonne a larghezza fissa.
9570
9571@syntax = DUP( string, times )
9572
9573@example PRINT DUP( "***", 10 )
9574
9575@seeAlso STRING (function)
9576
9577</usermanual> */
9578Variable * variable_string_dup( Environment * _environment, char * _string, char * _repetitions ) {
9579
9581
9582 char zeroLabel[MAX_TEMPORARY_STORAGE]; sprintf( zeroLabel, "%szero", label );
9583
9584 Variable * string = variable_retrieve( _environment, _string );
9585 Variable * stringAddress = variable_temporary( _environment, VT_ADDRESS, "(address)" );
9586 Variable * stringLen = variable_temporary( _environment, VT_BYTE, "(len)" );
9587 Variable * repetitions = variable_retrieve_or_define( _environment, _repetitions, VT_BYTE, 0 );
9588 Variable * copyOfRepetitions = variable_temporary( _environment, VT_BYTE, "(copy repetitions)" );
9589 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of STRING)");
9590 Variable * resultAddress = variable_temporary( _environment, VT_ADDRESS, "(address)" );
9591 Variable * resultLen = variable_temporary( _environment, VT_BYTE, "(len)" );
9592
9593 cpu_compare_and_branch_8bit_const( _environment, repetitions->realName, 0, zeroLabel, 1 );
9594
9595 switch( string->type ) {
9596 case VT_STRING: {
9597 cpu_move_8bit( _environment, string->realName, stringLen->realName );
9598 cpu_addressof_16bit( _environment, string->realName, stringAddress->realName );
9599 cpu_inc_16bit( _environment, stringAddress->realName );
9600 break;
9601 }
9602 case VT_DSTRING: {
9603 cpu_dsdescriptor( _environment, string->realName, stringAddress->realName, stringLen->realName );
9604 break;
9605 }
9606 default:
9608 }
9609
9610 Variable * repetitionsLen = variable_cast( _environment, variable_mul( _environment, repetitions->name, stringLen->name )->name, VT_BYTE );
9611
9612 cpu_dsalloc( _environment, repetitionsLen->realName, result->realName );
9613 cpu_dsdescriptor( _environment, result->realName, resultAddress->realName, resultLen->realName );
9614
9615 variable_move( _environment, repetitions->name, copyOfRepetitions->name );
9616
9617 cpu_label( _environment, label );
9618 cpu_mem_move( _environment, stringAddress->realName, resultAddress->realName, stringLen->realName );
9619 cpu_math_add_16bit_with_8bit( _environment, resultAddress->realName, stringLen->realName, resultAddress->realName );
9620 cpu_dec( _environment, copyOfRepetitions->realName );
9621 cpu_compare_and_branch_8bit_const( _environment, copyOfRepetitions->realName, 0, label, 0 );
9622
9623 cpu_label( _environment, zeroLabel );
9624
9625 return result;
9626
9627}
9628
9636/* <usermanual>
9637@keyword SPACE (function)
9638
9639@english
9640
9641The ''SPACE'' command is used to generate a string of a specified number of white
9642spaces. This string can then be used in various operations, such as formatting text,
9643creating spacing, or aligning data within a line.
9644
9645The ''SPACE'' command has many applications: you can use it to create margins,
9646indentations, or to align text precisely. By combining ''SPACE'' with other
9647commands, you can build simple tables with aligned columns. You can also
9648usethe '' SPACE'' to add or remove spaces from an existing string.
9649
9650@italian
9651
9652Il comando ''SPACE'' viene utilizzato per generare una stringa di un numero
9653specificato di spazi vuoti. Questa stringa può quindi essere utilizzata in
9654varie operazioni, come la formattazione del testo, la creazione di spaziature
9655o l'allineamento dei dati all'interno di una riga.
9656
9657Il comando ''SPACE'' ha molte applicazioni: puoi utilizzarlo per creare margini,
9658rientri o per allineare il testo in modo preciso. Combinando ''SPACE'' con altri
9659comandi, puoi creare semplici tabelle con colonne allineate. Puoi anche utilizzare
9660''SPACE'' per aggiungere o rimuovere spazi da una stringa esistente.
9661
9662@syntax = SPACE(number)
9663
9664@example y = 42: x = SPACE( y )
9665
9666@usedInExample strings_space_01.bas
9667
9668 </usermanual> */
9669Variable * variable_string_space( Environment * _environment, char * _repetitions ) {
9670
9671 Variable * repetitions = variable_retrieve_or_define( _environment, _repetitions, VT_BYTE, 0 );
9672 Variable * spaces = variable_temporary( _environment, VT_DSTRING, "(space)");
9673
9674 cpu_dsalloc( _environment, repetitions->realName, spaces->realName );
9675 cpu_dsfill_value( _environment, spaces->realName, 32 );
9676
9677 return spaces;
9678
9679}
9680
9688/* <usermanual>
9689@keyword FLIP (function)
9690
9691@english
9692The ''FLIP'' function simply reverses the order of the characters
9693held in the parameter (if a string) or the order of the bits (if a (SIGNED) BYTE).
9694
9695@italian
9696La funzione ''FLIP'' inverte semplicemente l'ordine dei caratteri
9697contenuti nel parametro (se è una stringa) oppure l'ordine dei bit (
9698nel caso di (SIGNED) BYTE)
9699
9700@syntax = FLIP( variable )
9701
9702@example x = FLIP( "test" )
9703@example DIM y AS BYTE = 42
9704@example x = FLIP( y )
9705
9706@usedInExample strings_flip_01.bas
9707
9708@target all
9709 </usermanual> */
9710Variable * variable_string_flip( Environment * _environment, char * _string ) {
9711
9712 Variable * string = variable_retrieve( _environment, _string );
9713
9714 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of STRING)");
9715 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of val)" );
9716 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of val)" );
9717 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of val)" );
9718 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of val)" );
9719
9720 switch( string->type ) {
9721 case VT_STRING: {
9722 cpu_move_8bit( _environment, string->realName, size->realName );
9723 cpu_addressof_16bit( _environment, string->realName, address->realName );
9724 cpu_inc_16bit( _environment, address->realName );
9725
9726 break;
9727 }
9728 case VT_DSTRING: {
9729 cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
9730 break;
9731 }
9732 default:
9734 }
9735
9736 cpu_dsfree( _environment, result->realName );
9737 cpu_dsalloc( _environment, size->realName, result->realName );
9738 cpu_dsdescriptor( _environment, result->realName, address2->realName, size2->realName );
9739
9740 cpu_flip( _environment, address->realName, size->realName, address2->realName );
9741
9742 return result;
9743
9744}
9745
9746Variable * variable_flip( Environment * _environment, char * _variable ) {
9747
9748 Variable * variable = variable_retrieve( _environment, _variable );
9749
9750 switch( variable->type ) {
9751 case VT_DSTRING:
9752 case VT_STRING:
9753 return variable_string_flip( _environment, _variable );
9754 default: {
9755 Variable * result = variable_temporary( _environment, variable->type, "(tmp)");
9756
9757 switch ( VT_BITWIDTH( variable->type ) ) {
9758 case 8:
9759 cpu_flip_8bit( _environment, variable->realName, result->realName );
9760 break;
9761 default:
9762 CRITICAL_CANNOT_FLIP( _variable );
9763 }
9764
9765 return result;
9766
9767 }
9768
9769 }
9770
9771}
9772
9780/* <usermanual>
9781@keyword CHR$
9782
9783@english
9784
9785The ''CHR$'' function converts a numeric code (usually an integer) into a
9786corresponding character. In other words, it takes a number and returns
9787the character associated with that number in the ASCII table.
9788
9789You can combine multiple ''CHR$'' to create strings of specific characters,
9790and insert special characters, such as control characters or non-printing characters,
9791using their ASCII codes. In some applications, ''CHR$'' can be used to encode
9792or decode information, because ASCII table associates a unique number with
9793each character used in computers. The first 32 codes (0 through 31) represent
9794control characters, such as the newline character or tabulator. Codes 32 through
9795127 represent printable characters, such as letters, numbers, and symbols.
9796
9797@italian
9798
9799La funzione ''CHR$'' converte un codice numerico (solitamente un intero)
9800in un carattere corrispondente. In altre parole, prende un numero e restituisce
9801il carattere associato a quel numero nella tabella ASCII.
9802
9803È possibile combinare più ''CHR$'' per creare stringhe di caratteri specifici
9804e inserire caratteri speciali, come caratteri di controllo o caratteri non stampabili,
9805utilizzando i loro codici ASCII. In alcune applicazioni, ''CHR$'' può essere
9806utilizzato per codificare o decodificare informazioni, perché la tabella ASCII
9807associa un numero univoco a ciascun carattere utilizzato nei computer. I primi
980832 codici (da 0 a 31) rappresentano caratteri di controllo, come il carattere di
9809nuova riga o tabulazione. I codici da 32 a 127 rappresentano caratteri stampabili
9810, come lettere, numeri e simboli.
9811
9812@syntax = CHR$(value)
9813
9814@example x = CHR$(65)
9815
9816@usedInExample strings_chr_01.bas
9817
9818@seeAlso ASC
9819
9820@target all
9821 </usermanual> */
9822Variable * variable_string_chr( Environment * _environment, char * _ascii ) {
9823
9824 Variable * ascii = variable_retrieve_or_define( _environment, _ascii, VT_BYTE, 0 );
9825
9826 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of CHR)");
9827 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of val)" );
9828 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of val)" );
9829
9830 switch( VT_BITWIDTH( ascii->type ) ) {
9831 case 8:
9832 case 16:
9833 case 32:
9834 break;
9835 default:
9837 break;
9838 }
9839
9840 cpu_dsfree( _environment, result->realName );
9841 cpu_dsalloc_size( _environment, 1, result->realName );
9842 cpu_dsdescriptor( _environment, result->realName, address->realName, size->realName );
9843
9844 cpu_move_8bit_indirect( _environment, ascii->realName, address->realName );
9845
9846 return result;
9847
9848}
9849
9857/* <usermanual>
9858@keyword ASC
9859
9860@english
9861
9862The ''ASC'' command performs a very specific function: it converts the first
9863character of a string into its corresponding ASCII code. ASCII stands for
9864American Standard Code for Information Interchange and it is a standard
9865encoding that associates each alphanumeric character and many symbols
9866with an integer between 0 and 127. This number represents the internal
9867representation of the character within the computer.
9868
9869The ''ASC'' command allows you to manipulate the individual characters
9870of a string numerically. For example, you can check whether a character
9871is an uppercase letter (its ASCII code will be between 65 and 90), or whether
9872it is a number (its ASCII code will be between 48 and 57).
9873
9874Comparing the ASCII codes of two characters is an efficient way to establish
9875the alphabetical order between them and, in some applications, you need to
9876convert characters to numbers or vice versa. ''ASC'' is a fundamental tool
9877for this type of operation.
9878
9879In 8-bit computers, memory is organized in bytes, which are sequences of
98808 bits. Each byte can represent a number from 0 to 255. Since ASCII
9881encoding uses only 7 bits, a byte can represent 128 different characters.
9882On 8-bit computers, the supported character set is limited to 128 ASCII
9883characters. This means that accented characters or characters from other
9884languages cannot be directly represented. The exact meaning of an ASCII
9885code can vary slightly depending on the encoding used. Note that the ''CHR$''
9886command is the inverse of ''ASC'', it converts an ASCII code to a character.
9887
9888@italian
9889
9890Il comando ''ASC'' esegue una funzione molto specifica: converte il primo
9891carattere di una stringa nel suo codice ASCII corrispondente. ASCII sta per
9892American Standard Code for Information Interchange ed è una codifica standard che
9893associa ogni carattere alfanumerico e molti simboli a un numero intero compreso
9894tra 0 e 127. Questo numero rappresenta la rappresentazione interna del carattere
9895all'interno del computer.
9896
9897Il comando ''ASC'' consente di manipolare numericamente i singoli caratteri
9898di una stringa. Ad esempio, è possibile verificare se un carattere è una lettera
9899maiuscola (il suo codice ASCII sarà compreso tra 65 e 90) o se è un numero
9900(il suo codice ASCII sarà compreso tra 48 e 57).
9901
9902Confrontare i codici ASCII di due caratteri è un modo efficiente per stabilire
9903l'ordine alfabetico tra di essi e, in alcune applicazioni, è necessario convertire
9904i caratteri in numeri o viceversa. ''ASC'' è uno strumento fondamentale per
9905questo tipo di operazione.
9906
9907Nei computer a 8 bit, la memoria è organizzata in byte, che sono sequenze di
99088 bit. Ogni byte può rappresentare un numero da 0 a 255. Poiché la codifica
9909ASCII utilizza solo 7 bit, un byte può rappresentare 128 caratteri diversi.
9910Nei computer a 8 bit, il set di caratteri supportato è limitato a 128 caratteri
9911ASCII. Ciò significa che i caratteri accentati o i caratteri di altre lingue
9912non possono essere rappresentati direttamente. Il significato esatto di un
9913codice ASCII può variare leggermente a seconda della codifica utilizzata.
9914Nota che il comando ''CHR$'' è l'inverso di ''ASC'', converte un codice
9915ASCII in un carattere.
9916
9917@syntax = ASC( string )
9918
9919@example x = ASC( "UGBASIC" )
9920
9921@usedInExample strings_asc_01.bas
9922
9923@seeAlso CHR
9924
9925@target all
9926 </usermanual> */
9927Variable * variable_string_asc( Environment * _environment, char * _char ) {
9928
9930
9931 Variable * character = variable_retrieve_or_define( _environment, _char, VT_BYTE, 0 );
9932
9933 Variable * result = variable_temporary( _environment, VT_BYTE, "(result of ASC)");
9934 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of ASC)" );
9935 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of ASC)" );
9936
9937 switch( character->type ) {
9938 case VT_STRING: {
9939 cpu_move_8bit( _environment, character->realName, size->realName );
9940 cpu_addressof_16bit( _environment, character->realName, address->realName );
9941 cpu_inc_16bit( _environment, address->realName );
9942
9943 break;
9944 }
9945 case VT_DSTRING: {
9946 cpu_dsdescriptor( _environment, character->realName, address->realName, size->realName );
9947 break;
9948 }
9949 default:
9950 CRITICAL_ASC_UNSUPPORTED( _char, DATATYPE_AS_STRING[character->type]);
9951 }
9952
9953 cpu_store_8bit( _environment, result->realName, 0 );
9954 cpu_compare_and_branch_8bit_const( _environment, size->realName, 0, label, 1 );
9955 cpu_move_8bit_indirect2( _environment, address->realName, result->realName );
9956
9957 cpu_label( _environment, label );
9958
9959 return result;
9960
9961}
9962
9970/* <usermanual>
9971@keyword LEN
9972
9973@english
9974
9975the ''LEN'' command (short for "length") is used to determine the length
9976of a string, or the total number of characters in the string. This
9977is a very useful command when you need to know the size of a string
9978to perform manipulation or comparison operations.
9979
9980You can check whether a string exceeds a certain maximum length or not.
9981You can use ''LEN'' to create strings of a fixed length by adding spaces
9982or other characters. You can combine ''LEN'' with other functions such as
9983''LEFT$'', ''RIGHT$'', and ''MID$'' to extract and modify parts of a string.
9984You can compare the length of two strings to make decisions in your program.
9985
9986@italian
9987
9988il comando ''LEN'' (abbreviazione di "length") è usato per determinare la
9989lunghezza di una stringa, o il numero totale di caratteri nella stringa.
9990Questo è un comando molto utile quando hai bisogno di conoscere la dimensione
9991di una stringa per eseguire operazioni di manipolazione o confronto.
9992
9993Puoi controllare se una stringa supera una certa lunghezza massima o meno.
9994Puoi usare ''LEN'' per creare stringhe di lunghezza fissa aggiungendo
9995spazi o altri caratteri. Puoi combinare ''LEN'' con altre funzioni come
9996''LEFT$'', ''RIGHT$'' e ''MID$'' per estrarre e modificare parti di una stringa.
9997Puoi confrontare la lunghezza di due stringhe per prendere decisioni nel
9998tuo programma.
9999
10000@syntax = LEN( text )
10001
10002@example x = LEN( "TEST" )
10003
10004@usedInExample strings_len_01.bas
10005
10006 </usermanual> */
10007Variable * variable_string_len( Environment * _environment, char * _string ) {
10008
10009 Variable * string = variable_retrieve( _environment, _string );
10010 Variable * result = variable_temporary( _environment, VT_BYTE, "(result of LEN)");
10011 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of val)" );
10012 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of val)" );
10013
10014 switch( string->type ) {
10015 case VT_STRING: {
10016 cpu_move_8bit( _environment, string->realName, size->realName );
10017 break;
10018 }
10019 case VT_DSTRING: {
10020 cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
10021 break;
10022 }
10023 case VT_DOJOKA: {
10024 cpu_store_8bit( _environment, size->realName, 8 );
10025 break;
10026 }
10027 default:
10029 }
10030
10031 cpu_move_8bit( _environment, size->realName, result->realName );
10032
10033 return result;
10034
10035}
10036
10037// @bit2: ok
10038static Variable * calculate_offset_in_array_byte( Environment * _environment, char * _array ) {
10039
10040 Variable * array = variable_retrieve( _environment, _array );
10041
10042 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
10043 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
10044 }
10045
10046 Variable * offset = variable_temporary( _environment, VT_BYTE, "(offset in array)");
10047
10048 int i,j;
10049
10050 if ( _environment->arrayIndexes[_environment->arrayNestedIndex] == 1 ) {
10051 if ( _environment->arrayIndexesEach[_environment->arrayNestedIndex][0] == NULL ) {
10052 // variable_add_inplace( _environment, offset->name, _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][0] );
10053 Variable * offset = variable_temporary( _environment, VT_BYTE, "(offset in array)");
10054 if ( _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][0] >= array->arrayDimensionsEach[0] ) {
10056 }
10057 variable_store( _environment, offset->name, _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][0] );
10058 return offset;
10059 } else {
10060 Variable * index = variable_retrieve_or_define( _environment, _environment->arrayIndexesEach[_environment->arrayNestedIndex][0], VT_BYTE, 0);
10061 if ( _environment->checkBoundary ) {
10063 char checkBoundaryOk[MAX_TEMPORARY_STORAGE]; sprintf( checkBoundaryOk, "%s", label );
10064 Variable * checkBoundary = variable_less_than_const( _environment, index->name, array->arrayDimensionsEach[0], 0 );
10065 cpu_compare_and_branch_8bit_const( _environment, checkBoundary->realName, 0xff, checkBoundaryOk, 1 );
10066 error_out_of_boundary( _environment );
10067 cpu_label( _environment, checkBoundaryOk );
10068 }
10069 return index;
10070 }
10071 } else {
10072
10073 Variable * base = variable_temporary( _environment, VT_BYTE, "(base in array)");
10074
10075 variable_store( _environment, offset->name, 0 );
10076
10077 for( i = 0; i<_environment->arrayIndexes[_environment->arrayNestedIndex]; ++i ) {
10078 int baseValue = 1;
10079 for( j=0; j<(_environment->arrayIndexes[_environment->arrayNestedIndex]-i-1); ++j ) {
10080 baseValue *= array->arrayDimensionsEach[j];
10081 }
10082 if ( _environment->arrayIndexesEach[_environment->arrayNestedIndex][array->arrayDimensions-i-1] == NULL ) {
10083 variable_add_inplace( _environment, offset->name, _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][array->arrayDimensions-i-1] * baseValue );
10084 } else {
10085 Variable * index = variable_retrieve( _environment, _environment->arrayIndexesEach[_environment->arrayNestedIndex][array->arrayDimensions-i-1]);
10086 if ( _environment->checkBoundary ) {
10088 char checkBoundaryOk[MAX_TEMPORARY_STORAGE]; sprintf( checkBoundaryOk, "%s", label );
10089 Variable * checkBoundary = variable_less_than_const( _environment, index->name, array->arrayDimensionsEach[array->arrayDimensions-i-1], 0 );
10090 cpu_compare_and_branch_8bit_const( _environment, checkBoundary->realName, 0xff, checkBoundaryOk, 1 );
10091 error_out_of_boundary( _environment );
10092 cpu_label( _environment, checkBoundaryOk );
10093 }
10094
10095 if(baseValue!=1) {
10096 variable_store( _environment, base->name, baseValue );
10097 Variable * additionalOffset = variable_mul( _environment, index->name, base->name );
10098 variable_add_inplace_vars( _environment, offset->name, additionalOffset->name );
10099 } else {
10100 variable_add_inplace_vars( _environment, offset->name, index->name );
10101 }
10102 }
10103 }
10104 }
10105
10106 return offset;
10107
10108}
10109
10110// @bit2: ok
10111void variable_store_array_const_bit( Environment * _environment, Variable * _array, int _value ) {
10112
10113 if ( _array->bankAssigned != -1 ) {
10115 }
10116
10117 Variable * offset = calculate_offset_in_array( _environment, _array->name );
10118 Variable * position = variable_temporary( _environment, VT_BYTE, "(position)");
10119 Variable * value = variable_temporary( _environment, VT_BYTE, "(value)" );
10120 variable_store( _environment, value->name, _value * 0xff );
10121
10122 variable_move( _environment, offset->name, position->name );
10123
10124 Variable * positionInside = variable_and_const( _environment, position->name, 7 );
10125
10126 offset = variable_sr_const( _environment, offset->name, 3 );
10127
10128 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10129
10130 cpu_bit_inplace_8bit_extended_indirect( _environment, offset->realName, positionInside->realName, value->realName );
10131
10132}
10133
10134void variable_store_array_const_byte( Environment * _environment, Variable * _array, int _value ) {
10135
10136 MAKE_LABEL;
10137
10138 // @bit2: ok
10139 Variable * offset = calculate_offset_in_array( _environment, _array->name );
10140
10141 switch( _array->arrayType ) {
10142 case VT_FLOAT:
10143 case VT_STRING:
10145 case VT_TILE:
10146 case VT_TILESET:
10147 case VT_SPRITE:
10148 case VT_MSPRITE:
10149 case VT_DSTRING:
10150 offset = variable_sl_const( _environment, offset->name, 0 );
10151 break;
10152 case VT_TILES:
10153 offset = variable_sl_const( _environment, offset->name, 2 );
10154 break;
10155 default:
10156 offset = variable_sl_const( _environment, offset->name, ( VT_BITWIDTH( _array->arrayType ) >> 3 ) - 1 );
10157 break;
10158 }
10159
10160 if ( _array->bankAssigned == -1 ) {
10161
10162 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10163
10164 switch( _array->arrayType ) {
10165 case VT_FLOAT:
10167 break;
10168 case VT_TILES:
10169 cpu_store_32bit( _environment, offset->realName, _value );
10170 break;
10171 case VT_TILE:
10172 case VT_TILESET:
10173 case VT_SPRITE:
10174 cpu_store_8bit( _environment, offset->realName, _value );
10175 break;
10176 case VT_MSPRITE:
10177 cpu_store_16bit( _environment, offset->realName, _value );
10178 break;
10179 default:
10180 switch( VT_BITWIDTH( _array->arrayType ) ) {
10181 case 32:
10182 cpu_store_32bit( _environment, offset->realName, _value );
10183 break;
10184 case 16:
10185 cpu_store_16bit( _environment, offset->realName, _value );
10186 break;
10187 case 8:
10188 cpu_store_8bit( _environment, offset->realName, _value );
10189 break;
10190 case 0:
10192 }
10193 break;
10194 }
10195
10196 } else {
10197
10198 switch( _array->arrayType ) {
10199 case VT_FLOAT:
10201 break;
10202 case VT_TILES:
10203 cpu_store_32bit( _environment, _array->realName, _value );
10204 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10205 bank_write_vars_bank_direct_size( _environment, _array->name, _array->bankAssigned, offset->name, 4 );
10206 break;
10207 case VT_TILE:
10208 case VT_TILESET:
10209 case VT_SPRITE:
10210 cpu_store_8bit( _environment, _array->realName, _value );
10211 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10212 bank_write_vars_bank_direct_size( _environment, _array->name, _array->bankAssigned, offset->name, 1 );
10213 break;
10214 case VT_MSPRITE:
10215 cpu_store_16bit( _environment, _array->realName, _value );
10216 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10217 bank_write_vars_bank_direct_size( _environment, _array->name, _array->bankAssigned, offset->name, 2 );
10218 break;
10219 default:
10220 switch( VT_BITWIDTH( _array->arrayType ) ) {
10221 case 32:
10222 cpu_store_32bit( _environment, _array->realName, _value );
10223 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10224 bank_write_vars_bank_direct_size( _environment, _array->name, _array->bankAssigned, offset->name, 4 );
10225 break;
10226 case 16:
10227 cpu_store_16bit( _environment, _array->realName, _value );
10228 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10229 bank_write_vars_bank_direct_size( _environment, _array->name, _array->bankAssigned, offset->name, 2 );
10230 break;
10231 case 8:
10232 cpu_store_8bit( _environment, _array->realName, _value );
10233 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10234 bank_write_vars_bank_direct_size( _environment, _array->name, _array->bankAssigned, offset->name, 1 );
10235 break;
10236 case 0:
10238 }
10239 break;
10240 }
10241
10242 }
10243}
10244
10245void variable_store_array_const( Environment * _environment, char * _array, int _value ) {
10246
10247 MAKE_LABEL;
10248
10249 Variable * array = variable_retrieve( _environment, _array );
10250
10251 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
10252 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
10253 }
10254
10255 if ( array->arrayType == 0 ) {
10257 array->arrayType = VT_WORD;
10258 }
10259
10260 if ( array->arrayType != VT_BIT ) {
10261 variable_store_array_const_byte( _environment, array, _value );
10262 } else {
10263 variable_store_array_const_bit( _environment, array, _value );
10264 }
10265
10266}
10267
10268// @bit2: ok
10269void variable_move_array_bit( Environment * _environment, Variable * _array, char * _value ) {
10270
10271 if ( _array->bankAssigned != -1 ) {
10273 }
10274
10275 Variable * offset = calculate_offset_in_array( _environment, _array->name );
10276 Variable * position = variable_temporary( _environment, VT_BYTE, "(position)");
10277
10278 variable_move( _environment, offset->name, position->name );
10279
10280 Variable * positionInside = variable_and_const( _environment, position->name, 7 );
10281
10282 offset = variable_sr_const( _environment, offset->name, 3 );
10283
10284 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10285
10286 Variable * value = variable_retrieve_or_define( _environment, _value, _array->arrayType, 0 );
10287 cpu_bit_inplace_8bit_extended_indirect( _environment, offset->realName, positionInside->realName, value->realName );
10288
10289}
10290
10291void variable_move_array_byte( Environment * _environment, Variable * _array, char * _value ) {
10292
10293 MAKE_LABEL;
10294
10295 if ( _array->bankAssigned == -1 && _array->size < 256 && VT_BITWIDTH( _array->arrayType ) == 8 ) {
10296
10297 if ( _environment->arrayIndexes[_environment->arrayNestedIndex] == 1 ) {
10298 if ( _environment->arrayIndexesEach[_environment->arrayNestedIndex][0] == NULL ) {
10299
10300 char precalculatedOffsetName[MAX_TEMPORARY_STORAGE];
10301 sprintf( precalculatedOffsetName, "%s%2.2xaddr", _array->name, _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][0] );
10302
10303 Constant * precalculatedOffset = constant_find( _environment, precalculatedOffsetName );
10304
10305 if ( !precalculatedOffset ) {
10306 precalculatedOffset = malloc( sizeof( Constant ) );
10307 memset( precalculatedOffset, 0, sizeof( Constant ) );
10308 precalculatedOffset->name = strdup( precalculatedOffsetName );
10309 precalculatedOffset->realName = strdup( precalculatedOffsetName );
10310 precalculatedOffset->value = _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][0];
10311 precalculatedOffset->type = CT_INTEGER;
10312 precalculatedOffset->relative = _array->realName;
10313 precalculatedOffset->next = _environment->constants;
10314 _environment->constants = precalculatedOffset;
10315 }
10316
10317 Variable * value = variable_retrieve_or_define( _environment, _value, _array->arrayType, 0 );
10318 if ( value->initializedByConstant ) {
10319 cpu_store_8bit( _environment, precalculatedOffset->realName, value->value );
10320 } else {
10321 cpu_move_8bit( _environment, value->realName, precalculatedOffset->realName );
10322 }
10323
10324 return;
10325 }
10326 }
10327
10328 Variable * offset = calculate_offset_in_array_byte( _environment, _array->name );
10329
10330 Variable * value = variable_retrieve_or_define( _environment, _value, _array->arrayType, 0 );
10331 if ( value->initializedByConstant ) {
10332 cpu_store_8bit_with_offset2( _environment, _array->realName, offset->realName, value->value );
10333 } else {
10334 cpu_move_8bit_with_offset2( _environment, value->realName, _array->realName, offset->realName );
10335 }
10336 return;
10337
10338 }
10339
10340 outline0("; variable_move_array_byte(2)");
10341
10342 // @bit2: ok
10343 Variable * offset = calculate_offset_in_array( _environment, _array->name );
10344
10345 switch( _array->arrayType ) {
10346 case VT_TYPE:
10347 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT(_array->typeType->size) );
10348 break;
10349 case VT_PATH:
10350 offset = variable_sl_const( _environment, offset->name, 4 );
10351 break;
10352 case VT_VECTOR2:
10353 offset = variable_sl_const( _environment, offset->name, 2 );
10354 break;
10355 case VT_IMAGEREF:
10356 offset = variable_sl_const( _environment, offset->name, 4 );
10357 break;
10358 case VT_FLOAT:
10360 break;
10361 case VT_NUMBER:
10362 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT( _environment->numberConfig.maxBytes ) );
10363 break;
10364 case VT_STRING:
10366 case VT_TILE:
10367 case VT_TILESET:
10368 case VT_SPRITE:
10369 case VT_DSTRING:
10370 offset = variable_sl_const( _environment, offset->name, 0 );
10371 break;
10372 case VT_MSPRITE:
10373 offset = variable_sl_const( _environment, offset->name, 1 );
10374 break;
10375 case VT_TILES:
10376 offset = variable_sl_const( _environment, offset->name, 2 );
10377 break;
10378 default:
10379 offset = variable_sl_const( _environment, offset->name, ( VT_BITWIDTH( _array->arrayType ) >> 3 ) - 1 );
10380 break;
10381 }
10382
10383 Variable * value = variable_retrieve_or_define( _environment, _value, _array->arrayType, 0 );
10384
10385 if ( _array->bankAssigned == -1 ) {
10386
10387 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10388
10389 switch( _array->arrayType ) {
10390 case VT_TYPE:
10391 cpu_move_nbit_indirect( _environment, _array->typeType->size * 8, value->realName, offset->realName );
10392 break;
10393 case VT_PATH:
10394 cpu_move_nbit_indirect( _environment, 16 * 8, value->realName, offset->realName );
10395 break;
10396 case VT_VECTOR2:
10397 cpu_move_nbit_indirect( _environment, 4 * 8, value->realName, offset->realName );
10398 break;
10399 case VT_IMAGEREF:
10400 cpu_move_nbit_indirect( _environment, 12 * 8, value->realName, offset->realName );
10401 break;
10402 case VT_FLOAT:
10403 cpu_move_nbit_indirect( _environment, VT_FLOAT_BITWIDTH( _array->arrayPrecision ), value->realName, offset->realName );
10404 break;
10405 case VT_NUMBER:
10406 cpu_move_nbit_indirect( _environment, _environment->numberConfig.maxBytes << 3, value->realName, offset->realName );
10407 break;
10408 case VT_TILES:
10409 cpu_move_32bit_indirect( _environment, value->realName, offset->realName );
10410 break;
10411 case VT_TILE:
10412 case VT_TILESET:
10413 case VT_SPRITE:
10414 cpu_move_8bit_indirect( _environment, value->realName, offset->realName );
10415 break;
10416 case VT_MSPRITE:
10417 cpu_move_16bit_indirect( _environment, value->realName, offset->realName );
10418 break;
10419 case VT_DSTRING: {
10420
10421 Variable * dstring = variable_temporary( _environment, _array->arrayType, "(array element)");
10422
10423 cpu_move_8bit_indirect2( _environment, offset->realName, dstring->realName );
10424 // cpu_dsfree( _environment, dstring->realName );
10425
10426 // Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of array move)" );
10427 // Variable * size = variable_temporary( _environment, VT_BYTE, "(result of array move)" );
10428 // Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of array move)" );
10429 // Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of array move)" );
10430
10431 // cpu_dsdescriptor( _environment, _value->realName, address->realName, size->realName );
10432 // cpu_dsalloc( _environment, size->realName, dstring->realName );
10433 // cpu_dsdescriptor( _environment, dstring->realName, address2->realName, size2->realName );
10434 // cpu_mem_move(_environment, address->realName, address2->realName, size->realName );
10435
10436 if ( value->type == VT_STRING ) {
10437 cpu_dsassign_string( _environment, value->realName, dstring->realName );
10438 } else if ( value->type == VT_DSTRING ) {
10439 cpu_dsassign( _environment, value->realName, dstring->realName );
10440 } else {
10442 }
10443
10444 cpu_move_8bit_indirect( _environment, dstring->realName, offset->realName );
10445
10446 }
10447 break;
10448 default:
10449 switch( VT_BITWIDTH( _array->arrayType ) ) {
10450 case 32:
10451 cpu_move_32bit_indirect( _environment, value->realName, offset->realName );
10452 break;
10453 case 16:
10454 cpu_move_16bit_indirect( _environment, value->realName, offset->realName );
10455 break;
10456 case 8:
10457 cpu_move_8bit_indirect( _environment, value->realName, offset->realName );
10458 break;
10459 case 1:
10460 case 0:
10462 }
10463 break;
10464 }
10465
10466 } else {
10467
10468 switch( _array->arrayType ) {
10469 case VT_TYPE:
10470 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10471 bank_write_vars_bank_direct_size( _environment, value->name, _array->bankAssigned, offset->name, _array->typeType->size );
10472 break;
10473 case VT_FLOAT:
10474 case VT_NUMBER:
10476 break;
10477 case VT_TILES:
10478 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10479 bank_write_vars_bank_direct_size( _environment, value->name, _array->bankAssigned, offset->name, 4 );
10480 break;
10481 case VT_TILE:
10482 case VT_TILESET:
10483 case VT_SPRITE:
10484 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10485 bank_write_vars_bank_direct_size( _environment, value->name, _array->bankAssigned, offset->name, 1 );
10486 break;
10487 case VT_MSPRITE:
10488 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10489 bank_write_vars_bank_direct_size( _environment, value->name, _array->bankAssigned, offset->name, 2 );
10490 break;
10491 default:
10492 switch( VT_BITWIDTH( _array->arrayType ) ) {
10493 case 32:
10494 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10495 bank_write_vars_bank_direct_size( _environment, value->name, _array->bankAssigned, offset->name, 4 );
10496 break;
10497 case 16:
10498 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10499 bank_write_vars_bank_direct_size( _environment, value->name, _array->bankAssigned, offset->name, 2 );
10500 break;
10501 case 8:
10502 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10503 bank_write_vars_bank_direct_size( _environment, value->name, _array->bankAssigned, offset->name, 1 );
10504 break;
10505 case 1:
10507 case 0:
10508 switch( _array->arrayType ) {
10509 case VT_PATH:
10510 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10511 bank_write_vars_bank_direct_size( _environment, value->name, _array->bankAssigned, offset->name, 16 );
10512 break;
10513 case VT_TYPE:
10514 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10515 bank_write_vars_bank_direct_size( _environment, value->name, _array->bankAssigned, offset->name, _array->typeType->size );
10516 break;
10517 default:
10519 }
10520 }
10521 break;
10522 }
10523
10524 }
10525}
10526
10527void variable_move_array( Environment * _environment, char * _array, char * _value ) {
10528
10529 MAKE_LABEL;
10530
10531 Variable * array = variable_retrieve( _environment, _array );
10532 // Variable * value = variable_cast( _environment, _value, array->arrayType );
10533
10534 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
10535 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
10536 }
10537
10538 if ( array->arrayType == 0 ) {
10540 array->arrayType = VT_WORD;
10541 }
10542
10543 if ( array->arrayType != VT_BIT ) {
10544 variable_move_array_byte( _environment, array, _value );
10545 } else {
10546 variable_move_array_bit( _environment, array, _value );
10547 }
10548
10549}
10550
10551void variable_move_array_string( Environment * _environment, char * _array, char * _string ) {
10552
10553 Variable * array = variable_retrieve( _environment, _array );
10554 Variable * string = variable_retrieve( _environment, _string );
10555
10556 if ( array->bankAssigned != -1 ) {
10558 }
10559
10560 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
10561 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
10562 }
10563
10564 // @bit2: ok
10565 Variable * offset = calculate_offset_in_array( _environment, _array);
10566
10567 cpu_math_add_16bit_with_16bit( _environment, offset->realName, array->realName, offset->realName );
10568
10569 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(array element)");
10570
10571 cpu_move_8bit_indirect2( _environment, offset->realName, dstring->realName );
10572
10573 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of array move)" );
10574 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of array move)" );
10575 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of array move)" );
10576 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of array move)" );
10577
10578 switch( string->type ) {
10579 case VT_STRING:
10580 cpu_move_8bit( _environment, string->realName, size->realName );
10581 cpu_addressof_16bit( _environment, string->realName, address->realName );
10582 cpu_inc_16bit( _environment, address->realName );
10583 cpu_dsfree( _environment, dstring->realName );
10584 outline1("; LINE: %d", __LINE__);
10585 cpu_dsalloc( _environment, size->realName, dstring->realName );
10586 cpu_dsdescriptor( _environment, dstring->realName, address2->realName, size2->realName );
10587 cpu_mem_move(_environment, address->realName, address2->realName, size->realName );
10588 break;
10589 case VT_DSTRING:
10590 // cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
10591 // cpu_dsfree( _environment, dstring->realName );
10592 // cpu_dsalloc( _environment, size->realName, dstring->realName );
10593 // cpu_dsdescriptor( _environment, dstring->realName, address2->realName, size2->realName );
10594 // cpu_mem_move(_environment, address->realName, address2->realName, size->realName );
10595 cpu_dsassign( _environment, string->realName, dstring->realName );
10596 break;
10597 default:
10599 }
10600
10601 cpu_move_8bit_indirect( _environment, dstring->realName, offset->realName );
10602 cpu_store_8bit( _environment, dstring->realName, 0 );
10603}
10604
10605// @bit2: ok
10607
10608 if ( _array->bankAssigned != -1 ) {
10610 }
10611
10612 Variable * tmp = variable_temporary( _environment, VT_BYTE, "(element from array)" );
10613 Variable * result = variable_temporary( _environment, VT_BIT, "(element from array)" );
10614
10615 Variable * offset = calculate_offset_in_array( _environment, _array->name );
10616 Variable * position = variable_temporary( _environment, VT_BYTE, "(position)");
10617 variable_move( _environment, offset->name, position->name );
10618 Variable * positionInside = variable_and_const( _environment, position->name, 7 );
10619 offset = variable_sr_const( _environment, offset->name, 3 );
10620
10621 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10622
10623 cpu_move_8bit_indirect2( _environment, offset->realName, tmp->realName );
10624
10626
10627 cpu_bit_check_extended( _environment, tmp->realName, positionInside->realName, NULL, 8 );
10628
10629 cpu_bit_inplace_8bit( _environment, result->realName, result->bitPosition, NULL );
10630
10631 return result;
10632
10633}
10634
10636
10637 Variable * result = variable_temporary( _environment, VT_BIT, "(element from array)" );
10638
10639 variable_move_from_array_bit_inplace( _environment, _array, result );
10640
10641 return result;
10642
10643}
10644
10645void variable_move_from_array_byte_inplace( Environment * _environment, Variable * _array, Variable * _result ) {
10646
10647 _result->typeType = _array->typeType;
10648 if ( _array->typeType ) {
10649 _result->size = _array->typeType->size;
10650 }
10651
10652 if ( _array->bankAssigned == -1 ) {
10653
10654 if ( _array->arrayDimensions == 1 && _array->arrayDimensionsEach[0] <= 256 && VT_BITWIDTH( _array->arrayType ) == 8 && _environment->arrayIndexesEach[_environment->arrayNestedIndex][0] != NULL ) {
10655 Variable * index = variable_retrieve_or_define( _environment, _environment->arrayIndexesEach[_environment->arrayNestedIndex][0], VT_BYTE, 0 );
10656 if ( _environment->checkBoundary ) {
10658 char checkBoundaryOk[MAX_TEMPORARY_STORAGE]; sprintf( checkBoundaryOk, "%s", label );
10659 Variable * checkBoundary = variable_less_than_const( _environment, index->name, _array->arrayDimensionsEach[0], 0 );
10660 cpu_compare_and_branch_8bit_const( _environment, checkBoundary->realName, 0xff, checkBoundaryOk, 1 );
10661 error_out_of_boundary( _environment );
10662 cpu_label( _environment, checkBoundaryOk );
10663 }
10664 cpu_move_8bit_indirect2_8bit( _environment, _array->realName, index->realName, _result->realName );
10665 } else if ( _array->arrayDimensions == 1 && _array->arrayDimensionsEach[0] <= 65535 && VT_BITWIDTH( _array->arrayType ) == 8 && _environment->arrayIndexesEach[_environment->arrayNestedIndex][0] != NULL ) {
10666 Variable * index = variable_retrieve_or_define( _environment, _environment->arrayIndexesEach[_environment->arrayNestedIndex][0], VT_WORD, 0 );
10667 if ( _environment->checkBoundary ) {
10669 char checkBoundaryOk[MAX_TEMPORARY_STORAGE]; sprintf( checkBoundaryOk, "%s", label );
10670 Variable * checkBoundary = variable_less_than_const( _environment, index->name, _array->arrayDimensionsEach[0], 0 );
10671 cpu_compare_and_branch_8bit_const( _environment, checkBoundary->realName, 0xff, checkBoundaryOk, 1 );
10672 error_out_of_boundary( _environment );
10673 cpu_label( _environment, checkBoundaryOk );
10674 }
10675 cpu_move_8bit_indirect2_16bit( _environment, _array->realName, index->realName, _result->realName );
10676 } else if ( _array->arrayDimensions == 1 && _array->arrayDimensionsEach[0] <= 256 && VT_BITWIDTH( _array->arrayType ) == 16 && _environment->arrayIndexesEach[_environment->arrayNestedIndex][0] != NULL ) {
10677 Variable * index = variable_retrieve_or_define( _environment, _environment->arrayIndexesEach[_environment->arrayNestedIndex][0], VT_BYTE, 0 );
10678 if ( _environment->checkBoundary ) {
10680 char checkBoundaryOk[MAX_TEMPORARY_STORAGE]; sprintf( checkBoundaryOk, "%s", label );
10681 Variable * checkBoundary = variable_less_than_const( _environment, index->name, _array->arrayDimensionsEach[0], 0 );
10682 cpu_compare_and_branch_8bit_const( _environment, checkBoundary->realName, 0xff, checkBoundaryOk, 1 );
10683 error_out_of_boundary( _environment );
10684 cpu_label( _environment, checkBoundaryOk );
10685 }
10686 cpu_move_16bit_indirect2_8bit( _environment, _array->realName, index->realName, _result->realName );
10687 } else if ( _array->size < 256 && VT_BITWIDTH( _array->arrayType ) == 8 ) {
10688 if ( _environment->arrayIndexes[_environment->arrayNestedIndex] == 1 ) {
10689 if ( _environment->arrayIndexesEach[_environment->arrayNestedIndex][0] == NULL ) {
10690
10691 char precalculatedOffsetName[MAX_TEMPORARY_STORAGE];
10692 sprintf( precalculatedOffsetName, "%s%2.2xaddr", _array->name, _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][0] );
10693
10694 Constant * precalculatedOffset = constant_find( _environment, precalculatedOffsetName );
10695
10696 if ( !precalculatedOffset ) {
10697 precalculatedOffset = malloc( sizeof( Constant ) );
10698 memset( precalculatedOffset, 0, sizeof( Constant ) );
10699 precalculatedOffset->name = strdup( precalculatedOffsetName );
10700 precalculatedOffset->realName = strdup( precalculatedOffsetName );
10701 precalculatedOffset->value = _environment->arrayIndexesDirectEach[_environment->arrayNestedIndex][0];
10702 precalculatedOffset->type = CT_INTEGER;
10703 precalculatedOffset->relative = _array->realName;
10704 precalculatedOffset->next = _environment->constants;
10705 _environment->constants = precalculatedOffset;
10706 }
10707
10708 cpu_move_8bit( _environment, precalculatedOffset->realName, _result->realName );
10709
10710 return;
10711 }
10712 }
10713
10714 Variable * offset = calculate_offset_in_array_byte( _environment, _array->name );
10715 cpu_move_8bit_indirect2_8bit( _environment, _array->realName, offset->realName, _result->realName );
10716 } else if ( _array->size < 256 && VT_BITWIDTH( _array->arrayType ) == 16 ) {
10717 Variable * offset = calculate_offset_in_array_byte( _environment, _array->name );
10718 cpu_move_16bit_indirect2_8bit( _environment, _array->realName, offset->realName, _result->realName );
10719 } else {
10720
10721 // @bit2: ok
10722 Variable * offset = calculate_offset_in_array( _environment, _array->name);
10723
10724 switch( _array->arrayType ) {
10725 case VT_STRING: {
10726
10728
10729 break;
10730 }
10731 case VT_TILES:{
10732
10733 offset = variable_sl_const( _environment, offset->name, 2 );
10734
10735 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10736
10737 cpu_move_32bit_indirect2( _environment, offset->realName, _result->realName );
10738
10739 break;
10740
10741 }
10742 case VT_TYPE: {
10743
10744 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT(_array->typeType->size) );
10745
10746 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10747
10748 cpu_move_nbit_indirect2( _environment, _array->typeType->size*8, offset->realName, _result->realName );
10749
10750 break;
10751
10752 }
10753 case VT_PATH: {
10754
10755 offset = variable_sl_const( _environment, offset->name, 4 );
10756
10757 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10758
10759 cpu_move_nbit_indirect2( _environment, 16*8, offset->realName, _result->realName );
10760
10761 break;
10762
10763 }
10764 case VT_VECTOR2: {
10765
10766 offset = variable_sl_const( _environment, offset->name, 2 );
10767
10768 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10769
10770 cpu_move_nbit_indirect2( _environment, 4*8, offset->realName, _result->realName );
10771
10772 break;
10773
10774 }
10775 case VT_TILESET:
10776 case VT_TILE:
10777 case VT_SPRITE: {
10778
10779 offset = variable_sl_const( _environment, offset->name, 0 );
10780
10781 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10782
10783 cpu_move_8bit_indirect2( _environment, offset->realName, _result->realName );
10784
10785 break;
10786
10787 }
10788 case VT_MSPRITE: {
10789
10790 offset = variable_sl_const( _environment, offset->name, 1 );
10791
10792 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10793
10794 cpu_move_16bit_indirect2( _environment, offset->realName, _result->realName );
10795
10796 break;
10797
10798 }
10799 case VT_DSTRING: {
10800
10801 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10802
10803 Variable * dstring = variable_temporary( _environment, _array->arrayType, "(array element)");
10804
10805 cpu_move_8bit_indirect2( _environment, offset->realName, dstring->realName );
10806
10807 // Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of array move)" );
10808 // Variable * size = variable_temporary( _environment, VT_BYTE, "(result of array move)" );
10809 // Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(result of array move)" );
10810 // Variable * size2 = variable_temporary( _environment, VT_BYTE, "(result of array move)" );
10811
10812 // cpu_dsdescriptor( _environment, dstring->realName, address->realName, size->realName );
10813 // cpu_dsfree( _environment, _result->realName );
10814 // outline1("; LINE: %d", __LINE__);
10815 // cpu_dsalloc( _environment, size->realName, _result->realName );
10816 // cpu_dsdescriptor( _environment, _result->realName, address2->realName, size2->realName );
10817 // cpu_mem_move(_environment, address->realName, address2->realName, size->realName );
10818
10819 cpu_dsassign( _environment, dstring->realName, _result->realName );
10820
10821 break;
10822 }
10823
10824 case VT_FLOAT: {
10825
10827
10828 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10829
10830 cpu_move_nbit_indirect2( _environment, VT_FLOAT_BITWIDTH( _array->arrayPrecision ), offset->realName, _result->realName );
10831
10832 break;
10833
10834 }
10835
10836 case VT_NUMBER: {
10837
10838 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT( _environment->numberConfig.maxBytes ) );
10839
10840 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10841
10842 cpu_move_nbit_indirect2( _environment, _environment->numberConfig.maxBytes << 3, offset->realName, _result->realName );
10843
10844 break;
10845
10846 }
10847
10848 case VT_IMAGEREF: {
10849
10850 offset = variable_sl_const( _environment, offset->name, 4 );
10851
10852 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10853
10854 cpu_move_nbit_indirect2( _environment, 14 * 8, offset->realName, _result->realName );
10855
10856 break;
10857
10858 }
10859
10860 default: {
10861
10862 if ( _array->arrayType == 0 ) {
10864 _array->arrayType = VT_WORD;
10865 }
10866
10867 switch( VT_BITWIDTH( _array->arrayType ) ) {
10868 case 32:
10869 offset = variable_sl_const( _environment, offset->name, 2 );
10870 break;
10871 case 16:
10872 offset = variable_sl_const( _environment, offset->name, 1 );
10873 break;
10874 case 8:
10875 break;
10876 case 1:
10878 break;
10879 case 0:
10881 }
10882
10883 cpu_math_add_16bit_with_16bit( _environment, offset->realName, _array->realName, offset->realName );
10884
10885 switch( VT_BITWIDTH( _array->arrayType ) ) {
10886 case 32:
10887 cpu_move_32bit_indirect2( _environment, offset->realName, _result->realName );
10888 break;
10889 case 16:
10890 cpu_move_16bit_indirect2( _environment, offset->realName, _result->realName);
10891 break;
10892 case 8:
10893 cpu_move_8bit_indirect2( _environment, offset->realName, _result->realName );
10894 break;
10895 case 1:
10897 case 0:
10899
10900 }
10901
10902 }
10903
10904 }
10905
10906 }
10907
10908
10909 } else {
10910
10911 // @bit2: ok
10912 Variable * offset = calculate_offset_in_array( _environment, _array->name);
10913
10914 switch( _array->arrayType ) {
10915 case VT_STRING: {
10916
10918
10919 break;
10920 }
10921 case VT_TILES: {
10922
10923 offset = variable_sl_const( _environment, offset->name, 4 );
10924
10925 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10926 bank_read_vars_bank_direct_size( _environment, _array->bankAssigned, offset->name, _result->name, 4 );
10927
10928 break;
10929
10930 }
10931 case VT_TILESET:
10932 case VT_TILE:
10933 case VT_SPRITE: {
10934
10935 offset = variable_sl_const( _environment, offset->name, 0 );
10936
10937 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10938 bank_read_vars_bank_direct_size( _environment, _array->bankAssigned, offset->name, _result->name, 1 );
10939
10940 break;
10941
10942 }
10943 case VT_MSPRITE: {
10944
10945 offset = variable_sl_const( _environment, offset->name, 1 );
10946
10947 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
10948 bank_read_vars_bank_direct_size( _environment, _array->bankAssigned, offset->name, _result->name, 2 );
10949
10950 break;
10951
10952 }
10953 case VT_DSTRING: {
10954
10956
10957 break;
10958 }
10959
10960 case VT_FLOAT: {
10961
10963
10964 break;
10965
10966 }
10967
10968 case VT_NUMBER: {
10969
10971
10972 break;
10973
10974 }
10975
10976 default: {
10977
10978 if ( _array->arrayType == 0 ) {
10980 _array->arrayType = VT_WORD;
10981 }
10982
10983 switch( VT_BITWIDTH( _array->arrayType ) ) {
10984 case 32:
10985 offset = variable_sl_const( _environment, offset->name, 2 );
10986 break;
10987 case 16:
10988 offset = variable_sl_const( _environment, offset->name, 1 );
10989 break;
10990 case 8:
10991 break;
10992 case 1:
10994 break;
10995 case 0:
10996 switch( _array->arrayType ) {
10997 case VT_PATH:
10998 offset = variable_sl_const( _environment, offset->name, 4 );
10999 break;
11000 case VT_TYPE:
11001 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT( _array->typeType->size ) );
11002 break;
11003 default:
11005 }
11006 }
11007
11008 switch( VT_BITWIDTH( _array->arrayType ) ) {
11009 case 32:
11010 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
11011 bank_read_vars_bank_direct_size( _environment, _array->bankAssigned, offset->name, _result->name, 4 );
11012 break;
11013 case 16:
11014 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
11015 bank_read_vars_bank_direct_size( _environment, _array->bankAssigned, offset->name, _result->name, 2 );
11016 break;
11017 case 8:
11018 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
11019 bank_read_vars_bank_direct_size( _environment, _array->bankAssigned, offset->name, _result->name, 1 );
11020 break;
11021 case 1:
11023 case 0:
11024 switch( _array->arrayType ) {
11025 case VT_PATH:
11026 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
11027 bank_read_vars_bank_direct_size( _environment, _array->bankAssigned, offset->name, _result->name, 16 );
11028 break;
11029 case VT_TYPE:
11030 cpu_math_add_16bit_const( _environment, offset->realName, _array->absoluteAddress, offset->realName );
11031 bank_read_vars_bank_direct_size( _environment, _array->bankAssigned, offset->name, _result->name, _array->typeType->size );
11032 break;
11033 default:
11035 }
11036 }
11037
11038 }
11039
11040 }
11041
11042 }
11043
11044}
11045
11047
11048 Variable * result = variable_temporary( _environment, _array->arrayType, "(element from array)" );
11049
11050 variable_move_from_array_byte_inplace( _environment, _array, result );
11051
11052 return result;
11053
11054}
11055
11056void variable_move_from_array_inplace( Environment * _environment, char * _array, char * _result ) {
11057
11058 Variable * array = variable_retrieve( _environment, _array );
11059 Variable * result = variable_retrieve( _environment, _result );
11060
11061 if ( array->type != VT_TARRAY ) {
11062 CRITICAL_NOT_ARRAY( _array );
11063 }
11064
11065 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
11066 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
11067 }
11068
11069 if ( array->arrayType != VT_BIT ) {
11070 variable_move_from_array_byte_inplace( _environment, array, result );
11071 } else {
11072 variable_move_from_array_bit_inplace( _environment, array, result );
11073 }
11074
11075}
11076
11077Variable * variable_move_from_array( Environment * _environment, char * _array ) {
11078
11079 Variable * array = variable_retrieve( _environment, _array );
11080 Variable * result = NULL;
11081
11082 if ( array->type != VT_TARRAY ) {
11083 CRITICAL_NOT_ARRAY( _array );
11084 }
11085
11086 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
11087 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
11088 }
11089
11090 if ( array->arrayType != VT_BIT ) {
11091 result = variable_move_from_array_byte( _environment, array );
11092 } else {
11093 result = variable_move_from_array_bit( _environment, array );
11094 }
11095
11096 return result;
11097
11098}
11099
11100int pattern_match(char *_pattern, char * _value)
11101{
11102
11103 // If we reach at the end of both strings, we are done
11104 if (*_pattern == '\0' && *_value == '\0')
11105 return 1;
11106
11107 // Make sure that the characters after '*' are present
11108 // in second string. This function assumes that the first
11109 // string will not contain two consecutive '*'
11110 if (*_pattern == '*' && *(_pattern+1) != '\0' && *_value == '\0')
11111 return 1;
11112
11113 // If the first string contains '?', or current characters
11114 // of both strings match
11115 if (*_pattern == '?' || *_pattern == *_value)
11116 return pattern_match(_pattern+1, _value+1);
11117
11118 // If there is *, then there are two possibilities
11119 // a) We consider current character of second string
11120 // b) We ignore current character of second string.
11121 if (*_pattern == '*')
11122 return pattern_match(_pattern+1, _value) || pattern_match(_pattern, _value+1);
11123 return 0;
11124
11125}
11126
11127
11138/* <usermanual>
11139@keyword BIN
11140
11141@english
11142
11143The ''BIN'' command allows you to convert a decimal number into a binary
11144representation. In other words, it takes a number that we are used to
11145writing in base 10 (with the digits 0 through 9) and turns it into a
11146sequence of 0s and 1s, which is the base that computers use to represent
11147data internally. It decode from the most significant to the least significant.
11148
11149It is also possible to indicate the number of digits to be represented.
11150If this parameter is omitted, the minimum number of digits for that data
11151format (8, 16 or 32 digits) will be used. Moreover, you can use a different
11152set of symbols instead of "0" and "1", by using the last two parameters.
11153
11154This command is essential for those who want to delve deeper into how
11155computers work at a lower level. Infact, this command allows you to
11156operate directly on individual bits of a number, which is useful in
11157some applications such as graphics or communications. Moreover,
11158many encryption algorithms rely on bit-level operations.
11159
11160@italian
11161
11162Il comando ''BIN'' consente di convertire un numero decimale in una
11163rappresentazione binaria. In altre parole, prende un numero che siamo
11164abituati a scrivere in base 10 (con le cifre da 0 a 9) e lo trasforma
11165in una sequenza di 0 e 1, che è la base che i computer utilizzano per
11166rappresentare i dati internamente. Decodifica dal più significativo
11167al meno significativo. È anche possibile indicare il numero di cifre
11168da rappresentare.
11169
11170Se questo parametro viene omesso, verrà utilizzato il numero minimo
11171di cifre per quel formato di dati (8, 16 o 32 cifre). Inoltre,
11172puoi utilizzare un differente insieme di simboli invece di "0" e
11173"1", utilizzando gli ultimi due parametri.
11174
11175Questo comando è essenziale per coloro che desiderano approfondire
11176il funzionamento dei computer a un livello inferiore. Infatti,
11177questo comando consente di operare direttamente su singoli bit di
11178un numero, il che è utile in alcune applicazioni come la grafica
11179o le comunicazioni. Inoltre, molti algoritmi di crittografia si
11180basano su operazioni a livello di bit.
11181
11182@syntax = BIN( value [, digits] [, zero, one ] )
11183
11184@example x = BIN(42)
11185@example z = BIN(42, 5)
11186@example k = BIN(255, 5, " ", "*"): REM k = "********"
11187
11188@target all
11189@verified
11190 </usermanual> */
11191 /* <usermanual>
11192@keyword %%
11193
11194@english
11195
11196@italian
11197
11198@syntax = %%(expression)
11199
11200@example x = %%( 42 )
11201@example PRINT %%( y )
11202
11203@alias BIN
11204
11205@target all
11206 </usermanual> */
11207/* <usermanual>
11208@keyword BIN$
11209
11210@english
11211
11212@italian
11213
11214@syntax = BIN$( value [, digits] [, zero, one] )
11215
11216@alias BIN
11217 </usermanual> */
11218
11219Variable * variable_bin( Environment * _environment, char * _value, char * _digits, char * _zero, char * _one ) {
11220
11222
11223 Variable * originalValue = variable_retrieve( _environment, _value );
11224 Variable * digits = NULL;
11225 if ( _digits ) {
11226 digits = variable_retrieve_or_define( _environment, _digits, VT_BYTE, 8 );
11227 }
11228 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result of BIN)" );
11229 Variable * pad = variable_temporary( _environment, VT_BYTE, "(is padding needed?)");
11230
11231 Variable * zero = NULL;
11232 if ( _zero ) {
11233 Variable * realZero = variable_retrieve( _environment, _zero );
11234 zero = variable_string_asc( _environment, realZero->name );
11235 }
11236 Variable * one = NULL;
11237 if ( _one ) {
11238 Variable * realOne = variable_retrieve( _environment, _one );
11239 one = variable_string_asc( _environment, realOne->name );
11240 }
11241
11242 switch( VT_BITWIDTH( originalValue->type ) ) {
11243 case 1:
11244 case 0:
11245 CRITICAL_BIN_UNSUPPORTED( _value, DATATYPE_AS_STRING[originalValue->type]);
11246 break;
11247 case 32:
11248 variable_store_string( _environment, result->name, "00000000000000000000000000000000" );
11249 break;
11250 case 16:
11251 variable_store_string( _environment, result->name, "0000000000000000" );
11252 break;
11253 case 8:
11254 variable_store_string( _environment, result->name, "00000000" );
11255 break;
11256 }
11257
11258 char finishedLabel[MAX_TEMPORARY_STORAGE]; sprintf(finishedLabel, "%send", label);
11259 char padLabel[MAX_TEMPORARY_STORAGE]; sprintf(padLabel, "%spad", label);
11260 char truncateLabel[MAX_TEMPORARY_STORAGE]; sprintf(truncateLabel, "%strunc", label);
11261
11262 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(result of val)" );
11263 Variable * size = variable_temporary( _environment, VT_BYTE, "(result of val)" );
11264 cpu_dswrite( _environment, result->realName );
11265 cpu_dsdescriptor( _environment, result->realName, address->realName, size->realName );
11266
11267 cpu_bits_to_string( _environment, originalValue->realName, address->realName, size->realName, VT_BITWIDTH( originalValue->type ), (zero?zero->realName:NULL), (one?one->realName:NULL) );
11268
11269 if ( digits ) {
11270 Variable * result2 = variable_temporary( _environment, VT_DSTRING, "(padding/truncating)" );
11271 Variable * address2 = variable_temporary( _environment, VT_ADDRESS, "(padding/truncating)" );
11272 Variable * size2 = variable_temporary( _environment, VT_BYTE, "(padding/truncating)" );
11273 Variable * zero = variable_temporary( _environment, VT_BYTE, "(0)" );
11274
11275 cpu_store_8bit( _environment, zero->realName, '0' );
11276
11277 cpu_less_than_8bit( _environment, size->realName, digits->realName, pad->realName, 0, 0 );
11278
11279 cpu_dsfree( _environment, result2->realName );
11280 cpu_dsalloc( _environment, digits->realName, result2->realName );
11281
11282 cpu_bveq( _environment, pad->realName, truncateLabel );
11283
11284 cpu_label( _environment, padLabel );
11285
11286 cpu_dsdescriptor( _environment, result2->realName, address2->realName, size2->realName );
11287 cpu_fill( _environment, address2->realName, digits->realName, VT_BITWIDTH( digits->type ), zero->realName );
11288
11289 cpu_math_add_16bit_with_8bit( _environment, address2->realName, digits->realName, address2->realName );
11290 cpu_math_sub_16bit_with_8bit( _environment, address2->realName, size->realName, address2->realName );
11291 cpu_mem_move( _environment, address->realName, address2->realName, size->realName );
11292
11293 cpu_jump( _environment, finishedLabel );
11294
11295 cpu_label( _environment, truncateLabel );
11296
11297 cpu_dsdescriptor( _environment, result2->realName, address2->realName, size2->realName );
11298 cpu_math_add_16bit_with_8bit( _environment, address->realName, size->realName, address->realName );
11299 cpu_math_sub_16bit_with_8bit( _environment, address->realName, digits->realName, address->realName );
11300 // cpu_dec_16bit( _environment, address->realName );
11301 cpu_mem_move( _environment, address->realName, address2->realName, digits->realName );
11302
11303 cpu_label( _environment, finishedLabel );
11304
11305 cpu_dsfree( _environment, result->realName );
11306
11307 result = result2;
11308
11309 }
11310
11311 return result;
11312
11313}
11314
11323/* <usermanual>
11324@keyword HAS BIT
11325
11326@english
11327Think of a number as a sequence of switches, each of which can be on (1) or off (0).
11328Each switch represents a bit. The ''HAS BIT'' instruction will check
11329a bit on (1), by checking the state of a specific switch within this sequence.
11330The parameter ''position'' refers to the bit position inside the data. This value
11331is zero based, and starts from the less significative bit and go on.
11332
11333@italian
11334Pensa a un numero come a una sequenza di switch, ognuno dei quali può essere
11335acceso (1) o spento (0). Ogni switch rappresenta un bit. L'istruzione ''HAS BIT''
11336controllerà un bit acceso (1), controllando lo stato di uno switch specifico
11337all'interno di questa sequenza. Il parametro ''position'' si riferisce alla
11338posizione del bit all'interno dei dati. Questo valore è zero-based e inizia
11339dal bit meno significativo.
11340
11341@syntax = value HAS BIT position
11342
11343@example IF x HAS BIT 2 THEN: PRINT "bit 2 is 1!": ENDIF
11344
11345@usedInExample controls_joy_02.bas
11346@usedInExample controls_keyboard_06.bas
11347@usedInExample screens_bitmap_01.bas
11348@usedInExample screens_tilemap_01.bas
11349
11350@seeAlso HAS NOT BIT
11351@alias IS
11352@alias IS NOT
11353
11354@target all
11355 </usermanual> */
11356/* <usermanual>
11357@keyword HAS NOT BIT
11358
11359@english
11360Think of a number as a sequence of switches, each of which can be on (1) or off (0).
11361Each switch represents a bit. The ''HAS NOT BIT'' instruction will check
11362a bit off (0), by checking the state of a specific switch within this sequence.
11363The parameter ''position'' refers to the bit position inside the data. This value
11364is zero based, and starts from the less significative bit and go on.
11365
11366@italian
11367Pensa a un numero come a una sequenza di switch, ognuno dei quali può essere
11368acceso (1) o spento (0). Ogni switch rappresenta un bit. L'istruzione ''HAS NOT BIT''
11369controllerà un bit spento (0), controllando lo stato di uno switch specifico
11370all'interno di questa sequenza. Il parametro ''position'' si riferisce alla
11371posizione del bit all'interno dei dati. Questo valore è zero-based e inizia
11372dal bit meno significativo.
11373
11374@syntax = value HAS NOT BIT position
11375
11376@example IF x HAS NOT BIT 2 THEN: PRINT "bit 2 is 0": ENDIF
11377
11378@usedInExample controls_joy_02.bas
11379@usedInExample controls_keyboard_05.bas
11380
11381@seeAlso HAS NOT BIT
11382@alias IS
11383@alias IS NOT
11384
11385@target all
11386 </usermanual> */
11387/* <usermanual>
11388@keyword IS
11389
11390@english
11391
11392@italian
11393
11394@syntax = value IS position
11395
11396@example IF x IS 2 THEN: PRINT "bit 2 is 1!": ENDIF
11397
11398@usedInExample controls_joy_02.bas
11399@usedInExample controls_keyboard_03.bas
11400
11401@seeAlso IS NOT
11402@alias HAS BIT
11403@alias HAS NOT BIT
11404
11405@target all
11406 </usermanual> */
11407/* <usermanual>
11408@keyword IS NOT
11409
11410@english
11411
11412@italian
11413
11414@syntax = value IS NOT position
11415
11416@example IF x IS NOT 2 THEN: PRINT "bit 2 is 0": ENDIF
11417
11418@usedInExample controls_joy_02.bas
11419@usedInExample controls_keyboard_05.bas
11420
11421@seeAlso IS BIT
11422@alias HAS NOT BIT
11423
11424@target all
11425 </usermanual> */
11426/* <usermanual>
11427@keyword BIT...OF
11428
11429@english
11430
11431@italian
11432
11433@syntax = BIT position OF value
11434
11435@example IF BIT 2 OF x THEN: PRINT "bit 2 is 1!": ENDIF
11436
11437@alias HAS BIT
11438@alias BIT (function)
11439
11440@target all
11441 </usermanual> */
11442 /* <usermanual>
11443@keyword BIT (function)
11444
11445@english
11446
11447@italian
11448
11449@syntax = BIT( value, position )
11450
11451@example IF BIT( 2, x )
11452@example PRINT "bit 2 is 1!"
11453@example ENDIF
11454
11455@alias HAS BIT
11456@alias BIT OF
11457
11458@target all
11459 </usermanual> */
11460
11461Variable * variable_bit( Environment * _environment, char * _value, char * _position ) {
11462 Variable * value = variable_retrieve( _environment, _value );
11463 Variable * position = variable_retrieve_or_define( _environment, _position, VT_BYTE, 1 );
11464 Variable * result = variable_temporary( _environment, VT_SBYTE, "(result of BIT)");
11465
11467
11468 char unsetLabel[MAX_TEMPORARY_STORAGE]; sprintf(unsetLabel, "%sunset", label );
11469 char setLabel[MAX_TEMPORARY_STORAGE]; sprintf(setLabel, "%sset", label );
11470 char endLabel[MAX_TEMPORARY_STORAGE]; sprintf(endLabel, "%send", label );
11471
11472 switch( VT_BITWIDTH( value->type ) ) {
11473 case 32:
11474 case 16:
11475 case 8:
11476 cpu_bit_check_extended( _environment, value->realName, position->realName, result->realName, VT_BITWIDTH( value->type ) );
11477 break;
11478 case 1:
11479 case 0:
11481 break;
11482 }
11483
11484 return result;
11485}
11486
11488
11489 ScreenMode * screenMode = _environment->screenModes;
11490
11491 while ( screenMode ) {
11492 screenMode->selected = 0;
11493 screenMode = screenMode->next;
11494 }
11495
11496}
11497
11499
11500 int result = 0;
11501 ScreenMode * screenMode = _environment->screenModes;
11502
11503 while ( screenMode ) {
11504 if ( screenMode->selected ) {
11505 ++result;
11506 }
11507 screenMode = screenMode->next;
11508 }
11509
11510 return result;
11511
11512}
11513
11514ScreenMode * find_screen_mode_by_suggestion( Environment * _environment, int _bitmap, int _width, int _height, int _colors, int _tile_width, int _tile_height ) {
11515
11516 ScreenMode * screenMode = _environment->screenModes;
11517 ScreenMode * firstMode = NULL;
11518
11519 while ( screenMode ) {
11520 if ( screenMode->bitmap == _bitmap ) {
11521 firstMode = screenMode;
11522 break;
11523 }
11524 screenMode = screenMode->next;
11525 }
11526
11527 if ( ! _width && ! _height && ! _colors ) {
11528 return firstMode;
11529 }
11530
11531 screenMode = _environment->screenModes;
11532 ScreenMode * bestMode = NULL;
11533
11534 while ( screenMode ) {
11535 if ( screenMode->bitmap == _bitmap ) {
11536 screenMode->score = 1000;
11537 if ( _width < 0 ) {
11538 screenMode->score -= abs( screenMode->width + _width );
11539 } else if ( _height < 0 ) {
11540 screenMode->score -= abs( screenMode->width + _height );
11541 } else {
11542 screenMode->score -= ( _width ) ? ( abs( _width - screenMode->width ) ) : 0;
11543 screenMode->score -= ( _height ) ? ( abs( _height - screenMode->height ) ) : 0;
11544 screenMode->score -= ( _colors ) ? ( abs( _colors - screenMode->colors ) * 100 ) : 0;
11545 screenMode->score -= ( _tile_width ) ? ( abs( _tile_width - screenMode->tileWidth ) * 10 ) : 0;
11546 screenMode->score -= ( _tile_height ) ? ( abs( _tile_height - screenMode->tileHeight ) * 10 ) : 0;
11547 }
11548 } else {
11549 screenMode->score = -1000;
11550 }
11551 screenMode = screenMode->next;
11552 }
11553
11554 screenMode = _environment->screenModes;
11555 bestMode = firstMode;
11556
11557 if ( firstMode ) {
11558 while ( screenMode ) {
11559 if ( screenMode->score > bestMode->score ) {
11560 bestMode = screenMode;
11561 }
11562 screenMode = screenMode->next;
11563 }
11564 }
11565
11566 return bestMode;
11567
11568}
11569
11570ScreenMode * find_screen_mode_by_id( Environment * _environment, int _id ) {
11571
11572 ScreenMode * screenMode = _environment->screenModes;
11573 ScreenMode * firstMode = NULL;
11574
11575 while ( screenMode ) {
11576 if ( screenMode->id == _id ) {
11577 firstMode = screenMode;
11578 break;
11579 }
11580 screenMode = screenMode->next;
11581 }
11582
11583 return firstMode;
11584
11585}
11586
11587/* <usermanual>
11588@keyword MOD
11589
11590@english
11591
11592The ''MOD'' operator is used to perform the modulo operation. This operation
11593returns the remainder of the integer division of two numbers.
11594The result of a ''MOD'' operation will not retain the sign of any, and so it may be
11595only positive. The result is always in the range ''[0, divisor)'', exclusive.
11596
11597If the result of ''MOD'' is 0, it means that the first number is divisible
11598by the second. Often used in conjunction with a pseudo-random number generator
11599to obtain random numbers within a certain range. It can be used to create loops
11600that repeat a certain number of times or to handle situations that repeat
11601periodically.
11602
11603For example:
11604
11605'''8 Mod 3 = 2'''
11606'''-8 Mod 3 = 2'''
11607'''8 Mod -3 = 2'''
11608'''-8 Mod -3 = 2'''
11609
11610If divisor evaluates to zero, the behavior of the ''MOD'' operator is to return the
11611dividend as result, without sign.
11612
11613@italian
11614
11615L'operatore ''MOD'' viene utilizzato per eseguire l'operazione di modulo.
11616Questa operazione restituisce il resto dell'intera divisione di due numeri.
11617Il risultato di un'operazione ''MOD'' non manterrà il segno di nessuno,
11618quindi può essere solo positivo. Il risultato è sempre compreso nell'intervallo
11619''[0, divisore)'', escluso.
11620
11621Ad esempio:
11622
11623'''8 Mod 3 = 2'''
11624'''-8 Mod 3 = 2'''
11625'''8 Mod -3 = 2'''
11626'''-8 Mod -3 = 2'''
11627
11628Se il risultato di ''MOD'' è 0, significa che il primo numero è divisibile
11629per il secondo. Spesso utilizzato insieme a un generatore di numeri
11630pseudo-casuali per ottenere numeri casuali entro un certo intervallo.
11631Può essere utilizzato per creare cicli che si ripetono un certo
11632numero di volte o per gestire situazioni che si ripetono periodicamente.
11633
11634Se il divisore è pari a zero, il comportamento dell'operatore ''MOD'' è quello
11635di restituire il dividendo come risultato, senza segno.
11636
11637@syntax = x MOD y
11638
11639@example IF x MOD 2 THEN
11640@example PRINT "odd"
11641@example ELSE
11642@example PRINT "even"
11643@example ENDIF
11644
11645</usermanual> */
11646Variable * variable_mod( Environment * _environment, char * _source, char * _destination ) {
11647
11648 Variable * source = variable_retrieve( _environment, _source );
11649 Variable * target = variable_retrieve( _environment, _destination );
11650
11651 int best = calculate_cast_type_best_fit( _environment, source->type, target->type );
11652 source = variable_cast( _environment, source->name, best );
11653 target = variable_cast( _environment, target->name, best );
11654
11655 Variable * result = NULL;
11656 Variable * remainder = NULL;
11657 switch( VT_BITWIDTH( source->type ) ) {
11658 case 32:
11659 result = variable_temporary( _environment, VT_WORD, "(result of division)" );
11660 remainder = variable_temporary( _environment, VT_WORD, "(remainder of division)" );
11661 cpu_math_div_32bit_to_16bit( _environment, source->realName, target->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
11662 break;
11663 case 16:
11664 result = variable_temporary( _environment, VT_WORD, "(result of division)" );
11665 remainder = variable_temporary( _environment, VT_WORD, "(remainder of division)" );
11666 cpu_math_div_16bit_to_16bit( _environment, source->realName, target->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
11667 break;
11668 case 8:
11669 result = variable_temporary( _environment, VT_BYTE, "(result of division)" );
11670 remainder = variable_temporary( _environment, VT_BYTE, "(remainder of division)" );
11671 cpu_math_div_8bit_to_8bit( _environment, source->realName, target->realName, result->realName, remainder->realName, VT_SIGNED( source->type ) );
11672 break;
11673 case 1:
11674 case 0: {
11675 switch( source->type ) {
11676 case VT_NUMBER:
11677 result = variable_temporary( _environment, VT_NUMBER, "(result of division)" );
11678 remainder = variable_temporary( _environment, VT_NUMBER, "(remainder of division)" );
11679 cpu_math_div_nbit_to_nbit( _environment, source->realName, target->realName, result->realName, remainder->realName, _environment->numberConfig.maxBytes << 3 );
11680 default:
11681
11683 break;
11684 }
11685 }
11686
11687 }
11688
11689 return remainder;
11690}
11691
11692int label_exists_numeric( Environment * _environment, int _label ) {
11693
11694 Label * actual = _environment->labels;
11695 while( actual ) {
11696 if ( !actual->name && actual->number == _label ) {
11697 return 1;
11698 }
11699 actual = actual->next;
11700 }
11701 return 0;
11702
11703}
11704
11705int label_exists_named( Environment * _environment, char * _label ) {
11706
11707 Label * actual = _environment->labels;
11708 while( actual ) {
11709 if ( actual->name && !strcmp( actual->name, _label ) ) {
11710 return 1;
11711 }
11712 actual = actual->next;
11713 }
11714 return 0;
11715
11716}
11717
11718void label_define_numeric( Environment * _environment, int _label ) {
11719
11720 if (label_exists_numeric( _environment, _label )) {
11722 }
11723
11724 Label * label = malloc( sizeof( Label ) );
11725 memset( label, 0, sizeof( Label ) );
11726 label->number = _label;
11727 Label * last = _environment->labels;
11728 if ( last ) {
11729 while( last->next ) {
11730 last = last->next;
11731 }
11732 last->next = label;
11733 } else {
11734 _environment->labels = label;
11735 }
11736
11737}
11738
11739void label_define_named( Environment * _environment, char * _label ) {
11740
11741 if (label_exists_named( _environment, _label )) {
11743 }
11744
11745 Label * label = malloc( sizeof( Label ) );
11746 memset( label, 0, sizeof( Label ) );
11747 label->name = strdup( _label );
11748 Label * last = _environment->labels;
11749 if ( last ) {
11750 while( last->next ) {
11751 last = last->next;
11752 }
11753 last->next = label;
11754 } else {
11755 _environment->labels = label;
11756 }
11757
11758}
11759
11760int label_referred_exists_numeric( Environment * _environment, int _label ) {
11761
11762 Label * actual = _environment->referredLabels;
11763 while( actual ) {
11764 if ( !actual->name && actual->number == _label ) {
11765 return 1;
11766 }
11767 actual = actual->next;
11768 }
11769 return 0;
11770
11771}
11772
11773int label_referred_exists_named( Environment * _environment, char * _label ) {
11774
11775 Label * actual = _environment->referredLabels;
11776 while( actual ) {
11777 if ( actual->name && !strcmp( actual->name, _label ) ) {
11778 return 1;
11779 }
11780 actual = actual->next;
11781 }
11782 return 0;
11783
11784}
11785
11786void label_referred_define_numeric( Environment * _environment, int _label ) {
11787
11788 if (label_exists_numeric( _environment, _label )) {
11789 return;
11790 }
11791
11792 Label * label = malloc( sizeof( Label ) );
11793 memset( label, 0, sizeof( Label ) );
11794 label->number = _label;
11795 Label * last = _environment->referredLabels;
11796 if ( last ) {
11797 while( last->next ) {
11798 last = last->next;
11799 }
11800 last->next = label;
11801 } else {
11802 _environment->referredLabels = label;
11803 }
11804
11805}
11806
11807void label_referred_define_named( Environment * _environment, char * _label ) {
11808
11809 if (label_referred_exists_named( _environment, _label )) {
11810 return;
11811 }
11812
11813 Label * label = malloc( sizeof( Label ) );
11814 memset( label, 0, sizeof( Label ) );
11815 label->name = strdup( _label );
11816 Label * last = _environment->referredLabels;
11817 if ( last ) {
11818 while( last->next ) {
11819 last = last->next;
11820 }
11821 last->next = label;
11822 } else {
11823 _environment->referredLabels = label;
11824 }
11825
11826}
11827
11828int label_stored_exists_named( Environment * _environment, char * _label ) {
11829
11830 Label * actual = _environment->storedLabels;
11831 while( actual ) {
11832 if ( actual->name && !strcmp( actual->name, _label ) ) {
11833 return 1;
11834 }
11835 actual = actual->next;
11836 }
11837 return 0;
11838
11839}
11840
11841void label_stored_define_named( Environment * _environment, char * _label ) {
11842
11843 if (label_stored_exists_named( _environment, _label )) {
11844 return;
11845 }
11846
11847 Label * label = malloc( sizeof( Label ) );
11848 memset( label, 0, sizeof( Label ) );
11849 label->name = strdup( _label );
11850 Label * last = _environment->storedLabels;
11851 if ( last ) {
11852 while( last->next ) {
11853 last = last->next;
11854 }
11855 last->next = label;
11856 } else {
11857 _environment->storedLabels = label;
11858 }
11859
11860}
11861
11862void const_define_numeric( Environment * _environment, char * _name, int _value ) {
11863
11864 if ( _environment->emptyProcedure ) {
11865 return;
11866 }
11867
11868 if (variable_exists( _environment, _name )) {
11870 }
11871
11872 Constant * c = constant_find( _environment, _name );
11873 if ( c ) {
11874 if ( c->type == CT_STRING ) {
11876 }
11877 if ( c->type == CT_INTEGER ) {
11878 if ( c->value != _value ) {
11880 }
11881 } else {
11882 if ( (int)c->valueFloating != _value ) {
11884 }
11885 }
11886 } else {
11887 c = malloc( sizeof( Constant ) );
11888 memset( c, 0, sizeof( Constant ) );
11889 c->name = strdup( _name );
11890 c->realName = malloc( strlen( _name ) + strlen( c->name ) + 2 ); strcopy( c->realName, "_" ); strcat( c->realName, c->name );
11891 c->value = _value;
11892 c->type = CT_INTEGER;
11893 Constant * constLast = _environment->constants;
11894 if ( constLast ) {
11895 while( constLast->next ) {
11896 constLast = constLast->next;
11897 }
11898 constLast->next = c;
11899 } else {
11900 _environment->constants = c;
11901 }
11902 // const_emit( _environment, c->name );
11903 }
11904
11905}
11906
11907void const_define_string( Environment * _environment, char * _name, char * _value ) {
11908
11909 if ( _environment->emptyProcedure ) {
11910 return;
11911 }
11912
11913 if (variable_exists( _environment, _name )) {
11915 }
11916
11917 Constant * c = constant_find( _environment, _name );
11918 if ( c ) {
11919 if ( ! c->valueString ) {
11921 }
11922 if ( strcmp( c->valueString->value , _value ) != 0 ) {
11924 }
11925 } else {
11926 c = malloc( sizeof( Constant ) );
11927 memset( c, 0, sizeof( Constant ) );
11928 c->name = strdup( _name );
11929 c->realName = malloc( strlen( _name ) + strlen( c->name ) + 2 ); strcopy( c->realName, "_" ); strcat( c->realName, c->name );
11930 c->valueString = string_reserve( _environment, _value );
11931 c->type = CT_STRING;
11932 Constant * constLast = _environment->constants;
11933 if ( constLast ) {
11934 while( constLast->next ) {
11935 constLast = constLast->next;
11936 }
11937 constLast->next = c;
11938 } else {
11939 _environment->constants = c;
11940 }
11941
11942 // const_emit( _environment, c->name );
11943
11944 }
11945
11946}
11947
11948static void variable_array_fill_value( Environment * _environment, char * _name, int _value ) {
11949
11950 Variable * array = variable_retrieve( _environment, _name );
11951
11952 if ( array->type != VT_TARRAY ) {
11953 CRITICAL_NOT_ARRAY( array->name );
11954 }
11955
11956 if ( array->size > 0 ) {
11957
11959 char loopLabel[MAX_TEMPORARY_STORAGE]; sprintf( loopLabel, "%slabel", label );
11960 int sizeInElements = 1;
11961 for( int i=0; i<array->arrayDimensions; ++i ) {
11962 sizeInElements *= array->arrayDimensionsEach[i];
11963 }
11964 Variable * index;
11965 if ( sizeInElements < 256 ) {
11966 index = variable_temporary( _environment, VT_BYTE, "(index)");
11967 } else {
11968 index = variable_temporary( _environment, VT_WORD, "(index)");
11969 }
11970 variable_store( _environment, index->name, 0 );
11971 Variable * value = variable_temporary( _environment, array->arrayType, "value");
11972 variable_store( _environment, value->name, _value );
11973 Variable * count = NULL;
11974 Variable * startAddress = variable_temporary( _environment, VT_ADDRESS, "(startAddress)");
11975 cpu_addressof_16bit( _environment, array->realName, startAddress->realName );
11976 cpu_label( _environment, loopLabel );
11977 switch( VT_BITWIDTH( array->arrayType ) ) {
11978 case 32:
11979 cpu_poked( _environment, startAddress->realName, value->realName );
11980 variable_increment( _environment, startAddress->name );
11981 variable_increment( _environment, startAddress->name );
11982 variable_increment( _environment, startAddress->name );
11983 variable_increment( _environment, startAddress->name );
11984 break;
11985 case 16:
11986 cpu_pokew( _environment, startAddress->realName, value->realName );
11987 variable_increment( _environment, startAddress->name );
11988 variable_increment( _environment, startAddress->name );
11989 break;
11990 case 8:
11991 cpu_poke( _environment, startAddress->realName, value->realName );
11992 variable_increment( _environment, startAddress->name );
11993 break;
11994 default:
11995 CRITICAL_NOT_SUPPORTED( _name );
11996 }
11997 variable_increment( _environment, index->name );
11998 variable_compare_and_branch_const( _environment, index->name, sizeInElements, label, 1 );
11999 cpu_jump( _environment, loopLabel );
12000 cpu_label( _environment, label );
12001 } else {
12002 CRITICAL_NOT_SUPPORTED( array->name );
12003 }
12004
12005}
12006
12007/* <usermanual>
12008@keyword ARRAY COUNT
12009
12010@english
12011
12012The ''ARRAY COUNT'' statement counts all the elements inside a vector or ''array'',
12013returning the number of times a certain ''value'' is present. If the value parameter is omitted,
12014the counting of elements with a value of zero (0) is intended.
12015
12016@italian
12017
12018L'istruzione effettua un conteggio di tutti gli elementi all'interno di un vettore o matrice
12019array (quindi, un ''array'' generico), restituendo il numero di volte in cui un certo valore (''value')
12020è presente. Se il parametro value viene omesso, si intende il contreggio degli elementi con valore zero.
12021
12022@syntax = [ARRAY] COUNT( array[, value] )
12023
12024@example IF COUNT(vector) = 0 THEN: PRINT "vector is empty!": ENDIF
12025
12026@alias COUNT
12027
12028@target all
12029</usermanual> */
12030/* <usermanual>
12031@keyword COUNT
12032
12033@english
12034
12035@italian
12036
12037@alias ARRAY COUNT
12038
12039@target all
12040</usermanual> */
12041
12042Variable * variable_array_count_vars( Environment * _environment, char * _name, char * _target ) {
12043
12044 Variable * array = variable_retrieve( _environment, _name );
12045 Variable * count = NULL;
12046
12047 if ( array->type != VT_TARRAY ) {
12048 CRITICAL_NOT_ARRAY( array->name );
12049 }
12050
12051 if ( array->size > 0 ) {
12052
12054 char loopLabel[MAX_TEMPORARY_STORAGE]; sprintf( loopLabel, "%slabel", label );
12055 char targetLabel[MAX_TEMPORARY_STORAGE]; sprintf( targetLabel, "%starget", label );
12056 int sizeInElements = 1;
12057 for( int i=0; i<array->arrayDimensions; ++i ) {
12058 sizeInElements *= array->arrayDimensionsEach[i];
12059 }
12060 Variable * index;
12061 if ( sizeInElements < 256 ) {
12062 index = variable_temporary( _environment, VT_BYTE, "(index)");
12063 count = variable_temporary( _environment, VT_BYTE, "(count)");
12064 } else {
12065 index = variable_temporary( _environment, VT_WORD, "(index)");
12066 count = variable_temporary( _environment, VT_WORD, "(count)");
12067 }
12068 variable_store( _environment, index->name, 0 );
12069 variable_store( _environment, count->name, 0 );
12070 Variable * target = variable_retrieve_or_define( _environment, _target, array->arrayType, 0 );
12071 Variable * value = variable_temporary( _environment, array->arrayType, "value");
12072 Variable * startAddress = variable_temporary( _environment, VT_ADDRESS, "(startAddress)");
12073 cpu_addressof_16bit( _environment, array->realName, startAddress->realName );
12074 cpu_label( _environment, loopLabel );
12075 switch( VT_BITWIDTH( array->arrayType ) ) {
12076 case 32:
12077 cpu_peekd( _environment, startAddress->realName, value->realName );
12078 variable_increment( _environment, startAddress->name );
12079 variable_increment( _environment, startAddress->name );
12080 variable_increment( _environment, startAddress->name );
12081 variable_increment( _environment, startAddress->name );
12082 break;
12083 case 16:
12084 cpu_peekw( _environment, startAddress->realName, value->realName );
12085 variable_increment( _environment, startAddress->name );
12086 variable_increment( _environment, startAddress->name );
12087 break;
12088 case 8:
12089 cpu_peek( _environment, startAddress->realName, value->realName );
12090 variable_increment( _environment, startAddress->name );
12091 break;
12092 default:
12093 CRITICAL_NOT_SUPPORTED( _name );
12094 }
12095 cpu_compare_and_branch_8bit_const( _environment, variable_compare( _environment, value->name, target->name )->realName, 0, targetLabel, 1 );
12096 variable_increment( _environment, count->name );
12097 cpu_label( _environment, targetLabel );
12098 variable_increment( _environment, index->name );
12099 variable_compare_and_branch_const( _environment, index->name, sizeInElements, label, 1 );
12100 cpu_jump( _environment, loopLabel );
12101 cpu_label( _environment, label );
12102 } else {
12103 CRITICAL_NOT_SUPPORTED( array->name );
12104 }
12105
12106 return count;
12107
12108}
12109
12110/* <usermanual>
12111@keyword ARRAY SUM
12112
12113@english
12114
12115The ''ARRAY SUM'' statement sums all the elements inside a vector or ''array''.
12116
12117@italian
12118
12119L'istruzione effettua la somma di tutti gli elementi all'interno di un vettore o matrice
12120array (quindi, un ''array'' generico).
12121
12122@syntax = [ARRAY] SUM( array )
12123
12124@example IF SUM(vector) = 0 THEN: PRINT "vector is empty!": ENDIF
12125
12126@alias SUM
12127
12128@target all
12129</usermanual> */
12130/* <usermanual>
12131@keyword SUM
12132
12133@english
12134
12135@italian
12136
12137@alias ARRAY SUM
12138
12139@target all
12140</usermanual> */
12141
12142Variable * variable_array_sum_vars( Environment * _environment, char * _name ) {
12143
12144 Variable * array = variable_retrieve( _environment, _name );
12145 Variable * sum = NULL;
12146
12147 if ( array->type != VT_TARRAY ) {
12148 CRITICAL_NOT_ARRAY( array->name );
12149 }
12150
12151 if ( array->size > 0 ) {
12152
12154 char loopLabel[MAX_TEMPORARY_STORAGE]; sprintf( loopLabel, "%slabel", label );
12155 char targetLabel[MAX_TEMPORARY_STORAGE]; sprintf( targetLabel, "%starget", label );
12156 int sizeInElements = 1;
12157 for( int i=0; i<array->arrayDimensions; ++i ) {
12158 sizeInElements *= array->arrayDimensionsEach[i];
12159 }
12160 Variable * index;
12161 if ( sizeInElements < 256 ) {
12162 index = variable_temporary( _environment, VT_BYTE, "(index)");
12163 sum = variable_temporary( _environment, VT_WORD, "(sum)");
12164 } else {
12165 index = variable_temporary( _environment, VT_WORD, "(index)");
12166 sum = variable_temporary( _environment, VT_DWORD, "(sum)");
12167 }
12168 variable_store( _environment, index->name, 0 );
12169 variable_store( _environment, sum->name, 0 );
12170 Variable * value = variable_temporary( _environment, array->arrayType, "value");
12171 Variable * startAddress = variable_temporary( _environment, VT_ADDRESS, "(startAddress)");
12172 cpu_addressof_16bit( _environment, array->realName, startAddress->realName );
12173 cpu_label( _environment, loopLabel );
12174 switch( VT_BITWIDTH( array->arrayType ) ) {
12175 case 32:
12176 cpu_peekd( _environment, startAddress->realName, value->realName );
12177 variable_increment( _environment, startAddress->name );
12178 variable_increment( _environment, startAddress->name );
12179 variable_increment( _environment, startAddress->name );
12180 variable_increment( _environment, startAddress->name );
12181 break;
12182 case 16:
12183 cpu_peekw( _environment, startAddress->realName, value->realName );
12184 variable_increment( _environment, startAddress->name );
12185 variable_increment( _environment, startAddress->name );
12186 break;
12187 case 8:
12188 cpu_peek( _environment, startAddress->realName, value->realName );
12189 variable_increment( _environment, startAddress->name );
12190 break;
12191 default:
12192 CRITICAL_NOT_SUPPORTED( _name );
12193 }
12194 variable_add_inplace_vars( _environment, sum->name, value->name );
12195 variable_increment( _environment, index->name );
12196 variable_compare_and_branch_const( _environment, index->name, sizeInElements, label, 1 );
12197 cpu_jump( _environment, loopLabel );
12198 cpu_label( _environment, label );
12199 } else {
12200 CRITICAL_NOT_SUPPORTED( array->name );
12201 }
12202
12203 return sum;
12204
12205}
12206
12207/* <usermanual>
12208@keyword ARRAY MAX
12209
12210@english
12211
12212The ''ARRAY MAX'' statement find out the maximum value of all the elements inside
12213a vector or ''array''.
12214
12215@italian
12216
12217L'istruzione trova il valore massimo di tutti gli elementi
12218all'interno di un vettore o matrice array (quindi, un ''array''
12219generico).
12220
12221@syntax = [ARRAY] MAX( array )
12222
12223@example IF MAX(vector) = 42 THEN: PRINT "max value is 42": ENDIF
12224
12225@alias MAX
12226
12227@target all
12228</usermanual> */
12229
12230Variable * variable_array_max_vars( Environment * _environment, char * _name ) {
12231
12232 Variable * array = variable_retrieve( _environment, _name );
12233 Variable * max = NULL;
12234
12235 if ( array->type != VT_TARRAY ) {
12236 CRITICAL_NOT_ARRAY( array->name );
12237 }
12238
12239 if ( array->size > 0 ) {
12240
12242 char loopLabel[MAX_TEMPORARY_STORAGE]; sprintf( loopLabel, "%slabel", label );
12243 char targetLabel[MAX_TEMPORARY_STORAGE]; sprintf( targetLabel, "%starget", label );
12244 char skipLabel[MAX_TEMPORARY_STORAGE]; sprintf( skipLabel, "%sskip", label );
12245 int sizeInElements = 1;
12246 for( int i=0; i<array->arrayDimensions; ++i ) {
12247 sizeInElements *= array->arrayDimensionsEach[i];
12248 }
12249 Variable * index;
12250 if ( sizeInElements < 256 ) {
12251 index = variable_temporary( _environment, VT_BYTE, "(index)");
12252 } else {
12253 index = variable_temporary( _environment, VT_WORD, "(index)");
12254 }
12255 max = variable_temporary( _environment, array->arrayType, "(max)");
12256 variable_store( _environment, index->name, 0 );
12257 variable_store( _environment, max->name, VT_MIN( max->type ) );
12258 Variable * value = variable_temporary( _environment, array->arrayType, "value");
12259 Variable * startAddress = variable_temporary( _environment, VT_ADDRESS, "(startAddress)");
12260 cpu_addressof_16bit( _environment, array->realName, startAddress->realName );
12261 cpu_label( _environment, loopLabel );
12262 switch( VT_BITWIDTH( array->arrayType ) ) {
12263 case 32:
12264 cpu_peekd( _environment, startAddress->realName, value->realName );
12265 variable_increment( _environment, startAddress->name );
12266 variable_increment( _environment, startAddress->name );
12267 variable_increment( _environment, startAddress->name );
12268 variable_increment( _environment, startAddress->name );
12269 break;
12270 case 16:
12271 cpu_peekw( _environment, startAddress->realName, value->realName );
12272 variable_increment( _environment, startAddress->name );
12273 variable_increment( _environment, startAddress->name );
12274 break;
12275 case 8:
12276 cpu_peek( _environment, startAddress->realName, value->realName );
12277 variable_increment( _environment, startAddress->name );
12278 break;
12279 default:
12280 CRITICAL_NOT_SUPPORTED( _name );
12281 }
12282 Variable * comparison = variable_less_than( _environment, max->name, value->name, 0 );
12283 cpu_compare_and_branch_8bit_const( _environment, comparison->realName, 0, skipLabel, 1 );
12284 variable_move( _environment, value->name, max->name );
12285 cpu_label( _environment, skipLabel );
12286 variable_increment( _environment, index->name );
12287 variable_compare_and_branch_const( _environment, index->name, sizeInElements, label, 1 );
12288 cpu_jump( _environment, loopLabel );
12289 cpu_label( _environment, label );
12290 } else {
12291 CRITICAL_NOT_SUPPORTED( array->name );
12292 }
12293
12294 return max;
12295
12296}
12297
12298/* <usermanual>
12299@keyword ARRAY MIN
12300
12301@english
12302
12303The ''ARRAY MIN'' statement find out the minimum value of all the elements inside
12304a vector or ''array''.
12305
12306@italian
12307
12308L'istruzione trova il valore minimo di tutti gli elementi
12309all'interno di un vettore o matrice array (quindi, un ''array''
12310generico).
12311
12312@syntax = [ARRAY] MIN( array )
12313
12314@example IF MIN(vector) = 42 THEN: PRINT "min value is 42": ENDIF
12315
12316@alias MIN
12317
12318@target all
12319</usermanual> */
12320
12321Variable * variable_array_min_vars( Environment * _environment, char * _name ) {
12322
12323 Variable * array = variable_retrieve( _environment, _name );
12324 Variable * min = NULL;
12325
12326 if ( array->type != VT_TARRAY ) {
12327 CRITICAL_NOT_ARRAY( array->name );
12328 }
12329
12330 if ( array->size > 0 ) {
12331
12333 char loopLabel[MAX_TEMPORARY_STORAGE]; sprintf( loopLabel, "%slabel", label );
12334 char targetLabel[MAX_TEMPORARY_STORAGE]; sprintf( targetLabel, "%starget", label );
12335 char skipLabel[MAX_TEMPORARY_STORAGE]; sprintf( skipLabel, "%sskip", label );
12336 int sizeInElements = 1;
12337 for( int i=0; i<array->arrayDimensions; ++i ) {
12338 sizeInElements *= array->arrayDimensionsEach[i];
12339 }
12340 Variable * index;
12341 if ( sizeInElements < 256 ) {
12342 index = variable_temporary( _environment, VT_BYTE, "(index)");
12343 } else {
12344 index = variable_temporary( _environment, VT_WORD, "(index)");
12345 }
12346 min = variable_temporary( _environment, array->arrayType, "(min)");
12347 variable_store( _environment, index->name, 0 );
12348 variable_store( _environment, min->name, VT_MAX( min->type ) );
12349 Variable * value = variable_temporary( _environment, array->arrayType, "value");
12350 Variable * startAddress = variable_temporary( _environment, VT_ADDRESS, "(startAddress)");
12351 cpu_addressof_16bit( _environment, array->realName, startAddress->realName );
12352 cpu_label( _environment, loopLabel );
12353 switch( VT_BITWIDTH( array->arrayType ) ) {
12354 case 32:
12355 cpu_peekd( _environment, startAddress->realName, value->realName );
12356 variable_increment( _environment, startAddress->name );
12357 variable_increment( _environment, startAddress->name );
12358 variable_increment( _environment, startAddress->name );
12359 variable_increment( _environment, startAddress->name );
12360 break;
12361 case 16:
12362 cpu_peekw( _environment, startAddress->realName, value->realName );
12363 variable_increment( _environment, startAddress->name );
12364 variable_increment( _environment, startAddress->name );
12365 break;
12366 case 8:
12367 cpu_peek( _environment, startAddress->realName, value->realName );
12368 variable_increment( _environment, startAddress->name );
12369 break;
12370 default:
12371 CRITICAL_NOT_SUPPORTED( _name );
12372 }
12373 Variable * comparison = variable_greater_than( _environment, min->name, value->name, 0 );
12374 cpu_compare_and_branch_8bit_const( _environment, comparison->realName, 0, skipLabel, 1 );
12375 variable_move( _environment, value->name, min->name );
12376 cpu_label( _environment, skipLabel );
12377 variable_increment( _environment, index->name );
12378 variable_compare_and_branch_const( _environment, index->name, sizeInElements, label, 1 );
12379 cpu_jump( _environment, loopLabel );
12380 cpu_label( _environment, label );
12381 } else {
12382 CRITICAL_NOT_SUPPORTED( array->name );
12383 }
12384
12385 return min;
12386
12387}
12388
12389/* <usermanual>
12390@keyword FILL (array)
12391
12392@english
12393
12394The ''FILL'' command allows you to fill an array with a specific ''value''
12395(if omitted, it will be 0). You can use the instruction ''RANDOM'' to fill
12396the array with random values. You can specify the maximum value (minus one)
12397to use to generate a random number using the ''MAX'' keyword. You can
12398limit the number of random values using the ''COUNT'' keyword. Finally,
12399you can fill the array with an increment value, related to the index,
12400by using the ''INCREMENTAL'' keyword.
12401
12402@italian
12403
12404Il comando FILL permette di riempire un array con un valore (''value'') specifico
12405(se omesso, sarà 0). È possibile utilizzare l'istruzione ''RANDOM'' per riempire
12406l'array con valori casuali. E' possibile indicare il valore massimo (minus one) da
12407utilizzare per generare un numero casuale usando la parola chiave ''MAX''. E'
12408possibile limitare il numero di valori casuali usando la parola chiave ''COUNT''.
12409Infine, puoi riempire l'array con un valore di incremento, correlato all'indice,
12410utilizzando la parola chiave ''INCREMENTAL''.
12411
12412@syntax FILL v1 WITH value[,v2 WITH value[,...]]
12413@syntax FILL v1 [WITH [value]] [RANDOM] [MAX value] [COUNT count][, v2 WITH [value] [RANDOM] [MAX value] [COUNT count] [,...]]
12414@syntax FILL v1 [WITH [INCREMENTAL]] [MIN value] [COUNT count][, v1 [WITH [INCREMENTAL]] [MIN value] [COUNT count] [,...]]
12415
12416@example DIM a(42) AS BYTE
12417@example FILL a WITH 1
12418@example FILL a WITH RANDOM
12419@example FILL a INCREMENTAL MIN 1
12420
12421@target all
12422</usermanual> */
12423void variable_array_fill( Environment * _environment, char * _name, int _value ) {
12424
12425 Variable * array = variable_retrieve( _environment, _name );
12426
12427 if ( array->type != VT_TARRAY ) {
12428 CRITICAL_NOT_ARRAY( array->name );
12429 }
12430
12431 if ( array->size > 0 ) {
12432 switch( VT_BITWIDTH( array->arrayType ) ) {
12433 case 8:
12434 cpu_fill_direct_size_value( _environment, array->realName, array->size, _value );
12435 break;
12436 case 16:
12437 case 32:
12438 variable_array_fill_value( _environment, _name, _value );
12439 break;
12440 default:
12441 CRITICAL_NOT_SUPPORTED( array->name );
12442 }
12443 } else {
12444 CRITICAL_NOT_SUPPORTED( array->name );
12445 }
12446
12447}
12448
12449void variable_array_fill_random( Environment * _environment, char * _name, int _base, int _min_value, int _max_value, int _count, int _boolean ) {
12450
12451 Variable * array = variable_retrieve( _environment, _name );
12452
12453 if ( array->type != VT_TARRAY ) {
12454 CRITICAL_NOT_ARRAY( array->name );
12455 }
12456
12457 if ( array->size > 0 ) {
12458
12459 variable_array_fill( _environment, _name, _base );
12460
12462 char loopLabel[MAX_TEMPORARY_STORAGE]; sprintf( loopLabel, "%slabel", label );
12463 char booleanLabel[MAX_TEMPORARY_STORAGE]; sprintf( booleanLabel, "%sboolean", label );
12464 int sizeInElements = 1;
12465 for( int i=0; i<array->arrayDimensions; ++i ) {
12466 sizeInElements *= array->arrayDimensionsEach[i];
12467 }
12468 Variable * index;
12469 if ( sizeInElements < 256 ) {
12470 index = variable_temporary( _environment, VT_BYTE, "(index)");
12471 } else {
12472 index = variable_temporary( _environment, VT_WORD, "(index)");
12473 }
12474 variable_store( _environment, index->name, 0 );
12475 Variable * startAddress = variable_temporary( _environment, VT_ADDRESS, "(startAddress)");
12476 Variable * maxValue = variable_temporary( _environment, array->arrayType, "maxValue");
12477 Variable * value = variable_temporary( _environment, array->arrayType, "value");
12478 Variable * count = NULL;
12479 if ( _max_value > 0 ) {
12480 variable_store( _environment, maxValue->name, _max_value - _min_value );
12481 } else {
12482 switch( VT_BITWIDTH( array->arrayType ) ) {
12483 case 32:
12484 variable_store( _environment, maxValue->name, 0xffffffff );
12485 break;
12486 case 16:
12487 variable_store( _environment, maxValue->name, 0xffff );
12488 break;
12489 case 8:
12490 variable_store( _environment, maxValue->name, 0xff );
12491 break;
12492 default:
12494 }
12495 }
12496 if ( _count > 0 ) {
12497 if ( _count < 256 ) {
12498 count = variable_temporary( _environment, VT_BYTE, "count");
12499 } else {
12500 count = variable_temporary( _environment, VT_WORD, "count");
12501 }
12502 variable_store( _environment, count->name, _count );
12503 }
12504 cpu_addressof_16bit( _environment, array->realName, startAddress->realName );
12505 outline0("; fill random");
12506 cpu_label( _environment, loopLabel );
12507 if ( count > 0 ) {
12508 variable_compare_and_branch_const( _environment, count->name, 0, label, 1 );
12509 variable_decrement( _environment, count->name );
12510 }
12511 variable_move( _environment, rnd( _environment, maxValue->name )->name, value->name );
12512 if ( _boolean ) {
12513 variable_compare_and_branch_const( _environment, value->name, 0, booleanLabel, 1 );
12514 switch( VT_BITWIDTH( array->arrayType ) ) {
12515 case 32:
12516 variable_store( _environment, value->name, 0xffffffff );
12517 break;
12518 case 16:
12519 variable_store( _environment, value->name, 0xffff );
12520 break;
12521 case 8:
12522 variable_store( _environment, value->name, 0xff );
12523 break;
12524 default:
12526 }
12527 cpu_label( _environment, booleanLabel );
12528 }
12529 if ( _min_value > 0 ) {
12530 variable_add_inplace( _environment, value->name, _min_value );
12531 }
12532 switch( VT_BITWIDTH( array->arrayType ) ) {
12533 case 32:
12534 cpu_poked( _environment, startAddress->realName, value->realName );
12535 variable_increment( _environment, startAddress->name );
12536 variable_increment( _environment, startAddress->name );
12537 variable_increment( _environment, startAddress->name );
12538 variable_increment( _environment, startAddress->name );
12539 break;
12540 case 16:
12541 cpu_pokew( _environment, startAddress->realName, value->realName );
12542 variable_increment( _environment, startAddress->name );
12543 variable_increment( _environment, startAddress->name );
12544 break;
12545 case 8:
12546 cpu_poke( _environment, startAddress->realName, value->realName );
12547 variable_increment( _environment, startAddress->name );
12548 break;
12549 default:
12551 }
12552 outline0("; increment index");
12553 variable_increment( _environment, index->name );
12554 variable_compare_and_branch_const( _environment, index->name, sizeInElements, label, 1 );
12555 cpu_jump( _environment, loopLabel );
12556 cpu_label( _environment, label );
12557 } else {
12558 CRITICAL_NOT_SUPPORTED( array->name );
12559 }
12560
12561}
12562
12563void variable_array_fill_incremental( Environment * _environment, char * _name, int _min, int _count ) {
12564
12565 Variable * array = variable_retrieve( _environment, _name );
12566
12567 if ( array->type != VT_TARRAY ) {
12568 CRITICAL_NOT_ARRAY( array->name );
12569 }
12570
12571 if ( array->size > 0 ) {
12572
12573 variable_array_fill( _environment, _name, 0 );
12574
12576 char loopLabel[MAX_TEMPORARY_STORAGE]; sprintf( loopLabel, "%slabel", label );
12577 int sizeInElements = 1;
12578 for( int i=0; i<array->arrayDimensions; ++i ) {
12579 sizeInElements *= array->arrayDimensionsEach[i];
12580 }
12581 Variable * index;
12582 if ( sizeInElements < 256 ) {
12583 index = variable_temporary( _environment, VT_BYTE, "(index)");
12584 } else {
12585 index = variable_temporary( _environment, VT_WORD, "(index)");
12586 }
12587 variable_store( _environment, index->name, 0 );
12588 Variable * value = variable_temporary( _environment, array->arrayType, "value");
12589 variable_store( _environment, value->name, _min );
12590 Variable * count = NULL;
12591 if ( _count > 0 ) {
12592 if ( _count < 256 ) {
12593 count = variable_temporary( _environment, VT_BYTE, "count");
12594 } else {
12595 count = variable_temporary( _environment, VT_WORD, "count");
12596 }
12597 variable_store( _environment, count->name, _count );
12598 }
12599 Variable * startAddress = variable_temporary( _environment, VT_ADDRESS, "(startAddress)");
12600 cpu_addressof_16bit( _environment, array->realName, startAddress->realName );
12601 cpu_label( _environment, loopLabel );
12602 if ( count > 0 ) {
12603 variable_compare_and_branch_const( _environment, count->name, 0, label, 1 );
12604 variable_decrement( _environment, count->name );
12605 }
12606 switch( VT_BITWIDTH( array->arrayType ) ) {
12607 case 32:
12608 cpu_poked( _environment, startAddress->realName, value->realName );
12609 variable_increment( _environment, startAddress->name );
12610 variable_increment( _environment, startAddress->name );
12611 variable_increment( _environment, startAddress->name );
12612 variable_increment( _environment, startAddress->name );
12613 break;
12614 case 16:
12615 cpu_pokew( _environment, startAddress->realName, value->realName );
12616 variable_increment( _environment, startAddress->name );
12617 variable_increment( _environment, startAddress->name );
12618 break;
12619 case 8:
12620 cpu_poke( _environment, startAddress->realName, value->realName );
12621 variable_increment( _environment, startAddress->name );
12622 break;
12623 default:
12625 }
12626 variable_increment( _environment, value->name );
12627 variable_increment( _environment, index->name );
12628 variable_compare_and_branch_const( _environment, index->name, sizeInElements, label, 1 );
12629 cpu_jump( _environment, loopLabel );
12630 cpu_label( _environment, label );
12631 } else {
12632 CRITICAL_NOT_SUPPORTED( array->name );
12633 }
12634
12635}
12636
12637void variable_array_shuffle( Environment * _environment, char * _name, int _rounds ) {
12638
12639 Variable * array = variable_retrieve( _environment, _name );
12640
12641 if ( array->type != VT_TARRAY ) {
12642 CRITICAL_NOT_ARRAY( array->name );
12643 }
12644
12645 if ( array->size > 0 ) {
12646
12648 char loopLabel[MAX_TEMPORARY_STORAGE]; sprintf( loopLabel, "%slabel", label );
12649 int sizeInElements = 1;
12650 for( int i=0; i<array->arrayDimensions; ++i ) {
12651 sizeInElements *= array->arrayDimensionsEach[i];
12652 }
12653 Variable * index, * maxValue;
12654 if ( sizeInElements < 256 ) {
12655 index = variable_temporary( _environment, VT_BYTE, "(index)");
12656 maxValue = variable_temporary( _environment, VT_BYTE, "(maxValue)");
12657 } else {
12658 index = variable_temporary( _environment, VT_WORD, "(index)");
12659 maxValue = variable_temporary( _environment, VT_WORD, "(maxValue)");
12660 }
12661 variable_store( _environment, index->name, 0 );
12662 variable_store( _environment, maxValue->name, sizeInElements );
12663 Variable * rounds = NULL;
12664 if ( _rounds < 256 ) {
12665 rounds = variable_temporary( _environment, VT_BYTE, "count");
12666 } else {
12667 rounds = variable_temporary( _environment, VT_WORD, "count");
12668 }
12669 variable_store( _environment, rounds->name, _rounds );
12670 Variable * startAddress = variable_temporary( _environment, VT_ADDRESS, "(startAddress)");
12671 Variable * first = variable_temporary( _environment, VT_ADDRESS, "(first)");
12672 Variable * second = variable_temporary( _environment, VT_ADDRESS, "(second)");
12673 Variable * firstValue = variable_temporary( _environment, array->arrayType, "(firstValue)");
12674 Variable * secondValue = variable_temporary( _environment, array->arrayType, "(secondValue)");
12675 cpu_addressof_16bit( _environment, array->realName, startAddress->realName );
12676 cpu_label( _environment, loopLabel );
12677 variable_compare_and_branch_const( _environment, rounds->name, 0, label, 1 );
12678 variable_decrement( _environment, rounds->name );
12679
12680 variable_move( _environment,
12681 variable_add( _environment,
12682 rnd( _environment, maxValue->name )->name,
12683 startAddress->name )->name,
12684 first->name ) ;
12685
12686 variable_move( _environment,
12687 variable_add( _environment,
12688 rnd( _environment, maxValue->name )->name,
12689 startAddress->name )->name,
12690 second->name ) ;
12691
12692 switch( VT_BITWIDTH( array->arrayType ) ) {
12693 case 32:
12694 cpu_peekd( _environment, first->realName, firstValue->realName );
12695 cpu_peekd( _environment, second->realName, secondValue->realName );
12696 cpu_poked( _environment, first->realName, secondValue->realName );
12697 cpu_poked( _environment, second->realName, firstValue->realName );
12698 break;
12699 case 16:
12700 cpu_peekw( _environment, first->realName, firstValue->realName );
12701 cpu_peekw( _environment, second->realName, secondValue->realName );
12702 cpu_pokew( _environment, first->realName, secondValue->realName );
12703 cpu_pokew( _environment, second->realName, firstValue->realName );
12704 break;
12705 case 8:
12706 cpu_peek( _environment, first->realName, firstValue->realName );
12707 cpu_peek( _environment, second->realName, secondValue->realName );
12708 cpu_poke( _environment, first->realName, secondValue->realName );
12709 cpu_poke( _environment, second->realName, firstValue->realName );
12710 break;
12711 default:
12713 }
12714 cpu_jump( _environment, loopLabel );
12715 cpu_label( _environment, label );
12716 } else {
12717 CRITICAL_NOT_SUPPORTED( array->name );
12718 }
12719
12720}
12721
12722void image_converter_asserts( Environment * _environment, int _width, int _height, int _offset_x, int _offset_y, int * _frame_width, int * _frame_height, int _modulo_x, int _modulo_y ) {
12723
12724 if ( *_frame_width == 0 ) {
12725 *_frame_width = _width;
12726 }
12727
12728 if ( _modulo_x == 0 ) {
12729 _modulo_x = 8;
12730 }
12731
12732 if ( _modulo_y == 0 ) {
12733 _modulo_y = 8;
12734 }
12735
12736 if ( (*_frame_width % _modulo_x) && !_environment->freeImageWidth ) {
12738 }
12739
12740 if ( (_offset_x < 0) || (_offset_x >= _width) || ( ( _offset_x + (*_frame_width ) ) > _width ) ) {
12742 }
12743
12744 if ( *_frame_height == 0 ) {
12745 *_frame_height = _height;
12746 }
12747
12748 if ( (*_frame_height % _modulo_y) && !_environment->freeImageHeight ) {
12749 CRITICAL_IMAGE_CONVERTER_INVALID_HEIGHT( _height, _modulo_y );
12750 }
12751
12752 if ( (*_frame_height % _modulo_y) && !_environment->freeImageHeight ) {
12753 CRITICAL_IMAGE_CONVERTER_INVALID_FRAME_HEIGHT( *_frame_height, _modulo_y );
12754 }
12755
12756 if ( (_offset_y < 0) || (_offset_y >= _height) || ( ( _offset_y + ( *_frame_height )) > _height ) ) {
12758 }
12759
12760}
12761
12762void image_converter_asserts_free( Environment * _environment, int _width, int _height, int _offset_x, int _offset_y, int * _frame_width, int * _frame_height ) {
12763
12764 if ( *_frame_width == 0 ) {
12765 *_frame_width = _width;
12766 }
12767
12768 if ( (_offset_x < 0) || (_offset_x >= _width) || ( ( _offset_x + (*_frame_width ) ) > _width ) ) {
12770 }
12771
12772 if ( *_frame_height == 0 ) {
12773 *_frame_height = _height;
12774 }
12775
12776 if ( (_offset_y < 0) || (_offset_y >= _height) || ( ( _offset_y + ( *_frame_height )) > _height ) ) {
12778 }
12779
12780}
12781
12782
12783void image_converter_asserts_free_width( Environment * _environment, int _width, int _height, int _offset_x, int _offset_y, int * _frame_width, int * _frame_height, int _modulo_y ) {
12784
12785 // if ( _width % 8 ) {
12786 // CRITICAL_IMAGE_CONVERTER_INVALID_WIDTH( _width );
12787 // }
12788
12789 if ( *_frame_width == 0 ) {
12790 *_frame_width = _width;
12791 }
12792
12793 if ( _modulo_y == 0 ) {
12794 _modulo_y = 8;
12795 }
12796
12797 if ( (_offset_x < 0) || (_offset_x >= _width) || ( ( _offset_x + (*_frame_width ) ) > _width ) ) {
12799 }
12800
12801 if ( *_frame_height == 0 ) {
12802 *_frame_height = _height;
12803 }
12804
12805 if ( (*_frame_height % 8) && !_environment->freeImageHeight ) {
12806 CRITICAL_IMAGE_CONVERTER_INVALID_HEIGHT( _height, _modulo_y );
12807 }
12808
12809 if ( (*_frame_height % _modulo_y) && !_environment->freeImageHeight ) {
12810 CRITICAL_IMAGE_CONVERTER_INVALID_FRAME_HEIGHT( *_frame_height, _modulo_y );
12811 }
12812
12813 if ( (_offset_y < 0) || (_offset_y >= _height) || ( ( _offset_y + ( *_frame_height )) > _height ) ) {
12815 }
12816
12817}
12818
12819void image_converter_asserts_free_height( Environment * _environment, int _width, int _height, int _offset_x, int _offset_y, int * _frame_width, int * _frame_height, int _modulo_x ) {
12820
12821 if ( *_frame_width == 0 ) {
12822 *_frame_width = _width;
12823 }
12824
12825 if ( _modulo_x == 0 ) {
12826 _modulo_x = 8;
12827 }
12828
12829 if ( (*_frame_width % 8) && !_environment->freeImageWidth ) {
12830 CRITICAL_IMAGE_CONVERTER_INVALID_WIDTH( _width, _modulo_x );
12831 }
12832
12833 if ( (_offset_x < 0) || (_offset_x >= _width) || ( ( _offset_x + (*_frame_width ) ) > _width ) ) {
12835 }
12836
12837 if ( *_frame_height == 0 ) {
12838 *_frame_height = _height;
12839 }
12840
12841 if ( (_offset_y < 0) || (_offset_y >= _height) || ( ( _offset_y + ( *_frame_height )) > _height ) ) {
12843 }
12844
12845}
12846
12847char * resource_load_asserts( Environment * _environment, char * _filename ) {
12848
12849 char * lookedFilename = malloc(MAX_TEMPORARY_STORAGE);
12850 char lookedExtension[MAX_TEMPORARY_STORAGE];
12851 memset( lookedFilename, 0, MAX_TEMPORARY_STORAGE);
12852 memset( lookedExtension, 0, MAX_TEMPORARY_STORAGE);
12853
12854 check_if_filename_is_valid( _environment, _filename );
12855
12856 strcopy( lookedFilename, _filename );
12857 char * c = strrchr( lookedFilename, '/' );
12858 if ( c ) {
12859 strcopy( lookedExtension, c );
12860 *c = 0;
12861 } else {
12862 strcopy( lookedFilename, "." );
12863 strcopy( lookedExtension, PATH_SEPARATOR_AS_STRING );
12864 strcat( lookedExtension, _filename );
12865 }
12866 strcat( lookedFilename, PATH_SEPARATOR_AS_STRING );
12867#if defined(__atari__)
12868 strcat( lookedFilename, "atari" );
12869#elif defined(__atarixl__)
12870 strcat( lookedFilename, "atarixl" );
12871#elif __c64__
12872 strcat( lookedFilename, "c64" );
12873#elif __plus4__
12874 strcat( lookedFilename, "plus4" );
12875#elif __c16__
12876 strcat( lookedFilename, "c16" );
12877#elif __zx__
12878 strcat( lookedFilename, "zx" );
12879#elif __d32__
12880 strcat( lookedFilename, "d32" );
12881#elif __d32b__
12882 strcat( lookedFilename, "d32" );
12883#elif __d64__
12884 strcat( lookedFilename, "d64" );
12885#elif __d64b__
12886 strcat( lookedFilename, "d64" );
12887#elif __pc128op__
12888 strcat( lookedFilename, "pc128op" );
12889#elif __to8__
12890 strcat( lookedFilename, "to8" );
12891#elif __mo5__
12892 strcat( lookedFilename, "mo5" );
12893#elif __vic20__
12894 strcat( lookedFilename, "vic20" );
12895#elif __msx1__
12896 strcat( lookedFilename, "msx1" );
12897#elif __coleco__
12898 strcat( lookedFilename, "coleco" );
12899#elif __sc3000__
12900 strcat( lookedFilename, "sc3000" );
12901#elif __sg1000__
12902 strcat( lookedFilename, "sg1000" );
12903#elif __cpc__
12904 strcat( lookedFilename, "cpc" );
12905#elif __c128__
12906 strcat( lookedFilename, "c128" );
12907#elif __c128z__
12908 strcat( lookedFilename, "c128z" );
12909#elif __vg5000__
12910 strcat( lookedFilename, "vg5000" );
12911#elif __coco__
12912 strcat( lookedFilename, "coco" );
12913#elif __cocob__
12914 strcat( lookedFilename, "coco" );
12915#elif __coco3__
12916 strcat( lookedFilename, "coco3" );
12917#elif __coco3b__
12918 strcat( lookedFilename, "coco3" );
12919#elif __c64reu__
12920 strcat( lookedFilename, "c64reu" );
12921#elif __pc1403__
12922 strcat( lookedFilename, "pc1403" );
12923#elif __gb__
12924 strcat( lookedFilename, "gb" );
12925#elif __pccga__
12926 strcat( lookedFilename, "pccga" );
12927#elif __vz200__
12928 strcat( lookedFilename, "vz200" );
12929#endif
12930
12931 if ( strlen( lookedExtension ) ) {
12932 strcat( lookedFilename, lookedExtension );
12933 }
12934
12935 FILE * file = fopen( lookedFilename, "rb" );
12936
12937 if ( !file ) {
12938
12939 strcopy( lookedFilename, _filename );
12940
12941 file = fopen( lookedFilename, "rb" );
12942
12943 if ( !file ) {
12944 CRITICAL_RESOURCE_LOAD_MISSING_FILE( lookedFilename );
12945 }
12946 }
12947
12948 if ( file ) {
12949 fclose( file );
12950 }
12951
12952 return lookedFilename;
12953
12954}
12955
12956void variable_temporary_remove( Environment * _environment, char * _name ) {
12957
12958 Variable * varLast = NULL;
12959 if ( _environment->procedureName ) {
12960 varLast = _environment->tempVariables[_environment->currentProcedure];
12961 } else {
12962 varLast = _environment->tempVariables[0];
12963 }
12964 if ( varLast ) {
12965 if ( strcmp( varLast->name, _name ) == 0 ) {
12966 if ( _environment->procedureName ) {
12967 _environment->tempVariables[_environment->currentProcedure] = varLast->next;
12968 } else {
12969 _environment->tempVariables[0] = varLast->next;
12970 }
12971 return;
12972 }
12973
12974 Variable * previous = varLast;
12975 varLast = varLast->next;
12976 while( varLast ) {
12977 if ( strcmp( varLast->name, _name ) == 0 ) {
12978 previous->next = varLast->next;
12979 break;
12980 }
12981 previous = varLast;
12982 varLast = varLast->next;
12983 }
12984 }
12985
12986}
12987
12988int calculate_white_area( TileData * _tileData ) {
12989 int i=0, j=0;
12990 int actual = 0;
12991 for(i=0;i<8;++i) {
12992 for(j=0;j<8;++j) {
12993 if ( _tileData->data[j] & ( 1 << i ) ) {
12994 ++actual;
12995 }
12996 }
12997 }
12998 return actual;
12999}
13000
13001int calculate_horizontal_edges( TileData * _tileData, int _position ) {
13002 int edges = 0;
13003 int i=0;
13004 int actual = 0;
13005 for(i=0;i<8;++i) {
13006 if ( _tileData->data[_position] & ( 1 << i ) ) {
13007 if ( !actual ) {
13008 ++edges;
13009 actual = 1;
13010 }
13011 } else {
13012 if ( actual ) {
13013 ++edges;
13014 actual = 0;
13015 }
13016 }
13017 }
13018 return edges;
13019}
13020
13021int calculate_vertical_edges( TileData * _tileData, int _position ) {
13022 int edges = 0;
13023 int i=0;
13024 int actual = 0;
13025 for(i=0;i<8;++i) {
13026 if ( _tileData->data[i] & ( 1 << _position ) ) {
13027 if ( !actual ) {
13028 ++edges;
13029 actual = 1;
13030 }
13031 } else {
13032 if ( actual ) {
13033 ++edges;
13034 actual = 0;
13035 }
13036 }
13037 }
13038 return edges;
13039}
13040
13042
13043 TileDescriptor * tileDescriptor = malloc( sizeof( TileDescriptor ) );
13044
13045 int i=0;
13046
13047 // printf( "+--------+\n" );
13048 // for( i=0; i<8; ++i ) {
13049 // printf( "|" );
13050 // int j;
13051 // for( j=0; j<8; ++j ) {
13052 // if ( _tileData->data[i] & ( 1 << j ) ) {
13053 // printf( "*" );
13054 // } else {
13055 // printf( " " );
13056 // }
13057 // }
13058 // printf( "|\n" );
13059 // }
13060 // printf( "+--------+\n" );
13061 // printf( "\n\n" );
13062
13063 tileDescriptor->whiteArea = calculate_white_area( _tileData );
13064 for(i=0;i<8;++i) {
13065 tileDescriptor->horizontalEdges[i] = calculate_horizontal_edges( _tileData, i );
13066 tileDescriptor->verticalEdges[i] = calculate_vertical_edges( _tileData, i );
13067 }
13068
13069 return tileDescriptor;
13070
13071}
13072
13073TileDescriptors * precalculate_tile_descriptors_for_font( char * _fontData, int _fontSize ) {
13074
13075 TileDescriptors * tileDescriptors = malloc( sizeof( TileDescriptors ) );
13076 memset( tileDescriptors, 0, sizeof( TileDescriptors ) );
13077
13078 int i=0,j=0;
13079
13080 for(i=0;i<_fontSize;++i) {
13081 for(j=0;j<8;++j) {
13082 tileDescriptors->data[i].data[j] = *(_fontData + i*8 + j);
13083 }
13084 tileDescriptors->descriptor[i] = calculate_tile_descriptor( &tileDescriptors->data[i] );
13085 }
13086
13087 tileDescriptors->count = 0;
13088
13089 return tileDescriptors;
13090
13091}
13092
13094
13095 int affinity = 0;
13096 int i=0;
13097
13098 affinity += abs( _first->whiteArea - _second->whiteArea );
13099 for(i=0;i<8;++i) {
13100 affinity += abs( _first->horizontalEdges[i] - _second->horizontalEdges[i] );
13101 affinity += abs( _first->verticalEdges[i] - _second->verticalEdges[i] );
13102 }
13103
13104 return affinity;
13105
13106}
13107
13109
13110 int minAffinity = 0xffffff;
13111 int nearestTileIndex = -1;
13112 int i;
13113
13114 for(i=0;i<256;++i) {
13115 if ( _tiles->descriptor[i] ) {
13116 int affinity = calculate_tile_affinity( _tile, _tiles->descriptor[i] );
13117 if ( minAffinity > affinity ) {
13118 minAffinity = affinity;
13119 nearestTileIndex = i;
13120 }
13121 }
13122 }
13123
13124 return nearestTileIndex;
13125
13126}
13127
13129
13130 int i=0;
13131
13132 if ( ! _tiles ) {
13133 return -1;
13134 }
13135
13136 if ( ! _tiles->descriptor ) {
13137 return -1;
13138 }
13139
13140 for(i=0;i<256;++i) {
13141 if ( _tiles->descriptor[i] ) {
13142 if ( calculate_tile_affinity( _tile, _tiles->descriptor[i] ) == 0 ) {
13143 return i;
13144 };
13145 }
13146 }
13147
13148 return -1;
13149
13150}
13151
13152int tile_allocate( TileDescriptors * _tiles, char * _data ) {
13153
13154 if ( _tiles->firstFree > _tiles->lastFree ) {
13155 return -1;
13156 }
13157
13158 memcpy( _tiles->data[_tiles->firstFree].data, _data, 8 );
13159
13160 _tiles->descriptor[_tiles->firstFree] = calculate_tile_descriptor( &_tiles->data[_tiles->firstFree] );
13161
13162 ++_tiles->count;
13163
13164 return _tiles->firstFree++;
13165
13166}
13167
13168char * parse_buffer( Environment * _environment, char * _buffer, int * _size, int _hex_only ) {
13169
13170 char * buffer = NULL;
13171
13172 if ( _hex_only ) {
13173 *_size = strlen( _buffer ) / 2;
13174 buffer = malloc( *_size );
13175 char hexdigits[3];
13176 int i = 0, c = 0;
13177 for( i = 0, c = strlen( _buffer ); i<(c); i += 2 ) {
13178 hexdigits[0] = _buffer[i];
13179 hexdigits[1] = _buffer[i+1];
13180 hexdigits[2] = 0;
13181 buffer[i>>1] = strtol(hexdigits,0,16);
13182 }
13183 } else {
13184 char * unescapedString = unescape_string( _environment, _buffer, 0, _size );
13185 buffer = malloc( *_size + 1 );
13186 memset( buffer, 0, *_size + 1 );
13187 memcpy( buffer, unescapedString, *_size );
13188 }
13189
13190 return buffer;
13191
13192}
13193
13194Variable * parse_buffer_definition( Environment * _environment, char * _buffer, VariableType _type, int _hex_only ) {
13195
13196 int bufferSize;
13197 char * buffer = parse_buffer( _environment, _buffer, &bufferSize, _hex_only );
13198 Variable * result = variable_temporary( _environment, _type, "(buffer)" );
13199 variable_store_buffer( _environment, result->name, buffer, bufferSize, 0 );
13200
13201 return result;
13202
13203}
13204
13205char * image_flip_x( Environment * _environment, char * _source, int _width, int _height, int _depth ) {
13206
13207 int x,y;
13208
13209 for( y=0; y<_height; ++y ) {
13210 for( x=0; x<( _width >> 1 ); ++x ) {
13211 char * pixel1r = _source + ( y * _width * _depth ) + ( x * _depth );
13212 char * pixel1g = _source + ( y * _width * _depth ) + ( x * _depth ) + 1;
13213 char * pixel1b = _source + ( y * _width * _depth ) + ( x * _depth ) + 2;
13214 char * pixel1a;
13215 if ( _depth > 3 ) {
13216 pixel1a = _source + ( y * _width * _depth ) + ( x * _depth ) + 3;
13217 }
13218 char * pixel2r = _source + ( y * _width * _depth ) + ( ( _width - x - 1 ) * _depth );
13219 char * pixel2g = _source + ( y * _width * _depth ) + ( ( _width - x - 1 ) * _depth ) + 1;
13220 char * pixel2b = _source + ( y * _width * _depth ) + ( ( _width - x - 1 ) * _depth ) + 2;
13221 char * pixel2a;
13222 if ( _depth > 3 ) {
13223 pixel2a = _source + ( y * _width * _depth ) + ( ( _width - x - 1 ) * _depth ) + 3;
13224 }
13225
13226 char t;
13227
13228 t = *pixel1r;
13229 *pixel1r = *pixel2r;
13230 *pixel2r = t;
13231
13232 t = *pixel1g;
13233 *pixel1g = *pixel2g;
13234 *pixel2g = t;
13235
13236 t = *pixel1b;
13237 *pixel1b = *pixel2b;
13238 *pixel2b = t;
13239
13240 if ( _depth > 3 ) {
13241 t = *pixel1a;
13242 *pixel1a = *pixel2a;
13243 *pixel2a = t;
13244 }
13245
13246 }
13247 }
13248
13249 return _source;
13250
13251}
13252
13253char * image_flip_y( Environment * _environment, char * _source, int _width, int _height, int _depth ) {
13254
13255 int x,y;
13256
13257 for( x=0; x<_width; ++x ) {
13258 for( y=0; y<( _height >> 1 ); ++y ) {
13259 char * pixel1r = _source + ( y * _width * _depth ) + ( x * _depth );
13260 char * pixel1g = _source + ( y * _width * _depth ) + ( x * _depth ) + 1;
13261 char * pixel1b = _source + ( y * _width * _depth ) + ( x * _depth ) + 2;
13262 char * pixel1a;
13263 if ( _depth > 3 ) {
13264 pixel1b = _source + ( y * _width * _depth ) + ( x * _depth ) + 3;
13265 }
13266 char * pixel2r = _source + ( ( _height - y - 1) * _width * _depth ) + ( x * _depth );
13267 char * pixel2g = _source + ( ( _height - y - 1) * _width * _depth ) + ( x * _depth ) + 1;
13268 char * pixel2b = _source + ( ( _height - y - 1) * _width * _depth ) + ( x * _depth ) + 2;
13269 char * pixel2a;
13270 if ( _depth > 3 ) {
13271 pixel2b = _source + ( ( _height - y - 1) * _width * _depth ) + ( x * _depth ) + 3;
13272 }
13273
13274 char t;
13275
13276 t = *pixel1r;
13277 *pixel1r = *pixel2r;
13278 *pixel2r = t;
13279
13280 t = *pixel1g;
13281 *pixel1g = *pixel2g;
13282 *pixel2g = t;
13283
13284 t = *pixel1b;
13285 *pixel1b = *pixel2b;
13286 *pixel2b = t;
13287
13288 if ( _depth > 3 ) {
13289 t = *pixel1a;
13290 *pixel1a = *pixel2a;
13291 *pixel2a = t;
13292 }
13293
13294 }
13295 }
13296
13297 return _source;
13298
13299}
13300
13301char * image_roll_x_right( Environment * _environment, char * _source, int _width, int _height ) {
13302
13303 int x,y;
13304
13305 for( y=0; y<_height; ++y ) {
13306
13307 unsigned char * pixel2r = _source + ( y * _width * 3 ) + ( (_width-1) * 3 );
13308 unsigned char * pixel2g = _source + ( y * _width * 3 ) + ( (_width-1) * 3 ) + 1;
13309 unsigned char * pixel2b = _source + ( y * _width * 3 ) + ( (_width-1) * 3 ) + 2;
13310
13311 unsigned char r, g, b;
13312
13313 r = *pixel2r;
13314 g = *pixel2g;
13315 b = *pixel2b;
13316
13317 for( x=(_width-2); x > -1; --x ) {
13318 unsigned char * pixel1r = _source + ( y * _width * 3 ) + ( x * 3 );
13319 unsigned char * pixel1g = _source + ( y * _width * 3 ) + ( x * 3 ) + 1;
13320 unsigned char * pixel1b = _source + ( y * _width * 3 ) + ( x * 3 ) + 2;
13321 unsigned char * pixel2r = _source + ( y * _width * 3 ) + ( (x+1) * 3 );
13322 unsigned char * pixel2g = _source + ( y * _width * 3 ) + ( (x+1) * 3 ) + 1;
13323 unsigned char * pixel2b = _source + ( y * _width * 3 ) + ( (x+1) * 3 ) + 2;
13324
13325 // printf( "%d,%d : %2.2x%2.2x%2.2x -> %2.2x%2.2x%2.2x\n", y, x, (unsigned char) *pixel2r, (unsigned char) *pixel2g, (unsigned char) *pixel2b, (unsigned char) *pixel1r, (unsigned char) *pixel1g, (unsigned char) *pixel1b );
13326
13327 *pixel2r = (unsigned char) *pixel1r;
13328 *pixel2g = (unsigned char) *pixel1g;
13329 *pixel2b = (unsigned char) *pixel1b;
13330
13331 }
13332
13333 unsigned char * pixel1r = _source + ( y * _width * 3 );
13334 unsigned char * pixel1g = _source + ( y * _width * 3 ) + 1;
13335 unsigned char * pixel1b = _source + ( y * _width * 3 ) + 2;
13336
13337 *pixel1r = r;
13338 *pixel1g = g;
13339 *pixel1b = b;
13340 }
13341
13342 return _source;
13343
13344}
13345
13346char * image_roll_x_left( Environment * _environment, char * _source, int _width, int _height ) {
13347
13348 int x,y;
13349
13350 for( y=0; y<_height; ++y ) {
13351
13352 unsigned char * pixel2r = _source + ( y * _width * 3 );
13353 unsigned char * pixel2g = _source + ( y * _width * 3 ) + 1;
13354 unsigned char * pixel2b = _source + ( y * _width * 3 ) + 2;
13355
13356 unsigned char r, g, b;
13357
13358 r = *pixel2r;
13359 g = *pixel2g;
13360 b = *pixel2b;
13361
13362 for( x=0; x<_width-2; ++x ) {
13363 unsigned char * pixel1r = _source + ( y * _width * 3 ) + ( (x+1) * 3 );
13364 unsigned char * pixel1g = _source + ( y * _width * 3 ) + ( (x+1) * 3 ) + 1;
13365 unsigned char * pixel1b = _source + ( y * _width * 3 ) + ( (x+1) * 3 ) + 2;
13366 unsigned char * pixel2r = _source + ( y * _width * 3 ) + ( (x) * 3 );
13367 unsigned char * pixel2g = _source + ( y * _width * 3 ) + ( (x) * 3 ) + 1;
13368 unsigned char * pixel2b = _source + ( y * _width * 3 ) + ( (x) * 3 ) + 2;
13369
13370 // printf( "%d,%d : %2.2x%2.2x%2.2x -> %2.2x%2.2x%2.2x\n", y, x, (unsigned char) *pixel2r, (unsigned char) *pixel2g, (unsigned char) *pixel2b, (unsigned char) *pixel1r, (unsigned char) *pixel1g, (unsigned char) *pixel1b );
13371
13372 *pixel2r = (unsigned char) *pixel1r;
13373 *pixel2g = (unsigned char) *pixel1g;
13374 *pixel2b = (unsigned char) *pixel1b;
13375
13376 }
13377
13378 unsigned char * pixel1r = _source + ( y * _width * 3 ) + ( (_width-1) * 3 );
13379 unsigned char * pixel1g = _source + ( y * _width * 3 ) + ( (_width-1) * 3 ) + 1;
13380 unsigned char * pixel1b = _source + ( y * _width * 3 ) + ( (_width-1) * 3 ) + 2;
13381
13382 *pixel1r = r;
13383 *pixel1g = g;
13384 *pixel1b = b;
13385 }
13386
13387 return _source;
13388
13389}
13390
13391char * image_roll_y_down( Environment * _environment, char * _source, int _width, int _height ) {
13392
13393 int x,y;
13394
13395 for( x=0; x < _width; ++x ) {
13396
13397 unsigned char * pixel2r = _source + ( ( _height - 1 ) * _width * 3 ) + x * 3;
13398 unsigned char * pixel2g = _source + ( ( _height - 1 ) * _width * 3 ) + x * 3 + 1;
13399 unsigned char * pixel2b = _source + ( ( _height - 1 ) * _width * 3 ) + x * 3 + 2;
13400
13401 unsigned char r, g, b;
13402
13403 r = *pixel2r;
13404 g = *pixel2g;
13405 b = *pixel2b;
13406
13407 for( y=( _height - 2); y > -1; --y ) {
13408 unsigned char * pixel1r = _source + ( y * _width * 3 ) + ( x * 3 );
13409 unsigned char * pixel1g = _source + ( y * _width * 3 ) + ( x * 3 ) + 1;
13410 unsigned char * pixel1b = _source + ( y * _width * 3 ) + ( x * 3 ) + 2;
13411 unsigned char * pixel2r = _source + ( (y+1) * _width * 3 ) + ( x * 3 );
13412 unsigned char * pixel2g = _source + ( (y+1) * _width * 3 ) + ( x * 3 ) + 1;
13413 unsigned char * pixel2b = _source + ( (y+1) * _width * 3 ) + ( x * 3 ) + 2;
13414
13415 // printf( "%d,%d : %2.2x%2.2x%2.2x -> %2.2x%2.2x%2.2x\n", y, x, (unsigned char) *pixel2r, (unsigned char) *pixel2g, (unsigned char) *pixel2b, (unsigned char) *pixel1r, (unsigned char) *pixel1g, (unsigned char) *pixel1b );
13416
13417 *pixel2r = (unsigned char) *pixel1r;
13418 *pixel2g = (unsigned char) *pixel1g;
13419 *pixel2b = (unsigned char) *pixel1b;
13420
13421 }
13422
13423 unsigned char * pixel1r = _source + x * 3;
13424 unsigned char * pixel1g = _source + x * 3 + 1;
13425 unsigned char * pixel1b = _source + x * 3 + 2;
13426
13427 *pixel1r = r;
13428 *pixel1g = g;
13429 *pixel1b = b;
13430 }
13431
13432 return _source;
13433
13434}
13435
13436char * image_enlarge_right( Environment * _environment, char * _source, int _width, int _height, int _delta ) {
13437
13438 int x,y;
13439
13440 int size = ( _width + _delta ) * 3 * _height;
13441 char * destination = malloc( size );
13442 memset( destination, 0, size );
13443
13444 for( y=0; y<_height; ++y ) {
13445 for( x=0; x < _width; ++x ) {
13446 unsigned char * pixel1r = _source + ( y * _width * 3 ) + ( x * 3 );
13447 unsigned char * pixel1g = _source + ( y * _width * 3 ) + ( x * 3 ) + 1;
13448 unsigned char * pixel1b = _source + ( y * _width * 3 ) + ( x * 3 ) + 2;
13449 unsigned char * pixel2r = destination + ( y * ( _width + _delta ) * 3 ) + ( (x+1) * 3 );
13450 unsigned char * pixel2g = destination + ( y * ( _width + _delta ) * 3 ) + ( (x+1) * 3 ) + 1;
13451 unsigned char * pixel2b = destination + ( y * ( _width + _delta ) * 3 ) + ( (x+1) * 3 ) + 2;
13452
13453 // printf( "%d,%d : %2.2x%2.2x%2.2x -> %2.2x%2.2x%2.2x\n", y, x, (unsigned char) *pixel2r, (unsigned char) *pixel2g, (unsigned char) *pixel2b, (unsigned char) *pixel1r, (unsigned char) *pixel1g, (unsigned char) *pixel1b );
13454
13455 *pixel2r = (unsigned char) *pixel1r;
13456 *pixel2g = (unsigned char) *pixel1g;
13457 *pixel2b = (unsigned char) *pixel1b;
13458 }
13459 }
13460
13461 return destination;
13462
13463}
13464
13465char * image_enlarge_bottom( Environment * _environment, char * _source, int _width, int _height, int _delta ) {
13466
13467 int x,y;
13468
13469 int size = ( _width ) * 3 * ( _height + _delta);
13470 char * destination = malloc( size );
13471 memset( destination, 0, size );
13472 memcpy( destination, _source, ( _width ) * 3 * ( _height ) );
13473
13474 return destination;
13475
13476}
13477
13478char * image_extract_subimage( Environment * _environment, char * _source, int _width, int _height, int _frame_width, int _frame_height, int _x, int _y, int _depth ) {
13479
13480 char * destination = malloc( _frame_width * _frame_height * _depth );
13481 memset( destination, 0, _frame_width * _frame_height * _depth );
13482
13483 char * source = _source + _frame_height * _width * _y * _depth + _frame_width * _x * _depth;
13484
13485 char * originalDestination = destination;
13486
13487 while( _frame_height ) {
13488 memcpy( destination, source, _frame_width * _depth );
13489 source += _width * _depth;
13490 destination += _frame_width * _depth;
13491 --_frame_height;
13492 }
13493
13494 return originalDestination;
13495
13496}
13497
13498int rgbi_equals_rgb( RGBi * _first, RGBi * _second ) {
13499 return _first->red == _second->red && _first->green == _second->green && _first->blue == _second->blue;
13500}
13501
13502int rgbi_equals_rgba( RGBi * _first, RGBi * _second ) {
13503 return rgbi_equals_rgb( _first, _second ) && ( _first->alpha == _second->alpha );
13504}
13505
13506void rgbi_move( RGBi * _source, RGBi * _destination ) {
13507 memcpy( _destination, _source, sizeof( RGBi ) );
13508}
13509
13523int rgbi_distance( RGBi * _e1, RGBi * _e2 ) {
13524
13525 long rmean = ( (long)_e1->red + (long)_e2->red ) / 2;
13526 long r = (long)_e1->red - (long)_e2->red;
13527 long g = (long)_e1->green - (long)_e2->green;
13528 long b = (long)_e1->blue - (long)_e2->blue;
13529 return (int)( sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8)) );
13530
13531}
13532
13533static int rgbi_qsort_compare(const void * _first, const void * _second ) {
13534
13535 RGBi * first = (RGBi *) _first;
13536 RGBi * second = (RGBi *) _second;
13537
13538 if ( first->alpha == second->alpha ) {
13539 if ( first->count < second->count ) {
13540 return 1;
13541 } else if ( first->count > second->count ) {
13542 return -1;
13543 } else {
13544 return 0;
13545 }
13546 } else {
13547 if ( first->alpha > second->alpha ) {
13548 return 1;
13549 } else if ( first->alpha < second->alpha ) {
13550 return -1;
13551 } else {
13552 return 0;
13553 };
13554 }
13555
13556}
13557
13566int rgbi_extract_palette( Environment * _environment, unsigned char* _source, int _width, int _height, int _depth, RGBi _palette[], int _palette_size, int _sorted) {
13567
13568 RGBi rgb;
13569
13570 int i = 0;
13571
13572 memset( _palette, 0, sizeof( RGBi ) * _palette_size );
13573 for( i=0; i<_palette_size; ++i ) {
13574 _palette[i].alpha = 255;
13575 }
13576
13577 int image_x, image_y;
13578
13579 int usedPalette = 0;
13580 unsigned char* source = _source;
13581
13582 for (image_y = 0; image_y < _height; ++image_y) {
13583 for (image_x = 0; image_x < _width; ++image_x) {
13584
13585 memset( &rgb, 0, sizeof( RGBi ) );
13586
13587 rgb.red = *source;
13588 rgb.green = *(source + 1);
13589 rgb.blue = *(source + 2);
13590 if (_depth>3) {
13591 rgb.alpha = *(source + 3);
13592 } else {
13593 rgb.alpha = 255;
13594 }
13595 if ( rgb.alpha == 0 ) {
13596 rgb.red = 0;
13597 rgb.green = 0;
13598 rgb.blue = 0;
13599 }
13600 rgb.count = 0;
13601
13602 // printf("%2.2x%2.2x%2.2x%2.2x ", rgb.red, rgb.blue, rgb.green, rgb.alpha );
13603
13604 for (i = 0; i < usedPalette; ++i) {
13605 if (rgbi_equals_rgba( &_palette[i], &rgb )) {
13606 break;
13607 }
13608 }
13609
13610 if (i >= usedPalette) {
13611 //printf( "added\n");
13612 //printf( "_palette[%d] vs %d\n", usedPalette, _palette_size);
13613 rgbi_move( &rgb, &_palette[usedPalette] );
13614 ++usedPalette;
13615 if (usedPalette >= (_palette_size-1)) {
13616 //printf( " done!");
13617 break;
13618 }
13619 //printf( "%2.2x", i );
13620 } else {
13621 // printf( "increment (%2.2x)\n", _palette[i].alpha);
13622 ++_palette[i].count;
13623 //printf( "%2.2x", i );
13624 }
13625 source += _depth;
13626 }
13627 //printf("\n");
13628 if (usedPalette > (_palette_size-1)) {
13629 break;
13630 }
13631 }
13632
13633 // printf("USED PALETTE: %d\n", usedPalette );
13634
13635 // printf("PALETTE:\n" );
13636 // for(i=0;i<8;++i) {
13637 // printf(" %i) %2.2x%2.2x%2.2x %2.2x (%d)\n", i, _palette[i].red, _palette[i].green, _palette[i].blue, _palette[i].alpha, _palette[i].count );
13638 // }
13639
13640 adilinepalette( "EPO:%d", usedPalette, _palette );
13641
13642 if ( _sorted ) {
13643 qsort( _palette, _palette_size, sizeof( RGBi ), rgbi_qsort_compare );
13644 adilinepalette( "EPS:%d", usedPalette, _palette );
13645 }
13646
13647 // printf("QSORT:\n" );
13648 // for(i=0;i<8;++i) {
13649 // printf(" %i) %2.2x%2.2x%2.2x %2.2x (%d)\n", i, _palette[i].red, _palette[i].green, _palette[i].blue, _palette[i].alpha, _palette[i].count );
13650 // }
13651
13652 return usedPalette;
13653
13654}
13655
13656float max_of_two(float _x, float _y) {
13657 return (_x > _y) ? _x : _y;
13658}
13659
13660float max_of_three(float _m, float _n, float _p) {
13661 return max_of_two(max_of_two(_m, _n), _p);
13662}
13663
13664float min_of_two(float _x, float _y) {
13665 return (_x < _y) ? _x : _y;
13666}
13667
13668float min_of_three(float _m, float _n, float _p) {
13669 return min_of_two(min_of_two(_m, _n), _p);
13670}
13671
13672char * get_temporary_filename( Environment * _environment ) {
13673
13674 char temp[16];
13675 memset( temp, 0, 16 );
13676
13677 char temporaryFilename[MAX_TEMPORARY_STORAGE];
13678
13679 int i = 0;
13680 for( i=0; i<15; ++i ) {
13681 temp[i] = 'a' + ((char) (rand() % 20));
13682 }
13683
13684 for(i=0; i<strlen(temp); ++i ) {
13685 if ( temp[i] == '.' ) {
13686 temp[i] = '0';
13687 }
13688 }
13689
13690 if ( _environment->temporaryPath ) {
13691 strcopy( temporaryFilename, _environment->temporaryPath );
13692 strcat( temporaryFilename, PATH_SEPARATOR_AS_STRING );
13693 strcat( temporaryFilename, temp );
13694 } else {
13695 strcopy( temporaryFilename, temp );
13696 }
13697
13698 return strdup( temporaryFilename );
13699
13700}
13701
13709int system_call( Environment * _environment, char * _commandline ) {
13710
13711 TRACE0( "system_call" );
13712
13713 // ----------------------------------------------------------
13714 // ------------------------------------------ WINDOWS VERSION
13715 // ----------------------------------------------------------
13716
13717 #ifdef _WIN32
13718
13719 // First of all, we will create a temporary batch file
13720 // to call in place of the original command line.
13721
13722 char batchFileName[MAX_TEMPORARY_STORAGE];
13723 sprintf( batchFileName, "%s.bat", get_temporary_filename( _environment ) );
13724
13725 TRACE1( " creating batchfile \"%s\"", batchFileName );
13726
13727 FILE * fh = fopen( batchFileName, "w+t" );
13728 fprintf( fh, "@echo off\n%s\n", _commandline );
13729 fclose( fh );
13730
13731 TRACE1( " content \"%s\"", _commandline );
13732
13733 // Add quotes around the executable filename,
13734 // in order to avoid wrong execution.
13735
13736 char systemDirectoryPath[MAX_TEMPORARY_STORAGE];
13737 GetSystemDirectoryA( systemDirectoryPath, MAX_TEMPORARY_STORAGE );
13738
13739 char batchFileName2[MAX_TEMPORARY_STORAGE];
13740 if ( _environment->cmdFileName ) {
13741 sprintf( batchFileName2, "%s /C \"%s\"", _environment->cmdFileName, batchFileName );
13742 } else {
13743 sprintf( batchFileName2, "%s\\cmd.exe /C \"%s\"", systemDirectoryPath, batchFileName );
13744 }
13745
13746 // Now we can exec the batch file.
13747
13748 int result = system( batchFileName2 );
13749
13750 // Remove the temporary batch file.
13751
13752 TRACE1( " removing \"%s\"", batchFileName );
13753
13754 remove( batchFileName );
13755
13756 // Give back the result.
13757
13758 TRACE1( " result = %d", result );
13759
13760 return result;
13761
13762 // ----------------------------------------------------------
13763 // -------------------------------------------- LINUX VERSION
13764 // ----------------------------------------------------------
13765
13766 #else
13767
13768 // We can directly execute the command line.
13769
13770 TRACE1( " executing %s", _commandline );
13771
13772 int result = system( _commandline );
13773
13774 // Give back the result.
13775
13776 TRACE1( " result = %d", result );
13777
13778 return result;
13779
13780 #endif
13781
13782}
13783
13784int system_remove_safe( Environment * _environment, char * _filename ) {
13785
13786 TRACE1( "system_remove_safe( ..., %s)", _filename );
13787
13788 FILE * f = fopen( _filename, "rb" );
13789 if ( f ) {
13790 fclose( f );
13791 if ( remove( _filename ) != 0 ) {
13792 CRITICAL_CANNOT_REMOVE_FILE( _filename, strerror(errno) );
13793 }
13794 }
13795
13796}
13797
13798char * escape_newlines_full( char * _string, int _size ) {
13799
13800 char * result = malloc( 6 * _size + 2 + MAX_TEMPORARY_STORAGE );
13801
13802 memset( result, 0, 6 * _size + 2 );
13803
13804 char * p = _string, * q = result;
13805
13806 while( _size ) {
13807 if ( *p == '\n' || *p == '\r' ) {
13808 if ( (q-result) > 2 && ( *(q-1) == '"') && ( *(q-2) == ',') ) {
13809 --q;
13810 } else {
13811 *q = '"';
13812 ++q;
13813 *q = ',';
13814 ++q;
13815 }
13816 *q = '1';
13817 ++q;
13818 *q = '3';
13819 ++q;
13820 *q = ',';
13821 ++q;
13822 *q = '"';
13823 ++q;
13824 ++p;
13825 } else if ( *p < 31 ) {
13826 if ( (q-result) > 2 && ( *(q-1) == '"') && ( *(q-2) == ',') ) {
13827 --q;
13828 } else {
13829 *q = '"';
13830 ++q;
13831 *q = ',';
13832 ++q;
13833 }
13834 *q = '$';
13835 ++q;
13836 *q = ( ( (*p & 0xf0) >> 4 ) < 10 ) ? ( ( (*p & 0xf0) >> 4 ) + '0' ) : ( ( ( (*p & 0xf0) >> 4 ) - 10 ) + 'a' );
13837 ++q;
13838 *q = ( ( (*p & 0x0f) ) < 10 ) ? ( ( (*p & 0x0f) ) + '0' ) : ( ( ( (*p & 0x0f) ) - 10 ) + 'a' );
13839 ++q;
13840 *q = ',';
13841 ++q;
13842 *q = '"';
13843 ++q;
13844 ++p;
13845 } else if ( *p == '"' ) {
13846 if ( (q-result) > 2 && ( *(q-1) == '"') && ( *(q-2) == ',') ) {
13847 --q;
13848 } else {
13849 *q = '"';
13850 ++q;
13851 *q = ',';
13852 ++q;
13853 }
13854 *q = '3';
13855 ++q;
13856 *q = '4';
13857 ++q;
13858 *q = ',';
13859 ++q;
13860 *q = '"';
13861 ++q;
13862 ++p;
13863 } else if ( *p == '\\' ) {
13864 if ( (q-result) > 2 && ( *(q-1) == '"') && ( *(q-2) == ',') ) {
13865 --q;
13866 } else {
13867 *q = '"';
13868 ++q;
13869 *q = ',';
13870 ++q;
13871 }
13872 *q = '9';
13873 ++q;
13874 *q = '2';
13875 ++q;
13876 *q = ',';
13877 ++q;
13878 *q = '"';
13879 ++q;
13880 ++p;
13881 } else {
13882 *q++ = *p++;
13883 }
13884 --_size;
13885 }
13886
13887 *q = 0;
13888 int escaped = 1;
13889 if ( strlen( result ) > 1 ) {
13890 if ( ( *result == '"' ) && ( *(result+1) == ',' ) ) {
13891 memmove( result, result+2, strlen( result ) - 2 );
13892 escaped = 0;
13893 *(result+strlen( result ) - 2) = 0;
13894 }
13895 }
13896
13897 if ( strlen( result ) > 2 ) {
13898 if ( ( *(result+strlen( result )-1) == '"' ) && ( *(result+strlen( result )-2) == ',' ) ) {
13899 *(result+strlen( result )-2 ) = 0;
13900 }
13901 }
13902
13903 q = result;
13904
13905 int close_escaped = 0;
13906 while(*q) {
13907 if ( *q == '"' ) {
13908 close_escaped = ! close_escaped;
13909 }
13910 ++q;
13911 }
13912
13913 char * result2 = malloc( 2 * strlen( result ) + MAX_TEMPORARY_STORAGE );
13914
13915 if ( escaped ) {
13916 sprintf( result2, "\"%s", result );
13917 close_escaped = ! close_escaped;
13918 } else {
13919 strcopy( result2, result );
13920 }
13921 strcopy( result, result2 );
13922
13923 if ( close_escaped ) {
13924 sprintf( result2, "%s\"", result );
13925 } else {
13926 strcopy( result2, result );
13927 }
13928 strcopy( result, result2 );
13929
13930 free( result2 );
13931
13932 return result;
13933
13934}
13935
13936char * escape_newlines( char * _string ) {
13937
13938 return escape_newlines_full( _string, strlen( _string ) );
13939
13940}
13941
13942int check_if_filename_is_valid( Environment * _environment, char * _filename ) {
13943
13944 if ( strchr( _filename, ':' ) ) {
13946 }
13947
13948 if ( strchr( _filename, '\\' ) ) {
13950 }
13951
13952 return 1;
13953
13954}
13955
13962RGBi * malloc_palette( int _size ) {
13963
13964 RGBi * palette = malloc( _size * sizeof(RGBi) );
13965
13966 memset( palette, 0, _size * sizeof(RGBi) );
13967
13968 return palette;
13969
13970}
13971
13981RGBi * palette_match( RGBi * _source, int _source_size, RGBi * _system, int _system_size ) {
13982
13983 RGBi * matchedPalette = malloc_palette( _source_size );
13984
13985 int i, j, k;
13986
13987 for ( i=0; i<_source_size; ++i ) {
13988
13989 unsigned int minDistance = 0xffff;
13990
13991 for( j=0; j<_system_size; ++j ) {
13992 if ( _source[i].alpha < 255 ) {
13993 if ( rgbi_equals_rgb( &_source[i], &_system[j] ) && _system[j].alpha == 0 ) {
13994 minDistance = 0;
13995 rgbi_move( &_system[j], &matchedPalette[i] );
13996 }
13997 } else {
13998 if ( _system[j].alpha < 255 ) {
13999 continue;
14000 }
14001 unsigned int distance = rgbi_distance( &_source[i], &_system[j] );
14002 if ( distance < minDistance ) {
14003 rgbi_move( &_system[j], &matchedPalette[i] );
14004 minDistance = distance;
14005 }
14006 }
14007 }
14008
14009 }
14010
14011 return matchedPalette;
14012
14013}
14014
14015RGBi * palette_match_hardware_index( RGBi * _source, int _source_size, RGBi * _system, int _system_size ) {
14016
14017 RGBi * matchedPalette = malloc_palette( _source_size );
14018
14019 int i, j, k;
14020
14021 for ( i=0; i<_source_size; ++i ) {
14022
14023 unsigned int minDistance = 0xffff;
14024
14025 for( j=0; j<_system_size; ++j ) {
14026
14027 unsigned int distance = rgbi_distance( &_source[i], &_system[j] );
14028
14029 if ( distance < minDistance ) {
14030 rgbi_move( &_source[i], &matchedPalette[i] );
14031 matchedPalette[i].index = _system[j].index;
14032 matchedPalette[i].hardwareIndex = _system[j].hardwareIndex;
14033 minDistance = distance;
14034 }
14035
14036 }
14037
14038 }
14039
14040 return matchedPalette;
14041
14042}
14043
14052RGBi * palette_remove_duplicates( RGBi * _source, int _source_size, int * _unique_size ) {
14053
14054 RGBi * uniquePalette = malloc_palette( _source_size );
14055 *_unique_size = 0;
14056
14057 int i, j;
14058
14059 for ( i=0; i<_source_size; ++i ) {
14060
14061 if ( _source[i].hardwareIndex == 0xff ) {
14062 // printf( "%d skipped\n", i );
14063 break;
14064 }
14065
14066 for( j=0; j<*_unique_size; ++j ) {
14067
14068 if ( rgbi_equals_rgba( &_source[i], &uniquePalette[j] ) ) {
14069 // printf( "%d == %d\n", i, j );
14070 // printf( "rgbi_equals_rgb(a, b) : \n");
14071 // printf( " a.red (%2.2x) == b.red (%2.2x), a.green (%2.2x) == b.green (%2.2x), a.blue (%2.2x) == b.blue (%2.2x)\n\n",
14072 // _source[i].red, uniquePalette[j].red,
14073 // _source[i].green, uniquePalette[j].green,
14074 // _source[i].blue, uniquePalette[j].blue
14075 // );
14076 break;
14077 }
14078
14079 }
14080
14081 if ( j >= *_unique_size ) {
14082 // printf( "%d > %d\n", i, j );
14083 rgbi_move( &_source[i], &uniquePalette[*_unique_size]);
14084 ++*_unique_size;
14085 if ( *_unique_size > _source_size ) {
14086 break;
14087 }
14088 }
14089
14090 }
14091
14092 return uniquePalette;
14093
14094}
14095
14105RGBi * palette_promote_color_as_background( int _index, RGBi * _source, int _source_size ) {
14106
14107 RGBi * reorderedPalette = malloc_palette( _source_size );
14108
14109 int i, j;
14110
14111 for ( i=0; i<_source_size; ++i ) {
14112 rgbi_move( &_source[i], &reorderedPalette[i] );
14113 }
14114
14115 for ( i=0; i<_source_size; ++i ) {
14116 if ( _source[i].hardwareIndex == _index ) {
14117 break;
14118 }
14119 }
14120
14121 if ( i <_source_size ) {
14122 RGBi tmp;
14123 rgbi_move( &reorderedPalette[i], &tmp );
14124 rgbi_move( &reorderedPalette[0], &reorderedPalette[i] );
14125 rgbi_move( &tmp, &reorderedPalette[0] );
14126 }
14127
14128 return reorderedPalette;
14129
14130}
14131
14141RGBi * palette_promote_color_as_foreground( int _index, RGBi * _source, int _source_size, int _max_size ) {
14142
14143 RGBi * reorderedPalette = malloc_palette( _max_size );
14144
14145 int i, j;
14146
14147 for ( i=0; i<_source_size; ++i ) {
14148 rgbi_move( &_source[i], &reorderedPalette[i] );
14149 }
14150 for ( i=_source_size; i<_max_size; ++i ) {
14151 rgbi_move( &_source[0], &reorderedPalette[i] );
14152 reorderedPalette[i].index = 0xff;
14153 reorderedPalette[i].hardwareIndex = 0xff;
14154 }
14155
14156 for ( i=0; i<_source_size; ++i ) {
14157 if ( _source[i].hardwareIndex == _index ) {
14158 break;
14159 }
14160 }
14161
14162 if ( i <_source_size ) {
14163 RGBi tmp;
14164 rgbi_move( &reorderedPalette[i], &tmp );
14165 // Force duplication of color to manage opacity of black.
14166 // rgbi_move( &reorderedPalette[(_max_size-1)], &reorderedPalette[i] );
14167 rgbi_move( &tmp, &reorderedPalette[(_max_size-1)] );
14168 reorderedPalette[(_max_size-1)].alpha = 0xff;
14169 }
14170
14171 return reorderedPalette;
14172
14173}
14174
14183RGBi * palette_shift( RGBi * _source, int _source_size, int _offset ) {
14184
14185 int i = 0;
14186
14187 if ( _offset == 0 ) {
14188 return _source;
14189 }
14190
14191 RGBi * shiftedPalette = malloc_palette( MAX_PALETTE );
14192
14193 unsigned char * dest = (unsigned char *)shiftedPalette;
14194 unsigned char * source = (unsigned char *)_source;
14195
14196 if ( _offset > 0 ) {
14197 memmove( dest + ( _offset * sizeof( RGBi ) ), source, _source_size * sizeof( RGBi ) );
14198 } else if ( _offset < 0 ) {
14199 memmove( shiftedPalette, _source - ( _offset * sizeof( RGBi ) ), _source_size * sizeof( RGBi ) );
14200 }
14201
14202 return shiftedPalette;
14203
14204}
14205
14216RGBi * palette_merge( RGBi * _palette1, int _palette1_size, RGBi * _palette2, int _palette2_size, int * _size ) {
14217
14218 RGBi * mergedPalette = malloc_palette( _palette1_size + _palette2_size );
14219 *_size = 0;
14220
14221 int i, j, k;
14222
14223 for ( i=0; i<_palette1_size; ++i ) {
14224 if ( _palette1[i].hardwareIndex == 0xff ) continue;
14225 if ( _palette1[i].alpha < 255 ) {
14226 rgbi_move( &_palette1[i], &mergedPalette[*_size] );
14227 ++*_size;
14228 }
14229 }
14230
14231 for ( i=0; i<_palette2_size; ++i ) {
14232 if ( _palette2[i].hardwareIndex == 0xff ) continue;
14233 if ( _palette2[i].alpha < 255 ) {
14234 int k = 0;
14235 for( int k=0; k<*_size; ++k ) {
14236 if ( rgbi_equals_rgba( &mergedPalette[k], &_palette2[i] ) ) {
14237 break;
14238 }
14239 }
14240 if ( k >= *_size ) {
14241 rgbi_move( &_palette2[i], &mergedPalette[*_size] );
14242 ++*_size;
14243 }
14244 }
14245 }
14246
14247 for ( i=0; i<_palette1_size; ++i ) {
14248 if ( _palette1[i].hardwareIndex == 0xff ) continue;
14249 if ( _palette1[i].alpha < 255 ) continue;
14250 for( j=0; j<*_size; ++j ) {
14251 if ( rgbi_equals_rgba( &_palette1[i], &mergedPalette[j] ) ) {
14252 break;
14253 }
14254 }
14255 if ( j >= *_size ) {
14256 rgbi_move( &_palette1[i], &mergedPalette[*_size] );
14257 ++*_size;
14258 }
14259 }
14260
14261 for ( i=0; i<_palette2_size; ++i ) {
14262 if ( _palette2[i].hardwareIndex == 0xff ) continue;
14263 if ( _palette2[i].alpha < 255 ) continue;
14264 for( j=0; j<*_size; ++j ) {
14265 if ( rgbi_equals_rgba( &_palette2[i], &mergedPalette[j] ) ) {
14266 break;
14267 }
14268 }
14269 if ( j >= *_size ) {
14270 rgbi_move( &_palette2[i], &mergedPalette[*_size] );
14271 ++*_size;
14272 }
14273 }
14274
14275 return mergedPalette;
14276
14277}
14278
14279/* returns true if the buffer matches a comment or and empty line */
14280int assemblyLineIsAComment( char * _buffer ) {
14281 if ( ! *_buffer ) {
14282 return 1;
14283 }
14284 if ( *_buffer == '\r' || *_buffer == '\n' ) {
14285 return 1;
14286 }
14287 while( * _buffer ) {
14288 if ( *_buffer == ' ' || *_buffer == '\t' ) {
14289 ++_buffer;
14290 } else if ( *_buffer == ';' ) {
14291 return 1;
14292 } else {
14293 return 0;
14294 }
14295 }
14296 return 0;
14297}
14298
14299char * strtoupper( char * _string ) {
14300
14301 char * target = strdup( _string );
14302
14303 char * p = target;
14304
14305 while( *p ) {
14306 *p = toupper(*p);
14307 ++p;
14308 }
14309
14310 return target;
14311
14312}
14313
14314char * basename( char * _path ) {
14315
14316 char * target = strdup( _path );
14317
14318 char * p = strrchr( target, '/' );
14319
14320 if ( !p ) {
14321 p = strrchr( target, '\\' );
14322 }
14323
14324 if ( p ) {
14325 return p+1;
14326 } else {
14327 return target;
14328 }
14329
14330}
14331
14332Variable * origin_resolution_relative_transform_x( Environment * _environment, char * _x, int _is_relative ) {
14333
14334 if ( !_x && !_is_relative && !((struct _Environment *)_environment)->originUsed && !((struct _Environment *)_environment)->resolutionUsed ) {
14335 return variable_retrieve( _environment, "XGR" );
14336 }
14337
14338 Variable * x;
14339
14340 if ( !((struct _Environment *)_environment)->originUsed && !((struct _Environment *)_environment)->resolutionUsed ) {
14341
14342 if ( _x ) {
14343 Variable * originX = variable_retrieve( _environment, _x );
14344 if ( !_is_relative ) {
14345 return originX;
14346 }
14347 x = variable_temporary( _environment, originX->type, "(x)" );
14348 variable_move( _environment, variable_add( _environment, "XGR", originX->name )->name, x->name );
14349 } else {
14350 x = variable_retrieve( _environment, "XGR" );
14351 }
14352
14353 return x;
14354
14355 } else {
14356
14357 Variable * result = variable_temporary( _environment, VT_POSITION, "(x)" );
14358
14359 result->reflected = _x;
14360
14361 Variable * originX = NULL;
14362
14363 if ( _x ) {
14364 originX = variable_retrieve( _environment, _x );
14365 x = variable_retrieve_or_define( _environment, _x, VT_POSITION, 0 );
14366 if ( _is_relative ) {
14367 x = variable_add( _environment, "XGR", x->name );
14368 }
14369 } else {
14370 x = variable_retrieve( _environment, "XGR" );
14371 }
14372
14373 if ( ((struct _Environment *)_environment)->originUsed ) {
14374 x = variable_add( _environment, "ORIGINX", x->name );
14375 }
14376
14377 if ( ((struct _Environment *)_environment)->resolutionUsed ) {
14378 Variable * xFloat = variable_cast( _environment, x->name, VT_FLOAT );
14379 Variable * currentWidthFloat = variable_cast( _environment, "CURRENTWIDTH", VT_FLOAT );
14380 Variable * resolutionFloat = variable_cast( _environment, "RESOLUTIONX", VT_FLOAT );
14381
14382 Variable * mul = variable_mul( _environment, xFloat->name, currentWidthFloat->name );
14383 Variable * div = variable_div( _environment, mul->name, resolutionFloat->name, NULL );
14384 variable_move( _environment,
14385 div->name,
14386 result->name
14387 );
14388 } else {
14389 variable_move( _environment, x->name, result->name );
14390 }
14391
14392 result->origin = originX;
14393
14394 return result;
14395
14396 }
14397
14398
14399}
14400
14401Variable * origin_resolution_relative_transform_y( Environment * _environment, char * _y, int _is_relative ) {
14402
14403 if ( !_y && !_is_relative && !((struct _Environment *)_environment)->originUsed && !((struct _Environment *)_environment)->resolutionUsed ) {
14404 return variable_retrieve( _environment, "YGR" );
14405 }
14406
14407 Variable * y;
14408
14409 if ( !((struct _Environment *)_environment)->originUsed && !((struct _Environment *)_environment)->resolutionUsed ) {
14410
14411 if ( _y ) {
14412 Variable * originY = variable_retrieve( _environment, _y );
14413 if ( !_is_relative ) {
14414 return originY;
14415 }
14416 y = variable_temporary( _environment, originY->type, "(y)" );
14417 variable_move( _environment, variable_add( _environment, "YGR", originY->name )->name, y->name );
14418 } else {
14419 y = variable_retrieve( _environment, "YGR" );
14420 }
14421
14422 return y;
14423
14424 } else {
14425
14426 Variable * result = variable_temporary( _environment, VT_POSITION, "(y)" );
14427
14428 result->reflected = _y;
14429
14430 Variable * originY = NULL;
14431
14432 if ( _y ) {
14433 originY = variable_retrieve( _environment, _y );
14434 y = variable_retrieve_or_define( _environment, _y, VT_POSITION, 0 );
14435 if ( _is_relative ) {
14436 y = variable_add( _environment, "YGR", y->name );
14437 }
14438 } else {
14439 y = variable_retrieve( _environment, "YGR" );
14440 }
14441
14442 if ( ((struct _Environment *)_environment)->originUsed ) {
14443 if ( ((struct _Environment *)_environment)->originYDirection >= 0 ) {
14444 y = variable_add( _environment, "ORIGINY", y->name );
14445 } else {
14446 y = variable_sub( _environment, "ORIGINY", y->name );
14447 }
14448 }
14449
14450 if ( ((struct _Environment *)_environment)->resolutionUsed ) {
14451 Variable * yFloat = variable_cast( _environment, y->name, VT_FLOAT );
14452 Variable * currentHeightFloat = variable_cast( _environment, "CURRENTHEIGHT", VT_FLOAT );
14453 Variable * resolutionFloat = variable_cast( _environment, "RESOLUTIONY", VT_FLOAT );
14454
14455 Variable * mul = variable_mul( _environment, yFloat->name, currentHeightFloat->name );
14456 Variable * div = variable_div( _environment, mul->name, resolutionFloat->name, NULL );
14457
14458 variable_move( _environment,
14459 div->name,
14460 result->name
14461 );
14462 } else {
14463 variable_move( _environment, y->name, result->name );
14464 }
14465
14466 result->origin = originY;
14467
14468 return result;
14469
14470 }
14471
14472}
14473
14474void font_descriptors_init( Environment * _environment, int _embedded_present ) {
14475
14476 char * data = NULL; int dataSize = 0;
14477
14478 switch( _environment->fontConfig.schema ) {
14480 if ( _embedded_present ) {
14481 break;
14482 }
14484 default:
14486 dataSize = data_font_standard_bin_len / 8;
14487 break;
14490 dataSize = data_font_semigraphic_bin_len / 8;
14491 break;
14494 dataSize = data_font_complete_bin_len / 8;
14495 break;
14496 case FONT_SCHEMA_ALPHA:
14497 data = data_font_alpha_bin;
14498 dataSize = data_font_alpha_bin_len / 8;
14499 break;
14500 case FONT_SCHEMA_ASCII:
14501 data = data_font_ascii_bin;
14502 dataSize = data_font_ascii_bin_len / 8;
14503 break;
14504 }
14505
14506 if ( data ) {
14507 _environment->descriptors = precalculate_tile_descriptors_for_font( data, dataSize );
14508 _environment->descriptors->first = 0;
14509 _environment->descriptors->firstFree = ( dataSize - 1 );
14510 _environment->descriptors->lastFree = 255;
14511 _environment->descriptors->count = dataSize;
14512 }
14513
14514}
14515
14516char * address_displacement( Environment * _environment, char * _address, char * _displacement ) {
14517
14518 char addressed[MAX_TEMPORARY_STORAGE];
14519
14520 if ( ! strchr( _address, '+' ) ) {
14521 if ( atoi(_displacement) ) {
14522 sprintf( addressed, "%s+%d", _address, atoi(_displacement) );
14523 } else {
14524 sprintf( addressed, "%s", _address );
14525 }
14526 } else {
14527 char * duplicated = strdup( _address );
14528 char * p = strtok( duplicated, "+");
14529 char * q = strtok ( NULL, "+" );
14530 if ( atoi(q) + atoi(_displacement) ) {
14531 sprintf( addressed, "%s+%d", p, atoi(q) + atoi(_displacement) );
14532 } else {
14533 sprintf( addressed, "%s", p );
14534 }
14535 }
14536
14537 return strdup( addressed );
14538
14539}
14540
14541Variable * calculate_frame_by_type( Environment * _environment, TsxTileset * _tileset, char * _images, char * _description ) {
14542
14543 Variable * frame = variable_temporary( _environment, VT_BYTE, "(frame)");
14544
14545 if ( !_tileset ) {
14547 }
14548
14549 if ( !_tileset->tiles ) {
14551 }
14552
14553 TsxTile * collectedTiles = NULL;
14554 TsxTile * actual = _tileset->tiles;
14555
14556 while( actual ) {
14557
14558 if ( strcmp( actual->type, _description ) == 0 ) {
14559
14560 TsxTile * duplicatedTile = malloc( sizeof( TsxTile ) );
14561 memcpy( duplicatedTile, actual, sizeof( TsxTile ) );
14562 duplicatedTile->next = NULL;
14563 if ( collectedTiles ) {
14564 duplicatedTile->next = collectedTiles;
14565 collectedTiles = duplicatedTile;
14566 } else {
14567 collectedTiles = duplicatedTile;
14568 }
14569 }
14570 actual = actual->next;
14571 }
14572
14573 if ( !collectedTiles ) {
14575 }
14576
14577 double totalProbability = 0.0f;
14578
14579 actual = collectedTiles;
14580
14581 while( actual ) {
14582 totalProbability += actual->probability;
14583 actual->probability = totalProbability;
14584 actual = actual->next;
14585 }
14586
14587 if ( totalProbability <= 0 ) {
14589 }
14590
14591 float r = ( (float) rand() ) / ( (float) (RAND_MAX/totalProbability) );
14592
14593 totalProbability = 0.0f;
14594
14595 actual = collectedTiles;
14596
14597 while( actual ) {
14598 if ( r < actual->probability ) {
14599 break;
14600 }
14601 actual = actual->next;
14602 }
14603
14604 if ( actual ) {
14605 variable_store(_environment, frame->name, actual->id );
14606 } else {
14607 variable_store(_environment, frame->name, collectedTiles->id );
14608 }
14609
14610}
14611
14612int find_frame_by_type( Environment * _environment, TsxTileset * _tileset, char * _images, char * _description ) {
14613
14614 if ( !_tileset ) {
14616 }
14617
14618 if ( !_tileset->tiles ) {
14620 }
14621
14622 TsxTile * collectedTiles = NULL;
14623 TsxTile * actual = _tileset->tiles;
14624
14625 while( actual ) {
14626
14627 if ( actual->type ) {
14628 if ( strcmp( actual->type, _description ) == 0 ) {
14629 return actual->id;
14630 }
14631 }
14632 actual = actual->next;
14633 }
14634
14636
14637}
14638
14639Variable * variable_direct_assign( Environment * _environment, char * _var, char * _expr ) {
14640
14641 Variable * expr = variable_retrieve( _environment, _expr );
14642 Variable * var;
14643 if ( variable_exists( _environment, _var ) ) {
14644 var = variable_retrieve( _environment, _var );
14645 if ( var->type != expr->type ) {
14647 }
14648 } else {
14649 if ( !((struct _Environment *)_environment)->optionExplicit ) {
14650 var = variable_define( _environment, _var, expr->type == VT_STRING ? VT_DSTRING : expr->type, 0 );
14651 } else {
14653 }
14654 }
14655
14656 if ( ! VT_DIRECT_ASSIGN( expr->type ) ) {
14658 }
14659
14660 var->value = expr->value;
14661 var->valueString = expr->valueString;
14662 var->valueFloating = expr->valueFloating;
14663 var->size = expr->size;
14664 if ( expr->valueBuffer ) {
14665 var->valueBuffer = malloc( expr->size );
14666 memcpy( var->valueBuffer, expr->valueBuffer, expr->size );
14667 }
14668 var->absoluteAddress = expr->absoluteAddress;
14669 var->bank = expr->bank;
14670 var->originalBitmap = expr->originalBitmap;
14671 var->originalWidth = expr->originalWidth;
14672 var->originalHeight = expr->originalHeight;
14673 var->frameWidth = expr->frameWidth;
14674 var->frameHeight = expr->frameHeight;
14675 var->mapWidth = expr->mapWidth;
14676 var->mapHeight = expr->mapHeight;
14677 var->mapLayers = expr->mapLayers;
14678 var->originalDepth = expr->originalDepth;
14679 var->originalColors = expr->originalColors;
14680 memcpy( var->originalPalette, expr->originalPalette, MAX_PALETTE * sizeof( RGBi ) );
14681 var->originalTileset = expr->originalTileset;
14682 var->originalTilemap = expr->originalTilemap;
14683 var->bitPosition = expr->bitPosition;
14684 var->bitByte = expr->bitByte;
14685 var->tileset = expr->tileset;
14686 var->bankAssigned = expr->bankAssigned;
14689 if ( var->bankAssigned != -1 ) {
14690 var->absoluteAddress = expr->absoluteAddress;
14692 }
14693 var->sidFile = expr->sidFile;
14694 var->memoryArea = expr->memoryArea;
14695 var->arrayDimensions = expr->arrayDimensions;
14696 memcpy( var->arrayDimensionsEach, expr->arrayDimensionsEach, MAX_ARRAY_DIMENSIONS * sizeof( int ) );
14697 var->arrayType = expr->arrayType;
14698 var->arrayPrecision = expr->arrayPrecision;
14699 var->frameSize = expr->frameSize;
14700 var->frameCount = expr->frameCount;
14701 var->readonly = expr->readonly;
14702 var->compression = expr->compression;
14703 expr->assigned = 1;
14705 if ( var->offsettingFrames ) {
14706 offsetting_add_variable_reference( _environment, var->offsettingFrames, var, 0 );
14707 }
14708 var->strips = expr->strips;
14709 if ( expr->typeType ) {
14710 var->typeType = expr->typeType;
14711 var->size = expr->typeType->size;
14712 }
14713
14715 if ( var->offsettingSequences ) {
14716 offsetting_add_variable_reference( _environment, var->offsettingSequences, var, 1 );
14717 }
14718
14719 if ( expr->onStorage ) {
14720 variable_move( _environment, expr->name, var->name );
14721 }
14722
14723 return var;
14724
14725}
14726
14727StaticString * string_reserve( Environment * _environment, char * _value ) {
14728
14729 if ( strlen( _value ) > 255 ) {
14731 }
14732
14733 StaticString * current = _environment->strings;
14734
14735 while ( current ) {
14736 if ( strcmp( current->value, _value ) == 0 ) {
14737 return current;
14738 }
14739 current = current->next;
14740 }
14741
14742 current = malloc( sizeof( StaticString ) );
14743 memset( current, 0, sizeof( StaticString ) );
14744
14745 current->id = UNIQUE_ID;
14746 current->value = unescape_string( _environment, _value, 0, &current->size );
14747
14748 current->next = _environment->strings;
14749 _environment->strings = current;
14750
14751 return current;
14752
14753}
14754
14756
14757 ArrayReference * result = malloc( sizeof( ArrayReference ) );
14758 memset( result, 0, sizeof( ArrayReference ) );
14759 result->arrayIndexes = ((struct _Environment *)_environment)->arrayIndexes[((struct _Environment *)_environment)->arrayNestedIndex];
14760 memcpy( result->arrayIndexesEach, ((struct _Environment *)_environment)->arrayIndexesEach[((struct _Environment *)_environment)->arrayNestedIndex], MAX_ARRAY_DIMENSIONS * sizeof( char * ) );
14761 memcpy( result->arrayIndexesDirectEach, ((struct _Environment *)_environment)->arrayIndexesDirectEach[((struct _Environment *)_environment)->arrayNestedIndex], MAX_ARRAY_DIMENSIONS * sizeof( int ) );
14762
14763 return result;
14764
14765}
14766
14767void parser_array_init( Environment * _environment ) {
14768
14769 ++((struct _Environment *)_environment)->arrayNestedIndex;
14770 memset( ((struct _Environment *)_environment)->arrayIndexesEach[((struct _Environment *)_environment)->arrayNestedIndex], 0, sizeof( char * ) * MAX_ARRAY_DIMENSIONS );
14771 memset( ((struct _Environment *)_environment)->arrayIndexesDirectEach[((struct _Environment *)_environment)->arrayNestedIndex], 0, sizeof( int ) * MAX_ARRAY_DIMENSIONS );
14772 ((struct _Environment *)_environment)->arrayIndexes[((struct _Environment *)_environment)->arrayNestedIndex] = 0;
14773
14774}
14775
14776void parser_array_init_by( Environment * _environment, ArrayReference * _array_reference ) {
14777
14778 ++((struct _Environment *)_environment)->arrayNestedIndex;
14779 ((struct _Environment *)_environment)->arrayIndexes[((struct _Environment *)_environment)->arrayNestedIndex] = _array_reference->arrayIndexes;
14780 memcpy( ((struct _Environment *)_environment)->arrayIndexesEach[((struct _Environment *)_environment)->arrayNestedIndex], _array_reference->arrayIndexesEach, MAX_ARRAY_DIMENSIONS * sizeof( char * ) );
14781 memcpy( ((struct _Environment *)_environment)->arrayIndexesDirectEach[((struct _Environment *)_environment)->arrayNestedIndex], _array_reference->arrayIndexesDirectEach, MAX_ARRAY_DIMENSIONS * sizeof( int ) );
14782
14783}
14784
14785void parser_array_cleanup( Environment * _environment ) {
14786
14787 -- ((struct _Environment *)_environment)->arrayNestedIndex;
14788
14789}
14790
14791void parser_array_index_symbolic( Environment * _environment, char * _index ) {
14792
14793 ((struct _Environment *)_environment)->arrayIndexesEach[((struct _Environment *)_environment)->arrayNestedIndex][((struct _Environment *)_environment)->arrayIndexes[((struct _Environment *)_environment)->arrayNestedIndex]] = strdup( _index );
14794 ((struct _Environment *)_environment)->arrayIndexesDirectEach[((struct _Environment *)_environment)->arrayNestedIndex][((struct _Environment *)_environment)->arrayIndexes[((struct _Environment *)_environment)->arrayNestedIndex]] = 0;
14795 ++((struct _Environment *)_environment)->arrayIndexes[((struct _Environment *)_environment)->arrayNestedIndex];
14796
14797}
14798
14799void parser_array_index_numeric( Environment * _environment, int _index ) {
14800
14801 ((struct _Environment *)_environment)->arrayIndexesEach[((struct _Environment *)_environment)->arrayNestedIndex][((struct _Environment *)_environment)->arrayIndexes[((struct _Environment *)_environment)->arrayNestedIndex]] = NULL;
14802 ((struct _Environment *)_environment)->arrayIndexesDirectEach[((struct _Environment *)_environment)->arrayNestedIndex][((struct _Environment *)_environment)->arrayIndexes[((struct _Environment *)_environment)->arrayNestedIndex]] = _index;
14803 ++((struct _Environment *)_environment)->arrayIndexes[((struct _Environment *)_environment)->arrayNestedIndex];
14804
14805}
14806
14808
14809 if ( _environment->defaultNarrowType ) {
14810 if ( _environment->defaultUnsignedType ) {
14811 if ( _number < 0 ) {
14812 if ( (-_number) > (0x7fff) ) {
14813 return VT_SDWORD;
14814 } else if ( (-_number) > (0x7f) ) {
14815 return VT_SWORD;
14816 } else {
14817 return VT_SBYTE;
14818 }
14819 } else {
14820 if ( _number > (0xffff) ) {
14821 return VT_DWORD;
14822 } else if ( _number > (0xff) ) {
14823 return VT_WORD;
14824 } else {
14825 return VT_BYTE;
14826 }
14827 }
14828 } else {
14829 if ( abs(_number) > (0x7fff) ) {
14830 return VT_SDWORD;
14831 } else if ( abs(_number) > (0x7f) ) {
14832 return VT_SWORD;
14833 } else {
14834 return VT_SBYTE;
14835 }
14836 }
14837 } else {
14838 switch( _environment->defaultVariableType ) {
14839 case VT_SDWORD:
14840 case VT_DWORD:
14841 return _environment->defaultVariableType;
14842 case VT_SWORD:
14843 case VT_WORD:
14844 if ( abs(_number) > 0x7fff ) {
14845 if ( VT_SIGNED( _environment->defaultVariableType ) ) {
14846 return VT_SDWORD;
14847 } else {
14848 return VT_DWORD;
14849 }
14850 } else {
14851 return _environment->defaultVariableType;
14852 }
14853 case VT_BYTE:
14854 case VT_SBYTE:
14855 if ( abs(_number) > 0x7fff ) {
14856 if ( VT_SIGNED( _environment->defaultVariableType ) ) {
14857 return VT_SDWORD;
14858 } else {
14859 return VT_DWORD;
14860 }
14861 } else if ( abs(_number) > 0x7f ) {
14862 if ( VT_SIGNED( _environment->defaultVariableType ) ) {
14863 return VT_SWORD;
14864 } else {
14865 return VT_WORD;
14866 }
14867 } else {
14868 return _environment->defaultVariableType;
14869 }
14870 }
14871 }
14872}
14873
14874Variable * parser_adapted_numeric( Environment * _environment, int _number ) {
14875
14876 Variable * number;
14877 VariableType type = variable_type_from_numeric_value( _environment, _number );
14878
14879 number = variable_temporary( _environment, type, "(value)" );
14880
14881 variable_store( _environment, number->name, _number );
14882
14883 number->initializedByConstant = 1;
14884
14885 return number;
14886
14887}
14888
14889Variable * parser_casted_numeric( Environment * _environment, VariableType _type, int _number ) {
14890
14891 Variable * number = variable_temporary( _environment, _type, "(CASTED value)" );
14892
14893 variable_store( _environment, number->name, _number );
14894
14895 number->initializedByConstant = 1;
14896
14897 return number;
14898
14899}
14900
14901DataSegment * data_segment_define( Environment * _environment, char * _name ) {
14902
14903 DataSegment * data = malloc( sizeof( DataSegment ) );
14904 memset( data, 0, sizeof( DataSegment ) );
14905 data->name = strdup( _name );
14906 data->realName = malloc( strlen( _name ) + 6 );
14907 data->absoluteAddress = _environment->dataLastAbsoluteAddress;
14908 strcopy( data->realName, "DATA_" );
14909 strcat( data->realName, data->name );
14910
14911 if ( ! _environment->dataSegment ) {
14912 _environment->dataSegment = data;
14913 } else {
14914 DataSegment * first = _environment->dataSegment;
14915 while( first->next ) {
14916 first = first->next;
14917 }
14918 first->next = data;
14919 }
14920
14921 return data;
14922
14923}
14924
14925DataSegment * data_segment_define_numeric( Environment * _environment, int _number ) {
14926
14927 DataSegment * data = malloc( sizeof( DataSegment ) );
14928 memset( data, 0, sizeof( DataSegment ) );
14929 data->lineNumber = _number;
14930 data->isNumeric = 1;
14931 data->absoluteAddress = _environment->dataLastAbsoluteAddress;
14932 data->realName = malloc( MAX_TEMPORARY_STORAGE );
14933 sprintf( data->realName, "DATA_%4.4x", _number );
14934
14935 if ( ! _environment->dataSegment ) {
14936 _environment->dataSegment = data;
14937 } else {
14938 DataSegment * first = _environment->dataSegment;
14939 while( first->next ) {
14940 first = first->next;
14941 }
14942 first->next = data;
14943 }
14944
14945 return data;
14946
14947}
14948
14949DataSegment * data_segment_find( Environment * _environment, char * _name ) {
14950
14951 DataSegment * first = _environment->dataSegment;
14952 while( first ) {
14953 if ( !first->isNumeric && strcmp( first->name, _name ) == 0 ) {
14954 return first;
14955 }
14956 first = first->next;
14957 }
14958
14959 return NULL;
14960
14961}
14962
14963DataSegment * data_segment_find_numeric( Environment * _environment, int _number ) {
14964
14965 DataSegment * first = _environment->dataSegment;
14966 while( first ) {
14967 if ( first->isNumeric && first->lineNumber == _number ) {
14968 return first;
14969 }
14970 first = first->next;
14971 }
14972
14973 return NULL;
14974
14975}
14976
14978
14979 DataSegment * data = data_segment_find( _environment, _name );
14980
14981 if ( !data ) {
14982 data = data_segment_define( _environment, _name );
14983 }
14984
14985 return data;
14986
14987}
14988
14990
14991 DataSegment * data = data_segment_find_numeric( _environment, _number );
14992
14993 if ( !data ) {
14994 data = data_segment_define_numeric( _environment, _number );
14995 }
14996
14997 return data;
14998
14999}
15000
15001static void buffered_realloc( Environment * _environment, const char * _ptr, int _size ) {
15002 if ( _environment->bufferOutput[_environment->currentBufferOutput] ) {
15003 _environment->bufferOutput[_environment->currentBufferOutput] = realloc( _environment->bufferOutput[_environment->currentBufferOutput], _environment->bufferOutputSize[_environment->currentBufferOutput] + _size );
15004 } else {
15005 _environment->bufferOutput[_environment->currentBufferOutput] = malloc( _size );
15006 }
15007 memcpy( _environment->bufferOutput[_environment->currentBufferOutput] + _environment->bufferOutputSize[_environment->currentBufferOutput], _ptr , _size );
15008 _environment->bufferOutputSize[_environment->currentBufferOutput] += _size;
15009}
15010
15011void buffered_fprintf( Environment * _environment, FILE * _stream, const char * _format, ... ) {
15012 char temporaryBuffer[ MAX_TEMPORARY_STORAGE * 16 ];
15013 va_list args;
15014 va_start( args, _format );
15015 // vfprintf( _stream, _format, args );
15016 vsprintf( temporaryBuffer, _format, args );
15017 buffered_realloc( _environment, temporaryBuffer, strlen( temporaryBuffer ) );
15018 va_end( args );
15019}
15020
15021int buffered_fputs( Environment * _environment, const char * _string, FILE * _stream ) {
15022 // fputs( _string, _stream );
15023 buffered_realloc( _environment, _string, strlen( _string ) );
15024}
15025
15026size_t buffered_fwrite( Environment * _environment, void * _data, size_t _size, size_t _count, FILE * _stream ) {
15027 // fwrite( _data, _size, _count, _stream );
15028 buffered_realloc( _environment, _data, _size * _count );
15029}
15030
15031void buffered_push_output( Environment * _environment ) {
15032 ++_environment->currentBufferOutput;
15033}
15034
15035void buffered_pop_output( Environment * _environment ) {
15036 _environment->bufferOutput[_environment->currentBufferOutput] = NULL;
15037 _environment->bufferOutputSize[_environment->currentBufferOutput] = 0;
15038 --_environment->currentBufferOutput;
15039}
15040
15041void buffered_prepend_output( Environment * _environment ) {
15042 char * p = malloc( _environment->bufferOutputSize[_environment->currentBufferOutput-1] + _environment->bufferOutputSize[_environment->currentBufferOutput] );
15043 memset( p, 0, _environment->bufferOutputSize[_environment->currentBufferOutput-1] + _environment->bufferOutputSize[_environment->currentBufferOutput] );
15044 memcpy( p, _environment->bufferOutput[_environment->currentBufferOutput], _environment->bufferOutputSize[_environment->currentBufferOutput] );
15045 memcpy( p + _environment->bufferOutputSize[_environment->currentBufferOutput], _environment->bufferOutput[_environment->currentBufferOutput-1], _environment->bufferOutputSize[_environment->currentBufferOutput-1] );
15046 _environment->bufferOutput[_environment->currentBufferOutput-1] = p;
15047 _environment->bufferOutputSize[_environment->currentBufferOutput-1] = _environment->bufferOutputSize[_environment->currentBufferOutput-1] + _environment->bufferOutputSize[_environment->currentBufferOutput];
15048 buffered_pop_output( _environment );
15049}
15050
15051void buffered_output( Environment * _environment, FILE * _stream ) {
15052 fwrite( _environment->bufferOutput[_environment->currentBufferOutput], 1, _environment->bufferOutputSize[_environment->currentBufferOutput], _stream );
15053}
15054
15055void get_image_overwrite_size( Environment * _environment, char * _image, char * _x1, char * _y1, char * _x2, char * _y2 ) {
15056
15057 Variable * image = variable_retrieve( _environment, _image );
15058 Variable * x1 = variable_retrieve_or_define( _environment, _x1, VT_POSITION, 0 );
15059 Variable * y1 = variable_retrieve_or_define( _environment, _y1, VT_POSITION, 0 );
15060
15061 Variable * x2 = variable_retrieve_or_define( _environment, _x2, VT_POSITION, 0 );
15062 Variable * y2 = variable_retrieve_or_define( _environment, _y2, VT_POSITION, 0 );
15063 Variable * width = absolute( _environment, variable_sub( _environment, x2->name, x1->name )->name );
15064 Variable * height = absolute( _environment, variable_sub( _environment, y2->name, y1->name )->name );
15065 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address)" );
15066 cpu_move_16bit( _environment, width->realName, image->realName );
15067 cpu_addressof_16bit( _environment, image->realName, address->realName );
15068 cpu_math_add_16bit_const( _environment, address->realName, 2, address->realName );
15069 cpu_move_8bit_indirect( _environment, height->realName, address->realName );
15070
15071}
15072
15073Resource * build_resource_for_sequence( Environment * _environment, char * _image, char * _frame, char * _sequence ) {
15074
15075 Resource * resource = malloc( sizeof( Resource ) );
15076 memset( resource, 0, sizeof( Resource ) );
15077
15078 Variable * image = variable_retrieve( _environment, _image );
15079
15080 if ( ! image->valueBuffer && image->type != VT_ADDRESS ) {
15082 }
15083
15084 resource->realName = image->realName;
15085 resource->type = image->type;
15086 resource->compression = image->compression;
15087
15088 if ( resource->type == VT_ADDRESS ) {
15089 resource->isAddress = 1;
15090 if ( _sequence ) {
15091 resource->type = VT_SEQUENCE;
15092 } else if ( _frame ) {
15093 resource->type = VT_IMAGES;
15094 } else {
15095 resource->type = VT_IMAGE;
15096 }
15097 }
15098
15099 return resource;
15100
15101}
15102
15103/* <usermanual>
15104@keyword INT (function)
15105
15106@english
15107
15108The ''INT'' command is a mathematical function that rounds a ''FLOAT''
15109to the smallest ''INT'' number. In other words, it cuts off the decimal
15110part of the number, returning only the whole part.
15111
15112If you apply ''INT'' to a number that is already an integer, the result
15113will be the same number. ''INT'' is rounded down, so for negative numbers
15114it means taking the largest integer (in absolute value) less than or
15115equal to the original number.
15116
15117''INT'' is useful when you need to work only with the integer part of
15118a number. It can be used in combination with other mathematical operations
15119to perform more complex calculations. Sometimes you need to convert a ''FLOAT''
15120to an integer in order to use it in certain functions or data structures.
15121
15122@italian
15123
15124Il comando ''INT'' è una funzione matematica che arrotonda un ''FLOAT''
15125al numero ''INT'' più piccolo. In altre parole, taglia la parte decimale
15126del numero, restituendo solo la parte intera.
15127
15128Se applichi ''INT'' a un numero che è già un intero, il risultato sarà
15129lo stesso numero. ''INT'' viene arrotondato per difetto, quindi per i
15130numeri negativi significa prendere l'intero più grande (in valore assoluto)
15131minore o uguale al numero originale.
15132
15133''INT'' è utile quando devi lavorare solo con la parte intera di un numero.
15134Può essere utilizzato in combinazione con altre operazioni matematiche per
15135eseguire calcoli più complessi. A volte devi convertire un ''FLOAT'' in un
15136intero per utilizzarlo in determinate funzioni o strutture dati.
15137
15138@syntax = INT(value)
15139
15140@example x = 1.5
15141@example PRINT INT(x) : ' It prints 1
15142
15143</usermanual> */
15144
15145Variable * variable_int( Environment * _environment, char * _expression ) {
15146
15147 Variable * expression = variable_retrieve( _environment, _expression );
15148 Variable * result = variable_temporary( _environment, VT_SWORD, "(result)" );
15149
15150 variable_move( _environment, expression->name, result->name );
15151
15152 return result;
15153
15154}
15155
15157
15158 char * result = NULL;
15159
15160 result = malloc( MAX_TEMPORARY_STORAGE );
15161 memset( result, 0, MAX_TEMPORARY_STORAGE );
15162
15163#ifdef _WIN32
15164
15165 // Windows: The path reported by the Windows GetTempPath API function.
15166
15167 int len = GetTempPathA( MAX_TEMPORARY_STORAGE, result );
15168
15169 if ( len > 0 ) {
15170 GetTempPathA( len, result );
15171 result[len] = 0;
15172 }
15173
15174 if ( result[strlen(result)-1] == '\\' || result[strlen(result)-1] == '/' ) {
15175 result[strlen(result)-1] = 0;
15176 }
15177
15178#else
15179
15180 // ISO/IEC 9945 (POSIX): The path supplied by the first environment
15181 // variable found in the list TMPDIR, TMP, TEMP, TEMPDIR. If none of these are
15182 // found, "/tmp", or, if macro __ANDROID__ is defined, "/data/local/tmp"
15183
15184 char * tmp = getenv( "TMPDIR" );
15185 if ( !tmp ) {
15186 tmp = getenv( "TMP" );
15187 }
15188 if ( !tmp ) {
15189 tmp = getenv( "TEMP" );
15190 }
15191 if ( !tmp ) {
15192 tmp = getenv( "TEMPDIR" );
15193 }
15194 if ( !tmp ) {
15195 tmp = strdup( "/tmp" );
15196 }
15197
15198 result = strdup( tmp );
15199
15200#endif
15201
15202 return result;
15203
15204}
15205
15206char * find_last_path_separator( char * _path ) {
15207
15208 char * basePath = strrchr( _path, '/' );
15209
15210 if ( !basePath ) {
15211 basePath = strrchr( _path, '\\' );
15212 }
15213
15214 return basePath;
15215
15216}
15217
15218void prepare_variable_storage( Environment * _environment, char * _name, Variable * _source ) {
15219
15220 Variable * v = NULL;
15221
15222 if ( variable_exists( _environment, _name ) ) {
15223 v = variable_retrieve( _environment, _name );
15224 if ( v->type != _source->type ) {
15226 }
15227 } else {
15228 v = variable_define( _environment, _name, _source->type, 0 );
15229 }
15230
15231 int currentSize = v->size;
15232
15233 variable_direct_assign( _environment, v->name, _source->name );
15234
15235 v->size = currentSize;
15236
15237 FileStorage * fileStorage = _environment->currentFileStorage;
15238
15239 if ( ! fileStorage ) {
15241 }
15242
15243 if ( v->size < fileStorage->size ) {
15244 if ( v->valueBuffer ) {
15245 v->valueBuffer = malloc( fileStorage->size );
15246 } else {
15247 v->valueBuffer = malloc( fileStorage->size );
15248 }
15249 v->size = fileStorage->size;
15250 memset( v->valueBuffer, 0, v->size );
15251 }
15252
15253 if ( v->bankAssigned != -1 ) {
15255 }
15256
15257 v->onStorage = 1;
15258
15259}
15260
15261char * generate_storage_filename( Environment * _environment, char * _prefix, char * _suffix, int _number ) {
15262
15263 char filename[ MAX_TEMPORARY_STORAGE ];
15264
15265 sprintf( filename, "%s%2.2d.%s", _prefix, _number, _suffix );
15266
15267 return strdup( filename );
15268
15269}
15270
15271int file_get_size( Environment * _environment, char * _filename ) {
15272
15273 FILE * lookedFileHandle = fopen( _filename, "rb" );
15274 fseek( lookedFileHandle, 0, SEEK_END );
15275 int fileSize = ftell( lookedFileHandle );
15276 fclose( lookedFileHandle );
15277 return fileSize;
15278
15279}
15280
15281Variable * variable_string_insert( Environment * _environment, char * _string, char * _altstring, char * _pos ) {
15282
15283 Variable * string = variable_retrieve_or_define( _environment, _string, VT_DSTRING, 0 );
15284 Variable * altstring = variable_retrieve_or_define( _environment, _altstring, VT_DSTRING, 0 );
15285 Variable * pos = variable_retrieve_or_define( _environment, _pos, VT_BYTE, 0 );
15286 Variable * pos1 = variable_temporary( _environment, VT_BYTE, 0 );
15287 Variable * len = variable_temporary( _environment, VT_BYTE, 0 );
15288 Variable * tmpLen = variable_temporary( _environment, VT_BYTE, 0 );
15289
15290 switch( string->type ) {
15291 case VT_STRING:
15292 variable_move( _environment, string->name, len->name );
15293 break;
15294 case VT_DSTRING:
15295 cpu_dsdescriptor( _environment, string->realName, NULL, len->realName );
15296 break;
15297 }
15298
15299 variable_move( _environment, len->name, tmpLen->name );
15300 variable_increment( _environment, tmpLen->name );
15301
15302 Variable * result = variable_temporary( _environment, VT_DSTRING, 0 );
15303
15305 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneLabel, "%sdone", label );
15306 char finishedLabel[MAX_TEMPORARY_STORAGE]; sprintf( finishedLabel, "%sfinish", label );
15307
15308 variable_move( _environment, pos->name, pos1->name );
15309
15310 cpu_compare_and_branch_8bit_const( _environment, variable_greater_than( _environment, pos->name, tmpLen->name, 0 )->realName, 0xff, doneLabel, 1 );
15311
15312 variable_move( _environment, pos->name, pos1->name );
15313
15314 Variable * left = variable_string_left( _environment, altstring->name, pos1->name );
15315 variable_increment( _environment, pos1->name );
15316 Variable * right = variable_string_mid( _environment, altstring->name, pos1->name, NULL );
15317
15318 variable_move( _environment, variable_add( _environment, variable_add( _environment, left->name, string->name )->name, right->name )->name, result->name );
15319
15320 cpu_jump( _environment, finishedLabel );
15321
15322 cpu_label( _environment, doneLabel );
15323
15324 variable_move( _environment, variable_add( _environment, altstring->name, string->name )->name, result->name );
15325
15326 cpu_label( _environment, finishedLabel );
15327
15328 return result;
15329
15330}
15331
15332/* <usermanual>
15333@keyword INST
15334
15335@english
15336
15337The ''INST'' function overwrites the characters of the string ''alt' with the character string
15338''string'' (first argument) in the character string ''alt'' (second argument) from the position
15339''pos'' (third argument), whereby the counting starts with 1. The length of the character
15340string ''altstring'' does not change.
15341
15342@italian
15343
15344La funzione ''INST'' sovrascrive i caratteri della stringa ''alt'' con la stringa di caratteri
15345''string'' (primo argomento) nella stringa di caratteri ''alt'' (secondo argomento) dalla posizione
15346''pos'' (terzo argomento), per cui il conteggio inizia da 1. La lunghezza della stringa di
15347caratteri ''altstring'' non cambia.
15348
15349@syntax = INST( string, alt, pos )
15350
15351@example c$=INST(a$,b$,9)
15352
15353@usedInExample tsb_insert_01.bas
15354
15355</usermanual> */
15356
15357Variable * variable_string_inst( Environment * _environment, char * _string, char * _altstring, char * _pos ) {
15358
15359 // INST overwrites the characters of the string <altstring> with the string <string> (first argument)
15360 // in the string <altstring> (second argument) from the position <pos> (third argument), whereby the
15361 // counting starts with 1, unlike in Simons' Basic (1 = first character; Simons' Basic: 0!). The length
15362 // of the string <altstring> does not change.
15363
15364 Variable * string = variable_retrieve_or_define( _environment, _string, VT_DSTRING, 0 );
15365 Variable * altstring = variable_retrieve_or_define( _environment, _altstring, VT_DSTRING, 0 );
15366 Variable * pos = variable_retrieve_or_define( _environment, _pos, VT_BYTE, 0 );
15367 Variable * pos1 = variable_temporary( _environment, VT_BYTE, 0 );
15368 variable_move( _environment, pos->name, pos1->name );
15369
15370 Variable * result = variable_temporary( _environment, VT_DSTRING, "(result)");
15371
15372 variable_move( _environment, altstring->name, result->name );
15373
15374 Variable * stringLen = variable_string_len( _environment, string->name );
15375 variable_string_mid_assign( _environment, result->name, pos->name, stringLen->name, string->name );
15376
15377 return result;
15378
15379}
15380
15381
15382/* <usermanual>
15383@keyword PICK
15384
15385@english
15386
15387The ''PICK'' function allows you to obtain the ASCII code of any character present in a
15388string, provided that the offset within the string is provided.
15389
15390@italian
15391
15392La funzione ''PICK'' permette di ottenere il codice ASCII di un qualsiasi
15393carattere presente in una stringa, purché sia fornito l'offset all'interno della stringa.
15394
15395@syntax = PICK( string, offset )
15396
15397@example PRINT PICK( "TEST", 2 )
15398
15399</usermanual> */
15400
15401Variable * variable_string_pick( Environment * _environment, char * _string, int _position ) {
15402
15403 Variable * result = variable_temporary( _environment, VT_BYTE, "(char)");
15404
15405 Variable * source = variable_retrieve( _environment, _string );
15406 Variable * sourceAddress = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING1)");
15407 Variable * sourceSize = variable_temporary( _environment, VT_BYTE, "(size of DSTRING1)");
15408
15409 switch( source->type ) {
15410 case VT_STRING:
15411 cpu_addressof_16bit( _environment, source->realName, sourceAddress->realName );
15412 cpu_math_add_16bit_const( _environment, sourceAddress->realName, _position+1, sourceAddress->realName );
15413 break;
15414 case VT_DSTRING:
15415 cpu_dsdescriptor( _environment, source->realName, sourceAddress->realName, sourceSize->realName );
15416 cpu_math_add_16bit_const( _environment, sourceAddress->realName, _position, sourceAddress->realName );
15417 break;
15418 }
15419
15420 cpu_move_8bit_indirect2( _environment, sourceAddress->realName, result->realName );
15421
15422 return result;
15423
15424}
15425
15426char * resolve_color( Environment * _environment, char * _color ) {
15427
15428 if ( _color ) {
15429 Variable * color = NULL;
15430 if (_environment->colorImplicit ) {
15431 color = sbpen_get( _environment, _color );
15432 } else {
15433 color = variable_retrieve_or_define( _environment, _color, VT_COLOR, COLOR_WHITE );
15434 }
15435 return color->name;
15436 } else {
15437 return NULL;
15438 }
15439
15440}
15441
15442static int show_troubleshooting_accessing_path( Environment * _environment, char * _path, int _mode, int _create, int _show ) {
15443
15444 int check = 0;
15445
15446 if ( _create ) {
15447 FILE * fh = fopen( _path, "wt" );
15448 fprintf( fh, "test" );
15449 fclose( fh );
15450 }
15451
15452 if ( ( _mode & R_OK ) && access( _path, R_OK ) ) {
15453 if ( _show ) {
15454 printf( "#####> It cannot be read: %s\n", strerror(errno));
15455 }
15456 check |= R_OK;
15457 }
15458 if ( ( _mode & W_OK ) && access( _path, W_OK ) ) {
15459 if ( _show ) {
15460 printf( "#####> It cannot be write: %s\n", strerror(errno));
15461 }
15462 check |= W_OK;
15463 }
15464 if ( ( _mode & X_OK ) && access( _path, X_OK ) ) {
15465 if ( _show ) {
15466 printf( "#####> It cannot be executed: %s\n", strerror(errno));
15467 }
15468 check |= X_OK;
15469 }
15470 if ( ( _mode & F_OK ) && access( _path, F_OK ) ) {
15471 if ( _show ) {
15472 printf( "#####> It does not exist: %s\n", strerror(errno));
15473 }
15474 check |= F_OK;
15475 }
15476
15477 if ( _create ) {
15478 remove( _path );
15479 }
15480
15481 return check;
15482
15483}
15484
15485static int show_troubleshooting_try_exec( Environment * _environment, char * _path, int _show ) {
15486
15487 char mutedExecutable[2*MAX_TEMPORARY_STORAGE]; sprintf( mutedExecutable, "%s >/dev/null 2>/dev/null", _path );
15488
15489 int check = 0;
15490
15491 if ( system( mutedExecutable ) < 0 ) {
15492 if ( _show ) {
15493 printf( "#####> It cannot be executed: %s\n", strerror(errno));
15494 }
15495 check = 1;
15496 }
15497
15498 return check;
15499
15500}
15501
15502int show_troubleshooting_and_exit( Environment * _environment, int _argc, char * _argv[] ) {
15503
15504 int check = 0;
15505
15506 printf( "========================\n");
15507 printf( "=== TROUBLE SHOOTING ===\n");
15508 printf( "========================\n\n");
15509
15510 printf( "Below you will find a brief analysis of the execution environment of\n" );
15511 printf( "the following compiler: \"%s\".\n", _argv[0] );
15512 printf( "For each entry, the outcome of a brief testing is reported, where the possible\n" );
15513 printf( "cause is also indicated. Please follow the preliminary indications contained\n" );
15514 printf( "here and, in case you are not successful in producing an assembly listing or\n" );
15515 printf( "an executable / binary file, please contact the author via GitHub here:\n" );
15516 printf( "https://github.com/spotlessmind1975/ugbasic/issues/new\n\n" );
15517
15518#ifdef _WIN32
15519
15520 char systemDirectoryPath[2*MAX_TEMPORARY_STORAGE];
15521 check = GetSystemDirectoryA( systemDirectoryPath, MAX_TEMPORARY_STORAGE );
15522 if ( check>0 ) {
15523 check = GetSystemDirectoryA( systemDirectoryPath, check );
15524 systemDirectoryPath[check] = 0;
15525 printf( "[PA0] SYSTEM DIRECTORY PATH = \"%s\" (%d)\n", systemDirectoryPath, check );
15526 } else {
15527 printf( "[PA0] SYSTEM DIRECTORY PATH: (unable to retrieve)\n" );
15528 printf( "##### An error occurred while the program tried to \n" );
15529 printf( "##### retrieve the name of the system directory: %d\n", GetLastError( ) );
15530 }
15531
15532 char systemDirectoryCmdPath[MAX_TEMPORARY_STORAGE];
15533 sprintf( systemDirectoryCmdPath, "%s\\cmd.exe", systemDirectoryPath );
15534 printf( "[PA1] FULL NAME FOR CMD.EXE = \"%s\"\n", systemDirectoryCmdPath );
15535 check = show_troubleshooting_accessing_path( _environment, systemDirectoryCmdPath, R_OK, 0, 1 );
15536 if ( (check & R_OK) ) {
15537 printf( "##### The cmd.exe program seems not to exists. \n" );
15538 }
15539
15540 char systemPath[8*MAX_TEMPORARY_STORAGE];
15541 check = GetEnvironmentVariable( "Path", systemPath, 8*MAX_TEMPORARY_STORAGE );
15542 if ( check>0 ) {
15543 check = GetEnvironmentVariable( "Path", systemPath, check );
15544 systemPath[check] = 0;
15545 printf( "[PA2] ENVIRONMENT PATH = \"%s\" (%d)\n", systemPath, check );
15546 } else {
15547 printf( "[PA2] ENVIRONMENT PATH: (unable to retrieve)\n" );
15548 printf( "##### An error occurred while the program tried to \n" );
15549 printf( "##### retrieve the variable Path: %d\n", GetLastError( ) );
15550 }
15551
15552 printf( "[PA3] IS CMD.EXE IN PATH?\n" );
15553 int checkComplete = 0;
15554 char * t = strtok( systemPath, ";");
15555 while( t ) {
15556 char systemFileName[MAX_TEMPORARY_STORAGE];
15557 sprintf( systemFileName, "%s\\cmd.exe", t );
15558 check = show_troubleshooting_accessing_path( _environment, systemFileName, R_OK, 0, 0 );
15559 if ( !(check & R_OK) ) {
15560 printf( "[PA4] IS CMD.EXE IN PATH \"%s\"\n", systemFileName );
15561 checkComplete = 1;
15562 }
15563 t = strtok( NULL, ";" );
15564 }
15565
15566 if ( !checkComplete ) {
15567 printf( "##### The cmd.exe does not seem to be present or reachable\n" );
15568 printf( "##### inside the system Path.\n" );
15569 }
15570
15571 printf( "[PA5] CMD.EXE REPLACEMENT: %s\n", ( _environment->cmdFileName ) ? _environment->cmdFileName : "(no replacement)" );
15572 printf( "[PA6] IS (REPLACEMENT) COMMAND CMD.EXE EXECUTABLE? " );
15573
15574 // Now we can exec the batch file.
15575
15576 int cmdEsito = system( "cmd.exe /C" );
15577
15578 // If command is not a null pointer, system() shall return the
15579 // termination status of the command language interpreter in
15580 // the format specified by waitpid().
15581
15582 // The termination status shall be as defined for the sh
15583 // utility; otherwise, the termination status is unspecified.
15584
15585 switch( cmdEsito ) {
15586
15587 // If some error prevents the command language interpreter
15588 // from executing after the child process is created, the
15589 // return value from system() shall be as if the command
15590 // language interpreter had terminated using exit(127)
15591 // or _exit(127).
15592 case 127:
15593 printf( "\n##### It is like some error prevents the cmd.exe \n" );
15594 printf( "##### from executing after the child process is created.\n" );
15595 break;
15596
15597 // If a child process cannot be created, or if the termination
15598 // status for the command language interpreter cannot be obtained,
15599 // system() shall return -1 and set errno to indicate the error.
15600 case -1:
15601 printf( "\n##### It is like the cmd.exe cannot be created, or if the\n" );
15602 printf( "##### termination status for the cmd.exe\n" );
15603 printf( "##### cannot be obtained (errno = %d).\n\n", errno );
15604 perror( "##### Error from execution:");
15605 break;
15606
15607 case 0:
15608 printf( "yes, it is.\n");
15609 break;
15610
15611 default:
15612 printf( "\n##### It is like some error occurrend in execution of cmd.exe (%d).\n\n", cmdEsito );
15613 break;
15614 }
15615
15616#endif
15617
15619
15620#ifdef _WIN32
15621
15622 // Windows: The path reported by the Windows GetTempPath API function.
15623
15624 check = GetTempPathA( MAX_TEMPORARY_STORAGE, temporaryPath );
15625 if ( check > 0 ) {
15626 GetTempPathA( check, temporaryPath );
15627 temporaryPath[check] = 0;
15628 }
15629
15630#else
15631
15632 // ISO/IEC 9945 (POSIX): The path supplied by the first environment
15633 // variable found in the list TMPDIR, TMP, TEMP, TEMPDIR. If none of these are
15634 // found, "/tmp", or, if macro __ANDROID__ is defined, "/data/local/tmp"
15635
15636 char * tmp = getenv( "TMPDIR" );
15637 if ( !tmp ) {
15638 tmp = getenv( "TMP" );
15639 }
15640 if ( !tmp ) {
15641 tmp = getenv( "TEMP" );
15642 }
15643 if ( !tmp ) {
15644 tmp = getenv( "TEMPDIR" );
15645 }
15646 if ( !tmp ) {
15647 tmp = strdup( "/tmp" );
15648 }
15649 strcopy( temporaryPath, tmp );
15650 check = strlen(temporaryPath);
15651
15652#endif
15653
15654 if ( check ) {
15655 printf( "[P01] TEMPORARY PATH : \"%s\"\n", temporaryPath );
15656 } else {
15657 printf( "[P01] TEMPORARY PATH : (unable to retrieve)\n" );
15658 printf( "##### An error occurred while the program tried to \n" );
15659 printf( "##### retrieve the path of the temporary directory.\n" );
15660 }
15661
15662 check = show_troubleshooting_accessing_path( _environment, temporaryPath, R_OK | W_OK, 0, 1 );
15663
15664 if ( (check & R_OK) | (check & W_OK) | (check & X_OK) ) {
15665 printf( "##### There is a problem in accessing the temporary path. Please, check the above\n" );
15666 printf( "##### path, or use the '-T' parameter to set it in an explicit way.\n\n" );
15667 }
15668
15669 char temporaryFileName[MAX_TEMPORARY_STORAGE];
15670 strcopy( temporaryFileName, get_temporary_filename( _environment ) );
15671 printf( "[P02] TEMPORARY FILENAME : \"%s\"\n", temporaryFileName );
15672 check = show_troubleshooting_accessing_path( _environment, temporaryFileName, R_OK | W_OK | F_OK, 1, 1 );
15673
15674 if ( (check & R_OK) | (check & W_OK) | (check & F_OK) ) {
15675 printf( "##### There is a problem in creating a temporary file. Please, check the above\n" );
15676 printf( "##### path, or use the '-T' parameter to set a different temporary path.\n\n" );
15677 }
15678
15679 char workingDirectory[MAX_TEMPORARY_STORAGE];
15680 (void)!getcwd(workingDirectory, MAX_TEMPORARY_STORAGE);
15681 printf( "[P03] WORKING DIRECTORY: \"%s\"\n", workingDirectory );
15682 check = show_troubleshooting_accessing_path( _environment, workingDirectory, R_OK | W_OK | F_OK, 0, 1 );
15683
15684 if ( (check & R_OK) | (check & W_OK) | (check & F_OK) ) {
15685 printf( "##### There is a problem in accessing the current (working) directory.\n" );
15686 printf( "##### Please, check the permissions or use an explicit path with '-o'\n" );
15687 printf( "##### option, otherwise the binary file cannot be created.\n" );
15688 }
15689
15690#if defined(cpu6809)||defined(cpu6309)
15691
15692 char executableName[MAX_TEMPORARY_STORAGE];
15693 BUILD_TOOLCHAIN_ASM6809_GET_EXECUTABLE( _environment, executableName );
15694 printf( "[P04] EXECUTABLE NAME FOR ASM6809: \"%s\"\n", executableName );
15695 check = show_troubleshooting_try_exec( _environment, executableName, 1 );
15696 if ( check ) {
15697 printf( "##### The assembler for the 6809 processor does not appear to be present\n" );
15698 printf( "##### or executable. Please check the path or specify it using the \n" );
15699 printf( "##### '-C' option.\n" );
15700 }
15701
15702 #ifdef _WIN32
15703
15704 // First of all, we will create a temporary batch file
15705 // to call in place of the original command line.
15706
15708 sprintf( asmFileName, "%s.asm", get_temporary_filename( _environment ) );
15709 printf( "[P05] ASSEMBLY EXAMPLE (on temp path): \"%s\"\n", asmFileName );
15710 check = show_troubleshooting_accessing_path( _environment, asmFileName, W_OK, 1, 1 );
15711 if ( (check & W_OK) ) {
15712 printf( "##### The sample assembly file cannot be created. This could be related \n" );
15713 printf( "##### to any temporary path problem, so check the previous messages. \n" );
15714 }
15715
15716 FILE * fh = fopen( asmFileName, "wt" );
15717 if ( fh ) {
15718 fprintf( fh, "TEST\n JMP TEST\n" );
15719 fclose( fh );
15720 }
15721
15722 char binaryFileName[MAX_TEMPORARY_STORAGE];
15723 sprintf( binaryFileName, "%s.bin", get_temporary_filename( _environment ) );
15724 printf( "[P06] BINARY EXAMPLE (on temp path): \"%s\"\n", binaryFileName );
15725 check = show_troubleshooting_accessing_path( _environment, binaryFileName, W_OK, 1, 1 );
15726 if ( (check & W_OK) ) {
15727 printf( "##### The sample binary file cannot be created. This could be related \n" );
15728 printf( "##### to any temporary path problem, so check the previous messages. \n" );
15729 }
15730
15731 char batchFileName[MAX_TEMPORARY_STORAGE];
15732 sprintf( batchFileName, "%s.bat", get_temporary_filename( _environment ) );
15733 printf( "[P07] AUXILIARY BATCH FILE: \"%s\"\n", batchFileName );
15734 check = show_troubleshooting_accessing_path( _environment, batchFileName, W_OK | X_OK, 1, 1 );
15735 if ( (check & W_OK) || (check & X_OK)) {
15736 printf( "##### The auxiliary batch file cannot be created or executed. This could be related \n" );
15737 printf( "##### to any temporary path problem, so check the previous messages. Anyway, if the\n" );
15738 printf( "##### file cannot be executed, the binary / disk image cannot be built.\n" );
15739 }
15740
15741 fh = fopen( batchFileName, "w+t" );
15742 if ( fh ) {
15743 fprintf( fh, "@echo off\n\"%s\" -o \"%s\" \"%s\"\n", executableName, binaryFileName, asmFileName );
15744 fclose( fh );
15745 }
15746
15747 char batchFileName2[MAX_TEMPORARY_STORAGE];
15748 sprintf( batchFileName2, "%s\\cmd.exe /C \"%s\"", systemDirectoryPath, batchFileName );
15749 printf( "[P08] BATCH LAUNCHER COMMAND LINE: %s\n", batchFileName2 );
15750
15751 // Now we can exec the batch file.
15752
15753 int esito = system( batchFileName2 );
15754
15755 // If command is not a null pointer, system() shall return the
15756 // termination status of the command language interpreter in
15757 // the format specified by waitpid().
15758
15759 // The termination status shall be as defined for the sh
15760 // utility; otherwise, the termination status is unspecified.
15761
15762 switch( esito ) {
15763
15764 // If some error prevents the command language interpreter
15765 // from executing after the child process is created, the
15766 // return value from system() shall be as if the command
15767 // language interpreter had terminated using exit(127)
15768 // or _exit(127).
15769 case 127:
15770 printf( "##### It is like some error prevents the command language interpreter \n" );
15771 printf( "##### from executing after the child process is created.\n" );
15772 break;
15773
15774 // If a child process cannot be created, or if the termination
15775 // status for the command language interpreter cannot be obtained,
15776 // system() shall return -1 and set errno to indicate the error.
15777 case -1:
15778 printf( "##### It is like the child process cannot be created, or if the\n" );
15779 printf( "##### termination status for the command language interpreter\n" );
15780 printf( "##### cannot be obtained (errno = %d).\n\n", errno );
15781 perror( "##### Error from execution:");
15782 break;
15783
15784 case 0:
15785 break;
15786
15787 default:
15788 printf( "##### It is like some error occurrend in execution.\n\n" );
15789 break;
15790 }
15791
15792 #endif
15793
15794#endif
15795
15796 exit(0);
15797
15798}
15799
15800int system_move_safe( Environment * _environment, char * _source, char * _destination ) {
15801
15802 TRACE2( "system_move_safe( ..., %s, %s)", _source, _destination );
15803
15804 if ( strcmp( _source, _destination ) != 0 ) {
15805
15806 FILE * fi = fopen( _source, "rb" );
15807 if ( ! fi ) {
15808 return 0;
15809 }
15810 FILE * fo = fopen( _destination, "wb" );
15811 if ( ! fo ) {
15812 CRITICAL_CANNOT_OPEN_FILE( _destination, strerror(errno) );
15813 }
15814
15815 fseek( fi, 0, SEEK_END );
15816 long size = ftell( fi );
15817 fseek( fi, 0, SEEK_SET );
15818
15819 if ( size ) {
15820 char * content = malloc( size );
15821 memset( content, 0, size );
15822 if ( ! fread( content, 1, size, fi ) ) {
15823 CRITICAL_CANNOT_READ_FILE( _source, strerror(errno) );
15824 };
15825 if ( ! fwrite(content, 1, size, fo ) ) {
15826 CRITICAL_CANNOT_WRITE_FILE( _destination, strerror(errno) );
15827 }
15828 }
15829
15830 fclose( fi );
15831 fclose( fo );
15832
15833 system_remove_safe( _environment, _source );
15834
15835 } else {
15836 return 1;
15837 }
15838
15839}
15840
15841int procedure_exists( Environment * _environment, char * _name ) {
15842
15843 Procedure * current = _environment->procedures;
15844
15845 while( current ) {
15846 current = current->next;
15847 if ( strcmp( _name, current->name ) ) {
15848 return 1;
15849 }
15850 }
15851
15852 return 0;
15853
15854}
15855
15856// Function to implement `strstr()` function
15857const char* strstrcase( const char* _x, const char* _y ) {
15858 int equal = 0;
15859 while (*_x != '\0' && !equal) {
15860 if ((*_x == *_y) ) {
15861
15862 int done = 0;
15863 const char *cX = _x, *cY = _y;
15864
15865 while (*cX && *cY && !done) {
15866 if (tolower(*cX) != tolower(*cY)) {
15867 done = 1;
15868 } else {
15869 cX++;
15870 cY++;
15871 }
15872 }
15873
15874 equal = (*cY == '\0');
15875 }
15876 _x++;
15877 }
15878
15879 return (*_x == '\0') ? NULL : _x;
15880}
15881
15882const char *strrstr(const char *haystack, const char *needle)
15883{
15884 if (*needle == '\0')
15885 return (char *) haystack;
15886
15887 char *result = NULL;
15888 for (;;) {
15889 char *p = strstr(haystack, needle);
15890 if (p == NULL)
15891 break;
15892 result = p;
15893 haystack = p + 1;
15894 }
15895
15896 return result;
15897}
15898
15899void define_implicit_array_if_needed( Environment * _environment, char * _name ) {
15900 if ( !variable_exists( _environment, _name ) ) {
15901 if ( _environment->optionExplicit ) {
15903 }
15904 memset( ((struct _Environment *)_environment)->arrayDimensionsEach, 0, sizeof( int ) * MAX_ARRAY_DIMENSIONS );
15905 ((struct _Environment *)_environment)->arrayDimensions = 1;
15906 ((struct _Environment *)_environment)->arrayDimensionsEach[0] = ((struct _Environment *)_environment)->defaultArraySize;
15907 ((struct _Environment *)_environment)->currentArray = variable_define( _environment, _name, VT_TARRAY, 0 );
15908 variable_array_type( _environment, _name, ((struct _Environment *)_environment)->defaultVariableType );
15909 }
15910}
15911
15912int check_datatype_limits( VariableType _type, int _value ) {
15913
15914 if ( VT_SIGNED( _type ) ) {
15915 switch( VT_BITWIDTH( _type ) ) {
15916 case 8:
15917 return abs(_value) <= 0x7f;
15918 case 16:
15919 return abs(_value) <= 0x7fff;
15920 case 32:
15921 return abs(_value) <= 0x7fffffff;
15922 default:
15923 return 0;
15924 }
15925 } else {
15926 switch( VT_BITWIDTH( _type ) ) {
15927 case 8:
15928 return _value <= 0xff;
15929 case 16:
15930 return _value <= 0xffff;
15931 case 32:
15932 return _value <= 0xffffffff;
15933 default:
15934 return 0;
15935 }
15936 }
15937
15938}
15939
15940char * file_read_csv( Environment * _environment, char * _filename, VariableType _type, int * _size, int * _count ) {
15941
15942 FILE * handle = fopen( _filename, "rt" );
15943 if ( ! handle ) {
15944 CRITICAL_FILE_NOT_FOUND( _filename );
15945 }
15946
15947 Constant * constants = NULL;
15948 Constant * current = NULL;
15949
15950 while( !feof( handle ) ) {
15951
15952 char valueString[MAX_TEMPORARY_STORAGE];
15953 memset( valueString, 0, MAX_TEMPORARY_STORAGE );
15954 int p=0, j=0, cmt=0;
15955
15956 while( !feof( handle ) ) {
15957 char c = fgetc(handle);
15958 if ( cmt ) {
15959 if ( c == 13 || c == 10 ) {
15960 cmt = 0;
15961 }
15962 continue;
15963 }
15964 if ( j == 0 ) {
15965 if ( c == '\'' && !cmt ) {
15966 cmt = 1;
15967 continue;
15968 }
15969 if ( (c < '0') || (c > '9') ) {
15970 continue;
15971 }
15972 j = 1;
15973 } else {
15974 if ( (c < '0') || (c > '9') ) {
15975 break;
15976 }
15977 }
15978 valueString[p] = c;
15979 ++p;
15980 }
15981
15982 if ( ! cmt && p ) {
15983 if ( ! current ) {
15984 current = malloc( sizeof( Constant ) );
15985 memset( current, 0, sizeof( Constant ) );
15986 constants = current;
15987 } else {
15988 current->next = malloc( sizeof( Constant ) );
15989 memset( current->next, 0, sizeof( Constant ) );
15990 current = current->next;
15991 }
15992 current->value = atoi( valueString );
15993 }
15994
15995 }
15996
15997 fclose( handle );
15998
15999 if ( _type == VT_TYPE ) {
16000
16001 int os = VT_OPTIMAL_SHIFT( _environment->currentType->size );
16002 int bytes = 1 << os;
16003
16004 Constant * current = constants;
16005
16006 *_count = 0;
16007 *_size = 0;
16008 while( current ) {
16009 Field * currentField = _environment->currentType->first;
16010 while( currentField && current ) {
16012 current = current->next;
16013 }
16014 *_size += bytes;
16015 ++*_count;
16016 if ( !current ) {
16017 if ( currentField ) {
16019 }
16020 break;
16021 }
16022 }
16023
16024 char * buffer = malloc( *_size );
16025 char * ptr = buffer;
16026 char * lastPtr = buffer;
16027 int i=0;
16028 Field * currentField = _environment->currentType->first;
16029 current = constants;
16030 while( current ) {
16031
16032 while(current&&currentField) {
16033 switch( VT_BITWIDTH(currentField->type) ) {
16034 case 8:
16035 *ptr = (current->value) & 0xff;
16036 ++ptr;
16037 break;
16038 case 16:
16039 #ifdef CPU_BIG_ENDIAN
16040 *ptr = ( current->value >> 8 ) & 0xff;
16041 *(ptr+1) = ( current->value ) & 0xff;
16042 #else
16043 *(ptr+1) = ( current->value >> 8 ) & 0xff;
16044 *ptr = ( current->value ) & 0xff;
16045 #endif
16046 ptr += 2;
16047 break;
16048 case 32:
16049 #ifdef CPU_BIG_ENDIAN
16050 *ptr = ( current->value >> 24 ) & 0xff;
16051 *(ptr+1) = ( current->value >> 16 ) & 0xff;
16052 *(ptr+2) = ( current->value >> 8 ) & 0xff;
16053 *(ptr+3) = ( current->value ) & 0xff;
16054 #else
16055 *(ptr+3) = ( current->value >> 24 ) & 0xff;
16056 *(ptr+2) = ( current->value >> 16 ) & 0xff;
16057 *(ptr+1) = ( current->value >> 8 ) & 0xff;
16058 *ptr = ( current->value ) & 0xff;
16059 #endif
16060 ptr += 4;
16061 break;
16062 }
16064 current = current->next;
16065 }
16066 lastPtr += bytes;
16067 ptr = lastPtr;
16068 currentField = _environment->currentType->first;
16069 }
16070
16071 return buffer;
16072
16073 } else {
16074
16075 *_size = 0;
16076 *_count = 0;
16077 Constant * first = constants;
16078 while( first ) {
16079 if ( first ) {
16080 *_size += VT_BITWIDTH(_type) >> 3;
16081 ++*_count;
16082 }
16083 first = first->next;
16084 }
16085
16086 char * buffer = malloc( *_size ), * ptr = buffer;
16087 int i=0;
16088 current = constants;
16089 while(current) {
16090 switch( VT_BITWIDTH(_type) ) {
16091 case 8:
16092 *ptr = (current->value) & 0xff;
16093 ++ptr;
16094 break;
16095 case 16:
16096 #ifdef CPU_BIG_ENDIAN
16097 *ptr = ( current->value >> 8 ) & 0xff;
16098 *(ptr+1) = ( current->value ) & 0xff;
16099 #else
16100 *(ptr+1) = ( current->value >> 8 ) & 0xff;
16101 *ptr = ( current->value ) & 0xff;
16102 #endif
16103 ptr += 2;
16104 break;
16105 case 32:
16106 #ifdef CPU_BIG_ENDIAN
16107 *ptr = ( current->value >> 24 ) & 0xff;
16108 *(ptr+1) = ( current->value >> 16 ) & 0xff;
16109 *(ptr+2) = ( current->value >> 8 ) & 0xff;
16110 *(ptr+3) = ( current->value ) & 0xff;
16111 #else
16112 *(ptr+3) = ( current->value >> 24 ) & 0xff;
16113 *(ptr+2) = ( current->value >> 16 ) & 0xff;
16114 *(ptr+1) = ( current->value >> 8 ) & 0xff;
16115 *ptr = ( current->value ) & 0xff;
16116 #endif
16117 ptr += 4;
16118 break;
16119 }
16120 current = current->next;
16121 }
16122
16123 return buffer;
16124
16125 }
16126
16127}
16128
16129Type * type_find( Type * _first, char * _name ) {
16130
16131 Type * current = _first;
16132
16133 while( current ) {
16134 if ( strcmp( current->name, _name ) == 0 ) {
16135 return current;
16136 }
16137 current = current->next;
16138 }
16139
16140 return NULL;
16141
16142}
16143
16144Field * field_find( Type * _type, char * _name ) {
16145
16146 Field * current = _type->first;
16147
16148 while( current ) {
16149 if ( strcmp( current->name, _name ) == 0 ) {
16150 return current;
16151 }
16152 current = current->next;
16153 }
16154
16155 return NULL;
16156
16157}
16158
16159void variable_set_type( Environment * _environment, char *_name, char * _type ) {
16160
16161 Variable * var = variable_retrieve( _environment, _name );
16162 if ( ! var ) {
16163 CRITICAL_VARIABLE( _name );
16164 }
16165 if ( var->type != VT_TYPE && var->type != VT_TARRAY ) {
16167 }
16168 Type * type = type_find( _environment->types, _type );
16169 if ( ! type ) {
16170 CRITICAL_UNKNOWN_TYPE( _type );
16171 }
16172 var->typeType = type;
16173 var->size = type->size;
16174
16175}
16176
16177Variable * variable_move_from_type( Environment * _environment, char * _type, char * _field ) {
16178
16179 Variable * typeVar = variable_retrieve( _environment, _type );
16180 if ( typeVar->type != VT_TYPE ) {
16182 }
16183 Field * field = field_find( typeVar->typeType, _field );
16184 if ( ! field ) {
16186 }
16187
16188 Variable * result = variable_temporary( _environment, field->type, "(element from array)" );
16189
16190 variable_move_from_type_inplace( _environment, _type, _field, result->name );
16191
16192 return result;
16193
16194}
16195
16196void variable_move_from_type_inplace( Environment * _environment, char * _type, char * _field, char * _value ) {
16197
16198 Variable * typeVar = variable_retrieve( _environment, _type );
16199 if ( typeVar->type != VT_TYPE ) {
16201 }
16202 Field * field = field_find( typeVar->typeType, _field );
16203 if ( ! field ) {
16205 }
16206
16207 Variable * result = variable_retrieve_or_define( _environment, _value, field->type, 0 );
16208
16209 char offsetAsString[MAX_TEMPORARY_STORAGE];
16210 sprintf( offsetAsString, "%d", field->offset );
16211 switch( VT_BITWIDTH( field->type ) ) {
16212 case 32:
16213 cpu_move_32bit( _environment, address_displacement( _environment, typeVar->realName, offsetAsString ), result->realName );
16214 break;
16215 case 16:
16216 cpu_move_16bit( _environment, address_displacement( _environment, typeVar->realName, offsetAsString ), result->realName );
16217 break;
16218 case 8:
16219 cpu_move_8bit( _environment, address_displacement( _environment, typeVar->realName, offsetAsString ), result->realName );
16220 break;
16221 case 1:
16222 case 0:
16223 switch( field->type ) {
16224 case VT_SPRITE:
16225 cpu_move_8bit( _environment, address_displacement( _environment, typeVar->realName, offsetAsString ), result->realName );
16226 break;
16227 case VT_MSPRITE:
16228 cpu_move_16bit( _environment, address_displacement( _environment, typeVar->realName, offsetAsString ), result->realName );
16229 break;
16230 case VT_DSTRING: {
16231 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(string)" );
16232 cpu_move_8bit( _environment, address_displacement( _environment, typeVar->realName, offsetAsString ), dstring->realName );
16233 cpu_dsassign( _environment, dstring->realName, result->realName );
16234 break;
16235 }
16236 default:
16238 }
16239 }
16240
16241}
16242
16243void variable_move_type( Environment * _environment, char * _type, char * _field, char * _value ) {
16244
16245 Variable * typeVar = variable_retrieve( _environment, _type );
16246 if ( typeVar->type != VT_TYPE ) {
16248 }
16249 Field * field = field_find( typeVar->typeType, _field );
16250 if ( ! field ) {
16252 }
16253
16254 Variable * value = variable_cast( _environment, _value, field->type );
16255
16256 char offsetAsString[MAX_TEMPORARY_STORAGE];
16257 sprintf( offsetAsString, "%d", field->offset );
16258 switch( VT_BITWIDTH( field->type ) ) {
16259 case 32:
16260 cpu_move_32bit( _environment, value->realName, address_displacement( _environment, typeVar->realName, offsetAsString ) );
16261 break;
16262 case 16:
16263 cpu_move_16bit( _environment, value->realName, address_displacement( _environment, typeVar->realName, offsetAsString ) );
16264 break;
16265 case 8:
16266 cpu_move_8bit( _environment, value->realName, address_displacement( _environment, typeVar->realName, offsetAsString ) );
16267 break;
16268 case 1:
16269 case 0: {
16270 switch( field->type ) {
16271 case VT_DSTRING:
16272 cpu_dsassign( _environment, value->realName, address_displacement( _environment, typeVar->realName, offsetAsString ) );
16273 break;
16274 case VT_SPRITE:
16275 cpu_move_8bit( _environment, value->realName, address_displacement( _environment, typeVar->realName, offsetAsString ) );
16276 break;
16277 case VT_MSPRITE:
16278 cpu_move_16bit( _environment, value->realName, address_displacement( _environment, typeVar->realName, offsetAsString ) );
16279 break;
16280 default:
16282 }
16283 }
16284 }
16285
16286}
16287
16288void variable_move_array_type( Environment * _environment, char * _array, char * _field, char * _value ) {
16289
16290 MAKE_LABEL;
16291
16292 Variable * array = variable_retrieve( _environment, _array );
16293
16294 if ( array->type != VT_TARRAY ) {
16295 CRITICAL_NOT_ARRAY( _array );
16296 }
16297 if ( array->arrayType != VT_TYPE ) {
16299 }
16300 if ( !array->typeType ) {
16302 }
16303 Field * field = field_find( array->typeType, _field );
16304 if ( ! field ) {
16306 }
16307
16308 Variable * value = variable_cast( _environment, _value, field->type );
16309
16310 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
16311 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
16312 }
16313
16314 Variable * offset = calculate_offset_in_array( _environment, array->name );
16315
16316 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT(array->typeType->size) );
16317
16318 variable_add_inplace( _environment, offset->name, field->offset );
16319
16320 if ( array->bankAssigned == -1 ) {
16321
16322 cpu_math_add_16bit_with_16bit( _environment, offset->realName, array->realName, offset->realName );
16323
16324 switch( VT_BITWIDTH( field->type ) ) {
16325 case 32:
16326 cpu_move_32bit_indirect( _environment, value->realName, offset->realName );
16327 break;
16328 case 16:
16329 cpu_move_16bit_indirect( _environment, value->realName, offset->realName );
16330 break;
16331 case 8:
16332 cpu_move_8bit_indirect( _environment, value->realName, offset->realName );
16333 break;
16334 case 1:
16335 case 0:
16336 switch( field->type ) {
16337 case VT_DSTRING: {
16338 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(type element)");
16339 cpu_move_8bit_indirect2( _environment, offset->realName, dstring->realName );
16340 cpu_dsassign( _environment, value->realName, dstring->realName );
16341 cpu_move_8bit_indirect( _environment, value->realName, offset->realName );
16342 break;
16343 };
16344 case VT_MSPRITE:
16345 cpu_move_16bit_indirect( _environment, value->realName, offset->realName );
16346 break;
16347 case VT_SPRITE:
16348 cpu_move_8bit_indirect( _environment, value->realName, offset->realName );
16349 break;
16350 default:
16352 }
16353 }
16354
16355 } else {
16356
16357 switch( VT_BITWIDTH( field->type ) ) {
16358 case 32:
16359 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16360 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 4 );
16361 break;
16362 case 16:
16363 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16364 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 2 );
16365 break;
16366 case 8:
16367 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16368 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 1 );
16369 break;
16370 case 1:
16371 case 0:
16372 switch( field->type ) {
16373 case VT_DSTRING: {
16374 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(array element)");
16375 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16376 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, value->name, 1 );
16377
16378 if ( value->type == VT_STRING ) {
16379 cpu_dsassign_string( _environment, value->realName, dstring->realName );
16380 } else if ( value->type == VT_DSTRING ) {
16381 cpu_dsassign( _environment, value->realName, dstring->realName );
16382 } else {
16384 }
16385
16386 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 1 );
16387 break;
16388 };
16389 case VT_MSPRITE:
16390 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16391 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 2 );
16392 break;
16393 case VT_SPRITE:
16394 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16395 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 1 );
16396 break;
16397 default:
16399 }
16400 }
16401
16402 }
16403
16404}
16405
16406Variable * variable_move_from_array_type( Environment * _environment, char * _array, char * _field ) {
16407
16409
16410 Variable * array = variable_retrieve( _environment, _array );
16411
16412 if ( array->type != VT_TARRAY ) {
16413 CRITICAL_NOT_ARRAY( _array );
16414 }
16415 if ( array->arrayType != VT_TYPE ) {
16417 }
16418 if ( !array->typeType ) {
16420 }
16421 Field * field = field_find( array->typeType, _field );
16422 if ( ! field ) {
16424 }
16425
16426 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
16427 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
16428 }
16429
16430 Variable * result = variable_temporary( _environment, field->type, "(element from array)" );
16431
16432 variable_move_from_array_type_inplace( _environment, _array, _field, result->name );
16433
16434 return result;
16435
16436}
16437
16438void variable_move_from_array_type_inplace( Environment * _environment, char * _array, char * _field, char * _value ) {
16439
16441
16442 Variable * array = variable_retrieve( _environment, _array );
16443
16444 if ( array->type != VT_TARRAY ) {
16445 CRITICAL_NOT_ARRAY( _array );
16446 }
16447 if ( array->arrayType != VT_TYPE ) {
16449 }
16450 if ( !array->typeType ) {
16452 }
16453 Field * field = field_find( array->typeType, _field );
16454 if ( ! field ) {
16456 }
16457
16458 if ( array->arrayDimensions != _environment->arrayIndexes[_environment->arrayNestedIndex] ) {
16459 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, _environment->arrayIndexes[_environment->arrayNestedIndex] );
16460 }
16461
16462 Variable * result = variable_retrieve_or_define( _environment, _value, field->type, 0 );
16463
16464 Variable * offset = calculate_offset_in_array( _environment, array->name);
16465
16466 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT(array->typeType->size) );
16467
16468 variable_add_inplace( _environment, offset->name, field->offset );
16469
16470 if ( array->bankAssigned == -1 ) {
16471
16472 cpu_math_add_16bit_with_16bit( _environment, offset->realName, array->realName, offset->realName );
16473
16474 switch( VT_BITWIDTH( field->type ) ) {
16475 case 32:
16476 cpu_move_32bit_indirect2( _environment, offset->realName, result->realName );
16477 break;
16478 case 16:
16479 cpu_move_16bit_indirect2( _environment, offset->realName, result->realName);
16480 break;
16481 case 8:
16482 cpu_move_8bit_indirect2( _environment, offset->realName, result->realName );
16483 break;
16484 case 1:
16485 case 0:
16486 switch( field->type ) {
16487 case VT_DSTRING: {
16488 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(string)" );
16489 cpu_move_8bit_indirect2( _environment, offset->realName, dstring->realName );
16490 cpu_dsassign( _environment, dstring->realName, result->realName );
16491 break;
16492 }
16493 case VT_MSPRITE:
16494 cpu_move_16bit_indirect2( _environment, offset->realName, result->realName);
16495 break;
16496 case VT_SPRITE:
16497 cpu_move_8bit_indirect2( _environment, offset->realName, result->realName );
16498 break;
16499 default:
16500 CRITICAL_DATATYPE_UNSUPPORTED("array(4b)", DATATYPE_AS_STRING[array->arrayType]);
16501 }
16502 }
16503
16504 } else {
16505
16506 switch( VT_BITWIDTH( field->type ) ) {
16507 case 32:
16508 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16509 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 4 );
16510 break;
16511 case 16:
16512 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16513 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 2 );
16514 break;
16515 case 8:
16516 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16517 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 1 );
16518 break;
16519 case 1:
16520 case 0:
16521 switch( field->type ) {
16522 case VT_DSTRING: {
16523 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(string)" );
16524 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16525 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, dstring->name, 1 );
16526 cpu_dsassign( _environment, dstring->realName, result->realName );
16527 break;
16528 }
16529 case VT_MSPRITE:
16530 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16531 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 2 );
16532 break;
16533 case VT_SPRITE:
16534 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16535 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 1 );
16536 break;
16537 default:
16538 CRITICAL_DATATYPE_UNSUPPORTED("array(4b)", DATATYPE_AS_STRING[array->arrayType]);
16539 }
16540 }
16541
16542 }
16543
16544}
16545
16546void variable_move_from_array1_type_inplace( Environment * _environment, char * _array, char * _index, char * _field, char * _value ) {
16547
16549
16550 Variable * array = variable_retrieve( _environment, _array );
16551
16552 if ( array->type != VT_TARRAY ) {
16553 CRITICAL_NOT_ARRAY( _array );
16554 }
16555 if ( array->arrayType != VT_TYPE ) {
16557 }
16558 if ( !array->typeType ) {
16560 }
16561 Field * field = field_find( array->typeType, _field );
16562 if ( ! field ) {
16564 }
16565
16566 if ( array->arrayDimensions != 1 ) {
16567 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, 1 );
16568 }
16569
16570 Variable * index = variable_retrieve( _environment, _index );
16571
16572 Variable * result = variable_retrieve_or_define( _environment, _value, field->type, 0 );
16573
16574 Variable * offset = variable_temporary( _environment, VT_ADDRESS, "(address)");
16575 variable_move( _environment, index->name, offset->name );
16576 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT(array->typeType->size) );
16577 variable_add_inplace( _environment, offset->name, field->offset );
16578
16579 if ( array->bankAssigned == -1 ) {
16580
16581 cpu_math_add_16bit_with_16bit( _environment, offset->realName, array->realName, offset->realName );
16582
16583 switch( VT_BITWIDTH( field->type ) ) {
16584 case 32:
16585 cpu_move_32bit_indirect2( _environment, offset->realName, result->realName );
16586 break;
16587 case 16:
16588 cpu_move_16bit_indirect2( _environment, offset->realName, result->realName);
16589 break;
16590 case 8:
16591 cpu_move_8bit_indirect2( _environment, offset->realName, result->realName );
16592 break;
16593 case 1:
16594 case 0:
16595 switch( field->type ) {
16596 case VT_DSTRING: {
16597 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(string)" );
16598 cpu_move_16bit_indirect2( _environment, offset->realName, dstring->realName);
16599 cpu_dsassign( _environment, dstring->realName, result->realName );
16600 break;
16601 }
16602 case VT_MSPRITE:
16603 cpu_move_16bit_indirect2( _environment, offset->realName, result->realName);
16604 break;
16605 case VT_SPRITE:
16606 cpu_move_8bit_indirect2( _environment, offset->realName, result->realName );
16607 break;
16608 default:
16609 CRITICAL_DATATYPE_UNSUPPORTED("array(4b)", DATATYPE_AS_STRING[array->arrayType]);
16610 }
16611 }
16612
16613 } else {
16614
16615 switch( VT_BITWIDTH( field->type ) ) {
16616 case 32:
16617 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16618 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 4 );
16619 break;
16620 case 16:
16621 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16622 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 2 );
16623 break;
16624 case 8:
16625 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16626 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 1 );
16627 break;
16628 case 1:
16629 case 0:
16630 switch( field->type ) {
16631 case VT_DSTRING: {
16632 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(string)" );
16633 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16634 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, dstring->name, 1 );
16635 cpu_dsassign( _environment, dstring->realName, result->realName );
16636 break;
16637 }
16638 case VT_MSPRITE:
16639 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16640 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 2 );
16641 break;
16642 case VT_SPRITE:
16643 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16644 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset->name, result->name, 1 );
16645 break;
16646 default:
16647 CRITICAL_DATATYPE_UNSUPPORTED("array(4b)", DATATYPE_AS_STRING[array->arrayType]);
16648 }
16649 }
16650
16651 }
16652
16653}
16654
16655Variable * variable_move_from_array1_type( Environment * _environment, char * _array, char * _index, char * _field ) {
16656
16658
16659 Variable * array = variable_retrieve( _environment, _array );
16660
16661 if ( array->type != VT_TARRAY ) {
16662 CRITICAL_NOT_ARRAY( _array );
16663 }
16664 if ( array->arrayType != VT_TYPE ) {
16666 }
16667 if ( !array->typeType ) {
16669 }
16670 Field * field = field_find( array->typeType, _field );
16671 if ( ! field ) {
16673 }
16674
16675 if ( array->arrayDimensions != 1 ) {
16676 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, 1 );
16677 }
16678
16679 Variable * result = variable_temporary( _environment, field->type, "(element from array)" );
16680
16681 variable_move_from_array1_type_inplace( _environment, _array, _index, _field, result->name );
16682
16683 return result;
16684
16685}
16686
16687void variable_move_array1_type( Environment * _environment, char * _array, char * _index, char * _field, char * _value ) {
16688
16689 MAKE_LABEL;
16690
16691 Variable * array = variable_retrieve( _environment, _array );
16692
16693 if ( array->type != VT_TARRAY ) {
16694 CRITICAL_NOT_ARRAY( _array );
16695 }
16696 if ( array->arrayType != VT_TYPE ) {
16698 }
16699 if ( !array->typeType ) {
16701 }
16702 Field * field = field_find( array->typeType, _field );
16703 if ( ! field ) {
16705 }
16706
16707 Variable * index = variable_retrieve( _environment, _index );
16708
16709 Variable * value = variable_cast( _environment, _value, field->type );
16710
16711 if ( array->arrayDimensions != 1 ) {
16712 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, 1 );
16713 }
16714
16715 Variable * offset = variable_temporary( _environment, VT_ADDRESS, "(address)");
16716 variable_move( _environment, index->name, offset->name );
16717 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT(array->typeType->size) );
16718 variable_add_inplace( _environment, offset->name, field->offset );
16719
16720 if ( array->bankAssigned == -1 ) {
16721
16722 cpu_math_add_16bit_with_16bit( _environment, offset->realName, array->realName, offset->realName );
16723
16724 switch( VT_BITWIDTH( field->type ) ) {
16725 case 32:
16726 cpu_move_32bit_indirect( _environment, value->realName, offset->realName );
16727 break;
16728 case 16:
16729 cpu_move_16bit_indirect( _environment, value->realName, offset->realName );
16730 break;
16731 case 8:
16732 cpu_move_8bit_indirect( _environment, value->realName, offset->realName );
16733 break;
16734 case 1:
16735 case 0:
16736 switch( field->type ) {
16737 case VT_DSTRING: {
16738 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(string)");
16739 cpu_dsassign( _environment, value->realName, dstring->realName );
16740 cpu_move_8bit_indirect( _environment, dstring->realName, offset->realName );
16741 break;
16742 }
16743 case VT_MSPRITE:
16744 cpu_move_16bit_indirect( _environment, value->realName, offset->realName );
16745 break;
16746 case VT_SPRITE:
16747 cpu_move_8bit_indirect( _environment, value->realName, offset->realName );
16748 break;
16749 default:
16751 }
16752 }
16753
16754 } else {
16755
16756 switch( VT_BITWIDTH( field->type ) ) {
16757 case 32:
16758 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16759 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 4 );
16760 break;
16761 case 16:
16762 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16763 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 2 );
16764 break;
16765 case 8:
16766 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16767 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 1 );
16768 break;
16769 case 1:
16770 case 0:
16771 switch( field->type ) {
16772 case VT_DSTRING: {
16773 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(string)");
16774 cpu_dsassign( _environment, value->realName, dstring->realName );
16775 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16776 bank_write_vars_bank_direct_size( _environment, dstring->name, array->bankAssigned, offset->name, 1 );
16777 break;
16778 }
16779 case VT_MSPRITE:
16780 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16781 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 2 );
16782 break;
16783 case VT_SPRITE:
16784 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16785 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset->name, 1 );
16786 break;
16787 default:
16789 }
16790 }
16791
16792 }
16793
16794}
16795
16796void variable_move_array1_type_fields( Environment * _environment, char * _array, char * _index, char * _field1, char * _field2 ) {
16797
16798 MAKE_LABEL;
16799
16800 Variable * array = variable_retrieve( _environment, _array );
16801
16802 if ( array->type != VT_TARRAY ) {
16803 CRITICAL_NOT_ARRAY( _array );
16804 }
16805 if ( array->arrayType != VT_TYPE ) {
16807 }
16808 if ( !array->typeType ) {
16810 }
16811 Field * field1 = field_find( array->typeType, _field1 );
16812 if ( ! field1 ) {
16814 }
16815 Field * field2 = field_find( array->typeType, _field2 );
16816 if ( ! field2 ) {
16818 }
16819 if ( field1->type != field2->type ) {
16820 CRITICAL_DATATYPE_MISMATCH( _field1, _field2 );
16821 }
16822
16823 Variable * index = variable_retrieve( _environment, _index );
16824
16825 Variable * value = variable_temporary( _environment, field1->type, "(tmp)" );
16826
16827 if ( array->arrayDimensions != 1 ) {
16828 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, 1 );
16829 }
16830
16831 if ( array->bankAssigned == -1 ) {
16832
16833 Variable * offset2 = variable_temporary( _environment, VT_ADDRESS, "(address)");
16834 variable_move( _environment, index->name, offset2->name );
16835 offset2 = variable_sl_const( _environment, offset2->name, VT_OPTIMAL_SHIFT(array->typeType->size) );
16836 cpu_math_add_16bit_with_16bit( _environment, offset2->realName, array->realName, offset2->realName );
16837 Variable * offset1 = variable_add_const( _environment, offset2->name, field1->offset );
16838 variable_add_inplace( _environment, offset2->name, field2->offset );
16839
16840 switch( VT_BITWIDTH( field1->type ) ) {
16841 case 32:
16842 cpu_move_32bit_indirect2( _environment, offset1->realName, value->realName );
16843 cpu_move_32bit_indirect( _environment, value->realName, offset2->realName );
16844 break;
16845 case 16:
16846 cpu_move_16bit_indirect2( _environment, offset1->realName, value->realName );
16847 cpu_move_16bit_indirect( _environment, value->realName, offset2->realName );
16848 break;
16849 case 8:
16850 cpu_move_8bit_indirect2( _environment, offset1->realName, value->realName );
16851 cpu_move_8bit_indirect( _environment, value->realName, offset2->realName );
16852 break;
16853 case 1:
16854 case 0:
16855 switch( field1->type ) {
16856 case VT_MSPRITE:
16857 cpu_move_16bit_indirect2( _environment, offset1->realName, value->realName );
16858 cpu_move_16bit_indirect( _environment, value->realName, offset2->realName );
16859 break;
16860 case VT_SPRITE:
16861 cpu_move_8bit_indirect2( _environment, offset1->realName, value->realName );
16862 cpu_move_8bit_indirect( _environment, value->realName, offset2->realName );
16863 break;
16864 default:
16866 }
16867 }
16868
16869 } else {
16870
16871 Variable * offset1 = variable_temporary( _environment, VT_ADDRESS, "(address)");
16872 Variable * offset2 = variable_temporary( _environment, VT_ADDRESS, "(address)");
16873 variable_move( _environment, index->name, offset2->name );
16874 offset2 = variable_sl_const( _environment, offset2->name, VT_OPTIMAL_SHIFT(array->typeType->size) );
16875 variable_move( _environment, offset2->name, offset1->name );
16876 cpu_math_add_16bit_const( _environment, offset1->realName, array->absoluteAddress, offset1->realName );
16877 cpu_math_add_16bit_const( _environment, offset1->realName, field1->offset, offset1->realName );
16878 cpu_math_add_16bit_const( _environment, offset2->realName, array->absoluteAddress, offset2->realName );
16879 cpu_math_add_16bit_const( _environment, offset2->realName, field2->offset, offset2->realName );
16880
16881 switch( VT_BITWIDTH( field1->type ) ) {
16882 case 32:
16883 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset1->name, value->name, 4 );
16884 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset2->name, 4 );
16885 break;
16886 case 16:
16887 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset1->name, value->name, 2 );
16888 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset2->name, 2 );
16889 break;
16890 case 8:
16891 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset1->name, value->name, 1 );
16892 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset2->name, 1 );
16893 break;
16894 case 1:
16895 case 0:
16896 switch( field1->type ) {
16897 case VT_MSPRITE:
16898 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset1->name, value->name, 2 );
16899 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset2->name, 2 );
16900 break;
16901 case VT_SPRITE:
16902 bank_read_vars_bank_direct_size( _environment, array->bankAssigned, offset1->name, value->name, 1 );
16903 bank_write_vars_bank_direct_size( _environment, value->name, array->bankAssigned, offset2->name, 1 );
16904 break;
16905 default:
16907 }
16908 }
16909
16910 }
16911
16912}
16913
16914void variable_move_array1_type_const( Environment * _environment, char * _array, char * _index, char * _field, int _value ) {
16915
16916 MAKE_LABEL;
16917
16918 Variable * array = variable_retrieve( _environment, _array );
16919
16920 if ( array->type != VT_TARRAY ) {
16921 CRITICAL_NOT_ARRAY( _array );
16922 }
16923 if ( array->arrayType != VT_TYPE ) {
16925 }
16926 if ( !array->typeType ) {
16928 }
16929 Field * field = field_find( array->typeType, _field );
16930 if ( ! field ) {
16932 }
16933
16934 Variable * index = variable_retrieve( _environment, _index );
16935
16936 if ( array->arrayDimensions != 1 ) {
16937 CRITICAL_ARRAY_SIZE_MISMATCH( _array, array->arrayDimensions, 1 );
16938 }
16939
16940 Variable * offset = variable_temporary( _environment, VT_ADDRESS, "(address)");
16941 variable_move( _environment, index->name, offset->name );
16942 offset = variable_sl_const( _environment, offset->name, VT_OPTIMAL_SHIFT(array->typeType->size) );
16943 variable_add_inplace( _environment, offset->name, field->offset );
16944
16945 if ( array->bankAssigned == -1 ) {
16946
16947 cpu_math_add_16bit_with_16bit( _environment, offset->realName, array->realName, offset->realName );
16948
16949 switch( VT_BITWIDTH( field->type ) ) {
16950 case 32:
16951 cpu_poked_const( _environment, offset->realName, _value );
16952 break;
16953 case 16:
16954 cpu_pokew_const( _environment, offset->realName, _value );
16955 break;
16956 case 8:
16957 cpu_poke_const( _environment, offset->realName, _value );
16958 break;
16959 case 1:
16960 case 0:
16962 }
16963
16964 } else {
16965
16966 cpu_math_add_16bit_const( _environment, offset->realName, array->absoluteAddress, offset->realName );
16967 switch( VT_BITWIDTH( field->type ) ) {
16968 case 32:
16969 cpu_store_32bit( _environment, array->realName, _value );
16970 bank_write_vars_bank_direct_size( _environment, array->name, array->bankAssigned, offset->name, 4 );
16971 break;
16972 case 16:
16973 cpu_store_16bit( _environment, array->realName, _value );
16974 bank_write_vars_bank_direct_size( _environment, array->name, array->bankAssigned, offset->name, 2 );
16975 break;
16976 case 8:
16977 cpu_store_8bit( _environment, array->realName, _value );
16978 bank_write_vars_bank_direct_size( _environment, array->name, array->bankAssigned, offset->name, 1 );
16979 break;
16980 case 1:
16981 case 0:
16983 }
16984
16985 }
16986
16987}
16988
16989static void variable_increment_decrement_array_type( Environment * _environment, char * _source, char * _field, int _direction ) {
16990
16991 if ( _environment->emptyProcedure ) {
16992 return;
16993 }
16994
16995 Variable * source = variable_retrieve( _environment, _source );
16996
16997 if ( source->type != VT_TARRAY ) {
16998 CRITICAL_NOT_ARRAY( _source );
16999 }
17000 if ( source->arrayType != VT_TYPE ) {
17002 }
17003 if ( !source->typeType ) {
17005 }
17006 Field * field = field_find( source->typeType, _field );
17007 if ( ! field ) {
17009 }
17010
17011 Variable * offset = variable_move_from_array_get_address( _environment, _source, _field );
17012
17013 Variable * value = NULL;
17014
17015 if ( source->bankAssigned == -1 ) {
17016
17017 value = variable_temporary( _environment, field->type, "(value)" );
17018
17019 switch( VT_BITWIDTH( field->type ) ) {
17020 case 32:
17021 cpu_move_32bit_indirect2( _environment, offset->realName, value->realName );
17022 break;
17023 case 16:
17024 cpu_move_16bit_indirect2( _environment, offset->realName, value->realName);
17025 break;
17026 case 8:
17027 cpu_move_8bit_indirect2( _environment, offset->realName, value->realName );
17028 break;
17029 case 1:
17031 case 0:
17033 }
17034
17035 } else {
17036
17037 value = source;
17038
17039 switch( VT_BITWIDTH( field->type ) ) {
17040 case 32:
17041 bank_read_vars_bank_direct_size( _environment, source->bankAssigned, offset->name, value->name, 4 );
17042 break;
17043 case 16:
17044 bank_read_vars_bank_direct_size( _environment, source->bankAssigned, offset->name, value->name, 2 );
17045 break;
17046 case 8:
17047 bank_read_vars_bank_direct_size( _environment, source->bankAssigned, offset->name, value->name, 1 );
17048 break;
17049 case 1:
17051 case 0:
17053 }
17054
17055 value->type = field->type;
17056
17057 }
17058
17059 if ( _direction > 0 ) {
17060 variable_increment( _environment, value->name );
17061 } else if ( _direction < 0 ) {
17062 variable_decrement( _environment, value->name );
17063 }
17064
17065 if ( source->bankAssigned == -1 ) {
17066
17067 switch( VT_BITWIDTH( field->type ) ) {
17068 case 32:
17069 cpu_move_32bit_indirect( _environment, value->realName, offset->realName );
17070 break;
17071 case 16:
17072 cpu_move_16bit_indirect( _environment, value->realName, offset->realName );
17073 break;
17074 case 8:
17075 cpu_move_8bit_indirect( _environment, value->realName, offset->realName );
17076 break;
17077 case 1:
17078 case 0:
17080 }
17081
17082 } else {
17083
17084 switch( VT_BITWIDTH( field->type ) ) {
17085 case 32:
17086 bank_write_vars_bank_direct_size( _environment, value->name, source->bankAssigned, offset->name, 4 );
17087 break;
17088 case 16:
17089 bank_write_vars_bank_direct_size( _environment, value->name, source->bankAssigned, offset->name, 2 );
17090 break;
17091 case 8:
17092 bank_write_vars_bank_direct_size( _environment, value->name, source->bankAssigned, offset->name, 1 );
17093 break;
17094 case 1:
17095 case 0:
17097 }
17098
17099 value->type = VT_TARRAY;
17100
17101 }
17102
17103}
17104
17105void variable_increment_array_type( Environment * _environment, char * _source, char * _field ) {
17106 variable_increment_decrement_array_type( _environment, _source, _field, 1 );
17107}
17108
17109void variable_decrement_array_type( Environment * _environment, char * _source, char * _field ) {
17110 variable_increment_decrement_array_type( _environment, _source, _field, -1 );
17111}
17112
17113void variable_increment_array( Environment * _environment, char * _source ) {
17114 variable_increment_decrement_array( _environment, _source, 1 );
17115}
17116
17117void variable_decrement_array( Environment * _environment, char * _source ) {
17118 variable_increment_decrement_array( _environment, _source, -1 );
17119}
17120
17121char * strcopy( char * _dest, char * _source ) {
17122
17123 if ( _dest == NULL || _source == NULL) {
17124 return NULL;
17125 }
17126
17127 memmove( _dest, _source, strlen(_source) + 1);
17128
17129 return _dest;
17130
17131}
17132
17133char * strreplace( const char * _orig, const char * _rep, const char * _with) {
17134
17135 char *result; // the return string
17136 const char *cins;
17137 char *ins; // the next insert point
17138 char *tmp; // varies
17139 int len_rep; // length of rep (the string to remove)
17140 int len_with; // length of _with (the string to replace rep _with)
17141 int len_front; // distance between rep and end of last rep
17142 int count; // number of replacements
17143
17144 // sanity checks and initialization
17145 if (!_orig || !_rep)
17146 return NULL;
17147 len_rep = strlen(_rep);
17148 if (len_rep == 0)
17149 return NULL; // empty rep causes infinite loop during count
17150 if (!_with)
17151 _with = "";
17152 len_with = strlen(_with);
17153
17154 // count the number of replacements needed
17155 cins = _orig;
17156 for (count = 0; (tmp = strstr(cins, _rep)); ++count) {
17157 cins = tmp + len_rep;
17158 }
17159
17160 tmp = result = malloc(strlen(_orig) + (len_with - len_rep) * count + 1);
17161
17162 if (!result)
17163 return NULL;
17164
17165 // first time through the loop, all the variable are set correctly
17166 // from here on,
17167 // tmp points to the end of the result string
17168 // ins points to the next occurrence of _rep in _orig
17169 // _orig points to the remainder of _orig after "end of _rep"
17170 while (count--) {
17171 ins = strstr(_orig, _rep);
17172 len_front = ins - _orig;
17173 tmp = strncpy(tmp, _orig, len_front) + len_front;
17174 tmp = strcpy(tmp, _with) + len_with;
17175 _orig += len_front + len_rep; // move to next "end of _rep"
17176 }
17177 strcpy(tmp, _orig);
17178 return result;
17179}
17180
17181CopperList * find_copper_list( Environment * _environment, char * _name ) {
17182
17183 CopperList * actual = _environment->copperList;
17184
17185 while( actual ) {
17186 if ( !_name ) {
17187 if ( !actual->name ) {
17188 return actual;
17189 }
17190 } else {
17191 if ( actual->name ) {
17192 if ( strcmp( actual->name, _name ) == 0 ) {
17193 return actual;
17194 }
17195 }
17196 }
17197 actual = actual->next;
17198 }
17199
17200 return NULL;
17201
17202}
17203
17204char * import_file_name( char * _import_path ) {
17205
17206 char * importDeclaresFilename = malloc(MAX_TEMPORARY_STORAGE);
17207 if ( _import_path ) {
17208 sprintf(importDeclaresFilename, "%s/%s.bas", _import_path, targetName);
17209 } else {
17210 sprintf(importDeclaresFilename, "../../imports/%s.bas", targetName);
17211 if( access( importDeclaresFilename, F_OK ) != 0 ) {
17212 sprintf(importDeclaresFilename, "../imports/%s.bas", targetName);
17213 }
17214 if( access( importDeclaresFilename, F_OK ) != 0 ) {
17215 sprintf(importDeclaresFilename, "imports/%s.bas", targetName);
17216 }
17217 if( access( importDeclaresFilename, F_OK ) != 0 ) {
17218 return NULL;
17219 }
17220 }
17221
17222 return importDeclaresFilename;
17223
17224}
17225
17226StaticString * static_string_find_by_value( Environment * _environment, char * _value, int _size ) {
17227
17228 StaticString * actual = ((Environment *)_environment)->strings;
17229 while( actual ) {
17230 if ( memcmp( actual->value, _value, _size ) == 0 ) {
17231 break;
17232 }
17233 actual = actual->next;
17234 }
17235 return actual;
17236}
17237
17238StaticString * static_string_create_filled( Environment * _environment, int _size, char _value ) {
17239
17240 StaticString * result = malloc( sizeof( StaticString ) );
17241 memset( result, 0, sizeof( StaticString ) );
17242 result->id = UNIQUE_ID;
17243 result->value = malloc( _size );
17244 memset( result->value, _value, _size );
17245 result->size = _size;
17246
17247 StaticString * storedStaticString = static_string_find_by_value( _environment, result->value, result->size );
17248 if ( storedStaticString ) {
17249 return storedStaticString;
17250 } else {
17251 result->next = _environment->strings;
17252 _environment->strings = result;
17253 return result;
17254 }
17255
17256}
17257
17258StaticString * static_string_create( Environment * _environment, char * _value, int _size ) {
17259 StaticString * result = malloc( sizeof( StaticString ) );
17260 memset( result, 0, sizeof( StaticString ) );
17261 result->id = UNIQUE_ID;
17262 result->value = malloc( _size );
17263 memcpy( result->value, _value, _size );
17264 result->size = _size;
17265 StaticString * storedStaticString = static_string_find_by_value( _environment, _value, _size );
17266 if ( storedStaticString ) {
17267 return storedStaticString;
17268 } else {
17269 result->next = _environment->strings;
17270 _environment->strings = result;
17271 return result;
17272 }
17273}
17274
17284 Environment * environment = malloc( sizeof(Environment) );
17285 memset( environment, 0, sizeof(Environment));
17286 return environment;
17287}
17288
17295
17296 _environment->optionClip = 1;
17297 _environment->optionReadSafe = 1;
17298 _environment->warningsEnabled = 0;
17299 _environment->defaultVariableType = VT_SWORD;
17300 _environment->peepholeOptimizationLimit = 16;
17301 _environment->floatType.precision = FT_FAST;
17302 _environment->numberConfig.maxBytes = 4;
17303 _environment->numberConfig.maxDigits = 10;
17304 _environment->temporaryPath = get_default_temporary_path( );
17308 _environment->printSafe = 1;
17309 _environment->putImageSafe = 1;
17310 _environment->getImageSafe = 1;
17311 _environment->keyboardConfig.latency = 700 / 20;
17312 _environment->keyboardConfig.delay = 150 / 20;
17313 _environment->keyboardConfig.release = 150 / 20;
17314 _environment->defaultPenColor = DEFAULT_PEN_COLOR;
17315 _environment->defaultPaperColor = DEFAULT_PAPER_COLOR;
17316 _environment->defaultArraySize = 10;
17317 _environment->vestigialConfig.screenModeUnique = 1;
17318
17319 #if defined(__pc128op__) || defined(__to8__)
17320 _environment->bankedLoadDefault = 1;
17321 #endif
17322
17323 #if defined(__atari__) || defined(__atarixl__)
17324 _environment->outputFileType = OUTPUT_FILE_TYPE_XEX;
17325 #elif defined(__c64__) || defined(__plus4__) || defined(__c16__) || defined(__vic20__) || defined(__c128__) || defined(__c128z__)
17326 _environment->outputFileType = OUTPUT_FILE_TYPE_PRG;
17327 #elif defined(__zx__)
17328 _environment->outputFileType = OUTPUT_FILE_TYPE_TAP;
17329 #elif defined(__coco__) || defined(__cocob__) || defined(__coco3__) || defined(__coco3b__)
17330 _environment->outputFileType = OUTPUT_FILE_TYPE_DSK;
17331 #elif defined(__d32__) || defined(__d32b__) || defined(__d64__) || defined(__d64b__)
17332 _environment->outputFileType = OUTPUT_FILE_TYPE_BIN;
17333 #elif defined(__pc128op__) || defined(__to8__) || defined(__mo5__)
17335 #elif defined(__msx1__) || defined(__coleco__) || defined(__sc3000__) || defined(__sg1000__)
17336 _environment->outputFileType = OUTPUT_FILE_TYPE_ROM;
17337 #elif defined(__gb__)
17338 _environment->outputFileType = OUTPUT_FILE_TYPE_GB;
17339 #elif defined(__pccga__)
17340 _environment->outputFileType = OUTPUT_FILE_TYPE_COM;
17341 #elif defined(__cpc__)
17342 _environment->outputFileType = OUTPUT_FILE_TYPE_DSK;
17343 #elif defined(__vg5000__)
17345 #elif defined(__c64reu__)
17346 _environment->outputFileType = OUTPUT_FILE_TYPE_D64;
17347 #elif defined(__pc1403__)
17348 _environment->outputFileType = OUTPUT_FILE_TYPE_RAM;
17349 #elif defined(__vz__)
17350 _environment->outputFileType = OUTPUT_FILE_TYPE_VZ;
17351 #endif
17352
17353}
17354
17355extern int yydebug;
17356extern char * importPath;
17357
17365void environment_parse_command_line( Environment * _environment, int _argc, char * _argv[] ) {
17366
17367 int opt;
17368
17369 while ((opt = getopt(_argc, _argv, "@1a:A:b:B:c:C:dD:Ee:Ffg:G:Ii:l:L:o:O:p:P:q:rR:st:T:VvWw:X:y")) != -1) {
17370 switch (opt) {
17371 case 'y':
17372 yydebug = 1;
17373 break;
17374 case '@':
17375 show_troubleshooting_and_exit( _environment, _argc, _argv );
17376 case 'a':
17377 if ( ! _environment->listingFileName ) {
17379 sprintf( listingFileName, "%s.lst", get_temporary_filename( _environment ) );
17380 _environment->listingFileName = strdup(listingFileName);
17381 }
17382 _environment->analysis = 1;
17383 break;
17384 case 'c':
17385 _environment->configurationFileName = strdup(optarg);
17386 break;
17387 case 'B':
17388 if ( strcmp( optarg, "UGBASIC" ) ) {
17389 _environment->dialect = DI_UGBASIC;
17390 } else if ( strcmp( optarg, "TSB" ) ) {
17391 _environment->dialect = DI_TSB;
17392 } else {
17393 CRITICAL("Option '-B': unknown dialect.");
17394 }
17395 break;
17396 case 'C':
17397 _environment->compilerFileName = strdup(optarg);
17398 if( access( _environment->compilerFileName, F_OK ) != 0 ) {
17399 CRITICAL("Option '-C': compiler not found.");
17400 }
17401 break;
17402 case 'w':
17403 _environment->cmdFileName = strdup(optarg);
17404 if( access( _environment->cmdFileName, F_OK ) != 0 ) {
17405 CRITICAL("Option '-w': replaced cmd.exe not found.");
17406 }
17407 break;
17408 case 'b':
17409 _environment->decbFileName = strdup(optarg);
17410 if( access( _environment->decbFileName, F_OK ) != 0 ) {
17411 CRITICAL("Option '-b': decb application not found.");
17412 }
17413 break;
17414 case 'X':
17415 _environment->executerFileName = strdup(optarg);
17416 if( access( _environment->executerFileName, F_OK ) != 0 ) {
17417 CRITICAL("Option '-X': executer not found.");
17418 }
17419 break;
17420 case 'F':
17421 _environment->dojoOnFujiNet = 1;
17422 break;
17423 case 'f':
17424 _environment->dojoOnVirtualizedFujiNet = 1;
17425 break;
17426 case 'P':
17427 _environment->profileFileName = strdup(optarg);
17428 break;
17429 case 'A':
17430 _environment->appMakerFileName = strdup(optarg);
17431 if( access( _environment->appMakerFileName, F_OK ) != 0 ) {
17432 CRITICAL("Option '-A': app maker no found.");
17433 }
17434 break;
17435 case 'i':
17436 importPath = strdup(optarg);
17437 break;
17438 case 't':
17439 #if defined(__atari__) || defined(__atarixl__)
17440 _environment->dir2atrFileName = strdup(optarg);
17441 if( access( _environment->dir2atrFileName, F_OK ) != 0 ) {
17442 CRITICAL("Option '-t': dir2atr not found.");
17443 }
17444 #endif
17445 #if defined(__msx1__)
17446 _environment->dsktoolsFileName = strdup(optarg);
17447 if( access( _environment->dsktoolsFileName, F_OK ) != 0 ) {
17448 CRITICAL("Option '-t': dsktools tool not found.");
17449 }
17450 #endif
17451 #if defined(__pc1403__)
17452 _environment->asLinkerFileName = strdup(optarg);
17453 if( access( _environment->asLinkerFileName, F_OK ) != 0 ) {
17454 CRITICAL("Option '-t': aslink tool not found.");
17455 }
17456 #endif
17457 break;
17458 case 'T':
17459 _environment->temporaryPath = strdup(optarg);
17460 break;
17461 case 'o':
17462 _environment->exeFileName = strdup(optarg);
17463 break;
17464 case 'd':
17465 break;
17466 case 'r':
17467 _environment->removeComments = 1;
17468 break;
17469 case 'v':
17470 _environment->outputGeneratedFiles = 1;
17471 break;
17472 case 'G':
17473 if ( strcmp( optarg, "none") == 0 || atoi( optarg ) == 0 ) {
17474 _environment->gammaCorrection = GAMMA_CORRECTION_NONE;
17475 } else if ( strcmp( optarg, "type1") == 0 || atoi( optarg ) == 1 ) {
17477 } else if ( strcmp( optarg, "type2") == 0 || atoi( optarg ) == 2 ) {
17479 }
17480 break;
17481 case 'O':
17482 if ( strcmp( optarg, "bin") == 0 ) {
17483 _environment->outputFileType = OUTPUT_FILE_TYPE_BIN;
17484 } else if ( strcmp( optarg, "prg") == 0 ) {
17485 _environment->outputFileType = OUTPUT_FILE_TYPE_PRG;
17486 } else if ( strcmp( optarg, "xex") == 0 ) {
17487 _environment->outputFileType = OUTPUT_FILE_TYPE_XEX;
17488 } else if ( strcmp( optarg, "k7o") == 0 ) {
17490 } else if ( strcmp( optarg, "k7") == 0 ) {
17492 } else if ( strcmp( optarg, "tap") == 0 ) {
17493 _environment->outputFileType = OUTPUT_FILE_TYPE_TAP;
17494 } else if ( strcmp( optarg, "rom") == 0 ) {
17495 _environment->outputFileType = OUTPUT_FILE_TYPE_ROM;
17496 } else if ( strcmp( optarg, "com") == 0 ) {
17497 _environment->outputFileType = OUTPUT_FILE_TYPE_COM;
17498 } else if ( strcmp( optarg, "d64") == 0 ) {
17499 _environment->outputFileType = OUTPUT_FILE_TYPE_D64;
17500 } else if ( strcmp( optarg, "gb") == 0 ) {
17501 _environment->outputFileType = OUTPUT_FILE_TYPE_GB;
17502 } else if ( strcmp( optarg, "ram") == 0 ) {
17503 _environment->outputFileType = OUTPUT_FILE_TYPE_RAM;
17504 } else if ( strcmp( optarg, "dsk") == 0 ) {
17505 _environment->outputFileType = OUTPUT_FILE_TYPE_DSK;
17506 } else if ( strcmp( optarg, "atr") == 0 ) {
17507 _environment->outputFileType = OUTPUT_FILE_TYPE_ATR;
17508 } else if ( strcmp( optarg, "reu") == 0 ) {
17509 _environment->outputFileType = OUTPUT_FILE_TYPE_REU;
17510 } else if ( strcmp( optarg, "vz") == 0 ) {
17511 _environment->outputFileType = OUTPUT_FILE_TYPE_VZ;
17512 } else if ( strcmp( optarg, "sddrive") == 0 ) {
17514 } else {
17515 CRITICAL2("Unknown output format", optarg);
17516 }
17517 break;
17518 case 'D':
17519 _environment->additionalInfoFileName = strdup(optarg);
17520 if ( ! _environment->listingFileName ) {
17521 char * p = malloc( strlen( _environment->additionalInfoFileName ) + MAX_TEMPORARY_STORAGE );
17522 strcopy( p, _environment->additionalInfoFileName );
17523 char * q = strrchr( p, '.' );
17524 if ( q ) {
17525 strcopy( q, ".listing" );
17526 }
17527 _environment->listingFileName = p;
17528 }
17529 break;
17530 case 'W':
17531 _environment->warningsEnabled = 1;
17532 break;
17533 case 'I':
17534 CRITICAL("Option '-I' has been removed, see bug#641" );
17535 break;
17536 case 'l':
17537 _environment->debuggerLabelsFileName = strdup(optarg);
17538 break;
17539 case 'L':
17540 _environment->listingFileName = strdup(optarg);
17541 break;
17542 case 'E':
17543 _environment->embeddedStatsEnabled = 1;
17544 break;
17545 case 'p':
17546 _environment->peepholeOptimizationLimit = atoi(optarg);
17547 break;
17548 case 'R':
17549 _environment->ramSize = atoi(optarg);
17550 break;
17551 case 'q':
17552 _environment->profileCycles = atoi(optarg);
17553 break;
17554 case 'V':
17555 fprintf(stderr, "%s\n%s\n", UGBASIC_VERSION, UGBASIC_REVISION );
17556 exit(0);
17557 break;
17558 case '1':
17559 _environment->tenLinerRulesEnforced = 1;
17560 break;
17561 case 's':
17562 _environment->sandbox = 1;
17563 break;
17564 case 'g': {
17565 char * p = strtok(optarg, ",");
17566 while(p) {
17567 if ( strcmp(p, "CLS_IMPLICIT" ) == 0 ) {
17568 ((struct _Environment *)_environment)->vestigialConfig.clsImplicit = 1;
17569 }
17570 if ( strstr(p, "STRING_COUNT=" ) != NULL ) {
17571 ((struct _Environment *)_environment)->dstring.count = atoi(p+13);
17572 }
17573 if ( strstr(p, "STRING_SPACE=" ) != NULL ) {
17574 ((struct _Environment *)_environment)->dstring.space = atoi(p+13);
17575 }
17576 p = strtok(NULL, ",");
17577 }
17578 }
17579 break;
17580 case 'e': {
17581 char * p = strtok(optarg, ",");
17582 while (p) {
17583
17584 parse_embedded( p, cpu_beq );
17597 parse_embedded( p, cpu_di );
17598 parse_embedded( p, cpu_ei );
17599 parse_embedded( p, cpu_inc );
17602 parse_embedded( p, cpu_dec );
17613 parse_embedded( p, cpu_end );
17617 parse_embedded( p, cpu_pop );
17719 parse_embedded( p, cpu_move_8bit_with_offset );
17727
17728 p = strtok(NULL, ",");
17729 }
17730
17731 }
17732 break;
17733 default: /* '?' */
17734 show_usage_and_exit( _argc, _argv );
17735 }
17736 }
17737
17738 if ( ! _argv[optind] ) {
17739 show_usage_and_exit( _argc, _argv );
17740 }
17741
17742 if ( ! _argv[optind+1] && !_environment->exeFileName ) {
17743 show_usage_and_exit( _argc, _argv );
17744 }
17745
17746}
17747
17749 _environment->dstring.space = 512;
17750 _environment->dstring.count = 32;
17751 _environment->defaultVariableType = VT_BYTE;
17752 _environment->vestigialConfig.clsImplicit = 1;
17753}
17754
17756
17757 /* retrocompatible hacks */
17758
17759 // If we are compiling "Beyond The Door" game with a recent
17760 // version of the compiler (>1.17), we must enable the hack.
17761 if ( strstr( strtoupper( _environment->sourceFileName ), "ACME-INC") != NULL ) {
17762 _environment->vestigialConfig.rchack_acme_1172 = 1;
17763 }
17764
17765 // If we are compiling "Beyond The Door" game with a recent
17766 // version of the compiler (>1.17), we must enable the hack.
17767 if ( strstr( strtoupper( _environment->sourceFileName ), "OSTRA") != NULL ) {
17768 _environment->vestigialConfig.rchack_ostra_1172 = 1;
17769 }
17770
17771 // If we are compiling "Beyond The Door" game with a recent
17772 // version of the compiler (>1.17), we must enable the hack.
17773 if ( strstr( _environment->sourceFileName, "btd-10liner") != NULL ) {
17774 _environment->vestigialConfig.rchack_btd_1171 = 1;
17775 }
17776
17777 // If we are compiling "Cocon" game with a recent
17778 // version of the compiler (>1.16.3), we must use the disruptive
17779 // optimization rule to reduce executable size.
17780 if ( strstr( _environment->sourceFileName, "cocon.bas") != NULL ) {
17781 _environment->vestigialConfig.rchack_cocon_1163 = 1;
17782 }
17783
17784 /* retrocompatible hacks */
17785 // If we are compiling "Pick the star" game with a recent
17786 // version of the compiler (>1.16.3), we must use a different
17787 // convention on joystick related return values (signed vs unsigned).
17788 if ( strstr( _environment->sourceFileName, "pick-the-star-10liner") != NULL ) {
17790 }
17791
17792 /* retrocompatible hacks */
17793 // We are compiling "4gravity" game with a recent
17794 // version of the compiler (>1.16.3).
17795 if ( strstr( _environment->sourceFileName, "4gravity") != NULL ) {
17796 _environment->vestigialConfig.rchack_4gravity_1163 = 1;
17797 _environment->vestigialConfig.rchack_4gravity_1164 = 1;
17798 }
17799
17800 /* retrocompatible hacks */
17801 // We are compiling "falling_balls" game with a recent
17802 // version of the compiler (>1.16.3).
17803 if ( strstr( _environment->sourceFileName, "falling-balls") != NULL ) {
17805 }
17806
17807 /* retrocompatible hacks */
17808 // We are compiling "Creepy carrots" game with a recent
17809 // version of the compiler (>1.16.3).
17810 if ( strstr( _environment->sourceFileName, "ccarrots") != NULL ) {
17811 _environment->vestigialConfig.rchack_ccarrots_1163 = 1;
17812 }
17813
17814}
void cpu_and_32bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4258
void cpu_move_32bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition 6309.c:5398
void cpu_dsfree(Environment *_environment, char *_index)
Definition 6309.c:5917
void cpu_less_than_memory_size(Environment *_environment, char *_source, char *_destination, int _size, char *_result, int _equal)
Definition 6309.c:5034
void cpu_dsresize_size(Environment *_environment, char *_index, int _resize)
Definition 6309.c:5948
void cpu_hex_to_string_calc_string(Environment *_environment, char *_size, int _separator, char *_string_size)
Definition 6309.c:5831
void cpu_move_8bit_signed_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7424
void cpu_float_fast_from_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition 6309.c:7043
void cpu_hex_to_string_calc_string_size(Environment *_environment, int _size, int _separator, char *_string_size)
Definition 6309.c:5848
void cpu_pokew(Environment *_environment, char *_address, char *_source)
Definition 6309.c:410
void cpu_move_32bit_signed_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7548
void cpu_combine_nibbles(Environment *_environment, char *_low_nibble, char *_hi_nibble, char *_byte)
Definition 6309.c:3724
void cpu_di(Environment *_environment)
Definition 6309.c:4547
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_not_16bit(Environment *_environment, char *_value, char *_result)
Definition 6309.c:4517
void cpu_move_8bit_unsigned_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7434
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_div_16bit_to_16bit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _signed)
Definition 6309.c:2009
void cpu_move_16bit_signed_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7478
void cpu_move_8bit_unsigned_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7398
void cpu_compare_32bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _positive)
CPU 6309: emit code to compare two 32 bit values
Definition 6309.c:2871
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_swap_32bit(Environment *_environment, char *_left, char *_right)
Definition 6309.c:4479
void cpu_float_fast_from_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition 6309.c:7066
void cpu_bveq(Environment *_environment, char *_value, char *_label)
Definition 6309.c:334
void cpu_dsresize(Environment *_environment, char *_index, char *_resize)
Definition 6309.c:5937
void cpu_move_nbit_indirect(Environment *_environment, int _n, char *_source, char *_value)
Definition 6309.c:6626
void cpu_math_div_8bit_to_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _signed)
Definition 6309.c:1242
void cpu_bit_check_extended(Environment *_environment, char *_value, char *_position, char *_result, int _bitwidth)
Definition 6309.c:5605
void cpu_math_div_32bit_to_16bit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _signed)
Definition 6309.c:2554
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_float_fast_div(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7228
void cpu_move_32bit_signed_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7541
void cpu_move_32bit_unsigned_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7534
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_uppercase(Environment *_environment, char *_source, char *_size, char *_result)
Definition 6309.c:5414
void cpu_math_add_16bit_with_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Definition 6309.c:1708
void cpu_mem_move(Environment *_environment, char *_source, char *_destination, char *_size)
Definition 6309.c:4692
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_xor_32bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition 6309.c:4432
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_poked(Environment *_environment, char *_address, char *_source)
Definition 6309.c:445
void cpu_and_8bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition 6309.c:4230
void cpu_dsassign(Environment *_environment, char *_original, char *_copy)
Definition 6309.c:5997
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_complement2_8bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:6045
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_less_than_memory(Environment *_environment, char *_source, char *_destination, char *_size, char *_result, int _equal)
Definition 6309.c:4969
void cpu_dsalloc_size(Environment *_environment, int _size, char *_index)
Definition 6309.c:5906
void cpu_move_16bit_unsigned_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7471
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_float_single_add(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7155
void cpu_float_single_sub(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7134
void cpu_bit_inplace_8bit_extended_indirect(Environment *_environment, char *_address, char *_position, char *_bit)
Definition 6309.c:5663
void cpu_move_8bit_unsigned_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7443
void cpu_move_8bit_indirect(Environment *_environment, char *_source, char *_value)
Definition 6309.c:5239
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_dec_16bit(Environment *_environment, char *_variable)
Definition 6309.c:4640
void cpu_dsgc(Environment *_environment)
Definition 6309.c:5959
void cpu_move_16bit_signed_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7488
void cpu_inc(Environment *_environment, char *_variable)
Definition 6309.c:4555
void cpu_poke_const(Environment *_environment, char *_address, int _source)
Definition 6309.c:388
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_dsdefine(Environment *_environment, char *_string, char *_index)
Definition 6309.c:5884
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_move_16bit_unsigned_32bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7507
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_dsfill(Environment *_environment, char *_string, char *_value)
Definition 6309.c:7610
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_fill_direct_size_value(Environment *_environment, char *_address, int _bytes, int _pattern)
CPU 6309: emit code to fill up a memory area
Definition 6309.c:712
void cpu_dec_32bit(Environment *_environment, char *_variable)
Definition 6309.c:4652
void cpu_greater_than_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 6309.c:1642
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_greater_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:1632
void cpu_bit_inplace_8bit(Environment *_environment, char *_value, int _position, int *_bit)
Definition 6309.c:5633
void cpu_math_add_16bit_const(Environment *_environment, char *_source, int _destination, char *_other)
Definition 6309.c:1674
void cpu_poked_const(Environment *_environment, char *_address, int _source)
Definition 6309.c:458
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_move_32bit_indirect(Environment *_environment, char *_source, char *_value)
Definition 6309.c:5382
void cpu_dswrite(Environment *_environment, char *_index)
Definition 6309.c:5927
void cpu_greater_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:989
void cpu_or_16bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4320
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_move_16bit_indirect(Environment *_environment, char *_source, char *_value)
Definition 6309.c:5339
void cpu_limit_16bit(Environment *_environment, char *_variable, int _value)
Definition 6309.c:4164
void cpu_move_8bit_indirect_with_offset2(Environment *_environment, char *_source, char *_value, char *_offset)
Definition 6309.c:5262
void cpu_less_than_32bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 6309.c:2985
void cpu_move_nbit_indirect2(Environment *_environment, int _n, char *_value, char *_source)
Definition 6309.c:6681
void cpu_and_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4216
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_compare_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _positive)
CPU 6309: emit code to compare two 16 bit values
Definition 6309.c:1542
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_store_nbit(Environment *_environment, char *_destination, int _n, int _value[])
CPU 6309: emit code to store n bit
Definition 6309.c:6499
void cpu_mem_move_direct_indirect_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition 6309.c:4815
void cpu_dec_nbit(Environment *_environment, char *_variable, int _bits)
Definition 6309.c:4672
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_move_8bit_indirect2_8bit(Environment *_environment, char *_value, char *_offset, char *_source)
Definition 6309.c:5307
void cpu_float_single_from_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition 6309.c:7070
void cpu_fill_indirect(Environment *_environment, char *_address, char *_size, char *_pattern, int _size_size)
Definition 6309.c:5517
void cpu_compare_and_branch_char_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:925
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_mul_nbit_to_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition 6309.c:1886
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_dec(Environment *_environment, char *_variable)
Definition 6309.c:4630
void cpu_and_16bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4244
void cpu_move_nbit(Environment *_environment, int _n, char *_source, char *_destination)
CPU cpu6309: emit code to store n bit
Definition 6309.c:6563
void cpu_logical_not_8bit(Environment *_environment, char *_value, char *_result)
Definition 6309.c:4493
void cpu_pokew_const(Environment *_environment, char *_address, int _source)
Definition 6309.c:421
void cpu_logical_and_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4198
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_halt(Environment *_environment)
Definition 6309.c:4050
void cpu_end(Environment *_environment)
Definition 6309.c:4064
void cpu_float_fast_from_double_to_int_array(Environment *_environment, double _value, int _result[])
Definition 6309.c:6743
void cpu_compare_memory(Environment *_environment, char *_source, char *_destination, char *_size, char *_result, int _equal)
Definition 6309.c:4849
void cpu_greater_than_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 6309.c:999
void cpu_complement2_16bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:6057
void cpu_xor_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4354
void cpu_complement2_32bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:6070
void cpu_lowercase(Environment *_environment, char *_source, char *_size, char *_result)
Definition 6309.c:5451
void cpu_float_single_to_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition 6309.c:7092
void cpu_move_16bit(Environment *_environment, char *_source, char *_destination)
CPU 6309: emit code to move 16 bit
Definition 6309.c:1474
void cpu_move_8bit_with_offset2(Environment *_environment, char *_source, char *_value, char *_offset)
Definition 6309.c:5278
void cpu_move_16bit_unsigned_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7465
void cpu_bneq(Environment *_environment, char *_label)
CPU 6309: emit code to make long conditional jump
Definition 6309.c:324
void cpu_move_16bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition 6309.c:5352
void cpu_float_fast_cmp(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7172
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_float_fast_mul(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7207
void cpu_bits_to_string(Environment *_environment, char *_number, char *_string, char *_string_size, int _bits, char *_zero, char *_one)
Definition 6309.c:5777
void cpu_dsalloc(Environment *_environment, char *_size, char *_index)
Definition 6309.c:5895
void cpu_less_than_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _equal, int _bits)
Definition 6309.c:3021
void cpu_not_32bit(Environment *_environment, char *_value, char *_result)
Definition 6309.c:4530
void cpu_float_single_from_double_to_int_array(Environment *_environment, double _value, int _result[])
Definition 6309.c:6747
void cpu_float_single_to_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition 6309.c:7113
void cpu_greater_than_memory_size(Environment *_environment, char *_source, char *_destination, int _size, char *_result, int _equal)
Definition 6309.c:5170
void cpu_hex_to_string(Environment *_environment, char *_number, char *_string, char *_size, int _separator)
Definition 6309.c:5865
void cpu_or_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4292
void cpu_move_8bit_indirect2_16bit(Environment *_environment, char *_value, char *_offset, char *_source)
Definition 6309.c:5323
void cpu_math_add_32bit_const(Environment *_environment, char *_source, int _destination, char *_other)
Definition 6309.c:3257
void cpu_move_8bit_indirect_with_offset(Environment *_environment, char *_source, char *_value, int _offset)
Definition 6309.c:5250
void cpu_sqroot(Environment *_environment, char *_number, char *_result)
Definition 6309.c:6113
void cpu_number_to_string(Environment *_environment, char *_number, char *_string, char *_string_size, int _bits, int _signed)
Definition 6309.c:5688
void cpu_greater_than_32bit(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:3117
void cpu_peekd(Environment *_environment, char *_address, char *_target)
Definition 6309.c:432
void cpu_call(Environment *_environment, char *_label)
Definition 6309.c:3755
void cpu_random_8bit(Environment *_environment, char *_entropy, char *_result)
Definition 6309.c:4129
void cpu_xor_8bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition 6309.c:4368
void cpu_move_16bit_signed_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7459
void cpu_mem_move_direct(Environment *_environment, char *_source, char *_destination, char *_size)
Definition 6309.c:4728
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_float_fast_to_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition 6309.c:7088
void cpu_float_single_div(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7232
void cpu_hex_to_bin(Environment *_environment, char *_value_address, char *_value_size, char *_variable_address, char *_variable_size, char *_result)
Definition 6309.c:7597
void cpu_greater_than_32bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 6309.c:3153
void cpu_float_fast_to_16(Environment *_environment, char *_value, char *_result, int _signed)
Definition 6309.c:7109
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_jump(Environment *_environment, char *_label)
Definition 6309.c:3739
void cpu_store_8bit_with_offset2(Environment *_environment, char *_source, char *_offset, int _value)
Definition 6309.c:6029
void cpu_move_16bit_unsigned_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7499
void cpu_move_32bit_signed_8bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7522
void cpu_mem_move_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition 6309.c:4781
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_float_single_mul(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7211
void cpu_move_16bit_signed_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7453
void cpu_math_div_16bit_to_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _signed)
Definition 6309.c:2153
void cpu_poke(Environment *_environment, char *_address, char *_source)
Definition 6309.c:377
void cpu_bit_check(Environment *_environment, char *_value, int _position, char *_result, int _bitwidth)
Definition 6309.c:5577
void cpu_move_32bit_signed_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7516
void cpu_math_div_nbit_to_nbit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _bits)
Definition 6309.c:2701
void cpu_random_32bit(Environment *_environment, char *_entropy, char *_result)
Definition 6309.c:4151
void cpu_move_32bit_unsigned_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7562
void cpu_less_than_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 6309.c:960
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_move_32bit_unsigned_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7555
void cpu_inc_32bit(Environment *_environment, char *_variable)
Definition 6309.c:4586
void cpu_move_8bit_signed_16bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7382
void cpu_mem_move_direct_size(Environment *_environment, char *_source, char *_destination, int _size)
Definition 6309.c:4798
void cpu_float_fast_sub(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7130
void cpu_xor_32bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4413
void cpu_return(Environment *_environment)
Definition 6309.c:4030
void cpu_move_8bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition 6309.c:5294
void cpu_inc_nbit(Environment *_environment, char *_variable, int _bits)
Definition 6309.c:4613
void cpu_pop(Environment *_environment)
Definition 6309.c:4040
void cpu_math_sub_16bit_with_8bit(Environment *_environment, char *_source, char *_destination, char *_other)
Definition 6309.c:2317
void cpu_random_16bit(Environment *_environment, char *_entropy, char *_result)
Definition 6309.c:4140
void cpu_ei(Environment *_environment)
Definition 6309.c:4551
void cpu_or_32bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4335
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_inc_16bit(Environment *_environment, char *_variable)
Definition 6309.c:4565
void cpu_logical_or_8bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4275
void cpu_random(Environment *_environment, char *_entropy)
Definition 6309.c:4075
void cpu_move_32bit_unsigned_8bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7528
void cpu_compare_and_branch_8bit(Environment *_environment, char *_source, char *_destination, char *_label, int _positive)
Definition 6309.c:851
void cpu_move_16bit_indirect2_8bit(Environment *_environment, char *_value, char *_offset, char *_source)
Definition 6309.c:5365
void cpu_float_single_from_8(Environment *_environment, char *_value, char *_result, int _signed)
Definition 6309.c:7047
void cpu_math_sub_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition 6309.c:3325
void cpu_float_single_cmp(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7176
void cpu_move_8bit_signed_32bit_signed(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7414
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_busy_wait(Environment *_environment, char *_timing)
Definition 6309.c:4183
void cpu_greater_than_memory(Environment *_environment, char *_source, char *_destination, char *_size, char *_result, int _equal)
Definition 6309.c:5105
void cpu_store_32bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 32 bit
Definition 6309.c:2540
void cpu_peekw(Environment *_environment, char *_address, char *_target)
Definition 6309.c:399
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_float_fast_add(Environment *_environment, char *_x, char *_y, char *_result)
Definition 6309.c:7151
void cpu_convert_string_into_16bit(Environment *_environment, char *_string, char *_len, char *_value)
Definition 6309.c:5502
void cpu_not_8bit(Environment *_environment, char *_value, char *_result)
Definition 6309.c:4505
void cpu_math_div_8bit_to_8bit(Environment *_environment, char *_source, char *_destination, char *_other, char *_other_remainder, int _signed)
Definition 6309.c:1163
void cpu_dsdescriptor(Environment *_environment, char *_index, char *_address, char *_size)
Definition 6309.c:5977
void cpu_math_add_nbit(Environment *_environment, char *_source, char *_destination, char *_other, int _bits)
Definition 6309.c:3238
void cpu_compare_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _positive)
CPU 6309: emit code to compare two 8 bit values
Definition 6309.c:831
void cpu_xor_16bit(Environment *_environment, char *_left, char *_right, char *_result)
Definition 6309.c:4382
void cpu_xor_16bit_const(Environment *_environment, char *_left, int _right, char *_result)
Definition 6309.c:4397
void cpu_swap_16bit(Environment *_environment, char *_left, char *_right)
Definition 6309.c:4465
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_math_div_32bit_to_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, char *_other_remainder, int _signed)
Definition 6309.c:2734
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
void cpu_dsfill_value(Environment *_environment, char *_string, int _value)
Definition 6309.c:7621
void cpu_dsassign_string(Environment *_environment, char *_string, char *_copy)
Definition 6309.c:6009
void cpu_move_8bit_signed_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7390
void cpu_move_8bit_unsigned_16bit_unsigned(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:7406
void cpu_compare_memory_size(Environment *_environment, char *_source, char *_destination, int _size, char *_result, int _equal)
Definition 6309.c:4906
void cpu_math_add_8bit_const(Environment *_environment, char *_source, int _destination, char *_other)
Definition 6309.c:1029
void cpu_flip_8bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:5544
void cpu_less_than_16bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 6309.c:1613
#define VT_FLOAT_NORMALIZED_BITWIDTH(p)
Definition 6309.h:44
#define VT_FLOAT_NORMALIZED_POW2_WIDTH(p)
Definition 6309.h:50
#define VT_FLOAT_BITWIDTH(p)
Definition 6309.h:38
#define DEFAULT_PAPER_COLOR
Definition 6847.h:70
#define COLOR_WHITE
Definition 6847.h:39
#define DEFAULT_PEN_COLOR
Definition 6847.h:69
Variable * variable_bin(Environment *_environment, char *_value, char *_digits, char *_zero, char *_one)
Emit code for <string>BIN(...).
int calculate_nearest_tile(TileDescriptor *_tile, TileDescriptors *_tiles)
StaticString * static_string_find_by_value(Environment *_environment, char *_value, int _size)
void label_define_numeric(Environment *_environment, int _label)
Variable * variable_move_from_array_bit(Environment *_environment, Variable *_array)
Variable * variable_array_min_vars(Environment *_environment, char *_name)
Variable * variable_hex2bin(Environment *_environment, char *_value, char *_variable)
Emit code for = HEX2BIN( ... ).
int procedure_exists(Environment *_environment, char *_name)
int assemblyLineIsAComment(char *_buffer)
Variable * variable_add(Environment *_environment, char *_source, char *_destination)
Add two variable and return the sum of them.
Variable * variable_retrieve(Environment *_environment, char *_name)
size_t buffered_fwrite(Environment *_environment, void *_data, size_t _size, size_t _count, FILE *_stream)
DataSegment * data_segment_find_numeric(Environment *_environment, int _number)
void variable_add_inplace(Environment *_environment, char *_source, int _destination)
void memory_area_unassign(MemoryArea *_first, Variable *_variable)
void parser_array_index_symbolic(Environment *_environment, char *_index)
char * image_extract_subimage(Environment *_environment, char *_source, int _width, int _height, int _frame_width, int _frame_height, int _x, int _y, int _depth)
ScreenMode * find_screen_mode_by_id(Environment *_environment, int _id)
int tile_allocate(TileDescriptors *_tiles, char *_data)
Variable * origin_resolution_relative_transform_x(Environment *_environment, char *_x, int _is_relative)
int system_move_safe(Environment *_environment, char *_source, char *_destination)
void variable_store_array_const_byte(Environment *_environment, Variable *_array, int _value)
RGBi * palette_match_hardware_index(RGBi *_source, int _source_size, RGBi *_system, int _system_size)
void variable_increment_array_type(Environment *_environment, char *_source, char *_field)
DataSegment * data_segment_define_or_retrieve_numeric(Environment *_environment, int _number)
int calculate_tile_affinity(TileDescriptor *_first, TileDescriptor *_second)
int find_frame_by_type(Environment *_environment, TsxTileset *_tileset, char *_images, char *_description)
void const_define_numeric(Environment *_environment, char *_name, int _value)
void variable_string_right_assign(Environment *_environment, char *_string, char *_position, char *_expression)
Emit code for RIGHT( ..., ... ) = ....
int reset_screen_mode_selected(Environment *_environment)
Variable * variable_string_right(Environment *_environment, char *_string, char *_position)
Emit code for = LEFT( ..., ... ).
Variable * variable_less_than_const(Environment *_environment, char *_source, int _destination, int _equal)
Variable * variable_string_mid(Environment *_environment, char *_string, char *_position, char *_len)
Emit code for = MID( ..., ... [, ...] ).
void variable_add_inplace_type(Environment *_environment, char *_source, char *_field, int _destination)
int count_screen_mode_selected(Environment *_environment)
VariableType variable_type_from_numeric_value(Environment *_environment, int _number)
void buffered_prepend_output(Environment *_environment)
void parser_array_cleanup(Environment *_environment)
Variable * variable_retrieve_or_define(Environment *_environment, char *_name, VariableType _type, int _value)
int rgbi_distance(RGBi *_e1, RGBi *_e2)
Calculate the distance between two colors.
void label_referred_define_named(Environment *_environment, char *_label)
RGBi * palette_shift(RGBi *_source, int _source_size, int _offset)
Shift colors in palette.
int calculate_horizontal_edges(TileData *_tileData, int _position)
Variable * variable_mul2_const(Environment *_environment, char *_destination, int _steps)
Double a variable for various times and return the result.
DataSegment * data_segment_define_numeric(Environment *_environment, int _number)
void variable_move_array(Environment *_environment, char *_array, char *_value)
StaticString * static_string_create(Environment *_environment, char *_value, int _size)
void variable_decrement(Environment *_environment, char *_source)
Decrement a variable by one.
DataSegment * data_segment_define_or_retrieve(Environment *_environment, char *_name)
Variable * variable_sr_const(Environment *_environment, char *_destination, int _bits)
void variable_add_inplace_mt(Environment *_environment, char *_source, char *_destination)
Add two variable and return the sum of them on the first.
Variable * variable_move_from_type(Environment *_environment, char *_type, char *_field)
void variable_string_mid_assign(Environment *_environment, char *_string, char *_position, char *_len, char *_expression)
Emit code for MID( ..., ... [, ...] ) = ....
CopperList * find_copper_list(Environment *_environment, char *_name)
char * image_roll_y_down(Environment *_environment, char *_source, int _width, int _height)
void variable_decrement_array(Environment *_environment, char *_source)
int variable_exists(Environment *_environment, char *_name)
Variable * variable_not(Environment *_environment, char *_value)
Calculate logical "not" and return it as the result.
DataSegment * data_segment_define(Environment *_environment, char *_name)
Variable * variable_string_inst(Environment *_environment, char *_string, char *_altstring, char *_pos)
void environment_setup_retrohack(Environment *_environment)
void label_stored_define_named(Environment *_environment, char *_label)
Variable * variable_move_from_array1_type(Environment *_environment, char *_array, char *_index, char *_field)
Variable * variable_store_type(Environment *_environment, char *_destination, char *_field, unsigned int _value)
Variable * variable_less_than(Environment *_environment, char *_source, char *_destination, int _equal)
Compare two variable and return the result of comparation.
void variable_array_fill_random(Environment *_environment, char *_name, int _base, int _min_value, int _max_value, int _count, int _boolean)
int system_call(Environment *_environment, char *_commandline)
Call an external executable.
Variable * variable_and(Environment *_environment, char *_left, char *_right)
Calculate logical "and" and return it as the result.
void variable_array_fill_incremental(Environment *_environment, char *_name, int _min, int _count)
Variable * calculate_frame_by_type(Environment *_environment, TsxTileset *_tileset, char *_images, char *_description)
char * find_last_path_separator(char *_path)
Variable * variable_greater_than(Environment *_environment, char *_source, char *_destination, int _equal)
Compare two variable and return the result of comparation.
Variable * parser_casted_numeric(Environment *_environment, VariableType _type, int _number)
Variable * variable_string_space(Environment *_environment, char *_repetitions)
Emit code for = SPACE( ... ).
void variable_compare_and_branch_const(Environment *_environment, char *_source, int _destination, char *_name, int _positive)
Variable * variable_string_val(Environment *_environment, char *_value)
Emit code for = VAL( ... ).
int buffered_fputs(Environment *_environment, const char *_string, FILE *_stream)
Variable * variable_move(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable by converting it.
Variable * variable_move_naked(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable without conversion.
Variable * variable_array_sum_vars(Environment *_environment, char *_name)
Variable * variable_array_type(Environment *_environment, char *_name, VariableType _type)
void variable_decrement_array_type(Environment *_environment, char *_source, char *_field)
RGBi * palette_merge(RGBi *_palette1, int _palette1_size, RGBi *_palette2, int _palette2_size, int *_size)
Make a "palette merge".
Variable * variable_string_str(Environment *_environment, char *_value)
Emit code for = STR( ... ).
char * file_read_csv(Environment *_environment, char *_filename, VariableType _type, int *_size, int *_count)
Variable * variable_string_upper(Environment *_environment, char *_string)
Emit code for = UPPER( ... ).
float min_of_three(float _m, float _n, float _p)
Variable * variable_and_const(Environment *_environment, char *_destination, int _mask)
Calculate "and" mask for a variable and it as the result.
int rgbi_equals_rgba(RGBi *_first, RGBi *_second)
int check_if_filename_is_valid(Environment *_environment, char *_filename)
int label_exists_named(Environment *_environment, char *_label)
void image_converter_asserts_free_height(Environment *_environment, int _width, int _height, int _offset_x, int _offset_y, int *_frame_width, int *_frame_height, int _modulo_x)
Variable * variable_int(Environment *_environment, char *_expression)
void image_converter_asserts_free_width(Environment *_environment, int _width, int _height, int _offset_x, int _offset_y, int *_frame_width, int *_frame_height, int _modulo_y)
Variable * variable_move_from_array(Environment *_environment, char *_array)
void image_converter_asserts_free(Environment *_environment, int _width, int _height, int _offset_x, int _offset_y, int *_frame_width, int *_frame_height)
void variable_string_left_assign(Environment *_environment, char *_string, char *_position, char *_expression)
Emit code for LEFT( ..., ... ) = ....
Variable * variable_string_chr(Environment *_environment, char *_ascii)
Emit code for = CHR( ... ).
void variable_add_inplace_type_vars(Environment *_environment, char *_source, char *_field, char *_destination)
char * image_flip_y(Environment *_environment, char *_source, int _width, int _height, int _depth)
ArrayReference * parser_array_retrieve(Environment *_environment)
char * basename(char *_path)
Variable * variable_define_no_init(Environment *_environment, char *_name, VariableType _type)
Variable * variable_string_pick(Environment *_environment, char *_string, int _position)
Variable * variable_sub_const(Environment *_environment, char *_source, int _destination)
Make a differenze between a variable a constant, and return the difference of them.
Variable * variable_add_const(Environment *_environment, char *_source, int _destination)
Add a variable with a constant, and return the sum of them.
void variable_store_array_const_bit(Environment *_environment, Variable *_array, int _value)
char * escape_newlines(char *_string)
void variable_increment(Environment *_environment, char *_source)
Increment a variable by one.
Resource * build_resource_for_sequence(Environment *_environment, char *_image, char *_frame, char *_sequence)
void define_implicit_array_if_needed(Environment *_environment, char *_name)
int label_stored_exists_named(Environment *_environment, char *_label)
void variable_increment_array(Environment *_environment, char *_source)
TileDescriptor * calculate_tile_descriptor(TileData *_tileData)
Variable * variable_string_lower(Environment *_environment, char *_string)
Emit code for = UPPER( ... ).
TileDescriptors * precalculate_tile_descriptors_for_font(char *_fontData, int _fontSize)
void environment_setup_10liner(Environment *_environment)
Variable * variable_mod(Environment *_environment, char *_source, char *_destination)
char * resolve_color(Environment *_environment, char *_color)
int pattern_match(char *_pattern, char *_value)
Environment * environment_create(void)
Create a new environment.
Variable * variable_string_left(Environment *_environment, char *_string, char *_position)
Emit code for = LEFT( ..., ... ).
Variable * variable_string_insert(Environment *_environment, char *_string, char *_altstring, char *_pos)
void variable_move_from_array_byte_inplace(Environment *_environment, Variable *_array, Variable *_result)
Variable * variable_flip(Environment *_environment, char *_variable)
Variable * variable_string_asc(Environment *_environment, char *_char)
Emit code for = ASC( ... ).
Variable * variable_retrieve_internal(Environment *_environment, char *_name, int _mandatory)
Retrieve the definition of a variable.
void variable_xor_inplace_mt(Environment *_environment, char *_source, char *_destination)
Add two variable and return the sum of them on the first.
Variable * variable_hex(Environment *_environment, char *_value, int _separator)
Emit code for = HEX( ... ).
Variable * variable_string_string(Environment *_environment, char *_string, char *_repetitions)
Emit code for = STRING( ..., ... ).
Variable * variable_move_from_array_byte(Environment *_environment, Variable *_array)
int rgbi_equals_rgb(RGBi *_first, RGBi *_second)
Variable * variable_import(Environment *_environment, char *_name, VariableType _type, int _size_or_value)
char * unescape_string(Environment *_environment, char *_value, int _printing, int *_final_size)
void environment_parse_command_line(Environment *_environment, int _argc, char *_argv[])
Parse command line parameters.
Variable * variable_move_from_mt(Environment *_environment, char *_source, char *_destination)
Increment a variable by one.
void get_image_overwrite_size(Environment *_environment, char *_image, char *_x1, char *_y1, char *_x2, char *_y2)
void variable_increment_type(Environment *_environment, char *_source, char *_field)
Variable * variable_compare_not(Environment *_environment, char *_source, char *_destination)
Compare two variable and return the result of comparation.
Variable * variable_resident(Environment *_environment, VariableType _type, char *_meaning)
Variable * variable_div_const(Environment *_environment, char *_source, int _destination, char *_remainder)
RGBi * palette_promote_color_as_background(int _index, RGBi *_source, int _source_size)
Promote an index color in a palette.
void variable_decrement_type(Environment *_environment, char *_source, char *_field)
int variable_exists_by_realname(Environment *_environment, char *_name)
const char * strrstr(const char *haystack, const char *needle)
char * image_roll_x_right(Environment *_environment, char *_source, int _width, int _height)
int label_referred_exists_named(Environment *_environment, char *_label)
Variable * variable_xor(Environment *_environment, char *_left, char *_right)
Calculate logical "xor" and return it as the result.
void variable_set_type(Environment *_environment, char *_name, char *_type)
char * image_flip_x(Environment *_environment, char *_source, int _width, int _height, int _depth)
RGBi * malloc_palette(int _size)
Allocate a palette space.
int variable_delete(Environment *_environment, char *_name)
Constant * constant_create(Environment *_environment, char *_name)
Variable * parse_buffer_definition(Environment *_environment, char *_buffer, VariableType _type, int _hex_only)
char * strcopy(char *_dest, char *_source)
Variable * variable_string_instr(Environment *_environment, char *_search, char *_searched, char *_start)
Emit code for = INSTR( ..., ... [, ...] ).
Variable * variable_resize_buffer(Environment *_environment, char *_destination, int _size)
Resize the (static) size of a buffer.
void variable_temporary_remove(Environment *_environment, char *_name)
char * image_enlarge_right(Environment *_environment, char *_source, int _width, int _height, int _delta)
void rgbi_move(RGBi *_source, RGBi *_destination)
DataSegment * data_segment_find(Environment *_environment, char *_name)
Variable * variable_by_constant(Environment *_environment, VariableType _type, int _value)
void variable_move_array_type(Environment *_environment, char *_array, char *_field, char *_value)
int calculate_exact_tile(TileDescriptor *_tile, TileDescriptors *_tiles)
Variable * variable_move_from_array_bit_inplace(Environment *_environment, Variable *_array, Variable *_result)
void variable_global(Environment *_environment, char *_pattern)
void variable_store_array_const(Environment *_environment, char *_array, int _value)
Variable * variable_store_float(Environment *_environment, char *_destination, double _value)
Store a string to a variable.
Variable * variable_define(Environment *_environment, char *_name, VariableType _type, int _value)
Define a variable for the program.
Variable * variable_export(Environment *_environment, char *_name, VariableType _type, int _size_or_value)
void label_define_named(Environment *_environment, char *_label)
ScreenMode * find_screen_mode_by_suggestion(Environment *_environment, int _bitmap, int _width, int _height, int _colors, int _tile_width, int _tile_height)
void variable_move_array1_type_const(Environment *_environment, char *_array, char *_index, char *_field, int _value)
Variable * variable_direct_assign(Environment *_environment, char *_var, char *_expr)
Variable * variable_array_max_vars(Environment *_environment, char *_name)
Variable * variable_mul(Environment *_environment, char *_source, char *_destination)
Make a multiplication between two variable and return the product of them.
void variable_xor_inplace_vars(Environment *_environment, char *_source, char *_destination)
Add two variable and return the sum of them on the first.
Type * type_find(Type *_first, char *_name)
float max_of_two(float _x, float _y)
void variable_move_array_byte(Environment *_environment, Variable *_array, char *_value)
void label_referred_define_numeric(Environment *_environment, int _label)
void variable_add_inplace_vars(Environment *_environment, char *_source, char *_destination)
Add two variable and return the sum of them on the first.
Variable * variable_sl_const(Environment *_environment, char *_destination, int _steps)
void parser_array_index_numeric(Environment *_environment, int _index)
Field * field_find(Type *_type, char *_name)
StaticString * string_reserve(Environment *_environment, char *_value)
Variable * variable_move_to_mt(Environment *_environment, char *_source, char *_destination)
void variable_sub_inplace(Environment *_environment, char *_source, char *_dest)
Make a differenze between two variable and assign the difference of them to the first.
void parser_array_init(Environment *_environment)
Variable * variable_store_string(Environment *_environment, char *_destination, char *_value)
Store a string to a variable.
void const_define_string(Environment *_environment, char *_name, char *_value)
void variable_move_array1_type_fields(Environment *_environment, char *_array, char *_index, char *_field1, char *_field2)
int show_troubleshooting_and_exit(Environment *_environment, int _argc, char *_argv[])
char * generate_storage_filename(Environment *_environment, char *_prefix, char *_suffix, int _number)
void prepare_variable_storage(Environment *_environment, char *_name, Variable *_source)
char * resource_load_asserts(Environment *_environment, char *_filename)
void variable_move_from_array_type_inplace(Environment *_environment, char *_array, char *_field, char *_value)
void offsetting_add_variable_reference(Environment *_environment, Offsetting *_first, Variable *_var, int _sequence)
Variable * origin_resolution_relative_transform_y(Environment *_environment, char *_y, int _is_relative)
char * strtoupper(char *_string)
Variable * variable_sub(Environment *_environment, char *_source, char *_dest)
Make a differenze between two variable and return the difference of them.
Variable * variable_div(Environment *_environment, char *_source, char *_destination, char *_remainder)
Make a division between two variable and return the product of them.
Variable * variable_cast(Environment *_environment, char *_source, VariableType _type)
Cast a variable from a type to another.
Variable * variable_string_len(Environment *_environment, char *_string)
Emit code for = LEN( ... ).
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
int label_referred_exists_numeric(Environment *_environment, int _label)
int rgbi_extract_palette(Environment *_environment, unsigned char *_source, int _width, int _height, int _depth, RGBi _palette[], int _palette_size, int _sorted)
Extract the color palette from the given image.
Variable * variable_compare(Environment *_environment, char *_source, char *_destination)
Compare two variable and return the result of comparation.
Offsetting * offsetting_size_count(Environment *_environment, int _size, int _count)
RGBi * palette_promote_color_as_foreground(int _index, RGBi *_source, int _source_size, int _max_size)
Promote an index color in a palette.
void variable_add_inplace_array(Environment *_environment, char *_source, char *_destination)
Add a variable to an array element, and return the sum of them on the array element.
Variable * variable_store_array(Environment *_environment, char *_destination, unsigned char *_buffer, int _size, int _at)
void variable_move_from_array1_type_inplace(Environment *_environment, char *_array, char *_index, char *_field, char *_value)
float max_of_three(float _m, float _n, float _p)
void variable_swap(Environment *_environment, char *_source, char *_dest)
Swap values of two variables.
void environment_setup_default(Environment *_environment)
Setup default environment values.
void variable_xor_inplace(Environment *_environment, char *_source, int _destination)
Variable * variable_store(Environment *_environment, char *_destination, unsigned int _value)
Store a direct value to a variable.
Variable * variable_string_dup(Environment *_environment, char *_string, char *_repetitions)
char * strreplace(const char *_orig, const char *_rep, const char *_with)
Variable * variable_array_count_vars(Environment *_environment, char *_name, char *_target)
char * parse_buffer(Environment *_environment, char *_buffer, int *_size, int _hex_only)
StaticString * static_string_create_filled(Environment *_environment, int _size, char _value)
Variable * variable_or(Environment *_environment, char *_left, char *_right)
Calculate logical "or" and return it as the result.
void variable_increment_mt(Environment *_environment, char *_source)
Increment a variable by one.
void variable_array_fill(Environment *_environment, char *_name, int _value)
void variable_reset(Environment *_environment)
Reset the usage flags for the temporary variable pool.
void variable_move_from_type_inplace(Environment *_environment, char *_type, char *_field, char *_value)
void variable_array_shuffle(Environment *_environment, char *_name, int _rounds)
#define UNESCAPE_COLOR(c, d)
char * get_default_temporary_path()
void buffered_push_output(Environment *_environment)
RGBi * palette_remove_duplicates(RGBi *_source, int _source_size, int *_unique_size)
Remove duplicates from a palette.
Variable * parser_adapted_numeric(Environment *_environment, int _number)
Variable * variable_move_from_array_type(Environment *_environment, char *_array, char *_field)
char * get_temporary_filename(Environment *_environment)
void font_descriptors_init(Environment *_environment, int _embedded_present)
Variable * variable_greater_than_const(Environment *_environment, char *_source, int _destination, int _equal)
char * image_roll_x_left(Environment *_environment, char *_source, int _width, int _height)
void buffered_pop_output(Environment *_environment)
Variable * variable_retrieve_by_realname(Environment *_environment, char *_name)
void variable_decrement_mt(Environment *_environment, char *_source)
Decrement a variable by one.
char * import_file_name(char *_import_path)
Variable * variable_div2_const(Environment *_environment, char *_destination, int _bits, char *_remainder)
Subdivide by two a variable for various times and return the result.
Variable * variable_compare_not_const(Environment *_environment, char *_source, int _destination)
Compare two variable and return the result of comparation.
char * image_enlarge_bottom(Environment *_environment, char *_source, int _width, int _height, int _delta)
Variable * variable_complement_const(Environment *_environment, char *_source, int _value)
Calculate the complement of a variable.
int system_remove_safe(Environment *_environment, char *_filename)
char * escape_newlines_full(char *_string, int _size)
void memory_area_assign(MemoryArea *_first, Variable *_variable)
RGBi * palette_match(RGBi *_source, int _source_size, RGBi *_system, int _system_size)
Make a "palette match".
int calculate_white_area(TileData *_tileData)
int label_exists_numeric(Environment *_environment, int _label)
void image_converter_asserts(Environment *_environment, int _width, int _height, int _offset_x, int _offset_y, int *_frame_width, int *_frame_height, int _modulo_x, int _modulo_y)
void variable_store_mt(Environment *_environment, char *_source, unsigned int _value)
Store a variable's value.
void parser_array_init_by(Environment *_environment, ArrayReference *_array_reference)
Variable * variable_string_substring(Environment *_environment, char *_string, char *_start, char *_end)
Emit code for = SUBSTRING( ..., ... [, ...] ).
void buffered_output(Environment *_environment, FILE *_stream)
#define strcmp_nocase
void variable_move_array_bit(Environment *_environment, Variable *_array, char *_value)
char * address_displacement(Environment *_environment, char *_address, char *_displacement)
Constant * constant_find(Environment *_environment, char *_name)
void buffered_fprintf(Environment *_environment, FILE *_stream, const char *_format,...)
Variable * variable_compare_const(Environment *_environment, char *_source, int _destination)
Compare two variable and return the result of comparation.
float min_of_two(float _x, float _y)
void variable_move_from_array_inplace(Environment *_environment, char *_array, char *_result)
const char * strstrcase(const char *_x, const char *_y)
void variable_move_array1_type(Environment *_environment, char *_array, char *_index, char *_field, char *_value)
void variable_move_array_string(Environment *_environment, char *_array, char *_string)
void variable_move_type(Environment *_environment, char *_type, char *_field, char *_value)
int file_get_size(Environment *_environment, char *_filename)
Bank * bank_find(Bank *_first, char *_name)
Variable * variable_string_flip(Environment *_environment, char *_string)
Emit code for = FLIP( ... ).
int check_datatype_limits(VariableType _type, int _value)
int calculate_vertical_edges(TileData *_tileData, int _position)
Variable * variable_store_buffer(Environment *_environment, char *_destination, unsigned char *_buffer, int _size, int _at)
Variable * variable_bit(Environment *_environment, char *_value, char *_position)
Emit code for HAS BIT / BIT(...).
Variable * absolute(Environment *_environment, char *_value)
Return the absolute value of a variable.
Definition abs.c:97
int size
Definition _optimizer.c:678
char * name
Definition _optimizer.c:672
int offset
Definition _optimizer.c:681
char BANK_TYPE_AS_STRING[][16]
Description of BANK TYPE, in readable format.
void color(Environment *_environment, int _index, int _shade)
Emit ASM code for instruction COLOR [int], [int].
Definition color.c:59
#define JOYSTICK_CONFIG_DEFAULT_SYNC
Definition atari.h:49
#define KEYBOARD_CONFIG_DEFAULT_SYNC
Definition atari.h:139
void bank_read_semi_var(Environment *_environment, int _bank, int _address1, char *_address2, int _size)
Emit ASM code for instruction BANK READ ....
Definition bank_read.c:50
void bank_read_vars_bank_direct_size(Environment *_environment, int _bank, char *_address1, char *_address2, int _size)
Definition bank_read.c:218
void bank_uncompress_semi_var(Environment *_environment, int _bank, int _address1, char *_address2)
Emit ASM code for instruction BANK UNCOMPRESS ....
void bank_write_vars_bank_direct_size(Environment *_environment, char *_address1, int _bank, char *_address2, int _size)
Definition bank_write.c:111
Variable * create_vector(Environment *_environment, char *_x, char *_y)
Emit ASM code to implement CREATE PATH command.
Variable * distance(Environment *_environment, char *_x1, char *_y1, char *_x2, char *_y2)
Return the distance between two (screen) positions.
Definition distance.c:76
void end(Environment *_environment)
Emit ASM code for END.
Definition end.c:91
void error(Environment *_environment, char *_message)
Emit ASM code for ERROR.
Definition error.c:73
unsigned int data_font_alpha_bin_len
Definition font_alpha.c:89
unsigned char data_font_alpha_bin[]
Definition font_alpha.c:1
unsigned int data_font_ascii_bin_len
Definition font_ascii.c:89
unsigned char data_font_ascii_bin[]
Definition font_ascii.c:1
unsigned int data_font_complete_bin_len
unsigned char data_font_complete_bin[]
unsigned char data_font_semigraphic_bin[]
unsigned int data_font_semigraphic_bin_len
unsigned int data_font_standard_bin_len
unsigned char data_font_standard_bin[]
Variable * rnd(Environment *_environment, char *_value)
Return a random value.
Definition rnd.c:79
Variable * sbpen_get(Environment *_environment, char *_index)
Definition sb.c:61
Variable * sign(Environment *_environment, char *_value)
Return the sign of a variable.
Definition sgn.c:85
#define abs(ticks)
Definition sidreloc.c:338
uint16_t word
Definition sidreloc.c:274
uint8_t byte
Definition sidreloc.c:273
int arrayIndexesDirectEach[MAX_ARRAY_DIMENSIONS]
Definition ugbc.h:959
char * arrayIndexesEach[MAX_ARRAY_DIMENSIONS]
Definition ugbc.h:954
int arrayIndexes
Definition ugbc.h:949
char * name
Definition ugbc.h:156
struct _Bank * next
Definition ugbc.h:185
double valueFloating
Definition ugbc.h:825
StaticString * valueString
Definition ugbc.h:820
char * name
Definition ugbc.h:800
char * relative
Definition ugbc.h:829
int value
Definition ugbc.h:815
ConstantType type
Definition ugbc.h:805
struct _Constant * next
Definition ugbc.h:832
char * realName
Definition ugbc.h:803
char * name
Definition ugbc.h:2252
struct _CopperList * next
Definition ugbc.h:2255
int space
Definition ugbc.h:1970
int count
Definition ugbc.h:1969
struct _DataSegment * next
Definition ugbc.h:2198
int lineNumber
Definition ugbc.h:2193
char * name
Definition ugbc.h:2191
int isNumeric
Definition ugbc.h:2189
Structure of compilation environment.
Definition ugbc.h:2269
Variable * tempResidentVariables
Definition ugbc.h:2595
char * bufferOutput[MAX_BUFFERED_OUTPUT]
Definition ugbc.h:3340
int embeddedStatsEnabled
Definition ugbc.h:2927
int disableMemoryAreas
Definition ugbc.h:2691
Variable * procedureVariables
Definition ugbc.h:2626
int defaultUnsignedType
Definition ugbc.h:3082
int defaultArraySize
Definition ugbc.h:3240
int currentBufferOutput
Definition ugbc.h:3335
Label * storedLabels
Definition ugbc.h:2555
char * listingFileName
Definition ugbc.h:2305
char * arrayIndexesEach[MAX_NESTED_ARRAYS][MAX_ARRAY_DIMENSIONS]
Definition ugbc.h:2738
int bitPosition
Definition ugbc.h:3155
Offsetting * offsetting
Definition ugbc.h:2937
char * temporaryPath
Definition ugbc.h:2360
int freeImageWidth
Definition ugbc.h:3088
Bank * banks[BANK_TYPE_COUNT]
Definition ugbc.h:2514
int analysis
Definition ugbc.h:2365
int optionClip
Definition ugbc.h:2467
int printSafe
Definition ugbc.h:3273
JoystickConfig joystickConfig
Definition ugbc.h:2437
int dojoOnVirtualizedFujiNet
Definition ugbc.h:3245
int maxExpansionBankSize[MAX_RESIDENT_SHAREDS]
Definition ugbc.h:3010
VariableType defaultVariableType
Definition ugbc.h:2956
int address
Definition ugbc.h:2780
char * configurationFileName
Definition ugbc.h:2295
char * executerFileName
Definition ugbc.h:2315
int bufferOutputSize[MAX_BUFFERED_OUTPUT]
Definition ugbc.h:3345
int arrayDimensions
Definition ugbc.h:2718
int originY
Definition ugbc.h:3050
char * dir2atrFileName
Definition ugbc.h:2340
OutputFileType outputFileType
Definition ugbc.h:2452
Variable * tempVariables[MAX_PROCEDURES]
Definition ugbc.h:2606
Type * types
Definition ugbc.h:2538
FileStorage * currentFileStorage
Definition ugbc.h:2536
char * compilerFileName
Definition ugbc.h:2320
Label * referredLabels
Definition ugbc.h:2550
char * decbFileName
Definition ugbc.h:2335
DataSegment * dataSegment
Definition ugbc.h:2568
char * debuggerLabelsFileName
Definition ugbc.h:2300
int sandbox
Definition ugbc.h:2990
int bitByte
Definition ugbc.h:3160
Dialect dialect
Definition ugbc.h:3181
int colorImplicit
Definition ugbc.h:2970
int tenLinerRulesEnforced
Definition ugbc.h:2985
StaticString * strings
Definition ugbc.h:2641
int peepholeOptimizationLimit
Definition ugbc.h:2370
MemoryArea * memoryAreas
Definition ugbc.h:2689
int outputGeneratedFiles
Definition ugbc.h:3173
int currentProcedure
Definition ugbc.h:2601
int originYDirection
Definition ugbc.h:3055
NumberConfig numberConfig
Definition ugbc.h:2410
DString dstring
Definition ugbc.h:2405
char * dsktoolsFileName
Definition ugbc.h:2345
int removeComments
Definition ugbc.h:3194
Label * labels
Definition ugbc.h:2545
int arrayNestedIndex
Definition ugbc.h:2728
CopperList * copperList
Definition ugbc.h:3282
int ramSize
Definition ugbc.h:3171
Variable * variables
Definition ugbc.h:2616
int arrayDimensionsEach[MAX_ARRAY_DIMENSIONS]
Definition ugbc.h:2723
char * sourceFileName
Definition ugbc.h:2280
char * profileFileName
Definition ugbc.h:2310
char * additionalInfoFileName
Definition ugbc.h:2355
Variable * currentArray
Definition ugbc.h:2748
Constant * constants
Definition ugbc.h:2611
char * asLinkerFileName
Definition ugbc.h:2350
FontConfig fontConfig
Definition ugbc.h:2415
char * cmdFileName
Definition ugbc.h:2325
Pattern * globalVariablePatterns
Definition ugbc.h:2631
ScreenMode * screenModes
Definition ugbc.h:2516
int leftReplace
Definition ugbc.h:3219
int originX
Definition ugbc.h:3045
ProtothreadConfig protothreadConfig
Definition ugbc.h:2430
int getImageSafe
Definition ugbc.h:3276
int optionExplicit
Definition ugbc.h:2457
int warningsEnabled
Definition ugbc.h:2380
int dojoOnFujiNet
Definition ugbc.h:3244
int resolutionUsed
Definition ugbc.h:3060
int arrayIndexes[MAX_NESTED_ARRAYS]
Definition ugbc.h:2733
FloatType floatType
Definition ugbc.h:2400
int bankedLoadDefault
Definition ugbc.h:2951
char * asmFileName
Definition ugbc.h:2285
Type * currentType
Definition ugbc.h:2540
int originUsed
Definition ugbc.h:3040
char * procedureName
Definition ugbc.h:2775
int arrayIndexesDirectEach[MAX_NESTED_ARRAYS][MAX_ARRAY_DIMENSIONS]
Definition ugbc.h:2743
int optionReadSafe
Definition ugbc.h:2472
KeyboardConfig keyboardConfig
Definition ugbc.h:2435
int residentDetectionEnabled
Definition ugbc.h:3192
int defaultNarrowType
Definition ugbc.h:3084
TileDescriptors * descriptors
Definition ugbc.h:2939
GammaCorrection gammaCorrection
Definition ugbc.h:3000
int midReplace
Definition ugbc.h:3217
int checkBoundary
Definition ugbc.h:2713
int profileCycles
Definition ugbc.h:2375
int dataLastAbsoluteAddress
Definition ugbc.h:3278
Field * currentField
Definition ugbc.h:3264
Procedure * procedures
Definition ugbc.h:2621
int putImageSafe
Definition ugbc.h:3275
char * appMakerFileName
Definition ugbc.h:2330
int freeImageHeight
Definition ugbc.h:3086
int defaultPaperColor
Definition ugbc.h:3226
int emptyProcedure
Definition ugbc.h:2932
char * exeFileName
Definition ugbc.h:2290
int defaultPenColor
Definition ugbc.h:3225
VestigialConfig vestigialConfig
Definition ugbc.h:2442
char * name
Definition ugbc.h:1231
VariableType type
Definition ugbc.h:1233
struct _Field * next
Definition ugbc.h:1237
int offset
Definition ugbc.h:1235
int size
Definition ugbc.h:204
FloatTypePrecision precision
Definition ugbc.h:868
int schema
Definition ugbc.h:2063
struct _Label * next
Definition ugbc.h:848
char * name
Definition ugbc.h:842
int number
Definition ugbc.h:845
int size
Definition ugbc.h:752
struct _MemoryArea * next
Definition ugbc.h:760
MemoryAreaType type
Definition ugbc.h:757
int current
Definition ugbc.h:742
int maxBytes
Definition ugbc.h:2261
int maxDigits
Definition ugbc.h:2262
int size
Definition ugbc.h:892
struct _Offsetting * next
Definition ugbc.h:905
int count
Definition ugbc.h:897
OffsettingVariable * variables
Definition ugbc.h:902
struct _Variable * variable
Definition ugbc.h:880
struct _OffsettingVariable * next
Definition ugbc.h:883
struct _Pattern * next
Definition ugbc.h:1461
char * pattern
Definition ugbc.h:1458
struct _Procedure * next
Definition ugbc.h:1327
char * name
Definition ugbc.h:1256
unsigned char red
Definition ugbc.h:433
unsigned char green
Definition ugbc.h:434
unsigned char blue
Definition ugbc.h:435
unsigned char alpha
Definition ugbc.h:436
unsigned char hardwareIndex
Definition ugbc.h:439
unsigned char index
Definition ugbc.h:437
int count
Definition ugbc.h:441
int compression
Definition ugbc.h:558
int isAddress
Definition ugbc.h:557
VariableType type
Definition ugbc.h:559
char * realName
Definition ugbc.h:555
int tileWidth
Definition ugbc.h:1504
int width
Definition ugbc.h:1498
int bitmap
Definition ugbc.h:1496
struct _ScreenMode * next
Definition ugbc.h:1512
int tileHeight
Definition ugbc.h:1506
int height
Definition ugbc.h:1500
int selected
Definition ugbc.h:1510
int score
Definition ugbc.h:1508
int colors
Definition ugbc.h:1502
char * value
Definition ugbc.h:337
struct _StaticString * next
Definition ugbc.h:342
char data[8]
Definition ugbc.h:2141
int horizontalEdges[8]
Definition ugbc.h:2134
int verticalEdges[8]
Definition ugbc.h:2135
TileData data[512]
Definition ugbc.h:2153
TileDescriptor * descriptor[512]
Definition ugbc.h:2152
double probability
Definition tsx.h:50
char * type
Definition tsx.h:49
struct _TsxTile * next
Definition tsx.h:52
int id
Definition tsx.h:48
struct _TsxTile * tiles
Definition tsx.h:72
int size
Definition ugbc.h:1245
char * name
Definition ugbc.h:1243
struct _Field * first
Definition ugbc.h:1247
struct _Type * next
Definition ugbc.h:1249
int bankAssigned
Definition ugbc.h:1172
TmxMap * originalTilemap
Definition ugbc.h:1189
unsigned char * reflected
Definition ugbc.h:1072
unsigned char * valueBuffer
Definition ugbc.h:1061
double valueFloating
Definition ugbc.h:1046
Offsetting * offsettingFrames
Definition ugbc.h:1206
struct _Variable * tileset
Definition ugbc.h:1186
char * originalBitmap
Definition ugbc.h:1142
Strip * strips
Definition ugbc.h:1215
FloatTypePrecision precision
Definition ugbc.h:991
SIDFILE * sidFile
Definition ugbc.h:1213
StaticString * valueString
Definition ugbc.h:1041
char * meaningName
Definition ugbc.h:985
int residentAssigned
Definition ugbc.h:1175
int assigned
Definition ugbc.h:1020
int bitPosition
Definition ugbc.h:1051
struct _Variable * origin
Definition ugbc.h:1067
Offsetting * offsettingSequences
Definition ugbc.h:1211
struct _Variable * next
Definition ugbc.h:1225
int locked
Definition ugbc.h:1009
int initialValue
Definition ugbc.h:1030
int size
Definition ugbc.h:1077
int originalHeight
Definition ugbc.h:1148
Compression compression
Definition ugbc.h:1087
int arrayDimensions
Definition ugbc.h:1112
int originalDepth
Definition ugbc.h:1151
int used
Definition ugbc.h:1002
char * name
Definition ugbc.h:979
int absoluteAddress
Definition ugbc.h:1092
TsxTileset * originalTileset
Definition ugbc.h:1184
int bitByte
Definition ugbc.h:1056
int mapLayers
Definition ugbc.h:1160
FloatTypePrecision arrayPrecision
Definition ugbc.h:1128
int onStorage
Definition ugbc.h:1201
int arrayDimensionsEach[MAX_ARRAY_DIMENSIONS]
Definition ugbc.h:1117
int originalColors
Definition ugbc.h:1154
VariableType type
Definition ugbc.h:988
int frameSize
Definition ugbc.h:1134
int readonly
Definition ugbc.h:1195
MemoryArea * memoryArea
Definition ugbc.h:1107
int mapHeight
Definition ugbc.h:1158
int frameCount
Definition ugbc.h:1137
int originalWidth
Definition ugbc.h:1145
int uncompressedSize
Definition ugbc.h:1082
int value
Definition ugbc.h:1025
Bank * bank
Definition ugbc.h:1102
int frameWidth
Definition ugbc.h:1162
int variableUniqueId
Definition ugbc.h:1178
int initializedByConstant
Definition ugbc.h:1036
int frameHeight
Definition ugbc.h:1164
RGBi originalPalette[MAX_PALETTE]
Definition ugbc.h:1169
int imported
Definition ugbc.h:1014
VariableType arrayType
Definition ugbc.h:1125
int mapWidth
Definition ugbc.h:1156
struct _Type * typeType
Definition ugbc.h:1222
int temporary
Definition ugbc.h:996
char * realName
Definition ugbc.h:982
char rchack_falling_balls_1163
Definition ugbc.h:2052
char rchack_4gravity_1163
Definition ugbc.h:2046
char rchack_pick_the_star_1163
Definition ugbc.h:2041
char rchack_ostra_1172
Definition ugbc.h:2020
char rchack_4gravity_1164
Definition ugbc.h:2047
char rchack_cocon_1163
Definition ugbc.h:2034
char screenModeUnique
Definition ugbc.h:2004
char clsImplicit
Definition ugbc.h:2008
char rchack_ccarrots_1163
Definition ugbc.h:2057
char rchack_acme_1172
Definition ugbc.h:2015
char rchack_btd_1171
Definition ugbc.h:2025
struct _TsxTile TsxTile
struct _TsxTileset TsxTileset
void * malloc(YYSIZE_T)
#define yydebug
void free(void *)
struct _ScreenMode ScreenMode
#define WARNING_DOWNCAST(v1, v2)
Definition ugbc.h:3877
struct _Resource Resource
#define CRITICAL_CANNOT_READ_FILE(f, n)
Definition ugbc.h:3757
#define FONT_SCHEMA_COMPLETE
Definition ugbc.h:580
#define CRITICAL_CONSTANT_ALREADY_DEFINED_AS_VARIABLE(f)
Definition ugbc.h:3583
#define CRITICAL_DATATYPE_MISMATCH(v1, v2)
Definition ugbc.h:3453
@ OUTPUT_FILE_TYPE_ROM
Definition ugbc.h:265
@ OUTPUT_FILE_TYPE_REU
Definition ugbc.h:269
@ OUTPUT_FILE_TYPE_K7_NEW
Definition ugbc.h:262
@ OUTPUT_FILE_TYPE_GB
Definition ugbc.h:271
@ OUTPUT_FILE_TYPE_DSK
Definition ugbc.h:267
@ OUTPUT_FILE_TYPE_PRG
Definition ugbc.h:259
@ OUTPUT_FILE_TYPE_TAP
Definition ugbc.h:263
@ OUTPUT_FILE_TYPE_VZ
Definition ugbc.h:273
@ OUTPUT_FILE_TYPE_K7_ORIGINAL
Definition ugbc.h:261
@ OUTPUT_FILE_TYPE_BIN
Definition ugbc.h:258
@ OUTPUT_FILE_TYPE_ATR
Definition ugbc.h:268
@ OUTPUT_FILE_TYPE_COM
Definition ugbc.h:272
@ OUTPUT_FILE_TYPE_RAM
Definition ugbc.h:270
@ OUTPUT_FILE_TYPE_SDDRIVE
Definition ugbc.h:274
@ OUTPUT_FILE_TYPE_D64
Definition ugbc.h:266
@ OUTPUT_FILE_TYPE_XEX
Definition ugbc.h:260
#define CRITICAL_RESIZE_UNSUPPORTED(t)
Definition ugbc.h:3450
#define FONT_SCHEMA_SEMIGRAPHIC
Definition ugbc.h:579
#define CRITICAL_VARIABLE_TYPE_NEEDED(n)
Definition ugbc.h:3831
#define VT_MAX(t)
Definition ugbc.h:674
#define CRITICAL_CANNOT_MOVE_PLACEHOLDERS_TO_IMAGE(v)
Definition ugbc.h:3786
#define CRITICAL_CANNOT_COPY_SID_FILE(f)
Definition ugbc.h:3802
#define CRITICAL_SUB_UNSUPPORTED(v, t)
Definition ugbc.h:3455
#define CRITICAL_NOT_SUPPORTED(v)
Definition ugbc.h:3488
#define CRITICAL_IMAGE_CONVERTER_INVALID_FRAME_HEIGHT(h, m)
Definition ugbc.h:3527
struct _RGBi RGBi
Structure to store color components (red, green and blue).
struct _Field Field
#define CRITICAL_MID_UNSUPPORTED(v, t)
Definition ugbc.h:3465
#define CRITICAL_CANNOT_FILL_RANDOM(v)
Definition ugbc.h:3801
#define CRITICAL_LABEL_ALREADY_DEFINED(n)
Definition ugbc.h:3675
#define CRITICAL_MID_UNSUPPORTED_FOR_STRING(s)
Definition ugbc.h:3787
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define CRITICAL_UNKNOWN_FIELD_ON_TYPE(n)
Definition ugbc.h:3834
#define TRACE1(s, p1)
Definition ugbc.h:87
struct _Offsetting Offsetting
#define CRITICAL_CANNOT_COMPARE(t1, t2)
Definition ugbc.h:3459
#define CRITICAL_MISSING_FILE_STORAGE(v)
Definition ugbc.h:3695
#define CRITICAL_IMAGE_CONVERTER_INVALID_OFFSET_Y(y)
Definition ugbc.h:3529
struct _ArrayReference ArrayReference
#define VT_SIGNED(t)
Definition ugbc.h:618
#define CRITICAL_BIN_UNSUPPORTED(v, t)
Definition ugbc.h:3508
#define FONT_SCHEMA_EMBEDDED
Definition ugbc.h:577
#define CRITICAL_XOR_UNSUPPORTED(v, t)
Definition ugbc.h:3580
#define VT_ESIGN_16BIT(t, v)
Definition ugbc.h:652
#define CRITICAL_VARIABLE_REDEFINED_DIFFERENT_TYPE(f)
Definition ugbc.h:3598
struct _TileDescriptors TileDescriptors
#define CRITICAL_CANNOT_STORE_BIT_ON_BANKED_ARRAY(v)
Definition ugbc.h:3718
#define CRITICAL_ASC_UNSUPPORTED(v, t)
Definition ugbc.h:3473
#define VT_OPTIMAL_SHIFT(s)
Definition ugbc.h:604
#define CRITICAL_STRING_UNSUPPORTED(v, t)
Definition ugbc.h:3467
@ MAT_RAM
Definition ugbc.h:726
#define CRITICAL_VARIABLE_UNDEFINED(f)
Definition ugbc.h:3602
#define CRITICAL_VARIABLE_CANNOT_DIRECT_ASSIGN_WRONG_TYPE(v, t)
Definition ugbc.h:3741
#define CRITICAL_IMAGE_CONVERTER_INVALID_OFFSET_X(x)
Definition ugbc.h:3528
#define FONT_SCHEMA_STANDARD
Definition ugbc.h:578
#define CRITICAL_CANNOT_OPEN_FILE(f, n)
Definition ugbc.h:3756
#define MAX_ARRAY_DIMENSIONS
Definition ugbc.h:566
#define VT_ESIGN_32BIT(t, v)
Definition ugbc.h:653
#define CRITICAL_BIT_UNSUPPORTED(v, t)
Definition ugbc.h:3489
#define CRITICAL_CANNOT_SWAP_DIFFERENT_DATATYPES(v1, v2)
Definition ugbc.h:3747
#define CRITICAL_LINE_NUMBER_ALREADY_DEFINED(n)
Definition ugbc.h:3674
#define CRITICAL_NOT_ARRAY(v)
Definition ugbc.h:3480
#define CRITICAL_MUL2_UNSUPPORTED(v, t)
Definition ugbc.h:3460
#define done()
Definition ugbc.h:4389
#define CRITICAL_CANNOT_MOVE_BIT_ON_BANKED_ARRAY(v)
Definition ugbc.h:3719
#define CRITICAL_CANNOT_REMOVE_FILE(f, n)
Definition ugbc.h:3582
#define UNIQUE_ID
Definition ugbc.h:3349
@ CT_STRING
Definition ugbc.h:789
@ CT_INTEGER
Definition ugbc.h:788
#define VT_MIN(t)
Definition ugbc.h:665
#define CRITICAL_ARRAY_OUT_OF_BOUND(a)
Definition ugbc.h:3810
#define CRITICAL_FILE_NOT_FOUND(n)
Definition ugbc.h:3825
#define CRITICAL_CANNOT_USE_FIELD_ON_NONTYPE(n)
Definition ugbc.h:3833
#define CRITICAL_PUT_IMAGE_NAMED_TILE_MISSING_TILESET(v)
Definition ugbc.h:3634
struct _Variable Variable
Structure of a single variable.
struct _Pattern Pattern
#define CRITICAL_CANNOT_USE_STRINGS_LONGER_256_CHARS()
Definition ugbc.h:3733
#define CRITICAL_CANNOT_MOVE_FROM_BIT_ON_BANKED_ARRAY(v)
Definition ugbc.h:3721
#define CRITICAL_CHR_UNSUPPORTED(v, t)
Definition ugbc.h:3472
#define CRITICAL_CANNOT_COPY_TO_BANKED(v)
Definition ugbc.h:3711
#define CRITICAL_CANNOT_CAST_TILEMAP_SIZE(v)
Definition ugbc.h:3643
#define CRITICAL_FILENAME_INVALID_COLON(v)
Definition ugbc.h:3573
#define CRITICAL_IMAGE_CONVERTER_INVALID_HEIGHT(h, m)
Definition ugbc.h:3507
struct _Type Type
#define CRITICAL_VARIABLE_IMPORTED_DIFFERENT_TYPE(f)
Definition ugbc.h:3599
#define WARNING_BITWIDTH(v1, v2)
Definition ugbc.h:3876
struct _Environment Environment
Structure of compilation environment.
struct _MemoryArea MemoryArea
#define CRITICAL_HEX2BIN_UNSUPPORTED_DATATYPE(v, s)
Definition ugbc.h:3858
#define parse_embedded(p, s)
Definition ugbc.h:4392
@ VT_DOJOKA
Definition ugbc.h:534
@ VT_TILE
Definition ugbc.h:504
@ VT_FLOAT
Definition ugbc.h:522
@ VT_TARRAY
Definition ugbc.h:480
@ VT_WORD
Definition ugbc.h:455
@ VT_POSITION
Definition ugbc.h:468
@ VT_NUMBER
Definition ugbc.h:549
@ VT_SDWORD
Definition ugbc.h:462
@ VT_MSPRITE
Definition ugbc.h:531
@ VT_STRING
Definition ugbc.h:474
@ VT_TILEMAP
Definition ugbc.h:525
@ VT_TILES
Definition ugbc.h:507
@ VT_SWORD
Definition ugbc.h:457
@ VT_BYTE
Definition ugbc.h:450
@ VT_DWORD
Definition ugbc.h:460
@ VT_BIT
Definition ugbc.h:528
@ VT_IMAGEREF
Definition ugbc.h:537
@ VT_VECTOR2
Definition ugbc.h:543
@ VT_CHAR
Definition ugbc.h:498
@ VT_BUFFER
Definition ugbc.h:477
@ VT_SPRITE
Definition ugbc.h:501
@ VT_SBYTE
Definition ugbc.h:452
@ VT_IMAGES
Definition ugbc.h:495
@ VT_MUSIC
Definition ugbc.h:516
@ VT_TYPE
Definition ugbc.h:546
@ VT_ADDRESS
Definition ugbc.h:465
@ VT_COLOR
Definition ugbc.h:471
@ VT_TILESET
Definition ugbc.h:510
@ VT_DSTRING
Definition ugbc.h:483
@ VT_PATH
Definition ugbc.h:540
@ VT_IMAGE
Definition ugbc.h:489
@ VT_SEQUENCE
Definition ugbc.h:513
#define PATH_SEPARATOR_AS_STRING
Definition ugbc.h:70
@ GAMMA_CORRECTION_TYPE2
Definition ugbc.h:324
@ GAMMA_CORRECTION_NONE
Definition ugbc.h:318
@ GAMMA_CORRECTION_TYPE1
Definition ugbc.h:321
#define CRITICAL_CANNOT_CAST(t1, t2)
Definition ugbc.h:3448
struct _OffsettingVariable OffsettingVariable
#define CRITICAL_LEN_UNSUPPORTED(v, t)
Definition ugbc.h:3474
#define CRITICAL_OR_UNSUPPORTED(v, t)
Definition ugbc.h:3524
#define FONT_SCHEMA_ALPHA
Definition ugbc.h:581
struct _Constant Constant
Structure of a single constant.
#define CRITICAL_PUT_IMAGE_NAMED_TILE_NOT_FOUND(v)
Definition ugbc.h:3636
#define MAX_PALETTE
Definition ugbc.h:568
#define CRITICAL_CANNOT_MOVE_STRING_ON_BANKED_ARRAY(v)
Definition ugbc.h:3720
#define CRITICAL_CANNOT_COMPARE_SID_FILE(f)
Definition ugbc.h:3803
#define CRITICAL_STORAGE_BANKED_UNCOMPATIBLE(v)
Definition ugbc.h:3717
#define CRITICAL_CANNOT_WRITE_FILE(f, n)
Definition ugbc.h:3758
#define CRITICAL_VARIABLE_ALREADY_DEFINED_AS_CONSTANT(f)
Definition ugbc.h:3584
#define CRITICAL_IMAGE_CONVERTER_INVALID_WIDTH(w, m)
Definition ugbc.h:3506
#define CRITICAL_STR_UNSUPPORTED(v, t)
Definition ugbc.h:3470
#define CRITICAL_MOVE_NAKED_UNSUPPORTED(t)
Definition ugbc.h:3451
#define CRITICAL_RESOURCE_LOAD_MISSING_FILE(f)
Definition ugbc.h:3633
#define CRITICAL_FILENAME_INVALID_BACKSLASH(v)
Definition ugbc.h:3574
#define CRITICAL_SWAP_DIFFERENT_BITWIDTH(v)
Definition ugbc.h:3581
#define CRITICAL_LEFT_UNSUPPORTED(v, t)
Definition ugbc.h:3463
#define VT_MAX_BITWIDTH_TYPE(a, b)
Definition ugbc.h:606
#define CRITICAL_CONSTANT_REDEFINED_DIFFERENT_TYPE(f)
Definition ugbc.h:3600
#define CRITICAL_CONSTANT_REDEFINED_DIFFERENT_VALUE(f)
Definition ugbc.h:3601
#define VT_SIGN(t)
Definition ugbc.h:633
@ FT_FAST
Definition ugbc.h:854
@ FT_SINGLE
Definition ugbc.h:855
enum _FloatTypePrecision FloatTypePrecision
#define CRITICAL_DIV_UNSUPPORTED(v, t)
Definition ugbc.h:3458
#define CRITICAL_UNKNOWN_TYPE(n)
Definition ugbc.h:3832
#define CRITICAL_LOWER_UNSUPPORTED(v, t)
Definition ugbc.h:3469
@ BT_VARIABLES
Definition ugbc.h:126
@ BT_TEMPORARY
Definition ugbc.h:129
#define CRITICAL_SWAP_UNSUPPORTED(v, t)
Definition ugbc.h:3622
#define CRITICAL_MUL2_INVALID_STEPS(v)
Definition ugbc.h:3509
#define CRITICAL_CANNOT_CAST_FLOAT_PRECISION(v1, v2)
Definition ugbc.h:3621
#define CRITICAL_XOR_INPLACE_UNSUPPORTED(v, t)
Definition ugbc.h:3759
#define CRITICAL_BUFFER_SIZE_MISMATCH(v1, v2)
Definition ugbc.h:3452
#define outline0(s)
Definition ugbc.h:4252
struct _StaticString StaticString
Structure of a single (static) string.
#define CRITICAL_IMAGE_CONVERTER_INVALID_FRAME_WIDTH(w, m)
Definition ugbc.h:3526
struct _FileStorage FileStorage
Structure of a single file inside a storage.
#define VT_SIGN_16BIT(v)
Definition ugbc.h:648
#define VT_ESIGN_8BIT(t, v)
Definition ugbc.h:651
struct _TileDescriptor TileDescriptor
#define CRITICAL_VARIABLE_CANNOT_DIRECT_ASSIGN_DIFFERENT_TYPE(t1, t2)
Definition ugbc.h:3698
#define CRITICAL_SUB_INPLACE_UNSUPPORTED(v, t)
Definition ugbc.h:3547
#define CRITICAL_MUL_UNSUPPORTED(v, t)
Definition ugbc.h:3457
struct _Label Label
Structure of a single label.
#define CRITICAL_DATATYPE_UNSUPPORTED(k, v)
Definition ugbc.h:3447
#define BUILD_TOOLCHAIN_ASM6809_GET_EXECUTABLE(_environment, executableName)
Definition ugbc.h:4855
#define CRITICAL_PUT_IMAGE_NAMED_TILE_MISSING_TILES_FROM_TILESET(v)
Definition ugbc.h:3635
#define CRITICAL_CANNOT_CAST_BUFFER_STRING_SIZE(a, b)
Definition ugbc.h:3499
#define CRITICAL_ADD_INPLACE_UNSUPPORTED(v, t)
Definition ugbc.h:3546
#define CRITICAL_FILE_CSV_NOT_ENOUGH_DATA(n)
Definition ugbc.h:3836
#define CRITICAL_CANNOT_CAST_FLOAT_32BIT_UNSIGNED(v)
Definition ugbc.h:3726
enum _VariableType VariableType
Type of variables.
#define CRITICAL_INSTR_UNSUPPORTED(v, t)
Definition ugbc.h:3466
#define TRACE0(s)
Definition ugbc.h:86
#define VT_DIRECT_ASSIGN(t)
Definition ugbc.h:683
#define CRITICAL_DIV2_UNSUPPORTED(v, t)
Definition ugbc.h:3461
#define outline1(s, a)
Definition ugbc.h:4253
#define WARNING_USE_OF_UNDEFINED_ARRAY(v1)
Definition ugbc.h:3879
#define CRITICAL_VAL_UNSUPPORTED(v, t)
Definition ugbc.h:3471
#define adilinepalette(s, c, p)
Definition ugbc.h:4219
#define CRITICAL(s)
Definition ugbc.h:3399
#define PROTOTHREAD_DEFAULT_COUNT
Definition ugbc.h:573
struct _DataSegment DataSegment
#define VT_BITWIDTH(t)
Definition ugbc.h:595
#define FONT_SCHEMA_ASCII
Definition ugbc.h:582
#define CRITICAL_PUT_IMAGE_NAMED_TILE_INVALID_PROBABILITY(v)
Definition ugbc.h:3637
#define CRITICAL_CANNOT_STORE_FILE_ON_VARIABLE_OF_DIFFERENT_TYPE(v)
Definition ugbc.h:3694
struct _Bank Bank
Structure of a single bank.
#define CRITICAL_HEX_UNSUPPORTED(v, t)
Definition ugbc.h:3548
#define CRITICAL2(s, v)
Definition ugbc.h:3405
#define CRITICAL_CANNOT_FLIP(s)
Definition ugbc.h:3853
#define UGBASIC_VERSION
Definition ugbc.h:63
#define CRITICAL_ADD_UNSUPPORTED(v, t)
Definition ugbc.h:3454
#define CRITICAL_ARRAY_SIZE_MISMATCH(v, d1, d2)
Definition ugbc.h:3479
struct _CopperList CopperList
#define TRACE2(s, p1, p2)
Definition ugbc.h:88
#define CRITICAL_AND_UNSUPPORTED(v, t)
Definition ugbc.h:3462
#define CRITICAL_PUT_IMAGE_UNINITIALIZED(v)
Definition ugbc.h:3700
#define CRITICAL_VARIABLE(v)
Definition ugbc.h:3446
#define CRITICAL_COMPLEMENT_UNSUPPORTED(v, t)
Definition ugbc.h:3456
struct _TileData TileData
@ DI_TSB
Definition ugbc.h:98
@ DI_UGBASIC
Definition ugbc.h:96
#define MAKE_LABEL
Definition ugbc.h:3351
struct _Procedure Procedure
#define CRITICAL_STORE_UNSUPPORTED(t)
Definition ugbc.h:3449
#define CRITICAL_RIGHT_UNSUPPORTED(v, t)
Definition ugbc.h:3464
#define CRITICAL_CANNOT_COMPARE_CONST(t)
Definition ugbc.h:3682
#define CRITICAL_NOT_UNSUPPORTED(v, t)
Definition ugbc.h:3525
void show_usage_and_exit(int _argc, char *_argv[])
Show usage and exit.
Definition ugbc.tab.c:53855
char OUTPUT_FILE_TYPE_AS_STRING[][16]
char DATATYPE_AS_STRING[][16]
char * importPath
Definition ugbc.tab.c:250
@ PINK
Definition ugbc.tab.h:655
@ BROWN
Definition ugbc.tab.h:176
@ PURPLE
Definition ugbc.tab.h:692
@ WHITE
Definition ugbc.tab.h:941
@ BLUE
Definition ugbc.tab.h:163
@ GREY
Definition ugbc.tab.h:432
@ MAGENTA
Definition ugbc.tab.h:533
@ LAVENDER
Definition ugbc.tab.h:510
@ VIOLET
Definition ugbc.tab.h:926
@ GREEN
Definition ugbc.tab.h:431
@ GOLD
Definition ugbc.tab.h:422
@ CYAN
Definition ugbc.tab.h:281
@ PEACH
Definition ugbc.tab.h:642
@ TAN
Definition ugbc.tab.h:846
@ ORANGE
Definition ugbc.tab.h:615
@ TURQUOISE
Definition ugbc.tab.h:886
@ YELLOW
Definition ugbc.tab.h:961
@ BLACK
Definition ugbc.tab.h:159
@ RED
Definition ugbc.tab.h:713
char targetName[]
Variable * vector_get_x(Environment *_environment, char *_vector)
Variable * vector_get_y(Environment *_environment, char *_vector)