diff options
author | Luc Verhaegen <lverhaegen@ridcully.suse.de> | 2009-01-07 15:32:25 +0100 |
---|---|---|
committer | Luc Verhaegen <lverhaegen@ridcully.suse.de> | 2009-01-07 15:32:25 +0100 |
commit | 925beab5c082137b171e4688e15d493f9ec5e8f4 (patch) | |
tree | da1679fb449eed3404e2d7792fd102328daf6ed0 |
Initial import of Anton Borisovs amideco 0.31e.
License seems to be pure GPL.
-rw-r--r-- | src/amideco.c | 172 | ||||
-rw-r--r-- | src/amideco.h | 144 | ||||
-rw-r--r-- | src/amifunc.c | 616 | ||||
-rw-r--r-- | src/amihelp.h | 77 | ||||
-rw-r--r-- | src/amisoft.h | 18 | ||||
-rw-r--r-- | src/amiver.h | 17 | ||||
-rw-r--r-- | src/kernel.c | 342 |
7 files changed, 1386 insertions, 0 deletions
diff --git a/src/amideco.c b/src/amideco.c new file mode 100644 index 0000000..6d08367 --- /dev/null +++ b/src/amideco.c @@ -0,0 +1,172 @@ +/* + * AMIBIOS Decompress + * + * Copyright (C) 2000, 2002 Anthony Borisow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/******************************************** +** +** Last update for 0.31 - Sep 29, 2000 +** +********************************************/ + +/****************************************/ +/* 0.31 Added Buffered Search */ +/****************************************/ +/* WARNING! Under DJGPP */ +/****************************************/ + +/* Version 0.31 */ + + +#include <stdio.h> +#include <stdlib.h> + + +#include "./amideco.h" +#include "./amisoft.h" +#include "./amiver.h" +#include "./amihelp.h" + +int main(byte argc, byte *argv[]) + { + + FILE *ptx, *pto; + dword fLen, i, RealRead = 0; + byte Temp[] = "AMIBIOSC", *BufBlk; + byte Buf[12]; + byte BufAdd[0x30]; + ABCTag abc; + + dword ConstOff, Offset, BODYOff = 0; + LZHHead FHead; + + byte AMIVer = 0; + AMIDATE amidate; + + byte PartTotal = 0; + byte Action = 0; + byte HelpID = 0; + + HelpID = HelpSystem(argc,argv); + switch( HelpID & 0x7F ){ + case 0x20: return 0; + case 0x10: Action = Xtract; break; + case 0x01: Action = List; break; + default: + PrintUsage(); + printf("\n"); + return 0; + } + + if( (ptx = fopen(argv[1],"rb")) == NULL ) + { + printf("\nFile %s opening error...\n", argv[1]); + return 0; + }; + + PrintHeader("\n\n"); + + fseek( ptx, 0, 2 ); + fLen = ftell(ptx); + rewind( ptx ); + printf("FileLength\t: %lX (%lu bytes)\n", fLen, fLen); + printf("FileName\t: %s\n", argv[1]); + + /*------- Memory Alloc --------*/ + + + if( (BufBlk = (byte*)calloc(BLOCK, sizeof(byte))) == NULL ) exit(1); + i = 0; + + while(!feof(ptx)) + { + fseek( ptx, i, 0 ); + RealRead = fread(BufBlk, 1, BLOCK, ptx); + if(( i = FoundAt(ptx, BufBlk, Temp, RealRead) ) != 0) + { + fseek(ptx, i + 8, 0); + fread(&abc, 1, sizeof(abc), ptx); + AMIVer = 95; + break; + } + i = ftell(ptx) - 0x100; + + } + if(AMIVer != 95) + { + printf("AMI'95 hook not found..Turning to AMI'94\n"); + rewind(ptx); + fread(&Buf, 1, 8, ptx); + if(memcmp(Buf, Temp, 8) != 0) + { + printf("Obviously not even AMIBIOS standard..Exit\n"); + + return 0; + } else { AMIVer = 94; }; + }; + + + + printf("\n\tAMIBIOS information:"); + + switch(AMIVer) + { + case 95: + fseek(ptx, -11L, 2); + fread(&amidate, 1, sizeof(amidate), ptx); + + printf("\nVersion\t\t: %.4s",abc.Version); + printf("\nPacked Data\t: %lX (%lu bytes)",(dword)abc.CRCLen*8,(dword)abc.CRCLen*8); + printf("\nStart\t\t: %lX",Offset=((dword)abc.BeginHi<<4)+(dword)abc.BeginLo); + + BODYOff = fLen - ( 0x100000 - ( Offset + 8 + sizeof(abc)) ) - 8 - sizeof(abc); + printf("\nPacked Offset\t: %lX", BODYOff); + + ConstOff = Offset - BODYOff; + printf("\nOffset\t\t: %lX", ConstOff); + + break; + case 94: + fread(&amidate, 1, sizeof(amidate), ptx); + if(atoi(amidate.Day) == 10 && atoi(amidate.Month) == 10) { Offset = 0x30; AMIVer = 10; } + else Offset = 0x10; + fseek(ptx, -11L, 2); + fread(&amidate, 1, sizeof(amidate), ptx); + break; + }; + printf("\nReleased\t: %s", GetFullDate(amidate.Month, amidate.Day, amidate.Year)); + + switch(AMIVer) + { + case 95: + PartTotal = Xtract95(ptx, HelpID, ConstOff, Offset, argv[1]); + break; + case 94: + PartTotal = Xtract0725(ptx, Action, Offset); + break; + case 10: + PartTotal = Xtract1010(ptx, Action, Offset); + default: break; + } + printf("\nTotal Sections\t: %i", PartTotal); + + free(BufBlk); + + printf("\n"); + return 0; + } diff --git a/src/amideco.h b/src/amideco.h new file mode 100644 index 0000000..1e5769b --- /dev/null +++ b/src/amideco.h @@ -0,0 +1,144 @@ +/********************************************** +** +** +** Defines & Functions for AmiDeco +** +** +***********************************************/ + +#ifndef AMIDECO_H +#define AMIDECO_H 1 + +#include <stdio.h> +#include <stdlib.h> + +#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) + #include <memory.h> + #define __LINUX_NOW__ +#else + #include <mem.h> + #include <conio.h> +#endif + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; + +#define Xtract 0x10 +#define List 0x01 +#define Delete 0x12 +#define XtractD 0x13 + +#define BLOCK 0x8000 + +#ifndef __LINUX_NOW__ + #define IDSign "" +#else + #define IDSign "+" +#endif + +typedef struct { + FILE *infile; + FILE *outfile; + unsigned long original; + unsigned long packed; + int dicbit; + int method; + } interfacing; + +typedef struct + { + byte Version[4]; + word CRCLen; + dword CRC32; + word BeginLo; + word BeginHi; + } ABCTag; + +typedef struct + { + word PrePartLo; /* Previous part LO word */ + word PrePartHi; /* Previous part HI word */ + /* value 0xFFFFFFFF = last */ + word CSize; /* This module header Len */ + byte PartID; /* ID for this header */ + byte IsComprs; /* Value 0x80 means that + this module not + compressed, 0x00 - is */ + dword RealCS; /* Address in RAM where + expand to */ + dword ROMSize; /* Compressed Len */ + dword ExpSize; /* Expanded Len */ + } PARTTag; + +typedef struct + { + byte HeadLen; + byte HeadCrc; + byte Method[5]; + dword PackLen; + dword RealLen; + dword TStamp; + byte Attr; + byte Level; + byte FilenameLen; + byte FileName[12]; + word CRC16; + byte DOS; + word Empty; + } LZHHead; + +typedef struct + { + word PackLenLo; + word PackLenHi; + word RealLenLo; + word RealLenHi; + } BIOS94; + +typedef struct + { + byte Month[2]; + byte rsrv1; + byte Day[2]; + byte rsrv2; + byte Year[2]; + } AMIDATE; + +typedef struct + { + dword Offset; + byte ModID; + byte IsPacked; + } AMIHEAD94; + +byte* GetModuleName(byte ID); + +//dword CalcCRC32(FILE *ptx, dword Begin, word Len); + +byte StrLen(byte *Str); +byte StrCmp(byte *Dst, byte *Src); + +byte *GetFullDate(byte *mon, byte *day, byte *year); + +/*--------------------------------- + FindHook +----------------------------------*/ +dword FoundAt(FILE *ptx, byte *Buf, byte *Pattern, dword BLOCK_LEN); + +/*--------------------------------- + Xtract95 +----------------------------------*/ +byte Xtract95(FILE *ptx, byte Action, dword ConstOff, dword Offset, byte* fname); + +/*--------------------------------- + Xtract0725 +----------------------------------*/ +byte Xtract0725(FILE *ptx, byte Action, dword Offset); + +/*--------------------------------- + Xtract1010 +----------------------------------*/ +byte Xtract1010(FILE *ptx, byte Action, dword Offset); + +#endif diff --git a/src/amifunc.c b/src/amifunc.c new file mode 100644 index 0000000..8655e8d --- /dev/null +++ b/src/amifunc.c @@ -0,0 +1,616 @@ +/********************************************** +** +** +** Defines & Functions for AmiDeco +** +** +***********************************************/ + + +#include <stdio.h> +#include <stdlib.h> + +#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) + #include <memory.h> + #define __LINUX_NOW__ +#else + #include <mem.h> + #include <conio.h> +#endif + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; + +#define Xtract 0x10 +#define List 0x01 +#define Delete 0x12 +#define XtractD 0x13 + +#define BLOCK 0x8000 + +#ifndef __LINUX_NOW__ + #define IDSign "" + +#else + #define IDSign "+" +#endif + +typedef struct { + FILE *infile; + FILE *outfile; + unsigned long original; + unsigned long packed; + int dicbit; + int method; + } interfacing; + +typedef struct + { + byte Version[4]; + word CRCLen; + dword CRC32; + word BeginLo; + word BeginHi; + } ABCTag; + +typedef struct + { + word PrePartLo; /* Previous part LO word */ + word PrePartHi; /* Previous part HI word */ + /* value 0xFFFFFFFF = last */ + word CSize; /* This module header Len */ + byte PartID; /* ID for this header */ + byte IsComprs; /* Value 0x80 means that + this module not + compressed, 0x00 - is */ + dword RealCS; /* Address in RAM where + expand to */ + dword ROMSize; /* Compressed Len */ + dword ExpSize; /* Expanded Len */ + } PARTTag; + +typedef struct + { + byte HeadLen; + byte HeadCrc; + byte Method[5]; + dword PackLen; + dword RealLen; + dword TStamp; + byte Attr; + byte Level; + byte FilenameLen; + byte FileName[12]; + word CRC16; + byte DOS; + word Empty; + } LZHHead; + +typedef struct + { + word PackLenLo; + word PackLenHi; + word RealLenLo; + word RealLenHi; + } BIOS94; + +typedef struct + { + byte Month[2]; + byte rsrv1; + byte Day[2]; + byte rsrv2; + byte Year[2]; + } AMIDATE; + +typedef struct + { + dword Offset; + byte ModID; + byte IsPacked; + } AMIHEAD94; + + byte *RecordList[]={ + "POST", "Setup Server", + "Runtime", "DIM", + "Setup Client", "Remote Server", + "DMI Data", "GreenPC", + "Interface", "MP", + "Notebook", "Int-10", + "ROM-ID", "Int-13", + "OEM Logo", "ACPI Table", + "ACPI AML", "P6 MicroCode", + "Configuration","DMI Code", + "System Health","UserDefined", + "","", + "","", + "","", + "","", + "","", + "PCI AddOn ROM","Multilanguage", + "UserDefined","", + "","", + "","", + "","", + "","", + "","", + "","", + "Font Database","OEM Logo Data", + "Graphic Logo Code","Graphic Logo Data", + "Action Logo Code","Action Logo Data", + "Virus", "Online Menu", + "","", + "","", + "","", + "","", + "","", + "","", + "","", + "","", + "","" + }; + + +byte* GetModuleName(byte ID) +{ + /* -------------- New Name Conventions -------------- */ + + switch(ID){ + case 0x00: return("POST"); + case 0x01: return("Setup Server"); + case 0x02: return("RunTime"); + case 0x03: return("DIM"); + case 0x04: return("Setup Client"); + case 0x05: return("Remote Server"); + case 0x06: return("DMI Data"); + case 0x07: return("Green PC"); + case 0x08: return("Interface"); + case 0x09: return("MP"); + case 0x0A: return("Notebook"); + case 0x0B: return("Int-10"); + case 0x0C: return("ROM-ID"); + case 0x0D: return("Int-13"); + case 0x0E: return("OEM Logo"); + case 0x0F: return("ACPI Table"); + case 0x10: return("ACPI AML"); + case 0x11: return("P6 Microcode"); + case 0x12: return("Configuration"); + case 0x13: return("DMI Code"); + case 0x14: return("System Health"); + + case 0x15: return("Memory Sizing"); + case 0x16: return("Memory Test"); + case 0x17: return("Debug"); + case 0x18: return("ADM (Display MGR)"); + case 0x19: return("ADM Font"); + case 0x1A: return("Small Logo"); + case 0x1B: return("SLAB"); + + case 0x20: return("PCI AddOn ROM"); + case 0x21: return("Multilanguage"); + case 0x22: return("UserDefined"); + case 0x23: return("ASCII Font"); + case 0x24: return("BIG5 Font"); + case 0x25: return("OEM Logo"); + case 0x2A: return("User ROM"); + case 0x2B: return("PXE Code"); + case 0x2C: return("AMI Font"); + case 0x2E: return("User ROM"); + case 0x2D: return("Battery Refresh"); + + case 0x30: return("Font Database"); + case 0x31: return("OEM Logo Data"); + case 0x32: return("Graphic Logo Code"); + case 0x33: return("Graphic Logo Data"); + case 0x34: return("Action Logo Code"); + case 0x35: return("Action Logo Data"); + case 0x36: return("Virus"); + case 0x37: return("Online Menu"); + + case 0x38: return("Lang1 as ROM"); + case 0x39: return("Lang2 as ROM"); + case 0x3A: return("Lang3 as ROM"); + + case 0x70: return("OSD Bitmaps"); + + default: return("User-Defined ;)"); + + } +} + +byte StrLen(byte *Str){ int i = 0; while( *(Str+i) != 0x0 ) i++; return(i); }; +byte StrCmp(byte *Dst, byte *Src) + { + byte i; + for( i = 0; i <= StrLen(Src); i++ ) + if( Dst[i] != Src[i] ) return(1); + return(0); + } + + +byte *GetFullDate(byte *mon, byte *day, byte *year) + { + byte *Months[]={"", + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December"}; + byte Buf[20]; + sprintf(Buf,"%2.2s",year); + + if((atoi(Buf)>=0) && (atoi(Buf)<70)) sprintf(Buf,"%.2s %s %s%.2s",day,Months[atoi(mon)],"20",year); + else sprintf(Buf,"%.2s %s %s%.2s",day,Months[atoi(mon)],"19",year); + + return(Buf); + } + +/*--------------------------------- + FindHook +----------------------------------*/ + +dword FoundAt(FILE *ptx, byte *Buf, byte *Pattern, dword BLOCK_LEN) +{ + + dword i, Ret; + word Len; + Len = StrLen(Pattern); + for(i=0;i<BLOCK_LEN-0x80;i++){ + if(memcmp(Buf+i,Pattern,Len)==0) + { + Ret = ftell(ptx)-(BLOCK_LEN-i); + return(Ret); + } + } + return 0; +} + +/*--------------------------------- + Xtract95 +----------------------------------*/ +byte Xtract95(FILE *ptx, byte Action, dword ConstOff, dword Offset, byte* fname) + { + + FILE *pto; + interfacing interface; + byte PartTotal = 0; + PARTTag part; + byte Buf[64]; + byte MyDirName[64] = "--DECO--"; + dword i; + byte sLen = 0; + + byte doDir = 0; + /* + For the case of multiple 0x20 modules + */ + byte Multiple = 0, j = 0; + + + sLen = StrLen(fname); + for ( i = sLen; i > 0; i-- ) + { + if( *(fname + i) == '/' || *(fname + i ) == '\\' ) { i++; break; } + } + + memcpy(MyDirName, (fname + i), sLen - i); + for ( i = 0; i < StrLen(MyDirName); i++ ) + if (MyDirName[i] == '.' ) MyDirName[i] = '\x0'; + + sprintf(MyDirName, "%s.---", MyDirName); + printf("\nDirName\t\t: %s", MyDirName); + + if((Action & 0x80) && (Action & 0x10)) + { + doDir = 1; + if(!mkdir(MyDirName, 0755)) + printf("\nOperation mkdir() is permitted"); + else printf("\nOperation mkdir() isn't permitted. Directory already exist?"); + } + + Action = ( Action & 0x7F ); + + printf("\n" + "+------------------------------------------------------------------------------+\n" + "| Class.Instance (Name) Packed ---> Expanded Compression Offset |\n" + "+------------------------------------------------------------------------------+\n" + ); + + while((part.PrePartLo!=0xFFFF || part.PrePartHi!=0xFFFF) && PartTotal<0x80) + { + fseek(ptx, Offset-ConstOff, 0); + fread(&part,1,sizeof(part),ptx); + PartTotal++; + + switch(Action){ + + case List: + +printf("\n %.2X %.2i (%17.17s) %5.5lX (%6.5lu) => %5.5lX (%6.5lu) %.2s %5.5lXh", + part.PartID, + PartTotal, + GetModuleName(part.PartID), + (part.IsComprs!=0x80)?(part.ROMSize):(part.CSize), + (part.IsComprs!=0x80)?(part.ROMSize):(part.CSize), + (part.IsComprs!=0x80)?(part.ExpSize):(part.CSize), + (part.IsComprs!=0x80)?(part.ExpSize):(part.CSize), + (part.IsComprs!=0x80)?(IDSign):(" "), + + Offset-ConstOff + ); + + break; + + case Xtract: + /* Xtracting Part */ + + if (part.PartID == 0x20) + { + if(doDir) sprintf(Buf, "%s/amipci_%.2X.%.2X", MyDirName, Multiple++, part.PartID); + else sprintf(Buf, "amipci_%.2X.%.2X", Multiple++, part.PartID); + } else + { + if(doDir) sprintf(Buf, "%s/amibody.%.2x", MyDirName, part.PartID); + else sprintf(Buf,"amibody.%.2x", part.PartID); + } + + if((pto = fopen(Buf,"wb")) == NULL) { + printf("\nFile %s I/O error..Exit",Buf); + exit(1); + } + + interface.infile = ptx; + interface.outfile = pto; + interface.original = part.ExpSize ; + interface.packed = part.ROMSize; + + interface.dicbit = 13; + interface.method = 5; + + if(part.IsComprs!=0x80) + decode(interface); + else + { + fseek(ptx, -8L, 1); + for(i=0;i<part.CSize;i++) { + fread(&Buf[0],1,1,ptx); + fwrite(&Buf[0],1,1,pto); + }; + } + fclose(pto); + break; + /* End of Xtract */ + + } + + Offset = ((dword)part.PrePartHi << 4) + (dword)part.PrePartLo; + } + + return (PartTotal); + + } + +/*--------------------------------- + Xtract0725 +----------------------------------*/ +byte Xtract0725(FILE *ptx, byte Action, dword Offset) + { + + BIOS94 b94; + FILE *pto; + interfacing interface; + byte Buf[12]; + byte PartTotal=0; + byte Module=0; + + while((b94.PackLenLo!=0x0000 || b94.RealLenLo!=0x0000) && PartTotal<0x80) + { + fseek(ptx, Offset, 0); + fread(&b94,1,sizeof(b94),ptx); + if(b94.PackLenLo==0x0000 && b94.RealLenLo==0x0000) break; + PartTotal++; + + switch(Action){ + + case List: + break; + + case Xtract: + /* Xtracting Part */ + sprintf(Buf,"amibody.%.2x",Module++); + pto = fopen(Buf,"wb"); + + interface.infile = ptx; + interface.outfile = pto; + + interface.original = b94.RealLenLo; + interface.packed = b94.PackLenLo; + interface.dicbit = 13; + interface.method = 5; + + decode(interface); + fclose(pto); + break; + /* End of Xtract */ + + } + + Offset = Offset + b94.PackLenLo; + + } + printf("\n\nThis Scheme Usually Contains:" + "\n\t%s\n\t%s\n\t%s",RecordList[0],RecordList[1],RecordList[2]); + + return (PartTotal); + + } + +/*--------------------------------- + Xtract1010 +----------------------------------*/ +byte Xtract1010(FILE *ptx, byte Action, dword Offset) + { + + FILE *pto; + word ModsInHead = 0; + word GlobalMods = 0; + PARTTag *Mods94; + BIOS94 ModHead; + word Tmp; + dword i, ii; + interfacing interface; + byte Buf[12]; + byte Module=0; + + fseek(ptx, 0x10, 0); + fread(&ModsInHead,1,sizeof(word),ptx); + GlobalMods = ModsInHead - 1; + + + Mods94 = (PARTTag*)calloc( ModsInHead, sizeof(PARTTag) ); + + for( i = 0;i < ModsInHead; i++ ) + { + fseek(ptx, 0x14 + i*4, 0); + fread(&Tmp,1,sizeof(Tmp),ptx); + if(i==0) { + Mods94[i].RealCS=(0x10000+Tmp); + } else Mods94[i].RealCS=Tmp; + fread(&Tmp,1,sizeof(Tmp),ptx); + Mods94[i].PartID = (Tmp&0xFF); + Mods94[i].IsComprs = ((((Tmp&0x8000)>>15)==1)?(1):(0)); + } + + + switch(Action){ + + case List: + printf("\n\nModules According to HeaderInfo: %i\n",ModsInHead); + for(i=1;i<ModsInHead;i++) + { + fseek(ptx, Mods94[i].RealCS, 0); + fread(&ModHead,1,sizeof(ModHead),ptx); + printf("\n%.2s %.2X (%17.17s) %5.5lX (%5.5lu) => %5.5lX (%5.5lu), %5.5lXh", + (Mods94[i].IsComprs==0)?(IDSign):(" "), + Mods94[i].PartID,(StrCmp(RecordList[Mods94[i].PartID],"")==0)?("UserDefined"):(RecordList[Mods94[i].PartID]), + (Mods94[i].IsComprs==1)?(0x10000-Mods94[i].RealCS):(ModHead.PackLenLo), + (Mods94[i].IsComprs==1)?(0x10000-Mods94[i].RealCS):(ModHead.PackLenLo), + (Mods94[i].IsComprs==1)?(0x10000-Mods94[i].RealCS):(ModHead.RealLenLo), + (Mods94[i].IsComprs==1)?(0x10000-Mods94[i].RealCS):(ModHead.RealLenLo), + Mods94[i].RealCS); + } + + Offset = 0x10000; + while( Offset <= Mods94[0].RealCS ) + { + fseek(ptx, Offset, 0); + fread(&ModHead,1,sizeof(ModHead),ptx); + if( (ModHead.RealLenHi) != 0 && (ModHead.PackLenHi) !=0 ) { + Offset += 0x1000; + if( (ModHead.RealLenHi) == 0xFFFF && (ModHead.PackLenHi) == 0xFFFF && (Offset%0x1000) != 0 ) { + Offset = 0x1000 * ( Offset / 0x1000 ); + continue; + } + continue; + } + + else { + printf("\nNext Module (%i): %5.5X (%5.5u) => %5.5X (%5.5u), %5.5lXh", + GlobalMods, + ModHead.PackLenLo, + ModHead.PackLenLo, + ModHead.RealLenLo, + ModHead.RealLenLo, + Offset); + GlobalMods++; Offset+=ModHead.PackLenLo; + } + } + + break; + + case Xtract: + /* Xtracting Part */ + + for(i=0;i<ModsInHead;i++) + { + fseek(ptx, Mods94[i].RealCS, 0); + fread(&ModHead,1,sizeof(ModHead),ptx); + + sprintf(Buf,"amibody.%.2x",Module++); + pto = fopen(Buf,"wb"); + if(pto == NULL) { printf("\nFile %s I/O Error..Exit"); exit(1); } + + interface.infile = ptx; + interface.outfile = pto; + + interface.original = ModHead.RealLenLo; + interface.packed = ModHead.PackLenLo; + interface.dicbit = 13; + interface.method = 5; + + if(Mods94[i].IsComprs==1) + { + fseek(ptx, -8L, 1); + for(ii=0;ii<(0x10000-(dword)Mods94[i].RealCS);ii++) { + fread(&Buf[0],1,1,ptx); + fwrite(&Buf[0],1,1,pto); + }; + } else decode(interface); + fclose(pto); + } + + /*------- Hidden Parts -----------*/ + + Offset = 0x10000; + while(Offset<Mods94[0].RealCS) + { + fseek(ptx, Offset, 0); + fread(&ModHead,1,sizeof(ModHead),ptx); + if((ModHead.RealLenHi)!=0 && (ModHead.PackLenHi)!=0) { + Offset+=0x1000; + if((ModHead.RealLenHi)==0xFFFF && (ModHead.PackLenHi)==0xFFFF && (Offset%0x1000)!=0) { + Offset=0x1000*(Offset/0x1000); + continue; + } + continue; + } + + else { + GlobalMods++; + sprintf(Buf,"amibody.%.2x",Module++); + pto = fopen(Buf,"wb"); + if(pto == NULL) { printf("\nFile %s I/O Error..Exit"); exit(1); } + + interface.infile = ptx; + interface.outfile = pto; + interface.original = ModHead.RealLenLo; + interface.packed = ModHead.PackLenLo; + interface.dicbit = 13; + interface.method = 5; + + decode(interface); + fclose(pto); + + Offset+=ModHead.PackLenLo; + } + } + + break; + /* End of Xtract */ + + } + + free(Mods94); + printf("\n\nThis Scheme Usually Doesn't Contain Modules Identification"); + + return (GlobalMods); + + } diff --git a/src/amihelp.h b/src/amihelp.h new file mode 100644 index 0000000..6222e4a --- /dev/null +++ b/src/amihelp.h @@ -0,0 +1,77 @@ +/********************************************** +** +** +** Defines for AmiHelp +** +** +***********************************************/ + +#include <stdio.h> + +byte HelpSystem(byte argc, byte *argv[]) + { + byte x; + byte ID = 0; + + for( x = 1; x < argc; x++ ) + { + if(StrCmp(argv[x],"-h") == 0) + { + printf("\n"SftName" HelpSystem Starting Now!\n"); + printf("\nThis Program Version Number %s",SftVersion); + +#ifndef __LINUX_NOW__ + printf( + "\n"SftName" - Decompressor for AmiBIOSes only.\n" + "\tSupported formats: AMIBIOS'94, AMIBIOS'95 and later\n\n" + ""SftName" performs on 386 or better CPU systems\n" + "under control of DOS, Win3.xx, Win9x/NT/2K or DosEmu\n\n" + "Compression schemes include: LZINT\n\n" + "Modules marked with "IDSign" sign are compressed modules\n\n" + "\tBug reports mailto: "SftEMail"\n" + "\t\tCompiled: %s, %s\n",__DATE__,__TIME__); +#else + printf( + "\n"SftName" - Decompressor for AmiBIOSes only.\n" + "\tSupported formats: AMIBIOS'94, AMIBIOS'95 or later\n\n" + ""SftName" performs on 386 or better CPU systems\n" + "under control of LinuxOS\n\n" + "Compression schemes include: LZINT\n\n" + "Modules marked with "IDSign" sign are compressed modules\n\n" + "\tBug reports mailto: "SftEMail"\n" + "\t\tCompiled: %s, %s with \n\t\t%s",__DATE__,__TIME__,__VERSION__); +#endif + + printf("\n"); + return( 0x20 ); + } + if(StrCmp(argv[x], "-x") == 0) (ID = ID ^ 0x10); + if(StrCmp(argv[x], "-l") == 0) (ID = ID ^ 0x01); + if(StrCmp(argv[x], "-d") == 0) (ID = ID ^ 0x80); + } + + return (ID); + return(0); + + } + +void PrintHeader(byte* EOL) + { + printf("\n%c%s%c%s", 0x4, SoftName, 0x4, EOL); + } + +void PrintUsage() + { + PrintHeader(""); + printf("%s",CopyRights); + printf("\n\nUsage: %s <AmiBIOS.BIN> [Options]",SftName); + printf( + "\n" + "\t\tOptions:" + "\n\t\t\t\"-l\" List Bios Structure" + "\n\t\t\t\"-x\" eXtract Bios Modules" + "\n\t\t\t\"-d\" create Directory" + "\n\t\t\t\"-h\" Help statistics" + ); + printf("\n\n\t*%s*\n",Url); + } diff --git a/src/amisoft.h b/src/amisoft.h new file mode 100644 index 0000000..1095831 --- /dev/null +++ b/src/amisoft.h @@ -0,0 +1,18 @@ +/********************************************** +** +** +** Defines for AmiSoft +** +** +***********************************************/ + +#include <stdio.h> +#include "./amiver.h" + +#define SftName "AmiBIOSDeco" +#define SftEMail "Anton Borisov, anton.borisov@gmail.com" + + /********SoftWare*************/ + byte SoftName[] = "-="SftName", version "SftVersion"=-"; + byte CopyRights[] = "\n(C) Anton Borisov, 2000, 2002-2003, 2006. Portions (C) 1999-2000"; + byte Url[] = "Bug-reports direct to "SftEMail; diff --git a/src/amiver.h b/src/amiver.h new file mode 100644 index 0000000..acce9ad --- /dev/null +++ b/src/amiver.h @@ -0,0 +1,17 @@ +/********************************************** +** +** +** Defines for AmiVer +** +** +***********************************************/ + +#include <stdio.h> + +#ifdef __LINUX_NOW__ + #define SftPlatform "Linux" +#else + #define SftPlatform "DOS32" +#endif + +#define SftVersion "0.31e ("SftPlatform")" diff --git a/src/kernel.c b/src/kernel.c new file mode 100644 index 0000000..f447086 --- /dev/null +++ b/src/kernel.c @@ -0,0 +1,342 @@ +/********************************************** +*** +*** +*** These decompression routines based on +*** LZHUFF algo from LHA archiver +*** +*** +***********************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <memory.h> + +#define UCHAR_MAX ((1<<(sizeof(unsigned char)*8))-1) +#define CHAR_BIT 8 + +#define CBIT 9 +#define USHRT_BIT 16 /* (CHAR_BIT * sizeof(ushort)) */ + +#define MAX_DICBIT 13 +#define MAX_DICSIZ (1 << MAX_DICBIT) +#define MATCHBIT 8 +#define MAXMATCH 256 +#define THRESHOLD 3 +#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD) + +#define NP (MAX_DICBIT + 1) +#define NT (USHRT_BIT + 3) +#define PBIT 4 +#define TBIT 5 +#define NPT 0x80 + +unsigned long origsize, compsize; +unsigned short dicbit; +unsigned short maxmatch; +unsigned long count; +unsigned short loc; +unsigned char *text; + +static unsigned short dicsiz; + +static unsigned char subbitbuf, bitcount; + +unsigned short crc, bitbuf; +int prev_char; +long reading_size; + +unsigned short left[2 * NC - 1], right[2 * NC - 1]; +unsigned char c_len[NC], pt_len[NPT]; +unsigned short c_table[4096], c_code[NC], + pt_table[256], pt_code[NPT]; +static unsigned char *buf; +static unsigned short bufsiz; +static unsigned short blocksize; + +FILE *infile, *outfile; + +typedef struct { + FILE *infile; + FILE *outfile; + unsigned long original; + unsigned long packed; + int dicbit; + int method; +} interfacing ; + + +static short c, n, tblsiz, len, depth, maxdepth, avail; +static unsigned short codeword, bit, *tbl; +static unsigned char *blen; + +/****************************************/ +/* mktbl() */ +/****************************************/ +static short mktbl(void) +{ + short i; + + if (len == depth) { + while (++c < n) + if (blen[c] == len) { + i = codeword; codeword += bit; + if (codeword > tblsiz) { printf("\nBad Table!"); exit(1); } + while (i < codeword) tbl[i++] = c; + return c; + } + c = -1; len++; bit >>= 1; + } + depth++; + if (depth < maxdepth) { + (void) mktbl(); (void) mktbl(); + } else if (depth > USHRT_BIT) { + { printf("\nBad Table [2]"); exit(1); } + } else { + if ((i = avail++) >= 2 * n - 1) { printf("\nBad Table [3]"); exit(1); } + left[i] = mktbl(); right[i] = mktbl(); + if (codeword >= tblsiz) { printf("\nBad Table [4]"); exit(1); } + if (depth == maxdepth) tbl[codeword++] = i; + } + depth--; + return i; +} + +/****************************************/ +/* make_table() */ +/****************************************/ +void make_table(short nchar, unsigned char bitlen[], + short tablebits, unsigned short table[]) +{ + n = avail = nchar; blen = bitlen; tbl = table; + tblsiz = 1U << tablebits; bit = tblsiz / 2; + maxdepth = tablebits + 1; + depth = len = 1; c = -1; codeword = 0; + (void) mktbl(); /* left subtree */ + (void) mktbl(); /* right subtree */ + if (codeword != tblsiz) { printf("\nBad Table [5]"); exit(1); } +} + + + +/****************************************/ +/* fillbif() */ +/****************************************/ +void fillbuf(unsigned char n) /* Shift bitbuf n bits left, read n bits */ +{ + while (n > bitcount) { + n -= bitcount; + bitbuf = (bitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount)); + if (compsize != 0) { + compsize--; subbitbuf = (unsigned char) getc(infile); + } else subbitbuf = 0; + bitcount = CHAR_BIT; + } + bitcount -= n; + bitbuf = (bitbuf << n) + (subbitbuf >> (CHAR_BIT - n)); + subbitbuf <<= n; +} + + +/****************************************/ +/* getbits() */ +/****************************************/ +unsigned short getbits(unsigned char n) +{ + unsigned short x; + + x = bitbuf >> (2 * CHAR_BIT - n); fillbuf(n); + return x; +} + +/****************************************/ +/* fwrite_crc() */ +/****************************************/ +void fwrite_crc( unsigned char *p, int n, FILE *fp ) +{ + + if ( fp ) + { + if (fwrite(p, 1, n, fp) < n) + { printf("\nFatal Error"); exit(1); } + } +} + +/****************************************/ +/* init_getbits() */ +/****************************************/ +void init_getbits(void) +{ + bitbuf = 0; subbitbuf = 0; bitcount = 0; + fillbuf(2 * CHAR_BIT); +} + + +/********************************************/ +/************* DECODE ***********************/ + +static void read_pt_len(short nn, short nbit, short i_special) +{ + short i, c, n; + + n = getbits(nbit); + if (n == 0) { + c = getbits(nbit); + for (i = 0; i < nn; i++) pt_len[i] = 0; + for (i = 0; i < 256; i++) pt_table[i] = c; + } else { + i = 0; + while (i < n) { + c = bitbuf >> (16 - 3); + if (c == 7) { + unsigned short mask = 1 << (16 - 4); + while (mask & bitbuf) { mask >>= 1; c++; } + } + fillbuf((c < 7) ? 3 : c - 3); + pt_len[i++] = c; + if (i == i_special) { + c = getbits(2); + while (--c >= 0) pt_len[i++] = 0; + } + } + while (i < nn) pt_len[i++] = 0; + make_table(nn, pt_len, 8, pt_table); + } +} + +static void read_c_len(void) +{ + short i, c, n; + + n = getbits(CBIT); + if (n == 0) { + c = getbits(CBIT); + for (i = 0; i < NC; i++) c_len[i] = 0; + for (i = 0; i < 4096; i++) c_table[i] = c; + } else { + i = 0; + while (i < n) { + c = pt_table[bitbuf >> (16 - 8)]; + if (c >= NT) { + unsigned short mask = 1 << (16 - 9); + do { + if (bitbuf & mask) c = right[c]; + else c = left [c]; + mask >>= 1; + } while (c >= NT); + } + fillbuf(pt_len[c]); + if (c <= 2) { + if (c == 0) c = 1; + else if (c == 1) c = getbits(4) + 3; + else c = getbits(CBIT) + 20; + while (--c >= 0) c_len[i++] = 0; + } else c_len[i++] = c - 2; + } + while (i < NC) c_len[i++] = 0; + make_table(NC, c_len, 12, c_table); + } +} + +unsigned short decode_c_st1(void) +{ + unsigned short j, mask; + + if (blocksize == 0) { + blocksize = getbits(16); + read_pt_len(NT, TBIT, 3); + read_c_len(); + read_pt_len(NP, PBIT, -1); + } + blocksize--; + j = c_table[bitbuf >> 4]; + if (j < NC) fillbuf(c_len[j]); + else { + fillbuf(12); mask = 1 << (16 - 1); + do { + if (bitbuf & mask) j = right[j]; + else j = left [j]; + mask >>= 1; + } while (j >= NC); + fillbuf(c_len[j] - 12); + } + return j; +} + +unsigned short decode_p_st1(void) +{ + unsigned short j, mask; + + j = pt_table[bitbuf >> (16 - 8)]; + if (j < NP) fillbuf(pt_len[j]); + else { + fillbuf(8); mask = 1 << (16 - 1); + do { + if (bitbuf & mask) j = right[j]; + else j = left [j]; + mask >>= 1; + } while (j >= NP); + fillbuf(pt_len[j] - 8); + } + if (j != 0) j = (1 << (j - 1)) + getbits(j - 1); + return j; +} + +void decode_start_st1(void) +{ + init_getbits(); + blocksize = 0; +} + +/********end of decode***********************/ + +void decode(interfacing interface) +{ + int i, j, k, c, dicsiz1, offset; + + infile = interface.infile; + outfile = interface.outfile; + dicbit = interface.dicbit; + origsize = interface.original; + compsize = interface.packed; + crc = 0; + prev_char = -1; + dicsiz = 1 << dicbit; + text = (unsigned char *)malloc(dicsiz); + if (text == NULL) exit( 1 ); + + memset(text, ' ', dicsiz); + decode_start_st1(); + + dicsiz1 = dicsiz - 1; + offset = 0x100 - 3; + count = 0; loc = 0; + while (count < origsize) { + + c= decode_c_st1(); + + if (c <= UCHAR_MAX) { + text[loc++] = c; + if (loc == dicsiz) { + fwrite_crc(text, dicsiz, outfile); + loc = 0; + } + count++; + } else { + j = c - offset; + i = (loc - decode_p_st1() - 1) & dicsiz1; + count += j; + for (k = 0; k < j; k++) { + c = text[(i + k) & dicsiz1]; + text[loc++] = c; + if (loc == dicsiz) { + fwrite_crc(text, dicsiz, outfile); + loc = 0; + } + } + } + } + if (loc != 0) { + fwrite_crc(text, loc, outfile); + } + free(text); +} |