// // Serial.cpp : Serial ports operations // #include "stdafx.h" #include #include #include #include "romdump.h" #include "Serial.h" #include "Step2.h" // for Progress control #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define PACKET_START 1 #define PACKET_STOP 13 #define CHR(ch) (((ch)+32)&0xFF) #define NUM(ch) ((ch)-32) static DWORD crc1[16] = { 0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387, 0x8408, 0x9489, 0xA50A, 0xB58B, 0xC60C, 0xD68D, 0xE70E, 0xF78F }; static DWORD crc2[16] = { 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7 }; int Port = 0; char *sPort = "COMx"; HANDLE hCom; BYTE pkt[1024]; BOOL SerialOpen() { BOOL fSuccess; DCB dcb; sPort[3] = Port+'0'; hCom = CreateFile(sPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); if (hCom == INVALID_HANDLE_VALUE) return FALSE; fSuccess = GetCommState(hCom, &dcb); if (!fSuccess) { CloseHandle(hCom); return FALSE; } dcb.BaudRate = 9600; dcb.fBinary = 1; dcb.ByteSize = 8; dcb.Parity = 0; dcb.StopBits = 0; dcb.fDtrControl = 0; dcb.fRtsControl = 0; dcb.fOutX = 1; dcb.fInX = 1; fSuccess = SetCommState(hCom, &dcb); if (!fSuccess) { CloseHandle(hCom); return FALSE; } return TRUE; } void SerialClose() { CloseHandle(hCom); return; } BYTE chk1(BYTE *pkt) { BYTE chk; for (chk=0; *pkt; pkt++) chk += *pkt; return ((chk>>6)+chk)&0x3F; } WORD chk3(BYTE *pkt) { DWORD crc; BYTE c; for (crc = 0; *pkt != '\0'; pkt++) { c = ((BYTE)crc) ^ (*pkt); crc = (crc>>8) ^ (crc1[c>>4] ^ crc2[c&0x0F]); } return (WORD)crc; } BOOL SendPKT(BYTE type, int n, char *d) { DWORD len = strlen(d); pkt[0] = PACKET_START; pkt[1] = CHR((BYTE)len+2+(n?3:1)); pkt[2] = CHR(n); pkt[3] = type; strcpy((char*)(pkt+4),d); len += 4; pkt[len] = 0; if (n) { // 16-bit CRC WORD crc = chk3(pkt+1); pkt[len++] = CHR((crc>>12)&0x0F); pkt[len++] = CHR((crc>>6)&0x3F); pkt[len++] = CHR(crc&0x3F); } else { // 6-bit chksum pkt[len++] = CHR(chk1(pkt+1)); } pkt[len++] = PACKET_STOP; pkt[len] = 0; WriteFile(hCom, pkt, len, &len, NULL); return pkt[len]; } BYTE RecvPKT() { int timeout = 10; DWORD len; pkt[0] = 0; while (timeout--) { ReadFile(hCom, pkt, 1, &len, NULL); if (pkt[0]==1) break; // received a packed ! if (pkt[0]=='0') ASSERT(FALSE); } if (!timeout) return 0; ReadFile(hCom, pkt+1, 3, &len, NULL); len = NUM(pkt[1])-1; ReadFile(hCom, pkt+4, len, &len, NULL); if (pkt[len+3]!=PACKET_STOP) return 0; pkt[len+4] = 0; return pkt[3]; } char *DataPKT(char *data, DWORD *len) { char *p = (char*)(pkt+4), *q; int i, n = NUM(pkt[1])-5, j, l; for (i=0, l=0; i>4) * 24; result = (char*)malloc(len+1); result[len] = 0; l1: SendPKT('I',0,"~* @-#Y3"); t = RecvPKT(); if (t!='Y') // not ACK ? { if (t=='E') return NULL; // ERROR, abort if (t=='N') goto l1; // NAK, resend if (t==0) goto l1; // received nothing, resend ASSERT(FALSE); } SendPKT('C',0,cmd); ReadFile(hCom, result, len, &len, NULL); do t=RecvPKT(); while (t!='E'); Sleep(5); return result; } __inline nib(char c) {return (c<='9')?(c-'0'):(c-'A'+10);} BYTE *DumpRangeBin(CStep2 *dlg,DWORD a, DWORD b) { char buf[32]; DWORD d, c, len; BYTE *res; BYTE t; wsprintf(buf,"##%05lX ##%05lX ROMDump",a,b); dlg->m_Progress.SetRange(0,(b-a)>>4); dlg->m_Progress.SetStep(1); dlg->m_Progress.SetPos(0); res = (BYTE*)malloc(b-a); l1: SendPKT('I',0,"~* @-#Y3"); t = RecvPKT(); if (t!='Y') // not ACK ? { if (t=='E') return NULL; // ERROR, abort if (t=='N') goto l1; // NAK, resend if (t==0) goto l1; // received nothing, resend ASSERT(FALSE); } SendPKT('C',0,buf); for (d=a; dm_Progress.StepIt(); } do t=RecvPKT(); while (t!='E'); Sleep(5); return res; } static WORD wCRC; 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 CheckROM(LPBYTE pRom, UINT uType) { DWORD dwD0, dwD1; WORD wRomCRC; UINT i; DWORD dwBase = 0x00000; UINT nPass = 0; UINT nPasses; switch (uType) { case HP48G: nPasses = 2; break; case HP48S: nPasses = 1; break; default: return TRUE; } for (dwD0=0x00100; dwD0<0x00140; dwD0++) pRom[dwD0]=0; 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) return FALSE; if (++nPass == nPasses) return TRUE; dwBase += 0x80000; goto again; return TRUE; }