ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
_banks.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
41extern char DATATYPE_AS_STRING[][16];
42
43void banks_init_extended( Environment * _environment, int * _allowed, int _allowed_count, int _allowed_size ) {
44
45 _environment->expansionBanks = NULL;
46
47 for(int i=0; i<_allowed_count; ++i) {
48 Bank * bank = malloc( sizeof( Bank ) );
49 bank->address = 0x0;
50 bank->filename = NULL;
51 bank->id = _allowed[i];
52 char bankName[MAX_TEMPORARY_STORAGE]; sprintf( bankName, "BANK%2.2x", _allowed[i] );
53 bank->name = strdup( bankName );
54 bank->type = BT_EXPANSION;
55 bank->remains = _allowed_size;
56 bank->space = _allowed_size;
58 bank->next = _environment->expansionBanks;
59 bank->data = malloc( _allowed_size );
60 bank->defaultResident = 1;
61 memset( bank->data, 0, _allowed_size );
62 _environment->expansionBanks = bank;
63 _environment->maxExpansionBankSize[i+1] = 0;
64 }
65
66}
67
68void banks_init( Environment * _environment ) {
69
70 _environment->expansionBanks = NULL;
71
72 for(int i=-1; i<BANK_COUNT; ++i) {
73 Bank * bank = malloc( sizeof( Bank ) );
74 bank->address = 0x0;
75 bank->filename = NULL;
76 bank->id = i+1;
77 char bankName[MAX_TEMPORARY_STORAGE]; sprintf( bankName, "BANK%2.2x", i+1 );
78 bank->name = strdup( bankName );
79 bank->type = BT_EXPANSION;
80 bank->remains = BANK_SIZE;
81 bank->space = BANK_SIZE;
83 bank->next = _environment->expansionBanks;
84 bank->data = malloc( BANK_SIZE );
85 bank->defaultResident = 1;
86 memset( bank->data, 0, BANK_SIZE );
87 _environment->expansionBanks = bank;
88 _environment->maxExpansionBankSize[i+1] = 0;
89 }
90
91}
92
93int banks_any_used( Environment * _environment ) {
94
95 Bank * bank = _environment->expansionBanks;
96 while( bank ) {
97 if ( bank->type == BT_EXPANSION && bank->name && ( bank->space != bank->remains ) ) {
98 return 1;
99 }
100 bank = bank->next;
101 }
102
103 return 0;
104
105}
106
107int banks_get_default_resident( Environment * _environment, int _bank ) {
108
109 Bank * bank = _environment->expansionBanks;
110 while( bank ) {
111 if ( bank->type == BT_EXPANSION && bank->id == _bank ) {
112 return bank->defaultResident;
113 }
114 bank = bank->next;
115 }
116
117 return 1;
118
119}
120
121char * banks_get_address( Environment * _environment, int _bank ) {
122
123 Variable * bankAddress = variable_temporary( _environment, VT_ADDRESS, "(address)" );
124
125 if ( banks_any_used( _environment ) ) {
126
127 Bank * bank = _environment->expansionBanks;
128
129 while( bank ) {
130 if ( bank->id == _bank ) {
131 break;
132 }
133 bank = bank->next;
134 }
135
136 if ( ! bank ) {
138 }
139
140 if ( bank->bankAddress ) {
141 variable_store( _environment, bankAddress->name, bank->bankAddress );
142 } else {
143 cpu_addressof_16bit( _environment, bank->name, bankAddress->realName );
144 }
145
146 }
147
148 return bankAddress->realName;
149
150}
151
152Variable * banks_get_address_var( Environment * _environment, char * _bank ) {
153
154 Variable * bankAddress = variable_temporary( _environment, VT_ADDRESS, "(address)" );
155
156 if ( banks_any_used( _environment ) ) {
157
158 Variable * bank = variable_retrieve_or_define( _environment, _bank, VT_WORD, 0 );
159
160 cpu_address_table_call( _environment, "EXPBANKS", bank->realName, bankAddress->realName );
161
162 return bankAddress;
163
164 } else {
165 return bankAddress;
166 }
167
168}
169
170int banks_store( Environment * _environment, Variable * _variable, int _resident ) {
171
172 Bank * bank = _environment->expansionBanks;
173
174 while( bank ) {
175 if ( bank->remains > _variable->size ) {
176 break;
177 }
178 bank = bank->next;
179 }
180
181 if ( ! bank ) {
182 return 0;
183 }
184
185 memory_area_unassign( _environment->memoryAreas, _variable );
186
187 _variable->bankAssigned = bank->id;
188 _variable->absoluteAddress = bank->baseAddress + bank->address;
189 _variable->residentAssigned = _resident;
191 _variable->bankReadOrWrite = 1;
192
193 if ( _variable->valueBuffer ) {
194 memcpy( &bank->data[bank->address], _variable->valueBuffer, _variable->size );
195 } else {
196 if ( _variable->value ) {
197 if ( _variable->type == VT_TARRAY ) {
198 switch( VT_BITWIDTH( _variable->arrayType ) ) {
199 case 32: {
200 for( int i=0; i<(_variable->size); i+=4 ) {
201#ifdef CPU_BIG_ENDIAN
202 bank->data[bank->address+i] = ( ( _variable->value >> 24 ) & 0xff );
203 bank->data[bank->address+i+1] = ( ( _variable->value >> 16 ) & 0xff );
204 bank->data[bank->address+i+2] = ( ( _variable->value >> 8 ) & 0xff );
205 bank->data[bank->address+i+3] = ( _variable->value & 0xff );
206#else
207 bank->data[bank->address+i+3] = ( ( _variable->value >> 24 ) & 0xff );
208 bank->data[bank->address+i+2] = ( ( _variable->value >> 16 ) & 0xff );
209 bank->data[bank->address+i+1] = ( ( _variable->value >> 8 ) & 0xff );
210 bank->data[bank->address+i] = ( _variable->value & 0xff );
211#endif
212 }
213 break;
214 }
215 case 16: {
216 for( int i=0; i<(_variable->size); i+=2 ) {
217#ifdef CPU_BIG_ENDIAN
218 bank->data[bank->address+i] = ( ( _variable->value >> 8 ) & 0xff );
219 bank->data[bank->address+i+1] = ( _variable->value & 0xff );
220#else
221 bank->data[bank->address+i] = ( _variable->value & 0xff );
222 bank->data[bank->address+i+1] = ( ( _variable->value >> 8 ) & 0xff );
223#endif
224 }
225 break;
226 }
227 case 8:
228 memset( &bank->data[bank->address], ( _variable->value & 0xff ), _variable->size );
229 break;
230 case 1:
231 memset( &bank->data[bank->address], ( _variable->value ? 0xff : 0x00), _variable->size );
232 break;
233 case 0:
235 }
236 } else {
237 switch( VT_BITWIDTH( _variable->type ) ) {
238 case 32: {
239 for( int i=0; i<(_variable->size); i+=4 ) {
240#ifdef CPU_BIG_ENDIAN
241 bank->data[bank->address+i] = ( ( _variable->value >> 24 ) & 0xff );
242 bank->data[bank->address+i+1] = ( ( _variable->value >> 16 ) & 0xff );
243 bank->data[bank->address+i+2] = ( ( _variable->value >> 8 ) & 0xff );
244 bank->data[bank->address+i+3] = ( _variable->value & 0xff );
245#else
246 bank->data[bank->address+i+3] = ( ( _variable->value >> 24 ) & 0xff );
247 bank->data[bank->address+i+2] = ( ( _variable->value >> 16 ) & 0xff );
248 bank->data[bank->address+i+1] = ( ( _variable->value >> 8 ) & 0xff );
249 bank->data[bank->address+i] = ( _variable->value & 0xff );
250#endif
251 }
252 break;
253 }
254 case 16: {
255 for( int i=0; i<(_variable->size); i+=2 ) {
256#ifdef CPU_BIG_ENDIAN
257 bank->data[bank->address+i] = ( _variable->value & 0xff );
258 bank->data[bank->address+i+1] = ( ( _variable->value >> 8 ) & 0xff );
259#else
260 bank->data[bank->address+i+1] = ( ( _variable->value >> 8 ) & 0xff );
261 bank->data[bank->address+i] = ( _variable->value & 0xff );
262#endif
263 }
264 break;
265 }
266 case 8:
267 memset( &bank->data[bank->address], ( _variable->value & 0xff ), _variable->size );
268 break;
269 case 1:
270 memset( &bank->data[bank->address], ( _variable->value ? 0xff : 0x00), _variable->size );
271 break;
272 case 0:
273 CRITICAL_DATATYPE_UNSUPPORTED( "BANKED", DATATYPE_AS_STRING[ _variable->type ] );
274 }
275
276 }
277 } else {
278 memset( &bank->data[bank->address], 0, _variable->size );
279 }
280 }
281
282 bank->address += _variable->size;
283 bank->remains -= _variable->size;
284
285 // Now we must calculate the effective size occupied by
286 // memory block, when it will be uncompressed. It is needed
287 // to have enough memory into the resident part of the
288 // memory. If uncompressed size is zero, it means that
289 // the memory block is not compressed -- so we can use the
290 // size as well.
291
292 if ( _variable->uncompressedSize ) {
293 if ( _environment->maxExpansionBankSize[_resident] < _variable->uncompressedSize ) {
294 _environment->maxExpansionBankSize[_resident] = _variable->uncompressedSize;
295 }
296 } else if ( _variable->frameSize ) {
297 if ( _environment->maxExpansionBankSize[_resident] < _variable->frameSize ) {
298 _environment->maxExpansionBankSize[_resident] = _variable->frameSize;
299 }
300 } else {
301 if ( _environment->maxExpansionBankSize[_resident] <_variable->size ) {
302 _environment->maxExpansionBankSize[_resident] = _variable->size;
303 }
304 }
305
306 return 1;
307
308}
309
311
312int banks_store_data( Environment * _environment, char * _data, int _size ) {
313
314 Bank * bank = _environment->expansionBanks;
315
316 while( bank ) {
317 if ( bank->remains == bank->space ) {
318 break;
319 }
320 bank = bank->next;
321 }
322
323 if ( ! bank ) {
324 return -1;
325 }
326
327 memcpy( &bank->data[0], _data, _size );
328
329 bank->address += _size;
330 bank->remains -= _size;
331
332 return bank->id;
333
334}
void cpu_addressof_16bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:1485
void cpu_address_table_call(Environment *_environment, char *_table, char *_value, char *_address)
Definition 6309.c:7374
void memory_area_unassign(MemoryArea *_first, Variable *_variable)
Variable * variable_retrieve_or_define(Environment *_environment, char *_name, VariableType _type, int _value)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
Variable * variable_store(Environment *_environment, char *_destination, unsigned int _value)
Store a direct value to a variable.
#define BANK_BASE_ADDRESS
Definition atari.h:147
#define BANK_COUNT
Definition atari.h:145
#define BANK_SIZE
Definition atari.h:146
int banks_store(Environment *_environment, Variable *_variable, int _resident)
Definition _banks.c:170
int banks_any_used(Environment *_environment)
Definition _banks.c:93
void banks_init(Environment *_environment)
Definition _banks.c:68
void banks_init_extended(Environment *_environment, int *_allowed, int _allowed_count, int _allowed_size)
Definition _banks.c:43
Variable * banks_get_address_var(Environment *_environment, char *_bank)
Definition _banks.c:152
int banks_get_default_resident(Environment *_environment, int _bank)
Definition _banks.c:107
int banks_store_data(Environment *_environment, char *_data, int _size)
Definition _banks.c:312
char * banks_get_address(Environment *_environment, int _bank)
Definition _banks.c:121
int remains
Definition ugbc.h:171
int address
Definition ugbc.h:159
int baseAddress
Definition ugbc.h:174
char * name
Definition ugbc.h:156
int id
Definition ugbc.h:153
struct _Bank * next
Definition ugbc.h:185
char * data
Definition ugbc.h:177
int defaultResident
Definition ugbc.h:182
int space
Definition ugbc.h:168
BankType type
Definition ugbc.h:162
int bankAddress
Definition ugbc.h:180
char * filename
Definition ugbc.h:165
int maxExpansionBankSize[MAX_RESIDENT_SHAREDS]
Definition ugbc.h:3010
Bank * expansionBanks
Definition ugbc.h:3005
MemoryArea * memoryAreas
Definition ugbc.h:2689
int bankAssigned
Definition ugbc.h:1172
unsigned char * valueBuffer
Definition ugbc.h:1061
int bankReadOrWrite
Definition ugbc.h:1181
int residentAssigned
Definition ugbc.h:1175
int size
Definition ugbc.h:1077
char * name
Definition ugbc.h:979
int absoluteAddress
Definition ugbc.h:1092
VariableType type
Definition ugbc.h:988
int frameSize
Definition ugbc.h:1134
int uncompressedSize
Definition ugbc.h:1082
int value
Definition ugbc.h:1025
int variableUniqueId
Definition ugbc.h:1178
VariableType arrayType
Definition ugbc.h:1125
char * realName
Definition ugbc.h:982
void * malloc(YYSIZE_T)
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define UNIQUE_RESOURCE_ID
Definition ugbc.h:3350
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
@ VT_ADDRESS
Definition ugbc.h:465
#define CRITICAL_OUT_OF_BANKS()
Definition ugbc.h:3710
@ BT_EXPANSION
Definition ugbc.h:138
#define CRITICAL_DATATYPE_UNSUPPORTED(k, v)
Definition ugbc.h:3447
#define VT_BITWIDTH(t)
Definition ugbc.h:595
struct _Bank Bank
Structure of a single bank.
char DATATYPE_AS_STRING[][16]