emu48-mirror/Sources/Convert/MAIN.C
Gwenhael Le Moine 04a295b23d
2022-07-31: Updated to version 1.65
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
2024-03-20 08:15:25 +01:00

401 lines
8.1 KiB
C

#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#define HP38G 0
#define HP48S 1
#define HP48G 2
LPBYTE pRom;
WORD wCRC;
WORD wType;
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 = (wType != HP48S)?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(LPBYTE 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])));
}
static BOOL IsHP(DWORD dwAddress)
{
char cH = (pRom[dwAddress + 1] << 4) | pRom[dwAddress];
char cP = (pRom[dwAddress + 3] << 4) | pRom[dwAddress + 2];
return cH == 'H' && cP == 'P';
}
UINT main(int argc, char *argv[])
{
HANDLE hFile;
HANDLE hMap;
HANDLE hOut;
LPBYTE pIn;
DWORD dwSizeLo;
BYTE szVersion[16];
UINT i,uLen;
DWORD dwAddress;
DWORD dwAddrOffset = 0x00000;
BOOL bFormatDetected = FALSE;
BOOL bUnpack = FALSE;
BOOL bSwap = FALSE;
BOOL bText = FALSE;
BOOL bDA19 = FALSE;
BOOL bPack = FALSE;
int iArg = 1; // first argument
if (argc < 2 || argc > 4)
{
printf("Usage:\n\t%s [-p] <old-rom-dump> [<new-rom-dump>]\n", argv[0]);
return 1;
}
while (*argv[iArg] == '-') // an option
{
if (strcmp(argv[iArg],"-p") == 0) // option "-p", pack result ROM image
{
bPack = TRUE; // pack target ROM image
--argc; // option is not an argument
}
++iArg; // first file argument
}
pRom = (LPBYTE) malloc(512*1024*2);
if (pRom == NULL)
{
printf("Memory Allocation Failed !");
return 1;
}
hFile = CreateFile(argv[iArg],GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
free(pRom);
printf("Cannot open file %s.\n", argv[iArg]);
return 1;
}
dwSizeLo = GetFileSize(hFile, NULL);
hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hMap == NULL)
{
free(pRom);
CloseHandle(hFile);
puts("CreateFileMapping failed.");
return 1;
}
pIn = (LPBYTE) MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
if (pIn == NULL)
{
free(pRom);
CloseHandle(hMap);
CloseHandle(hFile);
puts("MapViewOfFile failed.\n");
return 1;
}
for (i = 0; i < 2 && !bFormatDetected; ++i)
{
switch (pIn[0+dwAddrOffset])
{
case '0':
if (pIn[1+dwAddrOffset]!='0') break;
if (pIn[2+dwAddrOffset]!='0') break;
if (pIn[3+dwAddrOffset]!='0') break;
if (pIn[4+dwAddrOffset]!='0') break;
if (pIn[5+dwAddrOffset]!=':') break;
bText = TRUE;
bFormatDetected = TRUE;
break;
case 0x23:
bUnpack = TRUE;
bSwap = TRUE;
bFormatDetected = TRUE;
break;
case 0x32:
bUnpack = TRUE;
bFormatDetected = TRUE;
break;
case 0x03:
bSwap = TRUE;
case 0x02:
if (pIn[1+dwAddrOffset] == (bSwap ? 0x02 : 0x03))
{
bFormatDetected = TRUE;
break;
}
bSwap = FALSE;
default:
dwAddrOffset = dwSizeLo / 2;
bDA19 = TRUE;
break;
}
}
if (!bFormatDetected)
{
free(pRom);
UnmapViewOfFile(pIn);
CloseHandle(hMap);
CloseHandle(hFile);
printf("Stopped, unknown format.\n");
return 1;
}
if (bUnpack) printf("Unpacking nibbles.\n");
if (bSwap) printf("Swapping nibbles.\n");
if (bText) printf("Reading text file.\n");
if (bDA19) printf("Swapping banks.\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++)
{
BYTE byC = pIn[(i+dwAddrOffset)&(dwSizeLo-1)];
pRom[(i<<1) ] = byC>>4;
pRom[(i<<1)+1] = byC&0xF;
}
}
else
{
DWORD i;
for (i=0; i<dwSizeLo; i++)
{
BYTE byC = pIn[(i+dwAddrOffset)&(dwSizeLo-1)];
pRom[(i<<1) ] = byC&0xF;
pRom[(i<<1)+1] = byC>>4;
}
}
}
else
{
if (bSwap)
{
DWORD i;
for (i=0; i<dwSizeLo; i+=2)
{
BYTE a, b;
a = pIn[(i+dwAddrOffset)&(dwSizeLo-1)];
b = pIn[(i+1+dwAddrOffset)&(dwSizeLo-1)];
pRom[i] = b;
pRom[i+1] = a;
}
}
else
{
if(bDA19)
{
assert(dwAddrOffset == dwSizeLo/2);
CopyMemory(&pRom[0] , &pIn[dwAddrOffset], dwAddrOffset);
CopyMemory(&pRom[dwAddrOffset], &pIn[0] , dwAddrOffset);
}
else
{
CopyMemory(pRom, pIn, dwSizeLo);
}
}
}
}
UnmapViewOfFile(pIn);
CloseHandle(hMap);
CloseHandle(hFile);
if (bText||bUnpack||bSwap||bDA19)
{
printf("File converted.\n\n");
}
do
{
// HP38G
wType = HP38G;
dwAddress = 0x7FFAF;
uLen = 10;
if (IsHP(dwAddress)) break;
// HP48SX
wType = HP48S;
dwAddress = 0x7FFF0;
uLen = 6;
if (IsHP(dwAddress)) break;
// HP48GX
wType = HP48G;
dwAddress = 0x7FFBF;
uLen = 6;
if (IsHP(dwAddress)) break;
// unknown
uLen = 0;
}
while (0);
printf("ROM Model Detected : HP%c8%c\n",(wType == HP38G)?'3':'4',(wType != HP48S)?'G':'S');
for (i=0; i<uLen; ++i)
{
szVersion[i] = pRom[dwAddress + (i<<1) + 1] << 4;
szVersion[i] |= pRom[dwAddress + (i<<1)];
}
szVersion[i] = 0;
printf("ROM Version : %s\n", szVersion);
ZeroMemory(pRom+0x100, 0x40); // clear IO register area
if (CheckCRC())
{
printf("ROM CRC Test Passed.\n");
}
else
{
printf("ROM CRC Test FAILED !\n");
}
if (argc == 3) // write target file
{
DWORD dwWritten;
// size of target file
DWORD dwRomSize = (wType != HP48S)?(512*1024*2):(256*1024*2);
hOut = CreateFile(argv[iArg+1],GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
free(pRom);
printf("Cannot open file %s.\n", argv[iArg+1]);
return 1;
}
if (bPack) // pack target ROM image
{
LPBYTE pbySrc,pbyDest;
DWORD i;
dwRomSize /= 2; // packed image has half of size
// pack data
pbySrc = pbyDest = pRom;
for (i = 0; i < dwRomSize; i++)
{
*pbyDest = *pbySrc++;
*pbyDest |= *pbySrc++ << 4;
pbyDest++;
}
}
WriteFile(hOut,pRom,dwRomSize,&dwWritten,NULL);
CloseHandle(hOut);
}
free(pRom);
return 0;
}