ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
_cleanup.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
42
43}
44
45void target_finalization( Environment * _environment ) {
46
47 ef936x_finalization( _environment );
48
49 deploy( vars2, src_hw_to8_vars2_asm);
50
51 if ( ! _environment->deployed.pc128audio ) {
52 cpu_label( _environment, "PC128OPAUDIOSTARTUP" );
53 outline0( "RTS" );
54 }
55
56 if ( ! _environment->deployed.scancode ) {
57 cpu_label( _environment, "KBDMANAGER" );
58 outline0( "RTS" );
59 }
60
61 if ( _environment->dataSegment ) {
62 outhead0( "DATAPREPARATION" );
63 outline0( "LDD #DATAFIRSTSEGMENT" );
64 outline0( "STD DATAPTR" );
65 outline0( "RTS" );
66 }
67
68}
69
70// -------------------------------------------------------------------------
71// CONVERT BINARY TO K7 TAPE FILE
72// FOR THOMSON MO6 / PC128 OLIVETTI PRODEST
73//
74// This code was originally present in the repository
75// "PC 128 Olivetti Prodest (Thomson MO6) tools collection"
76// https://github.com/dinoflorenzi/MO5
77//
78// Code courtesy of Dino Florenzi (https://github.com/dinoflorenzi)
79// Adapted by Marco Spedaletti for ugBASIC
80// -------------------------------------------------------------------------
81
82#include<stdlib.h>
83#include<stdio.h>
84#include<math.h>
85
86int frmt( Environment * _environment, char * ptr, char size,char* out)
87{
88 memset(out,0x20,11);
89 char * point=".";
90 int k=0,i=0;
91 int p=strcspn(ptr,point);
92 if(p==size-1||p>8||size>12||p==0)
93 {
95 }
96 for(i=0;i<size;i++)
97 {
98 if(i==p)
99 k+=(8-p);
100 else
101 {
102 out[k]=ptr[i];
103 k++;
104 }
105
106 }
107 return 0;
108}
109
110/* http://dcmoto.free.fr/documentation/moniteur-mo5-casst/moniteur-mo5-casst_src.txt */
111static unsigned char blk[257];
112static void new_blk(int type)
113{
114 blk[0] = type; /* set type ok k7 block: 0=file-name, 1=file-data, 0xFF=end-of-file */
115 blk[1] = 0; /* len = 0 */
116 blk[256] = 0; /* checksum = 0 */
117}
118static void out_blk(FILE *f)
119{
120 static unsigned char hdr[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x3c,0x5a}; /* k7 block-header */
121 int pos = 2 + blk[1]; /* get checksum pos */
122 blk[1] = pos; /* update block len */
123 blk[pos] = 256 - blk[256]; /* complement checksum */
124 fwrite(hdr, sizeof(hdr), 1, f); /* write block header */
125 fwrite(blk, pos+1, 1, f); /* then block content */
126 new_blk(blk[0]); /* prepare a new block of the same kind */
127}
128
129static void write_byte(FILE *f, int byte)
130{
131 blk[256] += (unsigned char)byte;/* update checksum */
132 blk[2 + blk[1]++] = byte; /* update index & store byte */
133 if(254 == blk[1]) out_blk(f); /* when block is full, write it */
134}
135static void write_word(FILE *f, int word)
136{
137 write_byte(f, word >> 8);
138 write_byte(f, word & 255);
139}
140static void write_bytes(FILE *f, void *array, int len)
141{
142 unsigned char *ptr = array;
143 size_t cnt = len;
144 while(cnt--) write_byte(f, *ptr++);
145}
146
148
149static void addFileEntry( FILE * _handle, char * _filename, int _file_type ) {
150
151 // k7.AddRange(SynchroTO);
152 char synchroTO[] = { 0xdc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x3c };
153 fwrite(&synchroTO[0], sizeof(synchroTO), 1, _handle);
154
155 // k7.Add(0x00); // type de bloc entête
156 char blockType = 0;
157 fwrite(&blockType, 1, 1, _handle);
158
159 // k7.Add(0x14); // longueur
160 char blockLen = 0x14;
161 fwrite(&blockLen, 1, 1, _handle);
162 // byte checksum = 0x14;
163 unsigned char checksum = 0x14;
164
165 // Nom du fichier complété au besoin par des espaces.
166 // string basename = Path.GetFileNameWithoutExtension(filename).ToUpper();
167 // char filename[16];
168 // frmt( _filename, strlen(_filename), filename);
169
170 for( int i=0; i<11; ++i ) {
171 // k7.Add((byte)basename[i]);
172 fwrite(&_filename[i], 1, 1, _handle);
173 checksum += _filename[i];
174 }
175
176 // k7.Add((byte)fileType); // type de fichier
177 char fileType = _file_type;
178 fwrite(&fileType, 1, 1, _handle);
179 checksum += fileType;
180
181 // k7.Add(0x00);
182 char zero = 0;
183 fwrite(&zero, 1, 1, _handle);
184
185 // k7.Add(0xff);
186 char ff = 0xff;
187 fwrite(&ff, 1, 1, _handle);
188 checksum += 0xff;
189
190 for ( int i=0; i<6; ++i ) {
191 // k7.Add(0x00);
192 fwrite(&zero, 1, 1, _handle);
193 }
194
195 // k7.Add(checksum);
196 fwrite(&checksum, 1, 1, _handle);
197
198}
199
200static int addFileData( FILE * _handle, unsigned char _bytes[], int _size, int _offset ) {
201
202 // int length = bytes.Length - offset;
203 int length = _size - _offset;
204
205 if (length > 0xdf) {
206 length = 0xdf;
207 }
208
209 // k7.AddRange(SynchroTO);
210 char synchroTO[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x3c };
211 fwrite(&synchroTO[0], sizeof(synchroTO), 1, _handle);
212
213 // k7.Add(0x01); // type de bloc fichier
214 char blockType = 1;
215 fwrite(&blockType, 1, 1, _handle);
216
217 // byte checksum = (byte)0x01;
218 unsigned char checksum = 0x01;
219
220 // k7.Add((byte)length); // longueur
221 char blockLen = length;
222 fwrite(&blockLen, 1, 1, _handle);
223 // checksum += (byte)length;
224 checksum += length;
225
226 for (int i=_offset; i<_offset+length; i++) {
227 // k7.Add(bytes[i]); // données
228 fwrite(&_bytes[i], 1, 1, _handle);
229 checksum += _bytes[i];
230 }
231
232 // k7.Add(checksum);
233 fwrite(&checksum, 1, 1, _handle);
234
235 return length;
236}
237
245
246static void addBinaryFile( FILE * _handle, char * _filename, int _address, char * _bytes, int _size ) {
247
248 addFileEntry( _handle, _filename, ASM_PRG );
249
250 unsigned char * fileData = malloc( _size + 10 );
251
252 fileData[0] = 0x00;
253 fileData[1] = (_size >> 8);
254 fileData[2] = (_size & 0xff);
255 fileData[3] = (_address >> 8);
256 fileData[4] = (_address & 0xff);
257 for (int i=0; i<_size; i++) {
258 fileData[i+5] = _bytes[i];
259 }
260 fileData[_size+5] = 0xff;
261 fileData[_size+6] = 0x00;
262 fileData[_size+7] = 0x00;
263 fileData[_size+8] = (_address >> 8);
264 fileData[_size+9] = (_address & 0xff);
265 for (int i=0; i<_size+10;) {
266 i += addFileData( _handle, fileData, (_size+10), i);
267 }
268 // end of file
269 // k7.AddRange(SynchroTO);
270 char synchroTO[] = { 0xdc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x3c };
271 fwrite(&synchroTO[0], sizeof(synchroTO), 1, _handle);
272
273 // k7.Add(0xff); // type de bloc fin
274 char blockType = 0xff;
275 fwrite(&blockType, 1, 1, _handle);
276
277 // k7.Add(0x00); // longueur
278 char blockLen = 0;
279 fwrite(&blockLen, 1, 1, _handle);
280
281 // k7.Add(0xff); // checksum
282 char checksum = 0xff;
283 fwrite(&checksum, 1, 1, _handle);
284}
285
287
288int convertbintok7(Environment * _environment)
289{
290 unsigned short start=0x8100;
291 unsigned short size;
292 unsigned short runaddr=0x8100;
293 FILE *fr,*fw;
294 char nome[12];
295 char source[20];
296 char destin[100];
297
298 // Rename the output file into a temporary filename
299 char temporaryFileName[MAX_TEMPORARY_STORAGE];
300 sprintf(temporaryFileName, "%s.bin", get_temporary_filename( _environment ) );
301 remove( temporaryFileName );
302 BUILD_SAFE_MOVE( _environment, _environment->exeFileName, temporaryFileName );
303
304 fr=fopen(temporaryFileName,"rb");
305 if(!fr)
306 {
307 CRITICAL_CANNOT_OPEN_EXECUTABLE_FILE( temporaryFileName );
308 }
309
310 if(frmt( _environment, "main.exe",strlen("main.exe"),nome))
311 {
313 }
314
315 unsigned char file_type[]={0x02,0x00,0x00}; /* binary k7 file */
316
317 strcopy(destin,_environment->exeFileName);
318 fw=fopen(destin,"wb");
319
320 addBinaryFile( fw, "loader bin", 0xdeff, data_to8_loader_bin, data_to8_loader_bin_len );
321
322 fr=fopen(temporaryFileName,"rb");
323 fseek(fr, 0L, SEEK_END);
324 size = ftell(fr);
325 rewind(fr);
326 char * fileContent = malloc( size );
327 (void)!fread( fileContent, 1, size, fr );
328 fclose( fr );
329
330 addBinaryFile( fw, nome, 0x6400, fileContent, size );
331
332 // new_blk(0); /* k7 block 0: file name + type */
333 // write_bytes(fw, &nome[0], sizeof(nome)-1); /* file name */
334 // write_bytes(fw, &file_type[0], 3); /* file type */
335 // out_blk(fw); /* done with block 0 */
336
337 // new_blk(1); /* k7 block 1: content of file */
338 // write_byte(fw, 0); /* binary chunk */
339 // write_word(fw, size); /* size of chunk */
340 // write_word(fw, start); /* load address */
341 // for (int i=0;i<size;i++)
342 // {
343 // unsigned char byt;
344 // (void)!fread(&byt,1,1,fr);
345 // write_byte(fw, byt); /* data */
346 // }
347
348 // write_byte(fw, 0xff); /* execution chunk */
349 // write_word(fw, 0x0000); /* len = 0 */
350 // write_word(fw, runaddr); /* exec address */
351 // out_blk(fw); /* done with k7 block 1 */
352 // new_blk(0xff); /* k7 block 0xff : end of k7 file */
353 // out_blk(fw); /* done with it */
354
355 Bank * bank = _environment->expansionBanks;
356
357 while( bank ) {
358
359 if ( bank->address ) {
360
361 char bankNumber[MAX_TEMPORARY_STORAGE];
362 sprintf( bankNumber, "bank%2.2x dat", ( bank->id ) );
363
364 addBinaryFile( fw, bankNumber, 0xa000, bank->data, bank->address );
365
366 }
367
368 bank = bank->next;
369
370 }
371
372 Storage * storage = _environment->storage;
373
374 if ( storage ) {
375
376 FileStorage * fileStorage = storage->files;
377
378 while( fileStorage ) {
379
380 char bankNumber[MAX_TEMPORARY_STORAGE];
381 sprintf( bankNumber, "%8sdat", fileStorage->targetName );
382
383 int size = 0;
384 char * buffer;
385
386 if ( fileStorage->content && fileStorage->size ) {
387 size = fileStorage->size + 2;
388 buffer = malloc( size );
389 memset( buffer, 0, size );
390 memcpy( buffer, fileStorage->content, fileStorage->size );
391 } else {
392 FILE * file = fopen( fileStorage->sourceName, "rb" );
393 if ( !file ) {
395 }
396 fseek( file, 0, SEEK_END );
397 size = ftell( file );
398 fseek( file, 0, SEEK_SET );
399 buffer = malloc( size + 2 );
400 memset( buffer, 0, size + 2 );
401 (void)!fread( buffer, size, 1, file );
402 fclose( file );
403 }
404
405 addBinaryFile( fw, bankNumber, 0xa000, buffer, size );
406
407 fileStorage = fileStorage->next;
408
409 }
410
411 storage = storage->next;
412
413 }
414
415 fclose(fw);
416
417 remove(temporaryFileName);
418
419 return 0;
420}
421
422void target_analysis( Environment * _environment ) {
423
424}
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
char * get_temporary_filename(Environment *_environment)
void target_finalization(Environment *_environment)
Definition _cleanup.c:45
void target_prepare_finalization(Environment *_environment)
Definition _cleanup.c:41
void target_analysis(Environment *_environment)
Definition _cleanup.c:68
int size
Definition _optimizer.c:678
Variable * point(Environment *_environment, char *_x, char *_y)
Definition point.c:46
int frmt(Environment *_environment, char *ptr, char size, char *out)
Definition _cleanup.c:59
int convertbintok7(Environment *_environment)
Definition _cleanup.c:120
void ef936x_finalization(Environment *_environment)
Definition ef936x.c:861
uint16_t word
Definition sidreloc.c:274
uint8_t byte
Definition sidreloc.c:273
int address
Definition ugbc.h:159
int id
Definition ugbc.h:153
struct _Bank * next
Definition ugbc.h:185
char * data
Definition ugbc.h:177
int pc128audio
Definition ugbc.h:1828
int scancode
Definition ugbc.h:1790
Storage * storage
Definition ugbc.h:2526
DataSegment * dataSegment
Definition ugbc.h:2568
Bank * expansionBanks
Definition ugbc.h:3005
char * exeFileName
Definition ugbc.h:2290
Deployed deployed
Definition ugbc.h:2921
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
struct _Storage * next
Definition ugbc.h:235
ThomsonFileType
Definition _cleanup.c:239
@ ASM_PRG
Definition _cleanup.c:242
@ BASIC_PRG
Definition _cleanup.c:240
@ BASIC_DAT
Definition _cleanup.c:241
void * malloc(YYSIZE_T)
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define CRITICAL_DLOAD_MISSING_FILE(f)
Definition ugbc.h:3578
struct _Environment Environment
Structure of compilation environment.
#define CRITICAL_CANNOT_OPEN_EXECUTABLE_FILE(c)
Definition ugbc.h:3520
struct _Storage Storage
Structure of a single storage.
#define outhead0(s)
Definition ugbc.h:4246
#define CRITICAL_BUILD_INVALID_FILENAME_K7(f)
Definition ugbc.h:3869
#define outline0(s)
Definition ugbc.h:4252
struct _FileStorage FileStorage
Structure of a single file inside a storage.
#define BUILD_SAFE_MOVE(_environment, source, destination)
Definition ugbc.h:4751
struct _Bank Bank
Structure of a single bank.
#define deploy(s, e)
Definition ugbc.h:4288
@ TEXT
Definition ugbc.tab.h:854
@ L
Definition ugbc.tab.h:508
char * strcopy(char *_dest, char *_source)