-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBINFILE.CPP
More file actions
228 lines (193 loc) · 7.72 KB
/
Copy pathBINFILE.CPP
File metadata and controls
228 lines (193 loc) · 7.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/***********************************************************************
*
* BINFILE.CPP
* Teeside binary file routines for 68000 Assembler
* This file contains the routines that generate a binary
* file compatible with the Teeside 68000 emulator. I am
* not sure about the header configuration of the Teeside
* binary files. Several of the bytes in the header appear
* to be constant (perhaps version number info etc.) and
* are simply copied from a Teeside binary file.
*
* Function: initBin()
* Opens the specified binary code file for writing. If
* the file cannot be opened, then the routine prints a
* message and exits.
*
* outputBin()
* Places the data whose size, value, and address are
* specified in the binary code file.
*
* finishBin()
* Closes the object code file and writes the Teeside header.
*
* Author: Chuck Kelly
* Jan-28-2002
* Monroe County Community College
* http://www.monroeccc.edu/ckelly
*
************************************************************************/
// include <vcl.h>
#include <stdio.h>
#include <ctype.h>
// include "mainS.h"
// include "textS.h"
#include "asm.h"
// prototype
void writeBigEndian(int data, int size);
extern char line[256];
extern FILE *binFile;
extern char newOrg;
extern char buffer[256]; //ck used to form messages for display in windows
extern char numBuf[20];
extern bool offsetMode;
int binAddr;
bool newFile = false;
//unsigned int sectionCount; // number of sections
//unsigned int byteCount; // code bytes in current program section
//int byteCountFP; // byte count file position
//int currentFP; // save current file position
extern unsigned int startAddress; // starting address of program
//int fileSize; // count bytes in file
int execDataSize;
int initBin(const char *name)
{
binFile = fopen(name, "wb"); // create binary file
if (!binFile) {
sprintf(buffer,"Unable to create binary file!");
//Application->MessageBox(buffer, "Error", MB_OK);
fprintf(stderr,"%s\n",buffer);
return MILD_ERROR;
}
newFile = true;
//sectionCount = 0; // # of sections
//byteCount = 0; // clear section byte count
binAddr = 0; // default address
execDataSize = 500;
// fileSize = 0; // 0 bytes in header
// fileSize = 20; // 20 bytes in header
// write Teeside header to file (removed in EASy68K v4.4.4)
//writeBigEndian(0x0001, WORD_SIZE); // version # ?
//writeBigEndian(0, LONG_SIZE); // # of sections (update later)
//writeBigEndian(0, LONG_SIZE); // unknown
//writeBigEndian(0, LONG_SIZE); // starting address (update later)
//writeBigEndian(0x2800, WORD_SIZE); // unknown
//writeBigEndian(0, LONG_SIZE); // unknown
return NORMAL;
}
int outputBin(int newAddr, int data, int size)
{
int zero = 0;
static const char* headString = "]!QDOS File Header";
try {
if (offsetMode) // don't write data if processing Offset directive
return NORMAL;
// init starting address of new file
if (newFile)
{
//binAddr = newAddr;
newFile = false;
//sectionCount++; // count sections
//writeBigEndian(newAddr, LONG_SIZE); // write new address to file
//byteCountFP = ftell(binFile); // save file position of byteCount
//writeBigEndian(0, LONG_SIZE); // save room for byte count (update later)
//fileSize += 8; // keep track of file size
if (execDataSize) {
unsigned char buff[22] = { 0 };
strcpy((char*)buff, headString);
buff[19] = 15; // Header size in words
buff[21] = 1; // QDOS executable flag
fwrite(buff, 1, sizeof(buff), binFile);
writeBigEndian(execDataSize, LONG_SIZE);
writeBigEndian(0, LONG_SIZE);
}
}
// if writing WORD_SIZE or LONG_SIZE data to odd address
if ((size != BYTE_SIZE) && (newAddr % 2)) {
newAddr++; // next address
}
// If the new address doesn't follow the previous data's address
if (newAddr > binAddr) {
//currentFP = ftell(binFile); // save current file position
// position file at previous sections byte count
//fseek(binFile, byteCountFP, SEEK_SET);
//writeBigEndian(byteCount, LONG_SIZE); // write previous sections byte count
//fseek(binFile, currentFP, SEEK_SET); // return file to current position
//byteCount = 0; // clear byte count for new section
//sectionCount++; // count sections
//writeBigEndian(newAddr, LONG_SIZE); // write new address to file
//byteCountFP = ftell(binFile); // save file position of byteCount
//writeBigEndian(0, LONG_SIZE); // save room for byte count (update later)
while (binAddr + 4 <= newAddr) {
fwrite(&zero, 1, 4, binFile);
binAddr += 4;
}
if (newAddr > binAddr)
fwrite(&zero, 1, newAddr - binAddr, binFile);
binAddr = newAddr;
//fileSize += 8; // keep track of file size
}
writeBigEndian(data, size); // write the data to the file
//byteCount += (int) size; // count the bytes
binAddr += (int) size; // next address
//fileSize += size; // keep track of file size
}
catch( ... ) {
//sprintf(buffer, "ERROR: An exception occurred in routine 'outputBin'. \n");
printError(NULL, EXCEPTION, 0);
return MILD_ERROR;
}
return NORMAL;
}
int finishBin()
{
try {
// make sure file contains an even number of bytes
if (binAddr % 2) // if odd size
writeBigEndian(0, 1); // write an extra byte of 0
//currentFP = ftell(binFile); // save current file position
//// position file at previous sections byte count
//fseek(binFile, byteCountFP, SEEK_SET);
//writeBigEndian(byteCount, LONG_SIZE); // write previous sections byte count
//rewind(binFile); // rewind to start of file
// write Teeside header to file removed in EASy68K v4.4.4
//writeBigEndian(0x0001, WORD_SIZE); // version # ?
//writeBigEndian(sectionCount, LONG_SIZE); // # of sections
//writeBigEndian(0, LONG_SIZE); // unknown
//writeBigEndian(startAddress, LONG_SIZE); // starting address
//writeBigEndian(0x2800, WORD_SIZE); // unknown
//writeBigEndian(0, LONG_SIZE); // unknown
// close the file
fclose(binFile);
}
catch( ... ) {
//sprintf(buffer, "ERROR: An exception occurred in routine 'finishBin'. \n");
printError(NULL, EXCEPTION, 0);
return MILD_ERROR;
}
return NORMAL;
}
// Write size bytes from data to file in Big-Endian format
// Always writes WORD_SIZE and LONG_SIZE data to even address.
void writeBigEndian(int data, int size)
{
unsigned char dataByte;
try {
// if writing WORD_SIZE or LONG_SIZE data to odd address
//if ((size != BYTE_SIZE) && (ftell(binFile) % 2))
//{
// dataByte = 0;
// fwrite(&dataByte, 1, 1, binFile); // pad with byte of 0
//}
// write data to file
for (int i=size-1; i>=0; i--)
{
dataByte = data >> 8*i;
fwrite(&dataByte, 1, 1, binFile);
}
}
catch( ... ) {
sprintf(buffer, "ERROR: An exception occurred in routine 'writeBigEndian'. \n");
printError(NULL, EXCEPTION, 0);
}
}