ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
wait_cycles.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
49/* <usermanual>
50@keyword WAIT
51
52@english
53
54Pauses execution for a certain period of time. The ''WAIT'' statement can be
55accompanied by a suffix statement, which indicates the unit of measurement of
56the time to wait. The suffix ''CYCLES'' can be used to indicate CPU cycles,
57''TICKS'' to indicate the number of vertical blanks at 50Hz (PAL) or 60Hz (NTSC),
58and ''MS'' (''MILLISECONDS'') to indicate a number of milliseconds.
59
60The pause is of the "busy" type, so the entire program is suspended, except for
61the timer-related mechanisms. The multhtireading mechanism, instead, will continue
62to run. Note that the maximum duration you can expect is 65535 milliseconds, or
63approximately 65.5 seconds.
64
65The ''PARALLEL'' keyword can only be used with waits related to ''CYCLES''.
66
67@italian
68
69Interrompe l'esecuzione per un certo periodo di tempo. L'istruzione ''WAIT'' può
70essere corredata da una istruzione suffisso, che si occupa di indicare l'unità di
71misura del tempo da attendere. Si può usare il suffisso ''CYCLES'' per indicare
72cicli di CPU, ''TICKS'' per indicare il numero di blank verticali a 50Hz (PAL)
73o 60Hz (NTSC), e ''MS'' (''MILLISECONDS'') per indicare un numero di millisecondi.
74
75The pause is of the "busy" type, so the entire program is suspended, except for
76the timer-related mechanisms. The multhtireading mechanism, instead, will continue
77to run. Note that the maximum duration you can expect is 65535 milliseconds, or
78approximately 65.5 seconds.
79
80La parola chiave ''PARALLEL'' può essere usata solo con attese legate ai ''CYCLES''.
81
82Notare che esiste una variante di questo comando, che funziona solo all'interno
83delle copper list. Il comando è ''WAIT'' e permette di attendere l'arrivo di una
84specifica posizione del pennello video.
85
86@syntax WAIT cycles [CYCLES] [PARALLEL]
87@syntax WAIT ticks TICK
88@syntax WAIT ticks TICKS
89@syntax WAIT time MILLISECOND
90@syntax WAIT time MILLISECONDS
91@syntax WAIT time MS
92
93@example WAIT #42 CYCLES
94@usedInExample control_uncond_jumps_01.bas
95@usedInExample control_uncond_jumps_02.bas
96@usedInExample control_returning_01.bas
97@usedInExample control_returning_02.bas
98
99@seeAlso SLEEP
100
101@target all
102</usermanual> */
103void wait_cycles( Environment * _environment, int _timing, int _parallel ) {
104
105 if ( _environment->protothread && _environment->procedureName && _parallel ) {
106
107 if ( _environment->protothreadForbid ) {
109 }
110
111 char waitVariableName[MAX_TEMPORARY_STORAGE]; sprintf(waitVariableName, "%swaitms%d", _environment->procedureName, _environment->protothreadStep );
112
114 memset( ((struct _Environment *)_environment)->arrayDimensionsEach, 0, sizeof( int ) * MAX_ARRAY_DIMENSIONS );
115 ((struct _Environment *)_environment)->arrayDimensionsEach[0] = _environment->protothreadConfig.count;
116 ((struct _Environment *)_environment)->arrayDimensions = 1;
117 variable_define( _environment, waitVariableName, VT_TARRAY, 0 );
118 variable_array_type( _environment, waitVariableName, VT_WORD );
120
121 variable_store_array_const( _environment, waitVariableName, _timing );
122
123 yield( _environment );
124
125 char protothreadLabel[MAX_TEMPORARY_STORAGE]; sprintf(protothreadLabel, "%spt%d", _environment->procedureName, _environment->protothreadStep );
126
127 variable_decrement_mt( _environment, waitVariableName );
128 Variable * result = variable_temporary( _environment, VT_WORD, "(temporary)" );
129 variable_move_from_mt( _environment, waitVariableName, result->name );
130 variable_compare_and_branch_const( _environment, result->name, 0, protothreadLabel, 1 );
131
132 cpu_protothread_save( _environment, "PROTOTHREADCT", ( _environment->protothreadStep - 1 ) );
133 cpu_protothread_set_state( _environment, "PROTOTHREADCT", PROTOTHREAD_STATUS_YIELDED );
134 cpu_return( _environment );
135
136 cpu_label( _environment, protothreadLabel );
137 cpu_protothread_set_state( _environment, "PROTOTHREADCT", PROTOTHREAD_STATUS_RUNNING );
138
139 ++_environment->protothreadStep;
140
141 } else {
142
143 char timingString[MAX_TEMPORARY_STORAGE]; sprintf(timingString, "#$%2.2x", _timing );
144
145 cpu_busy_wait( _environment, timingString );
146
147 }
148
149}
150
159void wait_cycles_var( Environment * _environment, char * _timing, int _parallel ) {
160
162
163 Variable * timing = variable_retrieve( _environment, _timing );
164
165 if ( _environment->protothread && _environment->procedureName && _parallel) {
166
167 char waitVariableName[MAX_TEMPORARY_STORAGE]; sprintf(waitVariableName, "%swaitms%d", _environment->procedureName, _environment->protothreadStep );
168
170 memset( ((struct _Environment *)_environment)->arrayDimensionsEach, 0, sizeof( int ) * MAX_ARRAY_DIMENSIONS );
171 ((struct _Environment *)_environment)->arrayDimensionsEach[0] = _environment->protothreadConfig.count;
172 ((struct _Environment *)_environment)->arrayDimensions = 1;
173 variable_define( _environment, waitVariableName, VT_TARRAY, 0 );
174 variable_array_type( _environment, waitVariableName, VT_WORD );
176
177 variable_move_to_mt( _environment, _timing, waitVariableName );
178
179 yield( _environment );
180
181 char protothreadLabel[MAX_TEMPORARY_STORAGE]; sprintf(protothreadLabel, "%spt%d", _environment->procedureName, _environment->protothreadStep );
182
183 variable_decrement_mt( _environment, waitVariableName );
184 Variable * result = variable_temporary( _environment, VT_WORD, "(temporary)" );
185 variable_move_from_mt( _environment, waitVariableName, result->name );
186 variable_compare_and_branch_const( _environment, result->name, 0, protothreadLabel, 1 );
187
188 cpu_protothread_save( _environment, "PROTOTHREADCT", ( _environment->protothreadStep - 1 ) );
189 cpu_protothread_set_state( _environment, "PROTOTHREADCT", PROTOTHREAD_STATUS_YIELDED );
190 cpu_return( _environment );
191
192 cpu_label( _environment, protothreadLabel );
193 cpu_protothread_set_state( _environment, "PROTOTHREADCT", PROTOTHREAD_STATUS_RUNNING );
194
195 ++_environment->protothreadStep;
196
197
198 } else {
199
200 cpu_busy_wait( _environment, timing->realName );
201
202 }
203
204}
void cpu_protothread_save(Environment *_environment, char *_index, int _step)
Definition 6309.c:6203
void cpu_protothread_set_state(Environment *_environment, char *_index, int _state)
Definition 6309.c:6226
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_return(Environment *_environment)
Definition 6309.c:4030
void cpu_busy_wait(Environment *_environment, char *_timing)
Definition 6309.c:4183
Variable * variable_retrieve(Environment *_environment, char *_name)
void variable_compare_and_branch_const(Environment *_environment, char *_source, int _destination, char *_name, int _positive)
Variable * variable_array_type(Environment *_environment, char *_name, VariableType _type)
Variable * variable_move_from_mt(Environment *_environment, char *_source, char *_destination)
Increment a variable by one.
void variable_store_array_const(Environment *_environment, char *_array, int _value)
Variable * variable_define(Environment *_environment, char *_name, VariableType _type, int _value)
Define a variable for the program.
Variable * variable_move_to_mt(Environment *_environment, char *_source, char *_destination)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
void variable_decrement_mt(Environment *_environment, char *_source)
Decrement a variable by one.
void wait_cycles_var(Environment *_environment, char *_timing, int _parallel)
Emit ASM code for WAIT [expression] CYCLES.
void wait_cycles(Environment *_environment, int _timing, int _parallel)
Emit ASM code for WAIT # [integer] CYCLES.
Definition wait_cycles.c:49
Structure of compilation environment.
Definition ugbc.h:2269
int protothread
Definition ugbc.h:2830
int arrayDimensions
Definition ugbc.h:2718
int protothreadStep
Definition ugbc.h:2840
int arrayDimensionsEach[MAX_ARRAY_DIMENSIONS]
Definition ugbc.h:2723
ProtothreadConfig protothreadConfig
Definition ugbc.h:2430
char * procedureName
Definition ugbc.h:2775
int protothreadForbid
Definition ugbc.h:2845
char * name
Definition ugbc.h:979
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define MAX_ARRAY_DIMENSIONS
Definition ugbc.h:566
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_TARRAY
Definition ugbc.h:480
@ VT_WORD
Definition ugbc.h:455
#define PROTOTHREAD_STATUS_YIELDED
Definition ugbc.h:4548
#define CRITICAL_MULTITASKING_FORBIDDEN()
Definition ugbc.h:3703
#define PROTOTHREAD_STATUS_RUNNING
Definition ugbc.h:4547
#define MAKE_LABEL
Definition ugbc.h:3351
void yield(Environment *_environment)
Emit code for YIELD.
Definition yield.c:63