mirror of
https://github.com/MiSTer-devel/Main_MiSTer.git
synced 2026-04-12 03:04:02 +00:00
* DiskImage: match new[] with delete[] Signed-off-by: Sven Schnelle <fz@stackframe.org> * st_tos: match new[] with delete[] Signed-off-by: Sven Schnelle <fz@stackframe.org> * scaler: fix calloc arguments The first argument is the number of members, the second argument the size of each member. Swap the arguments to the correct order to prevent warings with newer compilers. Signed-off-by: Sven Schnelle <fz@stackframe.org> --------- Signed-off-by: Sven Schnelle <fz@stackframe.org>
3420 lines
134 KiB
C++
3420 lines
134 KiB
C++
#include <unistd.h>
|
||
#include <fcntl.h>
|
||
#include <sys/stat.h>
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <ctype.h>
|
||
|
||
#include "DiskImage.h"
|
||
|
||
#define ERR_OPEN "Error: can't open source file"
|
||
#define ERR_GETLEN "Error: can't get file length!"
|
||
#define ERR_NOMEM "Error: no memory!"
|
||
#define ERR_FORMAT "Error: incorrect format"
|
||
#define ERR_FILEVER "Error: unknown version of"
|
||
#define ERR_FILECRC "Error: bad file CRC"
|
||
#define ERR_CANTWRITE "Error: write to file failed!"
|
||
#define ERR_UNKFORMAT "Error: Unknown format of source file!"
|
||
#define ERR_MANYCYLS "Error: out of 256 cylinders in opening source file!"
|
||
#define ERR_MANYSIDS "Error: out of 2 surfaces in opening source file!"
|
||
#define ERR_IMPOSSIBLE "Error: impossible format in opening source file!"
|
||
#define ERR_CORRUPT "Error: source file is corrupted!"
|
||
#define ERR_TD0DOSALLOC "Error: files TD0 in 'DOS Allocated sectors were copied' format not supported!"
|
||
|
||
#define STR_CREATEDISKNAME "MiSTer "
|
||
|
||
char errsect[] = "ERROR: THIS SECTOR NOT FOUND OR IN NON TR-DOS FORMAT!";
|
||
|
||
enum TDiskImageType { DIT_UNK, DIT_SCL, DIT_FDI, DIT_TD0, DIT_UDI, DIT_HOB, DIT_FDD };
|
||
|
||
struct VGFIND_TRACK
|
||
{
|
||
unsigned char *TrackPointer;
|
||
unsigned char *ClkPointer;
|
||
unsigned int TrackLength;
|
||
bool FoundTrack;
|
||
};
|
||
|
||
|
||
struct VGFIND_ADM
|
||
{
|
||
unsigned char* TrackPointer;
|
||
unsigned char* ClkPointer;
|
||
unsigned int TrackLength;
|
||
|
||
unsigned char *ADMPointer;
|
||
unsigned int ADMLength;
|
||
|
||
unsigned int MarkedOffsetADM;
|
||
unsigned int OffsetADM;
|
||
unsigned int OffsetEndADM;
|
||
bool FoundADM;
|
||
bool CRCOK;
|
||
};
|
||
|
||
|
||
struct VGFIND_SECTOR
|
||
{
|
||
VGFIND_ADM vgfa;
|
||
|
||
unsigned char *SectorPointer;
|
||
unsigned int SectorLength;
|
||
|
||
unsigned int MarkedOffsetSector;
|
||
unsigned int OffsetSector;
|
||
unsigned int OffsetEndSector;
|
||
bool FoundDATA;
|
||
bool CRCOK;
|
||
unsigned char DataMarker;
|
||
};
|
||
|
||
|
||
class TDiskImage
|
||
{
|
||
unsigned int FTrackLength[256][256];
|
||
unsigned char* FTracksPtr[256][256][2];
|
||
|
||
TDiskImageType FType;
|
||
|
||
unsigned short MakeVGCRC(unsigned char *data, unsigned long length);
|
||
public:
|
||
bool Changed;
|
||
|
||
bool ReadOnly;
|
||
bool DiskPresent;
|
||
unsigned char MaxTrack;
|
||
unsigned char MaxSide;
|
||
|
||
TDiskImage();
|
||
~TDiskImage();
|
||
|
||
bool FindTrack(unsigned char CYL, unsigned char SIDE, VGFIND_TRACK *vgft);
|
||
bool FindADMark(unsigned char CYL, unsigned char SIDE,
|
||
unsigned int FromOffset,
|
||
VGFIND_ADM *vgfa);
|
||
bool FindSector(unsigned char CYL, unsigned char SIDE,
|
||
unsigned char SECT,
|
||
VGFIND_SECTOR *vgfs, unsigned int FromOffset = 0);
|
||
void ApplySectorCRC(VGFIND_SECTOR vgfs);
|
||
|
||
|
||
void Open(const char *filename, bool ReadOnly);
|
||
|
||
void writeTRD(fileTYPE *hfile);
|
||
|
||
void readSCL(int hfile, bool readonly);
|
||
void readFDI(int hfile, bool readonly);
|
||
void readUDI(int hfile, bool readonly);
|
||
void readTD0(int hfile, bool readonly);
|
||
void readFDD(int hfile, bool readonly);
|
||
void readHOB(int hfile);
|
||
|
||
void formatTRDOS(unsigned int tracks, unsigned int sides);
|
||
|
||
void ShowError(const char *str);
|
||
};
|
||
|
||
#pragma pack(1)
|
||
struct UDI_HEADER // 16 bytes
|
||
{
|
||
unsigned char ID[4];
|
||
unsigned long UnpackedLength;
|
||
unsigned char Version;
|
||
unsigned char MaxCylinder;
|
||
unsigned char MaxSide;
|
||
unsigned char _zero;
|
||
unsigned long ExtHdrLength;
|
||
};
|
||
|
||
struct TD0_MAIN_HEADER // 12 bytes
|
||
{
|
||
char ID[2]; // +0: "TD" - 'Normal'; "td" - packed LZH ('New Advanced data compression')
|
||
unsigned char __t; // +2: = 0x00
|
||
unsigned char __1; // +3: ???
|
||
unsigned char Ver; // +4: Source version (1.0 -> 10, ..., 2.1 -> 21)
|
||
unsigned char __2; // +5: ???
|
||
unsigned char DiskType; // +6: Source disk type
|
||
unsigned char Info; // +7: D7-наличие image info
|
||
unsigned char DataDOS; // +8: if(=0)'All sectors were copied', else'DOS Allocated sectors were copied'
|
||
unsigned char ChkdSides; // +9: if(=1)'One side was checked', else'Both sides were checked'
|
||
unsigned short CRC; // +A: CRC хидера TD0_MAIN_HEADER (кроме байт с CRC)
|
||
};
|
||
|
||
struct TD0_INFO_DATA // 10 байт без строки коментария...
|
||
{
|
||
unsigned short CRC; // +0: CRC для структуры COMMENT_DATA (без байтов CRC)
|
||
unsigned short strLen; // +2: Длина строки коментария
|
||
unsigned char Year; // +4: Дата создания - год (1900 + X)
|
||
unsigned char Month; // +5: Дата создания - месяц (Январь=0, Февраль=1,...)
|
||
unsigned char Day; // +6: Дата создания - число
|
||
unsigned char Hours; // +7: Время создания - часы
|
||
unsigned char Minutes; // +8: Время создания - минуты
|
||
unsigned char Seconds; // +9: Время создания - секунды
|
||
};
|
||
|
||
struct TD0_TRACK_HEADER // 4 bytes
|
||
{
|
||
unsigned char SectorCount;
|
||
unsigned char Track;
|
||
unsigned char Side;
|
||
unsigned char CRCL;
|
||
};
|
||
|
||
struct TD0_SECT_HEADER // 8 bytes
|
||
{
|
||
unsigned char ADRM[6];
|
||
unsigned short DataLength;
|
||
};
|
||
|
||
struct FDD_MAIN_HEADER
|
||
{
|
||
char ID[30]; /* сигнатура */
|
||
unsigned char MaxTracks; /* число треков (цилиндров) */
|
||
unsigned char MaxHeads; /* число головок (1 или 2) */
|
||
long diskIndex; /* unused */
|
||
long DataOffset[512 * 2]; /* смещение в файле к структурам заголовков */
|
||
/* треков */
|
||
};
|
||
|
||
struct FDD_TRACK_HEADER
|
||
{
|
||
unsigned char trkType; /* unused */
|
||
unsigned char SectNum; /* число секторов на треке */
|
||
struct
|
||
{
|
||
/* заголовок сектора */
|
||
unsigned char trk; /* номер трека */
|
||
unsigned char side; /* номер стороны */
|
||
/* 7 бит этого байта указывает бит a */
|
||
unsigned char sect; /* номер сектора */
|
||
unsigned char size; /* размер сектора (код) */
|
||
long SectPos; /* смещение в файле к данным сектора */
|
||
} sect[256];
|
||
};
|
||
|
||
|
||
struct TRDOS_DIR_ELEMENT // 16 bytes
|
||
{
|
||
char FileName[8];
|
||
char Type;
|
||
unsigned short Start;
|
||
unsigned short Length;
|
||
unsigned char SecLen;
|
||
unsigned char FirstSec;
|
||
unsigned char FirstTrk;
|
||
};
|
||
#pragma pack()
|
||
|
||
static const unsigned char sbootimage[] = {
|
||
0x00, 0x01, 0x1a, 0x00, 0xf9, 0xc0, 0xb0, 0x22, 0x31, 0x35, 0x36, 0x31, 0x39, 0x22, 0x3a, 0xea,
|
||
0x3a, 0xf7, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x20, 0x0d, 0x00, 0x02,
|
||
0x0f, 0x00, 0xf9, 0xc0, 0xb0, 0x22, 0x31, 0x35, 0x36, 0x31, 0x39, 0x22, 0x3a, 0xea, 0x3a, 0xf7,
|
||
0x0d, 0x00, 0x03, 0x0b, 0x00, 0xf9, 0xc0, 0xb0, 0x22, 0x31, 0x35, 0x36, 0x31, 0x36, 0x22, 0x0d,
|
||
0x00, 0x04, 0x47, 0x00, 0xea, 0x21, 0xa8, 0x61, 0x11, 0xa9, 0x61, 0x01, 0x07, 0x9d, 0x36, 0x00,
|
||
0xed, 0xb0, 0x21, 0xa8, 0x61, 0xed, 0x5b, 0xf4, 0x5c, 0x01, 0x05, 0x0f, 0xcd, 0x13, 0x3d, 0x21,
|
||
0x00, 0xa6, 0xed, 0x5b, 0xf4, 0x5c, 0x01, 0x05, 0x08, 0xcd, 0x13, 0x3d, 0x21, 0x50, 0xeb, 0xed,
|
||
0x5b, 0xf4, 0x5c, 0x01, 0x05, 0x0d, 0xcd, 0x13, 0x3d, 0xcd, 0xa8, 0x61, 0x21, 0xa8, 0x61, 0x11,
|
||
0xa9, 0x61, 0x01, 0x07, 0x9d, 0x36, 0x00, 0xed, 0xb0, 0xc9, 0x0d, 0x00, 0x0a, 0x25, 0x00, 0xe7,
|
||
0xc3, 0xa7, 0x3a, 0xda, 0xc3, 0xa7, 0x3a, 0xd9, 0xb0, 0x22, 0x37, 0x22, 0x3a, 0xfd, 0xb0, 0x22,
|
||
0x36, 0x35, 0x33, 0x34, 0x37, 0x22, 0x3a, 0xf9, 0xc0, 0xb0, 0x22, 0x32, 0x33, 0x39, 0x33, 0x36,
|
||
0x22, 0x3a, 0xf7, 0x0d, 0x80, 0xaa, 0x0a, 0x00, 0x6f, 0x6f, 0x74, 0x31, 0x31, 0x22, 0xca, 0x31,
|
||
0x30, 0x0d, 0x80, 0x31, 0x35, 0x36, 0x31, 0x36, 0x0e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x0d, 0x80,
|
||
0xca, 0xf3, 0x5e, 0x06, 0x00, 0x00, 0x00, 0xf3, 0x5e, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0xfd, 0x22, 0xc8, 0xaf, 0xd9, 0x22, 0xca, 0xaf, 0xed, 0x73, 0xcc, 0xaf, 0xed, 0x57, 0x32, 0xce,
|
||
0xaf, 0x11, 0x00, 0x00, 0x21, 0x00, 0x9d, 0x01, 0x05, 0x08, 0xcd, 0x13, 0x3d, 0x31, 0x68, 0xbf,
|
||
0xf3, 0x21, 0x00, 0xfd, 0x11, 0x01, 0xfd, 0x01, 0x00, 0x01, 0x36, 0xfc, 0xed, 0xb0, 0x21, 0x5a,
|
||
0x67, 0x22, 0xfd, 0xfc, 0x3e, 0xc3, 0x32, 0xfc, 0xfc, 0xed, 0x5e, 0x3e, 0xfd, 0xed, 0x47, 0xcd,
|
||
0x53, 0xeb, 0xcd, 0x50, 0xeb, 0xcd, 0x13, 0x65, 0xfb, 0x21, 0x9b, 0x6e, 0x11, 0x00, 0x77, 0x01,
|
||
0xc8, 0x00, 0xed, 0xb0, 0x21, 0x77, 0x6b, 0x11, 0x00, 0x76, 0x0e, 0x28, 0xed, 0xb0, 0x21, 0x9f,
|
||
0x6b, 0x11, 0x5c, 0x76, 0x0e, 0x09, 0xed, 0xb0, 0x11, 0x00, 0x78, 0x3e, 0x40, 0x32, 0x8e, 0x76,
|
||
0xcd, 0xf4, 0x62, 0x21, 0x00, 0x78, 0x11, 0x00, 0x81, 0x06, 0x08, 0xc5, 0xcd, 0xd9, 0x63, 0x24,
|
||
0x14, 0xc1, 0x10, 0xf7, 0x21, 0x00, 0x77, 0xcd, 0x25, 0x64, 0xcd, 0x25, 0x64, 0xcd, 0x25, 0x64,
|
||
0x11, 0x00, 0x8a, 0x3e, 0x80, 0x32, 0x8e, 0x76, 0xcd, 0xf4, 0x62, 0x21, 0x00, 0x8a, 0x11, 0x00,
|
||
0x93, 0x06, 0x08, 0xc5, 0xcd, 0xd9, 0x63, 0x24, 0x14, 0xc1, 0x10, 0xf7, 0x06, 0x11, 0x21, 0x00,
|
||
0x8a, 0xc5, 0xcd, 0x25, 0x64, 0x24, 0xc1, 0x10, 0xf8, 0xcd, 0xc9, 0x6d, 0x3e, 0xff, 0x32, 0xb0,
|
||
0xb3, 0x3c, 0x32, 0xb1, 0xb3, 0x3e, 0x05, 0x32, 0xb2, 0xb3, 0x3e, 0x08, 0x32, 0xb3, 0xb3, 0x3e,
|
||
0x0e, 0x32, 0xb4, 0xb3, 0xcd, 0x61, 0x64, 0x3a, 0xb0, 0xb3, 0x3c, 0x32, 0xb0, 0xb3, 0x3a, 0xb0,
|
||
0xb3, 0xe6, 0x01, 0xfe, 0x01, 0x20, 0x18, 0x21, 0x84, 0xac, 0x22, 0x87, 0x64, 0xcd, 0x85, 0x64,
|
||
0xcd, 0x85, 0x64, 0x21, 0xfc, 0xac, 0x22, 0x87, 0x64, 0xcd, 0x85, 0x64, 0xcd, 0x85, 0x64, 0x3a,
|
||
0xb0, 0xb3, 0xe6, 0x03, 0xfe, 0x03, 0x20, 0x21, 0x21, 0x00, 0x40, 0x11, 0x00, 0x78, 0x01, 0xb1,
|
||
0xb3, 0xcd, 0xdd, 0x64, 0x21, 0x1b, 0x40, 0x11, 0x00, 0x8a, 0x01, 0xb2, 0xb3, 0xcd, 0xdd, 0x64,
|
||
0x21, 0x74, 0xad, 0x22, 0x87, 0x64, 0xcd, 0x85, 0x64, 0x3a, 0xb0, 0xb3, 0xe6, 0x07, 0xfe, 0x07,
|
||
0x20, 0xa5, 0x21, 0x60, 0x50, 0x11, 0x00, 0x8a, 0x01, 0xb3, 0xb3, 0xcd, 0xdd, 0x64, 0x21, 0x7b,
|
||
0x50, 0x11, 0x00, 0x78, 0x01, 0xb4, 0xb3, 0xcd, 0xdd, 0x64, 0x18, 0x8b, 0xfd, 0x21, 0x5c, 0x76,
|
||
0x0e, 0x08, 0x21, 0x00, 0x77, 0x06, 0x28, 0xdd, 0x21, 0x00, 0x76, 0xcd, 0x3e, 0x63, 0xc5, 0x06,
|
||
0x05, 0xdd, 0x7e, 0x00, 0xe6, 0x3f, 0xcd, 0x57, 0x63, 0xdd, 0x2c, 0x10, 0xf4, 0x0d, 0x20, 0xef,
|
||
0xc1, 0xcd, 0x67, 0x63, 0x10, 0xe1, 0x14, 0x1e, 0x00, 0x0d, 0x20, 0xd6, 0xeb, 0x11, 0x00, 0x76,
|
||
0x3a, 0x8e, 0x76, 0x47, 0x2c, 0x2c, 0x1a, 0xb8, 0x38, 0x02, 0x36, 0x18, 0x2c, 0x2c, 0x2c, 0x1c,
|
||
0x7d, 0xfe, 0xc8, 0x20, 0xef, 0xc9, 0xd9, 0x21, 0x98, 0x76, 0x11, 0x99, 0x76, 0x01, 0x27, 0x00,
|
||
0x70, 0xed, 0xb0, 0xd9, 0x79, 0x32, 0x52, 0x63, 0xfd, 0x7e, 0x00, 0x32, 0xc0, 0x76, 0xc9, 0xdd,
|
||
0xe5, 0xdd, 0x21, 0x98, 0x76, 0x32, 0x62, 0x63, 0xdd, 0x36, 0x00, 0x01, 0xdd, 0xe1, 0xc9, 0xc5,
|
||
0xfd, 0xe5, 0xd5, 0xe5, 0xdd, 0xe1, 0xe5, 0x3a, 0xc0, 0x76, 0xe6, 0xf8, 0x0f, 0x0f, 0x0f, 0x4f,
|
||
0x06, 0x00, 0xeb, 0x09, 0xe5, 0xfd, 0xe1, 0x21, 0x98, 0x76, 0x3a, 0xc0, 0x76, 0xe6, 0x07, 0x4f,
|
||
0x3e, 0x07, 0x91, 0x4f, 0x16, 0x05, 0x1e, 0x7e, 0x7b, 0x32, 0x98, 0x63, 0xaf, 0xdd, 0xcb, 0x00,
|
||
0x46, 0x28, 0x02, 0x3e, 0x40, 0x08, 0x7e, 0xfe, 0x01, 0x20, 0x1b, 0x06, 0x86, 0x08, 0xb0, 0x47,
|
||
0x79, 0x07, 0x07, 0x07, 0xb0, 0x32, 0xb3, 0x63, 0xfd, 0xcb, 0x00, 0x86, 0x0d, 0x79, 0xfe, 0xff,
|
||
0x20, 0x04, 0xfd, 0x2c, 0x0e, 0x07, 0x2c, 0x7b, 0xd6, 0x08, 0x5f, 0xfe, 0x3e, 0x20, 0xc9, 0xdd,
|
||
0x23, 0x15, 0x20, 0xc2, 0xe1, 0xd1, 0x01, 0x05, 0x00, 0x09, 0xeb, 0x09, 0xeb, 0xfd, 0xe1, 0xc1,
|
||
0xc9, 0xe5, 0xdd, 0xe1, 0xd5, 0xfd, 0xe1, 0x06, 0x28, 0xc5, 0xdd, 0x4e, 0x00, 0xcd, 0x1c, 0x64,
|
||
0xdd, 0x7e, 0x04, 0xfd, 0x71, 0x04, 0x4f, 0xcd, 0x1c, 0x64, 0xfd, 0x71, 0x00, 0xdd, 0x4e, 0x01,
|
||
0xcd, 0x1c, 0x64, 0xdd, 0x7e, 0x03, 0xfd, 0x71, 0x03, 0x4f, 0xcd, 0x1c, 0x64, 0xfd, 0x71, 0x01,
|
||
0xdd, 0x4e, 0x02, 0xcd, 0x1c, 0x64, 0xfd, 0x71, 0x02, 0x01, 0x05, 0x00, 0xdd, 0x09, 0xfd, 0x09,
|
||
0xc1, 0x10, 0xc6, 0xc9, 0x06, 0x08, 0xcb, 0x19, 0x17, 0x10, 0xfb, 0x4f, 0xc9, 0xe5, 0x11, 0x00,
|
||
0x9c, 0x06, 0x05, 0xc5, 0xe5, 0x06, 0x08, 0xc5, 0xe5, 0x06, 0x28, 0xc5, 0xcb, 0x16, 0xd5, 0x06,
|
||
0x05, 0x1a, 0x1f, 0x12, 0x1c, 0x10, 0xfa, 0xd1, 0x01, 0x05, 0x00, 0x09, 0xc1, 0x10, 0xec, 0x1c,
|
||
0x1c, 0x1c, 0x1c, 0x1c, 0xe1, 0xc1, 0x10, 0xdf, 0xe1, 0xc1, 0x23, 0x10, 0xd6, 0xd1, 0xd5, 0x21,
|
||
0x00, 0x9c, 0x01, 0xc8, 0x00, 0xed, 0xb0, 0xe1, 0xc9, 0xdd, 0x21, 0x84, 0xac, 0x06, 0x3c, 0xdd,
|
||
0x6e, 0x00, 0xdd, 0x66, 0x01, 0xdd, 0x7e, 0x04, 0x32, 0x75, 0x64, 0xaf, 0xcb, 0x46, 0x28, 0x02,
|
||
0x3e, 0x01, 0xdd, 0x77, 0x05, 0x11, 0x06, 0x00, 0xdd, 0x19, 0x10, 0xe3, 0xc9, 0xdd, 0x21, 0x84,
|
||
0xac, 0x06, 0x14, 0xc5, 0xdd, 0x6e, 0x00, 0xdd, 0x66, 0x01, 0xdd, 0x56, 0x02, 0xdd, 0x5e, 0x03,
|
||
0xdd, 0x7e, 0x05, 0xfe, 0x01, 0x7a, 0x20, 0x01, 0x7b, 0x32, 0xa5, 0x64, 0xcb, 0x86, 0x24, 0x7c,
|
||
0xe6, 0x07, 0x20, 0x18, 0x7c, 0xd6, 0x08, 0x67, 0x7d, 0xc6, 0x20, 0x6f, 0xe6, 0xe0, 0x20, 0x0c,
|
||
0x7c, 0xc6, 0x08, 0x67, 0xe6, 0x18, 0xfe, 0x18, 0x20, 0x02, 0x26, 0x40, 0xdd, 0x75, 0x00, 0xdd,
|
||
0x74, 0x01, 0x06, 0x01, 0xcd, 0x67, 0x64, 0x3a, 0xa5, 0x64, 0xcb, 0xf7, 0x32, 0xd8, 0x64, 0xcb,
|
||
0xc6, 0xc1, 0x10, 0xaf, 0xc9, 0x0a, 0xc5, 0x4f, 0x06, 0x00, 0xdd, 0x21, 0xe0, 0x6a, 0xdd, 0x09,
|
||
0xdd, 0x7e, 0x00, 0x82, 0x57, 0xcd, 0xf7, 0x64, 0xe1, 0x7e, 0x3c, 0xe6, 0x1f, 0x77, 0xc9, 0x06,
|
||
0x05, 0xc5, 0x06, 0x08, 0xc5, 0x01, 0x05, 0x00, 0xeb, 0xed, 0xb0, 0xeb, 0x01, 0xfb, 0x00, 0x09,
|
||
0xc1, 0x10, 0xf1, 0x01, 0x20, 0xf8, 0x09, 0xc1, 0x10, 0xe7, 0xc9, 0x11, 0x9b, 0x6e, 0xd5, 0xd5,
|
||
0xd5, 0x21, 0x00, 0x40, 0xcd, 0xf7, 0x64, 0x21, 0x1b, 0x40, 0xd1, 0xcd, 0xf7, 0x64, 0x21, 0x60,
|
||
0x50, 0xd1, 0xcd, 0xf7, 0x64, 0x21, 0x7b, 0x50, 0xd1, 0xcd, 0xf7, 0x64, 0x11, 0x00, 0xa9, 0x21,
|
||
0x06, 0x40, 0xcd, 0xf7, 0x64, 0x11, 0xc8, 0xa9, 0x21, 0x0b, 0x40, 0xcd, 0xf7, 0x64, 0x11, 0x90,
|
||
0xaa, 0x21, 0x10, 0x40, 0xcd, 0xf7, 0x64, 0x11, 0x58, 0xab, 0x21, 0x15, 0x40, 0xcd, 0xf7, 0x64,
|
||
0x11, 0x06, 0x58, 0x21, 0x20, 0xac, 0x06, 0x05, 0xc5, 0x01, 0x14, 0x00, 0xed, 0xb0, 0x01, 0x0c,
|
||
0x00, 0xeb, 0x09, 0xeb, 0xc1, 0x10, 0xf1, 0xcd, 0xc2, 0x6c, 0x21, 0x00, 0xa5, 0x22, 0x36, 0x5c,
|
||
0x21, 0x00, 0x6b, 0xcd, 0x23, 0x67, 0x21, 0x00, 0x40, 0x11, 0x00, 0xc0, 0x01, 0x00, 0x1b, 0xed,
|
||
0xb0, 0xcd, 0x44, 0x6e, 0x21, 0x00, 0xc0, 0x11, 0x00, 0x40, 0x01, 0x00, 0x1b, 0xed, 0xb0, 0xcd,
|
||
0x33, 0x69, 0x3e, 0x01, 0x32, 0xbf, 0xb3, 0xdd, 0x21, 0x00, 0x9d, 0xcd, 0xca, 0x65, 0xcd, 0x4b,
|
||
0x68, 0x7e, 0x32, 0xcb, 0xb3, 0xdd, 0x22, 0xc1, 0xb3, 0x21, 0x00, 0x00, 0x22, 0x78, 0x5c, 0xaf,
|
||
0x32, 0xac, 0xde, 0x21, 0x00, 0x40, 0x11, 0x00, 0xc0, 0x01, 0x00, 0x1b, 0xed, 0xb0, 0xcd, 0x61,
|
||
0x64, 0xc9, 0xdd, 0xe5, 0xe1, 0xaf, 0x32, 0x78, 0x5c, 0x16, 0x00, 0x7e, 0xcd, 0x50, 0x67, 0xa7,
|
||
0x28, 0x22, 0xcd, 0x3a, 0x67, 0x7e, 0xa3, 0xfe, 0x42, 0x20, 0x01, 0x14, 0xfe, 0x43, 0xf5, 0x01,
|
||
0x05, 0x00, 0x09, 0xf1, 0x20, 0x06, 0x7e, 0xfe, 0xc0, 0x20, 0x01, 0x14, 0x23, 0x23, 0x23, 0x7c,
|
||
0xfe, 0xa5, 0x20, 0xd7, 0x7a, 0x32, 0xb5, 0xb3, 0x21, 0x00, 0x00, 0x22, 0xb8, 0xb3, 0x22, 0xba,
|
||
0xb3, 0x22, 0xbc, 0xb3, 0xa7, 0x20, 0x12, 0x21, 0x44, 0x6b, 0xcd, 0x23, 0x67, 0x21, 0x0b, 0x09,
|
||
0x22, 0xb6, 0xb3, 0x3e, 0x0e, 0x32, 0xbe, 0xb3, 0xc9, 0xfe, 0x0d, 0x30, 0x22, 0x32, 0xbb, 0xb3,
|
||
0x21, 0x06, 0x0e, 0x22, 0xb6, 0xb3, 0x3e, 0x01, 0x32, 0xb8, 0xb3, 0x32, 0xc0, 0xb3, 0x3e, 0x08,
|
||
0x32, 0xbe, 0xb3, 0xdd, 0xe5, 0xe1, 0x01, 0x06, 0x0a, 0x1e, 0x41, 0xcd, 0x91, 0x66, 0xc9, 0xfe,
|
||
0x19, 0x30, 0x38, 0xa7, 0x1f, 0x32, 0xbc, 0xb3, 0xce, 0x00, 0x32, 0xbb, 0xb3, 0x21, 0x06, 0x06,
|
||
0x22, 0xb6, 0xb3, 0x3e, 0x02, 0x32, 0xb8, 0xb3, 0x3d, 0x32, 0xc0, 0xb3, 0x3e, 0x08, 0x32, 0xbe,
|
||
0xb3, 0xdd, 0xe5, 0xe1, 0x01, 0x06, 0x02, 0x1e, 0x41, 0x3a, 0xbb, 0xb3, 0x57, 0xcd, 0x91, 0x66,
|
||
0x01, 0x06, 0x12, 0x3a, 0xbc, 0xb3, 0x57, 0xcd, 0x91, 0x66, 0xc9, 0x3e, 0x18, 0xcd, 0x4b, 0x66,
|
||
0x22, 0xc3, 0xb3, 0x3e, 0x01, 0x32, 0xb9, 0xb3, 0xc9, 0xed, 0x43, 0xcf, 0xb3, 0xd5, 0x7e, 0xcd,
|
||
0x50, 0x67, 0x1e, 0xff, 0xcd, 0x3a, 0x67, 0x16, 0x06, 0x7e, 0xa3, 0xfe, 0x42, 0x28, 0x14, 0xfe,
|
||
0x43, 0xf5, 0x01, 0x05, 0x00, 0x09, 0xf1, 0x20, 0x05, 0x7e, 0xfe, 0xc0, 0x28, 0x0b, 0x23, 0x23,
|
||
0x23, 0x18, 0xdb, 0x01, 0x05, 0x00, 0x09, 0x16, 0x04, 0x01, 0x0d, 0x00, 0xa7, 0xed, 0x42, 0x7a,
|
||
0x32, 0xda, 0xb3, 0x11, 0xdb, 0xb3, 0x06, 0x08, 0x7e, 0xfe, 0x20, 0x30, 0x02, 0x3e, 0x2e, 0xfe,
|
||
0x80, 0x38, 0x02, 0x3e, 0x2e, 0x12, 0x13, 0x23, 0x10, 0xee, 0x3e, 0xff, 0x12, 0xd1, 0xe5, 0x6b,
|
||
0x26, 0x3e, 0x22, 0xd5, 0xb3, 0x21, 0x20, 0x20, 0x22, 0xd7, 0xb3, 0x3e, 0x10, 0x32, 0xd9, 0xb3,
|
||
0x3e, 0x16, 0x32, 0xce, 0xb3, 0x21, 0x13, 0x01, 0x22, 0xd1, 0xb3, 0x21, 0x10, 0x05, 0x22, 0xd3,
|
||
0xb3, 0xd5, 0x21, 0xce, 0xb3, 0xcd, 0x23, 0x67, 0xd1, 0xe1, 0x01, 0x08, 0x00, 0x09, 0x3a, 0xcf,
|
||
0xb3, 0x3c, 0x32, 0xcf, 0xb3, 0x1c, 0x15, 0xc2, 0x95, 0x66, 0xc9, 0xe5, 0x2a, 0xca, 0xaf, 0xd9,
|
||
0xfd, 0x2a, 0xc8, 0xaf, 0x3e, 0x02, 0xcd, 0x01, 0x16, 0xe1, 0x7e, 0xfe, 0xff, 0xc8, 0xd7, 0x23,
|
||
0x18, 0xf8, 0xd5, 0x0e, 0x00, 0x06, 0x09, 0x11, 0x6e, 0x6b, 0x1a, 0xbe, 0x28, 0x02, 0x0e, 0xff,
|
||
0x23, 0x13, 0x10, 0xf6, 0xd1, 0x59, 0x2b, 0xc9, 0xfe, 0x01, 0xc0, 0x01, 0x10, 0x00, 0x09, 0x7e,
|
||
0x18, 0xf6, 0xfd, 0xe5, 0xdd, 0xe5, 0xe5, 0xd5, 0xc5, 0xf5, 0xd9, 0xe5, 0xd5, 0xc5, 0x2a, 0xca,
|
||
0xaf, 0xd9, 0x08, 0xf5, 0xfd, 0x2a, 0xc8, 0xaf, 0xcd, 0x56, 0xeb, 0x2a, 0x78, 0x5c, 0x23, 0x22,
|
||
0x78, 0x5c, 0x3a, 0xac, 0xde, 0xc6, 0x02, 0x32, 0xac, 0xde, 0xcd, 0xa8, 0x6b, 0xcd, 0x07, 0x6d,
|
||
0x3a, 0x78, 0x5c, 0xe6, 0x03, 0xfe, 0x03, 0x20, 0x21, 0xcd, 0x4b, 0x68, 0xed, 0x5b, 0xbe, 0xb3,
|
||
0x43, 0x72, 0x23, 0x10, 0xfc, 0xcb, 0x72, 0xcb, 0xf2, 0x28, 0x0b, 0xcb, 0xb2, 0x14, 0xcb, 0x5a,
|
||
0x28, 0x04, 0x14, 0x14, 0xcb, 0x9a, 0x7a, 0x32, 0xbf, 0xb3, 0x3a, 0x78, 0x5c, 0xfe, 0x32, 0x20,
|
||
0x58, 0x2a, 0xb6, 0xb3, 0x22, 0xcc, 0xb3, 0x3a, 0xbe, 0xb3, 0x32, 0xec, 0xb3, 0x21, 0xcc, 0xb3,
|
||
0x22, 0x4d, 0x68, 0xcd, 0x4b, 0x68, 0x2a, 0xc9, 0xb3, 0x7c, 0x07, 0x07, 0x07, 0xf6, 0xc0, 0x67,
|
||
0x22, 0xae, 0xde, 0x3a, 0xec, 0xb3, 0x47, 0xc5, 0xe5, 0x11, 0xed, 0xb3, 0xd5, 0x06, 0x08, 0x7e,
|
||
0x12, 0x24, 0x13, 0x10, 0xfa, 0xe1, 0xd1, 0xd5, 0x06, 0x08, 0x0e, 0x08, 0xe5, 0xcb, 0x16, 0x1f,
|
||
0x23, 0x0d, 0x20, 0xf9, 0x12, 0x14, 0xe1, 0x10, 0xf1, 0xe1, 0x23, 0xc1, 0x10, 0xd9, 0x21, 0xb6,
|
||
0xb3, 0x22, 0x4d, 0x68, 0xcd, 0xa5, 0x6c, 0x18, 0x1f, 0xfe, 0x3c, 0x28, 0xb0, 0xfe, 0x46, 0x28,
|
||
0xac, 0xfe, 0x50, 0x28, 0xa8, 0xfe, 0x5a, 0x20, 0x0f, 0x3e, 0xc9, 0x32, 0xdb, 0x67, 0xcd, 0xc5,
|
||
0x67, 0x3e, 0x3a, 0x32, 0xdb, 0x67, 0x18, 0xd6, 0x3a, 0x78, 0x5c, 0xe6, 0x07, 0xfe, 0x07, 0xcc,
|
||
0x67, 0x68, 0xd9, 0xf1, 0x08, 0xc1, 0xd1, 0xe1, 0xd9, 0xf1, 0xc1, 0xd1, 0xe1, 0xdd, 0xe1, 0xfd,
|
||
0xe1, 0xfb, 0xc9, 0xed, 0x5b, 0xb6, 0xb3, 0x21, 0x00, 0x00, 0x01, 0x20, 0x00, 0x7b, 0xa7, 0x28,
|
||
0x04, 0x09, 0x1d, 0x18, 0xf8, 0x4a, 0x09, 0x22, 0xc9, 0xb3, 0x01, 0x00, 0x58, 0x09, 0xc9, 0x0e,
|
||
0x41, 0x21, 0x56, 0x6b, 0x7e, 0x0f, 0x0f, 0xe6, 0x38, 0xf6, 0x87, 0x32, 0x79, 0x68, 0x3e, 0xff,
|
||
0xcb, 0x87, 0xdb, 0xfe, 0x2f, 0x47, 0x7e, 0xe6, 0x1f, 0xa0, 0xc4, 0x54, 0x6a, 0x0c, 0x23, 0x79,
|
||
0xfe, 0x59, 0x20, 0xe0, 0x3e, 0xf7, 0xdb, 0xfe, 0x1f, 0xd4, 0x6a, 0x69, 0x1f, 0xd4, 0x6a, 0x69,
|
||
0x1f, 0xd4, 0xc3, 0x69, 0x1f, 0xd4, 0x3d, 0x6a, 0x1f, 0xd4, 0x42, 0x6a, 0x3e, 0xef, 0xdb, 0xfe,
|
||
0x1f, 0xd4, 0x42, 0x6a, 0x1f, 0xd4, 0x3d, 0x6a, 0x1f, 0xd4, 0xc3, 0x69, 0x1f, 0xd4, 0x6a, 0x69,
|
||
0x1f, 0xd4, 0x6a, 0x69, 0x3e, 0x00, 0x1f, 0xdc, 0x6a, 0x69, 0x1f, 0xdc, 0x6a, 0x69, 0x1f, 0xdc,
|
||
0xc3, 0x69, 0x1f, 0xdc, 0x3d, 0x6a, 0x1f, 0xdc, 0x42, 0x6a, 0x3e, 0xfe, 0xdb, 0xfe, 0x1f, 0x38,
|
||
0x0f, 0x2a, 0xc1, 0xb3, 0x01, 0x01, 0x9d, 0xa7, 0xed, 0x42, 0x38, 0x04, 0xcd, 0x89, 0x65, 0xc9,
|
||
0x3e, 0xbf, 0xdb, 0xfe, 0x1f, 0xd4, 0x42, 0x6a, 0x3e, 0x7f, 0xdb, 0xfe, 0x1f, 0x38, 0x21, 0x2a,
|
||
0xca, 0xaf, 0xd9, 0xfd, 0x2a, 0xc8, 0xaf, 0xcd, 0x44, 0x6e, 0x21, 0x00, 0x9d, 0x11, 0x00, 0x00,
|
||
0x01, 0x05, 0x08, 0xf3, 0xed, 0x56, 0xcd, 0x13, 0x3d, 0xf3, 0xed, 0x5e, 0xcd, 0x89, 0x65, 0xc9,
|
||
0x1f, 0xd8, 0x3a, 0xb9, 0xb3, 0xa7, 0xc8, 0x2a, 0xc3, 0xb3, 0xaf, 0x32, 0xb9, 0xb3, 0x22, 0xa1,
|
||
0x65, 0xcd, 0x89, 0x65, 0x21, 0x00, 0x9d, 0x22, 0xa1, 0x65, 0xc9, 0x21, 0xc0, 0x40, 0x0e, 0x60,
|
||
0x06, 0x20, 0x36, 0x00, 0x2c, 0x10, 0xfb, 0x0d, 0x28, 0x1a, 0x7d, 0xd6, 0x20, 0x6f, 0x24, 0x7c,
|
||
0xe6, 0x07, 0x20, 0xec, 0x7c, 0xd6, 0x08, 0x67, 0x7d, 0xc6, 0x20, 0x6f, 0x20, 0xe2, 0x7c, 0xc6,
|
||
0x08, 0x67, 0x18, 0xdc, 0x21, 0xc0, 0x58, 0x11, 0xc1, 0x58, 0x01, 0x7f, 0x01, 0x36, 0x07, 0xed,
|
||
0xb0, 0xc9, 0xf5, 0x3a, 0xbc, 0xb3, 0xa7, 0x20, 0x02, 0xf1, 0xc9, 0xcd, 0x4b, 0x68, 0x3a, 0xbe,
|
||
0xb3, 0x47, 0x3a, 0xcb, 0xb3, 0x77, 0x23, 0x10, 0xfc, 0x3a, 0xbb, 0xb3, 0x47, 0x3a, 0xc0, 0xb3,
|
||
0x4f, 0x3d, 0x90, 0x30, 0x23, 0xfe, 0xff, 0x20, 0x13, 0x2a, 0xbb, 0xb3, 0x7c, 0xbd, 0x28, 0x0c,
|
||
0x3e, 0x01, 0x32, 0xc0, 0xb3, 0x3e, 0x06, 0x32, 0xb6, 0xb3, 0x18, 0x16, 0x79, 0x80, 0x32, 0xc0,
|
||
0xb3, 0x3e, 0x16, 0x32, 0xb7, 0xb3, 0x18, 0x0a, 0x79, 0x90, 0x32, 0xc0, 0xb3, 0x3e, 0x06, 0x32,
|
||
0xb7, 0xb3, 0xcd, 0x4b, 0x68, 0x7e, 0x32, 0xcb, 0xb3, 0xf1, 0xc9, 0xf5, 0x06, 0x00, 0x3a, 0xbc,
|
||
0xb3, 0xa7, 0x20, 0x09, 0x3a, 0xbb, 0xb3, 0xa7, 0x28, 0x9f, 0x3d, 0x28, 0x9c, 0xc5, 0xcd, 0x4b,
|
||
0x68, 0x3a, 0xbe, 0xb3, 0x47, 0x3a, 0xcb, 0xb3, 0x77, 0x23, 0x10, 0xfc, 0xc1, 0x3a, 0xc0, 0xb3,
|
||
0x4f, 0xed, 0x5b, 0xbb, 0xb3, 0x3a, 0xb6, 0xb3, 0x6f, 0x3a, 0xb7, 0xb3, 0xfe, 0x16, 0x28, 0x21,
|
||
0x78, 0xa7, 0x20, 0x0e, 0x79, 0xbb, 0x3e, 0x06, 0x26, 0x01, 0x28, 0x2f, 0x61, 0x24, 0x7d, 0x3c,
|
||
0x18, 0x29, 0x79, 0xfe, 0x01, 0x20, 0x04, 0x63, 0x7b, 0x18, 0x1e, 0x61, 0x25, 0x7d, 0x3d, 0x18,
|
||
0x1a, 0x78, 0xa7, 0x20, 0x0b, 0x7b, 0x82, 0xb9, 0x20, 0xe2, 0x63, 0x24, 0x3e, 0x06, 0x18, 0x0b,
|
||
0x7b, 0x3c, 0xb9, 0x20, 0xe6, 0x7b, 0x82, 0x67, 0x7a, 0xc6, 0x05, 0x32, 0xb6, 0xb3, 0x7c, 0x32,
|
||
0xc0, 0xb3, 0xc3, 0xba, 0x69, 0x06, 0x01, 0xf5, 0x18, 0x84, 0xf5, 0x3a, 0xbb, 0xb3, 0x47, 0x3a,
|
||
0xbc, 0xb3, 0xb0, 0xca, 0x71, 0x69, 0x3a, 0xc0, 0xb3, 0xc6, 0x40, 0x4f, 0x3a, 0xb5, 0xb3, 0xc6,
|
||
0x40, 0xb9, 0xd8, 0x06, 0x40, 0xd9, 0x2a, 0xc1, 0xb3, 0x7e, 0xcd, 0x50, 0x67, 0x1e, 0xff, 0xcd,
|
||
0x3a, 0x67, 0x16, 0xec, 0x7e, 0xa3, 0xfe, 0x42, 0x28, 0x14, 0xfe, 0x43, 0xf5, 0x01, 0x05, 0x00,
|
||
0x09, 0xf1, 0x20, 0x05, 0x7e, 0xfe, 0xc0, 0x28, 0x0b, 0x23, 0x23, 0x23, 0x18, 0xdb, 0x01, 0x05,
|
||
0x00, 0x09, 0x16, 0xf7, 0x01, 0x0d, 0x00, 0xa7, 0xed, 0x42, 0xd9, 0x04, 0x78, 0xb9, 0xd9, 0x7e,
|
||
0x36, 0x01, 0x20, 0xc5, 0x77, 0xd5, 0xe5, 0x21, 0x4c, 0x5d, 0x72, 0x23, 0x23, 0xeb, 0xe1, 0x01,
|
||
0x08, 0x00, 0xed, 0xb0, 0x13, 0x0e, 0x20, 0xe1, 0x7c, 0xfe, 0xf7, 0x28, 0x02, 0x0e, 0xaf, 0x79,
|
||
0x12, 0x21, 0x00, 0x00, 0x22, 0x78, 0x5c, 0x3a, 0xce, 0xaf, 0xed, 0x47, 0x2a, 0xca, 0xaf, 0xd9,
|
||
0xfd, 0x2a, 0xc8, 0xaf, 0xed, 0x7b, 0xcc, 0xaf, 0x21, 0x00, 0x3c, 0x22, 0x36, 0x5c, 0xcd, 0x4b,
|
||
0x6e, 0xcd, 0x75, 0x6e, 0xed, 0x56, 0xfb, 0xc9, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||
0x08, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x16, 0x13, 0x07, 0x13, 0x01, 0x10, 0x05, 0x53,
|
||
0x50, 0x41, 0x43, 0x45, 0x20, 0x20, 0x54, 0x4f, 0x20, 0x4e, 0x45, 0x57, 0x20, 0x44, 0x49, 0x53,
|
||
0x4b, 0x16, 0x14, 0x07, 0x22, 0x53, 0x53, 0x22, 0x20, 0x54, 0x4f, 0x20, 0x4e, 0x45, 0x58, 0x54,
|
||
0x20, 0x50, 0x41, 0x47, 0x45, 0x53, 0x16, 0x15, 0x07, 0x22, 0x43, 0x53, 0x22, 0x20, 0x54, 0x4f,
|
||
0x20, 0x46, 0x49, 0x52, 0x53, 0x54, 0x20, 0x50, 0x41, 0x47, 0x45, 0xff, 0x16, 0x0b, 0x09, 0x4e,
|
||
0x4f, 0x20, 0x45, 0x58, 0x45, 0x20, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x20, 0x21, 0xff, 0x21, 0xf0,
|
||
0x08, 0x24, 0x44, 0x28, 0x30, 0xd0, 0xa4, 0xc8, 0xc4, 0xc2, 0xe4, 0xe8, 0xa2, 0xa1, 0x41, 0x48,
|
||
0x22, 0x50, 0xa8, 0x10, 0x42, 0x04, 0x62, 0x6f, 0x6f, 0x74, 0x20, 0x20, 0x20, 0x20, 0x42, 0x08,
|
||
0x10, 0x13, 0x17, 0x1f, 0x05, 0x0c, 0x15, 0x1b, 0x22, 0x01, 0x03, 0x0a, 0x1d, 0x24, 0x27, 0x07,
|
||
0x0e, 0x19, 0x20, 0x02, 0x0b, 0x12, 0x16, 0x1c, 0x26, 0x00, 0x0f, 0x1e, 0x23, 0x09, 0x04, 0x11,
|
||
0x18, 0x25, 0x14, 0x06, 0x0d, 0x1a, 0x21, 0x13, 0x12, 0x0f, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x00,
|
||
0x3a, 0xac, 0xde, 0xa7, 0x20, 0x20, 0x2a, 0xa8, 0xde, 0x23, 0x7c, 0xe6, 0x07, 0x67, 0x22, 0xa8,
|
||
0xde, 0x06, 0x08, 0x4e, 0x21, 0xec, 0xad, 0xed, 0x5f, 0xae, 0xa9, 0x81, 0x4f, 0x3a, 0xb0, 0xb3,
|
||
0xa9, 0x77, 0x23, 0x10, 0xf2, 0xc9, 0x3a, 0xac, 0xde, 0xe6, 0x3f, 0xfe, 0x3e, 0x20, 0x21, 0x3a,
|
||
0xb0, 0xde, 0x3c, 0xe6, 0x07, 0x32, 0xb0, 0xde, 0x28, 0x08, 0x3a, 0xac, 0xde, 0xd6, 0x02, 0x32,
|
||
0xac, 0xde, 0x3e, 0xc9, 0x32, 0x1c, 0x6c, 0xcd, 0x00, 0x6c, 0x3e, 0x3a, 0x32, 0x1c, 0x6c, 0xc9,
|
||
0x3a, 0xac, 0xde, 0xe6, 0x07, 0xfe, 0x02, 0xc0, 0x3a, 0xac, 0xde, 0x07, 0x07, 0x07, 0xe6, 0x06,
|
||
0x4f, 0x06, 0x00, 0x21, 0xec, 0xad, 0x09, 0xcd, 0x59, 0x6c, 0xf5, 0xd4, 0xae, 0x6b, 0xf1, 0x30,
|
||
0xe7, 0xcd, 0x74, 0x6c, 0x3a, 0xac, 0xde, 0xe6, 0x20, 0x0e, 0x60, 0x20, 0x02, 0x0e, 0x00, 0x3a,
|
||
0xac, 0xde, 0x07, 0x07, 0xa9, 0xe6, 0x60, 0x4f, 0x06, 0x00, 0x21, 0x63, 0x6f, 0x09, 0xeb, 0x06,
|
||
0x10, 0x2a, 0xaa, 0xde, 0x4e, 0x1a, 0xb1, 0x77, 0x2c, 0x13, 0x4e, 0x1a, 0xb1, 0x77, 0x13, 0x2d,
|
||
0x24, 0x7c, 0xe6, 0x07, 0x20, 0x08, 0x7c, 0xd6, 0x08, 0x67, 0x7d, 0xc6, 0x20, 0x6f, 0x10, 0xe4,
|
||
0xc9, 0x06, 0x1a, 0x23, 0x7e, 0xe6, 0x18, 0x28, 0x06, 0xfe, 0x10, 0x28, 0x02, 0x06, 0x1f, 0x2b,
|
||
0x7e, 0xfe, 0xe0, 0xd0, 0xe6, 0x1f, 0xb8, 0xd0, 0xee, 0x1f, 0xb8, 0xc9, 0x23, 0x7e, 0xe6, 0x18,
|
||
0xfe, 0x18, 0x20, 0x02, 0x3e, 0x08, 0x2b, 0x6e, 0xf6, 0x40, 0x67, 0x22, 0xaa, 0xde, 0x06, 0x10,
|
||
0x7c, 0xf6, 0x80, 0x57, 0x5d, 0x1a, 0x77, 0x2c, 0x1c, 0x1a, 0x77, 0x2d, 0x24, 0x7c, 0xe6, 0x07,
|
||
0x20, 0x08, 0x7c, 0xd6, 0x08, 0x67, 0x7d, 0xc6, 0x20, 0x6f, 0x10, 0xe4, 0xc9, 0x2a, 0xae, 0xde,
|
||
0x7c, 0xe6, 0x7f, 0x57, 0x5d, 0x06, 0x08, 0xc5, 0x3a, 0xec, 0xb3, 0x4f, 0x06, 0x00, 0xe5, 0xd5,
|
||
0xed, 0xb0, 0xd1, 0xe1, 0x24, 0x14, 0xc1, 0x10, 0xee, 0xc9, 0x21, 0x00, 0x58, 0xcd, 0xdb, 0x6c,
|
||
0x21, 0x7b, 0x5a, 0xcd, 0xdb, 0x6c, 0x11, 0x1b, 0x58, 0xcd, 0xf2, 0x6c, 0x11, 0x60, 0x5a, 0xcd,
|
||
0xf2, 0x6c, 0xc9, 0x06, 0x05, 0x11, 0xf4, 0xad, 0x0e, 0x05, 0x1a, 0x77, 0x23, 0x0d, 0x20, 0xfb,
|
||
0x13, 0xc5, 0x01, 0x1b, 0x00, 0x09, 0xc1, 0x10, 0xef, 0xc9, 0x06, 0x05, 0xc5, 0x01, 0x05, 0x00,
|
||
0x21, 0xf4, 0xad, 0xed, 0xb0, 0xeb, 0x01, 0x1b, 0x00, 0x09, 0xeb, 0xc1, 0x10, 0xee, 0xc9, 0x3a,
|
||
0x78, 0x5c, 0xfe, 0x40, 0xd0, 0x21, 0x06, 0x58, 0x22, 0x41, 0x6d, 0x21, 0x19, 0x58, 0x22, 0x44,
|
||
0x6d, 0x21, 0x80, 0x58, 0x22, 0x57, 0x6d, 0x3a, 0x79, 0x5c, 0xe6, 0x01, 0x28, 0x12, 0x21, 0x66,
|
||
0x5a, 0x22, 0x41, 0x6d, 0x21, 0x79, 0x5a, 0x22, 0x44, 0x6d, 0x21, 0xe0, 0x5a, 0x22, 0x57, 0x6d,
|
||
0x3a, 0x78, 0x5c, 0xa7, 0x20, 0x09, 0x3e, 0x02, 0x32, 0x06, 0x58, 0x32, 0x19, 0x58, 0xc9, 0xe6,
|
||
0x01, 0xc0, 0x3a, 0x78, 0x5c, 0x0f, 0xe6, 0x1f, 0xfe, 0x1b, 0xd0, 0x4f, 0x06, 0x05, 0x21, 0x80,
|
||
0x58, 0x0d, 0xcd, 0x6d, 0x6d, 0x0c, 0xcd, 0x8d, 0x6d, 0x0c, 0xc5, 0x01, 0x20, 0x00, 0xa7, 0xed,
|
||
0x42, 0xc1, 0x10, 0xed, 0xc9, 0xc5, 0xe5, 0x7d, 0xb1, 0x6f, 0x5d, 0x7c, 0xf6, 0x80, 0x57, 0xe5,
|
||
0xd5, 0xeb, 0x01, 0x03, 0x00, 0xed, 0xb0, 0xe1, 0xd1, 0x7d, 0xee, 0x1f, 0x6f, 0x5d, 0x0e, 0x03,
|
||
0xed, 0xb8, 0xe1, 0xc1, 0xc9, 0xc5, 0xe5, 0x7d, 0xb1, 0x6f, 0xe5, 0xcd, 0xb1, 0x6d, 0x23, 0xcd,
|
||
0xbd, 0x6d, 0x23, 0xcd, 0xb1, 0x6d, 0xe1, 0x7d, 0xee, 0x1f, 0x6f, 0xcd, 0xb1, 0x6d, 0x2b, 0xcd,
|
||
0xbd, 0x6d, 0x2b, 0xcd, 0xb1, 0x6d, 0xe1, 0xc1, 0xc9, 0x7d, 0xe6, 0x1f, 0xfe, 0x06, 0xd8, 0xfe,
|
||
0x1a, 0xd0, 0x36, 0x02, 0xc9, 0x7d, 0xe6, 0x1f, 0xfe, 0x06, 0xd8, 0xfe, 0x1a, 0xd0, 0x36, 0x42,
|
||
0xc9, 0x21, 0x00, 0xa9, 0xcd, 0x38, 0x6e, 0x21, 0xc8, 0xa9, 0xcd, 0x38, 0x6e, 0x21, 0x90, 0xaa,
|
||
0xcd, 0x38, 0x6e, 0x21, 0x58, 0xab, 0xcd, 0x38, 0x6e, 0xf3, 0x11, 0x00, 0xa9, 0x21, 0x66, 0xd0,
|
||
0xcd, 0xf7, 0x64, 0x11, 0xc8, 0xa9, 0x21, 0x6b, 0xd0, 0xcd, 0xf7, 0x64, 0x11, 0x90, 0xaa, 0x21,
|
||
0x70, 0xd0, 0xcd, 0xf7, 0x64, 0x11, 0x58, 0xab, 0x21, 0x75, 0xd0, 0xcd, 0xf7, 0x64, 0x06, 0x05,
|
||
0x21, 0x06, 0xd8, 0x11, 0xe6, 0xda, 0xc5, 0x01, 0x14, 0x00, 0xed, 0xb0, 0x0e, 0x0c, 0x09, 0x0e,
|
||
0x34, 0xa7, 0xeb, 0xed, 0x42, 0xeb, 0xc1, 0x10, 0xed, 0x21, 0x00, 0xd0, 0x11, 0x00, 0x50, 0x01,
|
||
0x00, 0x08, 0xed, 0xb0, 0x21, 0x60, 0xda, 0x11, 0x60, 0x5a, 0x0e, 0xa0, 0xed, 0xb0, 0xfb, 0xc9,
|
||
0xcd, 0x25, 0x64, 0xcd, 0x25, 0x64, 0x54, 0x5d, 0xcd, 0xd9, 0x63, 0xc9, 0x21, 0x30, 0x75, 0xcd,
|
||
0x52, 0x6e, 0xc9, 0x21, 0x67, 0x6e, 0xcd, 0x52, 0x6e, 0xc9, 0xaf, 0x01, 0xfd, 0xff, 0xed, 0x79,
|
||
0xf5, 0x7e, 0x01, 0xfd, 0xbf, 0xed, 0x79, 0x23, 0xf1, 0x3c, 0xfe, 0x0e, 0xc8, 0x18, 0xec, 0x30,
|
||
0x00, 0x01, 0x00, 0x50, 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0xc4, 0x50, 0x01, 0x16, 0x08, 0x0e,
|
||
0x10, 0x21, 0x00, 0x40, 0x41, 0xaf, 0xcb, 0x1e, 0x23, 0xaf, 0xcb, 0x16, 0x23, 0x10, 0xf6, 0x41,
|
||
0xaf, 0xcb, 0x16, 0x23, 0xaf, 0xcb, 0x1e, 0x23, 0x10, 0xf6, 0x7c, 0xfe, 0x58, 0x20, 0xe5, 0x15,
|
||
0x20, 0xdd, 0xc9, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x72,
|
||
0x00, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x80, 0x00, 0x00, 0x03, 0xd0, 0x40,
|
||
0x00, 0x00, 0x07, 0xa8, 0x20, 0x00, 0x00, 0x0b, 0x54, 0x10, 0x00, 0x00, 0x1e, 0xaa, 0x08, 0x00,
|
||
0x00, 0x2d, 0x55, 0x04, 0x00, 0x00, 0x7a, 0xaa, 0x82, 0x00, 0x00, 0xb5, 0x55, 0x41, 0x00, 0x01,
|
||
0x6a, 0xaa, 0xa0, 0x80, 0x02, 0xd5, 0x45, 0x50, 0x40, 0x05, 0x2a, 0x82, 0xa8, 0x20, 0x09, 0x55,
|
||
0x01, 0x54, 0x10, 0x12, 0xaa, 0x00, 0xaa, 0x08, 0x25, 0x54, 0x00, 0x55, 0x04, 0x22, 0xa8, 0x00,
|
||
0x2a, 0x84, 0x25, 0x50, 0x00, 0x15, 0x44, 0x2a, 0xa4, 0x00, 0x3a, 0xa4, 0x35, 0x42, 0x00, 0x7d,
|
||
0x54, 0x2a, 0xa1, 0x00, 0xba, 0xa8, 0x15, 0x51, 0x01, 0xf5, 0x50, 0x0a, 0xa9, 0x03, 0xea, 0xa0,
|
||
0x05, 0x55, 0x05, 0xd5, 0x40, 0x02, 0xab, 0x0f, 0xaa, 0x80, 0x01, 0x55, 0x17, 0x55, 0x00, 0x00,
|
||
0xaa, 0x2e, 0xaa, 0x00, 0x00, 0x54, 0x55, 0x54, 0x00, 0x00, 0x28, 0x9a, 0xa8, 0x00, 0x00, 0x11,
|
||
0x35, 0x50, 0x00, 0x00, 0x01, 0x2a, 0xa0, 0x00, 0x00, 0x01, 0x55, 0x40, 0x00, 0x00, 0x01, 0xaa,
|
||
0x80, 0x00, 0x00, 0x01, 0x55, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00,
|
||
0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x00, 0x80, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x05, 0xd0, 0x00, 0x80, 0x00,
|
||
0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x90, 0x02, 0x80, 0x01, 0xc0, 0x2f, 0xf4, 0x01, 0xc0, 0x00,
|
||
0xa0, 0x04, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
|
||
0x80, 0x10, 0x08, 0x00, 0x80, 0x04, 0x80, 0x02, 0xa0, 0x01, 0xc0, 0x5f, 0xfd, 0x01, 0xc0, 0x02,
|
||
0x80, 0x04, 0x90, 0x00, 0x88, 0x10, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x10, 0x10, 0x00, 0x10, 0x00,
|
||
0x00, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x7e, 0x24, 0x24, 0x7e, 0x24, 0x00,
|
||
0x00, 0x08, 0x3e, 0x68, 0x3e, 0x0a, 0x7e, 0x08, 0x00, 0x66, 0x4c, 0x18, 0x30, 0x66, 0x4e, 0x00,
|
||
0x18, 0x24, 0x2c, 0x78, 0xda, 0xcc, 0x7e, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x30, 0x18, 0x18, 0x18, 0x18, 0x30, 0x00,
|
||
0x00, 0x00, 0x14, 0x08, 0x7e, 0x18, 0x2c, 0x00, 0x00, 0x00, 0x08, 0x08, 0x7e, 0x18, 0x18, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
|
||
0x38, 0x6c, 0xce, 0xd6, 0xe6, 0x6c, 0x38, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x3e, 0x7c, 0x00,
|
||
0x78, 0xcc, 0x1c, 0x38, 0x70, 0xe6, 0xfe, 0x00, 0x7e, 0xcc, 0x18, 0x3c, 0x0e, 0xce, 0x7c, 0x00,
|
||
0x24, 0x6c, 0xcc, 0xcc, 0xfc, 0x0c, 0x0c, 0x00, 0xfe, 0xc2, 0xf8, 0xcc, 0x0e, 0xce, 0x7c, 0x00,
|
||
0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00, 0x7e, 0x66, 0x0e, 0x1c, 0x38, 0x30, 0x30, 0x00,
|
||
0x7c, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00,
|
||
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30,
|
||
0x00, 0x00, 0x0c, 0x18, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x7e, 0x00, 0x00,
|
||
0x00, 0x00, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0x1c, 0x30, 0x00, 0x30, 0x00,
|
||
0x00, 0x3c, 0x4a, 0x56, 0xfe, 0xc0, 0x7c, 0x00, 0x3c, 0x66, 0xc6, 0xfe, 0xc6, 0xe6, 0x66, 0x00,
|
||
0xf8, 0xcc, 0xcc, 0xfc, 0xc6, 0xc6, 0xfc, 0x00, 0x38, 0x6c, 0xc6, 0xc0, 0xc0, 0xe6, 0x7c, 0x00,
|
||
0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00, 0xfe, 0xe6, 0x60, 0x7c, 0x60, 0xe6, 0xfe, 0x00,
|
||
0xfe, 0xe6, 0x60, 0x7c, 0x60, 0xe0, 0xc0, 0x00, 0x3c, 0x66, 0xc0, 0xde, 0xc6, 0xee, 0x7c, 0x00,
|
||
0xc4, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x46, 0x00, 0x7e, 0x98, 0x30, 0x30, 0x30, 0x1a, 0xfc, 0x00,
|
||
0x3e, 0x0c, 0x0c, 0xe6, 0x66, 0xc6, 0x7c, 0x00, 0xe6, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0xc6, 0x00,
|
||
0xc0, 0xe0, 0x60, 0x60, 0x60, 0xe6, 0xfe, 0x00, 0x46, 0xee, 0xfe, 0xd6, 0xd6, 0xc6, 0x46, 0x00,
|
||
0xc4, 0xe6, 0xf6, 0xde, 0xce, 0xce, 0x46, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xee, 0x7c, 0x00,
|
||
0xfc, 0xe6, 0xc6, 0xce, 0xfc, 0xc0, 0xc0, 0x00, 0x38, 0x6c, 0xc6, 0xd6, 0xce, 0xec, 0x7a, 0x00,
|
||
0xfc, 0xc6, 0xc6, 0xfc, 0xd8, 0xcc, 0xc6, 0x00, 0x3e, 0x66, 0x70, 0x1c, 0xc6, 0xc6, 0x7c, 0x00,
|
||
0xfe, 0xba, 0x18, 0x18, 0x18, 0x38, 0x30, 0x00, 0xe6, 0x66, 0xc6, 0xc6, 0xc6, 0xe6, 0x7c, 0x00,
|
||
0xce, 0xcc, 0xc6, 0xc6, 0x66, 0x7c, 0x38, 0x00, 0xce, 0xc6, 0xd6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00,
|
||
0xc6, 0xee, 0x6c, 0x38, 0x6c, 0xee, 0xc6, 0x00, 0xc6, 0xc6, 0x6e, 0x3c, 0x18, 0x18, 0x18, 0x00,
|
||
0x76, 0xec, 0x98, 0x30, 0x62, 0xde, 0xbc, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x30, 0x30, 0x3c, 0x00,
|
||
0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x1c, 0x04, 0x04, 0x0c, 0x0c, 0x3c, 0x00,
|
||
0x00, 0x08, 0x1c, 0x2a, 0x08, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||
0x00, 0x1c, 0x22, 0x78, 0x60, 0x60, 0xfc, 0x00, 0x00, 0x00, 0x1c, 0x02, 0x3e, 0x66, 0x3e, 0x00,
|
||
0x00, 0x20, 0x20, 0x3c, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x60, 0x60, 0x3c, 0x00,
|
||
0x00, 0x02, 0x02, 0x1e, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x7c, 0x60, 0x3e, 0x00,
|
||
0x00, 0x0c, 0x10, 0x18, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x66, 0x3e, 0x06, 0x3c,
|
||
0x00, 0x20, 0x20, 0x3c, 0x66, 0x66, 0x66, 0x00, 0x00, 0x08, 0x00, 0x08, 0x18, 0x18, 0x3c, 0x00,
|
||
0x00, 0x04, 0x00, 0x04, 0x0c, 0x0c, 0x6c, 0x38, 0x00, 0x20, 0x28, 0x30, 0x70, 0x78, 0x6c, 0x00,
|
||
0x00, 0x10, 0x10, 0x10, 0x30, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x34, 0x2a, 0x6a, 0x6a, 0x6a, 0x00,
|
||
0x00, 0x00, 0x3c, 0x22, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x66, 0x66, 0x3c, 0x00,
|
||
0x00, 0x00, 0x3c, 0x22, 0x66, 0x7c, 0x60, 0x60, 0x00, 0x00, 0x3c, 0x44, 0xcc, 0x7c, 0x0c, 0x0e,
|
||
0x00, 0x00, 0x1c, 0x20, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x3c, 0x06, 0x7c, 0x00,
|
||
0x00, 0x10, 0x38, 0x10, 0x30, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x22, 0x22, 0x66, 0x66, 0x3c, 0x00,
|
||
0x00, 0x00, 0x44, 0x44, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x22, 0x2a, 0x6a, 0x7e, 0x3c, 0x00,
|
||
0x00, 0x00, 0x22, 0x14, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x22, 0x22, 0x66, 0x3e, 0x06, 0x3c,
|
||
0x00, 0x00, 0x3e, 0x04, 0x18, 0x30, 0x7e, 0x00, 0x00, 0x0e, 0x08, 0x30, 0x10, 0x18, 0x1e, 0x00,
|
||
0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x38, 0x08, 0x04, 0x08, 0x18, 0x78, 0x00,
|
||
0x00, 0x12, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x99, 0xa1, 0xa1, 0x99, 0x42, 0x3c,
|
||
0x09, 0x20, 0x00, 0x00, 0x00, 0x05, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x91, 0xc0, 0x00, 0x07, 0xbe,
|
||
0xe4, 0x1e, 0x00, 0x70, 0x02, 0x7e, 0xa0, 0xff, 0x02, 0x01, 0x21, 0xf5, 0x00, 0x57, 0x09, 0x60,
|
||
0x1f, 0x95, 0xf8, 0x01, 0x20, 0x00, 0xff, 0xe0, 0x01, 0x11, 0xfc, 0x2d, 0xff, 0x01, 0x13, 0x9f,
|
||
0xff, 0xe1, 0x00, 0x17, 0xff, 0xff, 0x99, 0x01, 0x16, 0x04, 0xbf, 0xfe, 0x00, 0x2c, 0x01, 0xfd,
|
||
0xdf, 0x01, 0x2c, 0xff, 0x07, 0x57, 0x00, 0x3f, 0x00, 0x0e, 0xbb, 0x00, 0x78, 0x00, 0x0a, 0x96,
|
||
0x00, 0x00, 0x00, 0x15, 0x02, 0x00, 0x10, 0x00, 0x20, 0x0c, 0x00, 0x00, 0x00, 0x51, 0x04, 0x00,
|
||
0x10, 0x00, 0x80, 0x09, 0x00, 0x10, 0x83, 0x00, 0x12, 0x01, 0x10, 0x0a, 0x00, 0xa4, 0x00, 0x12,
|
||
0x3c, 0x21, 0x48, 0x00, 0x54, 0xd2, 0x12, 0xb0, 0x00, 0x3b, 0x29, 0x41, 0x50, 0x57, 0xec, 0xd1,
|
||
0x22, 0xa0, 0x00, 0x5b, 0xe4, 0x0c, 0x40, 0x00, 0xbf, 0x5b, 0x58, 0x80, 0x00, 0x77, 0xff, 0xf1,
|
||
0x03, 0x02, 0xdf, 0xb7, 0x56, 0xfc, 0x01, 0xbf, 0xff, 0xe8, 0x00, 0x01, 0x3f, 0x7f, 0xc7, 0x29,
|
||
0x02, 0x63, 0xc7, 0xf1, 0xff, 0x02, 0xdf, 0x8b, 0xf8, 0x1b, 0x04, 0x07, 0xfe, 0xdf, 0xff, 0x04,
|
||
0x01, 0xff, 0xff, 0xff, 0x04, 0xf8, 0x7f, 0xef, 0xff, 0x0b, 0x07, 0x8b, 0xff, 0x02, 0x0c, 0x00,
|
||
0x7f, 0x74, 0x1f, 0x08, 0x00, 0x00, 0xff, 0xf0, 0x07, 0x00, 0x00, 0x0f, 0xc0, 0x71, 0x00, 0x00,
|
||
0x10, 0x38, 0x02, 0x80, 0x00, 0x2f, 0x8c, 0x5e, 0x80, 0x00, 0x60, 0x72, 0xe4, 0x80, 0x00, 0x40,
|
||
0x99, 0x85, 0x00, 0x00, 0x43, 0x79, 0x09, 0x00, 0x00, 0x45, 0xfc, 0x0a, 0x00, 0x00, 0x4b, 0xb4,
|
||
0x12, 0x00, 0x00, 0x2f, 0x94, 0x92, 0x00, 0x00, 0x2f, 0x12, 0xe4, 0x00, 0x01, 0x17, 0x9a, 0xd8,
|
||
0x00, 0x00, 0x17, 0x89, 0xa8, 0x00, 0x00, 0x0f, 0xdd, 0x90, 0x00, 0x01, 0x05, 0xfc, 0x60, 0x00,
|
||
0x00, 0x03, 0xfc, 0xa0, 0x00, 0x21, 0x01, 0x7e, 0xc0, 0x00, 0x09, 0x00, 0xef, 0x40, 0x00, 0x05,
|
||
0x40, 0x3f, 0x80, 0x00, 0x03, 0x80, 0x0b, 0x00, 0x05, 0xbe, 0xea, 0x45, 0x00, 0x00, 0x01, 0x80,
|
||
0x02, 0x00, 0x00, 0x03, 0x40, 0x02, 0x00, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x31, 0x10, 0x01,
|
||
0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x0f, 0x79, 0x00, 0x00, 0x00, 0x77, 0xb7, 0x00, 0x00, 0x0f,
|
||
0x98, 0xb3, 0x00, 0x09, 0xf0, 0x26, 0x6a, 0x00, 0x01, 0x02, 0xbc, 0x4a, 0x00, 0x09, 0xa7, 0xfd,
|
||
0x84, 0x00, 0x82, 0xf9, 0xf7, 0x18, 0x00, 0x0b, 0xe1, 0xbc, 0x70, 0x00, 0x2a, 0x8f, 0xf0, 0xc0,
|
||
0x00, 0x1a, 0xff, 0xe3, 0x00, 0x05, 0xf4, 0xff, 0x8c, 0x00, 0x00, 0x1c, 0xec, 0xf0, 0x00, 0x00,
|
||
0x2c, 0xff, 0x00, 0x00, 0x00, 0x4c, 0xe0, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x09,
|
||
0x00, 0x00, 0x01, 0x00, 0x0f, 0x40, 0x0e, 0x00, 0x00, 0x30, 0x00, 0x11, 0xc1, 0x10, 0x4f, 0x48,
|
||
0x2c, 0x31, 0x00, 0x70, 0x50, 0x43, 0x89, 0x40, 0x80, 0x2d, 0x40, 0x75, 0x80, 0x83, 0xd0, 0x81,
|
||
0x92, 0xea, 0x87, 0xc0, 0x87, 0x8b, 0x80, 0x47, 0x80, 0x9f, 0xcb, 0x00, 0x4d, 0x41, 0x3d, 0xcb,
|
||
0x20, 0x2e, 0x41, 0x7d, 0x93, 0x00, 0x3e, 0x42, 0xf7, 0x95, 0x00, 0x16, 0x27, 0xe7, 0xa4, 0x00,
|
||
0x0e, 0x95, 0xcf, 0x29, 0x00, 0x05, 0x4f, 0xdf, 0x48, 0x00, 0x02, 0x6f, 0xfe, 0x91, 0x00, 0x01,
|
||
0xfb, 0xff, 0xa0, 0x00, 0x00, 0xdf, 0xfb, 0x40, 0x00, 0x00, 0xff, 0xb6, 0x80, 0x00, 0x00, 0xbf,
|
||
0xa4, 0x80, 0x00, 0x40, 0xdb, 0x45, 0x00, 0x00, 0x00, 0x58, 0x05, 0x00, 0x00, 0x40, 0x00, 0x0a,
|
||
0x00, 0x00, 0x00, 0x04, 0x0a, 0x00, 0x04, 0x42, 0x80, 0x8a, 0x00, 0x00, 0x47, 0x80, 0x01, 0x00,
|
||
0x01, 0x4f, 0x80, 0x25, 0x00, 0x00, 0xf7, 0x52, 0x45, 0x01, 0x5f, 0xaf, 0x41, 0xa8, 0x80, 0x00,
|
||
0x3f, 0x56, 0xf2, 0x80, 0x01, 0x5f, 0xfb, 0xb6, 0x80, 0x02, 0xbb, 0xff, 0xfa, 0x40, 0x00, 0xbf,
|
||
0xe6, 0xfd, 0x40, 0x09, 0x6f, 0xcf, 0xf9, 0x40, 0x01, 0x5d, 0xe7, 0xf8, 0x80, 0x01, 0x1f, 0x7f,
|
||
0xf1, 0x00, 0x02, 0x17, 0x12, 0x8e, 0x00, 0x02, 0x0f, 0x00, 0x1c, 0x00, 0x02, 0x04, 0x03, 0xe0,
|
||
0x00, 0x03, 0x01, 0xfc, 0x00, 0x00, 0x01, 0xfe, 0xf0, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x3e,
|
||
0xa8, 0x00, 0xec, 0x00, 0x41, 0xf0, 0x00, 0x72, 0x00, 0xbc, 0xdf, 0x60, 0xca, 0x01, 0x03, 0x30,
|
||
0x00, 0xc9, 0x02, 0x60, 0xa8, 0x00, 0xe5, 0x04, 0xf0, 0xa0, 0x00, 0xf4, 0x85, 0xcc, 0xa2, 0x00,
|
||
0xfa, 0x4f, 0xce, 0x20, 0x00, 0x7f, 0x5b, 0x8d, 0x40, 0x00, 0x7b, 0x3f, 0x9e, 0x40, 0x00, 0x7f,
|
||
0xbf, 0xba, 0xa0, 0x00, 0xdb, 0xfd, 0x74, 0xa0, 0x00, 0xbf, 0xb7, 0xf5, 0x00, 0x00, 0x4d, 0xf7,
|
||
0x49, 0x20, 0x00, 0x19, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x54, 0xb2, 0x00, 0x00, 0x42, 0x01, 0x2c,
|
||
0x00, 0x00, 0x20, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40, 0x10, 0xc5, 0x00,
|
||
0x00, 0xa1, 0x04, 0x24, 0x80, 0x00, 0x02, 0x00, 0x2a, 0x40, 0x00, 0x74, 0x20, 0x6b, 0x40, 0x00,
|
||
0x69, 0x59, 0x5f, 0x21, 0x00, 0xad, 0x5b, 0xde, 0xa0, 0x00, 0xfd, 0xaf, 0xf7, 0x91, 0x00, 0x6f,
|
||
0x27, 0x73, 0x50, 0x00, 0xff, 0x47, 0xfb, 0xc9, 0x00, 0xde, 0x85, 0xb9, 0xa9, 0x10, 0xbd, 0x03,
|
||
0xbc, 0xa5, 0x00, 0x3d, 0x02, 0xfc, 0xd5, 0x40, 0x3a, 0x02, 0xdc, 0xd5, 0x80, 0xba, 0x01, 0x5c,
|
||
0xd2, 0xf5, 0xf4, 0x01, 0x3c, 0xcb, 0x80, 0x68, 0x00, 0x8b, 0xcd, 0x00, 0xb0, 0x00, 0x82, 0x89,
|
||
0x20, 0xc0, 0x00, 0x80, 0x10, 0x00, 0x80, 0x00, 0x40, 0xe1, 0x00, 0x00, 0x00, 0x3f, 0x01, 0x00,
|
||
0x47, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x47, 0x47, 0x47, 0x47, 0x47, 0x07, 0x47, 0x47,
|
||
0x47, 0x47, 0x47, 0x07, 0x47, 0x47, 0x07, 0x07, 0x47, 0x07, 0x47, 0x07, 0x47, 0x47, 0x47, 0x07,
|
||
0x07, 0x47, 0x07, 0x07, 0x47, 0x47, 0x07, 0x07, 0x05, 0x45, 0x47, 0x47, 0x47, 0x07, 0x45, 0x47,
|
||
0x07, 0x47, 0x07, 0x07, 0x07, 0x07, 0x47, 0x07, 0x47, 0x07, 0x07, 0x07, 0x05, 0x45, 0x45, 0x45,
|
||
0x05, 0x05, 0x45, 0x05, 0x45, 0x45, 0x05, 0x05, 0x05, 0x05, 0x45, 0x45, 0x45, 0x45, 0x05, 0x07,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x45, 0x45, 0x05, 0x45, 0x45, 0x05, 0x45, 0x45, 0x05,
|
||
0x45, 0x05, 0x45, 0x07, 0x78, 0x41, 0xa6, 0xe6, 0x66, 0x00, 0x78, 0x41, 0x9e, 0xde, 0x5e, 0x00,
|
||
0xfe, 0x42, 0x9e, 0xde, 0x5e, 0x00, 0xfe, 0x42, 0x96, 0xd6, 0x56, 0x00, 0x82, 0x43, 0x9e, 0xde,
|
||
0x5e, 0x00, 0x82, 0x43, 0x96, 0xd6, 0x56, 0x00, 0xac, 0x46, 0xa6, 0xe6, 0x66, 0x00, 0xac, 0x46,
|
||
0x9e, 0xde, 0x5e, 0x00, 0xdb, 0x48, 0xbe, 0xfe, 0x7e, 0x00, 0xdb, 0x48, 0xb6, 0xf6, 0x76, 0x00,
|
||
0xe8, 0x49, 0xa6, 0xe6, 0x66, 0x00, 0xe8, 0x49, 0x9e, 0xde, 0x5e, 0x00, 0x25, 0x4e, 0xbe, 0xfe,
|
||
0x7e, 0x00, 0x25, 0x4e, 0xb6, 0xf6, 0x76, 0x00, 0x53, 0x4e, 0xbe, 0xfe, 0x7e, 0x00, 0x53, 0x4e,
|
||
0xb6, 0xf6, 0x76, 0x00, 0x8e, 0x56, 0x8e, 0xce, 0x4e, 0x00, 0x8e, 0x56, 0x86, 0xc6, 0x46, 0x00,
|
||
0xa1, 0x56, 0xa6, 0xe6, 0x66, 0x00, 0xa1, 0x56, 0x9e, 0xde, 0x5e, 0x00, 0x78, 0x42, 0xa6, 0xe6,
|
||
0x66, 0x00, 0x78, 0x42, 0x9e, 0xde, 0x5e, 0x00, 0xfe, 0x43, 0x9e, 0xde, 0x5e, 0x00, 0xfe, 0x43,
|
||
0x96, 0xd6, 0x56, 0x00, 0x82, 0x44, 0x9e, 0xde, 0x5e, 0x00, 0x82, 0x44, 0x96, 0xd6, 0x56, 0x00,
|
||
0xac, 0x47, 0xa6, 0xe6, 0x66, 0x00, 0xac, 0x47, 0x9e, 0xde, 0x5e, 0x00, 0xdb, 0x49, 0xbe, 0xfe,
|
||
0x7e, 0x00, 0xdb, 0x49, 0xb6, 0xf6, 0x76, 0x00, 0xe8, 0x4a, 0xa6, 0xe6, 0x66, 0x00, 0xe8, 0x4a,
|
||
0x9e, 0xde, 0x5e, 0x00, 0x25, 0x4f, 0xbe, 0xfe, 0x7e, 0x00, 0x25, 0x4f, 0xb6, 0xf6, 0x76, 0x00,
|
||
0x53, 0x4f, 0xbe, 0xfe, 0x7e, 0x00, 0x53, 0x4f, 0xb6, 0xf6, 0x76, 0x00, 0x8e, 0x57, 0x8e, 0xce,
|
||
0x4e, 0x00, 0x8e, 0x57, 0x86, 0xc6, 0x46, 0x00, 0xa1, 0x57, 0xa6, 0xe6, 0x66, 0x00, 0xa1, 0x57,
|
||
0x9e, 0xde, 0x5e, 0x00, 0xad, 0x43, 0x8e, 0xce, 0x4e, 0x00, 0xe2, 0x43, 0xb6, 0xf6, 0x76, 0x00,
|
||
0xea, 0x43, 0xa6, 0xe6, 0x66, 0x00, 0x46, 0x44, 0xbe, 0xfe, 0x7e, 0x00, 0x2f, 0x48, 0x86, 0xc6,
|
||
0x46, 0x00, 0xa7, 0x49, 0x9e, 0xde, 0x5e, 0x00, 0xea, 0x49, 0x8e, 0xce, 0x4e, 0x00, 0x6c, 0x4a,
|
||
0xb6, 0xf6, 0x76, 0x00, 0xb4, 0x4b, 0x8e, 0xce, 0x4e, 0x00, 0xe3, 0x4b, 0x86, 0xc6, 0x46, 0x00,
|
||
0x3a, 0x4d, 0xbe, 0xfe, 0x7e, 0x00, 0x80, 0x4d, 0x96, 0xd6, 0x56, 0x00, 0x9d, 0x4d, 0x86, 0xc6,
|
||
0x46, 0x00, 0xb0, 0x4d, 0x96, 0xd6, 0x56, 0x00, 0xd2, 0x52, 0x86, 0xc6, 0x46, 0x00, 0x2d, 0x53,
|
||
0xae, 0xee, 0x6e, 0x00, 0x32, 0x53, 0x9e, 0xde, 0x5e, 0x00, 0x17, 0x54, 0xa6, 0xe6, 0x66, 0x00,
|
||
0x9c, 0x55, 0xb6, 0xf6, 0x76, 0x00, 0x89, 0x57, 0xb6, 0xf6, 0x76, 0x00, 0x2c, 0x40, 0x06, 0x48,
|
||
0xd4, 0x78, 0x49, 0x50, 0x07, 0x06, 0x46, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0xc3, 0x59, 0xeb, 0xc3, 0xda, 0xeb, 0xc3, 0x44, 0xed, 0xf3, 0x2a, 0x35, 0xf0, 0x22, 0x60, 0xec,
|
||
0x2a, 0x37, 0xf0, 0x22, 0x74, 0xec, 0x2a, 0x39, 0xf0, 0x22, 0x88, 0xec, 0x3e, 0x01, 0x32, 0x62,
|
||
0xec, 0x32, 0x76, 0xec, 0x32, 0x8a, 0xec, 0x3e, 0x08, 0x32, 0x63, 0xec, 0x32, 0x77, 0xec, 0x32,
|
||
0x8b, 0xec, 0x21, 0x20, 0xec, 0x11, 0x20, 0x00, 0x22, 0xfa, 0xeb, 0x19, 0x22, 0xfc, 0xeb, 0x19,
|
||
0x22, 0xfe, 0xeb, 0x21, 0x00, 0x00, 0x22, 0x6e, 0xec, 0x22, 0x82, 0xec, 0x22, 0x96, 0xec, 0x22,
|
||
0x70, 0xec, 0x22, 0x84, 0xec, 0x22, 0x98, 0xec, 0xaf, 0x32, 0xf4, 0xeb, 0xc9, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0xff, 0x16, 0x07, 0xcd, 0x9b,
|
||
0xed, 0xcd, 0x85, 0xed, 0x00, 0xc9, 0xe3, 0xff, 0xf6, 0x03, 0xbd, 0x00, 0x0d, 0xff, 0x0a, 0x0d,
|
||
0x0a, 0x00, 0x00, 0x00, 0x0d, 0x03, 0x4f, 0x69, 0x5c, 0xc4, 0x16, 0xc4, 0x3c, 0xc4, 0x5c, 0xc4,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0xc7, 0x1c, 0xd8, 0x94, 0xc7, 0x94, 0xc7,
|
||
0x16, 0x95, 0xd7, 0xc7, 0xb5, 0xc6, 0x68, 0xaa, 0x5a, 0xaa, 0xfe, 0x07, 0x58, 0xaa, 0xfe, 0x06,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0xc7, 0x1c, 0xd8,
|
||
0x94, 0xc7, 0xb5, 0xc6, 0xb5, 0xc6, 0x63, 0x8c, 0x94, 0xc7, 0xb5, 0xc6, 0x05, 0xab, 0xe6, 0x02,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0xc7, 0x94, 0xc7, 0x00, 0x94,
|
||
0x94, 0xc7, 0x94, 0xc7, 0x57, 0x89, 0x94, 0xc7, 0x57, 0x89, 0xb5, 0xc6, 0xc5, 0xab, 0xe6, 0x02,
|
||
0xfa, 0xaa, 0x05, 0x01, 0xd4, 0xaa, 0x01, 0xe3, 0xff, 0x0a, 0xcc, 0xaa, 0x05, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x4d, 0x0f, 0x09, 0xab, 0x0f, 0x08, 0x9d, 0xab, 0x01, 0xf6, 0x03, 0x0d, 0x97, 0xab,
|
||
0xa7, 0xab, 0x00, 0x00, 0xa2, 0xab, 0x19, 0x08, 0xcf, 0xab, 0x05, 0x08, 0xd0, 0xad, 0x01, 0xbd,
|
||
0x00, 0x0a, 0xc4, 0xad, 0xda, 0xad, 0x00, 0x00, 0xd5, 0xad, 0x36, 0x04, 0xbf, 0x0f, 0xdc, 0x0e,
|
||
0x07, 0x0e, 0x3d, 0x0d, 0x7f, 0x0c, 0xcc, 0x0b, 0x22, 0x0b, 0x82, 0x0a, 0xeb, 0x09, 0x5d, 0x09,
|
||
0xd6, 0x08, 0x57, 0x08, 0xdf, 0x07, 0x6e, 0x07, 0x03, 0x07, 0x9f, 0x06, 0x40, 0x06, 0xe6, 0x05,
|
||
0x91, 0x05, 0x41, 0x05, 0xf6, 0x04, 0xae, 0x04, 0x6b, 0x04, 0x2c, 0x04, 0xf0, 0x03, 0xb7, 0x03,
|
||
0x82, 0x03, 0x4f, 0x03, 0x20, 0x03, 0xf3, 0x02, 0xc8, 0x02, 0xa1, 0x02, 0x7b, 0x02, 0x57, 0x02,
|
||
0x36, 0x02, 0x16, 0x02, 0xf8, 0x01, 0xdc, 0x01, 0xc1, 0x01, 0xa8, 0x01, 0x90, 0x01, 0x79, 0x01,
|
||
0x64, 0x01, 0x50, 0x01, 0x3d, 0x01, 0x2c, 0x01, 0x1b, 0x01, 0x0b, 0x01, 0xfc, 0x00, 0xee, 0x00,
|
||
0xe0, 0x00, 0xd4, 0x00, 0xc8, 0x00, 0xbd, 0x00, 0xb2, 0x00, 0xa8, 0x00, 0x9f, 0x00, 0x96, 0x00,
|
||
0x8d, 0x00, 0x85, 0x00, 0x7e, 0x00, 0x77, 0x00, 0x70, 0x00, 0x6a, 0x00, 0x64, 0x00, 0x5e, 0x00,
|
||
0x59, 0x00, 0x54, 0x00, 0x4f, 0x00, 0x4b, 0x00, 0x47, 0x00, 0x43, 0x00, 0x3f, 0x00, 0x3b, 0x00,
|
||
0x38, 0x00, 0x35, 0x00, 0x32, 0x00, 0x2f, 0x00, 0x2d, 0x00, 0x2a, 0x00, 0x28, 0x00, 0x25, 0x00,
|
||
0x23, 0x00, 0x21, 0x00, 0xdd, 0x21, 0x60, 0xec, 0x2a, 0xfa, 0xeb, 0x3e, 0x01, 0xcd, 0xb0, 0xed,
|
||
0x22, 0xfa, 0xeb, 0xdd, 0x21, 0x74, 0xec, 0x2a, 0xfc, 0xeb, 0x3e, 0x02, 0xcd, 0xb0, 0xed, 0x22,
|
||
0xfc, 0xeb, 0xdd, 0x21, 0x88, 0xec, 0x2a, 0xfe, 0xeb, 0x3e, 0x03, 0xcd, 0xb0, 0xed, 0x22, 0xfe,
|
||
0xeb, 0x3a, 0x8b, 0xec, 0x07, 0x47, 0x3a, 0x77, 0xec, 0xb0, 0x07, 0x47, 0x3a, 0x63, 0xec, 0xb0,
|
||
0x16, 0x07, 0xcd, 0x9b, 0xed, 0x16, 0x0d, 0x21, 0xf3, 0xeb, 0x7a, 0x01, 0xfd, 0xff, 0xed, 0x79,
|
||
0x7e, 0x06, 0xbf, 0xed, 0x79, 0x2b, 0x15, 0xf2, 0x8a, 0xed, 0xc9, 0x01, 0xe6, 0xeb, 0x6a, 0x26,
|
||
0x00, 0x09, 0x77, 0xc9, 0xed, 0x73, 0xf8, 0xeb, 0x2a, 0xf8, 0xeb, 0xed, 0x7b, 0xf6, 0xeb, 0xc9,
|
||
0xed, 0x73, 0xf6, 0xeb, 0xf9, 0x32, 0xf5, 0xeb, 0xdd, 0x35, 0x02, 0xca, 0xbf, 0xee, 0xdd, 0x35,
|
||
0x06, 0x20, 0x36, 0xdd, 0x6e, 0x04, 0xdd, 0x66, 0x05, 0x7e, 0xfe, 0x80, 0x20, 0x0c, 0x23, 0x5e,
|
||
0x23, 0x56, 0xdd, 0x73, 0x04, 0xdd, 0x72, 0x05, 0x18, 0xe9, 0xfe, 0x1e, 0x38, 0x0c, 0xd6, 0x32,
|
||
0xdd, 0x77, 0x09, 0xdd, 0x36, 0x06, 0x01, 0x23, 0x18, 0x09, 0xdd, 0x77, 0x09, 0x23, 0x7e, 0xdd,
|
||
0x77, 0x06, 0x23, 0xdd, 0x75, 0x04, 0xdd, 0x74, 0x05, 0xdd, 0x7e, 0x07, 0xdd, 0xb6, 0x08, 0xca,
|
||
0x82, 0xee, 0xdd, 0xcb, 0x0e, 0x56, 0xc2, 0x82, 0xee, 0xdd, 0x6e, 0x0c, 0xdd, 0x66, 0x0d, 0x7e,
|
||
0x23, 0xdd, 0x75, 0x0c, 0xdd, 0x74, 0x0d, 0xfe, 0x80, 0x20, 0x06, 0x7e, 0x23, 0x66, 0x6f, 0x18,
|
||
0xee, 0xfe, 0x82, 0xc2, 0x2d, 0xee, 0xdd, 0xcb, 0x0e, 0xde, 0xc3, 0x0f, 0xee, 0xfe, 0x83, 0xc2,
|
||
0x39, 0xee, 0xdd, 0xcb, 0x0e, 0x9e, 0xc3, 0x0f, 0xee, 0xfe, 0x84, 0xc2, 0x49, 0xee, 0x3e, 0x09,
|
||
0xdd, 0xae, 0x03, 0xdd, 0x77, 0x03, 0xc3, 0x0f, 0xee, 0xdd, 0xcb, 0x0e, 0x5e, 0xca, 0x6b, 0xee,
|
||
0xdd, 0x86, 0x12, 0xdd, 0x77, 0x12, 0x3d, 0x87, 0x5f, 0x16, 0x00, 0x21, 0x9c, 0xec, 0x19, 0x7e,
|
||
0xdd, 0x77, 0x07, 0x23, 0x7e, 0xdd, 0x77, 0x08, 0xc3, 0x82, 0xee, 0x5f, 0x16, 0x00, 0xdd, 0x6e,
|
||
0x07, 0xdd, 0x66, 0x08, 0xe6, 0x80, 0xca, 0x7b, 0xee, 0x16, 0xff, 0x19, 0xdd, 0x75, 0x07, 0xdd,
|
||
0x74, 0x08, 0x3a, 0xf4, 0xeb, 0x16, 0x06, 0xcd, 0x9b, 0xed, 0xdd, 0xcb, 0x0e, 0x96, 0x3a, 0xf5,
|
||
0xeb, 0xc6, 0x07, 0x57, 0xdd, 0x7e, 0x07, 0xdd, 0xb6, 0x08, 0x28, 0x03, 0xdd, 0x7e, 0x09, 0xcd,
|
||
0x9b, 0xed, 0x3a, 0xf5, 0xeb, 0x3d, 0x87, 0x57, 0xdd, 0x7e, 0x07, 0xcd, 0x9b, 0xed, 0x14, 0xdd,
|
||
0x7e, 0x08, 0xcd, 0x9b, 0xed, 0xc3, 0xa4, 0xed, 0xdd, 0x75, 0x00, 0xdd, 0x74, 0x01, 0xc9, 0xdd,
|
||
0x6e, 0x00, 0xdd, 0x66, 0x01, 0x7e, 0x23, 0xcd, 0xb8, 0xee, 0xcb, 0x7f, 0xc2, 0x3c, 0xef, 0x22,
|
||
0xf8, 0xeb, 0xb7, 0x28, 0x1b, 0xdd, 0x86, 0x0f, 0xdd, 0x77, 0x12, 0xdd, 0xcb, 0x0e, 0x9e, 0x3d,
|
||
0x87, 0x5f, 0x16, 0x00, 0x21, 0x9c, 0xec, 0x19, 0x5e, 0x23, 0x56, 0x2a, 0xf8, 0xeb, 0x18, 0x03,
|
||
0x11, 0x00, 0x00, 0x7e, 0x23, 0xcd, 0xb8, 0xee, 0xdd, 0x77, 0x02, 0xdd, 0x73, 0x07, 0xdd, 0x72,
|
||
0x08, 0xdd, 0x7e, 0x10, 0xdd, 0x77, 0x0c, 0xdd, 0x7e, 0x11, 0xdd, 0x77, 0x0d, 0xdd, 0xcb, 0x0e,
|
||
0xd6, 0xdd, 0xcb, 0x0e, 0x4e, 0xc2, 0xbe, 0xed, 0xdd, 0xcb, 0x0e, 0x46, 0xca, 0x23, 0xef, 0xdd,
|
||
0xcb, 0x0e, 0xce, 0xdd, 0x4e, 0x0a, 0xdd, 0x46, 0x0b, 0x0a, 0xdd, 0x77, 0x09, 0x03, 0x0a, 0x03,
|
||
0xdd, 0x77, 0x06, 0xdd, 0x71, 0x04, 0xdd, 0x70, 0x05, 0xc3, 0x82, 0xee, 0xe6, 0x7f, 0x22, 0xf8,
|
||
0xeb, 0x87, 0x5f, 0x16, 0x00, 0x21, 0x52, 0xef, 0x19, 0x7e, 0x23, 0x66, 0x6f, 0xe5, 0x2a, 0xf8,
|
||
0xeb, 0xc9, 0x70, 0xef, 0x7c, 0xef, 0x8a, 0xef, 0x94, 0xef, 0xa6, 0xef, 0xb1, 0xef, 0xde, 0xef,
|
||
0xbc, 0xef, 0xcc, 0xef, 0xd7, 0xef, 0xee, 0xef, 0xfc, 0xef, 0x0a, 0xf0, 0x17, 0xf0, 0x27, 0xf0,
|
||
0x7e, 0xdd, 0x77, 0x00, 0x23, 0x7e, 0xdd, 0x77, 0x01, 0xc3, 0xbf, 0xee, 0x7e, 0xdd, 0x77, 0x00,
|
||
0x23, 0x7e, 0xdd, 0x77, 0x01, 0x23, 0xe5, 0xc3, 0xbf, 0xee, 0x46, 0xc5, 0x23, 0xe5, 0xcd, 0xb8,
|
||
0xee, 0xc3, 0xbf, 0xee, 0xd1, 0xc1, 0x10, 0x03, 0xc3, 0xbf, 0xee, 0xc5, 0xd5, 0xdd, 0x73, 0x00,
|
||
0xdd, 0x72, 0x01, 0xc3, 0xbf, 0xee, 0x7e, 0x23, 0x32, 0xf4, 0xeb, 0xcd, 0xb8, 0xee, 0xc3, 0xbf,
|
||
0xee, 0x7e, 0x23, 0xcd, 0xb8, 0xee, 0xdd, 0x77, 0x03, 0xc3, 0xbf, 0xee, 0x7e, 0xdd, 0x77, 0x0a,
|
||
0x23, 0x7e, 0xdd, 0x77, 0x0b, 0x23, 0xcd, 0xb8, 0xee, 0xc3, 0xbf, 0xee, 0x7e, 0x23, 0xcd, 0xb8,
|
||
0xee, 0xdd, 0x77, 0x0f, 0xc3, 0xbf, 0xee, 0xe1, 0xcd, 0xb8, 0xee, 0xc3, 0xbf, 0xee, 0x7e, 0xdd,
|
||
0x77, 0x10, 0x23, 0x7e, 0xdd, 0x77, 0x11, 0x23, 0xcd, 0xb8, 0xee, 0xc3, 0xbf, 0xee, 0xdd, 0xcb,
|
||
0x0e, 0xc6, 0xdd, 0xcb, 0x0e, 0x8e, 0xcd, 0xb8, 0xee, 0xc3, 0xbf, 0xee, 0xdd, 0xcb, 0x0e, 0x86,
|
||
0xdd, 0xcb, 0x0e, 0x8e, 0xcd, 0xb8, 0xee, 0xc3, 0xbf, 0xee, 0x5e, 0x23, 0x56, 0x23, 0xcd, 0xb8,
|
||
0xee, 0x01, 0xbf, 0xee, 0xc5, 0xd5, 0xc9, 0x3a, 0xf4, 0xeb, 0x86, 0xe6, 0x0f, 0x32, 0xf4, 0xeb,
|
||
0x23, 0xcd, 0xb8, 0xee, 0xc3, 0xbf, 0xee, 0x7e, 0xdd, 0x86, 0x0f, 0xdd, 0x77, 0x0f, 0x23, 0xcd,
|
||
0xb8, 0xee, 0xc3, 0xbf, 0xee, 0x99, 0xf5, 0x96, 0xf4, 0x3b, 0xf0, 0x82, 0x04, 0x81, 0x57, 0xf4,
|
||
0x83, 0x81, 0x6d, 0xf3, 0x81, 0x6d, 0xf3, 0x81, 0x00, 0xf4, 0x81, 0x33, 0xf3, 0x81, 0x33, 0xf3,
|
||
0x81, 0x17, 0xf3, 0x81, 0x6a, 0xf2, 0x81, 0x6a, 0xf2, 0x88, 0x00, 0x81, 0xba, 0xf2, 0x81, 0xba,
|
||
0xf2, 0x88, 0x02, 0x81, 0xba, 0xf2, 0x88, 0x00, 0x81, 0xef, 0xf2, 0x82, 0x04, 0x81, 0x49, 0xf2,
|
||
0x83, 0x81, 0x17, 0xf3, 0x81, 0x49, 0xf2, 0x81, 0x49, 0xf2, 0x81, 0x1a, 0xf3, 0x81, 0x49, 0xf2,
|
||
0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7, 0x2b, 0x23, 0x86, 0x9b, 0xf7, 0x2b, 0x0c, 0x86, 0x5e, 0xf7,
|
||
0x2d, 0x48, 0x2b, 0x0c, 0x2d, 0x0c, 0x32, 0x0c, 0x30, 0x0c, 0x2d, 0x18, 0x30, 0x24, 0x86, 0x9b,
|
||
0xf7, 0x30, 0x0c, 0x86, 0x5e, 0xf7, 0x32, 0x48, 0x32, 0x0c, 0x37, 0x0c, 0x36, 0x0c, 0x32, 0x0c,
|
||
0x2d, 0x18, 0x2b, 0x24, 0x86, 0x9b, 0xf7, 0x2b, 0x0c, 0x86, 0x5e, 0xf7, 0x2d, 0x48, 0x32, 0x0c,
|
||
0x86, 0x97, 0xf7, 0x32, 0x0c, 0x86, 0x5e, 0xf7, 0x32, 0x0c, 0x30, 0x0c, 0x2d, 0x18, 0x32, 0x24,
|
||
0x86, 0x97, 0xf7, 0x32, 0x0c, 0x86, 0x5e, 0xf7, 0x30, 0x48, 0x32, 0x0c, 0x34, 0x0c, 0x37, 0x0c,
|
||
0x36, 0x0c, 0x37, 0x0c, 0x39, 0x0c, 0x37, 0x24, 0x86, 0x9b, 0xf7, 0x37, 0x0c, 0x86, 0x5e, 0xf7,
|
||
0x39, 0x30, 0x37, 0x06, 0x39, 0x0c, 0x37, 0x06, 0x39, 0x0c, 0x37, 0x06, 0x36, 0x0c, 0x37, 0x06,
|
||
0x36, 0x0c, 0x34, 0x0c, 0x32, 0x0c, 0x30, 0x06, 0x32, 0x0c, 0x30, 0x06, 0x32, 0x0c, 0x30, 0x06,
|
||
0x2f, 0x0c, 0x30, 0x06, 0x2f, 0x0c, 0x2d, 0x0c, 0x2b, 0x0c, 0x2d, 0x06, 0x2d, 0x0c, 0x2b, 0x06,
|
||
0x2d, 0x0c, 0x2f, 0x06, 0x30, 0x0c, 0x32, 0x06, 0x34, 0x0c, 0x36, 0x0c, 0x37, 0x0c, 0x3b, 0x24,
|
||
0x86, 0x97, 0xf7, 0x3b, 0x0c, 0x86, 0x5e, 0xf7, 0x39, 0x48, 0x37, 0x0c, 0x39, 0x0c, 0x3c, 0x06,
|
||
0x3c, 0x06, 0x39, 0x0c, 0x3e, 0x0c, 0x3c, 0x0c, 0x40, 0x24, 0x86, 0x97, 0xf7, 0x40, 0x0c, 0x86,
|
||
0x5e, 0xf7, 0x3e, 0x60, 0x00, 0x06, 0x3e, 0x06, 0x3e, 0x06, 0x40, 0x06, 0x41, 0x06, 0x40, 0x06,
|
||
0x3c, 0x06, 0x3e, 0x07, 0x81, 0xd9, 0xf1, 0x81, 0x11, 0xf2, 0x82, 0x02, 0x3d, 0x0b, 0x36, 0x0c,
|
||
0x3b, 0x0c, 0x36, 0x06, 0x3a, 0x0c, 0x36, 0x06, 0x38, 0x0c, 0x36, 0x06, 0x36, 0x06, 0x3b, 0x06,
|
||
0x3d, 0x06, 0x3d, 0x06, 0x3d, 0x06, 0x36, 0x0c, 0x3b, 0x0c, 0x36, 0x06, 0x3a, 0x0c, 0x36, 0x06,
|
||
0x38, 0x0c, 0x36, 0x06, 0x36, 0x06, 0x3b, 0x06, 0x3d, 0x07, 0x83, 0x81, 0x6a, 0xf2, 0x81, 0x49,
|
||
0xf2, 0x81, 0xc3, 0xf1, 0x81, 0x1a, 0xf3, 0x81, 0x4c, 0xf2, 0x81, 0xba, 0xf2, 0x81, 0x4c, 0xf2,
|
||
0x88, 0x02, 0x81, 0xba, 0xf2, 0x88, 0x00, 0x81, 0xef, 0xf2, 0x81, 0x4c, 0xf2, 0x81, 0xc3, 0xf1,
|
||
0x80, 0x3b, 0xf0, 0x87, 0xff, 0xf6, 0x46, 0x18, 0x00, 0x30, 0x87, 0x33, 0xf7, 0x86, 0x1b, 0xf7,
|
||
0x28, 0x0b, 0x00, 0x01, 0x28, 0x0b, 0x00, 0x01, 0x89, 0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7, 0x82,
|
||
0x02, 0x40, 0x0b, 0x39, 0x0c, 0x3e, 0x0c, 0x39, 0x06, 0x3c, 0x0c, 0x39, 0x06, 0x3b, 0x0c, 0x3c,
|
||
0x06, 0x39, 0x06, 0x3c, 0x06, 0x3e, 0x06, 0x40, 0x06, 0x40, 0x06, 0x39, 0x0c, 0x3e, 0x0c, 0x39,
|
||
0x06, 0x3c, 0x0c, 0x39, 0x06, 0x3b, 0x0c, 0x3c, 0x06, 0x39, 0x06, 0x3c, 0x06, 0x3e, 0x07, 0x83,
|
||
0x89, 0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7, 0x82, 0x02, 0x40, 0x0b, 0x39, 0x0c, 0x3f, 0x0c, 0x39,
|
||
0x06, 0x3d, 0x0c, 0x3d, 0x06, 0x3b, 0x0c, 0x3d, 0x06, 0x39, 0x06, 0x3d, 0x06, 0x3f, 0x06, 0x40,
|
||
0x06, 0x40, 0x06, 0x39, 0x0c, 0x3f, 0x0c, 0x39, 0x06, 0x3d, 0x0c, 0x3d, 0x06, 0x3b, 0x0c, 0x3d,
|
||
0x06, 0x39, 0x06, 0x3d, 0x06, 0x3f, 0x07, 0x83, 0x89, 0x81, 0x4c, 0xf2, 0x86, 0x45, 0xf7, 0x87,
|
||
0x9f, 0xf7, 0x82, 0x04, 0x46, 0x06, 0x83, 0x46, 0x0c, 0x44, 0x06, 0x46, 0x0a, 0x00, 0x02, 0x44,
|
||
0x06, 0x46, 0x0a, 0x00, 0x02, 0x46, 0x0c, 0x44, 0x0c, 0x89, 0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7,
|
||
0x36, 0x23, 0x86, 0x97, 0xf7, 0x36, 0x0c, 0x86, 0x5e, 0xf7, 0x34, 0x18, 0x31, 0x0c, 0x2f, 0x18,
|
||
0x2e, 0x0c, 0x2e, 0x0c, 0x81, 0xef, 0xf3, 0x8e, 0xfd, 0x81, 0xef, 0xf3, 0x8e, 0x03, 0x87, 0x4f,
|
||
0xf7, 0x86, 0x5e, 0xf7, 0x2e, 0x0c, 0x2f, 0x0c, 0x31, 0x0c, 0x31, 0x12, 0x31, 0x12, 0x31, 0x0c,
|
||
0x34, 0x12, 0x31, 0x12, 0x2f, 0x0c, 0x31, 0x18, 0x86, 0x97, 0xf7, 0x31, 0x30, 0x81, 0xef, 0xf3,
|
||
0x8e, 0xfd, 0x81, 0xef, 0xf3, 0x00, 0x01, 0x8e, 0x03, 0x89, 0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7,
|
||
0x32, 0x18, 0x81, 0xef, 0xf3, 0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7, 0x32, 0x06, 0x32, 0x06, 0x34,
|
||
0x12, 0x32, 0x12, 0x30, 0x0c, 0x32, 0x18, 0x81, 0xef, 0xf3, 0x8e, 0xfb, 0x81, 0xef, 0xf3, 0x81,
|
||
0x87, 0xf5, 0x86, 0x1b, 0xf7, 0x87, 0x33, 0xf7, 0x8e, 0x05, 0x2b, 0x0c, 0x28, 0x0c, 0x89, 0x87,
|
||
0x4f, 0xf7, 0x86, 0x5e, 0xf7, 0x34, 0x18, 0x81, 0xef, 0xf3, 0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7,
|
||
0x34, 0x06, 0x34, 0x06, 0x36, 0x12, 0x34, 0x12, 0x32, 0x0c, 0x34, 0x12, 0x36, 0x12, 0x38, 0x0c,
|
||
0x36, 0x12, 0x38, 0x12, 0x39, 0x0c, 0x89, 0x81, 0x1a, 0xf3, 0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7,
|
||
0x82, 0x02, 0x82, 0x02, 0x30, 0x06, 0x2f, 0x0c, 0x2e, 0x06, 0x2d, 0x0c, 0x83, 0x30, 0x0c, 0x32,
|
||
0x0c, 0x83, 0x89, 0x87, 0x4f, 0xf7, 0x86, 0x7c, 0xf7, 0x82, 0x04, 0x30, 0x06, 0x2f, 0x0c, 0x2e,
|
||
0x06, 0x2d, 0x0c, 0x83, 0x30, 0x06, 0x2f, 0x0c, 0x2d, 0x06, 0x35, 0x0c, 0x34, 0x0c, 0x82, 0x02,
|
||
0x35, 0x06, 0x34, 0x0c, 0x33, 0x06, 0x32, 0x0c, 0x83, 0x35, 0x0c, 0x34, 0x0c, 0x82, 0x02, 0x2f,
|
||
0x06, 0x2e, 0x0c, 0x2d, 0x06, 0x2c, 0x0c, 0x83, 0x30, 0x0c, 0x2f, 0x0c, 0x89, 0x87, 0x4f, 0xf7,
|
||
0x86, 0x5e, 0xf7, 0x88, 0x00, 0x00, 0x05, 0x2d, 0x06, 0x2d, 0x0c, 0x2d, 0x0c, 0x2d, 0x0c, 0x2d,
|
||
0x18, 0x2d, 0x1e, 0x2d, 0x06, 0x34, 0x0c, 0x34, 0x0c, 0x34, 0x0c, 0x34, 0x18, 0x81, 0xef, 0xf3,
|
||
0x00, 0x0c, 0x35, 0x18, 0x34, 0x18, 0x35, 0x18, 0x34, 0x0c, 0x32, 0x12, 0x2f, 0x06, 0x2f, 0x0c,
|
||
0x2f, 0x0c, 0x2f, 0x0c, 0x2f, 0x18, 0x81, 0xef, 0xf3, 0x00, 0x0c, 0x00, 0x06, 0x30, 0x06, 0x30,
|
||
0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x18, 0x30, 0x1e, 0x30, 0x06, 0x37, 0x0c, 0x37, 0x0c, 0x37,
|
||
0x0c, 0x37, 0x18, 0x81, 0xef, 0xf3, 0x00, 0x0c, 0x38, 0x18, 0x37, 0x18, 0x38, 0x18, 0x37, 0x0c,
|
||
0x35, 0x12, 0x32, 0x06, 0x32, 0x0c, 0x32, 0x0c, 0x32, 0x0c, 0x32, 0x18, 0x87, 0x33, 0xf7, 0x86,
|
||
0x1b, 0xf7, 0x00, 0x01, 0x2d, 0x0b, 0x00, 0x01, 0x28, 0x05, 0x00, 0x01, 0x28, 0x06, 0x89, 0x87,
|
||
0x33, 0xf7, 0x86, 0x1b, 0xf7, 0x00, 0x01, 0x2b, 0x0b, 0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7, 0x89,
|
||
0x87, 0x69, 0xf7, 0x84, 0x1f, 0x85, 0x01, 0x82, 0x04, 0x07, 0x06, 0x8d, 0xfe, 0x83, 0x85, 0x08,
|
||
0x87, 0x4f, 0xf7, 0x86, 0x5e, 0xf7, 0x2d, 0x0b, 0x2d, 0x0c, 0x2d, 0x06, 0x2d, 0x06, 0x2d, 0x0c,
|
||
0x2f, 0x0c, 0x30, 0x0c, 0x32, 0x06, 0x32, 0x06, 0x32, 0x0c, 0x32, 0x0c, 0x32, 0x0c, 0x32, 0x18,
|
||
0x81, 0xef, 0xf3, 0x32, 0x06, 0x34, 0x06, 0x35, 0x06, 0x35, 0x06, 0x34, 0x0c, 0x32, 0x0c, 0x30,
|
||
0x0c, 0x2f, 0x0c, 0x2d, 0x0c, 0x2c, 0x1e, 0x2d, 0x06, 0x2d, 0x0c, 0x2d, 0x0c, 0x2f, 0x0c, 0x2d,
|
||
0x18, 0x81, 0xef, 0xf3, 0x00, 0x0d, 0x89, 0x88, 0x07, 0x87, 0x3e, 0xf7, 0x86, 0x45, 0xf7, 0x45,
|
||
0x04, 0x00, 0x02, 0x45, 0x04, 0x00, 0x02, 0x39, 0x0c, 0x87, 0x1f, 0xf7, 0x86, 0x38, 0xf7, 0x2d,
|
||
0x0b, 0x2d, 0x0c, 0x2e, 0x12, 0x2d, 0x12, 0x2b, 0x0c, 0x2b, 0x06, 0x2d, 0x06, 0x2d, 0x06, 0x2d,
|
||
0x06, 0x2d, 0x0c, 0x2b, 0x0c, 0x2d, 0x06, 0x2b, 0x06, 0x2d, 0x0d, 0x87, 0x3e, 0xf7, 0x86, 0x45,
|
||
0xf7, 0x40, 0x0c, 0x39, 0x0c, 0x89, 0x82, 0x04, 0x81, 0x6e, 0xf5, 0x83, 0x81, 0x60, 0xf5, 0x81,
|
||
0x60, 0xf5, 0x82, 0x06, 0x81, 0x6e, 0xf5, 0x83, 0x81, 0x2f, 0xf5, 0x81, 0x2f, 0xf5, 0x8e, 0xf8,
|
||
0x81, 0x2c, 0xf5, 0x81, 0x2c, 0xf5, 0x8e, 0x01, 0x81, 0x2c, 0xf5, 0x8e, 0x02, 0x81, 0x2c, 0xf5,
|
||
0x8e, 0x05, 0x88, 0xf4, 0x82, 0x04, 0x81, 0x49, 0xf2, 0x83, 0x88, 0x00, 0x81, 0x2f, 0xf5, 0x81,
|
||
0x2f, 0xf5, 0x88, 0xf4, 0x81, 0x49, 0xf2, 0x81, 0x49, 0xf2, 0x88, 0x00, 0x81, 0x2f, 0xf5, 0x88,
|
||
0xf4, 0x81, 0x49, 0xf2, 0x88, 0x00, 0x82, 0x08, 0x81, 0x2f, 0xf5, 0x83, 0x81, 0x2c, 0xf5, 0x88,
|
||
0xf8, 0x81, 0x2c, 0xf5, 0x81, 0x2c, 0xf5, 0x81, 0x2c, 0xf5, 0x88, 0xf4, 0x81, 0x49, 0xf2, 0x88,
|
||
0xff, 0x81, 0xc3, 0xf1, 0x88, 0x00, 0x81, 0x2f, 0xf5, 0x81, 0x24, 0xf5, 0x88, 0xf9, 0x81, 0x2f,
|
||
0xf5, 0x81, 0x24, 0xf5, 0x88, 0xfb, 0x81, 0x2c, 0xf5, 0x81, 0x24, 0xf5, 0x81, 0xc3, 0xf1, 0x88,
|
||
0x00, 0x80, 0x96, 0xf4, 0x88, 0xf4, 0x81, 0x4c, 0xf2, 0x88, 0xff, 0x89, 0x81, 0x2f, 0xf5, 0x87,
|
||
0x8c, 0xf7, 0x86, 0x38, 0xf7, 0x43, 0x0c, 0x45, 0x0c, 0x86, 0x84, 0xf7, 0x8e, 0x0c, 0x2d, 0x0c,
|
||
0x2d, 0x0c, 0x2d, 0x24, 0x2b, 0x06, 0x2b, 0x0c, 0x2d, 0x06, 0x2d, 0x0c, 0x2d, 0x0c, 0x2b, 0x0c,
|
||
0x2d, 0x06, 0x2b, 0x06, 0x2d, 0x0c, 0x8e, 0xf4, 0x86, 0x38, 0xf7, 0x43, 0x0c, 0x45, 0x0c, 0x89,
|
||
0x81, 0x6b, 0xf5, 0x8e, 0x03, 0x81, 0x6b, 0xf5, 0x8e, 0xfd, 0x89, 0x81, 0x6e, 0xf5, 0x81, 0x87,
|
||
0xf5, 0x34, 0x0c, 0x34, 0x0c, 0x35, 0x12, 0x34, 0x12, 0x32, 0x0c, 0x81, 0x87, 0xf5, 0x34, 0x0c,
|
||
0x34, 0x0c, 0x34, 0x18, 0x00, 0x18, 0x89, 0x84, 0x0a, 0x85, 0x01, 0x87, 0x69, 0xf7, 0x86, 0x2b,
|
||
0xf7, 0x07, 0x18, 0x85, 0x08, 0x87, 0x1f, 0xf7, 0x89, 0x81, 0xa0, 0xf6, 0x81, 0xa0, 0xf6, 0x81,
|
||
0x95, 0xf6, 0x81, 0x95, 0xf6, 0x81, 0xb6, 0xf6, 0x88, 0x05, 0x81, 0xb6, 0xf6, 0x88, 0xfb, 0x81,
|
||
0xb6, 0xf6, 0x88, 0x00, 0x81, 0xb6, 0xf6, 0x81, 0xa0, 0xf6, 0x81, 0xa0, 0xf6, 0x81, 0xb3, 0xf6,
|
||
0x88, 0x05, 0x81, 0xb3, 0xf6, 0x88, 0xfd, 0x81, 0x8a, 0xf6, 0x81, 0x8a, 0xf6, 0x88, 0x05, 0x81,
|
||
0xb0, 0xf6, 0x88, 0xfb, 0x81, 0xb0, 0xf6, 0x88, 0x00, 0x82, 0x04, 0x81, 0x55, 0xf6, 0x83, 0x81,
|
||
0xb3, 0xf6, 0x88, 0x05, 0x81, 0xb3, 0xf6, 0x88, 0x00, 0x81, 0x55, 0xf6, 0x81, 0x55, 0xf6, 0x81,
|
||
0xb6, 0xf6, 0x88, 0x05, 0x81, 0xb6, 0xf6, 0x88, 0x00, 0x81, 0x55, 0xf6, 0x82, 0x04, 0x88, 0x00,
|
||
0x81, 0xb3, 0xf6, 0x88, 0x05, 0x81, 0xb3, 0xf6, 0x83, 0x88, 0x00, 0x81, 0xb3, 0xf6, 0x88, 0x05,
|
||
0x81, 0xb3, 0xf6, 0x88, 0x04, 0x81, 0xb3, 0xf6, 0x88, 0x00, 0x81, 0xb3, 0xf6, 0x88, 0xfd, 0x81,
|
||
0xb3, 0xf6, 0x88, 0x04, 0x81, 0xb3, 0xf6, 0x88, 0xfd, 0x81, 0x8a, 0xf6, 0x88, 0x00, 0x81, 0x55,
|
||
0xf6, 0x00, 0x60, 0x81, 0xb6, 0xf6, 0x88, 0x05, 0x81, 0xb6, 0xf6, 0x81, 0x58, 0xf6, 0x88, 0x05,
|
||
0x81, 0xb3, 0xf6, 0x81, 0x58, 0xf6, 0x88, 0xfb, 0x81, 0xb0, 0xf6, 0x81, 0x58, 0xf6, 0x00, 0x60,
|
||
0x88, 0x00, 0x80, 0x99, 0xf5, 0x81, 0x58, 0xf6, 0x88, 0x00, 0x86, 0x1b, 0xf7, 0x82, 0x04, 0x81,
|
||
0x76, 0xf6, 0x83, 0x2b, 0x09, 0x00, 0x03, 0x82, 0x06, 0x81, 0x76, 0xf6, 0x83, 0x2b, 0x09, 0x00,
|
||
0x03, 0x27, 0x09, 0x00, 0x03, 0x89, 0x87, 0x33, 0xf7, 0x85, 0x01, 0x84, 0x1c, 0x07, 0x01, 0x00,
|
||
0x01, 0x84, 0x02, 0x07, 0x01, 0x00, 0x03, 0x85, 0x08, 0x89, 0x81, 0xb3, 0xf6, 0x8e, 0x07, 0x81,
|
||
0xb3, 0xf6, 0x8e, 0xf9, 0x89, 0x81, 0xa0, 0xf6, 0x8e, 0x03, 0x81, 0xa0, 0xf6, 0x8e, 0xfd, 0x89,
|
||
0x81, 0xb3, 0xf6, 0x8e, 0x01, 0x81, 0xb6, 0xf6, 0x8e, 0xfa, 0x81, 0xb6, 0xf6, 0x8e, 0x05, 0x89,
|
||
0x81, 0xb3, 0xf6, 0x81, 0xb6, 0xf6, 0x87, 0xeb, 0xf6, 0x86, 0xf4, 0xf6, 0x15, 0x0c, 0x15, 0x06,
|
||
0x21, 0x06, 0x81, 0xd1, 0xf6, 0x15, 0x0c, 0x15, 0x18, 0x81, 0xd1, 0xf6, 0x1f, 0x06, 0x21, 0x06,
|
||
0x89, 0x87, 0xff, 0xf6, 0x84, 0x1f, 0x85, 0x01, 0x8a, 0x82, 0x06, 0x07, 0x01, 0x8d, 0xf0, 0x07,
|
||
0x01, 0x8d, 0x0e, 0x83, 0x8b, 0x85, 0x08, 0x87, 0xeb, 0xf6, 0x89, 0x0f, 0x01, 0x40, 0x3f, 0x0c,
|
||
0xff, 0x80, 0xeb, 0xf6, 0x00, 0x00, 0x05, 0x05, 0x03, 0xfd, 0xfb, 0xfb, 0x80, 0xf4, 0xf6, 0x0f,
|
||
0x01, 0x40, 0x3b, 0x3f, 0x3e, 0x3b, 0x3d, 0x3c, 0x3b, 0x3b, 0x3a, 0x3b, 0x39, 0x38, 0x3b, 0x37,
|
||
0x36, 0x3b, 0x35, 0x34, 0x3b, 0x33, 0x00, 0xff, 0x80, 0xff, 0xf6, 0x32, 0x80, 0x1b, 0xf7, 0x0f,
|
||
0x01, 0x40, 0x3f, 0x3e, 0x3d, 0x3a, 0x0b, 0x02, 0x80, 0x25, 0xf7, 0x82, 0x0c, 0xf4, 0x07, 0xf9,
|
||
0x80, 0x2b, 0xf7, 0x0f, 0xff, 0x80, 0x33, 0xf7, 0x82, 0x0c, 0xf4, 0x80, 0x38, 0xf7, 0x0f, 0x01,
|
||
0x3f, 0x3a, 0x80, 0x3e, 0xf7, 0x82, 0x05, 0x03, 0xf8, 0x05, 0x07, 0xf4, 0x80, 0x45, 0xf7, 0x00,
|
||
0x01, 0x0f, 0x03, 0x0e, 0x04, 0x0d, 0x04, 0x0c, 0x04, 0x0b, 0xff, 0x80, 0x4f, 0xf7, 0x02, 0x01,
|
||
0xff, 0xfe, 0xfe, 0xff, 0x01, 0x02, 0x80, 0x5e, 0xf7, 0x0f, 0x02, 0x00, 0x04, 0x0e, 0x02, 0x00,
|
||
0x04, 0x0d, 0x03, 0x00, 0x03, 0x0c, 0x03, 0x00, 0x03, 0x80, 0x69, 0xf7, 0x83, 0x05, 0x82, 0x18,
|
||
0xe8, 0x80, 0x7c, 0xf7, 0x82, 0x00, 0x0c, 0xf4, 0x00, 0x80, 0x84, 0xf7, 0x0e, 0x01, 0x3f, 0x3e,
|
||
0x0b, 0x02, 0x0a, 0x02, 0x80, 0x90, 0xf7, 0x02, 0x80, 0x97, 0xf7, 0xfe, 0x80, 0x9b, 0xf7, 0x0e,
|
||
0x01, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x80, 0x9f, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||
};
|
||
|
||
TRDOS_DIR_ELEMENT sbootdir = { {'b','o','o','t',' ',' ',' ',' '}, 'B', 0xB4, 0xB4, (sizeof(sbootimage)+255)/256, 0, 0 };
|
||
|
||
long CalcCRC32(long CRC, unsigned char Symbol)
|
||
{
|
||
long temp;
|
||
CRC ^= -1l ^ Symbol;
|
||
for (int k = 8; k--;)
|
||
{
|
||
temp = -(CRC & 1), CRC >>= 1, CRC ^= 0xEDB88320ul & temp;
|
||
}
|
||
CRC ^= -1l;
|
||
return CRC;
|
||
}
|
||
|
||
long filelength(int hfile)
|
||
{
|
||
long ret = lseek(hfile, 0, SEEK_END);
|
||
lseek(hfile, 0, SEEK_SET);
|
||
return ret;
|
||
}
|
||
|
||
//----------------------------------------------------------------------------
|
||
TDiskImage::TDiskImage()
|
||
{
|
||
for (int t = 0; t < 256; t++)
|
||
for (int s = 0; s < 256; s++)
|
||
{
|
||
FTrackLength[t][s] = 0;
|
||
FTracksPtr[t][s][0] = NULL;
|
||
FTracksPtr[t][s][1] = NULL;
|
||
}
|
||
|
||
DiskPresent = false;
|
||
ReadOnly = true;
|
||
Changed = false;
|
||
FType = DIT_UNK;
|
||
MaxTrack = 81;
|
||
MaxSide = 0x01;
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
TDiskImage::~TDiskImage()
|
||
{
|
||
ReadOnly = true;
|
||
DiskPresent = false;
|
||
Changed = false;
|
||
FType = DIT_UNK;
|
||
|
||
for (int t = 0; t < 256; t++)
|
||
for (int s = 0; s < 256; s++)
|
||
{
|
||
FTrackLength[t][s] = 0;
|
||
if (FTracksPtr[t][s][0]) delete FTracksPtr[t][s][0];
|
||
FTracksPtr[t][s][0] = NULL;
|
||
if (FTracksPtr[t][s][1]) delete FTracksPtr[t][s][1];
|
||
FTracksPtr[t][s][1] = NULL;
|
||
}
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
unsigned short TDiskImage::MakeVGCRC(unsigned char *data, unsigned long length)
|
||
{
|
||
unsigned short CRC = 0xFFFF;
|
||
for (unsigned int i = 0; i < length; i++)
|
||
{
|
||
CRC ^= data[i] << 8;
|
||
for (unsigned int j = 0; j < 8; j++)
|
||
{
|
||
if (CRC & 0x8000) CRC = (CRC << 1) ^ 0x1021;
|
||
else CRC <<= 1;
|
||
}
|
||
}
|
||
return CRC; // H<-->L !!!
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::ApplySectorCRC(VGFIND_SECTOR vgfs)
|
||
{
|
||
unsigned char *TrackPtr = vgfs.vgfa.TrackPointer;
|
||
unsigned int TrackLen = vgfs.vgfa.TrackLength;
|
||
unsigned int len = vgfs.OffsetEndSector - vgfs.MarkedOffsetSector;
|
||
if (vgfs.OffsetEndSector < vgfs.MarkedOffsetSector)
|
||
len = (TrackLen - vgfs.MarkedOffsetSector) + vgfs.OffsetEndSector;
|
||
|
||
unsigned int off1 = vgfs.MarkedOffsetSector;
|
||
unsigned int len1 = TrackLen - vgfs.MarkedOffsetSector;
|
||
if (len1 > len) len1 = len;
|
||
unsigned int off2 = 0;
|
||
unsigned int len2 = 0;
|
||
if (len1 < len) len2 = len - len1;
|
||
|
||
unsigned int i;
|
||
unsigned short CRC = 0xFFFF;
|
||
for (i = 0; i < len1; i++)
|
||
{
|
||
CRC ^= TrackPtr[off1 + i] << 8;
|
||
for (unsigned int j = 0; j < 8; j++)
|
||
{
|
||
if (CRC & 0x8000) CRC = (CRC << 1) ^ 0x1021;
|
||
else CRC <<= 1;
|
||
}
|
||
}
|
||
for (i = 0; i < len2; i++)
|
||
{
|
||
CRC ^= TrackPtr[off2 + i] << 8;
|
||
for (unsigned int j = 0; j < 8; j++)
|
||
{
|
||
if (CRC & 0x8000) CRC = (CRC << 1) ^ 0x1021;
|
||
else CRC <<= 1;
|
||
}
|
||
}
|
||
unsigned int crcoff = (off1 + len1) % TrackLen;
|
||
if (len2) crcoff = (off2 + len2) % TrackLen;
|
||
|
||
TrackPtr[crcoff] = (unsigned char)(CRC >> 8);
|
||
TrackPtr[(crcoff + 1) % TrackLen] = (unsigned char)(CRC & 0xFF);
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
//
|
||
// DANGER! CRC checking not prepared for track length overflow!
|
||
//
|
||
bool TDiskImage::FindADMark(unsigned char CYL, unsigned char SIDE,
|
||
unsigned int FromOffset,
|
||
VGFIND_ADM *vgfa)
|
||
{
|
||
vgfa->TrackPointer = NULL;
|
||
vgfa->ClkPointer = NULL;
|
||
vgfa->TrackLength = 0;
|
||
vgfa->ADMPointer = NULL;
|
||
vgfa->ADMLength = 0;
|
||
vgfa->FoundADM = false;
|
||
vgfa->CRCOK = false;
|
||
|
||
if ((!DiskPresent) |
|
||
((CYL > MaxTrack) || (SIDE > MaxSide)) |
|
||
((!FTracksPtr[CYL][SIDE][0]) || (!FTracksPtr[CYL][SIDE][1])))
|
||
{
|
||
return false; // ERROR: disk not ready
|
||
}
|
||
|
||
unsigned char *track = vgfa->TrackPointer = FTracksPtr[CYL][SIDE][0];
|
||
unsigned char *clks = vgfa->ClkPointer = FTracksPtr[CYL][SIDE][1];
|
||
unsigned int tlen = vgfa->TrackLength = FTrackLength[CYL][SIDE];
|
||
|
||
unsigned int off, rc;
|
||
|
||
unsigned int pos = FromOffset;
|
||
for (; pos < tlen + FromOffset; pos++)
|
||
{
|
||
off = pos%tlen;
|
||
if ((track[off] == 0xA1) && (clks[off])) // fnd Mark
|
||
{
|
||
off = (off + 1) % tlen;
|
||
|
||
rc = tlen;
|
||
while ((track[off] == 0xA1) && (clks[off])) // repeat Mark
|
||
{
|
||
if (!rc) return false; // ERROR: MFM marks all disk
|
||
off = (off + 1) % tlen;
|
||
rc--;
|
||
}
|
||
|
||
if (track[off] != 0xFE) continue;
|
||
|
||
off = (off + 1) % tlen;
|
||
|
||
vgfa->FoundADM = true;
|
||
vgfa->MarkedOffsetADM = pos%tlen;
|
||
vgfa->OffsetADM = off;
|
||
vgfa->OffsetEndADM = (off + 6) % tlen;
|
||
vgfa->ADMLength = 6;
|
||
vgfa->ADMPointer = track + off;
|
||
|
||
unsigned short crc = MakeVGCRC(track + (pos%tlen), (off - (pos%tlen)) + 4);
|
||
|
||
vgfa->CRCOK = (track[(off + 4) % tlen] == (crc >> 8)) && (track[(off + 5) % tlen] == (crc & 0xFF));
|
||
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
//
|
||
// DANGER! CRC checking not prepared for track length overflow!
|
||
//
|
||
bool TDiskImage::FindSector(unsigned char CYL, unsigned char SIDE,
|
||
unsigned char SECT,
|
||
VGFIND_SECTOR *vgfs, unsigned int FromOffset)
|
||
{
|
||
vgfs->SectorPointer = NULL;
|
||
vgfs->SectorLength = 0;
|
||
vgfs->FoundDATA = false;
|
||
vgfs->CRCOK = false;
|
||
|
||
if ((!DiskPresent) |
|
||
((CYL > MaxTrack) || (SIDE > MaxSide)) |
|
||
((!FTracksPtr[CYL][SIDE][0]) || (!FTracksPtr[CYL][SIDE][1])))
|
||
{
|
||
vgfs->vgfa.TrackPointer = NULL;
|
||
vgfs->vgfa.ClkPointer = NULL;
|
||
vgfs->vgfa.TrackLength = 0;
|
||
vgfs->vgfa.ADMPointer = NULL;
|
||
vgfs->vgfa.ADMLength = 0;
|
||
vgfs->vgfa.FoundADM = false;
|
||
vgfs->vgfa.CRCOK = false;
|
||
return false; // ERROR: disk not ready
|
||
}
|
||
|
||
unsigned int TrackOffset = FromOffset;
|
||
|
||
bool FirstFind = true;
|
||
unsigned int FirstPos = 0;
|
||
|
||
// Поиск адресной метки требуемого сектора...
|
||
bool ADFOUND = false;
|
||
for (;;)
|
||
{
|
||
if (!FindADMark(CYL, SIDE, TrackOffset, &(vgfs->vgfa)))
|
||
return false; // ERROR: No ADMARK found on track
|
||
|
||
if (vgfs->vgfa.TrackPointer[(vgfs->vgfa.OffsetADM + 2) % vgfs->vgfa.TrackLength] == SECT)
|
||
{
|
||
ADFOUND = true;
|
||
break;
|
||
}
|
||
|
||
if (!FirstFind)
|
||
{
|
||
if (vgfs->vgfa.OffsetEndADM == FirstPos) break;
|
||
}
|
||
else
|
||
{
|
||
FirstPos = vgfs->vgfa.OffsetEndADM;
|
||
FirstFind = false;
|
||
}
|
||
|
||
TrackOffset = vgfs->vgfa.OffsetEndADM;
|
||
};
|
||
|
||
if (!ADFOUND) return false;
|
||
|
||
// ADRMARK нужного найден, поиск массива данных...
|
||
|
||
unsigned char *track = vgfs->vgfa.TrackPointer;
|
||
unsigned char *clks = vgfs->vgfa.ClkPointer;
|
||
unsigned int tlen = vgfs->vgfa.TrackLength;
|
||
|
||
unsigned int pos = vgfs->vgfa.OffsetEndADM;
|
||
|
||
unsigned int off, rc;
|
||
|
||
for (; pos < tlen * 2; pos++)
|
||
{
|
||
off = pos%tlen;
|
||
if ((track[off] == 0xA1) && (clks[off])) // fnd Mark
|
||
{
|
||
off = (off + 1) % tlen;
|
||
|
||
rc = tlen;
|
||
while ((track[off] == 0xA1) && (clks[off])) // repeat Mark
|
||
{
|
||
if (!rc) return false; // ERROR: MFM marks all disk
|
||
off = (off + 1) % tlen;
|
||
rc--;
|
||
}
|
||
|
||
if ((track[off] < 0xF8) || (track[off] > 0xFB))
|
||
{
|
||
break; // ERROR: data array not found
|
||
}
|
||
vgfs->DataMarker = track[off];
|
||
|
||
off = (off + 1) % tlen;
|
||
|
||
vgfs->FoundDATA = true;
|
||
|
||
unsigned char SL = vgfs->vgfa.TrackPointer[(vgfs->vgfa.OffsetADM + 3) % vgfs->vgfa.TrackLength];
|
||
vgfs->SectorLength = 128;
|
||
if (SL) vgfs->SectorLength <<= SL;
|
||
vgfs->SectorPointer = track + off;
|
||
|
||
vgfs->MarkedOffsetSector = pos%tlen;
|
||
vgfs->OffsetSector = off;
|
||
vgfs->OffsetEndSector = (off + vgfs->SectorLength) % tlen;
|
||
|
||
unsigned short crc = MakeVGCRC(track + (pos%tlen), (off - (pos%tlen)) + vgfs->SectorLength);
|
||
vgfs->CRCOK = (track[(off + vgfs->SectorLength) % tlen] == (crc >> 8)) && (track[(off + vgfs->SectorLength + 1) % tlen] == (crc & 0xFF));
|
||
|
||
return true; // OK read
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
bool TDiskImage::FindTrack(unsigned char CYL, unsigned char SIDE, VGFIND_TRACK *vgft)
|
||
{
|
||
vgft->FoundTrack = false;
|
||
vgft->TrackPointer = NULL;
|
||
vgft->ClkPointer = NULL;
|
||
vgft->TrackLength = 0;
|
||
|
||
if ((!DiskPresent) |
|
||
((CYL > MaxTrack) || (SIDE > MaxSide)) |
|
||
((!FTracksPtr[CYL][SIDE][0]) || (!FTracksPtr[CYL][SIDE][1])))
|
||
{
|
||
return false; // ERROR: disk not ready
|
||
}
|
||
|
||
vgft->TrackPointer = FTracksPtr[CYL][SIDE][0];
|
||
vgft->ClkPointer = FTracksPtr[CYL][SIDE][1];
|
||
vgft->TrackLength = FTrackLength[CYL][SIDE];
|
||
vgft->FoundTrack = true;
|
||
return true;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::Open(const char *filename, bool ROnly)
|
||
{
|
||
const char *ext = "";
|
||
if (strlen(filename) > 4) ext = filename + strlen(filename) - 4;
|
||
|
||
TDiskImageType typ = DIT_UNK;
|
||
if (!strcasecmp(ext, ".SCL")) typ = DIT_SCL;
|
||
if (!strcasecmp(ext, ".FDI")) typ = DIT_FDI;
|
||
if (!strcasecmp(ext, ".UDI")) typ = DIT_UDI;
|
||
if (!strcasecmp(ext, ".TD0")) typ = DIT_TD0;
|
||
if (!strcasecmp(ext, ".FDD")) typ = DIT_FDD;
|
||
if (!memcmp(ext + 1, ".$", 2)) typ = DIT_HOB;
|
||
if (!memcmp(ext + 1, ".!", 2)) typ = DIT_HOB;
|
||
|
||
if (!((FType == DIT_HOB) && (typ == DIT_HOB))) // if not hobeta clear disk...
|
||
{
|
||
ReadOnly = true;
|
||
DiskPresent = false;
|
||
Changed = false;
|
||
FType = DIT_UNK;
|
||
|
||
for (int t = 0; t < 256; t++)
|
||
for (int s = 0; s < 256; s++)
|
||
{
|
||
FTrackLength[t][s] = 0;
|
||
if (FTracksPtr[t][s][0]) delete FTracksPtr[t][s][0];
|
||
FTracksPtr[t][s][0] = NULL;
|
||
if (FTracksPtr[t][s][1]) delete FTracksPtr[t][s][1];
|
||
FTracksPtr[t][s][1] = NULL;
|
||
}
|
||
}
|
||
|
||
if (typ == DIT_UNK)
|
||
{
|
||
ShowError(ERR_UNKFORMAT);
|
||
return;
|
||
}
|
||
FType = typ;
|
||
|
||
int hfile = open(filename, O_RDONLY | O_CLOEXEC);
|
||
|
||
if (hfile < 0)
|
||
{
|
||
char sbuf[8192];
|
||
sprintf(sbuf, ERR_OPEN" %s", filename);
|
||
ShowError(sbuf);
|
||
return;
|
||
}
|
||
|
||
if (typ == DIT_SCL) readSCL(hfile, ROnly);
|
||
if (typ == DIT_FDI) readFDI(hfile, ROnly);
|
||
if (typ == DIT_UDI) readUDI(hfile, ROnly);
|
||
if (typ == DIT_TD0) readTD0(hfile, ROnly);
|
||
if (typ == DIT_FDD) readFDD(hfile, ROnly);
|
||
if (typ == DIT_HOB) readHOB(hfile);
|
||
|
||
close(hfile);
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::formatTRDOS(unsigned int Tcount, unsigned int Scount)
|
||
{
|
||
MaxTrack = Tcount - 1;
|
||
MaxSide = Scount - 1;
|
||
|
||
unsigned short TotalSecs = Tcount*Scount * 16 - 16;
|
||
|
||
// форматирование нового диска под TR-DOS (16 x 256bytes sector per track)...
|
||
unsigned int ptrcrc;
|
||
unsigned int r;
|
||
unsigned short vgcrc;
|
||
for (unsigned int trk = 0; trk <= unsigned(MaxTrack); trk++)
|
||
for (unsigned int side = 0; side <= unsigned(MaxSide); side++)
|
||
{
|
||
FTrackLength[trk][side] = 6250;
|
||
|
||
FTracksPtr[trk][side][0] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // trk img
|
||
FTracksPtr[trk][side][1] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // clk img
|
||
|
||
unsigned int tptr = 0;
|
||
for (int sec = 0; sec < 16; sec++)
|
||
{
|
||
for (r = 0; r < 10; r++) // Первый пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
for (r = 0; r < 12; r++) // Синхропромежуток
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x00;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
ptrcrc = tptr;
|
||
for (r = 0; r < 3; r++) // Синхроимпульс
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0xA1;
|
||
FTracksPtr[trk][side][1][tptr++] = 0xFF;
|
||
}
|
||
FTracksPtr[trk][side][0][tptr] = 0xFE; // Метка "Адрес"
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)trk; // cyl
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)0x00; // head (TR always 0)
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(sec + 1); // secN
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)0x01; // len=256b
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
vgcrc = MakeVGCRC(FTracksPtr[trk][side][0] + ptrcrc, tptr - ptrcrc);
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc >> 8); // VG93 CRC
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc & 0xFF);
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
for (r = 0; r < 22; r++) // Второй пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
for (r = 0; r < 12; r++) // Синхропромежуток
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x00;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
ptrcrc = tptr;
|
||
for (r = 0; r < 3; r++) // Синхроимпульс
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0xA1;
|
||
FTracksPtr[trk][side][1][tptr++] = 0xFF;
|
||
}
|
||
FTracksPtr[trk][side][0][tptr] = 0xFB; // Метка "Данные"
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
for (r = 0; r < 256; r++) // сектор 256байт
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x00;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
if ((trk == 0) && (side == 0) && (sec == 8)) // make TR-DOS id
|
||
{
|
||
int ssec = tptr - 256;
|
||
FTracksPtr[trk][side][0][ssec + 0xE1] = 0x00; // first free SECT
|
||
FTracksPtr[trk][side][0][ssec + 0xE2] = 0x01; // first free TRACK
|
||
FTracksPtr[trk][side][0][ssec + 0xE3] = 0x16; // 80trk DS
|
||
FTracksPtr[trk][side][0][ssec + 0xE4] = 0x00; // file count
|
||
*(unsigned short*)(FTracksPtr[trk][side][0] + ssec + 0xE5)
|
||
= TotalSecs; // free SECS count
|
||
FTracksPtr[trk][side][0][ssec + 0xE7] = 0x10; // TR-DOS id
|
||
FTracksPtr[trk][side][0][ssec + 0xF4] = 0x00; // deleted file count
|
||
|
||
memcpy(FTracksPtr[trk][side][0] + ssec + 0xF5,
|
||
STR_CREATEDISKNAME" ", 8); // disk name
|
||
FTracksPtr[trk][side][0][ssec + 0xFD] = 0x00; // zero
|
||
FTracksPtr[trk][side][0][ssec + 0xFE] = 0x00; // zero
|
||
FTracksPtr[trk][side][0][ssec + 0xFF] = 0x00; // zero
|
||
}
|
||
|
||
vgcrc = MakeVGCRC(FTracksPtr[trk][side][0] + ptrcrc, tptr - ptrcrc);
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc >> 8); // VG93 CRC
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc & 0xFF);
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
for (r = 0; r < 60; r++) // Третий пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
}
|
||
for (int eoftrk = tptr; eoftrk < 6250; eoftrk++)
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
}
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::readUDI(int hfile, bool ronly)
|
||
{
|
||
long fsize = filelength(hfile);
|
||
if (fsize < 0)
|
||
{
|
||
ShowError(ERR_GETLEN);
|
||
return;
|
||
}
|
||
|
||
unsigned char *ptr = (unsigned char*)new char[fsize + 1024 * 2048];
|
||
if (!ptr)
|
||
{
|
||
ShowError(ERR_NOMEM);
|
||
return;
|
||
}
|
||
|
||
unsigned long rsize = read(hfile, ptr, fsize + 1024);
|
||
if (rsize < 16 + 4)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
if (memcmp(ptr, "UDI!", 4) != 0)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_FORMAT" UDI!");
|
||
return;
|
||
}
|
||
|
||
UDI_HEADER *udi_hdr = (UDI_HEADER*)(ptr);
|
||
|
||
if ((udi_hdr->Version != 0x00) || (udi_hdr->_zero != 0x00) || (udi_hdr->ExtHdrLength != 0))
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_FILEVER" UDI!");
|
||
return;
|
||
}
|
||
if (rsize != (udi_hdr->UnpackedLength + 4))
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
MaxTrack = udi_hdr->MaxCylinder;
|
||
MaxSide = udi_hdr->MaxSide;
|
||
|
||
|
||
// checking for corrupt...
|
||
unsigned int udiOFF = 0x10;
|
||
|
||
unsigned int trk, side;
|
||
|
||
for (trk = 0; trk <= unsigned(MaxTrack); trk++)
|
||
for (side = 0; side <= unsigned(MaxSide); side++)
|
||
{
|
||
unsigned char frmt = ptr[udiOFF++];
|
||
if (rsize < udiOFF + 4)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
if (frmt)
|
||
{
|
||
udiOFF += *((unsigned long*)(ptr + udiOFF));
|
||
udiOFF += 4;
|
||
continue;
|
||
}
|
||
|
||
unsigned ccctlen = *((unsigned short*)(ptr + udiOFF));
|
||
udiOFF += ccctlen;
|
||
udiOFF += 2;
|
||
if (rsize < udiOFF + 4)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
udiOFF += ccctlen / 8 + ((ccctlen - (ccctlen / 8) * 8) ? 1 : 0);
|
||
if (rsize < udiOFF + 4)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
udiOFF = 0x10;
|
||
|
||
unsigned int trklen;
|
||
|
||
for (trk = 0; trk <= unsigned(MaxTrack); trk++)
|
||
for (side = 0; side <= unsigned(MaxSide); side++)
|
||
{
|
||
if (udiOFF >= rsize) break;
|
||
|
||
if (ptr[udiOFF++] != 0) // non MFM track?
|
||
{
|
||
FTrackLength[trk][side] = 6250;
|
||
// make unformatted track...
|
||
FTracksPtr[trk][side][0] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // trk img
|
||
FTracksPtr[trk][side][1] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // clk img
|
||
for (unsigned ij = 0; ij < 6250; ij++)
|
||
{
|
||
FTracksPtr[trk][side][0][ij] = 0x00;
|
||
FTracksPtr[trk][side][1][ij] = 0x00;
|
||
}
|
||
|
||
udiOFF += *((unsigned long*)(ptr + udiOFF));
|
||
udiOFF += 4;
|
||
continue;
|
||
}
|
||
trklen = *((unsigned short*)(ptr + udiOFF));
|
||
udiOFF += 2;
|
||
FTrackLength[trk][side] = trklen;
|
||
|
||
// make unformatted track...
|
||
FTracksPtr[trk][side][0] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // trk img
|
||
FTracksPtr[trk][side][1] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // clk img
|
||
for (unsigned ij = 0; ij < FTrackLength[trk][side]; ij++)
|
||
{
|
||
FTracksPtr[trk][side][0][ij] = 0x00;
|
||
FTracksPtr[trk][side][1][ij] = 0x00;
|
||
}
|
||
|
||
memcpy(FTracksPtr[trk][side][0], ptr + udiOFF, FTrackLength[trk][side]);
|
||
udiOFF += trklen;
|
||
|
||
unsigned int MFMinfoLen = trklen / 8 + ((trklen - (trklen / 8) * 8) ? 1 : 0);
|
||
|
||
unsigned char mask;
|
||
for (unsigned i = 0; i < MFMinfoLen; i++)
|
||
{
|
||
mask = 0x01;
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
if (ptr[udiOFF] & mask) FTracksPtr[trk][side][1][i * 8 + j] = 0xFF;
|
||
else FTracksPtr[trk][side][1][i * 8 + j] = 0x00;
|
||
mask <<= 1;
|
||
}
|
||
udiOFF++;
|
||
}
|
||
}
|
||
long CRC = -1l;
|
||
for (unsigned int i = 0; i < udiOFF; i++) CRC = CalcCRC32(CRC, ptr[i]);
|
||
|
||
|
||
if (udiOFF < rsize)
|
||
if (*((long*)(ptr + udiOFF)) != CRC)
|
||
ShowError(ERR_FILECRC" UDI!");
|
||
|
||
delete[] ptr;
|
||
ReadOnly = ronly;
|
||
FType = DIT_UDI;
|
||
DiskPresent = true;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::writeTRD(fileTYPE *hfile)
|
||
{
|
||
VGFIND_SECTOR vgfs;
|
||
|
||
// prepare nullbuf...
|
||
unsigned char nullbuf[256];
|
||
for (int i = 0; i < 256; i++) nullbuf[i] = '*';
|
||
memcpy(nullbuf, errsect, sizeof(errsect));
|
||
|
||
for (unsigned int trk = 0; trk <= unsigned(MaxTrack); trk++)
|
||
for (unsigned int side = 0; side <= unsigned(MaxSide); side++)
|
||
for (unsigned int sec = 0; sec < 16; sec++)
|
||
{
|
||
if (FindSector(trk, side, sec + 1, &vgfs))
|
||
{
|
||
FileWriteAdv(hfile, vgfs.SectorPointer, 256);
|
||
if ((!vgfs.CRCOK) || (!vgfs.vgfa.CRCOK)) printf("Warning: sector %d on track %d, side %d with BAD CRC!\n", sec + 1, trk, side);
|
||
if (vgfs.SectorLength != 256) printf("Warning: sector %d on track %d, side %d is non 256 bytes!\n", sec + 1, trk, side);
|
||
}
|
||
else
|
||
{
|
||
FileWriteAdv(hfile, nullbuf, 256);
|
||
printf("DANGER! Sector %d on track %d, side %d not found!\n", sec + 1, trk, side);
|
||
}
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::readFDI(int hfile, bool readonly)
|
||
{
|
||
long fsize = filelength(hfile);
|
||
if (fsize < 0)
|
||
{
|
||
ShowError(ERR_GETLEN);
|
||
return;
|
||
}
|
||
|
||
unsigned char *ptr = (unsigned char*)new char[fsize + 1024 * 2048];
|
||
if (!ptr)
|
||
{
|
||
ShowError(ERR_NOMEM);
|
||
return;
|
||
}
|
||
|
||
unsigned long rsize = read(hfile, ptr, fsize);
|
||
if (rsize < 14)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
if (memcmp(ptr, "FDI", 3) != 0)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_FORMAT" FDI!");
|
||
return;
|
||
}
|
||
|
||
// ==========================================
|
||
// ********** Analyse FDI header ************...
|
||
// ------------------------------------------
|
||
unsigned short *fdihead = (unsigned short*)(ptr + 4);
|
||
unsigned int fdiCylCount = fdihead[0]; // +4
|
||
unsigned int fdiSideCount = fdihead[1]; // +6
|
||
// unsigned int fdiOFFtext = fdihead[2]; // +8
|
||
unsigned int fdiOFFdata = fdihead[3]; // +A
|
||
unsigned int fdiSIZEext = fdihead[4]; // +C
|
||
|
||
if ((fdiCylCount > 256) || (fdiCylCount == 0))
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_MANYCYLS);
|
||
return;
|
||
}
|
||
if ((fdiSideCount > 256) || (fdiSideCount == 0))
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_MANYSIDS);
|
||
return;
|
||
}
|
||
|
||
MaxTrack = (unsigned char)(fdiCylCount - 1);
|
||
MaxSide = (unsigned char)(fdiSideCount - 1);
|
||
|
||
if (rsize < (0x0E + fdiSIZEext + (unsigned(MaxTrack) + 1)*(unsigned(MaxSide) + 1) * 7))
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
struct FDISECINFO
|
||
{
|
||
unsigned char ADAM[5];
|
||
unsigned int SectorOffset; // относит DataOffset
|
||
};
|
||
struct FDITRACKHDR
|
||
{
|
||
unsigned int DataOffset; // относит начала файла
|
||
unsigned int SectorCount;
|
||
FDISECINFO SectorsInfo[256];
|
||
};
|
||
FDITRACKHDR *tracksinfo = new FDITRACKHDR[(unsigned(MaxTrack) + 1)*(unsigned(MaxSide) + 1)];
|
||
|
||
unsigned int fdiOFF = 0x0E + fdiSIZEext;
|
||
|
||
unsigned int trk, side;
|
||
// Анализ области заголовков треков...
|
||
for (trk = 0; trk <= unsigned(MaxTrack); trk++)
|
||
for (side = 0; side <= unsigned(MaxSide); side++)
|
||
{
|
||
if (rsize < fdiOFF)
|
||
{
|
||
delete[] tracksinfo;
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
tracksinfo[trk*(MaxSide + 1) + side].DataOffset = *((unsigned long*)(ptr + fdiOFF));
|
||
fdiOFF += 4;
|
||
|
||
if (rsize < fdiOFFdata + tracksinfo[trk*(MaxSide + 1) + side].DataOffset)
|
||
{
|
||
delete[] tracksinfo;
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
fdiOFF += 2; // "Всегда содержит 0 (резерв для модернизации)"
|
||
|
||
tracksinfo[trk*(MaxSide + 1) + side].SectorCount = unsigned(ptr[fdiOFF++]);
|
||
|
||
for (unsigned isec = 0; isec < tracksinfo[trk*(MaxSide + 1) + side].SectorCount; isec++)
|
||
{
|
||
memcpy(tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[isec].ADAM, ptr + fdiOFF, 5);
|
||
fdiOFF += 5;
|
||
tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[isec].SectorOffset = unsigned(*((unsigned short*)(ptr + fdiOFF)));
|
||
fdiOFF += 2;
|
||
|
||
if (rsize < fdiOFFdata + tracksinfo[trk*(MaxSide + 1) + side].DataOffset + tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[isec].SectorOffset)
|
||
{
|
||
delete[] tracksinfo;
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
// форматирование нового диска и размещение FDI секторов...
|
||
unsigned int ptrcrc;
|
||
unsigned int r;
|
||
unsigned short vgcrc;
|
||
unsigned int trkdatalen;
|
||
unsigned SecCount;
|
||
unsigned SL;
|
||
|
||
for (trk = 0; trk <= unsigned(MaxTrack); trk++)
|
||
for (side = 0; side <= unsigned(MaxSide); side++)
|
||
{
|
||
FTrackLength[trk][side] = 6250;
|
||
|
||
// make unformatted track...
|
||
FTracksPtr[trk][side][0] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // trk img
|
||
FTracksPtr[trk][side][1] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // clk img
|
||
for (unsigned ij = 0; ij < 6250; ij++)
|
||
{
|
||
FTracksPtr[trk][side][0][ij] = 0x00;
|
||
FTracksPtr[trk][side][1][ij] = 0x00;
|
||
}
|
||
|
||
SecCount = tracksinfo[trk*(MaxSide + 1) + side].SectorCount;
|
||
|
||
// Вычисляем необходимое число байт под данные:
|
||
trkdatalen = 0;
|
||
for (unsigned int ilsec = 0; ilsec < SecCount; ilsec++)
|
||
{
|
||
trkdatalen += 2 + 6; // for marks: 0xA1, 0xFE, 6bytes
|
||
SL = unsigned(tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[ilsec].ADAM[3]);
|
||
if (!SL) SL = 128;
|
||
else SL = 128 << SL;
|
||
|
||
if (tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[ilsec].ADAM[4] & 0x40)
|
||
SL = 0; // заголовок без массива данных
|
||
else
|
||
trkdatalen += 4; // for data header/crc: 0xA1, 0xFB, ...,2bytes
|
||
|
||
trkdatalen += SL;
|
||
}
|
||
|
||
if (trkdatalen + SecCount*(3 + 2) > 6250) // 3x4E & 2x00 per sec checking
|
||
{
|
||
delete[] tracksinfo;
|
||
delete[] ptr;
|
||
for (int t = 0; t < 256; t++)
|
||
for (int s = 0; s < 256; s++)
|
||
{
|
||
FTrackLength[t][s] = 0;
|
||
if (FTracksPtr[t][s][0]) delete FTracksPtr[t][s][0];
|
||
FTracksPtr[t][s][0] = NULL;
|
||
if (FTracksPtr[t][s][1]) delete FTracksPtr[t][s][1];
|
||
FTracksPtr[t][s][1] = NULL;
|
||
}
|
||
ShowError(ERR_IMPOSSIBLE);
|
||
return;
|
||
}
|
||
|
||
unsigned int FreeSpace = 6250 - (trkdatalen + SecCount*(3 + 2));
|
||
|
||
unsigned int SynchroPulseLen = 1; // 1 уже учтен в trkdatalen...
|
||
unsigned int FirstSpaceLen = 1;
|
||
unsigned int SecondSpaceLen = 1;
|
||
unsigned int ThirdSpaceLen = 1;
|
||
unsigned int SynchroSpaceLen = 1;
|
||
FreeSpace -= FirstSpaceLen + SecondSpaceLen + ThirdSpaceLen + SynchroSpaceLen;
|
||
|
||
// Распределяем длины пробелов и синхропромежутка:
|
||
while (FreeSpace > 0)
|
||
{
|
||
if (FreeSpace >= (SecCount * 2))
|
||
if (SynchroSpaceLen < 12) { SynchroSpaceLen++; FreeSpace -= SecCount * 2; } // Synchro for ADM & DATA
|
||
if (FreeSpace < SecCount) break;
|
||
|
||
if (FirstSpaceLen < 10) { FirstSpaceLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace < SecCount) break;
|
||
if (SecondSpaceLen < 22) { SecondSpaceLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace < SecCount) break;
|
||
if (ThirdSpaceLen < 60) { ThirdSpaceLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace < SecCount) break;
|
||
|
||
if ((SynchroSpaceLen >= 12) && (FirstSpaceLen >= 10) && (SecondSpaceLen >= 22) && (ThirdSpaceLen >= 60)) break;
|
||
};
|
||
// по возможности делаем три синхроимпульса...
|
||
if (FreeSpace >(SecCount * 2) + 10) { SynchroPulseLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace >(SecCount * 2) + 9) SynchroPulseLen++;
|
||
|
||
// Форматируем дорожку...
|
||
|
||
unsigned int tptr = 0;
|
||
for (unsigned sec = 0; sec < SecCount; sec++)
|
||
{
|
||
for (r = 0; r < FirstSpaceLen; r++) // Первый пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
for (r = 0; r < SynchroSpaceLen; r++) // Синхропромежуток
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x00;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
ptrcrc = tptr;
|
||
for (r = 0; r < SynchroPulseLen; r++) // Синхроимпульс
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0xA1;
|
||
FTracksPtr[trk][side][1][tptr++] = 0xFF;
|
||
}
|
||
FTracksPtr[trk][side][0][tptr] = 0xFE; // Метка "Адрес"
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
FTracksPtr[trk][side][0][tptr] = tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[sec].ADAM[0]; // cyl
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[sec].ADAM[1]; // head
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[sec].ADAM[2]; // secN
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[sec].ADAM[3]; // len code
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
vgcrc = MakeVGCRC(FTracksPtr[trk][side][0] + ptrcrc, tptr - ptrcrc);
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc >> 8); // VG93 CRC
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc & 0xFF);
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
for (r = 0; r < SecondSpaceLen; r++) // Второй пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
for (r = 0; r < SynchroSpaceLen; r++) // Синхропромежуток
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x00;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
|
||
unsigned char fdiSectorFlags = tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[sec].ADAM[4];
|
||
|
||
// !!!!!!!!!
|
||
// !WARNING! this feature of FDI format is NOT FULL DOCUMENTED!!!
|
||
// !!!!!!!!!
|
||
//
|
||
// Flags::bit6 - Возможно, 1 в данном разряде
|
||
// будет обозначать адресный маркер без области данных.
|
||
//
|
||
|
||
if (!(fdiSectorFlags & 0x40)) // oh-oh, data area not present... ;-)
|
||
{
|
||
ptrcrc = tptr;
|
||
for (r = 0; r < SynchroPulseLen; r++) // Синхроимпульс
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0xA1;
|
||
FTracksPtr[trk][side][1][tptr++] = 0xFF;
|
||
}
|
||
|
||
if (fdiSectorFlags & 0x80)
|
||
FTracksPtr[trk][side][0][tptr] = 0xF8; // Метка "Удаленные данные"
|
||
else
|
||
FTracksPtr[trk][side][0][tptr] = 0xFB; // Метка "Данные"
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
|
||
SL = unsigned(tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[sec].ADAM[3]);
|
||
if (!SL) SL = 128;
|
||
else SL = 128 << SL;
|
||
|
||
unsigned int secDATAOFF = fdiOFFdata + tracksinfo[trk*(MaxSide + 1) + side].DataOffset + tracksinfo[trk*(MaxSide + 1) + side].SectorsInfo[sec].SectorOffset;
|
||
|
||
for (r = 0; r < SL; r++) // сектор SL байт
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = ptr[secDATAOFF + r];
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
|
||
vgcrc = MakeVGCRC(FTracksPtr[trk][side][0] + ptrcrc, tptr - ptrcrc);
|
||
|
||
|
||
if (fdiSectorFlags & 0x3F) // CRC correct?
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc >> 8); // VG93 CRC
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc & 0xFF);
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
else // oh-oh, high technology... CRC bad... ;-)
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc >> 8) ^ 0xFF; // emulation bad CRC... ;)
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc & 0xFF) ^ 0xFF; // --//-- ;)
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
}
|
||
|
||
|
||
for (r = 0; r < ThirdSpaceLen; r++) // Третий пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
}
|
||
for (int eoftrk = tptr; eoftrk < 6250; eoftrk++)
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
}
|
||
|
||
delete[] tracksinfo;
|
||
delete[] ptr;
|
||
ReadOnly = readonly;
|
||
FType = DIT_FDI;
|
||
DiskPresent = true;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::readFDD(int hfile, bool readonly)
|
||
{
|
||
|
||
long fsize = filelength(hfile);
|
||
if (fsize < 0)
|
||
{
|
||
ShowError(ERR_GETLEN);
|
||
return;
|
||
}
|
||
|
||
unsigned char *ptr = (unsigned char*)new char[fsize + 1024 * 32];
|
||
if (!ptr)
|
||
{
|
||
ShowError(ERR_NOMEM);
|
||
return;
|
||
}
|
||
|
||
unsigned long rsize = read(hfile, ptr, fsize);
|
||
if (rsize < sizeof(FDD_MAIN_HEADER))
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
FDD_MAIN_HEADER *fdd_hdr = (FDD_MAIN_HEADER*)ptr;
|
||
|
||
int MaxC = fdd_hdr->MaxTracks;
|
||
int MaxH = fdd_hdr->MaxHeads;
|
||
|
||
if (MaxH > 2)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_MANYSIDS);
|
||
return;
|
||
}
|
||
|
||
|
||
MaxH = (MaxH - 1) & 0xFF;
|
||
MaxC = (MaxC - 1) & 0xFF;
|
||
|
||
|
||
MaxTrack = MaxC;
|
||
MaxSide = MaxH;
|
||
|
||
|
||
// форматирование нового диска и размещение FDD секторов...
|
||
unsigned int ptrcrc;
|
||
unsigned int r;
|
||
unsigned short vgcrc;
|
||
unsigned int trkdatalen;
|
||
unsigned SecCount;
|
||
unsigned SL;
|
||
|
||
FDD_TRACK_HEADER *trackinfo;
|
||
|
||
unsigned int trk, side;
|
||
|
||
for (trk = 0; trk <= unsigned(MaxTrack); trk++)
|
||
for (side = 0; side <= unsigned(MaxSide); side++)
|
||
{
|
||
FTrackLength[trk][side] = 6250;
|
||
|
||
// make unformatted track...
|
||
FTracksPtr[trk][side][0] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // trk img
|
||
FTracksPtr[trk][side][1] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // clk img
|
||
for (unsigned ij = 0; ij < 6250; ij++)
|
||
{
|
||
FTracksPtr[trk][side][0][ij] = 0x00;
|
||
FTracksPtr[trk][side][1][ij] = 0x00;
|
||
}
|
||
|
||
if ((fdd_hdr->DataOffset[trk*(MaxSide + 1) + side] + 2) > int(rsize))
|
||
{
|
||
delete[] ptr;
|
||
for (int t = 0; t < 256; t++)
|
||
for (int s = 0; s < 256; s++)
|
||
{
|
||
FTrackLength[t][s] = 0;
|
||
if (FTracksPtr[t][s][0]) delete FTracksPtr[t][s][0];
|
||
FTracksPtr[t][s][0] = NULL;
|
||
if (FTracksPtr[t][s][1]) delete FTracksPtr[t][s][1];
|
||
FTracksPtr[t][s][1] = NULL;
|
||
}
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
trackinfo = (FDD_TRACK_HEADER *)(ptr + fdd_hdr->DataOffset[trk*(MaxSide + 1) + side]);
|
||
|
||
SecCount = trackinfo->SectNum;
|
||
|
||
if ((2 + SecCount * 8 + fdd_hdr->DataOffset[trk*(MaxSide + 1) + side]) > rsize)
|
||
{
|
||
delete[] ptr;
|
||
for (int t = 0; t < 256; t++)
|
||
for (int s = 0; s < 256; s++)
|
||
{
|
||
FTrackLength[t][s] = 0;
|
||
if (FTracksPtr[t][s][0]) delete FTracksPtr[t][s][0];
|
||
FTracksPtr[t][s][0] = NULL;
|
||
if (FTracksPtr[t][s][1]) delete FTracksPtr[t][s][1];
|
||
FTracksPtr[t][s][1] = NULL;
|
||
}
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
else if (trackinfo->sect[SecCount - 1].SectPos > int(rsize))
|
||
{
|
||
delete[] ptr;
|
||
for (int t = 0; t < 256; t++)
|
||
for (int s = 0; s < 256; s++)
|
||
{
|
||
FTrackLength[t][s] = 0;
|
||
if (FTracksPtr[t][s][0]) delete FTracksPtr[t][s][0];
|
||
FTracksPtr[t][s][0] = NULL;
|
||
if (FTracksPtr[t][s][1]) delete FTracksPtr[t][s][1];
|
||
FTracksPtr[t][s][1] = NULL;
|
||
}
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
// Вычисляем необходимое число байт под данные:
|
||
trkdatalen = 0;
|
||
for (unsigned int ilsec = 0; ilsec < SecCount; ilsec++)
|
||
{
|
||
trkdatalen += 2 + 6; // for marks: 0xA1, 0xFE, 6bytes
|
||
SL = unsigned(trackinfo->sect[ilsec].size);
|
||
if (!SL) SL = 128;
|
||
else SL = 128 << SL;
|
||
|
||
trkdatalen += 4; // for data header/crc: 0xA1, 0xFB, ...,2bytes
|
||
|
||
trkdatalen += SL;
|
||
}
|
||
|
||
if (trkdatalen + SecCount*(3 + 2) > 6250) // 3x4E & 2x00 per sec checking
|
||
{
|
||
delete[] ptr;
|
||
for (int t = 0; t < 256; t++)
|
||
for (int s = 0; s < 256; s++)
|
||
{
|
||
FTrackLength[t][s] = 0;
|
||
if (FTracksPtr[t][s][0]) delete FTracksPtr[t][s][0];
|
||
FTracksPtr[t][s][0] = NULL;
|
||
if (FTracksPtr[t][s][1]) delete FTracksPtr[t][s][1];
|
||
FTracksPtr[t][s][1] = NULL;
|
||
}
|
||
ShowError(ERR_IMPOSSIBLE);
|
||
return;
|
||
}
|
||
|
||
unsigned int FreeSpace = 6250 - (trkdatalen + SecCount*(3 + 2));
|
||
|
||
unsigned int SynchroPulseLen = 1; // 1 уже учтен в trkdatalen...
|
||
unsigned int FirstSpaceLen = 1;
|
||
unsigned int SecondSpaceLen = 1;
|
||
unsigned int ThirdSpaceLen = 1;
|
||
unsigned int SynchroSpaceLen = 1;
|
||
FreeSpace -= FirstSpaceLen + SecondSpaceLen + ThirdSpaceLen + SynchroSpaceLen;
|
||
|
||
// Распределяем длины пробелов и синхропромежутка:
|
||
while (FreeSpace > 0)
|
||
{
|
||
if (FreeSpace >= (SecCount * 2))
|
||
if (SynchroSpaceLen < 12) { SynchroSpaceLen++; FreeSpace -= SecCount * 2; } // Synchro for ADM & DATA
|
||
if (FreeSpace < SecCount) break;
|
||
|
||
if (FirstSpaceLen < 10) { FirstSpaceLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace < SecCount) break;
|
||
if (SecondSpaceLen < 22) { SecondSpaceLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace < SecCount) break;
|
||
if (ThirdSpaceLen < 60) { ThirdSpaceLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace < SecCount) break;
|
||
|
||
if ((SynchroSpaceLen >= 12) && (FirstSpaceLen >= 10) && (SecondSpaceLen >= 22) && (ThirdSpaceLen >= 60)) break;
|
||
};
|
||
// по возможности делаем три синхроимпульса...
|
||
if (FreeSpace >(SecCount * 2) + 10) { SynchroPulseLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace >(SecCount * 2) + 9) SynchroPulseLen++;
|
||
|
||
// Форматируем дорожку...
|
||
|
||
unsigned int tptr = 0;
|
||
for (unsigned sec = 0; sec < SecCount; sec++)
|
||
{
|
||
for (r = 0; r < FirstSpaceLen; r++) // Первый пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
for (r = 0; r < SynchroSpaceLen; r++) // Синхропромежуток
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x00;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
ptrcrc = tptr;
|
||
for (r = 0; r < SynchroPulseLen; r++) // Синхроимпульс
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0xA1;
|
||
FTracksPtr[trk][side][1][tptr++] = 0xFF;
|
||
}
|
||
FTracksPtr[trk][side][0][tptr] = 0xFE; // Метка "Адрес"
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
FTracksPtr[trk][side][0][tptr] = trackinfo->sect[sec].trk; // cyl
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = trackinfo->sect[sec].side; // head
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = trackinfo->sect[sec].sect; // secN
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = trackinfo->sect[sec].size; // len code
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
vgcrc = MakeVGCRC(FTracksPtr[trk][side][0] + ptrcrc, tptr - ptrcrc);
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc >> 8); // VG93 CRC
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc & 0xFF);
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
for (r = 0; r < SecondSpaceLen; r++) // Второй пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
for (r = 0; r < SynchroSpaceLen; r++) // Синхропромежуток
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x00;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
|
||
|
||
// DATA AM
|
||
ptrcrc = tptr;
|
||
for (r = 0; r < SynchroPulseLen; r++) // Синхроимпульс
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0xA1;
|
||
FTracksPtr[trk][side][1][tptr++] = 0xFF;
|
||
}
|
||
|
||
FTracksPtr[trk][side][0][tptr] = 0xFB; // Метка "Данные"
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
|
||
SL = unsigned(trackinfo->sect[sec].size);
|
||
if (!SL) SL = 128;
|
||
else SL = 128 << SL;
|
||
|
||
unsigned int secDATAOFF = trackinfo->sect[sec].SectPos;
|
||
|
||
for (r = 0; r < SL; r++) // сектор SL байт
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = ptr[secDATAOFF + r];
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
|
||
vgcrc = MakeVGCRC(FTracksPtr[trk][side][0] + ptrcrc, tptr - ptrcrc);
|
||
|
||
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc >> 8); // VG93 CRC
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc & 0xFF);
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
|
||
for (r = 0; r < ThirdSpaceLen; r++) // Третий пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
}
|
||
for (int eoftrk = tptr; eoftrk < 6250; eoftrk++)
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
}
|
||
|
||
delete[] ptr;
|
||
ReadOnly = readonly;
|
||
FType = DIT_FDD;
|
||
DiskPresent = true;
|
||
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::readSCL(int hfile, bool readonly)
|
||
{
|
||
long fsize = filelength(hfile);
|
||
if (fsize < 0)
|
||
{
|
||
ShowError(ERR_GETLEN);
|
||
return;
|
||
}
|
||
unsigned char *ptr = (unsigned char*)new char[fsize + 1024 * 2048];
|
||
if (!ptr)
|
||
{
|
||
ShowError(ERR_NOMEM);
|
||
return;
|
||
}
|
||
unsigned long rsize = read(hfile, ptr, fsize);
|
||
|
||
if (!rsize)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
if (rsize < 9 + 4) // header
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
if (memcmp(ptr, "SINCLAIR", 8) != 0)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_FORMAT" SCL!");
|
||
return;
|
||
}
|
||
|
||
unsigned int FileCount = ptr[8];
|
||
if (rsize < 9 + 4 + FileCount * 14)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
TRDOS_DIR_ELEMENT *fileinfo[256];
|
||
|
||
unsigned short FilesTotalSecs = 0;
|
||
|
||
// checking for corrupt + SCL-CRC + FileDIRS parse
|
||
unsigned long SCLCRC = 0;
|
||
unsigned sclOFF = 0;
|
||
unsigned int i, j;
|
||
for (i = 0; i < 9; i++) SCLCRC += unsigned(ptr[sclOFF++]);
|
||
|
||
for (i = 0; i < FileCount; i++)
|
||
{
|
||
fileinfo[i] = (TRDOS_DIR_ELEMENT*)(ptr + sclOFF);
|
||
for (j = 0; j < 14; j++) SCLCRC += unsigned(ptr[sclOFF++]);
|
||
}
|
||
for (i = 0; i < FileCount; i++)
|
||
{
|
||
unsigned SL = unsigned(fileinfo[i]->SecLen) * 256;
|
||
FilesTotalSecs += fileinfo[i]->SecLen;
|
||
if (rsize < sclOFF + 4 + SL)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
for (j = 0; j < SL; j++) SCLCRC += unsigned(ptr[sclOFF++]);
|
||
}
|
||
|
||
if (*((unsigned long*)(ptr + sclOFF)) != SCLCRC)
|
||
ShowError(ERR_FILECRC" SCL!");
|
||
|
||
|
||
if (FilesTotalSecs < 2544) FilesTotalSecs = 2544;
|
||
else
|
||
{
|
||
int cyls = ((16 + FilesTotalSecs) / (16 * 2)) + (((16 + FilesTotalSecs) % (16 * 2)) ? 1 : 0);
|
||
FilesTotalSecs = (cyls * 16 * 2) - 16;
|
||
}
|
||
|
||
formatTRDOS((FilesTotalSecs + 16) / (16 * 2), 2);
|
||
ReadOnly = true;
|
||
FType = DIT_SCL;
|
||
DiskPresent = true;
|
||
|
||
sclOFF = 9 + 14 * FileCount;
|
||
|
||
bool BOOTADD = true;
|
||
unsigned char _FileCount = 0;
|
||
unsigned char _DelFileCount = 0;
|
||
|
||
for (i = 0; i < FileCount; i++)
|
||
{
|
||
if (fileinfo[i]->FileName[0] == 0x01) _DelFileCount++;
|
||
_FileCount++;
|
||
|
||
if (!strncasecmp(fileinfo[i]->FileName, "BOOT B", 9))
|
||
{
|
||
BOOTADD = false;
|
||
}
|
||
}
|
||
|
||
unsigned char SEC = 0, TRK = 1;
|
||
unsigned short FreeSEC = 2544;
|
||
unsigned int cnt = 0;
|
||
unsigned int dirsec;
|
||
|
||
TRDOS_DIR_ELEMENT trdosde;
|
||
VGFIND_SECTOR vgfs;
|
||
|
||
if (BOOTADD && (unsigned(_FileCount) + unsigned(_DelFileCount) < 127))
|
||
{
|
||
dirsec = ((cnt * 16) / 256) + 1;
|
||
|
||
memcpy(&trdosde, &sbootdir, sizeof(sbootdir));
|
||
|
||
trdosde.FirstSec = SEC;
|
||
trdosde.FirstTrk = TRK;
|
||
|
||
if (FindSector(0, 0, dirsec, &vgfs)) // DIR ELEMENT write
|
||
{
|
||
memcpy(vgfs.SectorPointer + ((cnt * 16) % 256), &trdosde, sizeof(trdosde));
|
||
ApplySectorCRC(vgfs);
|
||
}
|
||
_FileCount++;
|
||
cnt++;
|
||
int _bOFF = 0;
|
||
|
||
for (j = 0; j < unsigned(trdosde.SecLen); j++)
|
||
{
|
||
if (FindSector(TRK / 2, TRK % 2, SEC + 1, &vgfs)) // SECTOR write
|
||
{
|
||
memcpy(vgfs.SectorPointer, sbootimage + _bOFF, 256);
|
||
ApplySectorCRC(vgfs);
|
||
}
|
||
_bOFF += 256;
|
||
SEC++;
|
||
FreeSEC--;
|
||
if (SEC > 15) { SEC = 0; TRK++; }
|
||
}
|
||
}
|
||
|
||
for (i = 0; i < FileCount; i++)
|
||
{
|
||
if (TRK >= (MaxTrack + 1)*(MaxSide + 1)) break; // disk full ?
|
||
|
||
memcpy(&trdosde, fileinfo[i], 14);
|
||
|
||
trdosde.FirstSec = SEC;
|
||
trdosde.FirstTrk = TRK;
|
||
|
||
unsigned int dirsec = ((cnt * 16) / 256) + 1;
|
||
if (FindSector(0, 0, dirsec, &vgfs)) // DIR ELEMENT write
|
||
{
|
||
memcpy(vgfs.SectorPointer + ((cnt * 16) % 256), &trdosde, 16);
|
||
ApplySectorCRC(vgfs);
|
||
}
|
||
|
||
cnt++;
|
||
|
||
for (j = 0; j < unsigned(trdosde.SecLen); j++)
|
||
{
|
||
if (FindSector(TRK / 2, TRK % 2, SEC + 1, &vgfs)) // SECTOR write
|
||
{
|
||
memcpy(vgfs.SectorPointer, ptr + sclOFF, 256);
|
||
ApplySectorCRC(vgfs);
|
||
}
|
||
sclOFF += 256;
|
||
SEC++;
|
||
FreeSEC--;
|
||
if (SEC > 15) { SEC = 0; TRK++; }
|
||
|
||
if (TRK >= (MaxTrack + 1)*(MaxSide + 1)) break; // disk full ?
|
||
}
|
||
}
|
||
|
||
if (FindSector(0, 0, 9, &vgfs)) // update disk info
|
||
{
|
||
vgfs.SectorPointer[0xE1] = SEC;
|
||
vgfs.SectorPointer[0xE2] = TRK;
|
||
vgfs.SectorPointer[0xE4] = _FileCount;
|
||
vgfs.SectorPointer[0xF4] = _DelFileCount;
|
||
*((unsigned short*)(vgfs.SectorPointer + 0xE5)) = FreeSEC;
|
||
ApplySectorCRC(vgfs);
|
||
}
|
||
|
||
delete[] ptr;
|
||
ReadOnly = readonly;
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::readHOB(int hfile)
|
||
{
|
||
long fsize = filelength(hfile);
|
||
if (fsize < 0)
|
||
{
|
||
ShowError(ERR_GETLEN);
|
||
return;
|
||
}
|
||
unsigned char *ptr = (unsigned char*)new char[fsize + 1024 * 2048];
|
||
if (!ptr)
|
||
{
|
||
ShowError(ERR_NOMEM);
|
||
return;
|
||
}
|
||
unsigned long rsize = read(hfile, ptr, fsize);
|
||
|
||
if (!rsize)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
if (rsize < 17) // header
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
TRDOS_DIR_ELEMENT dired;
|
||
memcpy(&dired, ptr, 14);
|
||
|
||
unsigned short hobRealCRC = *((unsigned short*)(ptr + 0x0F));
|
||
unsigned int DataLength = *((unsigned short*)(ptr + 0x0D));
|
||
|
||
if (rsize < 17 + (DataLength & 0xFF00))
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
unsigned int i;
|
||
unsigned short CRC = 0;
|
||
for (i = 0; i < 15; i++) CRC = CRC + ptr[i];
|
||
CRC *= 257;
|
||
CRC += 105; // сумма чисел от 0 до 14
|
||
|
||
if (CRC != hobRealCRC)
|
||
ShowError(ERR_FILECRC" HOBETA!");
|
||
|
||
|
||
|
||
|
||
ReadOnly = true;
|
||
if (!DiskPresent)
|
||
{
|
||
formatTRDOS(80, 2);
|
||
FType = DIT_HOB;
|
||
DiskPresent = true;
|
||
}
|
||
|
||
// --- read file...
|
||
dired.SecLen = ptr[0x0E]; // число секторов файла
|
||
|
||
VGFIND_SECTOR vgfs9;
|
||
if (!FindSector(0, 0, 9, &vgfs9)) { delete[] ptr; return; }
|
||
|
||
dired.FirstSec = vgfs9.SectorPointer[0xE1];
|
||
dired.FirstTrk = vgfs9.SectorPointer[0xE2];
|
||
|
||
VGFIND_SECTOR vgfs;
|
||
|
||
unsigned char SEC = dired.FirstSec, TRK = dired.FirstTrk;
|
||
unsigned short FreeSEC = *((unsigned short*)(vgfs9.SectorPointer + 0xE5));
|
||
unsigned char FileCount = vgfs9.SectorPointer[0xE4];
|
||
unsigned char DelFileCount = vgfs9.SectorPointer[0xF4];
|
||
|
||
if (TRK >= 160) // disk full ?
|
||
{
|
||
delete[] ptr;
|
||
return;
|
||
}
|
||
|
||
for (unsigned int j = 0; j < unsigned(dired.SecLen); j++)
|
||
{
|
||
if (FindSector(TRK / 2, TRK % 2, SEC + 1, &vgfs))
|
||
{
|
||
memcpy(vgfs.SectorPointer, ptr + 17 + j * 256, 256);
|
||
ApplySectorCRC(vgfs);
|
||
}
|
||
SEC++;
|
||
FreeSEC--;
|
||
if (SEC > 15) { SEC = 0; TRK++; }
|
||
|
||
if (TRK >= 160) break; // disk full?
|
||
}
|
||
|
||
if (FindSector(0, 0, ((FileCount * 16) / 256) + 1, &vgfs))
|
||
{
|
||
memcpy(vgfs.SectorPointer + ((FileCount * 16) % 256), &dired, 16);
|
||
ApplySectorCRC(vgfs);
|
||
}
|
||
|
||
if (dired.FileName[0] == 0x01) DelFileCount++;
|
||
FileCount++;
|
||
|
||
vgfs9.SectorPointer[0xE1] = SEC;
|
||
vgfs9.SectorPointer[0xE2] = TRK;
|
||
*((unsigned short*)(vgfs9.SectorPointer + 0xE5)) = FreeSEC;
|
||
vgfs9.SectorPointer[0xE4] = FileCount;
|
||
vgfs9.SectorPointer[0xF4] = DelFileCount;
|
||
ApplySectorCRC(vgfs9);
|
||
}
|
||
//-----------------------------------------------------------------------------
|
||
bool unpack_td0(unsigned char *data, long &size);
|
||
unsigned short TD0CRC(unsigned char *buf, unsigned int len);
|
||
|
||
#define WORD2(a,b) ((a)+(b)*0x100)
|
||
|
||
void TDiskImage::readTD0(int hfile, bool readonly)
|
||
{
|
||
long fsize = filelength(hfile);
|
||
if (fsize < 0)
|
||
{
|
||
ShowError(ERR_GETLEN);
|
||
return;
|
||
}
|
||
unsigned char *ptr = (unsigned char*)new char[fsize + 256 * 20000];
|
||
if (!ptr)
|
||
{
|
||
ShowError(ERR_NOMEM);
|
||
return;
|
||
}
|
||
long rsize = read(hfile, ptr, fsize);
|
||
|
||
TD0_MAIN_HEADER *td0hdr = (TD0_MAIN_HEADER*)ptr;
|
||
TD0_INFO_DATA *td0inf = (TD0_INFO_DATA*)(ptr + 12);
|
||
|
||
if (!rsize)
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
if (rsize < 12) // header
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_CORRUPT);
|
||
return;
|
||
}
|
||
|
||
if ((*(short*)ptr != WORD2('T', 'D')) && (*(short*)ptr != WORD2('t', 'd')))// non TD0
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_FORMAT" TD0!");
|
||
return;
|
||
}
|
||
if (TD0CRC(ptr, 10) != td0hdr->CRC) // CRC bad...
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_FILECRC" TD0!");
|
||
return;
|
||
}
|
||
if ((td0hdr->Ver > 21) || (td0hdr->Ver < 10)) // 1.0 <= version <= 2.1...
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_FILEVER" TD0!");
|
||
return;
|
||
}
|
||
if (td0hdr->DataDOS != 0) // if DOS allocated sectors only...
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_TD0DOSALLOC);
|
||
return;
|
||
}
|
||
if (!unpack_td0(ptr, rsize))
|
||
{
|
||
delete[] ptr;
|
||
ShowError(ERR_FORMAT" TD0!");
|
||
return;
|
||
}
|
||
|
||
// loading unpacked TD0...
|
||
|
||
int tdOFF = 12;
|
||
if (ptr[7] & 0x80) tdOFF += sizeof(TD0_INFO_DATA) + td0inf->strLen;
|
||
|
||
TD0_TRACK_HEADER *tdtrk;
|
||
TD0_SECT_HEADER *tdsect;
|
||
|
||
MaxTrack = 0;
|
||
MaxSide = 0;
|
||
|
||
for (; tdOFF < rsize;)
|
||
{
|
||
tdtrk = (TD0_TRACK_HEADER*)(ptr + tdOFF);
|
||
tdOFF += sizeof(TD0_TRACK_HEADER);
|
||
|
||
if (tdOFF >= rsize) break;
|
||
if (tdtrk->SectorCount == 0xFF) break; // EOF marker
|
||
|
||
|
||
unsigned trk = tdtrk->Track;
|
||
unsigned side = tdtrk->Side;
|
||
FTrackLength[trk][side] = 6250;
|
||
|
||
// make unformatted track...
|
||
FTracksPtr[trk][side][0] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // trk img
|
||
FTracksPtr[trk][side][1] = (unsigned char*)new char[FTrackLength[trk][side] + 1024]; // clk img
|
||
for (unsigned ij = 0; ij < 6250; ij++)
|
||
{
|
||
FTracksPtr[trk][side][0][ij] = 0x00;
|
||
FTracksPtr[trk][side][1][ij] = 0x00;
|
||
}
|
||
|
||
|
||
unsigned SecCount = tdtrk->SectorCount;
|
||
|
||
unsigned int tmpOFF = tdOFF;
|
||
|
||
// Вычисляем необходимое число байт под данные:
|
||
unsigned int trkdatalen = 0;
|
||
unsigned int SL;
|
||
for (unsigned int ilsec = 0; ilsec < SecCount; ilsec++)
|
||
{
|
||
tdsect = (TD0_SECT_HEADER*)(ptr + tmpOFF);
|
||
tmpOFF += sizeof(TD0_SECT_HEADER) + tdsect->DataLength;
|
||
|
||
trkdatalen += 2 + 6; // for marks: 0xA1, 0xFE, 6bytes
|
||
trkdatalen += 4; // for data header/crc: 0xA1, 0xFB, ...,2bytes
|
||
// SL = unsigned(tdsect->ADRM[3]);
|
||
// if(!SL) SL = 128;
|
||
// else SL = 128 << SL;
|
||
SL = tdsect->DataLength - 1;
|
||
trkdatalen += SL;
|
||
}
|
||
|
||
// проверка на возможность формата...
|
||
if (trkdatalen + SecCount*(3 + 2) > 6250) // 3x4E & 2x00 per sec checking
|
||
{
|
||
delete[] ptr;
|
||
for (int t = 0; t < 256; t++)
|
||
for (int s = 0; s < 256; s++)
|
||
{
|
||
FTrackLength[t][s] = 0;
|
||
if (FTracksPtr[t][s][0]) delete FTracksPtr[t][s][0];
|
||
FTracksPtr[t][s][0] = NULL;
|
||
if (FTracksPtr[t][s][1]) delete FTracksPtr[t][s][1];
|
||
FTracksPtr[t][s][1] = NULL;
|
||
}
|
||
ShowError(ERR_IMPOSSIBLE);
|
||
return;
|
||
}
|
||
|
||
unsigned int FreeSpace = 6250 - (trkdatalen + SecCount*(3 + 2));
|
||
|
||
unsigned int SynchroPulseLen = 1; // 1 уже учтен в trkdatalen...
|
||
unsigned int FirstSpaceLen = 1;
|
||
unsigned int SecondSpaceLen = 1;
|
||
unsigned int ThirdSpaceLen = 1;
|
||
unsigned int SynchroSpaceLen = 1;
|
||
FreeSpace -= FirstSpaceLen + SecondSpaceLen + ThirdSpaceLen + SynchroSpaceLen;
|
||
|
||
// Распределяем длины пробелов и синхропромежутка:
|
||
while (FreeSpace > 0)
|
||
{
|
||
if (FreeSpace >= (SecCount * 2))
|
||
if (SynchroSpaceLen < 12) { SynchroSpaceLen++; FreeSpace -= SecCount * 2; } // Synchro for ADM & DATA
|
||
if (FreeSpace < SecCount) break;
|
||
|
||
if (FirstSpaceLen < 10) { FirstSpaceLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace < SecCount) break;
|
||
if (SecondSpaceLen < 22) { SecondSpaceLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace < SecCount) break;
|
||
if (ThirdSpaceLen < 60) { ThirdSpaceLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace < SecCount) break;
|
||
|
||
if ((SynchroSpaceLen >= 12) && (FirstSpaceLen >= 10) && (SecondSpaceLen >= 22) && (ThirdSpaceLen >= 60)) break;
|
||
};
|
||
// по возможности делаем три синхроимпульса...
|
||
if (FreeSpace >(SecCount * 2) + 10) { SynchroPulseLen++; FreeSpace -= SecCount; }
|
||
if (FreeSpace >(SecCount * 2) + 9) SynchroPulseLen++;
|
||
|
||
// Форматируем дорожку...
|
||
|
||
unsigned int tptr = 0;
|
||
unsigned int ptrcrc;
|
||
unsigned int r;
|
||
unsigned short vgcrc;
|
||
for (unsigned sec = 0; sec < SecCount; sec++)
|
||
{
|
||
tdsect = (TD0_SECT_HEADER*)(ptr + tdOFF);
|
||
tdOFF += sizeof(TD0_SECT_HEADER) + 1;
|
||
|
||
for (r = 0; r < FirstSpaceLen; r++) // Первый пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
for (r = 0; r < SynchroSpaceLen; r++) // Синхропромежуток
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x00;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
ptrcrc = tptr;
|
||
for (r = 0; r < SynchroPulseLen; r++) // Синхроимпульс
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0xA1;
|
||
FTracksPtr[trk][side][1][tptr++] = 0xFF;
|
||
}
|
||
FTracksPtr[trk][side][0][tptr] = 0xFE; // Метка "Адрес"
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
FTracksPtr[trk][side][0][tptr] = tdsect->ADRM[0]; // cyl
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = tdsect->ADRM[1]; // head
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = tdsect->ADRM[2]; // secN
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = tdsect->ADRM[3]; // len code
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
vgcrc = MakeVGCRC(FTracksPtr[trk][side][0] + ptrcrc, tptr - ptrcrc);
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc >> 8); // VG93 CRC
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc & 0xFF);
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
for (r = 0; r < SecondSpaceLen; r++) // Второй пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
for (r = 0; r < SynchroSpaceLen; r++) // Синхропромежуток
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x00;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
|
||
if (tdsect->DataLength - 1) // oh-oh, data area not present... ;-)
|
||
{
|
||
ptrcrc = tptr;
|
||
for (r = 0; r < SynchroPulseLen; r++) // Синхроимпульс
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0xA1;
|
||
FTracksPtr[trk][side][1][tptr++] = 0xFF;
|
||
}
|
||
|
||
FTracksPtr[trk][side][0][tptr] = 0xFB; // Метка "Данные"
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
|
||
// SL = unsigned(tdsect->ADRM[3]);
|
||
// if(!SL) SL = 128;
|
||
// else SL = 128 << SL;
|
||
SL = tdsect->DataLength - 1;
|
||
|
||
for (r = 0; r < SL; r++) // сектор SL байт
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = ptr[tdOFF + r];
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
tdOFF += SL;
|
||
|
||
vgcrc = MakeVGCRC(FTracksPtr[trk][side][0] + ptrcrc, tptr - ptrcrc);
|
||
|
||
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc >> 8); // VG93 CRC
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
FTracksPtr[trk][side][0][tptr] = (unsigned char)(vgcrc & 0xFF);
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
|
||
for (r = 0; r < ThirdSpaceLen; r++) // Третий пробел
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
}
|
||
for (int eoftrk = tptr; eoftrk < 6250; eoftrk++)
|
||
{
|
||
FTracksPtr[trk][side][0][tptr] = 0x4E;
|
||
FTracksPtr[trk][side][1][tptr++] = 0x00;
|
||
}
|
||
|
||
if (unsigned(MaxTrack) < trk) MaxTrack = trk;
|
||
if (unsigned(MaxSide) < side) MaxSide = side;
|
||
}
|
||
|
||
delete[] ptr;
|
||
ReadOnly = readonly;
|
||
FType = DIT_TD0;
|
||
DiskPresent = true;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
void TDiskImage::ShowError(const char *str)
|
||
{
|
||
printf("DiskImage Error: %s\n", str);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// convert packed td0 to unpacked
|
||
unsigned short TD0CRC(unsigned char *buf, unsigned int len);
|
||
unsigned unpack_lzh(unsigned char *src, unsigned size, unsigned char *buf);
|
||
unsigned char *td0_dst, *td0_src;
|
||
|
||
void td0_move(unsigned size)
|
||
{
|
||
memcpy(td0_dst, td0_src, size);
|
||
td0_dst += size;
|
||
td0_src += size;
|
||
}
|
||
|
||
//----------------------------------------------------------------------------
|
||
bool unpack_td0(unsigned char *data, long &size)
|
||
{
|
||
if (size < 12) return false;
|
||
if ((*(short*)data != WORD2('T', 'D')) && (*(short*)data != WORD2('t', 'd')))
|
||
return false; // non TD0
|
||
if (TD0CRC(data, 10) != *((unsigned short*)(data + 0x0A)))
|
||
return false; // CRC bad...
|
||
if (data[4] > 21)
|
||
return false; // version > 2.1...
|
||
|
||
unsigned char *snbuf = (unsigned char*)new char[size * 2 + 1500000]; // if compressed then UUUUFF ;-/
|
||
if (!snbuf) return false;
|
||
|
||
memcpy(snbuf, data, size);
|
||
if (*(short*)snbuf == WORD2('t', 'd')) // packed disk
|
||
{
|
||
if (snbuf[4] < 20) // unsupported Old Advanced compression
|
||
{
|
||
delete[] snbuf;
|
||
return false;
|
||
}
|
||
unpack_lzh((unsigned char*)data + 12, size - 12, (unsigned char*)snbuf + 12), *(short*)snbuf = WORD2('T', 'D');
|
||
}
|
||
|
||
td0_src = snbuf, td0_dst = data;
|
||
td0_move(12);
|
||
|
||
if (snbuf[7] & 0x80) // additional info...
|
||
{
|
||
unsigned short *cs = (unsigned short*)(snbuf + 12 + 2);
|
||
|
||
if (TD0CRC(snbuf + 12 + 2, 8 + *cs) != cs[-1])
|
||
{
|
||
delete[] snbuf;
|
||
return false;
|
||
}
|
||
td0_move(10);
|
||
td0_move(*((unsigned short*)(snbuf + 12 + 2)));
|
||
}
|
||
|
||
for (;;)
|
||
{
|
||
unsigned char s = *td0_src;
|
||
td0_move(4);
|
||
if (s == 0xFF) break;
|
||
for (; s; s--)
|
||
{
|
||
// unsigned char *sec = td0_src;
|
||
unsigned size = 128; if (td0_src[3]) size <<= td0_src[3];
|
||
td0_move(6);
|
||
*(unsigned short*)td0_dst = size + 1; td0_dst += 2;
|
||
*td0_dst++ = 0;
|
||
unsigned char *dst = td0_dst;
|
||
unsigned src_size = *(unsigned short*)td0_src; td0_src += 2;
|
||
unsigned char *end_packed_data = td0_src + src_size;
|
||
memset(td0_dst, 0, size);
|
||
switch (*td0_src++)
|
||
{
|
||
case 0:
|
||
memcpy(dst, td0_src, src_size - 1); break;
|
||
case 1:
|
||
{
|
||
unsigned n = *(unsigned short*)td0_src;
|
||
td0_src += 2;
|
||
unsigned short data = *(unsigned short*)td0_src;
|
||
for (; n; n--) *(unsigned short*)dst = data, dst += 2;
|
||
break;
|
||
}
|
||
case 2:
|
||
{
|
||
unsigned short data;
|
||
unsigned char s;
|
||
do
|
||
{
|
||
switch (*td0_src++)
|
||
{
|
||
case 0:
|
||
for (s = *td0_src++; s; s--) *dst++ = *td0_src++;
|
||
break;
|
||
case 1:
|
||
s = *td0_src++;
|
||
data = *(unsigned short*)td0_src;
|
||
td0_src += 2;
|
||
for (; s; s--) *(unsigned short*)dst = data, dst += 2;
|
||
break;
|
||
default: shit:
|
||
delete[] snbuf;
|
||
return false; // "bad TD0 file"
|
||
}
|
||
} while (td0_src < end_packed_data);
|
||
break;
|
||
}
|
||
default: goto shit;
|
||
}
|
||
td0_dst += size;
|
||
td0_src = end_packed_data;
|
||
}
|
||
}
|
||
size = unsigned(td0_dst) - unsigned(data);
|
||
delete[] snbuf;
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------
|
||
//
|
||
// TD0 CRC - table&proc grabed from TDCHECK.EXE by Alex Makeev
|
||
//
|
||
unsigned char tbltd0crc[512] = {
|
||
0x00,0x00,0xA0,0x97,0xE1,0xB9,0x41,0x2E,0x63,0xE5,0xC3,0x72,0x82,0x5C,0x22,0xCB,
|
||
0xC7,0xCA,0x67,0x5D,0x26,0x73,0x86,0xE4,0xA4,0x2F,0x04,0xB8,0x45,0x96,0xE5,0x01,
|
||
0x2F,0x03,0x8F,0x94,0xCE,0xBA,0x6E,0x2D,0x4C,0xE6,0xEC,0x71,0xAD,0x5F,0x0D,0xC8,
|
||
0xE8,0xC9,0x48,0x5E,0x09,0x70,0xA9,0xE7,0x8B,0x2C,0x2B,0xBB,0x6A,0x95,0xCA,0x02,
|
||
0x5E,0x06,0xFE,0x91,0xBF,0xBF,0x1F,0x28,0x3D,0xE3,0x9D,0x74,0xDC,0x5A,0x7C,0xCD,
|
||
0x99,0xCC,0x39,0x5B,0x78,0x75,0xD8,0xE2,0xFA,0x29,0x5A,0xBE,0x1B,0x90,0xBB,0x07,
|
||
0x71,0x05,0xD1,0x92,0x90,0xBC,0x30,0x2B,0x12,0xE0,0xB2,0x77,0xF3,0x59,0x53,0xCE,
|
||
0xB6,0xCF,0x16,0x58,0x57,0x76,0xF7,0xE1,0xD5,0x2A,0x75,0xBD,0x34,0x93,0x94,0x04,
|
||
0xBC,0x0C,0x1C,0x9B,0x5D,0xB5,0xFD,0x22,0xDF,0xE9,0x7F,0x7E,0x3E,0x50,0x9E,0xC7,
|
||
0x7B,0xC6,0xDB,0x51,0x9A,0x7F,0x3A,0xE8,0x18,0x23,0xB8,0xB4,0xF9,0x9A,0x59,0x0D,
|
||
0x93,0x0F,0x33,0x98,0x72,0xB6,0xD2,0x21,0xF0,0xEA,0x50,0x7D,0x11,0x53,0xB1,0xC4,
|
||
0x54,0xC5,0xF4,0x52,0xB5,0x7C,0x15,0xEB,0x37,0x20,0x97,0xB7,0xD6,0x99,0x76,0x0E,
|
||
0xE2,0x0A,0x42,0x9D,0x03,0xB3,0xA3,0x24,0x81,0xEF,0x21,0x78,0x60,0x56,0xC0,0xC1,
|
||
0x25,0xC0,0x85,0x57,0xC4,0x79,0x64,0xEE,0x46,0x25,0xE6,0xB2,0xA7,0x9C,0x07,0x0B,
|
||
0xCD,0x09,0x6D,0x9E,0x2C,0xB0,0x8C,0x27,0xAE,0xEC,0x0E,0x7B,0x4F,0x55,0xEF,0xC2,
|
||
0x0A,0xC3,0xAA,0x54,0xEB,0x7A,0x4B,0xED,0x69,0x26,0xC9,0xB1,0x88,0x9F,0x28,0x08,
|
||
0xD8,0x8F,0x78,0x18,0x39,0x36,0x99,0xA1,0xBB,0x6A,0x1B,0xFD,0x5A,0xD3,0xFA,0x44,
|
||
0x1F,0x45,0xBF,0xD2,0xFE,0xFC,0x5E,0x6B,0x7C,0xA0,0xDC,0x37,0x9D,0x19,0x3D,0x8E,
|
||
0xF7,0x8C,0x57,0x1B,0x16,0x35,0xB6,0xA2,0x94,0x69,0x34,0xFE,0x75,0xD0,0xD5,0x47,
|
||
0x30,0x46,0x90,0xD1,0xD1,0xFF,0x71,0x68,0x53,0xA3,0xF3,0x34,0xB2,0x1A,0x12,0x8D,
|
||
0x86,0x89,0x26,0x1E,0x67,0x30,0xC7,0xA7,0xE5,0x6C,0x45,0xFB,0x04,0xD5,0xA4,0x42,
|
||
0x41,0x43,0xE1,0xD4,0xA0,0xFA,0x00,0x6D,0x22,0xA6,0x82,0x31,0xC3,0x1F,0x63,0x88,
|
||
0xA9,0x8A,0x09,0x1D,0x48,0x33,0xE8,0xA4,0xCA,0x6F,0x6A,0xF8,0x2B,0xD6,0x8B,0x41,
|
||
0x6E,0x40,0xCE,0xD7,0x8F,0xF9,0x2F,0x6E,0x0D,0xA5,0xAD,0x32,0xEC,0x1C,0x4C,0x8B,
|
||
0x64,0x83,0xC4,0x14,0x85,0x3A,0x25,0xAD,0x07,0x66,0xA7,0xF1,0xE6,0xDF,0x46,0x48,
|
||
0xA3,0x49,0x03,0xDE,0x42,0xF0,0xE2,0x67,0xC0,0xAC,0x60,0x3B,0x21,0x15,0x81,0x82,
|
||
0x4B,0x80,0xEB,0x17,0xAA,0x39,0x0A,0xAE,0x28,0x65,0x88,0xF2,0xC9,0xDC,0x69,0x4B,
|
||
0x8C,0x4A,0x2C,0xDD,0x6D,0xF3,0xCD,0x64,0xEF,0xAF,0x4F,0x38,0x0E,0x16,0xAE,0x81,
|
||
0x3A,0x85,0x9A,0x12,0xDB,0x3C,0x7B,0xAB,0x59,0x60,0xF9,0xF7,0xB8,0xD9,0x18,0x4E,
|
||
0xFD,0x4F,0x5D,0xD8,0x1C,0xF6,0xBC,0x61,0x9E,0xAA,0x3E,0x3D,0x7F,0x13,0xDF,0x84,
|
||
0x15,0x86,0xB5,0x11,0xF4,0x3F,0x54,0xA8,0x76,0x63,0xD6,0xF4,0x97,0xDA,0x37,0x4D,
|
||
0xD2,0x4C,0x72,0xDB,0x33,0xF5,0x93,0x62,0xB1,0xA9,0x11,0x3E,0x50,0x10,0xF0,0x87,
|
||
};
|
||
unsigned short TD0CRC(unsigned char *buf, unsigned int len)
|
||
{
|
||
unsigned short CRC = 0;
|
||
int j;
|
||
for (unsigned int i = 0; i < len; i++)
|
||
{
|
||
CRC ^= *buf++;
|
||
j = CRC & 0xFF;
|
||
CRC &= 0xFF00;
|
||
CRC = (CRC << 8) | (CRC >> 8);
|
||
CRC ^= ((unsigned short*)tbltd0crc)[j];
|
||
}
|
||
return (CRC << 8) | (CRC >> 8);
|
||
}
|
||
// ----------------------------------------------------------------------------
|
||
|
||
unsigned char *packed_ptr, *packed_end;
|
||
|
||
int readChar(void)
|
||
{
|
||
if (packed_ptr < packed_end) return *packed_ptr++;
|
||
else return -1;
|
||
}
|
||
|
||
// ------------------------------------------------------ LZH unpacker
|
||
|
||
unsigned char d_code[256] = {
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
|
||
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
|
||
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
|
||
0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
|
||
0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
|
||
0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
|
||
0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
|
||
0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
|
||
0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
|
||
0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
|
||
0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
|
||
0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
|
||
0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
|
||
0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
|
||
0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
|
||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||
};
|
||
|
||
unsigned char d_len[256] = {
|
||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||
};
|
||
|
||
|
||
const int N = 4096; // buffer size
|
||
const int F = 60; // lookahead buffer size
|
||
const int THRESHOLD = 2;
|
||
const int NIL = N; // leaf of tree
|
||
|
||
unsigned char text_buf[N + F - 1];
|
||
|
||
const int N_CHAR = (256 - THRESHOLD + F); // kinds of characters (character code = 0..N_CHAR-1)
|
||
const int T = (N_CHAR * 2 - 1); // size of table
|
||
const int R = (T - 1); // position of root
|
||
const int MAX_FREQ = 0x8000; // updates tree when the
|
||
// root frequency comes to this value.
|
||
|
||
unsigned short freq[T + 1]; // frequency table
|
||
|
||
short prnt[T + N_CHAR]; // pointers to parent nodes, except for the
|
||
// elements [T..T + N_CHAR - 1] which are used to get
|
||
// the positions of leaves corresponding to the codes.
|
||
short son[T]; // pointers to child nodes (son[], son[] + 1)
|
||
|
||
|
||
int r;
|
||
|
||
unsigned getbuf;
|
||
unsigned char getlen;
|
||
|
||
int GetBit(void) /* get one bit */
|
||
{
|
||
int i;
|
||
|
||
while (getlen <= 8)
|
||
{
|
||
if ((i = readChar()) == -1) i = 0;
|
||
getbuf |= i << (8 - getlen);
|
||
getlen += 8;
|
||
}
|
||
i = getbuf;
|
||
getbuf <<= 1;
|
||
getlen--;
|
||
return ((i >> 15) & 1);
|
||
}
|
||
|
||
int GetByte(void) /* get one byte */
|
||
{
|
||
unsigned i;
|
||
|
||
while (getlen <= 8)
|
||
{
|
||
if ((int)(i = readChar()) == -1) i = 0;
|
||
getbuf |= i << (8 - getlen);
|
||
getlen += 8;
|
||
}
|
||
i = getbuf;
|
||
getbuf <<= 8;
|
||
getlen -= 8;
|
||
return (i >> 8) & 0xFF;
|
||
}
|
||
|
||
void StartHuff(void)
|
||
{
|
||
int i, j;
|
||
|
||
getbuf = 0, getlen = 0;
|
||
for (i = 0; i < N_CHAR; i++) {
|
||
freq[i] = 1;
|
||
son[i] = i + T;
|
||
prnt[i + T] = i;
|
||
}
|
||
i = 0; j = N_CHAR;
|
||
while (j <= R) {
|
||
freq[j] = freq[i] + freq[i + 1];
|
||
son[j] = i;
|
||
prnt[i] = prnt[i + 1] = j;
|
||
i += 2; j++;
|
||
}
|
||
freq[T] = 0xffff;
|
||
prnt[R] = 0;
|
||
|
||
for (i = 0; i < N - F; i++) text_buf[i] = ' ';
|
||
r = N - F;
|
||
}
|
||
|
||
/* reconstruction of tree */
|
||
void reconst(void)
|
||
{
|
||
int i, j, k;
|
||
int f, l;
|
||
|
||
/* collect leaf nodes in the first half of the table */
|
||
/* and replace the freq by (freq + 1) / 2. */
|
||
j = 0;
|
||
for (i = 0; i < T; i++)
|
||
{
|
||
if (son[i] >= T)
|
||
{
|
||
freq[j] = (freq[i] + 1) / 2;
|
||
son[j] = son[i];
|
||
j++;
|
||
}
|
||
}
|
||
/* begin constructing tree by connecting sons */
|
||
for (i = 0, j = N_CHAR; j < T; i += 2, j++)
|
||
{
|
||
k = i + 1;
|
||
f = freq[j] = freq[i] + freq[k];
|
||
for (k = j - 1; f < freq[k]; k--);
|
||
k++;
|
||
l = (j - k) * sizeof(*freq);
|
||
memmove(&freq[k + 1], &freq[k], l);
|
||
freq[k] = f;
|
||
memmove(&son[k + 1], &son[k], l);
|
||
son[k] = i;
|
||
}
|
||
/* connect prnt */
|
||
for (i = 0; i < T; i++)
|
||
if ((k = son[i]) >= T) prnt[k] = i;
|
||
else prnt[k] = prnt[k + 1] = i;
|
||
}
|
||
|
||
|
||
/* increment frequency of given code by one, and update tree */
|
||
|
||
void update(int c)
|
||
{
|
||
int i, j, k, l;
|
||
|
||
if (freq[R] == MAX_FREQ) reconst();
|
||
|
||
c = prnt[c + T];
|
||
do {
|
||
k = ++freq[c];
|
||
|
||
/* if the order is disturbed, exchange nodes */
|
||
if (k > freq[l = c + 1])
|
||
{
|
||
while (k > freq[++l]);
|
||
l--;
|
||
freq[c] = freq[l];
|
||
freq[l] = k;
|
||
|
||
i = son[c];
|
||
prnt[i] = l;
|
||
if (i < T) prnt[i + 1] = l;
|
||
|
||
j = son[l];
|
||
son[l] = i;
|
||
|
||
prnt[j] = c;
|
||
if (j < T) prnt[j + 1] = c;
|
||
son[c] = j;
|
||
|
||
c = l;
|
||
}
|
||
} while ((c = prnt[c]) != 0); /* repeat up to root */
|
||
}
|
||
|
||
int DecodeChar(void)
|
||
{
|
||
int c;
|
||
|
||
c = son[R];
|
||
|
||
/* travel from root to leaf, */
|
||
/* choosing the smaller child node (son[]) if the read bit is 0, */
|
||
/* the bigger (son[]+1} if 1 */
|
||
while (c < T) c = son[c + GetBit()];
|
||
c -= T;
|
||
update(c);
|
||
return c;
|
||
}
|
||
|
||
int DecodePosition(void)
|
||
{
|
||
int i, j, c;
|
||
|
||
/* recover upper 6 bits from table */
|
||
i = GetByte();
|
||
c = (int)d_code[i] << 6;
|
||
j = d_len[i];
|
||
/* read lower 6 bits verbatim */
|
||
j -= 2;
|
||
while (j--) i = (i << 1) + GetBit();
|
||
return c | (i & 0x3f);
|
||
}
|
||
|
||
unsigned unpack_lzh(unsigned char *src, unsigned size, unsigned char *buf)
|
||
{
|
||
packed_ptr = src;
|
||
packed_end = src + size;
|
||
int i, j, k, c;
|
||
unsigned count = 0;
|
||
StartHuff();
|
||
|
||
// while (count < textsize) // textsize - sizeof unpacked data
|
||
while (packed_ptr < packed_end)
|
||
{
|
||
c = DecodeChar();
|
||
if (c < 256)
|
||
{
|
||
*buf++ = c;
|
||
text_buf[r++] = c;
|
||
r &= (N - 1);
|
||
count++;
|
||
}
|
||
else {
|
||
i = (r - DecodePosition() - 1) & (N - 1);
|
||
j = c - 255 + THRESHOLD;
|
||
for (k = 0; k < j; k++)
|
||
{
|
||
c = text_buf[(i + k) & (N - 1)];
|
||
*buf++ = c;
|
||
text_buf[r++] = c;
|
||
r &= (N - 1);
|
||
count++;
|
||
}
|
||
}
|
||
}
|
||
return count;
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
|
||
#define VOLUME_NUMBER 254
|
||
|
||
#define TRACKS 35
|
||
#define SECTORS 16
|
||
#define SECTOR_SIZE 256
|
||
#define DOS_TRACK_uint8_tS (SECTORS * SECTOR_SIZE)
|
||
|
||
#define RAW_TRACK_uint8_tS 0x1A00
|
||
|
||
static uint8_t *target; /* Where to write in the raw_track buffer */
|
||
|
||
#define write_byte(x) (*target++ = (x))
|
||
|
||
static uint8_t GCR_encoding_table[64] = {
|
||
0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6,
|
||
0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3,
|
||
0xB4, 0xB5, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC,
|
||
0xBD, 0xBE, 0xBF, 0xCB, 0xCD, 0xCE, 0xCF, 0xD3,
|
||
0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE,
|
||
0xDF, 0xE5, 0xE6, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC,
|
||
0xED, 0xEE, 0xEF, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6,
|
||
0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };
|
||
|
||
int Swap_Bit[4] = { 0, 2, 1, 3 }; /* swap lower 2 bits */
|
||
static uint8_t GCR_buffer[256];
|
||
static uint8_t GCR_buffer2[86];
|
||
|
||
/* physical sector no. to DOS 3.3 logical sector no. table */
|
||
static int Logical_Sector[16] = {
|
||
0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4,
|
||
0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF };
|
||
|
||
static int Logical_Sector_po[16] = {
|
||
0x0, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8,
|
||
0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0xF };
|
||
|
||
/*
|
||
* write an FM encoded value, used in writing address fields
|
||
*/
|
||
static void FM_encode(uint8_t data)
|
||
{
|
||
write_byte((data >> 1) | 0xAA);
|
||
write_byte(data | 0xAA);
|
||
}
|
||
|
||
/*
|
||
* Write 0xFF sync bytes
|
||
*/
|
||
static void write_sync(int length)
|
||
{
|
||
while (length--) write_byte(0xFF);
|
||
}
|
||
|
||
static void write_address_field(int volume, int track, int sector)
|
||
{
|
||
/*
|
||
* write address mark
|
||
*/
|
||
write_byte(0xD5);
|
||
write_byte(0xAA);
|
||
write_byte(0x96);
|
||
|
||
/*
|
||
* write Volume, Track, Sector & Check-sum
|
||
*/
|
||
FM_encode(volume);
|
||
FM_encode(track);
|
||
FM_encode(sector);
|
||
FM_encode(volume ^ track ^ sector);
|
||
|
||
/*
|
||
* write epilogue
|
||
*/
|
||
write_byte(0xDE);
|
||
write_byte(0xAA);
|
||
write_byte(0xEB);
|
||
}
|
||
|
||
/*
|
||
* 6-and-2 group encoding: the heart of the "nibblization" procedure
|
||
*/
|
||
static void encode62(uint8_t *page)
|
||
{
|
||
int i, j;
|
||
|
||
/* 86 * 3 = 258, so the first two byte are encoded twice */
|
||
GCR_buffer2[0] = Swap_Bit[page[1] & 0x03];
|
||
GCR_buffer2[1] = Swap_Bit[page[0] & 0x03];
|
||
|
||
/* save higher 6 bits in GCR_buffer and lower 2 bits in GCR_buffer2 */
|
||
for (i = 255, j = 2; i >= 0; i--, j = j == 85 ? 0 : j + 1) {
|
||
GCR_buffer2[j] = (GCR_buffer2[j] << 2) | Swap_Bit[page[i] & 0x03];
|
||
GCR_buffer[i] = page[i] >> 2;
|
||
}
|
||
|
||
/* clear off higher 2 bits of GCR_buffer2 set in the last call */
|
||
for (i = 0; i < 86; i++)
|
||
GCR_buffer2[i] &= 0x3f;
|
||
}
|
||
|
||
static void write_data_field(uint8_t *page)
|
||
{
|
||
int i;
|
||
uint8_t last, checksum;
|
||
|
||
encode62(page);
|
||
|
||
/* write prologue */
|
||
write_byte(0xD5);
|
||
write_byte(0xAA);
|
||
write_byte(0xAD);
|
||
|
||
/* write GCR encoded data */
|
||
for (i = 0x55, last = 0; i >= 0; --i) {
|
||
checksum = last ^ GCR_buffer2[i];
|
||
write_byte(GCR_encoding_table[checksum]);
|
||
last = GCR_buffer2[i];
|
||
}
|
||
for (i = 0; i < 256; ++i) {
|
||
checksum = last ^ GCR_buffer[i];
|
||
write_byte(GCR_encoding_table[checksum]);
|
||
last = GCR_buffer[i];
|
||
}
|
||
|
||
/* write checksum and epilogue */
|
||
write_byte(GCR_encoding_table[last]);
|
||
write_byte(0xDE);
|
||
write_byte(0xAA);
|
||
write_byte(0xEB);
|
||
}
|
||
|
||
int dsk2nib(const char *name, fileTYPE *f)
|
||
{
|
||
int len = strlen(name);
|
||
int po = 0;
|
||
|
||
if (len > 3 && !strcasecmp(name + len - 3, ".po"))
|
||
{
|
||
po = 1;
|
||
}
|
||
else if (!(len > 4 && !strcasecmp(name + len - 4, ".dsk")) && !(len > 3 && !strcasecmp(name + len - 3, ".do")))
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
static uint8_t dos_track[SECTORS * SECTOR_SIZE]; // , pro_track[SECTORS * SECTOR_SIZE];
|
||
static uint8_t raw_track[RAW_TRACK_uint8_tS];
|
||
|
||
fileTYPE disk_file = {};
|
||
|
||
if (!FileOpen(&disk_file, name))
|
||
{
|
||
printf("Unable to mount disk file \"%s\"\n", name);
|
||
return 0;
|
||
}
|
||
|
||
if (!FileOpenEx(f, "vdsk", -1))
|
||
{
|
||
FileClose(&disk_file);
|
||
printf("ERROR: fail to create vdsk\n");
|
||
return 0;
|
||
}
|
||
|
||
/* Read, convert, and write each track */
|
||
for (int track = 0; track < TRACKS; ++track)
|
||
{
|
||
if (FileReadAdv(&disk_file, dos_track, DOS_TRACK_uint8_tS) != DOS_TRACK_uint8_tS)
|
||
{
|
||
printf("Unexpected end of disk data\n");
|
||
FileClose(&disk_file);
|
||
FileClose(f);
|
||
return 0;
|
||
}
|
||
|
||
target = raw_track;
|
||
|
||
for (int sector = 0; sector < SECTORS; sector++)
|
||
{
|
||
int sec = po ? Logical_Sector_po[sector] : sector;
|
||
|
||
write_sync(38); /* Inter-sector gap */
|
||
write_address_field(VOLUME_NUMBER, track, sector);
|
||
write_sync(8);
|
||
write_data_field(dos_track + Logical_Sector[sec] * SECTOR_SIZE);
|
||
}
|
||
|
||
/* Pad rest of buffer with sync bytes */
|
||
while (target != &raw_track[RAW_TRACK_uint8_tS]) write_byte(0xff);
|
||
|
||
if (FileWriteAdv(f, raw_track, RAW_TRACK_uint8_tS) != RAW_TRACK_uint8_tS)
|
||
{
|
||
printf("Error writing to vdsk file\n");
|
||
FileClose(&disk_file);
|
||
FileClose(f);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
FileClose(&disk_file);
|
||
|
||
f->size = FileGetSize(f);
|
||
FileSeekLBA(f, 0);
|
||
printf("dsk2nib: vdsk size=%llu.\n", f->size);
|
||
|
||
return 1;
|
||
}
|
||
|
||
//--------------------------------------------------------------------------
|
||
int x2trd(const char *name, fileTYPE *f)
|
||
{
|
||
TDiskImage *img = new TDiskImage;
|
||
img->Open(getFullPath(name), true);
|
||
|
||
if (!FileOpenEx(f, "vdsk", -1))
|
||
{
|
||
delete img;
|
||
printf("ERROR: fail to create vdsk\n");
|
||
return 0;
|
||
}
|
||
|
||
img->writeTRD(f);
|
||
delete(img);
|
||
|
||
f->size = FileGetSize(f);
|
||
FileSeekLBA(f, 0);
|
||
printf("x2trd: vdsk size=%llu.\n", f->size);
|
||
|
||
return 1;
|
||
}
|
||
|
||
int x2trd_ext_supp(const char *name)
|
||
{
|
||
const char *ext = "";
|
||
if (strlen(name) > 4) ext = name + strlen(name) - 4;
|
||
return (!strcasecmp(ext, ".scl") || !strcasecmp(ext, ".fdi") || !strcasecmp(ext, ".udi"));
|
||
}
|