Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

debugdll.c

Go to the documentation of this file.
00001 
00006 #include "../dllkit/dllkit.h"
00007 #include "../usrmsgs.h"
00008 #include "resource.h"
00009 #include "instructions.h"
00010 #include <windows.h>
00011 #include <commctrl.h>
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 
00015 #define ADR(X, Y) (((Y) << 8) + (X))
00016 
00017 #define FN 0x80         
00018 #define FV 0x40         
00019 #define FB 0x10         
00020 #define FD 0x08         
00021 #define FI 0x04         
00022 #define FZ 0x02         
00023 #define FC 0x01         
00026 typedef struct {
00027         UINT PC;                        
00028         unsigned char X;        
00029         unsigned char Y;        
00030         unsigned char A;        
00031         unsigned char P;        
00032         UINT S;                         
00033 } Regs;
00034 
00035 HANDLE hThisModule;
00036 MSGLIST Msgs;
00037 INITDLLSTRUCT info;
00038 
00040 HMENU hMenu;
00042 HMENU hDebugMenu;
00043 
00044 /* ----- begin forward declarations */
00045 
00052 void StartDebug();
00053 
00063 void DisAsm(int lower, int upper, HANDLE fil, int act);
00064 
00065 
00074 void DumpMemHex(HANDLE fil, UINT adr1, UINT adr2);
00075 
00084 void DumpMem(HANDLE fil, UINT adr1, UINT adr2);
00085 
00087 void printhelp();
00088 
00096 HANDLE ofile();
00097 
00105 HANDLE orfile();
00106 
00115 void SetReg(Regs* regs, char* buf);
00116 
00118 void printregs(Regs* regs);
00119 
00128 void printfil(HANDLE fil, char* str);
00129 
00131 void rinterval(UINT* adr1, UINT* adr2);
00132 
00134 UINT rhex(char* msg);
00135 
00137 void mklpstr(char* str);
00138 
00140 void print(char* str);
00141 
00143 void rline(char* str);
00144 
00146 void printact(Regs* regs);
00147 
00148 /* ----- end forward declarations */
00149 BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, 
00150                                           LPVOID lpReserved)
00151 {
00152         hThisModule = hModule;
00153         switch (ul_reason_for_call) {
00154         case DLL_PROCESS_ATTACH:
00155                 CreateMsgList(&Msgs, 1);
00156                 break;
00157         case DLL_PROCESS_DETACH:
00158                 FreeMsgList(Msgs);
00159                 break;
00160         }       
00161     return TRUE;
00162 }
00163 
00164 DLLEXPORT void __cdecl InitDll(INITDLLSTRUCT* ids, INITDLLINFO* idi)
00165 {
00166         TBADDBITMAP tbab;
00167         TBBUTTON tbt;
00168         int index;
00169 
00170         // Add Message list of messages to be catched
00171         AddMessage(Msgs, WM_COMMAND);
00172 
00173         // Copy informations passed to this dll
00174         info.CSMemory = ids->CSMemory;
00175         info.hInst = ids->hInst;
00176         info.hWnd = ids->hWnd;
00177         info.memory = ids->memory;
00178         info.memgetb = ids->memgetb;
00179         info.memsetb = ids->memsetb;
00180         info.optional = ids->optional;
00181         info.hTb = ids->hTb;
00182 
00183         hMenu = GetMenu(info.hWnd);
00184         hDebugMenu = LoadMenu(hThisModule, MAKEINTRESOURCE(IDR_DEBUG));
00185         AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT) hDebugMenu, "&Debug");
00186         DrawMenuBar(info.hWnd);
00187 
00188         tbab.hInst = hThisModule;
00189         tbab.nID = IDR_TB;
00190         index = SendMessage(info.hTb, TB_ADDBITMAP, (WPARAM) 1, 
00191         (WPARAM) &tbab); 
00192         ZeroMemory(&tbt, sizeof(TBBUTTON));
00193         tbt.iBitmap = index;
00194         tbt.idCommand = ID_DEBUG_STARTDEBUG;
00195         tbt.fsState = TBSTATE_ENABLED;
00196         tbt.fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
00197 
00198     SendMessage(info.hTb, TB_ADDBUTTONS, (WPARAM) 1, 
00199         (LPARAM) &tbt); 
00200     SendMessage(info.hTb, TB_AUTOSIZE, 0, 0); 
00201 
00202    
00203         // We don't need any io memory
00204         idi->iolo = 0;
00205         idi->iohi = 0;
00206         idi->msglist = Msgs;
00207 }
00208 
00209 
00210 DLLEXPORT void __cdecl OnMessage(MESSAGEDLLSTRUCT* mds)
00211 {
00212         int wmId, wmEvent;
00213 
00214         switch (mds->message) {
00215         case WM_COMMAND:
00216                 wmId = LOWORD(mds->wParam); 
00217                 wmEvent = HIWORD(mds->wParam); 
00218                 switch (wmId) {
00219                 case ID_DEBUG_STARTDEBUG:
00220                         ShowWindow(info.hWnd, SW_MINIMIZE);
00221                         // Stop CPU
00222                         SendMessage(info.hWnd, PAUSECPU, 0, 0);
00223                         SendMessage(info.hWnd, WAITEND, 0, 0);
00224                         AllocConsole();
00225                         StartDebug();
00226                         FreeConsole();
00227                         ShowWindow(info.hWnd, SW_RESTORE);
00228                         break;
00229                 case ID_DEBUG_ABOUT:
00230                         MessageBox(info.hWnd, "Debug plugin\nAdds some debugging & disassembling features to emu6502\n(c)2002 Petr Cermak", "About", MB_OK);
00231                         break;
00232                 }
00233                 break;
00234         }
00235 
00236 }
00237 
00238 DLLEXPORT void __cdecl IOFunc(UINT adr, unsigned char* data, 
00239                                                                                   iomode mode)
00240 {
00241 }
00242 
00243 void StartDebug()
00244 {
00245     char buf[256]; 
00246         UINT adr1, adr2, val;
00247         DWORD tmp;
00248         Regs* regs = NULL;
00249         HANDLE fil = NULL;
00250 
00251         print("Emu6502 debugger & disassembler\n");
00252         print("To retrieve list of commands, type 'h' and press enter.\n");
00253 
00254         // Retrieve pointer to the Regs struct.
00255         SendMessage(info.hWnd, GETREGS, 0, (LPARAM) &regs);
00256 
00257         if (regs == NULL) {
00258                 print("Cpu plugin not running!\nDebugging not available.\nPress Enter key to return.\n");
00259                 rline(buf);
00260                 return;
00261         }
00262 
00263         do {
00264                 print("\n");
00265                 print("> ");
00266                 rline(buf);
00267                 switch (buf[0]) {
00268                 case 'H':
00269                 case 'h':
00270                         printhelp();
00271                         break;
00272                 case 'D':
00273                 case 'd':
00274                         print("Disassemble\n");
00275                         fil = NULL;
00276                         rinterval(&adr1, &adr2);
00277                         if (buf[1] == 'f') {
00278                                 fil = ofile();
00279                                 if (fil == NULL) {
00280                                         break;
00281                                 }
00282                         }
00283                         DisAsm(adr1, adr2, fil, -1);
00284                         if (fil != NULL) {
00285                                 CloseHandle(fil);
00286                         }
00287                         break;
00288                 case 'M':
00289                 case 'm':
00290                         fil = NULL;
00291                         if (buf[1] == 'f' || buf[1] == 'F') {
00292                                 rinterval(&adr1, &adr2);
00293                                 if (buf[2] == 'h' || buf[2] == 'H') {
00294                                         fil = ofile();
00295                                         if (fil == NULL) {
00296                                                 break;
00297                                         }
00298                                         DumpMemHex(fil, adr1, adr2);
00299                                 }
00300                                 else {
00301                                         fil = ofile();
00302                                         if (fil == NULL) {
00303                                                 break;
00304                                         }
00305                                         DumpMem(fil, adr1, adr2);
00306                                 }       
00307                                 CloseHandle(fil);
00308                         }
00309                         else if (buf[1] == 's' || buf[1] == 'S'){
00310                                 if(buf[2] == 'f' || buf[2] == 'F'){
00311                                         do {
00312                                                 adr1 = rhex("From addr.: ");
00313                                         } while (adr1 > 0xFFFF);
00314                                         fil = orfile();
00315                                         if (fil == NULL) {
00316                                                 break;
00317                                         }
00318                                         adr2 = GetFileSize(fil, NULL);
00319                                         if (adr1 + adr2 - 1 > 0xFFFF) {
00320                                                 print("Given address and size overreach the $ffff boundary\n");
00321                                                 CloseHandle(fil);
00322                                                 break;
00323                                         }
00324                                         if (!ReadFile(fil, info.memory + adr1, adr2, &tmp, NULL)) {
00325                                                 print("Error reading file\n");
00326                                                 break;
00327                                         }
00328                                 } 
00329                                 else {
00330                                         rinterval(&adr1, &adr2);
00331                                         do {
00332                                                 val = rhex("Value: ");
00333                                         } while (val > 0xFF);
00334                                         for (tmp = adr1; tmp <= adr2; tmp++) {
00335                                                 (*info.memsetb)(tmp, (unsigned char) val);
00336                                         }
00337                                 }
00338                         }
00339                         else {
00340                                 rinterval(&adr1, &adr2);
00341                                 DumpMemHex(fil, adr1, adr2);
00342                         }
00343                         break;
00344                 case 'R':
00345                 case 'r':
00346                         printregs(regs);
00347                         break;
00348                 case 'A':
00349                 case 'a':
00350                         printact(regs);
00351                         break;
00352                 case 'N':
00353                 case 'n':
00354                         SendMessage(info.hWnd, ISTEP, 0, (LPARAM) &adr1);
00355                         printact(regs);
00356                         sprintf(buf, "Instruction took %d cycles\n", adr1);
00357                         print(buf);
00358                         break;
00359                 case 'I':
00360                 case 'i':
00361                         switch(buf[1]) {
00362                         case 'I':
00363                         case 'i':
00364                                 print("IRQ\n");
00365                                 (*info.memsetb)(IRQID, 254);
00366                                 SendMessage(info.hWnd, IRQD, 0, 0);
00367                                 printact(regs);
00368                                 break;
00369                         case 'N':
00370                         case 'n':
00371                                 print("NMI\n");
00372                                 (*info.memsetb)(NMIID, 254);
00373                                 SendMessage(info.hWnd, NMID, 0, 0);
00374                                 printact(regs);
00375                                 break;
00376                         case 'R':
00377                         case 'r':
00378                                 print("RESET\n");
00379                                 (*info.memsetb)(RESETID, 254);
00380                                 SendMessage(info.hWnd, RESETD, 0, 0);
00381                                 printact(regs);
00382                                 break;
00383                         default:
00384                                 print("Unknown interrupt name\n");
00385                                 break;
00386                         }
00387                         break;
00388                 case 'S':
00389                 case 's':
00390                         SetReg(regs, buf);
00391                         break;
00392                 case 'Q':
00393                 case 'q':
00394                         break;
00395                 default:
00396                         print("Unknown command, type 'h' for help\n");
00397                         break;
00398                 }
00399         } while (buf[0] != 'q');
00400 }
00401 
00402 void SetReg(Regs* regs, char* buf)
00403 {
00404         UINT adr1;
00405         BOOL ok = FALSE;
00406         
00407         if (buf[1] != 'f' && buf[1] != 'F') {
00408                 printregs(regs);
00409         }
00410 
00411         do {
00412                 ok = FALSE;
00413                 switch(buf[1]) {
00414                 case 'A':
00415                 case 'a':
00416                         adr1 = rhex("A: ");
00417                         if (adr1 <= 255) {
00418                                 ok = TRUE;
00419                                 regs->A = adr1;
00420                         }
00421                         break;
00422                 case 'X':
00423                 case 'x':
00424                         adr1 = rhex("X: ");
00425                         if (adr1 <= 255) {
00426                                 ok = TRUE;
00427                                 regs->X = adr1;
00428                         }
00429                         break;
00430                 case 'Y':
00431                 case 'y':
00432                         adr1 = rhex("Y: ");
00433                         if (adr1 <= 255) {
00434                                 ok = TRUE;
00435                                 regs->Y = adr1;
00436                         }
00437                         break;
00438                 case 'S':
00439                 case 's':
00440                         adr1 = rhex("S: ");
00441                         if (adr1 >= 256 && adr1 <511) {
00442                                 ok = TRUE;
00443                                 regs->A = adr1;
00444                         }
00445                         break;
00446                 case 'P':
00447                 case 'p':
00448                         if (buf[2] == 'c' || buf[2] == 'C') {
00449                                 adr1 = rhex("PC: ");
00450                                 if (adr1 <= 65535) {
00451                                         ok = TRUE;
00452                                         regs->PC = adr1;
00453                                 }
00454                         } 
00455                         else {
00456                                 adr1 = rhex("P: ");
00457                                 if (adr1 <= 255) {
00458                                         ok = TRUE;
00459                                         regs->P = adr1;
00460                                 }
00461                         }
00462                         break;
00463                 case 'F':
00464                 case 'f':
00465                         ok = TRUE;
00466                         switch(buf[2]) {
00467                         case 'N':
00468                         case 'n':
00469                                 regs->P = regs->P ^ FN;
00470                                 break;
00471                         case 'V':
00472                         case 'v':
00473                                 regs->P = regs->P ^ FV;
00474                                 break;
00475                         case 'B':
00476                         case 'b':
00477                                 regs->P = regs->P ^ FB;
00478                                 break;
00479                         case 'D':
00480                         case 'd':
00481                                 regs->P = regs->P ^ FD;
00482                                 break;
00483                         case 'I':
00484                         case 'i':
00485                                 regs->P = regs->P ^ FI;
00486                                 break;
00487                         case 'Z':
00488                         case 'z':
00489                                 regs->P = regs->P ^ FZ;
00490                                 break;
00491                         case 'C':
00492                         case 'c':
00493                                 regs->P = regs->P ^ FC;
00494                                 break;
00495                         default:
00496                                 print("Wrong name of flag\n");
00497                                 break;
00498                         }
00499                         break;
00500                 default:
00501                         print("Wrong name of register\n");
00502                         ok = TRUE;
00503                         break;
00504                 }
00505         } while (ok == FALSE);
00506         printregs(regs);
00507 }
00508 
00509 
00510 void DisAsm(int lower, int upper, HANDLE fil, int act)
00511 {
00512         int adr = lower;
00513         int tmp;
00514         unsigned char instr, op1, op2;
00515         char buf[20];
00516 
00517         while (adr <= upper) {
00518                 instr = (*info.memgetb)(adr);
00519                 if (act == adr) {
00520                         printfil(fil, ">>> ");
00521                 }
00522                 sprintf(buf, "%04x\t", adr);
00523                 printfil(fil, buf);
00524                 printfil(fil, INSTRUCTIONS[instr].name);
00525 
00526                 switch (INSTRUCTIONS[instr].aType) {
00527                 case IMPL:
00528                         break;
00529                 case ACC:
00530                         printfil(fil, " A");
00531                         break;
00532                 case IMM:
00533                         printfil(fil, " #$");
00534                         op1 = (*info.memgetb)(adr + 1);
00535                         sprintf(buf, "%02x", op1);
00536                         printfil(fil, buf);
00537                         break;
00538                 case ABS:
00539                         printfil(fil, " $");
00540                         op1 = (*info.memgetb)(adr + 1);
00541                         op2 = (*info.memgetb)(adr + 2);
00542                         sprintf(buf, "%04x", ADR(op1, op2));
00543                         printfil(fil, buf);
00544                         break;
00545                 case ABSX:
00546                         printfil(fil, " $");
00547                         op1 = (*info.memgetb)(adr + 1);
00548                         op2 = (*info.memgetb)(adr + 2);
00549                         sprintf(buf, "%04x, X", ADR(op1, op2));
00550                         printfil(fil, buf);
00551                         break;
00552                 case ABSY:
00553                         printfil(fil, " $");
00554                         op1 = (*info.memgetb)(adr + 1);
00555                         op2 = (*info.memgetb)(adr + 2);
00556                         sprintf(buf, "%04x, Y", ADR(op1, op2));
00557                         printfil(fil, buf);
00558                         break;
00559                 case ZP:
00560                         printfil(fil, " $");
00561                         op1 = (*info.memgetb)(adr + 1);
00562                         sprintf(buf, "%02x", op1);
00563                         printfil(fil, buf);
00564                         break;
00565                 case ZPX:
00566                         printfil(fil, " $");
00567                         op1 = (*info.memgetb)(adr + 1);
00568                         sprintf(buf, "%02x, X", op1);
00569                         printfil(fil, buf);
00570                         break;
00571                 case ZPY:
00572                         printfil(fil, " $");
00573                         op1 = (*info.memgetb)(adr + 1);
00574                         sprintf(buf, "%02x, Y", op1);
00575                         printfil(fil, buf);
00576                         break;
00577                 case REL:
00578                         op1 = (*info.memgetb)(adr + 1);
00579                         printfil(fil, " $");
00580                         if (op1 > 0x7F) {
00581                                 tmp = adr + 2 - 0x100 + op1;
00582                         }
00583                         else {
00584                                 tmp = adr + 2 + op1;
00585                         }
00586                         sprintf(buf, "%04x", tmp);
00587                         printfil(fil, buf);
00588                         break;
00589                 case IND:
00590                         printfil(fil, " (");
00591                         op1 = (*info.memgetb)(adr + 1);
00592                         op2 = (*info.memgetb)(adr + 2);
00593                         sprintf(buf, "%04x)", ADR(op1, op2));
00594                         printfil(fil, buf);
00595                         break;
00596                 case INDX:
00597                         printfil(fil, " (");
00598                         op1 = (*info.memgetb)(adr + 1);
00599                         sprintf(buf, "%02x, X)", op1);
00600                         printfil(fil, buf);
00601                         break;
00602                 case INDY:
00603                         printfil(fil, " (");
00604                         op1 = (*info.memgetb)(adr + 1);
00605                         sprintf(buf, "%02x), Y", op1);
00606                         printfil(fil, buf);
00607                         break;
00608                 }
00609                 printfil(fil, "\r\n");
00610                 adr += INSTRUCTIONS[instr].len;
00611         }
00612 }
00613 
00614 void printhelp()
00615 {
00616         print("(a)ctual state   --   prints actual state of emulator (registers and disassembled position in memory)\n");
00617         print("(d)isassemble   --   disassembles given range of memory\n");
00618         print("(d)isassemble into (f)ile\n");
00619         print("(i)nterrupt (i)rq   --   raises interrupt request\n");
00620         print("(i)nterrupt (n)mi   --   raises nonmaskable interrupt\n");
00621         print("(i)nterrupt(r)eset   --   raises reset interrupt\n");
00622         print("(h)elp   --   this message\n");
00623         print("(m)emory dump   --   prints memory dump in hex format onto screen\n");
00624         print("(m)emory dump into (f)ile   --   dumps given range of memory into file (binary)\n");
00625         print("(m)emory dump into (f)ile in (h)ex format\n");
00626         print("(m)emory (s)et   --   set given range of memory to specified value\n");
00627         print("(m)emory (s)et from (f)ile   --   load block of memory from file\n");
00628         print("(n)ext instruction   --   executes one instruction\n");
00629         print("(q)uit debugger\n");
00630         print("(r)egisters   --   prints actual state of registers\n");
00631         print("(s)et ([A, X, Y, P, PC, S]) register to given value\n");
00632         print("(s)et (f)lag ([N, V, B, D, I, Z, C])   --   negates given flag\n");
00633         print("Creating commands - example:\n");
00634         print("(m)emory dump\tinto (f)ile in (h)ex format\n");
00635         print("means: > mfh <enter>\n");
00636         print("All values must be in hex format!\n");
00637 }
00638 
00639 void DumpMem(HANDLE fil, UINT adr1, UINT adr2)
00640 {
00641         DWORD tmp;
00642         WriteFile(fil, info.memory + adr1, adr2 - adr1 + 1, &tmp, NULL);
00643 }
00644 
00645 
00646 void DumpMemHex(HANDLE fil, UINT adr1, UINT adr2)
00647 {
00648         UINT i;
00649         char buf[10];
00650         for (i = adr1; i <= adr2; i++) {
00651                 if ((i - adr1) % 20 == 0) {
00652                         sprintf(buf, "\r\n%04x    ", i);
00653                         printfil(fil, buf);
00654                 }
00655                 sprintf(buf, "%02x ", (*info.memgetb)(i));
00656                 printfil(fil, buf);
00657         }
00658 }
00659 
00660 HANDLE orfile()
00661 {
00662         OPENFILENAME ofn;
00663         TCHAR FileName[1024];
00664         HANDLE hFile;
00665 
00666         lstrcpy(FileName, "");
00667         ZeroMemory(&ofn, sizeof(OPENFILENAME));
00668         
00669         ofn.lStructSize = sizeof(OPENFILENAME);
00670         ofn.lpstrFile = FileName;
00671         ofn.hwndOwner = info.hWnd;
00672         ofn.nMaxFile = sizeof(FileName);
00673         ofn.lpstrFilter = 
00674                 TEXT("Pratial memory image files (*.bin;*.img)\0*.bin;*.img\0All Files (*.*)\0*.*\0");
00675         ofn.nFilterIndex = 1;
00676         ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
00677         
00678         ShowWindow(info.hWnd, SW_RESTORE);
00679         if (!GetOpenFileName(&ofn))
00680                 return NULL;
00681         ShowWindow(info.hWnd, SW_MINIMIZE);
00682         
00683         hFile=CreateFile((LPCSTR) FileName, GENERIC_READ, 0,NULL, OPEN_EXISTING, 0, NULL);
00684         if (hFile==INVALID_HANDLE_VALUE) {
00685                 print("Cannot open file\n");
00686                 return NULL;
00687         }
00688         return hFile;
00689 }
00690 
00691 
00692 
00693 HANDLE ofile()
00694 {
00695         OPENFILENAME ofn;
00696         TCHAR FileName[1024];
00697         HANDLE hFile;
00698 
00699         lstrcpy(FileName, "");
00700         ZeroMemory(&ofn, sizeof(OPENFILENAME));
00701         
00702         ofn.lStructSize = sizeof(OPENFILENAME);
00703         ofn.lpstrFile = FileName;
00704         ofn.hwndOwner = info.hWnd;
00705         ofn.nMaxFile = sizeof(FileName);
00706         ofn.lpstrFilter = 
00707                 TEXT("All Files (*.*)\0*.*\0");
00708         ofn.nFilterIndex = 1;
00709         ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
00710         
00711         ShowWindow(info.hWnd, SW_RESTORE);
00712         if (!GetSaveFileName(&ofn)) {
00713                 ShowWindow(info.hWnd, SW_MINIMIZE);
00714                 return NULL;
00715         }
00716         ShowWindow(info.hWnd, SW_MINIMIZE);
00717 
00718         hFile=CreateFile((LPCSTR) FileName, GENERIC_WRITE, 0,NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
00719         if (hFile==INVALID_HANDLE_VALUE) {
00720                 print("Error creating file\n");
00721                 return FALSE;
00722         }
00723         return hFile;
00724 }
00725 
00726 
00727 void printact(Regs* regs)
00728 {
00729         printregs(regs);
00730         print("\n");
00731         DisAsm(regs->PC,
00732                 ((regs->PC + 10) > 0xffff) ? 0xffff : (regs->PC + 10), NULL, regs->PC);
00733 }
00734 
00735 #define GETFLAG(FL)     \
00736         ((regs->P & (FL)) == 0) ? 0 : 1
00737 
00738 void printregs(Regs* regs)
00739 {
00740         char buf[255];
00741         sprintf(buf, "PC = %04x, S = %04x\nA = %02x, X = %02x, Y = %02x\n", 
00742                 regs->PC, regs->S, regs->A, regs->X, regs->Y);
00743         print(buf);
00744         sprintf(buf, "P = %02x: N = %d, V = %d, B = %d, D = %d, I = %d, Z = %d, C = %d\n", 
00745                 regs->P, GETFLAG(FN), GETFLAG(FV), GETFLAG(FB), GETFLAG(FD), GETFLAG(FI), GETFLAG(FZ), GETFLAG(FC));
00746         print(buf);
00747 }
00748 
00749 void rinterval(UINT* adr1, UINT* adr2)
00750 {
00751         do {
00752                 *adr1 = rhex("From addr.: ");
00753                 *adr2 = rhex("To addr.: ");
00754         } while (!(adr1 <= adr2 <= 0xFFFF));
00755 }
00756 
00757 UINT rhex(char* msg)
00758 {
00759         char str[255];
00760         long num;
00761         str[0] = '0';
00762         str[1] = 'x';
00763         do {
00764                 print(msg);
00765                 rline(str + 2);
00766                 print("\n");
00767                 if (str[3] == 13 && str[2] == '0') {
00768                         num = 0;
00769                         break;
00770                 }
00771         } while (!(num = strtoul(str, NULL, 16)));
00772         return (UINT) num;
00773 }
00774 
00775 void mklpstr(char* str)
00776 {
00777         for(; *str != 13; str++)
00778                 ;
00779         *str = '\0';
00780 }
00781 
00782 void printfil(HANDLE fil, char* str)
00783 {
00784         DWORD tmp;
00785         if (fil == NULL) {
00786                 print(str);
00787         }
00788         else {
00789                 WriteFile(fil, str, lstrlen(str), &tmp, NULL);
00790         }
00791 }
00792 
00793 void print(char* str)
00794 {
00795         DWORD tmp;
00796         WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), str, lstrlen(str), &tmp, NULL);
00797 }
00798 
00799 void rline(char* str)
00800 {
00801         DWORD tmp;
00802         ReadFile(GetStdHandle(STD_INPUT_HANDLE), str, 255, &tmp, NULL);
00803 }

Generated on Fri Sep 6 18:32:14 2002 for Emu6502 by doxygen1.2.17