301 lines
5.6 KiB
C
301 lines
5.6 KiB
C
|
#define WIN32_LEAN_AND_MEAN
|
||
|
#define WIN32_EXTRA_LEAN
|
||
|
#include <windows.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <malloc.h>
|
||
|
|
||
|
HANDLE hFile;
|
||
|
HANDLE hMap;
|
||
|
HANDLE hOut;
|
||
|
LPBYTE pIn;
|
||
|
LPBYTE pRom;
|
||
|
DWORD dwSizeLo, dwSizeHi;
|
||
|
BYTE szVersion[16];
|
||
|
BOOL bUnpack = FALSE;
|
||
|
BOOL bSwap = FALSE;
|
||
|
BOOL bText = FALSE;
|
||
|
DWORD dwWritten;
|
||
|
WORD wCRC;
|
||
|
BOOL bIsGx;
|
||
|
|
||
|
static WORD crc_table[16] =
|
||
|
{
|
||
|
0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387,
|
||
|
0x8408, 0x9489, 0xA50A, 0xB58B, 0xC60C, 0xD68D, 0xE70E, 0xF78F
|
||
|
};
|
||
|
static __inline VOID CRC(BYTE nib)
|
||
|
{
|
||
|
wCRC = (WORD)((wCRC>>4)^crc_table[(wCRC^nib)&0xf]);
|
||
|
}
|
||
|
|
||
|
BOOL CheckCRC()
|
||
|
{
|
||
|
DWORD dwD0, dwD1;
|
||
|
WORD wRomCRC;
|
||
|
UINT i;
|
||
|
DWORD dwBase = 0x00000;
|
||
|
UINT nPass = 0;
|
||
|
UINT nPasses = bIsGx?2:1;
|
||
|
|
||
|
again:
|
||
|
|
||
|
wRomCRC = pRom[dwBase+0x7FFFC]
|
||
|
|(pRom[dwBase+0x7FFFD]<<4)
|
||
|
|(pRom[dwBase+0x7FFFE]<<8)
|
||
|
|(pRom[dwBase+0x7FFFF]<<12);
|
||
|
|
||
|
wCRC = 0x0000;
|
||
|
dwD0 = dwBase + 0x00000;
|
||
|
dwD1 = dwBase + 0x40000;
|
||
|
do
|
||
|
{
|
||
|
for (i=0; i<16; i++) CRC(pRom[dwD0+i]);
|
||
|
for (i=0; i<16; i++) CRC(pRom[dwD1+i]);
|
||
|
dwD0 += 16;
|
||
|
dwD1 += 16;
|
||
|
} while (dwD0&0x3FFFF);
|
||
|
|
||
|
if (wCRC==0xFFFF)
|
||
|
{
|
||
|
printf("CRC%i: %04X Ok\n", nPass, wRomCRC);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("CRC%i: %04X Failed (%04X)\n", nPass, wRomCRC, wCRC);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (++nPass == nPasses) return TRUE;
|
||
|
|
||
|
dwBase += 0x80000;
|
||
|
goto again;
|
||
|
|
||
|
}
|
||
|
|
||
|
static BYTE Asc2Nib(char c)
|
||
|
{
|
||
|
if (c<'0') return 0;
|
||
|
if (c<='9') return c-'0';
|
||
|
if (c<'A') return 0;
|
||
|
if (c<='F') return c-'A'+10;
|
||
|
if (c<'a') return 0;
|
||
|
if (c<='f') return c-'a'+10;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static DWORD Asc2Nib5(LPSTR lpBuf)
|
||
|
{
|
||
|
return (
|
||
|
((DWORD)Asc2Nib(lpBuf[0])<<16)
|
||
|
|((DWORD)Asc2Nib(lpBuf[1])<<12)
|
||
|
|((DWORD)Asc2Nib(lpBuf[2])<<8)
|
||
|
|((DWORD)Asc2Nib(lpBuf[3])<<4)
|
||
|
|((DWORD)Asc2Nib(lpBuf[4])));
|
||
|
}
|
||
|
|
||
|
UINT main(int argc, char *argv[])
|
||
|
{
|
||
|
|
||
|
if ((argc!=2)&&(argc!=3))
|
||
|
{
|
||
|
printf("Usage:\n\t%s <old-rom-dump> [<new-rom-dump>]\n", argv[0]);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
pRom = LocalAlloc(0,1048576);
|
||
|
if (pRom == NULL)
|
||
|
{
|
||
|
printf("Memory Allocation Failed !");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
hFile = CreateFile(argv[1],GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
|
||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
printf("Cannot open file %s.\n", argv[1]);
|
||
|
return 1;
|
||
|
}
|
||
|
dwSizeLo = GetFileSize(hFile, &dwSizeHi);
|
||
|
hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||
|
if (hMap == NULL)
|
||
|
{
|
||
|
CloseHandle(hFile);
|
||
|
puts("CreateFileMapping failed.");
|
||
|
return 1;
|
||
|
}
|
||
|
pIn = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
|
||
|
if (pIn == NULL)
|
||
|
{
|
||
|
CloseHandle(hMap);
|
||
|
CloseHandle(hFile);
|
||
|
puts("MapViewOfFile failed.\n");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
switch (pIn[0])
|
||
|
{
|
||
|
case '0':
|
||
|
if (pIn[1]!='0') break;
|
||
|
if (pIn[2]!='0') break;
|
||
|
if (pIn[3]!='0') break;
|
||
|
if (pIn[4]!='0') break;
|
||
|
if (pIn[5]!=':') break;
|
||
|
bText = TRUE;
|
||
|
break;
|
||
|
case 0x23:
|
||
|
bUnpack = TRUE;
|
||
|
bSwap = TRUE;
|
||
|
break;
|
||
|
case 0x32:
|
||
|
bUnpack = TRUE;
|
||
|
break;
|
||
|
case 0x02:
|
||
|
break;
|
||
|
case 0x03:
|
||
|
if (pIn[1] == 0x02)
|
||
|
{
|
||
|
bSwap = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (bUnpack) printf("Unpacking nibbles.\n");
|
||
|
if (bSwap) printf("Swapping nibbles.\n");
|
||
|
if (bText) printf("Reading text file.\n");
|
||
|
|
||
|
if (bText)
|
||
|
{
|
||
|
DWORD i = 0;
|
||
|
while (i<dwSizeLo)
|
||
|
{
|
||
|
DWORD d = Asc2Nib5(pIn+i);
|
||
|
i+=6;
|
||
|
pRom[d+0x0] = Asc2Nib(pIn[i+0x0]);
|
||
|
pRom[d+0x1] = Asc2Nib(pIn[i+0x1]);
|
||
|
pRom[d+0x2] = Asc2Nib(pIn[i+0x2]);
|
||
|
pRom[d+0x3] = Asc2Nib(pIn[i+0x3]);
|
||
|
pRom[d+0x4] = Asc2Nib(pIn[i+0x4]);
|
||
|
pRom[d+0x5] = Asc2Nib(pIn[i+0x5]);
|
||
|
pRom[d+0x6] = Asc2Nib(pIn[i+0x6]);
|
||
|
pRom[d+0x7] = Asc2Nib(pIn[i+0x7]);
|
||
|
pRom[d+0x8] = Asc2Nib(pIn[i+0x8]);
|
||
|
pRom[d+0x9] = Asc2Nib(pIn[i+0x9]);
|
||
|
pRom[d+0xA] = Asc2Nib(pIn[i+0xA]);
|
||
|
pRom[d+0xB] = Asc2Nib(pIn[i+0xB]);
|
||
|
pRom[d+0xC] = Asc2Nib(pIn[i+0xC]);
|
||
|
pRom[d+0xD] = Asc2Nib(pIn[i+0xD]);
|
||
|
pRom[d+0xE] = Asc2Nib(pIn[i+0xE]);
|
||
|
pRom[d+0xF] = Asc2Nib(pIn[i+0xF]);
|
||
|
i+=16;
|
||
|
while ((i<dwSizeLo)&&((pIn[i]==0x0D)||(pIn[i]==0x0A))) i++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (bUnpack)
|
||
|
{
|
||
|
if (bSwap)
|
||
|
{
|
||
|
DWORD i;
|
||
|
for (i=0; i<dwSizeLo; i++)
|
||
|
{
|
||
|
pRom[(i<<1) ] = pIn[i]>>4;
|
||
|
pRom[(i<<1)+1] = pIn[i]&0xF;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DWORD i;
|
||
|
for (i=0; i<dwSizeLo; i++)
|
||
|
{
|
||
|
pRom[(i<<1) ] = pIn[i]&0xF;
|
||
|
pRom[(i<<1)+1] = pIn[i]>>4;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (bSwap)
|
||
|
{
|
||
|
DWORD i;
|
||
|
for (i=0; i<dwSizeLo; i+=2)
|
||
|
{
|
||
|
BYTE a, b;
|
||
|
a = pIn[i];
|
||
|
b = pIn[i+1];
|
||
|
pRom[i] = a;
|
||
|
pRom[i+1] = b;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CopyMemory(pRom, pIn, dwSizeLo);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UnmapViewOfFile(pIn);
|
||
|
CloseHandle(hMap);
|
||
|
CloseHandle(hFile);
|
||
|
|
||
|
if (bText||bUnpack||bSwap)
|
||
|
{
|
||
|
printf("File converted.");
|
||
|
}
|
||
|
|
||
|
bIsGx = (pRom[0x29] == 0x00);
|
||
|
|
||
|
printf("ROM Model Detected : HP48%c\n", bIsGx?'G':'S');
|
||
|
|
||
|
if (bIsGx)
|
||
|
{
|
||
|
UINT i;
|
||
|
for (i=0; i<6; i++)
|
||
|
{
|
||
|
szVersion[i] = pRom[0x7FFBF + (i<<1) + 1] << 4;
|
||
|
szVersion[i] |= pRom[0x7FFBF + (i<<1) ];
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UINT i;
|
||
|
for (i=0; i<6; i++)
|
||
|
{
|
||
|
szVersion[i] = pRom[0x7FFF0 + (i<<1) + 1] << 4;
|
||
|
szVersion[i] |= pRom[0x7FFF0 + (i<<1) ];
|
||
|
}
|
||
|
}
|
||
|
szVersion[6] = 0;
|
||
|
|
||
|
printf("ROM Version : %s\n", szVersion);
|
||
|
|
||
|
FillMemory(pRom+0x100, 0x40, 0);
|
||
|
|
||
|
if (CheckCRC())
|
||
|
{
|
||
|
printf("ROM CRC Test Passed.\n");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("ROM CRC Test FAILED !\n");
|
||
|
}
|
||
|
|
||
|
if (argc == 3)
|
||
|
{
|
||
|
hOut = CreateFile(argv[2],GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
|
||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
LocalFree(pRom);
|
||
|
printf("Cannot open file %s.\n", argv[2]);
|
||
|
return 1;
|
||
|
}
|
||
|
WriteFile(hOut,pRom,bIsGx?1048576:524288,&dwWritten,NULL);
|
||
|
CloseHandle(hOut);
|
||
|
}
|
||
|
|
||
|
LocalFree(pRom);
|
||
|
|
||
|
return 0;
|
||
|
}
|