ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
restore.c
Go to the documentation of this file.
1/*****************************************************************************
2 * ugBASIC - an isomorphic BASIC language compiler for retrocomputers *
3 *****************************************************************************
4 * Copyright 2021-2026 Marco Spedaletti (asimov@mclink.it)
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *----------------------------------------------------------------------------
18 * Concesso in licenza secondo i termini della Licenza Apache, versione 2.0
19 * (la "Licenza"); è proibito usare questo file se non in conformità alla
20 * Licenza. Una copia della Licenza è disponibile all'indirizzo:
21 *
22 * http://www.apache.org/licenses/LICENSE-2.0
23 *
24 * Se non richiesto dalla legislazione vigente o concordato per iscritto,
25 * il software distribuito nei termini della Licenza è distribuito
26 * "COSÌ COM'È", SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o
27 * implicite. Consultare la Licenza per il testo specifico che regola le
28 * autorizzazioni e le limitazioni previste dalla medesima.
29 ****************************************************************************/
30
31/****************************************************************************
32 * INCLUDE SECTION
33 ****************************************************************************/
34
35#include "../../ugbc.h"
36
37/****************************************************************************
38 * CODE SECTION
39 ****************************************************************************/
40
41/* <usermanual>
42@keyword RESTORE
43
44@english
45
46The ''RESTORE'' command is used to reset the data read pointer to the beginning
47of a list of ''DATA''. Imagine having a cassette tape with numbers on it, and
48you want to read those numbers one at a time. When you use ''RESTORE'', it's as
49if you're rewinding the tape to the beginning, ready to read all the numbers again.
50
51When the program encounters this command, the data read pointer is automatically
52reset to the beginning of the first data list you defined. If you give a ''parameter'',
53you can set the pointer to the label given.
54
55The ''RESTORE'' command is especially useful when you want to reuse a list of data.
56If you need to read the same data multiple times in your program, you can use
57''RESTORE'' to reset the pointer to the beginning of the list without having to
58retype it. If you want to read only part of the data, you can use ''RESTORE'' to
59skip parts of the list and start reading from a specific point. If you want to
60create loops that read the data, by combining ''RESTORE'' with other commands
61such as ''READ'' and ''DATA'', you can create loops that repeatedly read
62the same data.
63
64@italian
65
66Il comando ''RESTORE'' viene utilizzato per reimpostare il puntatore di lettura
67dei dati all'inizio di un elenco di ''DATA''. Immagina di avere una cassetta con dei
68numeri e di voler leggere quei numeri uno alla volta. Quando utilizzi ''RESTORE'',
69è come se stessi riavvolgendo il nastro all'inizio, pronto per leggere di nuovo
70tutti i numeri.
71
72Quando il programma incontra questo comando, il puntatore di lettura dei dati viene
73automaticamente reimpostato all'inizio del primo elenco di dati che hai definito.
74Se fornisci un ''label'', puoi impostare il puntatore all'etichetta specificata.
75
76Il comando ''RESTORE'' è particolarmente utile quando vuoi riutilizzare un
77elenco di dati. Se hai bisogno di leggere gli stessi dati più volte nel tuo
78programma, puoi utilizzare ''RESTORE'' per reimpostare il puntatore all'inizio
79dell'elenco senza doverlo digitare di nuovo. Se vuoi leggere solo una parte dei dati,
80puoi utilizzare ''RESTORE'' per saltare parti dell'elenco e iniziare la lettura da un
81punto specifico. Se vuoi creare loop che leggono i dati, combinando ''RESTORE'' con altri
82comandi come ''READ'' e ''DATA'', puoi creare loop che leggono ripetutamente gli stessi dati.
83
84@syntax RESTORE label
85
86@example RESTORE inizio
87
88@usedInExample data_example_03.bas
89
90@seeAlso READ
91@seeAlso DATA
92
93</usermanual> */
94
95void restore_label( Environment * _environment, char * _label ) {
96
97 if ( !_label || label_exists_named( _environment, _label ) ) {
98
99 DataSegment * data;
100
101 if ( _label ) {
102 data = data_segment_define_or_retrieve( _environment, _label );
103 } else {
104 data = data_segment_define_or_retrieve( _environment, "DATA" );
105 }
106
107 if ( !data ) {
109 }
110
111 Variable * dataptr = variable_retrieve( _environment, "DATAPTR" );
112
113#if defined(__c64reu__)
114 cpu_store_16bit( _environment, dataptr->realName, data->absoluteAddress );
115#else
116 cpu_addressof_16bit( _environment, data->realName, dataptr->realName );
117#endif
118
119 restore_label_unsafe( _environment, _label );
120
121 } else {
122
124
125 char searchDataSegmentLabel[MAX_TEMPORARY_STORAGE]; sprintf( searchDataSegmentLabel, "%ssearch", label );
126 char doneDataSegmentLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneDataSegmentLabel, "%sdone", label );
127
128 _environment->restoreDynamic = 1;
129
130 Variable * variable = variable_retrieve_or_define( _environment, _label, VT_WORD, 0 );
131 Variable * dataptr = variable_retrieve( _environment, "DATAPTR" );
132 Variable * lineNumber = variable_temporary( _environment, VT_WORD, "(line number)");
133 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address)");
134
135 if ( VT_BITWIDTH( variable->type ) > 1 ) {
136
137 cpu_addressof_16bit( _environment, "DATASEGMENTNUMERIC", dataptr->realName );
138
139 cpu_label( _environment, searchDataSegmentLabel );
140
141 cpu_move_16bit_indirect2( _environment, dataptr->realName, lineNumber->realName );
142 cpu_inc_16bit( _environment, dataptr->realName );
143 cpu_inc_16bit( _environment, dataptr->realName );
144 cpu_move_16bit_indirect2( _environment, dataptr->realName, address->realName );
145 cpu_inc_16bit( _environment, dataptr->realName );
146 cpu_inc_16bit( _environment, dataptr->realName );
147 cpu_compare_and_branch_16bit( _environment, lineNumber->realName, variable->realName, doneDataSegmentLabel, 1 );
148 cpu_compare_and_branch_16bit_const( _environment, lineNumber->realName, 0xffff, doneDataSegmentLabel, 1 );
149
150 cpu_jump( _environment, searchDataSegmentLabel );
151
152 cpu_label( _environment, doneDataSegmentLabel );
153
154 variable_move( _environment, address->name, dataptr->name );
155
156 } else {
158 }
159
160 restore_label_unsafe( _environment, NULL );
161
162 }
163
164}
165
166
void cpu_store_16bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 16 bit
Definition 6309.c:1503
void cpu_addressof_16bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:1485
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_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_move_16bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition 6309.c:5352
void cpu_jump(Environment *_environment, char *_label)
Definition 6309.c:3739
void cpu_compare_and_branch_16bit(Environment *_environment, char *_source, char *_destination, char *_label, int _positive)
Definition 6309.c:1552
void cpu_inc_16bit(Environment *_environment, char *_variable)
Definition 6309.c:4565
Variable * variable_retrieve(Environment *_environment, char *_name)
Variable * variable_retrieve_or_define(Environment *_environment, char *_name, VariableType _type, int _value)
DataSegment * data_segment_define_or_retrieve(Environment *_environment, char *_name)
Variable * variable_move(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable by converting it.
int label_exists_named(Environment *_environment, char *_label)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
void restore_label_unsafe(Environment *_environment, char *_label)
void restore_label(Environment *_environment, char *_label)
Definition restore.c:95
int restoreDynamic
Definition ugbc.h:2573
char * name
Definition ugbc.h:979
VariableType type
Definition ugbc.h:988
char * realName
Definition ugbc.h:982
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_WORD
Definition ugbc.h:455
@ VT_ADDRESS
Definition ugbc.h:465
#define CRITICAL_RESTORE_WITH_UNSUPPORTED_DATA_TYPE(t)
Definition ugbc.h:3686
#define CRITICAL_RESTORE_WITHOUT_DATA(v)
Definition ugbc.h:3679
struct _DataSegment DataSegment
#define VT_BITWIDTH(t)
Definition ugbc.h:595
#define MAKE_LABEL
Definition ugbc.h:3351