5
5
interface
6
6
7
7
uses
8
- Classes,SysUtils,Forms,Controls,Graphics, Dialogs,ExtCtrls,StdCtrls,Buttons,
8
+ Classes,SysUtils,Forms,Controls,Dialogs,ExtCtrls,StdCtrls,Buttons,
9
9
ComCtrls,ZStream,crc,Global,StrUtils,Math;
10
10
11
11
type
@@ -50,7 +50,7 @@ TMainForm = class(TForm)
50
50
function TargetMachine (machine: Byte): String;
51
51
function GetCRC16 (start,length: Cardinal;var buffer: TDynByteArray): Cardinal;
52
52
function GetCRC32 (var buffer: TDynByteArray): String;
53
- function Inflate (source: String): TDynByteArray;
53
+ function Inflate (source: String; var IsInflated: Boolean ): TDynByteArray;
54
54
function GetIEEEFloat (input: Cardinal): Real;
55
55
private
56
56
@@ -96,9 +96,12 @@ procedure TMainForm.ReadUEFFile(source: String);
96
96
chunklen,
97
97
blocklen,
98
98
blocknum,
99
+ lastblock,
99
100
ptr,
100
101
headcrc,
101
102
datacrc : Cardinal;
103
+ firstblock,
104
+ IsGZip,
102
105
ok : Boolean;
103
106
temp,
104
107
line : String;
@@ -114,6 +117,7 @@ procedure TMainForm.ReadUEFFile(source: String);
114
117
SetLength(files,0 );
115
118
baud:=1200 ; // Default baud rate
116
119
phase:=180 ;
120
+ IsGZip:=False;
117
121
// Reset the controls
118
122
Report.Clear; // The reading of the file would actually go quicker without these
119
123
FileLoader.Clear; // being updated as it read.
@@ -128,7 +132,8 @@ procedure TMainForm.ReadUEFFile(source: String);
128
132
// Begin the report
129
133
Report.Lines.Add(' File: "' +source+' "' ); // Put the filename in as the first line
130
134
// Open the file
131
- buffer:=Inflate(source);
135
+ buffer:=Inflate(source,IsGzip);
136
+ if (IsGZip)then Report.Lines.Add(' File is GZipped' );
132
137
Report.Lines.Add(' Total uncompressed file length: '
133
138
+IntToStr(Length(buffer))+' bytes (0x'
134
139
+IntToHex(Length(buffer),10 )+' )' );
@@ -143,6 +148,9 @@ procedure TMainForm.ReadUEFFile(source: String);
143
148
Report.Lines.Add(' File is a UEF file' );
144
149
Report.Lines.Add(' UEF version: ' +IntToStr(buffer[$0A])+' .' +IntToStr(buffer[$0B]));
145
150
Report.Lines.Add(' ' );
151
+ // Keep track of the last block's details
152
+ lastblock:=0 ;
153
+ firstblock:=True;
146
154
// Starting position is after the magic string
147
155
pos:=$0C;
148
156
// Keep track of which file we are on
@@ -218,21 +226,34 @@ procedure TMainForm.ReadUEFFile(source: String);
218
226
files[filenum].Filename:=temp; // Filename
219
227
files[filenum].Offset :=pos-6 ; // Where to find it (first block)
220
228
SetLength(files[filenum].Data,0 );// Clear the data
221
- FileLoader.Lines.Add(temp) ;
222
- end ;
223
- // Read in the load address
224
- files[filenum].LoadAddr:= buffer[pos+i]
225
- +buffer[pos+i+1 ]*$100
226
- +buffer[pos+i+2 ]*$10000
227
- +buffer[pos+i+ 3 ]*$ 1000000 ;
228
- // Read in the execution address
229
- files[filenum].ExecAddr:= buffer[pos+i+4 ]
230
- +buffer[pos+i+5 ]*$100
231
- +buffer[pos+i+6 ]*$10000
232
- +buffer[pos+i+ 7 ]*$ 1000000 ;
229
+ firstblock:=True ;
230
+ // Read in the load address
231
+ files[filenum].LoadAddr:=buffer[pos+i]
232
+ + buffer[pos+i+ 1 ]*$ 100
233
+ +buffer[pos+i+2 ]*$10000
234
+ +buffer[pos+i+3 ]*$1000000 ;
235
+ // Read in the execution address
236
+ files[filenum].ExecAddr:=buffer[pos+i+ 4 ]
237
+ + buffer[pos+i+5 ]*$ 100
238
+ +buffer[pos+i+6 ]*$10000
239
+ +buffer[pos+i+7 ]*$1000000 ;
240
+ end else firstblock:=False ;
233
241
// Read in the block number
234
242
blocknum:=buffer[pos+i+8 ]+buffer[pos+i+9 ]*$100 ;
235
243
line:=line+' #' +IntToHex(blocknum,4 );
244
+ // Is it a new block, or copy protection?
245
+ if (blocknum>0 )and (firstblock)and (Length(files)>1 )then
246
+ if (lastblock=blocknum-1 )
247
+ and (files[filenum-1 ].Filename=files[filenum].Filename)
248
+ { and(files[filenum-1].LoadAddr=files[filenum].LoadAddr)
249
+ and(files[filenum-1].ExecAddr=files[filenum].ExecAddr)} then
250
+ begin
251
+ SetLength(files,Length(files)-1 );
252
+ dec(filenum);
253
+ firstblock:=False;
254
+ end ;
255
+ lastblock:=blocknum;
256
+ if firstblock then FileLoader.Lines.Add(files[filenum].Filename);
236
257
// Take a note of where we are in the file's data, as we build it up
237
258
ptr:=files[filenum].Length;
238
259
// Get the length of this block
@@ -241,6 +262,7 @@ procedure TMainForm.ReadUEFFile(source: String);
241
262
inc(files[filenum].Length,blocklen);
242
263
// Get the block status
243
264
blockst:=buffer[pos+i+12 ];
265
+ line:=line+' Status: ' +IntToHex(blockst,2 );
244
266
// Get the CRC16 value for the header
245
267
headcrc:=buffer[pos+i+17 ]+buffer[pos+i+18 ]*$100 ;
246
268
// Check it is valid
@@ -497,7 +519,7 @@ function TMainForm.GetCRC32(var buffer: TDynByteArray): String;
497
519
{ -------------------------------------------------------------------------------
498
520
Load, and inflate if it is GZipped, a UEF file
499
521
-------------------------------------------------------------------------------}
500
- function TMainForm.Inflate (Source: String): TDynByteArray;
522
+ function TMainForm.Inflate (Source: String; var IsInflated: Boolean ): TDynByteArray;
501
523
function L_Inflate (Source: String): TDynByteArray;
502
524
var
503
525
GZ : TGZFileStream;
@@ -554,14 +576,18 @@ function TMainForm.Inflate(Source: String): TDynByteArray;
554
576
except
555
577
end ;
556
578
F.Free;
557
- // Count how many blocks and make note of their positions
558
- for ptr:=0 to Length(buffer)-10 do
559
- if (buffer[ptr]=$1F )and (buffer[ptr+1 ]=$8B)and (buffer[ptr+2 ]=$08 )then
560
- begin
561
- // Make a note of the position
562
- SetLength(blockptrs,Length(blockptrs)+1 );
563
- blockptrs[Length(blockptrs)-1 ]:=ptr;
564
- end ;
579
+ // First, is it actually a GZip file?
580
+ if (buffer[$00 ]=$1F )and (buffer[$01 ]=$8B)and (buffer[$02 ]=$08 )then
581
+ begin
582
+ // Count how many blocks and make note of their positions
583
+ for ptr:=0 to Length(buffer)-10 do
584
+ if (buffer[ptr]=$1F )and (buffer[ptr+1 ]=$8B)and (buffer[ptr+2 ]=$08 )then
585
+ begin
586
+ // Make a note of the position
587
+ SetLength(blockptrs,Length(blockptrs)+1 );
588
+ blockptrs[Length(blockptrs)-1 ]:=ptr;
589
+ end ;
590
+ end ;
565
591
// Separate each block, if more than one
566
592
if Length(blockptrs)>1 then
567
593
begin
@@ -597,6 +623,7 @@ function TMainForm.Inflate(Source: String): TDynByteArray;
597
623
if Length(blockptrs)=1 then Result:=L_Inflate(Source);
598
624
// If there are no blocks, then just return the entire file
599
625
if Length(blockptrs)=0 then Result:=buffer;
626
+ IsInflated:=Length(buffer)<>Length(Result);
600
627
end ;
601
628
602
629
{ -------------------------------------------------------------------------------
0 commit comments