G1E/G2E eActivity-files consist of a
StandardHeader, a special header,
the setup-area, some
intermediate data, the
linedirectory and the lines.
The File
type identifier in the non-inverted
StandardHeader is 0x49.
The
setup-area:
When an EACT-file is stored, a part of the actual
calculator-setup is stored inside of the
EACT-file. Each bit of the setup-directory represents the corresponding
setup-entry. The size of the setup-directory
is 0x10 with G1E/G2E- and 0x2C with
G3E-files.
The setup-data-area contains the setup-value for each
setup-entry, which corresponding bit in the
setup-directory is set. If a bit in the setup-directory is not set,
the value of the corresponding setup-entry is assumed to be zero and does
not occur in the setup-data-area. Therefore the length of the
setup-data-area depends on the count of setup-entries,
which value is not zero.
After the line count, the
line directory starts. It
consists of an according number of line descriptors (EntryType, EntryOffset).
A line must be delimited by at least one binary zero and has to end 4-aligned.
Alignment fillbytes are generally at random.
G2E-files may contain ECON2-EntryTypes, which is not supported by G1E-eactivity.
The standard heading has the EntryType 0x07.
Pure text lines have the EntryType 0x81.
Text mixed with functions (sin, tan, log a.s.o.) contains zeros and has the
EntryType 0x82. The end of such lines cannot be detected by search-for-zero.
The offset of the next entry has to be used instead.
The 8 bytes at offset 0x28 are (as hex):
00 01 01 00 50 61 63 6B with
G1E-files;
00 01 02 00 02 02 02 01 with G2E-files; (the second int is the version of the
OS, which has written the file)
00 01 04 00 01 04 02 00 with G3E-files.
(the second int is the version of the OS, which has written the file)
Possibly this is some EACT-version information.
EACT:
Offset (b) | Size (b) | Description |
0x20 | 4 | filesize |
0x24 | 4 | LS, length of the setup-area (starting at 0x30; 4-aligned) |
0x28 | 4 | some EACT-version information (see above) |
0x2C | 4 | with G2E/G3E the OS version, when writing the file ( (see above; only informational) |
0x30 | 4 | { 0, 0, 0, 0 } |
0x34 | 0x10 (LSDIR) | setup-directory (0x2C for G3E-files) |
0x34+LSDIR | LS-0x30 | setup-data; 4-aligned (filler bytes are usually zero) |
0x20+LS | 0x10 | zeros |
0x30+LS | 8 | "@EACT" 0x00 0x00 0x00 |
0x38+LS | 4 | { 0, 0, 0, 1 } |
0x3C+LS | 4 | length1 (filesize - 0x40 - LS) |
0x40+LS | 8 | "EACT1" 0 0 0 |
0x48+LS | 4 | { 0, 0, 0, 0x14 } |
0x4C+LS | 4 | length2 (filesize - 0x54 - LS) |
0x50+LS | 4 | { 0xD4, 0, 0, 0x66 } |
0x54+LS | 4 | LC; Line count |
0x58+LS | 4*LC | LineDirectory (array of TLineDescriptor; see below) |
0x58+LS+4*LC | 4 | { 0, 0, 0, 0 } (equal to length2 for G3E-files) |
0x5C+LS+4*LC | ... | Line array; each line is zero-terminated and 4-aligned by random filler bytes |
struct LineDirectory
{
unsigned
int LineCount;
TLineDescriptor LineDescriptor[LineCount];
};
typedef
struct LineDescriptor {
char
EntryType;
char
EntryOffset[3];
/* offset relative to
0x54+LS,
big endian */
} TLineDescriptor;
EACT/Text-conversion:
The setup-area should be based on a template, which has been derived from some
valid G1E/G2E/G3E-file. Only such setup-enties should be changed, which are
well known.
Build a G1E/G2E/G3E-file from pure text:
First calculate the filesize. Add the sizes of the constant parts:
TStandardHeader, TEACTcommonHeader, TEACTsubHeader. The size of the setup-area
depends on the EACT-filetype and on the amount of setup-entries, which values
should be non-zero. The setup-data must end 4-aligned. Fill up with zeros in
case of need. The setup-area has four zero bytes at the beginning and 16 zero
bytes at the end. These must be included into the count LS
stored at offset 0x24. The length of the LineDirectory is LC*4.
The LineDirectory is terminated by four bytes (see offset
0x58+LS+4*LC).
Finally each line needs at least space for the line itself and one
terminatiing zero. Each line must end 4-aligned, hence add zero bytes in case
of need.
After the filesize is properly calculated, the
StandardHeader can be set up. Hint: fx-CG OS 1.04 does not care for the
bytes at offset 0x1C/0x1D of G3E-files.
Then EACTcommonHeader can be
written. The size of the setup-area has to be known.
The setup-area has to be
constructed as described or some convenient constant pattern could be used.
The most important data of the following intermediate block
EACTsubHeader is the line count.
The first entry in the
LineDirectory must be
the heading (EntryType 0x07), though it is not used, when the file is read in
by EACT. The heading is always derived from the filename.
The following code fragment contains a function EACT2TXT to demonstrate the conversion of an EACT-file to some text. The function TXT2EACT converts some textlines to an EACT-file. The snippet is a fragment. It cannot be compiled as it is.
#define G1E 0x00010100 #define G2E 0x00010200 #define G3E 0x00010400
#define OMIT_ZERO_SETUP_VALUES #define MAX_SETUP_DIR_SIZE 0x2C #define WRITE_THE_LINES
#define SETUP_ANGLE 0x13 #define SETUP_ANGLE_DEG 0x00 #define SETUP_ANGLE_RAD 0x01 #define SETUP_ANGLE_GRA 0x02
#define SETUP_SHIFT_ALPHA 0x14 #define SETUP_SHIFT_ALPHA_OFF 0x00 #define SETUP_SHIFT_ALPHA_SHIFT 0x01 #define SETUP_SHIFT_ALPHA_ALPHA 0x04 #define SETUP_SHIFT_ALPHA_SHIFT_ALPHA 0x84
#define SETUP_INS_OVWR 0x15 #define SETUP_INS_OVWR_OVWR 0x01 #define SETUP_INS_OVWR_INS 0x02
#define SETUP_MODE 0x17 #define SETUP_MODE_COMP 0x00 #define SETUP_MODE_BIN 0x01 #define SETUP_MODE_OCT 0x07 #define SETUP_MODE_DEC 0x09 #define SETUP_MODE_HEX 0x0F
#define SETUP_FUNCTYPE 0x18 #define SETUP_FUNCTYPE_YEQ 0x00 #define SETUP_FUNCTYPE_REQ 0x01 #define SETUP_FUNCTYPE_PARAM 0x02 #define SETUP_FUNCTYPE_XC 0x03 #define SETUP_FUNCTYPE_YGT 0x04 #define SETUP_FUNCTYPE_YLT 0x05 #define SETUP_FUNCTYPE_YGE 0x06 #define SETUP_FUNCTYPE_YLE 0x07
#define SETUP_DRAWTYPE 0x19 #define SETUP_DRAWTYPE_CON 0x00 #define SETUP_DRAWTYPE_PLOT 0x01
#define SETUP_DERIVATIVE 0x1A #define SETUP_DERIVATIVE_ON 0x00 #define SETUP_DERIVATIVE_OFF 0x01
#define SETUP_COORD 0x1B #define SETUP_COORD_ON 0x00 #define SETUP_COORD_OFF 0x01
#define SETUP_GRID 0x1C #define SETUP_GRID_ON 0x00 #define SETUP_GRID_OFF 0x01
#define SETUP_AXES 0x1D #define SETUP_AXES_ON 0x00 #define SETUP_AXES_OFF 0x01
#define SETUP_LABEL 0x1E #define SETUP_LABEL_ON 0x00 #define SETUP_LABEL_OFF 0x01
#define SETUP_STATWIND 0x20 #define SETUP_STATWIND_AUTO 0x00 #define SETUP_STATWIND_MANUAL 0x01
#define SETUP_GRAPHFUNC 0x21 #define SETUP_GRAPHFUNC_ON 0x00 #define SETUP_GRAPHFUNC_OFF 0x01
#define SETUP_DUALSCREEN 0x22 #define SETUP_DUALSCREEN_OFF 0x03
#define SETUP_SIMULFUNC 0x23 #define SETUP_SIMULFUNC_ON 0x00 #define SETUP_SIMULFUNC_OFF 0x01
#define SETUP_DYNAMICTYPE 0x24 #define SETUP_DYNAMICTYPE_CONT 0x00 #define SETUP_DYNAMICTYPE_STOP 0x01
#define SETUP_SIGMADISPLAY 0x25 #define SETUP_SIGMADISPLAY_ON 0x00 #define SETUP_SIGMADISPLAY_OFF 0x01
#define SETUP_SLOPE 0x26 #define SETUP_SLOPE_ON 0x00 #define SETUP_SLOPE_OFF 0x01
#define SETUP_PAYMENT 0x27 #define SETUP_PAYMENT_BGN 0x00 #define SETUP_PAYMENT_END 0x01
#define SETUP_DATEMODE 0x28 #define SETUP_DATEMODE_365 0x00 #define SETUP_DATEMODE_360 0x01
#define SETUP_ANSWERTYPE 0x29 #define SETUP_ANSWERTYPE_REAL 0x00 #define SETUP_ANSWERTYPE_COMPLEX 0x01
#define SETUP_COMPLEXMODE 0x2A #define SETUP_COMPLEXMODE_REAL 0x00 #define SETUP_COMPLEXMODE_APBI 0x01 #define SETUP_COMPLEXMODE_RLTT 0x02
#define SETUP_DISPLAY 0x2B #define SETUP_DISPLAY_NORM1 0x00 #define SETUP_DISPLAY_NORM2 0x10 #define SETUP_DISPLAY_FIX0 0x20 #define SETUP_DISPLAY_FIX1 0x21 #define SETUP_DISPLAY_FIX2 0x22 #define SETUP_DISPLAY_FIX3 0x23 #define SETUP_DISPLAY_FIX4 0x24 #define SETUP_DISPLAY_FIX5 0x25 #define SETUP_DISPLAY_FIX6 0x26 #define SETUP_DISPLAY_FIX7 0x27 #define SETUP_DISPLAY_FIX8 0x28 #define SETUP_DISPLAY_FIX9 0x29 #define SETUP_DISPLAY_SCI0 0x30 #define SETUP_DISPLAY_SCI1 0x31 #define SETUP_DISPLAY_SCI2 0x32 #define SETUP_DISPLAY_SCI3 0x33 #define SETUP_DISPLAY_SCI4 0x34 #define SETUP_DISPLAY_SCI5 0x35 #define SETUP_DISPLAY_SCI6 0x36 #define SETUP_DISPLAY_SCI7 0x37 #define SETUP_DISPLAY_SCI8 0x38 #define SETUP_DISPLAY_SCI9 0x39 #define SETUP_DISPLAY_TOGGLE_E_MODE 0x80
#define SETUP_BACKGROUND 0x2C #define SETUP_BACKGROUND_NONE 0x00 #define SETUP_BACKGROUND_PICT01 0x01 #define SETUP_BACKGROUND_PICT02 0x02 #define SETUP_BACKGROUND_PICT03 0x03 #define SETUP_BACKGROUND_PICT04 0x04 #define SETUP_BACKGROUND_PICT05 0x05 #define SETUP_BACKGROUND_PICT06 0x06 #define SETUP_BACKGROUND_PICT07 0x07 #define SETUP_BACKGROUND_PICT08 0x08 #define SETUP_BACKGROUND_PICT09 0x09 #define SETUP_BACKGROUND_PICT10 0x0A #define SETUP_BACKGROUND_PICT11 0x0B #define SETUP_BACKGROUND_PICT12 0x0C #define SETUP_BACKGROUND_PICT13 0x0D #define SETUP_BACKGROUND_PICT14 0x0E #define SETUP_BACKGROUND_PICT15 0x0F #define SETUP_BACKGROUND_PICT16 0x10 #define SETUP_BACKGROUND_PICT17 0x11 #define SETUP_BACKGROUND_PICT18 0x12 #define SETUP_BACKGROUND_PICT19 0x13 #define SETUP_BACKGROUND_PICT20 0x14
#define SETUP_RESIDLIST 0x2D #define SETUP_RESIDLIST_NONE 0x00 #define SETUP_RESIDLIST_LIST01 0x01 #define SETUP_RESIDLIST_LIST02 0x02 #define SETUP_RESIDLIST_LIST03 0x03 #define SETUP_RESIDLIST_LIST04 0x04 #define SETUP_RESIDLIST_LIST05 0x05 #define SETUP_RESIDLIST_LIST06 0x06 #define SETUP_RESIDLIST_LIST07 0x07 #define SETUP_RESIDLIST_LIST08 0x08 #define SETUP_RESIDLIST_LIST09 0x09 #define SETUP_RESIDLIST_LIST10 0x0A #define SETUP_RESIDLIST_LIST11 0x0B #define SETUP_RESIDLIST_LIST12 0x0C #define SETUP_RESIDLIST_LIST13 0x0D #define SETUP_RESIDLIST_LIST14 0x0E #define SETUP_RESIDLIST_LIST15 0x0F #define SETUP_RESIDLIST_LIST16 0x10 #define SETUP_RESIDLIST_LIST17 0x11 #define SETUP_RESIDLIST_LIST18 0x12 #define SETUP_RESIDLIST_LIST19 0x13 #define SETUP_RESIDLIST_LIST20 0x14 #define SETUP_RESIDLIST_LIST21 0x15 #define SETUP_RESIDLIST_LIST22 0x16 #define SETUP_RESIDLIST_LIST23 0x17 #define SETUP_RESIDLIST_LIST24 0x18 #define SETUP_RESIDLIST_LIST25 0x19 #define SETUP_RESIDLIST_LIST26 0x1A
#define SETUP_LISTFILE 0x2E #define SETUP_LISTFILE_FILE01 0x01 #define SETUP_LISTFILE_FILE02 0x02 #define SETUP_LISTFILE_FILE03 0x03 #define SETUP_LISTFILE_FILE04 0x04 #define SETUP_LISTFILE_FILE05 0x05 #define SETUP_LISTFILE_FILE06 0x06
#define SETUP_VARIABLE 0x2F #define SETUP_VARIABLE_RANGE 0x00 #define SETUP_VARIABLE_LIST01 0x01 #define SETUP_VARIABLE_LIST02 0x02 #define SETUP_VARIABLE_LIST03 0x03 #define SETUP_VARIABLE_LIST04 0x04 #define SETUP_VARIABLE_LIST05 0x05 #define SETUP_VARIABLE_LIST06 0x06 #define SETUP_VARIABLE_LIST07 0x07 #define SETUP_VARIABLE_LIST08 0x08 #define SETUP_VARIABLE_LIST09 0x09 #define SETUP_VARIABLE_LIST10 0x0A #define SETUP_VARIABLE_LIST11 0x0B #define SETUP_VARIABLE_LIST12 0x0C #define SETUP_VARIABLE_LIST13 0x0D #define SETUP_VARIABLE_LIST14 0x0E #define SETUP_VARIABLE_LIST15 0x0F #define SETUP_VARIABLE_LIST16 0x10 #define SETUP_VARIABLE_LIST17 0x11 #define SETUP_VARIABLE_LIST18 0x12 #define SETUP_VARIABLE_LIST19 0x13 #define SETUP_VARIABLE_LIST20 0x14 #define SETUP_VARIABLE_LIST21 0x15 #define SETUP_VARIABLE_LIST22 0x16 #define SETUP_VARIABLE_LIST23 0x17 #define SETUP_VARIABLE_LIST24 0x18 #define SETUP_VARIABLE_LIST25 0x19 #define SETUP_VARIABLE_LIST26 0x1A
#define SETUP_RECURDUAL 0x31 #define SETUP_RECURDUAL_TPG 0x00 #define SETUP_RECURDUAL_OFF 0x01
#define SETUP_AUTOCALC 0x4E #define SETUP_AUTOCALC_ON 0x00 #define SETUP_AUTOCALC_OFF 0x01
#define SETUP_SHOWCELL 0x4F #define SETUP_SHOWCELL_FORMULA 0x00 #define SETUP_SHOWCELL_VALUE 0x01
#define SETUP_MOVE 0x50 #define SETUP_MOVE_LOWER 0x00 #define SETUP_MOVE_RIGHT 0x01
#define SETUP_SUBNAME 0x51 #define SETUP_SUBNAME_ON 0x00 #define SETUP_SUBNAME_OFF 0x01
#define SETUP_INPUTMODE 0x53 #define SETUP_INPUTMODE_MATH 0x00 #define SETUP_INPUTMODE_LINEAR 0x01
#define SETUP_LOCUS 0x54 #define SETUP_LOCUS_ON 0x00 #define SETUP_LOCUS_OFF 0x01
#define SETUP_DRAWSPEED 0x55 #define SETUP_DRAWSPEED_NORM 0x00 #define SETUP_DRAWSPEED_HIGH 0x01
#define SETUP_SKETCHLINE 0x56 #define SETUP_SKETCHLINE_NORM 0x00 #define SETUP_SKETCHLINE_THICK 0x01 #define SETUP_SKETCHLINE_BROKEN 0x02 #define SETUP_SKETCHLINE_DOT 0x03
#define SETUP_FRACRESULT 0x57 #define SETUP_FRACRESULT_DC 0x00 #define SETUP_FRACRESULT_ABC 0x01
#define SETUP_SIMPLIFY 0x5F #define SETUP_SIMPLIFY_AUTO 0x00 #define SETUP_SIMPLIFY_MANUAL 0x01
#define SETUP_EOL 0xFF
typedef struct { unsigned char Id; unsigned char Value; } TSetupEntry;
const TSetupEntry SetupTemplate[] = { { SETUP_ANGLE, SETUP_ANGLE_GRA } ,{ SETUP_INS_OVWR, SETUP_INS_OVWR_INS } ,{ SETUP_DERIVATIVE, SETUP_DERIVATIVE_OFF } ,{ SETUP_GRID, SETUP_GRID_OFF } ,{ SETUP_LABEL, SETUP_LABEL_OFF } ,{ SETUP_DUALSCREEN, SETUP_DUALSCREEN_OFF } ,{ SETUP_SIMULFUNC, SETUP_SIMULFUNC_OFF } ,{ SETUP_DYNAMICTYPE, SETUP_DYNAMICTYPE_STOP } ,{ SETUP_SIGMADISPLAY, SETUP_SIGMADISPLAY_OFF } ,{ SETUP_SLOPE, SETUP_SLOPE_OFF } ,{ SETUP_PAYMENT, SETUP_PAYMENT_END } ,{ SETUP_LISTFILE, SETUP_LISTFILE_FILE01 } ,{ 0x30, 0x01 } ,{ 0x31, 0x01 } ,{ 0x52, 0x01 } ,{ 0x54, 0x01 } ,{ 0x5A, 0x01 } ,{ 0x5B, 0x01 } ,{ SETUP_EOL, 0 } };
typedef struct { unsigned char USBPower[8]; unsigned char Type; unsigned char Filler1[5]; unsigned char ControlByte1; unsigned char One1; unsigned int filesize; unsigned char ControlByte2; unsigned char Filler2[11]; } TStandardHeader;
typedef struct { unsigned int filesize; unsigned int setup_area_size; unsigned int version[2]; } TEACTcommonHeader;
typedef struct { unsigned char AT_EACT[8]; unsigned int one; unsigned int length1; unsigned char EACT1[8]; unsigned int onefour; unsigned int length2; unsigned int D4000066; unsigned int line_count; } TEACTsubHeader;
typedef union{ unsigned int Entry; struct { unsigned char EntryType; unsigned char EntryOffset[3]; /* offset relative to 0x54+LS, big endian */ }; } TLineDescriptor;
typedef TLineDescriptor* PLineDescriptor;
// void TwoAlign( char*s, char*sFiller ){ if ( strlen( s ) & 1 ) strcat( s, sFiller ); }
// void writeln( int h, char*s ){ TwoAlign( s, " " ); strcat( (char*)s, "\x00D\x00A" ); Bfile_WriteFile_OS( h, s, strlen( s ) ); }
// unsigned int EACT2TXT( void ){ int result = -1; int readresult = -1; unsigned short in_name[ FILENAMESIZE ]; unsigned short out_name[ FILENAMESIZE ]; unsigned char textfilename[ FILENAMESIZE ]; int handle, hTXT; unsigned int key; unsigned char x[21]; unsigned char y[21]; TStandardHeader StandardHeader; int i, j, jMax; TEACTcommonHeader EACTcommonHeader; int setup_dir_size; int required_setup_size, required_size; unsigned char setup_directory[ MAX_SETUP_DIR_SIZE ]; unsigned char setup_data[ MAX_SETUP_DIR_SIZE*8 ]; unsigned char bitroll, ibit, ibits, isetup_entry; unsigned int line_count; unsigned int iwork, offset_of_line_count, inext; PLineDescriptor LineDirectory; unsigned int start_of_line, required_line_size; char*line; char*line_out; TSMemView smv;
smv.SetFlags( FLAG_EXIT_ON_EXE | smv.GetFlags() ); smv.SetFilter( "*.g?e" ); smv.AutoSelectPattern(); if ( smv.browse() != lvmKEY + KEY_CTRL_EXE ) return 1;
// MessageDlg( (void*)smv.SelectedFullname, mtInformation, 6 );
memset( textfilename, 0, sizeof( textfilename ) ); strcpy( (char*)textfilename, smv.SelectedFullname ); i = strlen( (char*)textfilename ); while ( i > 0 ){ if ( textfilename[ i ] == '.' ) break; textfilename[ i-- ] = 0; } strcat( (char*)textfilename, "TXT" ); // MessageDlg( (void*)textfilename, mtInformation, 6 );
LineDirectory = 0; line = 0; line_out = 0;
handle = -1; hTXT = -1;
while ( 1 ){ // open EACT-file // Bfile_StrToName_ncpy( in_name, "\\\\fls0\\EACTTST2.g2e", FILENAMESIZE ); // Bfile_StrToName_ncpy( in_name, "\\\\fls0\\EAEXMPL.g1e", FILENAMESIZE ); Bfile_StrToName_ncpy( in_name, (unsigned char*)smv.SelectedFullname, FILENAMESIZE ); handle = Bfile_OpenFile_OS( in_name, 3 ); if ( handle < 0 ){ result = 0x80000001; break; }
// read StandardHeader and check readresult readresult = Bfile_ReadFile_OS( handle, (void*)&StandardHeader, sizeof( TStandardHeader ), 0 ); if ( readresult != sizeof( TStandardHeader ) ){ result = 0x80010001; break; } // invert the standard header InvertMem( (char*)&StandardHeader, sizeof( StandardHeader ) ); // check controlbyte1 if ( ( ( StandardHeader.filesize + 0x41 ) & 0xFF ) != StandardHeader.ControlByte1 ){ result = 0x80010002; break; } // check controlbyte2 if ( ( ( StandardHeader.filesize + 0xB8 ) & 0xFF ) != StandardHeader.ControlByte2 ){ result = 0x80010003; break; } // read the common EACT-header and check readresult readresult = Bfile_ReadFile_OS( handle, (void*)&EACTcommonHeader, sizeof( TEACTcommonHeader ), -1 ); if ( readresult != sizeof( TEACTcommonHeader ) ){ result = 0x80020001; break; } // check for consistency if ( EACTcommonHeader.filesize != StandardHeader.filesize ){ result = 0x80020002; break; } // now decide, which type of EACT-file has been read. if ( EACTcommonHeader.version[0] == G1E ) setup_dir_size = 0x10; else if ( EACTcommonHeader.version[0] == G2E ) setup_dir_size = 0x10; else if ( EACTcommonHeader.version[0] == G3E ) setup_dir_size = 0x2C; else{ result = 0x80020003; setup_dir_size = EACTcommonHeader.version[0]; break; }
readresult = Bfile_ReadFile_OS( handle, (void*)setup_directory, 4, -1 ); // kill the four trailing zero bytes readresult = Bfile_ReadFile_OS( handle, (void*)setup_directory, (int)setup_dir_size, -1 ); if ( readresult != setup_dir_size ){ result = 0x80020004; break; } // calculate number of non-zero setup-entries ibits = 0; for ( i = 0; i < setup_dir_size; i++ ){ bitroll = setup_directory[ i ]; for ( ibit = 0; ibit < 8; ibit++ ){ if ( bitroll & 0x80 ){ ibits++; } bitroll<<=1; } } // read the setup-data required_setup_size = ( ibits + 3 ) & 0xFFFFFFFC; // 4-aligned readresult = Bfile_ReadFile_OS( handle, (void*)&setup_data, required_setup_size, -1 ); if ( readresult != required_setup_size ){ result = 0x80020005; break; } // read the count of EACT-lines offset_of_line_count = 0x54+EACTcommonHeader.setup_area_size; readresult = Bfile_ReadFile_OS( handle, (void*)&line_count, sizeof( line_count ), offset_of_line_count ); if ( readresult != sizeof( line_count ) ){ result = 0x80020006; break; } // allocate memory for the LineDirectory LineDirectory = (PLineDescriptor)malloc( sizeof( TLineDescriptor ) * line_count ); // read the LineDirectory readresult = Bfile_ReadFile_OS( handle, (void*)LineDirectory, sizeof( TLineDescriptor ) * line_count, -1 ); if ( readresult != ( sizeof( TLineDescriptor ) * line_count ) ){ result = 0x80020007; break; }
required_line_size = 0; #ifdef WRITE_THE_LINES // calculate the size of the lines for ( i = 0; i < line_count; i++ ){ start_of_line = offset_of_line_count + ( LineDirectory[ i ].Entry & 0x00FFFFFF ); if ( i < ( line_count - 1 ) ) inext = offset_of_line_count + ( LineDirectory[ i + 1 ].Entry & 0x00FFFFFF ); else inext = StandardHeader.filesize; jMax = inext - start_of_line; switch ( LineDirectory[ i ].EntryType ){ case 0x03 : line = (char*)malloc( jMax ); readresult = Bfile_ReadFile_OS( handle, line, jMax, start_of_line ); required_line_size += strlen( ( line + 8 ) ); break; case 0x07 : case 0x81 : line = (char*)malloc( jMax ); readresult = Bfile_ReadFile_OS( handle, line, jMax, start_of_line ); required_line_size += strlen( line ); break; default : required_line_size += jMax * 3; break; } required_line_size += 2; // CRLF required_line_size = ( required_line_size + 1 ) & 0xFFFFFFFE; // 2-align free( line ); line = 0; } #endif
// prepare the textfile #ifdef OMIT_ZERO_SETUP_VALUES required_size = ibits*8; #else required_size = setup_dir_size*8*8; #endif required_size += 10; // for the line count (); 8 bytes for the hex-representation and two for 0D0A required_size += 14*line_count;
required_size += required_line_size;
// 2-alignment required_size += 1; required_size &= 0xFFFFFFFE;
// create the textfile Bfile_StrToName_ncpy( out_name, textfilename, FILENAMESIZE ); #ifdef fxCG Bfile_DeleteEntry( out_name ); #else Bfile_DeleteEntry( out_name, 0 ); #endif result = Bfile_CreateEntry_OS( out_name, 1, &required_size ); if ( result == 0 ){ hTXT = Bfile_OpenFile_OS( out_name, 3 ); if ( hTXT < 0 ){ result = 0x80030001; break; } }else{ result = 0x80030002; break; }
// write the setup-informmation to the textfile ibits = 0; isetup_entry = 0; memset( y, 0, sizeof( y ) ); for ( i = 0; i < setup_dir_size; i++ ){ bitroll = setup_directory[ i ]; for ( ibit = 0; ibit < 8; ibit++ ){ memset( x, 0, sizeof( x ) ); ByteToHex( isetup_entry, (unsigned char*)x ); strcat( (char*)x, "=" );
if ( bitroll & 0x80 ){ ByteToHex( setup_data[ ibits ], (unsigned char*)y ); strcat( (char*)x, (char*)y ); ibits++; }else{ strcat( (char*)x, "00" ); } #ifdef OMIT_ZERO_SETUP_VALUES if ( bitroll & 0x80 ) #endif writeln( hTXT, (char*)x );
bitroll<<=1; isetup_entry++; } } // write the line-count to the textfile memset( x, 0, sizeof( x ) ); IntToHex( line_count, (unsigned char*)x ); writeln( hTXT, (char*)x );
// write the LineDirectory to the textfile memset( y, 0, sizeof( y ) ); for ( i = 0; i < line_count; i++ ){ memset( x, 0, sizeof( x ) ); ByteToHex( LineDirectory[ i ].EntryType, (unsigned char*)x ); strcat( (char*)x, ": " );
iwork = LineDirectory[ i ].Entry & 0x00FFFFFF;
iwork += offset_of_line_count; IntToHex( iwork, (unsigned char*)y ); strcat( (char*)x, (char*)y );
writeln( hTXT, (char*)x ); }
break; }
#ifdef WRITE_THE_LINES // write the lines memset( x, 0, sizeof( x ) ); for ( i = 0; i < line_count; i++ ){ start_of_line = offset_of_line_count + ( LineDirectory[ i ].Entry & 0x00FFFFFF ); if ( i < ( line_count - 1 ) ) inext = offset_of_line_count + ( LineDirectory[ i + 1 ].Entry & 0x00FFFFFF ); else inext = StandardHeader.filesize; jMax = inext - start_of_line; line = (char*)malloc( jMax + 4 ); readresult = Bfile_ReadFile_OS( handle, line, jMax, start_of_line ); switch ( LineDirectory[ i ].EntryType ){ case 0x03 : writeln( hTXT, line+8 ); break; case 0x07 : case 0x81 : writeln( hTXT, line ); break; default : line_out = (char*)malloc( jMax * 3 + 2 ); memset( line_out, 0, jMax * 3 ); for ( j = 0; j < jMax; j++ ){ ByteToHex( line[ j ], (unsigned char*)x ); strcat( line_out, (char*)x ); strcat( line_out, " " ); } writeln( hTXT, line_out ); break; } free( line ); line = 0; free( line_out ); line_out = 0; } #endif
// close TXT-file if ( hTXT >= 0 ){ result = Bfile_CloseFile_OS( hTXT ); }else result = 0x80040001;
// close EACT-file if ( handle >= 0 ){ result = Bfile_CloseFile_OS( handle ); }else result = 0x80040002 ;
free( LineDirectory );
// display some results for diagnostics during development Bdisp_AllClr_VRAM();
locate(1,1); IntToHex( result, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,2); IntToHex( handle, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,3); IntToHex( required_setup_size, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,4); IntToHex( setup_dir_size, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,5); IntToHex( StandardHeader.filesize, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,6); IntToHex( required_size, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,7); IntToHex( line_count, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,8); // IntToHex( EACTcommonHeader.setup_area_size, (unsigned char*)x ); // IntToHex( iwork, (unsigned char*)x ); IntToHex( offset_of_line_count, (unsigned char*)x ); Print( (unsigned char*)x ); // Print( (unsigned char*)smv.SelectedFullname );
GetKey( &key );
return result; }
// specify test scheme for TXT2EACT #define EACT_TYPE G1E #define EACT_FILENAME "\\\\fls0\\EACTNEW1." // test lines as stringlist const unsigned char Lines[] = "x\x00D\x00A\x000" "first line\x00D\x00A\x000" "second line\x00D\x00A\x000" "\x00D\x00A\x000" "fourth line\x00D\x00A\x000" "1\x00D\x00A\x000" "12\x00D\x00A\x000" "123\x00D\x00A\x000" "1234\x00D\x00A\x000" "12345\x00D\x00A\x000" "123456\x00D\x00A\x000" "1234567\x00D\x00A\x000" "12345678\x00D\x00A\x000" "last line\x00D\x00A\x000" ;
// the heading is not heeded for by the OS. It is always constructed based on the filename.
// size of CRLF (0x0D0A), which is used as input line delimiter in this case #define SIZE_OF_TEXTLINE_DELIMITER 2
// int TXT2EACT( void ){ unsigned short in_name[ FILENAMESIZE ]; unsigned short out_name[ FILENAMESIZE ]; unsigned char work[ FILENAMESIZE ]; int setup_dir_size, setup_data_size; int required_setup_size, required_size, required_lines_size, required_line_size; int i, j, k, ibits; unsigned char setup_directory[ MAX_SETUP_DIR_SIZE ]; unsigned char setup_data[ MAX_SETUP_DIR_SIZE*8+16 ]; // +16 because of the 16 finalizing zero bytes TStandardHeader StandardHeader; TEACTcommonHeader EACTcommonHeader; TEACTsubHeader EACTsubHeader; unsigned int filesize; unsigned int line_count; TStringList sl; int handle = -1; int ioresult; unsigned int line_offset; TLineDescriptor LineDescriptor; unsigned char*workline; unsigned char x[21]; unsigned int key;
workline = 0;
//--------------------------- // the StringList is used for convenience during development only; normally a textfile would be used as input sl.Assign( (char*)Lines ); sl.GoEndOfList(); line_count = sl.LineNo() + 1;
//--------------------------- // now calculate the required size for all lines required_lines_size = 0; // goto begin of text-input (the first line is the EACT-heading) sl.GoBeginOfList(); while ( 1 ){ // calculate the required space for the current line required_line_size = sl.StringLength(); // length of the current text-line required_line_size++; // add one for the terminating zero required_line_size -= SIZE_OF_TEXTLINE_DELIMITER; required_line_size = ( required_line_size + 3 ) & 0xFFFFFFFC; // 4-align
required_lines_size += required_line_size; if ( !sl.NextLine() ) break; // break, if end of text } //--------------------------- // build up the EACT-filename memset( work, 0, sizeof( work ) ); // initialize strcpy( (char*)work, EACT_FILENAME ); // copy the basefilename EACTcommonHeader.version[0] = EACT_TYPE; // this is important! // EACTcommonHeader.version[0] = 0; // this leads to failure
switch ( EACT_TYPE ){ case G1E : strcat( (char*)work, "g1e" ); // append the extension to filename setup_dir_size = 0x10; EACTcommonHeader.version[1] = 0x5061636B; // written on save on fx-9860 OS 1.XX // EACTcommonHeader.version[1] = 0x00000000; // the OS does not mind while reading break; case G2E : strcat( (char*)work, "g2e" ); // append the extension to filename setup_dir_size = 0x10; EACTcommonHeader.version[1] = 0x02020201; // the version of the OS while writing (fx-9860 OS 2.XX) // EACTcommonHeader.version[1] = 0x00000000; // the OS does not mind while reading break; case G3E : strcat( (char*)work, "g3e" ); // append the extension to filename setup_dir_size = 0x2C; EACTcommonHeader.version[1] = 0x01040200; break; }; // convert an unsigned char filename to unsigned short Bfile_StrToName_ncpy( out_name, work, FILENAMESIZE );
//--------------------------- // calculate the setup sizes memset( setup_directory, 0, sizeof( setup_directory ) ); // initialize with zeros memset( setup_data, 0, sizeof( setup_data ) ); // initialize with zeros k = 0; // index to SetupTemplate ibits = 0; for ( i = 0; i < setup_dir_size; i++ ){ for ( j = 0; j < 8; j++ ){ if ( SetupTemplate[ k ].Id == SETUP_EOL ) break; if ( SetupTemplate[ k ].Id == i*8+j ){ if ( SetupTemplate[ k ].Value ){ // only the entries with non-zero-values are heeded for setup_directory[ i ] |= ( 0x80 >> j ); // set the corresponding bit setup_data[ ibits ] = SetupTemplate[ k ].Value; // stor the next non-zero value to the setup_data-array ibits++; } // next SetupTemplate-item k++; } } if ( SetupTemplate[ k ].Id == SETUP_EOL ) break; } // ibits contains the count of non-zero setup-values now setup_data_size = ( ( ibits + 3 ) & 0xFFFFFFFC ); // 4-align required_setup_size = setup_dir_size + setup_data_size; required_setup_size += 4; // starting zeros at offset 0x30 required_setup_size += 16; // trailing zeros at offset ( 0x20 + setup_area_size )
//--------------------------- // calculate the required filesize filesize = sizeof( TStandardHeader ); filesize += sizeof( TEACTcommonHeader ); filesize += required_setup_size; filesize += sizeof( TEACTsubHeader ); filesize += line_count*4; // LineDirectory filesize += 4; // LineDirectory finalizing four bytes (all zeros with G1E/G2E; filesize - 0x54 - required_setup_size with G3E ) filesize += required_lines_size; // space required for the LineArray
// set up standard header memcpy( StandardHeader.USBPower, "USBPower", 8 ); StandardHeader.Type = 0x49; memset( StandardHeader.Filler1, 0, sizeof( StandardHeader.Filler1 ) ); StandardHeader.ControlByte1 = ( filesize + 0x41 ) & 0xFF; StandardHeader.One1 = 1; StandardHeader.filesize = filesize; StandardHeader.ControlByte2 = ( filesize + 0xB8 ) & 0xFF; memset( StandardHeader.Filler2, 0, sizeof( StandardHeader.Filler2 ) ); // invert the standard header InvertMem( (char*)&StandardHeader, sizeof( StandardHeader ) );
// set up EACTcommonHeader header EACTcommonHeader.filesize = filesize; EACTcommonHeader.setup_area_size = required_setup_size;
memset( &EACTsubHeader, 0, sizeof( EACTsubHeader ) ); memcpy( EACTsubHeader.AT_EACT, "@EACT\x000\x000\x000", sizeof( EACTsubHeader.AT_EACT ) ); // mandatory EACTsubHeader.one = 0x00000001; // mandatory EACTsubHeader.length1 = filesize - 0x40 - required_setup_size; memcpy( EACTsubHeader.EACT1, "EACT1\x000\x000\x000", sizeof( EACTsubHeader.EACT1 ) ); EACTsubHeader.onefour = 0x00000014; EACTsubHeader.length2 = filesize - 0x54 - required_setup_size; EACTsubHeader.D4000066 = 0xD4000066; EACTsubHeader.line_count = line_count;
//--------------------------- // delete EACT-file #ifdef fxCG ioresult = Bfile_DeleteEntry( out_name ); #else ioresult = Bfile_DeleteEntry( out_name, 0 ); #endif //--------------------------- // create and open EACT-file required_size = filesize; ioresult = Bfile_CreateEntry_OS( out_name, 1, &required_size ); if ( ioresult == 0 ){ handle = Bfile_OpenFile_OS( out_name, 3 ); if ( handle >= 0 ){ //--------------------------- // write the StandardHeader ioresult = Bfile_WriteFile_OS( handle, &StandardHeader, sizeof( TStandardHeader ) ); //--------------------------- // write the EACTcommonHeader ioresult = Bfile_WriteFile_OS( handle, &EACTcommonHeader, sizeof( TEACTcommonHeader ) ); //--------------------------- // write the setup-area k = 0; ioresult = Bfile_WriteFile_OS( handle, &k, sizeof( k ) ); ioresult = Bfile_WriteFile_OS( handle, &setup_directory, setup_dir_size ); ioresult = Bfile_WriteFile_OS( handle, &setup_data, setup_data_size+16 ); // +16 because of the 16 finalizing zero bytes //--------------------------- // write the EACTsubHeader ioresult = Bfile_WriteFile_OS( handle, &EACTsubHeader, sizeof( TEACTsubHeader ) );
// process the lines // each TEXT line gives one EACT-line (type 0x81) //--------------------------- // first the LineDirectory line_offset = ( line_count + 2 ) * 4; sl.GoBeginOfList(); // go to the start of text-input for ( i = 0; i < line_count; i++ ){ LineDescriptor.Entry = line_offset; if ( i ) LineDescriptor.EntryType = 0x81; // normal line else LineDescriptor.EntryType = 0x07; // header-line // now write the LineDescriptor ioresult = Bfile_WriteFile_OS( handle, &LineDescriptor, sizeof( TLineDescriptor ) );
required_line_size = sl.StringLength(); required_line_size++; // add one for the terminating zero required_line_size -= SIZE_OF_TEXTLINE_DELIMITER; required_line_size = ( required_line_size + 3 ) & 0xFFFFFFFC; // 4-align line_offset += required_line_size; sl.NextLine(); } //--------------------------- // write LineDirectory finalizing item. switch ( EACT_TYPE ){ case G1E : case G2E : k = 0; break; case G3E : k = EACTsubHeader.length2; break; } ioresult = Bfile_WriteFile_OS( handle, &k, 4 );
//--------------------------- // write the lines sl.GoBeginOfList(); // go to the start of text-input again for ( i = 0; i < line_count; i++ ){ // calculate the required space for the current line required_line_size = sl.StringLength(); required_line_size -= SIZE_OF_TEXTLINE_DELIMITER; k = required_line_size; // remember the count to be copied to workline required_line_size++; // add one for the terminating zero required_line_size = ( required_line_size + 3 ) & 0xFFFFFFFC; // 4-align
workline = (unsigned char*)malloc( required_line_size ); // get some heap memset( workline, 0, required_line_size ); // initialize the allocated memory with zeros memcpy( workline, sl.Line(), k ); // this truncates the trailing TEXTLINE_DELIMITER
ioresult = Bfile_WriteFile_OS( handle, workline, required_line_size );
free( workline );
sl.NextLine(); } } }
//--------------------------- // close EACT-file if ( handle >= 0 ){ ioresult = Bfile_CloseFile_OS( handle ); }
// display some results for diagnostics during development Bdisp_AllClr_VRAM();
locate(1,1); IntToHex( ioresult, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,2); IntToHex( handle, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,3); IntToHex( required_lines_size, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,4); IntToHex( ibits, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,5); IntToHex( filesize, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,6); IntToHex( line_count, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,7); IntToHex( 0, (unsigned char*)x ); Print( (unsigned char*)x );
locate(1,8); IntToHex( 0, (unsigned char*)x ); Print( (unsigned char*)x );
GetKey( &key );
return 1; }
(06.10.2012 09:21:42)