ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
_build.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#include <errno.h>
38#include <sys/stat.h>
39#include <sys/types.h>
40
41/****************************************************************************
42 * CODE SECTION
43 ****************************************************************************/
44
48
49extern char OUTPUT_FILE_TYPE_AS_STRING[][16];
50
51void generate_xex( Environment * _environment ) {
52
53 char commandLine[8*MAX_TEMPORARY_STORAGE];
54 char executableName[MAX_TEMPORARY_STORAGE];
55 char listingFileName[MAX_TEMPORARY_STORAGE];
56
57 BUILD_SAFE_REMOVE( _environment, _environment->exeFileName );
58
59 BUILD_TOOLCHAIN_CC65_GET_EXECUTABLE( _environment, executableName );
60
61 BUILD_TOOLCHAIN_CC65_GET_LISTING_FILE( _environment, listingFileName );
62
63 BUILD_TOOLCHAIN_CC65_EXEC( _environment, "atari", executableName, listingFileName, "" );
64
65 if ( _environment->listingFileName ) {
66
67 if ( _environment->profileFileName && _environment->profileCycles ) {
68 if ( _environment->executerFileName ) {
69 sprintf(executableName, "%s", _environment->executerFileName );
70 } else if( access( "run6502.exe", F_OK ) == 0 ) {
71 sprintf(executableName, "%s", "run6502.exe" );
72 } else {
73 sprintf(executableName, "%s", "run6502" );
74 }
75
76 sprintf( commandLine, "\"%s\" -c atari -X 0000 -R 2000 -l 1ffa \"%s\" -u \"%s\" -p \"%s\" %d",
77 executableName,
78 _environment->exeFileName,
79 _environment->listingFileName,
80 _environment->profileFileName,
81 _environment->profileCycles ? _environment->profileCycles : 1000000
82 );
83
84 if ( system_call( _environment, commandLine ) ) {
85 printf("The profiling of assembly program failed.\n\n");
86 return;
87 };
88
89 }
90
91 }
92
93}
94
95static void autorun_atr( Environment * _environment, char * _atr_image, char * _filename ) {
96
97 int i, j;
98
99 FILE * diskIn = fopen( _atr_image, "rb" );
100
101 if (diskIn == NULL) {
102 return;
103 }
104
105 fseek( diskIn, 0, SEEK_END );
106 int diskSize = ftell( diskIn );
107 fseek( diskIn, 0, SEEK_SET );
108
109 char * disk = malloc( diskSize );
110
111 if (disk == NULL) {
112 return;
113 }
114
115 if (fread( disk, 1, diskSize, diskIn) != diskSize ) {
116 return;
117 };
118
119 fclose(diskIn);
120
121 int found = 0;
122 for (i = 0; i < diskSize; ++i) {
123 for (j = 0; j < 11; ++j) {
124 if (disk[i+j] != _filename[j]) {
125 break;
126 }
127 }
128 if (j == 11) {
129 memcpy(&disk[i], "AUTORUN SYS", 11);
130 i += 11;
131 found = 1;
132 }
133 }
134
135 FILE * diskOut = fopen( _atr_image, "wb" );
136
137 if ( diskOut == NULL ) {
138
139 return;
140 }
141
142 fwrite( disk, 1, diskSize, diskOut );
143
144 fclose(diskOut);
145
146}
147
148void generate_atr( Environment * _environment ) {
149
150 char dir2AtrExecutableName[MAX_TEMPORARY_STORAGE];
151 BUILD_TOOLCHAIN_DIR2ATR_GET_EXECUTABLE( _environment, dir2AtrExecutableName );
152
153 Storage * storage = _environment->storage;
154
155 char temporaryPath[MAX_TEMPORARY_STORAGE];
156 strcopy( temporaryPath, _environment->temporaryPath );
157 strcat( temporaryPath, " " );
158 temporaryPath[strlen(temporaryPath)-1] = PATH_SEPARATOR;
159
160 char bootCodeFilename[MAX_TEMPORARY_STORAGE];
161 sprintf( bootCodeFilename, "%sBOOTCODE", temporaryPath );
162
163 remove( bootCodeFilename );
164
165 strcat( temporaryPath, "atr" );
166#ifdef _WIN32
167 mkdir( temporaryPath );
168#else
169 mkdir( temporaryPath, 0777 );
170#endif
171 strcat( temporaryPath, " " );
172 temporaryPath[strlen(temporaryPath)-1] = PATH_SEPARATOR;
173
174 char pipes[256];
175 #ifdef _WIN32
176 strcopy( pipes, ">nul 2>nul");
177 #else
178 strcopy( pipes, ">/dev/null 2>/dev/null");
179 #endif
180
181 char commandLine[8*MAX_TEMPORARY_STORAGE];
182#ifdef _WIN32
183 sprintf( commandLine, "del /f /q %s*.* %s", temporaryPath, pipes );
184#else
185 sprintf( commandLine, "rm %s* %s", temporaryPath, pipes );
186#endif
187 system_call( _environment, commandLine );
188
189 char mainFilename[MAX_TEMPORARY_STORAGE];
190 sprintf( mainFilename, "%sMAIN.EXE", temporaryPath );
191
192 char dos25Filename[MAX_TEMPORARY_STORAGE];
193 sprintf( dos25Filename, "%sDOS.SYS", temporaryPath );
194
195 char dup25Filename[MAX_TEMPORARY_STORAGE];
196 sprintf( dup25Filename, "%sDUP.SYS", temporaryPath );
197
198 char atrFileName[MAX_TEMPORARY_STORAGE];
199 strcopy( atrFileName, _environment->exeFileName );
200 char * p = strstr( atrFileName, ".atr" );
201 if ( !p ) {
202 strcat( atrFileName, ".atr");
203 }
204
205 BUILD_SAFE_MOVE( _environment, _environment->exeFileName, mainFilename );
206
207 FILE * fileOut;
208
209 fileOut = fopen( bootCodeFilename, "wb" );
210 if ( fileOut ) {
211 fwrite( dos25_bootcode, 1, sizeof( dos25_bootcode ), fileOut );
212 fclose( fileOut );
213 }
214
215 fileOut = fopen( dos25Filename, "wb" );
216 if ( fileOut ) {
217 fwrite( dos25_dos_sys, 1, sizeof( dos25_dos_sys ), fileOut );
218 fclose( fileOut );
219 }
220
221 fileOut = fopen( dup25Filename, "wb" );
222 if ( fileOut ) {
223 fwrite( dos25_dup_sys, 1, sizeof( dos25_dup_sys ), fileOut );
224 fclose( fileOut );
225 }
226
227 if ( !storage ) {
228 BUILD_TOOLCHAIN_DIR2ATR( _environment, dir2AtrExecutableName, bootCodeFilename, temporaryPath, atrFileName, pipes );
229 autorun_atr( _environment, atrFileName, "MAIN EXE" );
230 if ( _environment->outputGeneratedFiles ) {
231 printf( "%s\n",atrFileName );
232 }
233 } else {
234 int i=0;
235 while( storage ) {
236 FileStorage * fileStorage = storage->files;
237 while( fileStorage ) {
238 int size;
239 char * buffer;
240
241 if ( fileStorage->content && fileStorage->size ) {
242 size = fileStorage->size + 2;
243 buffer = malloc( size );
244 memset( buffer, 0, size );
245 memcpy( buffer, fileStorage->content, fileStorage->size );
246 } else {
247 FILE * file = fopen( fileStorage->sourceName, "rb" );
248 if ( !file ) {
250 }
251 fseek( file, 0, SEEK_END );
252 size = ftell( file );
253 fseek( file, 0, SEEK_SET );
254 buffer = malloc( size + 2 );
255 memset( buffer, 0, size + 2 );
256 (void)!fread( buffer, size, 1, file );
257 fclose( file );
258 }
259 char dataFilename[8*MAX_TEMPORARY_STORAGE];
260 sprintf( dataFilename, "%s%s", temporaryPath, fileStorage->targetName );
261 fileOut = fopen( dataFilename, "wb" );
262 if ( fileOut ) {
263 fwrite( buffer, 1, size, fileOut );
264 fclose(fileOut );
265 }
266 fileStorage = fileStorage->next;
267 }
268 char buffer[MAX_TEMPORARY_STORAGE];
269 char filemask[MAX_TEMPORARY_STORAGE];
270 strcopy( filemask, _environment->exeFileName );
271 char * basePath = find_last_path_separator( filemask );
272 if ( basePath ) {
273 ++basePath;
274 *basePath = 0;
275 if ( storage->fileName ) {
276 strcat( basePath, storage->fileName );
277 } else {
278 strcat( basePath, "disk%d.atr" );
279 }
280 } else {
281 if ( storage->fileName ) {
282 strcopy( filemask, storage->fileName );
283 } else {
284 strcopy( filemask, "disk%d.atr" );
285 }
286 }
287 sprintf( buffer, filemask, i );
288 if ( !strstr( buffer, ".atr" ) ) {
289 strcat( buffer, ".atr" );
290 }
291 BUILD_TOOLCHAIN_DIR2ATR( _environment, dir2AtrExecutableName, bootCodeFilename, temporaryPath, buffer, pipes );
292 if ( i == 0 ) {
293 autorun_atr( _environment, buffer, "MAIN EXE" );
294 }
295 if ( _environment->outputGeneratedFiles ) {
296 printf( "%s\n",buffer );
297 }
298 storage = storage->next;
299 ++i;
300
301 #ifdef _WIN32
302 sprintf( commandLine, "del /f /q %s*.* %s", temporaryPath, pipes );
303 #else
304 sprintf( commandLine, "rm %s* %s", temporaryPath, pipes );
305 #endif
306 system_call( _environment, commandLine );
307
308 }
309 }
310
311#ifdef _WIN32
312 sprintf( commandLine, "del /f /q %s*.* %s", temporaryPath, pipes );
313#else
314 sprintf( commandLine, "rm %s* %s", temporaryPath, pipes );
315#endif
316 system_call( _environment, commandLine );
317
318 remove( bootCodeFilename );
319
320}
321
327void target_linkage( Environment * _environment ) {
328
329 switch( _environment->outputFileType ) {
331 generate_xex( _environment );
332 break;
334 generate_xex( _environment );
335 generate_atr( _environment );
336 break;
337 default:
339 }
340
341}
342
343void target_cleanup( Environment * _environment ) {
344
345 remove( _environment->configurationFileName );
346 remove( _environment->asmFileName );
347
348 if ( _environment->analysis && _environment->listingFileName ) {
349 target_analysis( _environment );
350 }
351
352}
int system_call(Environment *_environment, char *_commandline)
Call an external executable.
char * find_last_path_separator(char *_path)
void generate_xex(Environment *_environment)
Definition _build.c:51
void target_linkage(Environment *_environment)
Convert C64's assembly to executable.
Definition _build.c:327
void target_cleanup(Environment *_environment)
Definition _build.c:343
void generate_atr(Environment *_environment)
Definition _build.c:148
void target_analysis(Environment *_environment)
Definition _cleanup.c:68
int size
Definition _optimizer.c:678
unsigned char dos25_bootcode[]
unsigned char dos25_dos_sys[]
unsigned char dos25_dup_sys[]
Storage * storage
Definition ugbc.h:2526
char * listingFileName
Definition ugbc.h:2305
char * temporaryPath
Definition ugbc.h:2360
int analysis
Definition ugbc.h:2365
char * configurationFileName
Definition ugbc.h:2295
char * executerFileName
Definition ugbc.h:2315
OutputFileType outputFileType
Definition ugbc.h:2452
int outputGeneratedFiles
Definition ugbc.h:3173
char * profileFileName
Definition ugbc.h:2310
char * asmFileName
Definition ugbc.h:2285
int profileCycles
Definition ugbc.h:2375
char * exeFileName
Definition ugbc.h:2290
char * targetName
Definition ugbc.h:201
int size
Definition ugbc.h:204
char * sourceName
Definition ugbc.h:198
char * content
Definition ugbc.h:210
struct _FileStorage * next
Definition ugbc.h:213
FileStorage * files
Definition ugbc.h:232
char * fileName
Definition ugbc.h:229
struct _Storage * next
Definition ugbc.h:235
void * malloc(YYSIZE_T)
@ OUTPUT_FILE_TYPE_ATR
Definition ugbc.h:268
@ OUTPUT_FILE_TYPE_XEX
Definition ugbc.h:260
#define BUILD_SAFE_REMOVE(_environment, filename)
Definition ugbc.h:4748
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define PATH_SEPARATOR
Definition ugbc.h:69
#define CRITICAL_DLOAD_MISSING_FILE(f)
Definition ugbc.h:3578
#define BUILD_TOOLCHAIN_CC65_GET_EXECUTABLE(_environment, executableName)
Definition ugbc.h:4754
#define BUILD_TOOLCHAIN_CC65_GET_LISTING_FILE(_environment, listingFileName)
Definition ugbc.h:4773
struct _Environment Environment
Structure of compilation environment.
struct _Storage Storage
Structure of a single storage.
#define BUILD_TOOLCHAIN_CC65_EXEC(_environment, target, executableName, listingFileName, additionalParameters)
Definition ugbc.h:4781
#define BUILD_TOOLCHAIN_DIR2ATR_GET_EXECUTABLE(_environment, executableName)
Definition ugbc.h:4929
struct _FileStorage FileStorage
Structure of a single file inside a storage.
#define BUILD_SAFE_MOVE(_environment, source, destination)
Definition ugbc.h:4751
#define CRITICAL_UNSUPPORTED_OUTPUT_FILE_TYPE(t)
Definition ugbc.h:3537
#define BUILD_TOOLCHAIN_DIR2ATR(_environment, executableName, bootCodePath, contentPath, atrFileName, pipes)
Definition ugbc.h:4961
char OUTPUT_FILE_TYPE_AS_STRING[][16]
char * strcopy(char *_dest, char *_source)