Subversion Repositories NedoOS

Rev

Rev 2382 | Blame | Compare with Previous | Last modification | View Log | Download

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <intrz80.h>
  4. #include <stdlib.h>
  5. #include <oscalls.h>
  6. #include <../common/terminal.c>
  7. #include <tcp.h>
  8. #include <osfs.h>
  9. #include <graphic.h>
  10. #include <ctype.h>
  11. #include <math.h>
  12. ///
  13. #define true 1
  14. #define false 0
  15. #define screenHeight 23
  16. #define screenWidth 80
  17.  
  18. unsigned int RBR_THR = 0xf8ef;
  19. unsigned int IER = 0xf9ef;
  20. unsigned int IIR_FCR = 0xfaef;
  21. unsigned int LCR = 0xfbef;
  22. unsigned int MCR = 0xfcef;
  23. unsigned int LSR = 0xfdef;
  24. unsigned int MSR = 0xfeef;
  25. unsigned int SR = 0xffef;
  26. unsigned int divider = 1;
  27. unsigned int comType = 0;
  28. unsigned int espType = 32;
  29. unsigned int netDriver = 0;
  30. unsigned int espRetry = 5;
  31. unsigned long factor, timerok, count = 0;
  32. unsigned int magic = 15;
  33.  
  34. unsigned char uVer[] = "1.6";
  35. unsigned char curPath[128];
  36. unsigned char cmd[512];
  37. unsigned int pageOffsets[128];
  38. unsigned long volumeOffsets[16];
  39. unsigned char crlf[2] = {13, 10};
  40. const unsigned char gotWiFi[] = "WIFI GOT IP";
  41.  
  42. struct sockaddr_in targetadr;
  43. struct readstructure readStruct;
  44. struct sockaddr_in dnsaddress;
  45.  
  46. struct mouseStruct
  47. {
  48.         char lmb;
  49.         char rmb;
  50.         char mmb;
  51.         char wheel;
  52.         char prevWheel;
  53.         char mouseXpos;
  54.         char mouseYpos;
  55.         char prevMouseXpos;
  56.         char prevMouseYpos;
  57.         int cursXpos;
  58.         int cursYpos;
  59.         unsigned int prevMouseButtons;
  60.         char prevMouseMove;
  61.         char oldAtr;
  62.         char classic;
  63.         char divider;
  64. } mouse;
  65.  
  66. struct navigationStruct
  67. {
  68.         unsigned int page;
  69.         unsigned int volume;
  70.         unsigned int maxVolume;
  71.         unsigned int maxPage;
  72.         unsigned int linePage;
  73.         unsigned int lineSelect;
  74.         unsigned int lastLine;
  75.         unsigned int prevLineSelect;
  76.         unsigned int bufPos;
  77.         unsigned int nextBufPos;
  78.         unsigned int history;
  79.         unsigned int saveAs;
  80.         unsigned char fileName[128];
  81. } navi;
  82.  
  83. struct linkStruct
  84. {
  85.         unsigned char type;
  86.         unsigned long size;
  87.         unsigned char nexType;
  88.         unsigned char path[512];
  89.         unsigned char host[300];
  90.         unsigned char prevHost[300];
  91.         unsigned int port;
  92. } link;
  93.  
  94. struct window
  95. {
  96.         unsigned char x;
  97.         unsigned char y;
  98.         unsigned char w;
  99.         unsigned char h;
  100.         unsigned char text;
  101.         unsigned char back;
  102.         unsigned char tittle[80];
  103. } curWin;
  104.  
  105. struct time
  106. {
  107.         unsigned int hours;
  108.         unsigned int minutes;
  109.         unsigned char oldMinutes;
  110.  
  111. } clock;
  112.  
  113. unsigned char nvext[1024];
  114. unsigned char netbuf[31768];
  115. unsigned char heap[2000];
  116.  
  117. void spaces(unsigned char number)
  118. {
  119.         while (number > 0)
  120.         {
  121.                 putchar(' ');
  122.                 number--;
  123.         }
  124. }
  125.  
  126. void waitKey(void)
  127. {
  128.         do
  129.         {
  130.                 YIELD();
  131.         } while (OS_GETKEY() == 0);
  132. }
  133.  
  134. void clearStatus(void)
  135. {
  136.         OS_SETCOLOR(5);
  137.         OS_SETXY(0, 24);
  138.         spaces(79);
  139.         putchar('\r');
  140. }
  141.  
  142. void printTable(void)
  143. {
  144.         unsigned int cycle;
  145.  
  146.         for (cycle = 1; cycle < 256; cycle++)
  147.         {
  148.                 OS_SETCOLOR(7);
  149.                 printf("%03u:", cycle);
  150.                 OS_SETCOLOR(71);
  151.                 putchar(cycle);
  152.                 OS_SETCOLOR(7);
  153.                 printf(" ");
  154.                 if (cycle % 12 == 0)
  155.                 {
  156.                         printf("\r\n");
  157.                 }
  158.         }
  159. }
  160.  
  161. void delay(unsigned long counter)
  162. {
  163.         unsigned long start, finish;
  164.         counter = counter / 20;
  165.         if (counter < 1)
  166.         {
  167.                 counter = 1;
  168.         }
  169.         start = time();
  170.         finish = start + counter;
  171.  
  172.         while (start < finish)
  173.         {
  174.                 start = time();
  175.         }
  176. }
  177.  
  178. ///////////////////////////
  179. #include <../common/esp-com.c>
  180. #include <../common/network.c>
  181. //////////////////////////
  182.  
  183. char readParamFromIni(void)
  184. {
  185.         FILE *fpini;
  186.         unsigned char *count1;
  187.         const char currentNetwork[] = "currentNetwork";
  188.         unsigned char curNet = 0;
  189.  
  190.         OS_GETPATH((unsigned int)&curPath);
  191.         OS_SETSYSDRV();
  192.         OS_CHDIR("/");
  193.         OS_CHDIR("ini");
  194.  
  195.         fpini = OS_OPENHANDLE("network.ini", 0x80);
  196.         if (((int)fpini) & 0xff)
  197.         {
  198.                 clearStatus();
  199.                 printf("network.ini not found.\r\n");
  200.                 getchar();
  201.                 return false;
  202.         }
  203.  
  204.         OS_READHANDLE(netbuf, fpini, sizeof(netbuf) - 1);
  205.         OS_CLOSEHANDLE(fpini);
  206.  
  207.         count1 = strstr(netbuf, currentNetwork);
  208.         if (count1 != NULL)
  209.         {
  210.                 sscanf(count1 + strlen(currentNetwork) + 1, "%u", &curNet);
  211.         }
  212.  
  213.         OS_CHDIR(curPath);
  214.         return curNet;
  215. }
  216.  
  217. void clearNetbuf(void)
  218. {
  219.         unsigned int counter;
  220.         for (counter = 0; counter < sizeof(netbuf); counter++)
  221.         {
  222.                 netbuf[counter] = 0;
  223.         }
  224. }
  225.  
  226. unsigned char saveBuf(unsigned char *fileNamePtr, unsigned char operation, unsigned int sizeOfBuf)
  227. {
  228.  
  229.         FILE *fp2;
  230.         if (operation == 00)
  231.         {
  232.                 fp2 = OS_CREATEHANDLE(fileNamePtr, 0x80);
  233.                 if (((int)fp2) & 0xff)
  234.                 {
  235.                         clearStatus();
  236.                         printf("%s  creating error.", fileNamePtr);
  237.                         waitKey();
  238.                         exit(0);
  239.                 }
  240.                 OS_CLOSEHANDLE(fp2);
  241.                 return 0;
  242.         }
  243.  
  244.         if (operation == 01)
  245.         {
  246.                 long fileSize;
  247.                 fp2 = OS_OPENHANDLE(fileNamePtr, 0x80);
  248.                 if (((int)fp2) & 0xff)
  249.                 {
  250.                         clearStatus();
  251.                         printf("%s", fileNamePtr);
  252.                         printf(" opening error. ");
  253.                         waitKey();
  254.                         exit(0);
  255.                 }
  256.                 fileSize = OS_GETFILESIZE(fp2);
  257.                 OS_SEEKHANDLE(fp2, fileSize);
  258.                 OS_WRITEHANDLE(netbuf, fp2, sizeOfBuf);
  259.                 OS_CLOSEHANDLE(fp2);
  260.                 return 0;
  261.         }
  262.  
  263.         if (operation == 02)
  264.         {
  265.                 OS_CLOSEHANDLE(fp2);
  266.                 return 0;
  267.         }
  268.         return 0;
  269. }
  270.  
  271. void drawClock(void)
  272. {
  273.         unsigned long dosTime;
  274.         dosTime = OS_GETTIME();
  275.         clock.hours = dosTime >> 11 & 31;        // 0b00011111
  276.         clock.minutes = (dosTime >> 5) & 63; // 0b00111111
  277.  
  278.         if (clock.minutes != clock.oldMinutes)
  279.         {
  280.                 clock.oldMinutes = clock.minutes;
  281.                 OS_SETCOLOR(207);
  282.                 OS_SETXY(73, 0);
  283.                 printf("[%02u:%02u]", clock.hours, clock.minutes);
  284.         }
  285. }
  286.  
  287. void mainWinDraw(void)
  288. {
  289.         OS_SETCOLOR(207);
  290.         OS_SETXY(0, 0);
  291.         spaces(80);
  292.         OS_SETXY(0, 0);
  293.         printf("NedoGopher %s", uVer);
  294.  
  295.         OS_SETXY(39 - strlen(link.host) / 2, 0);
  296.         printf("%s", link.host);
  297.  
  298.         OS_SETXY(55, 0);
  299.  
  300.         if (netDriver)
  301.         {
  302.                 printf("[ESP-COM]");
  303.         }
  304.         else
  305.         {
  306.                 printf("[NEDONET]");
  307.         }
  308.         OS_SETXY(64, 0);
  309.         if (navi.saveAs)
  310.         {
  311.                 printf("[Save As]");
  312.         }
  313.         else
  314.         {
  315.                 printf("[Play It]");
  316.         }
  317.  
  318.         clock.oldMinutes = 255;
  319.         drawClock();
  320. }
  321.  
  322. void initMouse(void)
  323. {
  324.         unsigned long mouseRaw;
  325.         unsigned int mouseButtons;
  326.         mouseRaw = OS_GETMOUSE();
  327.         mouseButtons = mouseRaw;
  328.         mouse.wheel = (mouseButtons >> 4) & 15;
  329.         mouse.prevWheel = mouse.wheel;
  330.         mouse.classic = 0;
  331. }
  332.  
  333. unsigned char OS_SHELL(const char *command)
  334. {
  335.         unsigned char fileName[] = "term.com";
  336.         unsigned char appCmd[128] = "term.com ";
  337.         unsigned int shellSize, loop;
  338.         unsigned char pgbak;
  339.         union APP_PAGES shell_pg;
  340.         union APP_PAGES main_pg;
  341.         FILE *fp3;
  342.         main_pg.l = OS_GETMAINPAGES();
  343.         pgbak = main_pg.pgs.window_3;
  344.  
  345.         OS_GETPATH((unsigned int)&curPath);
  346.         OS_SETSYSDRV();
  347.         strcat(appCmd, command);
  348.  
  349.         fp3 = OS_OPENHANDLE(fileName, 0x80);
  350.         if (((int)fp3) & 0xff)
  351.         {
  352.                 clearStatus();
  353.                 printf("%s not found.", fileName);
  354.                 waitKey();
  355.                 exit(0);
  356.         }
  357.  
  358.         shellSize = OS_GETFILESIZE(fp3);
  359.  
  360.         OS_CHDIR(curPath);
  361.  
  362.         OS_NEWAPP((unsigned int)&shell_pg);
  363.         shell_pg.l = OS_GETAPPMAINPAGES(shell_pg.pgs.pId);
  364.         SETPG32KHIGH(shell_pg.pgs.window_0);
  365.         memcpy((unsigned char *)(0xC080), (unsigned char *)(&appCmd), strlen(appCmd) + 1);
  366.  
  367.         loop = 0;
  368.         while (loop < shellSize)
  369.         {
  370.                 unsigned int loaded, adr;
  371.                 loaded = OS_READHANDLE(cmd, fp3, sizeof(cmd) - 1);
  372.                 adr = 0xC100 + loop;
  373.                 memcpy((unsigned char *)(adr), &cmd, loaded);
  374.                 loop = loop + loaded;
  375.         }
  376.         OS_CLOSEHANDLE(fp3);
  377.         SETPG32KHIGH(pgbak);
  378.         OS_RUNAPP(shell_pg.pgs.pId);
  379.         return shell_pg.pgs.pId;
  380. }
  381.  
  382. char loadPageFromDisk(unsigned char *filepath, unsigned int volume)
  383. {
  384.         unsigned int todo = 0;
  385.         unsigned long clean = 0, loaded = 0;
  386.         FILE *fp1;
  387.  
  388.         fp1 = OS_OPENHANDLE(filepath, 0x80);
  389.         if (((int)fp1) & 0xff)
  390.         {
  391.                 clearStatus();
  392.                 printf("%s opening error. ", filepath);
  393.                 return false;
  394.         }
  395.         OS_SEEKHANDLE(fp1, volumeOffsets[volume]);
  396.  
  397.         do
  398.         {
  399.                 if ((sizeof(netbuf) - loaded) < 513)
  400.                 {
  401.                         clearStatus();
  402.                         printf("Файл слишком большой, будет загружаться частями (%ld kb)...", link.size / 1024);
  403.                         break;
  404.                 }
  405.  
  406.                 todo = OS_READHANDLE(netbuf + loaded, fp1, 512);
  407.                 loaded = loaded + todo;
  408.  
  409.         } while (todo != 0 && errno == 0);
  410.         OS_CLOSEHANDLE(fp1);
  411.  
  412.         netbuf[loaded + 1] = 0;
  413.  
  414.         if (todo == 0 && errno == 0)
  415.         {
  416.                 navi.maxVolume = volume;
  417.         }
  418.         volumeOffsets[volume + 1] = volumeOffsets[volume] + loaded;
  419.  
  420.         /*
  421.         clean = loaded + 128;
  422.         do
  423.         {
  424.                 netbuf[loaded] = 0;
  425.                 loaded++;
  426.         } while (loaded < clean);
  427. */
  428.         return true;
  429. }
  430.  
  431. void loadNVext(void)
  432. {
  433.         FILE *nvf;
  434.         unsigned int nvextSize, loop = 0, loaded;
  435.         OS_SETSYSDRV();
  436.         nvf = OS_OPENHANDLE("nv.ext", 0x80);
  437.         if (((int)nvf) & 0xff)
  438.         {
  439.                 clearStatus();
  440.                 printf("nv.ext not found.\r\n");
  441.                 exit(0);
  442.         }
  443.         nvextSize = OS_GETFILESIZE(nvf);
  444.         do
  445.         {
  446.                 loaded = OS_READHANDLE(nvext + loop, nvf, sizeof(nvext) - 1);
  447.                 loop = loop + loaded;
  448.         } while (loop < nvextSize);
  449.  
  450.         OS_CLOSEHANDLE(nvf);
  451.         nvext[loop + 1] = 0;
  452. }
  453.  
  454. void init(void)
  455. {
  456.         targetadr.family = AF_INET;
  457.         targetadr.porth = 00;
  458.         targetadr.portl = 70;
  459.         targetadr.b1 = 0;
  460.         targetadr.b2 = 0;
  461.         targetadr.b3 = 0;
  462.         targetadr.b4 = 0;
  463.         mouse.oldAtr = 79;
  464.         navi.lineSelect = 1;
  465.         navi.prevLineSelect = 2;
  466.         navi.nextBufPos = 0;
  467.         navi.page = 0;
  468.         navi.maxPage = 32767;
  469.         navi.maxVolume = 32767;
  470.         navi.volume = 0;
  471.         volumeOffsets[0] = 0;
  472.         navi.saveAs = true;
  473.         mouse.divider = 0;
  474.         mouse.prevMouseButtons = 0;
  475.         navi.history = 0;
  476.         link.type = '1';
  477.         link.size = 0;
  478.         link.nexType = '1';
  479.         strcpy(link.path, "HOMEPAGE");
  480.         strcpy(link.host, "HOMEPAGE");
  481.         strcpy(link.prevHost, "HOMEPAGE");
  482.         link.port = 70;
  483.         OS_SETSYSDRV();
  484.         OS_DELETE("browser/ng_hist.dat");
  485.         get_dns();
  486.         loadNVext();
  487.         loadEspConfig();
  488.  
  489.         netDriver = readParamFromIni();
  490.         if (netDriver == 1)
  491.         {
  492.                 uart_init(divider);
  493.                 espReBoot();
  494.         }
  495.  
  496.         initMouse();
  497.         clock.oldMinutes = 255;
  498. }
  499. void newPage(void)
  500. {
  501.         navi.page = 0;
  502.         navi.maxPage = 32767;
  503.         navi.maxVolume = 32767;
  504.         navi.linePage = 0;
  505.         navi.lineSelect = 1;
  506.         navi.prevLineSelect = 2;
  507.         navi.bufPos = 0;
  508.         navi.nextBufPos = 0;
  509.         volumeOffsets[0] = 0;
  510.         navi.lastLine = 0;
  511. }
  512.  
  513. void renderType(unsigned char linkType)
  514. {
  515.         OS_SETCOLOR(70);
  516.  
  517.         switch (linkType)
  518.         {
  519.         case 'i':
  520.                 putchar(' ');
  521.                 break;
  522.         case '0':
  523.                 putchar(21); // plain text
  524.                 putchar(' ');
  525.                 break;
  526.         case '1':
  527.                 putchar(16); // directory
  528.                 putchar(' ');
  529.                 break;
  530.         case '3':
  531.                 putchar(15); // error link
  532.                 putchar(' ');
  533.                 break;
  534.         case '5': // Dos zip
  535.                 putchar('Z');
  536.                 putchar(' ');
  537.                 break;
  538.         case '6': // uuencoded file
  539.                 putchar('Z');
  540.                 putchar(' ');
  541.                 break;
  542.         case '7': // search input
  543.                 putchar(253);
  544.                 putchar(' ');
  545.                 break;
  546.         case '8': // Telnet session
  547.                 putchar('T');
  548.                 putchar(' ');
  549.                 break;
  550.         case '9': // binary (pt3/scr)
  551.                 putchar(8);
  552.                 putchar(' ');
  553.                 break;
  554.         case 'g': // gif pic
  555.                 putchar(2);
  556.                 putchar(' ');
  557.                 break;
  558.         case 'I': // image
  559.                 putchar(2);
  560.                 putchar(' ');
  561.                 break;
  562.         case 's': // sound
  563.                 putchar(14);
  564.                 putchar(' ');
  565.                 break;
  566.         case 'h': // html
  567.                 putchar('H');
  568.                 putchar(' ');
  569.                 break;
  570.         default:
  571.                 putchar(linkType);
  572.                 break;
  573.         }
  574.         OS_SETCOLOR(7);
  575. }
  576.  
  577. unsigned int renderPlain(unsigned int bufPos)
  578. {
  579.         unsigned int counter = 0, colCount = 0;
  580.         unsigned int flag = true;
  581.  
  582.         link.type = '0';
  583.  
  584.         OS_CLS(0);
  585.         mainWinDraw();
  586.         OS_SETCOLOR(7);
  587.         OS_SETXY(0, 1);
  588.  
  589.         counter = 0;
  590.         do
  591.         {
  592.                 unsigned int byte;
  593.                 byte = netbuf[bufPos];
  594.                 if (byte == 0)
  595.                 {
  596.                         navi.maxPage = navi.page;
  597.                         return bufPos;
  598.                 }
  599.  
  600.                 if (colCount == 80)
  601.                 {
  602.                         counter++;
  603.                         colCount = 0;
  604.                 }
  605.  
  606.                 if (byte == 0xd)
  607.                 {
  608.                         if (colCount != 80)
  609.                         {
  610.                                 putchar('\r');
  611.                                 flag = true;
  612.                         }
  613.                         else
  614.                         {
  615.                                 flag = false;
  616.                         }
  617.  
  618.                         bufPos++;
  619.                         colCount = 0;
  620.                         continue;
  621.                 }
  622.  
  623.                 if (byte == 0xa)
  624.                 {
  625.                         if (flag)
  626.                         {
  627.                                 putchar('\n');
  628.                         }
  629.  
  630.                         bufPos++;
  631.                         counter++;
  632.                         flag = true;
  633.                         continue;
  634.                 }
  635.  
  636.                 putchar(byte);
  637.  
  638.                 colCount++;
  639.                 bufPos++;
  640.  
  641.         } while (counter < screenHeight);
  642.         return bufPos;
  643. }
  644.  
  645. unsigned int renderPage(unsigned int bufPos)
  646. {
  647.         unsigned char counter = 0, colCount = 0;
  648.         unsigned char byte = 0;
  649.  
  650.         link.type = '1';
  651.  
  652.         OS_CLS(0);
  653.         mainWinDraw();
  654.         OS_SETXY(0, 1);
  655.  
  656.         byte = netbuf[bufPos];
  657.         renderType(byte);
  658.  
  659.         OS_SETCOLOR(7);
  660.         do
  661.         {
  662.                 while (42)
  663.                 {
  664.                         bufPos++;
  665.  
  666.                         byte = netbuf[bufPos];
  667.  
  668.                         if (byte == 9)
  669.                         {
  670.                                 putchar('\r');
  671.                                 putchar('\n');
  672.                                 break;
  673.                         }
  674.  
  675.                         if (byte == 0)
  676.                         {
  677.                                 navi.maxPage = navi.page;
  678.                                 navi.lastLine = counter;
  679.                                 return bufPos;
  680.                         }
  681.                         colCount++;
  682.                         if (colCount < 78)
  683.                         {
  684.                                 putchar(byte);
  685.                         }
  686.                 }
  687.                 while (42)
  688.                 {
  689.                         bufPos++;
  690.                         if (netbuf[bufPos] == 10)
  691.                         {
  692.                                 colCount = 0;
  693.                                 counter++;
  694.                                 bufPos++;
  695.                                 if (netbuf[bufPos] == '.')
  696.                                 {
  697.                                         navi.maxPage = navi.page;
  698.                                         navi.lastLine = counter;
  699.                                         return bufPos;
  700.                                 }
  701.                                 if (counter < screenHeight)
  702.                                 {
  703.                                         renderType(netbuf[bufPos]);
  704.                                 }
  705.                                 break;
  706.                         }
  707.                 }
  708.         } while (counter < screenHeight);
  709.         navi.lastLine = counter;
  710.         return bufPos;
  711. }
  712.  
  713. void reDraw(void)
  714. {
  715.         if (link.type == '0')
  716.         {
  717.                 navi.nextBufPos = renderPlain(pageOffsets[navi.page]);
  718.         }
  719.         else
  720.         {
  721.                 if (link.type == '1')
  722.                 {
  723.                         navi.nextBufPos = renderPage(pageOffsets[navi.page]);
  724.                 }
  725.         }
  726. }
  727.  
  728. void errorBox(struct window w, const char *message)
  729. {
  730.         unsigned char wcount, tempx, tittleStart;
  731.  
  732.         w.h++;
  733.         OS_SETXY(w.x, w.y - 1);
  734.         BDBOX(w.x, w.y, w.w + 1, w.h, w.back, 32);
  735.         OS_SETXY(w.x, w.y);
  736.         OS_SETCOLOR(w.text);
  737.         putchar(201);
  738.         for (wcount = 0; wcount < w.w; wcount++)
  739.         {
  740.                 putchar(205);
  741.         }
  742.         putchar(187);
  743.         OS_SETXY(w.x, w.y + w.h);
  744.         putchar(200);
  745.         for (wcount = 0; wcount < w.w; wcount++)
  746.         {
  747.                 putchar(205);
  748.         }
  749.         putchar(188);
  750.  
  751.         tempx = w.x + w.w + 1;
  752.         for (wcount = 1; wcount < w.h; wcount++)
  753.         {
  754.                 OS_SETXY(w.x, w.y + wcount);
  755.                 putchar(186);
  756.                 OS_SETXY(tempx, w.y + wcount);
  757.                 putchar(186);
  758.         }
  759.         tittleStart = w.x + (w.w / 2) - (strlen(w.tittle) / 2);
  760.         OS_SETXY(tittleStart, w.y);
  761.         printf("[%s]", w.tittle);
  762.         OS_SETXY(w.x + 1, w.y + 1);
  763.         OS_SETCOLOR(w.back);
  764.         tittleStart = w.x + (w.w / 2) - (strlen(message) / 2);
  765.         OS_SETXY(tittleStart, w.y + 1);
  766.         printf("%s", message);
  767. }
  768.  
  769. unsigned char inputBox(struct window w, const char *prefilled)
  770. {
  771.         unsigned char wcount, tempx, tittleStart;
  772.         unsigned char byte, counter;
  773.         w.h++;
  774.         OS_SETXY(w.x, w.y - 1);
  775.         BDBOX(w.x, w.y, w.w + 1, w.h, w.back, 32);
  776.         OS_SETXY(w.x, w.y);
  777.         OS_SETCOLOR(w.text);
  778.         putchar(201);
  779.         for (wcount = 0; wcount < w.w; wcount++)
  780.         {
  781.                 putchar(205);
  782.         }
  783.         putchar(187);
  784.         OS_SETXY(w.x, w.y + w.h);
  785.         putchar(200);
  786.         for (wcount = 0; wcount < w.w; wcount++)
  787.         {
  788.                 putchar(205);
  789.         }
  790.         putchar(188);
  791.  
  792.         tempx = w.x + w.w + 1;
  793.         for (wcount = 1; wcount < w.h; wcount++)
  794.         {
  795.                 OS_SETXY(w.x, w.y + wcount);
  796.                 putchar(186);
  797.                 OS_SETXY(tempx, w.y + wcount);
  798.                 putchar(186);
  799.         }
  800.         tittleStart = w.x + (w.w / 2) - (strlen(w.tittle) / 2);
  801.         OS_SETXY(tittleStart, w.y);
  802.         printf("[%s]", w.tittle);
  803.         OS_SETXY(w.x + 1, w.y + 1);
  804.         OS_SETCOLOR(w.back);
  805.         putchar(219);
  806.  
  807.         cmd[0] = 0;
  808.  
  809.         counter = strlen(prefilled);
  810.         if (counter != 0)
  811.         {
  812.                 strcpy(cmd, prefilled);
  813.                 goto skipKeys;
  814.         }
  815.  
  816.         do
  817.         {
  818.                 byte = OS_GETKEY();
  819.                 if (byte != 0)
  820.                 {
  821.                         switch (byte)
  822.                         {
  823.                         case 0x08:
  824.                                 if (counter > 0)
  825.                                 {
  826.                                         counter--;
  827.                                         cmd[counter] = 0;
  828.                                 }
  829.                                 break;
  830.                         case 0x0d:
  831.  
  832.                                 if (counter == 0)
  833.                                 {
  834.                                         return false;
  835.                                 }
  836.                                 else
  837.                                 {
  838.                                         return true;
  839.                                 }
  840.  
  841.                         case 31:
  842.                                 break;
  843.                         case 250:
  844.                                 break;
  845.                         case 249:
  846.                                 break;
  847.                         case 248:
  848.                                 break;
  849.                         case 251: // Right
  850.                                 break;
  851.                         case 252: // Del
  852.                                 OS_SETXY(w.x + 1, w.y + 1);
  853.                                 spaces(counter + 1);
  854.                                 cmd[0] = 0;
  855.                                 counter = 0;
  856.                                 break;
  857.                         case 27:
  858.                                 cmd[0] = 0;
  859.                                 return false;
  860.                         default:
  861.                                 if (counter < w.w - 1)
  862.                                 {
  863.                                         cmd[counter] = byte;
  864.                                         counter++;
  865.                                         cmd[counter] = 0;
  866.                                 }
  867.                                 break;
  868.                         }
  869.                 skipKeys:
  870.                         OS_SETXY(w.x + 1, w.y + 1);
  871.                         printf("%s", cmd);
  872.                         putchar(219);
  873.                         if (byte == 0x08)
  874.                         {
  875.                                 putchar(' ');
  876.                         }
  877.                 }
  878.                 YIELD();
  879.         } while (42);
  880.         return false;
  881. }
  882.  
  883. void pusHistory(void)
  884. {
  885.         FILE *hf;
  886.         unsigned int structSize;
  887.         unsigned long filePos;
  888.         if (link.type == '7')
  889.         {
  890.                 return;
  891.         }
  892.  
  893.         navi.history++;
  894.         structSize = sizeof(struct linkStruct);
  895.         filePos = structSize * (navi.history - 1);
  896.  
  897.         OS_SETSYSDRV();
  898.  
  899.         hf = OS_CREATEHANDLE("browser/ng_hist.dat", 0x80);
  900.         if (((int)hf) & 0xff)
  901.         {
  902.                 clearStatus();
  903.                 printf("browser/ng_hist.dat creating error.");
  904.                 exit(0);
  905.         }
  906.         OS_CLOSEHANDLE(hf);
  907.  
  908.         hf = OS_OPENHANDLE("browser/ng_hist.dat", 0x80);
  909.         if (((int)hf) & 0xff)
  910.         {
  911.                 clearStatus();
  912.                 printf("browser/ng_hist.dat opening error.");
  913.                 exit(0);
  914.         }
  915.         OS_SEEKHANDLE(hf, filePos);
  916.         memcpy(&heap, &link, structSize);
  917.         OS_WRITEHANDLE(heap, hf, structSize);
  918.         OS_CLOSEHANDLE(hf);
  919. }
  920.  
  921. void popHistory(void)
  922. {
  923.         FILE *hf;
  924.         unsigned int structSize;
  925.         unsigned long filePos;
  926.         navi.history--;
  927.         structSize = sizeof(struct linkStruct);
  928.         filePos = structSize * (navi.history - 1);
  929.         OS_SETSYSDRV();
  930.         hf = OS_OPENHANDLE("browser/ng_hist.dat", 0x80);
  931.         if (((int)hf) & 0xff)
  932.         {
  933.                 clearStatus();
  934.                 printf("browser/ng_hist.dat opening error.");
  935.                 exit(0);
  936.         }
  937.  
  938.         OS_SEEKHANDLE(hf, filePos);
  939.         OS_READHANDLE(netbuf, hf, structSize);
  940.  
  941.         memcpy(&link, netbuf, structSize);
  942. }
  943.  
  944. void goHome(char backSpace)
  945. {
  946.         OS_SETSYSDRV();
  947.         if (loadPageFromDisk("browser/nedogoph.gph", 0))
  948.         {
  949.                 newPage();
  950.                 link.type = '1';
  951.                 strcpy(link.host, "HOMEPAGE");
  952.                 if (!backSpace)
  953.                 {
  954.                         pusHistory();
  955.                 }
  956.                 navi.nextBufPos = renderPage(navi.nextBufPos);
  957.         }
  958.         else
  959.         {
  960.                 newPage();
  961.                 clearNetbuf();
  962.                 OS_CLS(0);
  963.                 mainWinDraw();
  964.         }
  965. }
  966.  
  967. void errNoConnect(void)
  968. {
  969.  
  970.         if (strcmp(link.host, "HOMEPAGE") == 0)
  971.         {
  972.                 goHome(false);
  973.                 return;
  974.         }
  975.  
  976.         curWin.w = 50;
  977.         curWin.x = 80 / 2 - curWin.w / 2 - 1;
  978.         curWin.y = 10;
  979.         curWin.h = 1;
  980.         curWin.text = 215;
  981.         curWin.back = 215;
  982.         strcpy(curWin.tittle, "Ошибка открытия страницы");
  983.         strcpy(cmd, "Нет соединения с ");
  984.         strcat(cmd, link.host);
  985.         errorBox(curWin, cmd);
  986.         strcpy(link.host, link.prevHost);
  987.         waitKey();
  988.  
  989.         switch (link.type)
  990.         {
  991.         case '0':
  992.                 OS_SETSYSDRV();
  993.                 loadPageFromDisk("browser/current.txt", 0);
  994.                 navi.nextBufPos = renderPlain(pageOffsets[navi.page]);
  995.                 break;
  996.         case '1':
  997.                 OS_SETSYSDRV();
  998.                 loadPageFromDisk("browser/current.gph", 0);
  999.                 navi.nextBufPos = renderPage(pageOffsets[navi.page]);
  1000.                 break;
  1001.         default:
  1002.                 OS_SETSYSDRV();
  1003.                 loadPageFromDisk("browser/current.gph", 0);
  1004.                 navi.nextBufPos = renderPage(pageOffsets[navi.page]);
  1005.                 break;
  1006.         }
  1007. }
  1008.  
  1009. char getFileEsp(unsigned char *fileNamePtr)
  1010. {
  1011.         int todo;
  1012.         unsigned char byte;
  1013.         unsigned long downloaded = 0;
  1014.         unsigned int count;
  1015.         const unsigned char sendOk[] = "SEND OK";
  1016.  
  1017.         if ((strlen(link.path) == 1 && link.path[0] == '/') || strlen(link.path) == 0)
  1018.         {
  1019.                 strcpy(link.path, "\r\n");
  1020.         }
  1021.         else
  1022.         {
  1023.                 strcat(link.path, "\r\n");
  1024.         }
  1025.  
  1026.         sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%u", link.host, link.port);
  1027.         sendcommand(cmd);
  1028.         do
  1029.         {
  1030.                 getAnswer3(); // CONNECT or ERROR or link is not valid
  1031.  
  1032.                 if (strstr(netbuf, "CONNECT") != NULL)
  1033.                 {
  1034.                         break;
  1035.                 }
  1036.                 else
  1037.                 {
  1038.                         if (strstr(netbuf, "ERROR") != NULL)
  1039.                         {
  1040.                                 return false;
  1041.                         }
  1042.                 }
  1043.         } while (42); // Try until endo of the days recieve CONNECT or ERROR
  1044.  
  1045.         getAnswer3(); // OK
  1046.  
  1047.         sprintf(cmd, "AT+CIPSEND=%u", strlen(link.path)); // second CRLF in send command
  1048.         sendcommand(cmd);
  1049.         getAnswer3();
  1050.  
  1051.         do
  1052.         {
  1053.                 byte = uartReadBlock();
  1054.         } while (byte != '>');
  1055.  
  1056.         sendcommandNrn(link.path);
  1057.  
  1058.         count = 0;
  1059.         do
  1060.         {
  1061.                 byte = uartReadBlock();
  1062.                 if (byte == sendOk[count])
  1063.                 {
  1064.                         count++;
  1065.                         // putchar(byte);
  1066.                 }
  1067.                 else
  1068.                 {
  1069.                         count = 0;
  1070.                 }
  1071.         } while (count < strlen(sendOk));
  1072.  
  1073.         uartReadBlock(); // CR
  1074.         uartReadBlock(); // LF
  1075.  
  1076.         OS_DELETE(fileNamePtr);
  1077.         saveBuf(fileNamePtr, 00, 0);
  1078.         clearStatus();
  1079.         do
  1080.         {
  1081.                 todo = recvHead();
  1082.                 downloaded = downloaded + todo;
  1083.                 if (downloaded == 0)
  1084.                 {
  1085.                         return false;
  1086.                 }
  1087.                 getdataEsp(todo);
  1088.                 saveBuf(fileNamePtr, 01, todo);
  1089.                 printf("%lu kb  \r", downloaded / 1024);
  1090.         } while (todo != 0);
  1091.         link.size = downloaded;
  1092.         return true;
  1093. }
  1094.  
  1095. char getFileNet(unsigned char *fileNamePtr)
  1096. {
  1097.         int todo;
  1098.         int socket;
  1099.         unsigned long downloaded = 0;
  1100.  
  1101.         if (!dnsResolve(link.host))
  1102.         {
  1103.                 clearStatus();
  1104.                 printf("Ошибка определения адреса '%s'", link.host);
  1105.                 return false;
  1106.         }
  1107.         targetadr.porth = 00;
  1108.         targetadr.portl = link.port;
  1109.  
  1110.         // clearStatus();
  1111.         // printf("File:%s", fileNamePtr);
  1112.         // printf("\r\nAddress:%u.%u.%u.%u:%u\r\n", targetadr.b1, targetadr.b2, targetadr.b3, targetadr.b4, targetadr.porth * 256 + targetadr.portl);
  1113.         // waitKey();
  1114.  
  1115.         if ((strlen(link.path) == 1 && link.path[0] == '/') || strlen(link.path) == 0)
  1116.         {
  1117.                 strcpy(link.path, crlf);
  1118.         }
  1119.         else
  1120.         {
  1121.                 strcat(link.path, crlf);
  1122.         }
  1123.         socket = OpenSock(AF_INET, SOCK_STREAM);
  1124.         if (socket < 0)
  1125.         {
  1126.                 return false;
  1127.         }
  1128.         todo = netConnect(socket, 1);
  1129.         if (todo < 0)
  1130.         {
  1131.                 return false;
  1132.         }
  1133.         todo = tcpSend(socket, (unsigned int)&link.path, strlen(link.path), 1);
  1134.         if (todo < 0)
  1135.         {
  1136.                 return false;
  1137.         }
  1138.         saveBuf(fileNamePtr, 00, 0);
  1139.         clearStatus();
  1140.         do
  1141.         {
  1142.                 todo = tcpRead(socket, 3);
  1143.                 if (todo < 1)
  1144.                 {
  1145.                         break;
  1146.                 }
  1147.  
  1148.                 downloaded = downloaded + todo;
  1149.                 printf("%lu kb    \r", downloaded / 1024);
  1150.                 saveBuf(fileNamePtr, 01, todo);
  1151.         } while (42);
  1152.         clearStatus();
  1153.         netShutDown(socket, 0);
  1154.         link.size = downloaded;
  1155.         if (downloaded == 0)
  1156.         {
  1157.                 clearStatus();
  1158.                 printf("Ошибка получения данных от '%s' (%u.%u.%u.%u:%u)", link.host, targetadr.b1, targetadr.b2, targetadr.b3, targetadr.b4, targetadr.porth * 256 + targetadr.portl);
  1159.                 return false;
  1160.         }
  1161.         return true;
  1162. }
  1163.  
  1164. char getFile(unsigned char *fileNamePtr)
  1165. {
  1166.         int result;
  1167.         switch (netDriver)
  1168.         {
  1169.         case 0:
  1170.                 result = getFileNet(fileNamePtr);
  1171.                 break;
  1172.         case 1:
  1173.                 do
  1174.                 {
  1175.                         result = getFileEsp(fileNamePtr);
  1176.                 } while (result == 0);
  1177.                 break;
  1178.  
  1179.         default:
  1180.                 break;
  1181.         }
  1182.         return result;
  1183. }
  1184.  
  1185. unsigned char selectorProcessor(void)
  1186. {
  1187.         unsigned int startSearch = 0, lineSearch = 0, SelectedPos, counter1 = 0;
  1188.         unsigned char byte;
  1189.  
  1190.         if (link.type == '0' || navi.lineSelect > navi.lastLine) // Если текущая страница текстовая, нечего по ней тыкать или тыкнули ниже низа.
  1191.         {
  1192.                 // clearStatus();
  1193.                 // printf("[%c]Cтраница текстовая или [%u>%u]тыкнули ниже низа.", link.type, navi.lineSelect, navi.lastLine);
  1194.                 return false;
  1195.         }
  1196.  
  1197.         startSearch = pageOffsets[navi.page];
  1198.  
  1199.         do
  1200.         {
  1201.                 byte = netbuf[startSearch + counter1];
  1202.  
  1203.                 if (byte == 0x0a)
  1204.                 {
  1205.                         lineSearch++;
  1206.                 }
  1207.                 counter1++;
  1208.  
  1209.         } while (lineSearch < navi.lineSelect - 1);
  1210.  
  1211.         if (counter1 == 1)
  1212.         {
  1213.                 counter1 = 0;
  1214.         }
  1215.         SelectedPos = startSearch + counter1;
  1216.  
  1217.         strcpy(link.prevHost, link.host);
  1218.         link.nexType = link.type;
  1219.         link.type = netbuf[SelectedPos];
  1220.  
  1221.         if (link.type == 'i' || link.type == '.' || link.type == 0)
  1222.         {
  1223.                 link.type = link.nexType;
  1224.                 return false;
  1225.         }
  1226.  
  1227.         counter1 = 1; // Пропускаем  заголовок селектора
  1228.         do
  1229.         {
  1230.                 byte = netbuf[SelectedPos + counter1];
  1231.                 counter1++;
  1232.         } while (byte != 9);
  1233.  
  1234.         SelectedPos = SelectedPos + counter1;
  1235.         counter1 = 0; // Извлекаем путь к селектору
  1236.  
  1237.         while (netbuf[SelectedPos + counter1] != 9)
  1238.         {
  1239.                 link.path[counter1] = netbuf[SelectedPos + counter1];
  1240.                 counter1++;
  1241.         }
  1242.         link.path[counter1] = 0;
  1243.  
  1244.         SelectedPos = SelectedPos + counter1 + 1;
  1245.         counter1 = 0; // Извлекаем хост селектора
  1246.         do
  1247.         {
  1248.                 link.host[counter1] = netbuf[SelectedPos + counter1];
  1249.                 counter1++;
  1250.         } while (netbuf[SelectedPos + counter1] != 9);
  1251.         link.host[counter1] = 0;
  1252.  
  1253.         SelectedPos = SelectedPos + counter1 + 1;
  1254.         link.port = atoi(netbuf + SelectedPos);
  1255.         return true;
  1256. }
  1257.  
  1258. char extractName(void)
  1259. {
  1260.         unsigned int counter, counter2 = 0, lng, byte, source;
  1261.         unsigned char ext2[128];
  1262.         const unsigned char *count1;
  1263.  
  1264.         lng = strlen(link.path);
  1265.  
  1266.         for (counter = lng - 1; counter != 0; counter--)
  1267.         {
  1268.                 byte = link.path[counter];
  1269.                 if (byte == '/' || byte == ':')
  1270.                 {
  1271.                         break;
  1272.                 }
  1273.  
  1274.                 counter2++;
  1275.         }
  1276.         source = lng - counter2;
  1277.  
  1278.         for (counter = 0; counter < counter2; counter++)
  1279.         {
  1280.                 navi.fileName[counter] = link.path[source + counter];
  1281.         }
  1282.         navi.fileName[counter2] = 0;
  1283.  
  1284.         if (navi.saveAs)
  1285.         {
  1286.                 curWin.w = 61;
  1287.                 curWin.x = 80 / 2 - curWin.w / 2 - 1;
  1288.                 curWin.y = 10;
  1289.                 curWin.h = 1;
  1290.                 curWin.text = 103;
  1291.                 curWin.back = 103;
  1292.                 strcpy(curWin.tittle, "Введите имя файла");
  1293.  
  1294.                 // navi.fileName[64] = 0;
  1295.  
  1296.                 if (inputBox(curWin, navi.fileName))
  1297.                 {
  1298.                         strcpy(navi.fileName, cmd);
  1299.                 }
  1300.                 else
  1301.                 {
  1302.                         return false;
  1303.                 }
  1304.         }
  1305.         else // Play It
  1306.         {
  1307.                 count1 = strstr(navi.fileName, ".");
  1308.                 if (count1 == NULL)
  1309.                 {
  1310.                         clearStatus();
  1311.                         printf("Ошибка определения типа файла, не найдено расширение. [%s]", navi.fileName);
  1312.                         waitKey();
  1313.                         return false;
  1314.                 }
  1315.                 else
  1316.                 {
  1317.                         strcpy(ext2, count1 + 1);
  1318.                         strcpy(navi.fileName, "current.");
  1319.                         strcat(navi.fileName, ext2);
  1320.                 }
  1321.         }
  1322.         return true;
  1323. }
  1324.  
  1325. int pos(unsigned char *s, unsigned char *c, unsigned int n, unsigned int startPos)
  1326. {
  1327.         unsigned int i, j;
  1328.         unsigned int lenC, lenS;
  1329.  
  1330.         for (lenC = 0; c[lenC]; lenC++)
  1331.                 ;
  1332.         for (lenS = 0; s[lenS]; lenS++)
  1333.                 ;
  1334.  
  1335.         for (i = startPos; i <= lenS - lenC; i++)
  1336.         {
  1337.                 for (j = 0; s[i + j] == c[j]; j++)
  1338.                         ;
  1339.  
  1340.                 if (j - lenC == 1 && i == lenS - lenC && !(n - 1))
  1341.                         return i;
  1342.                 if (j == lenC)
  1343.                         if (n - 1)
  1344.                                 n--;
  1345.                         else
  1346.                                 return i;
  1347.         }
  1348.         return -1;
  1349. }
  1350.  
  1351. unsigned char mediaProcessorExt(void)
  1352. {
  1353.         // unsigned char ext[65];
  1354.         unsigned char extLow[4];
  1355.         unsigned char extUp[4];
  1356.         unsigned char byte;
  1357.         const unsigned char *count1;
  1358.         unsigned int counter, counter2, next, curPosition;
  1359.         int n;
  1360.  
  1361.         count1 = strstr(navi.fileName, ".");
  1362.         if (count1 == NULL)
  1363.         {
  1364.                 clearStatus();
  1365.                 printf("Ошибка определения типа файла, не найдено расширение. [%s]", navi.fileName);
  1366.                 waitKey();
  1367.         }
  1368.  
  1369.         counter = strlen(navi.fileName);
  1370.         do
  1371.         {
  1372.                 counter--;
  1373.                 if (navi.fileName[counter] == '.')
  1374.                 {
  1375.  
  1376.                         for (counter2 = 0; counter2 < 3; counter2++)
  1377.                         {
  1378.                                 extLow[counter2] = tolower(navi.fileName[counter + counter2 + 1]);
  1379.                                 extUp[counter2] = toupper(navi.fileName[counter + counter2 + 1]);
  1380.                         }
  1381.                         extUp[3] = 0;
  1382.                         extLow[3] = 0;
  1383.                         // printf("[%s]\r\n[%s]\r\n", extLow, extUp);
  1384.                         break;
  1385.                 }
  1386.  
  1387.         } while (counter != 0);
  1388.  
  1389.         next = 1;
  1390.         curPosition = 0;
  1391.         do
  1392.         {
  1393.                 // n = -1;
  1394.                 n = pos(nvext, extLow, next, curPosition);
  1395.                 curPosition = n;
  1396.                 if (n == -1)
  1397.                 {
  1398.                         curPosition = 0;
  1399.                         n = pos(nvext, extUp, next, curPosition);
  1400.                         curPosition = n;
  1401.                         if (n == -1)
  1402.                         {
  1403.                                 clearStatus();
  1404.                                 printf("[ext]не найдено соответствие к расширению [%s][%s]", extLow, extUp);
  1405.                                 waitKey();
  1406.                                 return false;
  1407.                         }
  1408.                 }
  1409.                 else
  1410.                 {
  1411.                         counter = 0;
  1412.                         do
  1413.                         {
  1414.                                 byte = nvext[n + counter];
  1415.                                 if (byte == 0x0d)
  1416.                                 {
  1417.                                         next++;
  1418.                                         break;
  1419.                                 }
  1420.  
  1421.                                 if (byte == ':')
  1422.                                 {
  1423.                                         counter++;
  1424.                                         counter2 = 0;
  1425.  
  1426.                                         while (nvext[n + counter] == ' ')
  1427.                                         {
  1428.                                                 counter++;
  1429.                                         }
  1430.  
  1431.                                         do
  1432.                                         {
  1433.                                                 byte = nvext[n + counter];
  1434.                                                 cmd[counter2] = byte;
  1435.                                                 counter++;
  1436.                                                 counter2++;
  1437.                                         } while (byte != 0x0d);
  1438.                                         cmd[counter2 - 1] = ' ';
  1439.                                         cmd[counter2] = 0;
  1440.                                         strcat(cmd, " ");
  1441.                                         strcat(cmd, curPath);
  1442.                                         strcat(cmd, "/current.");
  1443.                                         strcat(cmd, extLow);
  1444.                                         return true;
  1445.                                 }
  1446.                                 counter++;
  1447.                         } while (42);
  1448.                 }
  1449.         } while (42);
  1450.         return false;
  1451. }
  1452.  
  1453. void doLink(char backSpace)
  1454. {
  1455.         unsigned char *count1;
  1456.         if (strcmp(link.host, "HOMEPAGE") == 0)
  1457.         {
  1458.                 goHome(backSpace);
  1459.                 return;
  1460.         }
  1461.  
  1462.         switch (link.type) // Тут уже новый элемент
  1463.         {
  1464.         case 'i':
  1465.                 link.type = link.nexType; // так-как мы остались на странице, восстановим тип, хотя можно просто ставить 1 (пока других нет)
  1466.                 return;
  1467.         case '0': // plain texts
  1468.                 if (getFile("browser/current.txt"))
  1469.                 {
  1470.                         newPage();
  1471.                         OS_SETSYSDRV();
  1472.                         loadPageFromDisk("browser/current.txt", 0);
  1473.                         if (!backSpace)
  1474.                         {
  1475.                                 pusHistory();
  1476.                         }
  1477.                         navi.nextBufPos = renderPlain(navi.nextBufPos);
  1478.                 }
  1479.                 else
  1480.                 {
  1481.                         errNoConnect();
  1482.                 }
  1483.                 return;
  1484.         case '1': // gopher page
  1485.                 if (getFile("browser/current.gph"))
  1486.                 {
  1487.                         newPage();
  1488.                         OS_SETSYSDRV();
  1489.                         loadPageFromDisk("browser/current.gph", 0);
  1490.                         if (!backSpace)
  1491.                         {
  1492.                                 pusHistory();
  1493.                         }
  1494.                         navi.nextBufPos = renderPage(navi.nextBufPos);
  1495.                 }
  1496.                 else
  1497.                 {
  1498.  
  1499.                         errNoConnect();
  1500.                 }
  1501.                 return;
  1502.         case '7': // search input
  1503.                 curWin.w = 40;
  1504.                 curWin.x = 80 / 2 - curWin.w / 2 - 1;
  1505.                 curWin.y = 10;
  1506.                 curWin.h = 1;
  1507.                 curWin.text = 95;
  1508.                 curWin.back = 95;
  1509.                 strcpy(curWin.tittle, "Введите поисковый запрос");
  1510.                 if (inputBox(curWin, ""))
  1511.                 {
  1512.                         strcat(link.path, "\t");
  1513.                         strcat(link.path, cmd);
  1514.                         if (getFile("browser/current.gph"))
  1515.                         {
  1516.                                 newPage();
  1517.                                 OS_SETSYSDRV();
  1518.                                 loadPageFromDisk("browser/current.gph", 0);
  1519.                                 navi.nextBufPos = renderPage(navi.nextBufPos);
  1520.                                 link.type = '1';
  1521.                         }
  1522.                         else
  1523.                         {
  1524.                                 reDraw();
  1525.                                 errNoConnect();
  1526.                         }
  1527.                 }
  1528.                 else
  1529.                 {
  1530.                         link.type = '1';
  1531.                         reDraw();
  1532.                         return;
  1533.                 }
  1534.                 return;
  1535.         case 'g': // gif pic
  1536.         case 'I': // image
  1537.         case 's': // sound
  1538.         case '9': // binary (pt3/scr)
  1539.         case '8':
  1540.         case '6':
  1541.         case '5':
  1542.         case '4':
  1543.                 if (!extractName())
  1544.                 {
  1545.                         link.type = '1';
  1546.                         reDraw();
  1547.                         return;
  1548.                 }
  1549.                 OS_CHDIR("/");
  1550.                 OS_CHDIR("downloads");
  1551.                 OS_GETPATH((unsigned int)&curPath);
  1552.  
  1553.                 if (getFile(navi.fileName))
  1554.                 {
  1555.                         OS_SETSYSDRV();
  1556.                         loadPageFromDisk("browser/current.gph", 0);
  1557.                         navi.nextBufPos = renderPage(pageOffsets[navi.page]);
  1558.                         if (!navi.saveAs)
  1559.                         {
  1560.                                 if (mediaProcessorExt())
  1561.                                 {
  1562.                                         OS_CHDIR("/");
  1563.                                         OS_CHDIR("downloads");
  1564.                                         clearStatus();
  1565.                                         printf("cmd:[%s]", cmd);
  1566.                                         OS_SHELL(cmd);
  1567.                                         OS_SETSYSDRV();
  1568.                                 }
  1569.                         }
  1570.                 }
  1571.                 else
  1572.                 {
  1573.                         errNoConnect();
  1574.                 }
  1575.                 return;
  1576.         case 'h': // html
  1577.                 clearStatus();
  1578.  
  1579.                 count1 = strstr(link.path, "http");
  1580.                 if (count1 == NULL)
  1581.                 {
  1582.                         count1 = strstr(link.path, "HTTP");
  1583.                         if (count1 == NULL)
  1584.                         {
  1585.                                 clearStatus();
  1586.                                 printf("Не удалось получить ссылку [%s]", link.path);
  1587.                                 link.type = link.nexType;
  1588.                                 return;
  1589.                         }
  1590.                 }
  1591.                 sprintf(cmd, "browser.com %s", count1);
  1592.                 OS_SHELL(cmd);
  1593.                 OS_SETSYSDRV();
  1594.                 link.type = '1';
  1595.                 break;
  1596.         default:
  1597.                 clearStatus();
  1598.                 printf("Неизвестный селектор:[%u]lineselect[%u]linelast[%u]", link.type, navi.lineSelect, navi.lastLine);
  1599.                 link.type = link.nexType;
  1600.                 return;
  1601.         }
  1602. }
  1603.  
  1604. void activate(void)
  1605. {
  1606.         if (!selectorProcessor())
  1607.         {
  1608.                 return;
  1609.         }
  1610.         doLink(false);
  1611. }
  1612.  
  1613. void enterDomain(void)
  1614. {
  1615.         curWin.w = 40;
  1616.         curWin.x = 80 / 2 - curWin.w / 2 - 1;
  1617.         curWin.y = 10;
  1618.         curWin.h = 1;
  1619.         curWin.text = 207;
  1620.         curWin.back = 207;
  1621.         strcpy(curWin.tittle, "Введите адрес Gopher сервера");
  1622.  
  1623.         if (inputBox(curWin, ""))
  1624.         {
  1625.                 strcpy(link.prevHost, link.host);
  1626.                 link.type = '1';
  1627.                 strcpy(link.host, cmd);
  1628.                 strcpy(link.path, "/");
  1629.                 link.port = 70;
  1630.                 doLink(false);
  1631.         }
  1632.         else
  1633.         {
  1634.                 reDraw();
  1635.         }
  1636. }
  1637.  
  1638. void navigationPage(char keypress)
  1639. {
  1640.         unsigned char counter;
  1641.  
  1642.         switch (keypress)
  1643.         {
  1644.         case 250: // Up
  1645.                 navi.prevLineSelect = navi.lineSelect;
  1646.                 navi.lineSelect--;
  1647.  
  1648.                 if (navi.lineSelect < 1 && navi.page == 0)
  1649.                 {
  1650.                         navi.lineSelect = screenHeight;
  1651.                         break;
  1652.                 }
  1653.  
  1654.                 if (navi.page != 0 && navi.lineSelect == 0)
  1655.                 {
  1656.                         navi.page--;
  1657.                         navi.nextBufPos = pageOffsets[navi.page];
  1658.                         navi.nextBufPos = renderPage(navi.nextBufPos);
  1659.                         navi.lineSelect = screenHeight;
  1660.                 }
  1661.                 break;
  1662.         case 249: // down
  1663.                 navi.prevLineSelect = navi.lineSelect;
  1664.                 navi.lineSelect++;
  1665.                 if (navi.lineSelect > screenHeight && navi.page == navi.maxPage)
  1666.                 {
  1667.                         navi.lineSelect = 1;
  1668.                         break;
  1669.                 }
  1670.                 if (navi.page != navi.maxPage && navi.lineSelect > screenHeight)
  1671.                 {
  1672.                         navi.page++;
  1673.                         pageOffsets[navi.page] = navi.nextBufPos;
  1674.                         navi.nextBufPos = renderPage(navi.nextBufPos);
  1675.                         navi.lineSelect = 1;
  1676.                 }
  1677.                 break;
  1678.         case 248: // Left
  1679.                 if (navi.page == 0)
  1680.                 {
  1681.                         break;
  1682.                 }
  1683.                 navi.page--;
  1684.                 navi.nextBufPos = pageOffsets[navi.page];
  1685.                 navi.nextBufPos = renderPage(navi.nextBufPos);
  1686.                 navi.lineSelect = screenHeight;
  1687.                 break;
  1688.         case 251: // Right
  1689.                 if (navi.page == navi.maxPage)
  1690.                 {
  1691.                         break;
  1692.                 }
  1693.                 navi.page++;
  1694.                 pageOffsets[navi.page] = navi.nextBufPos;
  1695.  
  1696.                 navi.nextBufPos = renderPage(navi.nextBufPos);
  1697.                 navi.lineSelect = 1;
  1698.                 break;
  1699.         case 0x0d:
  1700.                 activate();
  1701.                 break;
  1702.         case 0x08: // BS
  1703.                 if (navi.history > 1)
  1704.                 {
  1705.                         popHistory();
  1706.                         doLink(true);
  1707.                 }
  1708.                 break;
  1709.         case 31: // screen redraw
  1710.                 renderPage(pageOffsets[navi.page]);
  1711.                 break;
  1712.         case 'h':
  1713.         case 'H':
  1714.                 goHome(false);
  1715.                 break;
  1716.         case 'd':
  1717.         case 'D':
  1718.                 enterDomain();
  1719.                 break;
  1720.         case 's':
  1721.         case 'S':
  1722.                 navi.saveAs = !navi.saveAs;
  1723.                 mainWinDraw();
  1724.                 break;
  1725.         case 'i':
  1726.         case 'I':
  1727.                 netDriver = !netDriver;
  1728.                 mainWinDraw();
  1729.                 if (netDriver)
  1730.                 {
  1731.                         uart_init(divider);
  1732.                         espReBoot();
  1733.                 }
  1734.                 break;
  1735.         case 'm':
  1736.         case 'M':
  1737.                 mouse.classic = !mouse.classic;
  1738.                 break;
  1739.         }
  1740.  
  1741.         if (link.type == '1')
  1742.         {
  1743.                 for (counter = 1; counter < 79; counter++)
  1744.                 {
  1745.                         OS_SETXY(counter, navi.prevLineSelect);
  1746.                         OS_PRATTR(7);
  1747.                 }
  1748.  
  1749.                 if (mouse.cursYpos == navi.prevLineSelect)
  1750.                 {
  1751.                         OS_SETXY(mouse.cursXpos, mouse.cursYpos);
  1752.                         mouse.oldAtr = OS_GETATTR();
  1753.                 }
  1754.                 for (counter = 1; counter < 79; counter++)
  1755.                 {
  1756.                         OS_SETXY(counter, navi.lineSelect);
  1757.                         OS_PRATTR(15);
  1758.                 }
  1759.         }
  1760. }
  1761.  
  1762. void navigationPlain(char keypress)
  1763. {
  1764.         switch (keypress)
  1765.         {
  1766.         case 248: // Left
  1767.         case 250: // Up
  1768.  
  1769.                 if (navi.page == 0)
  1770.                 {
  1771.                         if (navi.volume == 0)
  1772.                         {
  1773.                                 break;
  1774.                         }
  1775.                         navi.volume--;
  1776.                         newPage();
  1777.                         OS_SETSYSDRV();
  1778.                         loadPageFromDisk("browser/current.txt", navi.volume);
  1779.                         navi.nextBufPos = renderPlain(navi.nextBufPos);
  1780.                         break;
  1781.                 }
  1782.                 navi.page--;
  1783.                 navi.nextBufPos = pageOffsets[navi.page];
  1784.                 navi.lineSelect = screenHeight;
  1785.                 navi.nextBufPos = renderPlain(navi.nextBufPos);
  1786.                 break;
  1787.         case 251: // Right
  1788.         case 249: // down
  1789.                 if (navi.page == navi.maxPage)
  1790.                 {
  1791.                         if (navi.volume == navi.maxVolume)
  1792.                         {
  1793.                                 break;
  1794.                         }
  1795.                         navi.volume++;
  1796.                         newPage();
  1797.                         OS_SETSYSDRV();
  1798.                         loadPageFromDisk("browser/current.txt", navi.volume);
  1799.                         navi.nextBufPos = renderPlain(navi.nextBufPos);
  1800.                         break;
  1801.                 }
  1802.                 navi.page++;
  1803.                 pageOffsets[navi.page] = navi.nextBufPos;
  1804.                 navi.lineSelect = 1;
  1805.                 navi.nextBufPos = renderPlain(navi.nextBufPos);
  1806.                 break;
  1807.         case 0x08: // BS
  1808.                 if (navi.history > 1)
  1809.                 {
  1810.                         popHistory();
  1811.                         doLink(true);
  1812.                 }
  1813.                 break;
  1814.         case 31: // screen redraw
  1815.                 renderPlain(pageOffsets[navi.page]);
  1816.                 break;
  1817.         case 'h':
  1818.         case 'H':
  1819.                 goHome(false);
  1820.                 break;
  1821.         case 'd':
  1822.         case 'D':
  1823.                 enterDomain();
  1824.                 break;
  1825.         case 's':
  1826.         case 'S':
  1827.                 navi.saveAs = !navi.saveAs;
  1828.                 mainWinDraw();
  1829.                 break;
  1830.         case 'i':
  1831.         case 'I':
  1832.                 netDriver = !netDriver;
  1833.                 mainWinDraw();
  1834.                 if (netDriver)
  1835.                 {
  1836.                         uart_init(divider);
  1837.                         espReBoot();
  1838.                 }
  1839.                 break;
  1840.         case 'm':
  1841.         case 'M':
  1842.                 mouse.classic = !mouse.classic;
  1843.                 break;
  1844.         }
  1845.  
  1846.         if (mouse.cursYpos == navi.prevLineSelect)
  1847.         {
  1848.                 OS_SETXY(mouse.cursXpos, mouse.cursYpos);
  1849.                 mouse.oldAtr = OS_GETATTR();
  1850.         }
  1851. }
  1852.  
  1853. void navigation(unsigned char keypress)
  1854. {
  1855.  
  1856.         switch (link.type)
  1857.         {
  1858.         case '0':
  1859.                 navigationPlain(keypress);
  1860.                 break;
  1861.         case '1':
  1862.                 navigationPage(keypress);
  1863.                 break;
  1864.         default:
  1865.                 clearStatus();
  1866.                 printf("Unknown link.type, [%d]", link.type);
  1867.                 waitKey();
  1868.                 break;
  1869.         }
  1870. }
  1871.  
  1872. unsigned char getMouse(void)
  1873. {
  1874.         unsigned long mouseRaw;
  1875.         unsigned int mouseMove;
  1876.         unsigned int mouseButtons;
  1877.         int mouseScroll = 0;
  1878.         int mouseXpos;
  1879.         int mouseYpos;
  1880.         int dx, dy;
  1881.         mouseRaw = OS_GETMOUSE();
  1882.  
  1883.         mouseMove = mouseRaw >> 16;
  1884.         mouseButtons = mouseRaw;
  1885.  
  1886.         if (mouseMove != mouse.prevMouseMove)
  1887.         {
  1888.                 OS_SETXY(mouse.cursXpos, mouse.cursYpos);
  1889.                 OS_PRATTR(mouse.oldAtr);
  1890.                 mouse.prevMouseMove = mouseMove;
  1891.  
  1892.                 mouse.prevMouseXpos = mouse.mouseXpos;
  1893.                 mouse.prevMouseYpos = mouse.mouseYpos;
  1894.  
  1895.                 mouse.mouseXpos = mouseRaw >> 16;
  1896.                 mouse.mouseYpos = mouseRaw >> 24;
  1897.  
  1898.                 if (mouse.classic)
  1899.                 {
  1900.                         mouse.cursXpos = mouse.mouseXpos / 3;
  1901.                         mouse.cursYpos = 25 - mouse.mouseYpos / 10;
  1902.                 }
  1903.                 else
  1904.                 {
  1905.                         mouseXpos = mouse.mouseXpos - mouse.prevMouseXpos;
  1906.                         mouseYpos = mouse.mouseYpos - mouse.prevMouseYpos;
  1907.  
  1908.                         dx = abs(mouseXpos / 2);
  1909.                         dy = abs(mouseYpos / 2);
  1910.  
  1911.                         if (dx == 0)
  1912.                                 dx = 1;
  1913.                         if (dy == 0)
  1914.                                 dy = 1;
  1915.                         if (dx > 3)
  1916.                                 dx = 3;
  1917.                         if (dy > 2)
  1918.                                 dy = 2;
  1919.  
  1920.                         if (mouseXpos < -250)
  1921.                         {
  1922.                                 mouseXpos = 1;
  1923.                         }
  1924.                         else if (mouseXpos > 250)
  1925.                         {
  1926.                                 mouseXpos = -1;
  1927.                         }
  1928.  
  1929.                         if (mouseYpos < -254)
  1930.                         {
  1931.                                 mouseYpos = 1;
  1932.                         }
  1933.                         else if (mouseYpos > 254)
  1934.                         {
  1935.                                 mouseYpos = -1;
  1936.                         }
  1937.  
  1938.                         if (mouseXpos < 0)
  1939.                         {
  1940.                                 mouse.cursXpos = mouse.cursXpos - dx;
  1941.                         }
  1942.                         else if (mouseXpos > 0)
  1943.                         {
  1944.                                 mouse.cursXpos = mouse.cursXpos + dx;
  1945.                         }
  1946.  
  1947.                         if (mouse.divider == 0)
  1948.                         {
  1949.                                 if (mouseYpos > 0)
  1950.                                 {
  1951.                                         mouse.cursYpos = mouse.cursYpos - dy;
  1952.                                 }
  1953.                                 else if (mouseYpos < 0)
  1954.                                 {
  1955.                                         mouse.cursYpos = mouse.cursYpos + dy;
  1956.                                 }
  1957.                                 mouse.divider = 2;
  1958.                         }
  1959.                         mouse.divider--;
  1960.                         // clearStatus();
  1961.                         // printf("dx=%d dy=%d X=%d Y=%d", dx, dy, mouse.mouseXpos, mouse.mouseYpos);
  1962.  
  1963.                         if (mouse.cursXpos > 79)
  1964.                         {
  1965.                                 mouse.cursXpos = 79;
  1966.                         }
  1967.                         if (mouse.cursYpos > 24)
  1968.                         {
  1969.                                 mouse.cursYpos = 24;
  1970.                         }
  1971.  
  1972.                         if (mouse.cursXpos < 0)
  1973.                         {
  1974.                                 mouse.cursXpos = 0;
  1975.                         }
  1976.                         if (mouse.cursYpos < 0)
  1977.                         {
  1978.                                 mouse.cursYpos = 0;
  1979.                         }
  1980.                 }
  1981.                 OS_SETXY(mouse.cursXpos, mouse.cursYpos);
  1982.                 mouse.oldAtr = OS_GETATTR();
  1983.                 OS_PRATTR(215);
  1984.         }
  1985.  
  1986.         if (mouseButtons != mouse.prevMouseButtons)
  1987.         {
  1988.  
  1989.                 mouse.prevWheel = mouse.wheel;
  1990.                 mouse.wheel = (mouseButtons >> 4) & 15;
  1991.                 mouse.mmb = (mouseButtons >> 2) & 1;
  1992.                 mouse.rmb = (mouseButtons >> 1) & 1;
  1993.                 mouse.lmb = mouseButtons & 1;
  1994.         }
  1995.  
  1996.         // clearStatus();
  1997.         // printf("lmb:[%d] rmb:[%d] mmb:[%d] wheel:[%02d] X:[%03d] Y:[%03d] cursX:[%02d] cursY:[%02d]", mouse.lmb, mouse.rmb, mouse.mmb, mouse.wheel, mouse.mouseXpos, mouse.mouseYpos, mouse.cursXpos, mouse.cursYpos);
  1998.  
  1999.         OS_SETXY(mouse.cursXpos, mouse.cursYpos);
  2000.  
  2001.         mouseScroll = mouse.wheel - mouse.prevWheel;
  2002.  
  2003.         if (mouseScroll < -12)
  2004.         {
  2005.                 mouseScroll = 1;
  2006.         }
  2007.         else if (mouseScroll > 12)
  2008.         {
  2009.                 mouseScroll = -1;
  2010.         }
  2011.  
  2012.         if (mouseScroll < 0)
  2013.         {
  2014.                 navigation(248); // Left
  2015.         }
  2016.         else if (mouseScroll > 0)
  2017.         {
  2018.                 navigation(251); // Right
  2019.         }
  2020.         mouse.prevWheel = mouse.wheel;
  2021.  
  2022.         return mouseButtons >> 8;
  2023. }
  2024.  
  2025. C_task main(int argc, const char *argv[])
  2026. {
  2027.         unsigned char keypress;
  2028.         OS_SETGFX(0x86);
  2029.         OS_CLS(0);
  2030.         OS_SETSYSDRV();
  2031.         init();
  2032.         OS_HIDEFROMPARENT();
  2033.         // printTable();
  2034.         // waitKey();
  2035.  
  2036.         goHome(false);
  2037.  
  2038.         do
  2039.         {
  2040.                 keypress = getMouse();
  2041.                 if (mouse.lmb == 0)
  2042.                 {
  2043.                         if (mouse.cursYpos > 0 && mouse.cursYpos < screenHeight + 1)
  2044.                         {
  2045.                                 navi.prevLineSelect = navi.lineSelect;
  2046.                                 navi.lineSelect = mouse.cursYpos;
  2047.                                 activate();
  2048.                                 OS_SETXY(mouse.cursXpos, mouse.cursYpos);
  2049.                                 OS_PRATTR(215);
  2050.                         }
  2051.                         else
  2052.                         {
  2053.                                 if (mouse.cursYpos == 0)
  2054.                                 {
  2055.                                         enterDomain();
  2056.                                 }
  2057.                         }
  2058.                 }
  2059.                 else if (mouse.rmb == 0)
  2060.                 {
  2061.                         popHistory();
  2062.                         doLink(true);
  2063.                 }
  2064.  
  2065.                 if (keypress != 0)
  2066.                 {
  2067.                         navigation(keypress);
  2068.  
  2069.                         //      printf("keypress [%d]", keypress);
  2070.                 }
  2071.                 YIELD();
  2072.                 drawClock();
  2073.         } while (keypress != 27);
  2074.         OS_DELETE("browser/current.gph");
  2075.         OS_DELETE("browser/current.txt");
  2076.         OS_DELETE("browser/ng_hist.dat");
  2077. }
  2078.