ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
load.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#include "../../libs/msc1.h"
37
38/****************************************************************************
39 * CODE SECTION
40 ****************************************************************************/
41
48/* <usermanual>
49@keyword LOAD
50
51@english
52The ''LOAD'' command allows you to load a generic binary file from the file system
53of the host system and use it, as a buffer, directly in the program. Loading occurs
54at compile time: there is no access to the target system's file system. If multiple
55uploads are made to the same file, a single buffer will still be generated.
56
57An absolute starting address can be given: in that case, files will be loaded starting
58from that position instead of the first free position available.
59
60Since it is possible to upload only one file of the same type at a time, it is necessary
61to be able to indicate an "alias" with which to exceed this limit. In this regard, there is also
62the ''AS'' syntax, which allows you to load the same file several times but with different names.
63
64@italian
65Il comando ''LOAD'' permette di caricare un generico file binario dal filesystem del sistema
66host e di utilizzarlo, come buffer, direttamente nel programma. Il caricamento avviene al
67momento della compilazione: non vi sono accessi al file system del sistema target. Se vengono
68svolti più caricamenti nel medesimo file, sarà comunque generato un singolo buffer.
69
70Può essere dato un indirizzo assoluto: in tal caso, i file saranno caricati a partire
71da quella posizione invece della prima posizione disponibile.
72
73Dal momento in cui è possibile caricare un solo file dello stesso tipo alla volta,
74è necessario poter indicare un "alias" con cui superare questo limite. A tal riguardo
75esiste anche la sintassi ''AS'', che permette di caricare più volte lo stesso file
76ma con nomi diversi.
77
78@syntax = LOAD( filename[,address] )
79@syntax = LOAD( filename AS alias[,address] )
80
81@example testo = LOAD("aiuto.txt")
82@example testoRipetuto = LOAD("aiuto.txt" AS "aiuto1")
83@example schermata = LOAD("aiuto.txt", 0x8400)
84@example schermataRipetuta = LOAD("aiuto.txt" AS "schermata2", 0x8400)
85
86@usedInExample buffers_definition_02.bas
87
88</usermanual> */
89Variable * load( Environment * _environment, char * _filename, char * _alias, int _at, int _bank_expansion, int _flags ) {
90
91 Variable * result = variable_temporary( _environment, VT_BUFFER, "(buffer)" );
92
93 if ( _environment->emptyProcedure ) {
94 return result;
95 }
96
97 if ( _environment->tenLinerRulesEnforced ) {
99 }
100
101 if ( _environment->sandbox ) {
103 }
104
105 LoadedFile * first = _environment->loadedFiles;
106 char *lookfor = _filename;
107 if ( _alias ) {
108 lookfor = _alias;
109 }
110 while( first ) {
111 if ( strcmp(lookfor, first->fileName ) == 0 ) {
112 return first->variable;
113 }
114 first = first->next;
115 }
116
117 adiline1("LF:%s", _filename );
118
119 check_if_filename_is_valid( _environment, _filename );
120
121 char * lookedFilename = resource_load_asserts( _environment, _filename );
122
123 FILE * file = fopen( lookedFilename, "rb" );
124
125 if ( !file ) {
126 CRITICAL_LOAD_MISSING_FILE( _filename );
127 }
128
129 fseek( file, 0, SEEK_END );
130 int size = ftell( file );
131 fseek( file, 0, SEEK_SET );
132
133 char * buffer = malloc( size );
134
135 (void)!fread( buffer, size, 1, file );
136
137 fclose( file );
138
139 variable_store_buffer( _environment, result->name, buffer, size, _at );
140
141 // If a bank expasion has been requested, and there is at least one bank...
142 if ( _bank_expansion && _environment->expansionBanks ) {
143
144 if ( ! banks_store( _environment, result, _bank_expansion ) ) {
146 }
147 } else if ( ( _flags & FLAG_COMPRESSED ) && _environment->expansionBanks ) {
148
149 // Try to compress the result of image conversion.
150 // This means that the buffer will be compressed using MSC1
151 // algorithm, up to 32 frequent sequences. The original size of
152 // the buffer will be considered as "uncompressed" size.
153 MSC1Compressor * compressor = msc1_create( 32 );
154 result->uncompressedSize = result->size;
155 MemoryBlock * output = msc1_compress( compressor, result->valueBuffer, result->uncompressedSize, &result->size );
156
157 int temporary;
158 MemoryBlock * outputCheck = msc1_uncompress( compressor, output, result->size, &temporary );
159 // printf("\n0000: " );
160 // for( int k=0; k<result->uncompressedSize; ++k ) {
161 // printf( "%2.2x ", result->valueBuffer[k] );
162 // if ( ((k+1) % 8 == 0 ) ) {
163 // printf("\n%4.4x: ", (k) );
164 // };
165 // }
166 // printf("\n0000: " );
167 // for( int k=0; k<result->uncompressedSize; ++k ) {
168 // if ( outputCheck[k] == result->valueBuffer[k] ) {
169 // printf( " " );
170 // } else {
171 // printf( "%2.2x [%2.2x] ", outputCheck[k], result->valueBuffer[k] );
172 // }
173 // if ( ((k+1) % 8 == 0 ) ) {
174 // printf("\n%4.4x: ", (k) );
175 // };
176 // }
177 if ( memcmp( outputCheck, result->valueBuffer, result->uncompressedSize ) != 0 ) {
179 }
180 msc1_free( compressor );
181 // printf( "%s: %d bytes -> %d bytes\n", _filename, result->uncompressedSize, result->size );
182 // If the compressed memory is greater than the original
183 // size, we discard the compression and we will continue as
184 // usual.
185 if ( result->uncompressedSize < result->size ) {
186 result->size = result->uncompressedSize;
187 result->uncompressedSize = 0;
188 free( output );
189 }
190 // Otherwise, we can safely replace the original data
191 // buffer with the compressed one.
192 else {
193 result->valueBuffer = output;
194 if ( ! banks_store( _environment, result, 1 ) ) {
196 };
197 free( result->valueBuffer );
198 result->valueBuffer = NULL;
199 }
200
201 }
202
203 LoadedFile * loaded = malloc( sizeof( LoadedFile ) );
204 loaded->next = first;
205 loaded->variable = result;
206 loaded->fileName = lookfor;
207 _environment->loadedFiles = loaded;
208
209 if ( _alias ) {
210 const_define_numeric( _environment, _alias, UNIQUE_ID );
211 }
212
213 result->readonly = 1;
214
215 return result;
216
217}
void const_define_numeric(Environment *_environment, char *_name, int _value)
int check_if_filename_is_valid(Environment *_environment, char *_filename)
char * resource_load_asserts(Environment *_environment, char *_filename)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
Variable * variable_store_buffer(Environment *_environment, char *_destination, unsigned char *_buffer, int _size, int _at)
int size
Definition _optimizer.c:678
int banks_store(Environment *_environment, Variable *_variable, int _resident)
Definition _banks.c:170
Variable * load(Environment *_environment, char *_filename, char *_alias, int _at, int _bank_expansion, int _flags)
Emit code for LOAD(...).
Definition load.c:89
MSC1Compressor * msc1_create(int _maximum_repeated_sequences)
Definition msc1.c:300
void msc1_free(MSC1Compressor *_msc1)
Definition msc1.c:740
MemoryBlock * msc1_uncompress(MSC1Compressor *_msc1, MemoryBlock *_input, int _size, int *_output_size)
Definition msc1.c:746
MemoryBlock * msc1_compress(MSC1Compressor *_msc1, MemoryBlock *_input, int _size, int *_output_size)
Definition msc1.c:381
unsigned char MemoryBlock
Definition msc1.h:90
struct _MSC1Compressor MSC1Compressor
LoadedFile * loadedFiles
Definition ugbc.h:2636
int sandbox
Definition ugbc.h:2990
Bank * expansionBanks
Definition ugbc.h:3005
int tenLinerRulesEnforced
Definition ugbc.h:2985
int emptyProcedure
Definition ugbc.h:2932
char * fileName
Definition ugbc.h:1481
struct _LoadedFile * next
Definition ugbc.h:1486
Variable * variable
Definition ugbc.h:1483
unsigned char * valueBuffer
Definition ugbc.h:1061
int size
Definition ugbc.h:1077
char * name
Definition ugbc.h:979
int readonly
Definition ugbc.h:1195
int uncompressedSize
Definition ugbc.h:1082
void * malloc(YYSIZE_T)
void free(void *)
#define FLAG_COMPRESSED
Definition ugbc.h:4570
#define CRITICAL_10_LINE_RULES_ENFORCED(v)
Definition ugbc.h:3550
#define adiline1(s, a)
Definition ugbc.h:4187
#define UNIQUE_ID
Definition ugbc.h:3349
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_BUFFER
Definition ugbc.h:477
#define CRITICAL_LOAD_MISSING_FILE(f)
Definition ugbc.h:3497
#define CRITICAL_EXPANSION_OUT_OF_MEMORY_LOADING(v)
Definition ugbc.h:3568
#define CRITICAL_SANDBOX_ENFORCED(v)
Definition ugbc.h:3687
struct _LoadedFile LoadedFile
#define CRITICAL_COMPRESSION_FAILED(v)
Definition ugbc.h:3768