Subversion Repositories NedoOS

Rev

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