#define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include #include #include #include #include #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] []\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>4; pRom[(i<<1)+1] = byC&0xF; } } else { DWORD i; for (i=0; i>4; } } } else { if (bSwap) { DWORD i; for (i=0; i