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#if defined(__pc128op__) || defined(__mo5__)
38
39/****************************************************************************
40 * CODE SECTION
41 ****************************************************************************/
42
43// -------------------------------------------------------------------------
44// CONVERT BINARY TO K7 TAPE FILE
45// FOR THOMSON MO6 / PC128 OLIVETTI PRODEST
46//
47// This code was originally present in the repository
48// "PC 128 Olivetti Prodest (Thomson MO6) tools collection"
49// https://github.com/dinoflorenzi/MO5
50//
51// Code courtesy of Dino Florenzi (https://github.com/dinoflorenzi)
52// Adapted by Marco Spedaletti for ugBASIC
53// -------------------------------------------------------------------------
54
55#include<stdlib.h>
56#include<stdio.h>
57#include<math.h>
58
59int frmt( Environment * _environment, char * ptr, char size,char* out)
60{
61 memset(out,0x20,11);
62 char * point=".";
63 int k=0,i=0;
64 int p=strcspn(ptr,point);
65 if(p==size-1||p>8||size>12||p==0)
66 {
68 }
69 for(i=0;i<size;i++)
70 {
71 if(i==p)
72 k+=(8-p);
73 else
74 {
75 out[k]=ptr[i];
76 k++;
77 }
78
79 }
80 return 0;
81}
82
83/* http://dcmoto.free.fr/documentation/moniteur-mo5-casst/moniteur-mo5-casst_src.txt */
84static unsigned char blk[257];
85static void new_blk(int type)
86{
87 blk[0] = type; /* set type ok k7 block: 0=file-name, 1=file-data, 0xFF=end-of-file */
88 blk[1] = 0; /* len = 0 */
89 blk[256] = 0; /* checksum = 0 */
90}
91static void out_blk(FILE *f)
92{
93 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 */
94 int pos = 2 + blk[1]; /* get checksum pos */
95 blk[1] = pos; /* update block len */
96 blk[pos] = 256 - blk[256]; /* complement checksum */
97 fwrite(hdr, sizeof(hdr), 1, f); /* write block header */
98 fwrite(blk, pos+1, 1, f); /* then block content */
99 new_blk(blk[0]); /* prepare a new block of the same kind */
100}
101
102static void write_byte(FILE *f, int byte)
103{
104 blk[256] += (unsigned char)byte;/* update checksum */
105 blk[2 + blk[1]++] = byte; /* update index & store byte */
106 if(254 == blk[1]) out_blk(f); /* when block is full, write it */
107}
108static void write_word(FILE *f, int word)
109{
110 write_byte(f, word >> 8);
111 write_byte(f, word & 255);
112}
113static void write_bytes(FILE *f, void *array, int len)
114{
115 unsigned char *ptr = array;
116 size_t cnt = len;
117 while(cnt--) write_byte(f, *ptr++);
118}
119
120int convertbintok7(Environment * _environment)
121{
122 unsigned short start=_environment->program.startingAddress;
123 unsigned short size;
124 unsigned short runaddr=_environment->program.startingAddress;
125 FILE *fr,*fw;
126 char nome[12];
127 char source[20];
128 char destin[100];
129
130 // Rename the output file into a temporary filename
131 char temporaryFileName[MAX_TEMPORARY_STORAGE];
132 sprintf(temporaryFileName, "%s.bin", get_temporary_filename( _environment ) );
133 remove( temporaryFileName );
134 BUILD_SAFE_MOVE( _environment, _environment->exeFileName, temporaryFileName );
135
136 fr=fopen(temporaryFileName,"rb");
137 if(!fr)
138 {
139 CRITICAL_CANNOT_OPEN_EXECUTABLE_FILE( temporaryFileName );
140 }
141
142 if(frmt(_environment, "main.exe",strlen("main.exe"),nome))
143 {
145 }
146
147 unsigned char file_type[]={0x02,0x00,0x00}; /* binary k7 file */
148
149 fr=fopen(temporaryFileName,"rb");
150
151 strcopy(destin,_environment->exeFileName);
152 fw=fopen(destin,"wb");
153
154 fseek(fr, 0L, SEEK_END);
155 size = ftell(fr);
156 rewind(fr);
157
158 new_blk(0); /* k7 block 0: file name + type */
159 write_bytes(fw, &nome[0], sizeof(nome)-1); /* file name */
160 write_bytes(fw, &file_type[0], 3); /* file type */
161 out_blk(fw); /* done with block 0 */
162
163 new_blk(1); /* k7 block 1: content of file */
164 write_byte(fw, 0); /* binary chunk */
165 write_word(fw, size); /* size of chunk */
166 write_word(fw, start); /* load address */
167 for (int i=0;i<size;i++)
168 {
169 unsigned char byt;
170 (void)!fread(&byt,1,1,fr);
171 write_byte(fw, byt); /* data */
172 }
173
174 write_byte(fw, 0xff); /* execution chunk */
175 write_word(fw, 0x0000); /* len = 0 */
176 write_word(fw, runaddr); /* exec address */
177 out_blk(fw); /* done with k7 block 1 */
178 new_blk(0xff); /* k7 block 0xff : end of k7 file */
179 out_blk(fw); /* done with it */
180
181 Bank * bank = _environment->expansionBanks;
182
183 while( bank ) {
184
185 if ( bank->address ) {
186
187 char bankNumber[MAX_TEMPORARY_STORAGE];
188 sprintf( bankNumber, "bank%2.2x dat", ( bank->id ) );
189
190 new_blk(0); /* k7 block 0: file name + type */
191 write_bytes(fw, bankNumber, 11); /* file name */
192 write_bytes(fw, &file_type[0], 3); /* file type */
193 out_blk(fw); /* done with block 0 */
194
195 new_blk(1); /* k7 block 2: content of file */
196 write_byte(fw, 0); /* binary chunk */
197 write_word(fw, bank->address); /* size of chunk */
198 write_word(fw, start); /* load address */
199 for (int i=0;i<bank->address;i++)
200 {
201 unsigned char byt = bank->data[i];
202 write_byte(fw, byt); /* data */
203 }
204
205 out_blk(fw); /* done with k7 block 1 */
206
207 }
208
209 new_blk(0xff); /* k7 block 0xff : end of k7 file */
210 out_blk(fw); /* done with it */
211
212 bank = bank->next;
213
214 }
215
216 Storage * storage = _environment->storage;
217
218 if ( storage ) {
219
220 FileStorage * fileStorage = storage->files;
221
222 while( fileStorage ) {
223
224 char bankNumber[MAX_TEMPORARY_STORAGE];
225 strcopy( bankNumber, fileStorage->targetName );
226
227 int size = 0;
228 char * buffer;
229
230 if ( fileStorage->content && fileStorage->size ) {
231 size = fileStorage->size + 2;
232 buffer = malloc( size );
233 memset( buffer, 0, size );
234 memcpy( buffer, fileStorage->content, fileStorage->size );
235 } else {
236 FILE * file = fopen( fileStorage->sourceName, "rb" );
237 if ( !file ) {
239 }
240 fseek( file, 0, SEEK_END );
241 size = ftell( file );
242 fseek( file, 0, SEEK_SET );
243 buffer = malloc( size + 2 );
244 memset( buffer, 0, size + 2 );
245 (void)!fread( buffer, size, 1, file );
246 fclose( file );
247 }
248
249 new_blk(0); /* k7 block 0: file name + type */
250 write_bytes(fw, bankNumber, 11); /* file name */
251 write_bytes(fw, &file_type[0], 3); /* file type */
252 out_blk(fw); /* done with block 0 */
253
254 new_blk(1); /* k7 block 2: content of file */
255 write_byte(fw, 0); /* binary chunk */
256 write_word(fw, size); /* size of chunk */
257 write_word(fw, 0x6000); /* load address */
258 for (int i=0;i<size;i++)
259 {
260 unsigned char byt = buffer[i];
261 write_byte(fw, byt); /* data */
262 }
263
264 out_blk(fw); /* done with k7 block 1 */
265
266 fileStorage = fileStorage->next;
267
268 }
269
270 storage = storage->next;
271
272 }
273
274 new_blk(0xff); /* k7 block 0xff : end of k7 file */
275 out_blk(fw); /* done with it */
276
277}
278
279#endif
char * get_temporary_filename(Environment *_environment)
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
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
Storage * storage
Definition ugbc.h:2526
Program program
Definition ugbc.h:3179
Bank * expansionBanks
Definition ugbc.h:3005
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
int startingAddress
Definition ugbc.h:2217
FileStorage * files
Definition ugbc.h:232
struct _Storage * next
Definition ugbc.h:235
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 CRITICAL_BUILD_INVALID_FILENAME_K7(f)
Definition ugbc.h:3869
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.
@ L
Definition ugbc.tab.h:508
char * strcopy(char *_dest, char *_source)