Subversion Repositories Kolibri OS

Rev

Rev 485 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;
  2. ;    HTTPC.ASM
  3. ;
  4. ;    Compile with FASM for Menuet ( v1.40 for DOS )
  5. ;
  6. ;    This program implements a very simple web browser
  7. ;
  8. ;    Version 0.4    2nd December 2003 Mike Hibbett
  9. ;    Enabled lowercase/uppcase characters in URL
  10. ;    Version 0.3    30th November 2003 Mike Hibbett
  11. ;    Fixed bug with tcp socket opne - uses unique port
  12. ;    Version 0.2    27th November 2003 Mike Hibbett
  13. ;    Added user entry of url, and implements url -> IP address
  14. ;    resolution through DNS
  15. ;
  16. ;    Version 0.1  Ville Mikael Turjanmaa
  17. ;    Original version
  18.  
  19.  
  20. ; Enabling debugging puts stuff to the debug board
  21. DEBUGGING_ENABLED           equ     1
  22. DEBUGGING_DISABLED          equ     0
  23. DEBUGGING_STATE             equ     DEBUGGING_DISABLED
  24.  
  25. use32
  26.  org    0x0
  27.  db     'MENUET01'    ; header
  28.  dd     0x01          ; header version
  29.  dd     START         ; entry point
  30.  dd     I_END         ; image size
  31.  dd     0x100000      ; required memory
  32.  dd     0x100000      ; esp
  33.  dd     0x0 , 0x0     ; I_Param , I_Path
  34.  
  35. include 'lang.inc'
  36. include 'macros.inc'
  37. ;include "DEBUG.INC"
  38.  
  39. URLMAXLEN       equ     50  ; maximum length of url string
  40.  
  41. ; Memory usage
  42. ; webpage source file at 0x10000
  43. ; decoded text page at   0x20000
  44. ; text attribute         0x30000  (1 = normal, 2 = bold, 128+ = link)
  45.  
  46. START:                              ; start of execution
  47.  
  48. ;dps <"Program started",13,10>
  49.  
  50.     mov     eax,40                          ; Report events
  51.     mov     ebx,10000111b                   ; Stack 8 + defaults
  52.     mcall
  53.  
  54. red:                    ; redraw
  55.     call    draw_window
  56.  
  57. still:
  58.     mov     eax,23                 ; wait here for event
  59.     mov     ebx,1
  60.     mcall
  61.  
  62.     cmp     eax,1                  ; redraw request ?
  63.     je      red
  64.     cmp     eax,2                  ; key in buffer ?
  65.     je      key
  66.     cmp     eax,3                  ; button in buffer ?
  67.     je      button
  68.  
  69.     ; Get the web page data from the remote server
  70.     call    read_incoming_data
  71.  
  72.     mov     eax,[status]
  73.     mov     [prev_status],eax
  74.  
  75.     mov     eax,53
  76.     mov     ebx,6
  77.     mov     ecx,[socket]
  78.     mcall
  79.  
  80.     mov     [status],eax
  81.  
  82.     cmp     [prev_status],4
  83.     jge     no_send
  84.     cmp     [status],4
  85.     jne     no_send
  86.  
  87.     mov     [onoff],1
  88.  
  89.     call    send_request
  90.  
  91. no_send:
  92.     call    print_status
  93.  
  94.     cmp     [prev_status],4
  95.     jne     no_close
  96.     cmp     [status],4   ; connection closed by server
  97.     jbe     no_close     ; respond to connection close command
  98.                          ; draw page
  99.  
  100.     call    read_incoming_data
  101.  
  102.     mov     eax,53
  103.     mov     ebx,8
  104.     mov     ecx,[socket]
  105.     mcall
  106.  
  107.     call    draw_page
  108.  
  109.     mov     [onoff],0
  110.  
  111. no_close:
  112.     jmp     still
  113.  
  114. key:                    ; key
  115.     mov     eax,2       ; just read it and ignore
  116.     mcall
  117.     shr     eax,8
  118.     cmp     eax,184
  119.     jne     no_down
  120.     cmp     [display_from],25
  121.     jb      no_down
  122.     sub     [display_from],25
  123.     call    display_page
  124.  
  125. no_down:
  126.     cmp     eax,183
  127.     jne     no_up
  128.     add     [display_from],25
  129.     call    display_page
  130.  
  131. no_up:
  132.     jmp     still
  133.  
  134. button:                 ; button
  135. ;dps <"Button pressed",13,10>
  136.     mov     eax,17      ; get id
  137.     mcall
  138.     cmp     ah,1                   ; button id=1 ?
  139.     jne     noclose
  140.  
  141. ;dps "Closing socket before exit... "
  142.  
  143.     mov     eax, 53
  144.     mov     ebx, 8
  145.     mov     ecx, [socket]
  146.     mcall
  147.  
  148. ;dpd eax
  149. ;dps <13,10>
  150.  
  151. exit:
  152.     or      eax,-1                 ; close this program
  153.     mcall
  154.  
  155. noclose:
  156.     cmp     ah,31
  157.     jne     noup
  158.     sub     [display_from],20
  159.     call    display_page
  160.     jmp     still
  161.  
  162. noup:
  163.     cmp     ah,32
  164.     jne     nodown
  165.     add     [display_from],20
  166.     call    display_page
  167.     jmp     still
  168.  
  169. nodown:
  170.     cmp     ah, 10              ; Enter url
  171.     jne     nourl
  172.  
  173.     mov     [addr],dword document_user
  174.     mov     [ya],dword 38
  175.     mov     [len],dword URLMAXLEN
  176.  
  177.     mov     ecx,[len]
  178.     mov     edi,[addr]
  179.     mov     al,' '
  180.     rep     stosb
  181.  
  182.     call    print_text
  183.  
  184.     mov     edi,[addr]
  185.  
  186. f11:
  187.     mov     eax,10
  188.     mcall
  189.     cmp     eax,2 ; key?
  190.     jz      fbu
  191.     jmp     still
  192.  
  193. fbu:
  194.     mov     eax,2
  195.     mcall  ; get key
  196.     shr     eax,8
  197.     cmp     eax,8
  198.     jnz     nobs
  199.     cmp     edi,[addr]
  200.     jz      f11
  201.     sub     edi,1
  202.     mov     [edi],byte ' '
  203.     call    print_text
  204.     jmp     f11
  205.  
  206. nobs:
  207.     cmp     eax, dword 10
  208.     je      retkey
  209.     cmp     eax, dword 13
  210.     je      retkey
  211.  
  212.     cmp     eax,dword 31
  213.     jbe     f11
  214.  
  215. ; Removed in v0.4
  216. ;    cmp     eax,dword 95
  217. ;    jb      keyok
  218. ;    sub     eax,32
  219.  
  220. keyok:
  221.     mov     [edi],al
  222.  
  223.     call    print_text
  224.  
  225.     add     edi,1
  226.     mov     esi,[addr]
  227.     add     esi,URLMAXLEN
  228.     cmp     esi,edi
  229.     jnz     f11
  230.  
  231.     jmp  still
  232.  
  233. retkey:
  234.     mov     ah, 22   ; start load
  235.  
  236. nourl:
  237.     call    socket_commands     ; opens or closes the connection
  238.     jmp     still
  239.  
  240.  
  241. ;****************************************************************************
  242. ;    Function
  243. ;       send_request
  244. ;
  245. ;   Description
  246. ;       Transmits the GET request to the server.
  247. ;       This is done as GET then URL then HTTP/1.0',13,10,13,10 in 3 packets
  248. ;
  249. ;****************************************************************************
  250. send_request:
  251.     pusha
  252.     mov     eax,53     ; 'GET '
  253.     mov     ebx,7
  254.     mov     ecx,[socket]
  255.     mov     edx,4
  256.     mov     esi,string0
  257.     mcall
  258.  
  259.     mov     edx,0
  260.  
  261. next_edx:
  262.     ; Determine the length of the url to send in the GET request
  263.     inc     edx
  264.     cmp     [edx+document],byte ' '
  265.     jne     next_edx
  266.  
  267.     mov     eax,53     ; document_user
  268.     mov     ebx,7
  269.     mov     ecx,[socket]
  270.     mov     esi,document
  271.     mcall
  272.  
  273.     mov     eax,53     ; ' HTTP/1.0 .. '
  274.     mov     ebx,7
  275.     mov     ecx,[socket]
  276.     mov     edx,stringh_end-stringh
  277.     mov     esi,stringh
  278.     mcall
  279.  
  280.     popa
  281.     ret
  282.  
  283.  
  284. ;****************************************************************************
  285. ;    Function
  286. ;       print_status
  287. ;
  288. ;   Description
  289. ;       displays the socket/data received status information
  290. ;
  291. ;****************************************************************************
  292. print_status:
  293.     pusha
  294.  
  295.     mov     eax,26
  296.     mov     ebx,9
  297.     mcall
  298.  
  299.     cmp     eax,[nextupdate]
  300.     jb      status_return
  301.  
  302.     add     eax,25
  303.  
  304.     mov     [nextupdate],eax
  305.  
  306.     mov     eax,13
  307.     mov     ebx,5*65536+100
  308.     mov     ecx,[winys]
  309.     shl     ecx,16
  310.     add     ecx,-18*65536+10
  311.     mov     edx,0xffffff
  312.     mcall
  313.  
  314.     mov     eax,47
  315.     mov     ebx,3*65536
  316.     mov     ecx,[status]
  317.     mov     edx,12*65536-18
  318.     add     edx,[winys]
  319.     mov     esi,0x000000
  320.     mcall
  321.  
  322.     mov     eax,47
  323.     mov     ebx,6*65536
  324.     mov     ecx,[pos]
  325.     mov     edx,40*65536-18
  326.     add     edx,[winys]
  327.     mov     esi,0x000000
  328.     mcall
  329.  
  330. status_return:
  331.     popa
  332.     ret
  333.  
  334.  
  335. ;****************************************************************************
  336. ;    Function
  337. ;       read_incoming_data
  338. ;
  339. ;   Description
  340. ;       receive the web page from the server, storing it without processing
  341. ;
  342. ;****************************************************************************
  343. read_incoming_data:
  344.     cmp     [onoff],1
  345.     je      rid
  346.     ret
  347.  
  348. rid:
  349.     mov     ecx,-1
  350.  
  351. newbyteread:
  352.     mov     eax, 53
  353.     mov     ebx, 2
  354.     mov     ecx, [socket]
  355.     mcall
  356.  
  357.     cmp     eax,0
  358.     je      no_more_data
  359.  
  360. read_more:
  361.     mov     eax, 53
  362.     mov     ebx, 3
  363.     mov     ecx, [socket]
  364.     mcall
  365.  
  366. yesm:
  367.     inc     [pos]
  368.     mov     ecx,[pos]
  369.     mov     [0x10000+ecx],bl
  370.  
  371.     call    print_status
  372.  
  373.     cmp     eax,0
  374.     jne     read_more
  375.  
  376.     mov     eax,5
  377.     mov     ebx,50
  378.     mcall
  379.  
  380.     jmp     newbyteread
  381.  
  382. no_more_data:
  383.     ret
  384.  
  385.  
  386. ;****************************************************************************
  387. ;    Function
  388. ;       draw_page
  389. ;
  390. ;   Description
  391. ;       parses the web page data, storing displayable data at 0x20000
  392. ;       and attributes at 0x30000. It then calls display_page to render
  393. ;       the data
  394. ;
  395. ;****************************************************************************
  396. draw_page:
  397.     pusha
  398.     mov     esi,0
  399.     mov     [command_on_off],0
  400.  
  401. newlettercheck:
  402.     movzx   eax,byte [esi+0x10000]
  403.     cmp     al,'<'
  404.     jne     no_c_on
  405.     mov     [command_on_off],1
  406.  
  407. no_c_on:
  408.     cmp     al,'>'
  409.     jne     no_c_off
  410.     mov     [command_on_off],0
  411.  
  412. no_c_off:
  413.     cmp     [command_on_off],0
  414.     je      no_lower_case
  415.  
  416.     cmp     eax,96
  417.     jg      no_lower_case
  418.     cmp     eax,65
  419.     jb      no_lower_case
  420.     add     eax,32
  421.  
  422. no_lower_case:
  423.     mov     [esi+0x10000],al
  424.     inc     esi
  425.     cmp     esi,[pos]
  426.     jbe     newlettercheck
  427.     mov     edi,0x30000
  428.     mov     ecx,0x10000
  429.     mov     al,0
  430.     cld
  431.     rep     stosb
  432.     mov     [text_type],1
  433.     mov     [command_on_off],0
  434.  
  435.     mov     esi,0
  436.     mov     ecx,[pos]
  437.  
  438.     ; search for double lf
  439.  
  440. find_dlf:
  441.     cmp     [0x10000+esi-4],dword 0x0d0a0d0a
  442.     je      found_dlf
  443.     cmp     [0x10000+esi-4],dword 0x0a0d0a0d
  444.     je      found_dlf
  445.     cmp     [0x10000+esi-2],word 0x0d0d
  446.     je      found_dlf
  447.     cmp     [0x10000+esi-2],word 0x0a0a
  448.     je      found_dlf
  449.  
  450.     cmp     esi,5500
  451.     je      found_dlf
  452.  
  453.     inc     esi
  454.  
  455.     jmp     find_dlf
  456.  
  457. found_dlf:
  458. newbyte:
  459.     mov     al,[esi+0x10000]
  460.     cmp     al,'<'
  461.     jne     no_command_on
  462.     mov     [command_on_off],1
  463.  
  464. no_command_on:
  465.     cmp     al,'>'
  466.     jne     no_command_off
  467.     mov     [command_on_off],0
  468.     jmp     byte_done
  469.  
  470. no_command_off:
  471.     mov     eax,[esi+0x10000]    ; <!--
  472.     cmp     eax,'<!--'
  473.     jne     no_com2_start
  474.     mov     [com2],1
  475.  
  476. no_com2_start:
  477.     mov     ax,[esi+0x10000]    ; -->
  478.     cmp     ax,'->'
  479.     jne     no_com2_end
  480.     mov     [com2],0
  481.     inc     esi
  482.     jmp     byte_done
  483.  
  484. no_com2_end:
  485.     mov     eax,[esi+0x10000]    ; <script
  486.     cmp     eax,'<scr'
  487.     jne     no_script_start
  488.     mov     [script],1
  489.  
  490. no_script_start:
  491.     mov     eax,[esi+0x10000]    ; /script>
  492.     cmp     eax,'</sc'
  493.     jne     no_script_end
  494.     mov     [script],0
  495.     inc     esi
  496.     jmp     byte_done
  497.  
  498. no_script_end:
  499.     cmp     [command_on_off],0
  500.     jne     no_print
  501.  
  502.     cmp     [com2],0
  503.     jne     no_print
  504.  
  505.     cmp     [script],0
  506.     jne     no_print
  507.  
  508.     mov     al,[esi+0x10000] ; &
  509.     cmp     al,'&'
  510.     jne     no_nbsp
  511.  
  512. newsps:
  513.     inc     esi
  514.     mov     al,[esi+0x10000] ;
  515.     cmp     al,';'
  516.     jne     newsps
  517.     jmp     byte_done
  518.  
  519. no_nbsp:
  520.     cmp     al,13
  521.     jne     no_lb
  522.     jmp     byte_done
  523.  
  524. no_lb:
  525.     cmp     al,10
  526.     jne     no_lf
  527.     jmp     byte_done
  528.  
  529. no_lf:
  530.     mov     ebx,[pagey]
  531.     imul    ebx,[pagexs]
  532.     add     ebx,[pagex]
  533.     add     ebx,0x20000
  534.     and     eax,0xff
  535.     cmp     eax,31
  536.     jbe     byte_done
  537.     cmp     [lastletter],al
  538.     jne     letter_ok
  539.     cmp     al,' '
  540.     je      byte_done
  541.  
  542. letter_ok:
  543.     mov     [ebx],al
  544.     mov     dl,[text_type]
  545.     mov     [ebx+0x10000],dl
  546.     mov     [pageyinc],0
  547.     mov     [lastletter],al
  548.  
  549.     inc     [pagex]
  550.  
  551.     mov     ebx,[pagex]
  552.     cmp     ebx,[pagexs]
  553.     jb      byte_done
  554.     mov     [pagex],0
  555.     inc     [pagey]
  556.  
  557.     jmp     byte_done
  558.  
  559. no_print:
  560.     ; HTML -COMMAND
  561.  
  562.     mov     ax,[esi+0x10000]    ; b> bold
  563.     cmp     ax,'b>'
  564.     jne     no_bold_start
  565.     mov     [text_type],2
  566.  
  567. no_bold_start:
  568.     mov     eax,[esi+0x10000]    ; /b bold end
  569.     cmp     eax,'</b>'
  570.     jne     no_bold_end
  571.     mov     [text_type],1
  572.     add     esi,2
  573.  
  574. no_bold_end:
  575.     mov     ax,[esi+0x10000]    ; <a
  576.     cmp     ax,'a '
  577.     jne     no_link_start
  578.     mov     [text_type],128
  579.     add     esi,2
  580.  
  581. no_link_start:
  582.     mov     ax,[esi+0x10000]    ; /a
  583.     cmp     ax,'/a'
  584.     jne     no_link_end2
  585.     mov     [text_type],1
  586.     add     esi,0
  587.  
  588. no_link_end2:
  589.     mov     ax,[esi+0x10000]
  590.     cmp     ax,'br'
  591.     jne     no_br
  592.     call    linefeed
  593.     inc     esi
  594.  
  595. no_br:
  596.     mov     ax,[esi+0x10000]
  597.     cmp     ax,'td'
  598.     jne     no_td
  599.     call    linefeed
  600.     inc     esi
  601.  
  602. no_td:
  603.     mov     eax,[esi+0x10000]
  604.     cmp     eax,'tabl'
  605.     jne     no_table
  606.     call    linefeed
  607.     add     esi,3
  608.  
  609. no_table:
  610. byte_done:
  611.     inc     esi
  612.     cmp     esi,[pos]
  613.     jbe     newbyte
  614.  
  615.     mov     [display_from],0
  616.     call    display_page
  617.  
  618.     popa
  619.     ret
  620.  
  621.  
  622.  
  623. ;****************************************************************************
  624. ;    Function
  625. ;       linefeed
  626. ;
  627. ;   Description
  628. ;
  629. ;
  630. ;****************************************************************************
  631. linefeed:
  632.     cmp     [pageyinc],2
  633.     jge     nolf
  634.  
  635.     mov     [pagex],0
  636.     inc     [pagey]
  637.     inc     [pageyinc]
  638.  
  639. nolf:
  640.     ret
  641.  
  642.  
  643.  
  644. ;****************************************************************************
  645. ;    Function
  646. ;       display_page
  647. ;
  648. ;   Description
  649. ;       Renders the text decoded by draw_page
  650. ;
  651. ;****************************************************************************
  652. display_page:
  653.     pusha
  654.  
  655.     mov     eax,0
  656.     mov     ebx,0
  657.  
  658. newpxy:
  659.     push    eax
  660.     push    ebx
  661.  
  662.     mov     eax,13       ; background for letter
  663.     mov     ebx,[esp+4]
  664.     imul    ebx,6
  665.     add     ebx,[dpx]
  666.     shl     ebx,16
  667.     add     ebx,6
  668.     mov     ecx,[esp+0]
  669.     imul    ecx,10
  670.     add     ecx,[dpy]
  671.     shl     ecx,16
  672.     add     ecx,10
  673.     mov     edx,0xffffff
  674.     mcall
  675.  
  676.     mov     eax,4
  677.     mov     ebx,[esp+4]
  678.     imul    ebx,6
  679.     add     ebx,[dpx]
  680.     shl     ebx,16
  681.  
  682.     mov     bx,[esp+0]
  683.     imul    bx,10
  684.     add     bx,word [dpy]
  685.  
  686.     mov     esi,[esp]
  687.     imul    esi,[pagexs]
  688.     add     esi,[esp+4]
  689.  
  690.     mov     edx,[display_from]
  691.     imul    edx,[pagexs]
  692.     add     edx,0x20000
  693.     add     edx,esi
  694.  
  695.     movzx   ecx,byte [edx+0x10000]
  696.     cmp     ecx,1
  697.     jne     noecx1
  698.     mov     ecx,0x000000
  699.  
  700. noecx1:
  701.     movzx   ecx,byte [edx+0x10000]
  702.     cmp     ecx,2
  703.     jne     noecx2
  704.     mov     ecx,0xff0000
  705.  
  706. noecx2:
  707.     cmp     ecx,128
  708.     jne     noecx128
  709.     mov     ecx,0x0000ff
  710.  
  711. noecx128:
  712.     mov     esi,1
  713.  
  714.     mcall
  715.  
  716.     pop     ebx
  717.     pop     eax
  718.  
  719.     inc     eax
  720.     cmp     eax,[pagexs]
  721.     jb      newpxy
  722.     mov     eax,0
  723.     inc     ebx
  724.     cmp     ebx,30
  725.     jb      newpxy
  726.  
  727.     popa
  728.     ret
  729.  
  730.  
  731.  
  732.  
  733. ;****************************************************************************
  734. ;    Function
  735. ;       socket_commands
  736. ;
  737. ;   Description
  738. ;       opens or closes the socket
  739. ;
  740. ;****************************************************************************
  741. socket_commands:
  742.     cmp     ah,22       ; open socket
  743.     jnz     tst3
  744.  
  745.     ; Clear all page memory
  746.     mov     edi,0x10000
  747.     mov     ecx,0x30000
  748.     mov     al,0
  749.     cld
  750.     rep     stosb
  751.  
  752.     ; Parse the entered url
  753.     call    parse_url
  754.  
  755.     ; Get a free port number
  756.         mov         ecx, 1000           ; local port starting at 1000
  757. getlp1:
  758.         inc         ecx
  759.         push    ecx
  760.         mov         eax, 53
  761.         mov         ebx, 9
  762.         mcall
  763.         pop         ecx
  764.         cmp         eax, 0                      ; is this local port in use?
  765.         jz              getlp1              ; yes - so try next
  766.  
  767.     mov     eax,53
  768.     mov     ebx,5
  769.     mov     edx,80
  770.     mov     esi,dword [server_ip]
  771.     mov     edi,1
  772.     mcall
  773.     mov     [socket], eax
  774.  
  775.     mov     [pos],0
  776.     mov     [pagex],0
  777.     mov     [pagey],0
  778.     mov     [pagexs],80
  779.     mov     [command_on_off],0
  780.  
  781.     ret
  782.  
  783. tst3:
  784.     cmp     ah,24     ; close socket
  785.     jnz     no_24
  786.  
  787.     mov     eax,53
  788.     mov     ebx,8
  789.     mov     ecx,[socket]
  790.     mcall
  791.  
  792.     call    draw_page
  793.  
  794.     ret
  795.  
  796. no_24:
  797.     ret
  798.  
  799.  
  800.  
  801. ;****************************************************************************
  802. ;    Function
  803. ;       parse_url
  804. ;
  805. ;   Description
  806. ;       parses the full url typed in by the user into a web address ( that
  807. ;       can be turned into an IP address by DNS ) and the page to display
  808. ;       DNS will be used to translate the web address into an IP address, if
  809. ;       needed.
  810. ;       url is at document_user and will be space terminated.
  811. ;       web address goes to webAddr and is space terminated.
  812. ;       ip address goes to server_ip
  813. ;       page goes to document and is space terminated.
  814. ;
  815. ;       Supported formats:
  816. ;       <protocol://>address<page>
  817. ;       <protocol> is optional, removed and ignored - only http supported
  818. ;       <address> is required. It can be an ip address or web address
  819. ;       <page> is optional and must start with a leading / character
  820. ;
  821. ;****************************************************************************
  822. parse_url:
  823.     ; First, reset destination variables
  824.     cld
  825.     mov     al, ' '
  826.     mov     edi, document
  827.     mov     ecx,URLMAXLEN
  828.     rep     stosb
  829.     mov     edi, webAddr
  830.     mov     ecx,URLMAXLEN
  831.     rep     stosb
  832.     mov     al, '/'
  833.     mov     [document], al
  834.  
  835.     mov     esi, document_user
  836.     ; remove any leading protocol text
  837.     mov     ecx, URLMAXLEN
  838.     mov     ax, '//'
  839.  
  840. pu_000:
  841.     cmp     [esi], byte ' '     ; end of text?
  842.     je      pu_002              ; yep, so not found
  843.     cmp     word [esi], ax
  844.     je      pu_001              ; Found it, so esi+2 is start
  845.     inc     esi
  846.     loop    pu_000
  847.  
  848. pu_002:
  849.     ; not found, so reset esi to start
  850.     mov     esi, document_user -2
  851.  
  852. pu_001:
  853.     add     esi, 2
  854.  
  855.     mov     ebx, esi    ; save address of start of web address
  856.     mov     edi, document_user + URLMAXLEN  ; end of string
  857.  
  858.     ; look for page delimiter - it's a '/' character
  859. pu_003:
  860.     cmp     [esi], byte ' '     ; end of text?
  861.     je      pu_004              ; yep, so none found
  862.     cmp     esi, edi            ; end of string?
  863.     je      pu_004              ; yep, so none found
  864.     cmp     [esi], byte '/'     ; delimiter?
  865.     je      pu_005              ; yep - process it
  866.     inc     esi
  867.     jmp     pu_003
  868.  
  869. pu_005:
  870.     ; copy page to document address
  871.     ; esi = delimiter
  872.     push    esi
  873.     inc     esi
  874.     mov     ecx, edi            ; end of document_user
  875.     mov     edi, document
  876.     cld
  877.  
  878. pu_006:
  879.     movsb
  880.     cmp     esi, ecx
  881.     je      pu_007              ; end of string?
  882.     cmp     [esi], byte ' '     ; end of text
  883.     je      pu_007
  884.     jmp     pu_006
  885.  
  886. pu_007:
  887.     pop     esi                 ; point esi to '/' delimiter
  888.  
  889. pu_004:
  890.     ; copy web address to webAddr
  891.     ; start in ebx, end in esi-1
  892.     mov     ecx, esi
  893.     mov     esi, ebx
  894.     mov     edi, webAddr
  895.     cld
  896.  
  897. pu_008:
  898.     movsb
  899.     cmp     esi, ecx
  900.     je      pu_009
  901.     jmp     pu_008
  902.  
  903. pu_009:
  904.     ; For debugging, display resulting strings
  905.  
  906. if DEBUGGING_STATE = DEBUGGING_ENABLED
  907.     mov     esi, document_user
  908.     call    debug_print_string
  909.     mov     esi, webAddr
  910.     call    debug_print_string
  911.     mov     esi, document
  912.     call    debug_print_string
  913. end if
  914.  
  915.     ; Look up the ip address, or was it specified?
  916.     mov     al, [webAddr]
  917.     cmp     al, '0'
  918.     jb      pu_010              ; Resolve address
  919.     cmp     al, '9'
  920.     ja      pu_010              ; Resolve address
  921.  
  922.  
  923. if DEBUGGING_STATE = DEBUGGING_ENABLED
  924.     mov     esi, str2       ; print gotip
  925.     call    debug_print_string
  926. end if
  927.  
  928.     ; Convert address
  929.     mov     esi,webAddr-1
  930.     mov     edi,server_ip
  931.     xor     eax,eax
  932. ip1:
  933.     inc     esi
  934.     cmp     [esi],byte '0'
  935.     jb      ip2
  936.     cmp     [esi],byte '9'
  937.     jg      ip2
  938.     imul    eax,10
  939.     movzx   ebx,byte [esi]
  940.     sub     ebx,48
  941.     add     eax,ebx
  942.     jmp     ip1
  943. ip2:
  944.     mov     [edi],al
  945.     xor     eax,eax
  946.     inc     edi
  947.     cmp     edi,server_ip+3
  948.     jbe     ip1
  949.  
  950.     jmp     pu_011
  951.  
  952. pu_010:
  953.  
  954. if DEBUGGING_STATE = DEBUGGING_ENABLED
  955.     mov     esi, str1       ; print resolving
  956.     call    debug_print_string
  957. end if
  958.  
  959.     ; Resolve Address
  960.     call    translateData       ; Convert domain & DNS IP address
  961.     call    resolveDomain       ; get ip address
  962.  
  963. if DEBUGGING_STATE = DEBUGGING_ENABLED
  964.     mov     esi, str3
  965.     call    debug_print_string
  966. end if
  967.  
  968. pu_011:
  969.  
  970.     ; Done
  971.     ret
  972.  
  973.  
  974. ;***************************************************************************
  975. ;   Function
  976. ;      translateData
  977. ;
  978. ;   Description
  979. ;      Coverts the domain name and DNS IP address typed in by the user into
  980. ;      a format suitable for the IP layer.
  981. ;
  982. ;    The ename, in query, is converted and stored in dnsMsg
  983. ;
  984. ;***************************************************************************
  985. translateData:
  986.  
  987.     ; first, get the IP address of the DNS server
  988.     ; Then, build up the request string.
  989.  
  990.  
  991.     ; Build the request string
  992.  
  993.  
  994.     mov     eax, 0x00010100
  995.     mov     [dnsMsg], eax
  996.     mov     eax, 0x00000100
  997.     mov     [dnsMsg+4], eax
  998.     mov     eax, 0x00000000
  999.     mov     [dnsMsg+8], eax
  1000.  
  1001.     ; domain name goes in at dnsMsg+12
  1002.     mov     esi, dnsMsg + 12        ; location of label length
  1003.     mov     edi, dnsMsg + 13        ; label start
  1004.     mov     edx, webAddr
  1005.     mov     ecx, 12                  ; total string length so far
  1006.  
  1007. td002:
  1008.     mov     [esi], byte 0
  1009.     inc     ecx
  1010.  
  1011. td0021:
  1012.     mov     al, [edx]
  1013.     cmp     al, ' '
  1014.     je      td001                   ; we have finished the string translation
  1015.     cmp     al, '.'                 ; we have finished the label
  1016.     je      td004
  1017.  
  1018.     inc     byte [esi]
  1019.     inc     ecx
  1020.     mov     [edi], al
  1021.     inc     edi
  1022.     inc     edx
  1023.     jmp     td0021
  1024.  
  1025. td004:
  1026.     mov     esi, edi
  1027.     inc     edi
  1028.     inc     edx
  1029.     jmp     td002
  1030.  
  1031.  
  1032.  
  1033.     ; write label len + label text
  1034.  
  1035. td001:
  1036.     mov     [edi], byte 0
  1037.     inc     ecx
  1038.     inc     edi
  1039.     mov     [edi], dword 0x01000100
  1040.     add     ecx, 4
  1041.  
  1042.     mov     [dnsMsgLen], ecx
  1043.  
  1044.     ret
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050. ;***************************************************************************
  1051. ;   Function
  1052. ;      resolveDomain
  1053. ;
  1054. ;   Description
  1055. ;       Sends a question to the dns server
  1056. ;       works out the IP address from the response from the DNS server
  1057. ;
  1058. ;***************************************************************************
  1059. resolveDomain:
  1060.     ; Get a free port number
  1061.         mov         ecx, 1000           ; local port starting at 1000
  1062. getlp:
  1063.         inc         ecx
  1064.         push    ecx
  1065.         mov         eax, 53
  1066.         mov         ebx, 9
  1067.         mcall
  1068.         pop         ecx
  1069.         cmp         eax, 0                      ; is this local port in use?
  1070.         jz              getlp               ; yes - so try next
  1071.  
  1072.     ; First, open socket
  1073.     mov     eax, 53
  1074.     mov     ebx, 0
  1075.     mov     edx, 53    ; remote port - dns
  1076.     mov     esi, dword [dns_ip]
  1077.     mcall
  1078.  
  1079.     mov     [socketNum], eax
  1080.  
  1081.     ; write to socket ( request DNS lookup )
  1082.     mov     eax, 53
  1083.     mov     ebx, 4
  1084.     mov     ecx, [socketNum]
  1085.     mov     edx, [dnsMsgLen]
  1086.     mov     esi, dnsMsg
  1087.     mcall
  1088.  
  1089.     ; Setup the DNS response buffer
  1090.  
  1091.     mov     eax, dnsMsg
  1092.     mov     [dnsMsgLen], eax
  1093.  
  1094.     ; now, we wait for
  1095.     ; UI redraw
  1096.     ; UI close
  1097.     ; or data from remote
  1098.  
  1099. ctr001:
  1100.     mov     eax,10                 ; wait here for event
  1101.     mcall
  1102.  
  1103.     cmp     eax,1                  ; redraw request ?
  1104.     je      ctr003
  1105.     cmp     eax,2                  ; key in buffer ?
  1106.     je      ctr004
  1107.     cmp     eax,3                  ; button in buffer ?
  1108.     je      ctr005
  1109.  
  1110.  
  1111.     ; Any data in the UDP receive buffer?
  1112.     mov     eax, 53
  1113.     mov     ebx, 2
  1114.     mov     ecx, [socketNum]
  1115.     mcall
  1116.  
  1117.     cmp     eax, 0
  1118.     je      ctr001
  1119.  
  1120.     ; we have data - this will be the response
  1121. ctr002:
  1122.     mov     eax, 53
  1123.     mov     ebx, 3
  1124.     mov     ecx, [socketNum]
  1125.     mcall                ; read byte - block (high byte)
  1126.  
  1127.     ; Store the data in the response buffer
  1128.     mov     eax, [dnsMsgLen]
  1129.     mov     [eax], bl
  1130.     inc     dword [dnsMsgLen]
  1131.  
  1132.     mov     eax, 53
  1133.     mov     ebx, 2
  1134.     mov     ecx, [socketNum]
  1135.     mcall                ; any more data?
  1136.  
  1137.     cmp     eax, 0
  1138.     jne     ctr002              ; yes, so get it
  1139.  
  1140.     ; close socket
  1141.     mov     eax, 53
  1142.     mov     ebx, 1
  1143.     mov     ecx, [socketNum]
  1144.     mcall
  1145.  
  1146.     mov     [socketNum], dword 0xFFFF
  1147.  
  1148.     ; Now parse the message to get the host IP
  1149.     ; Man, this is complicated. It's described in
  1150.     ; RFC 1035
  1151.  
  1152. if DEBUGGING_STATE = DEBUGGING_ENABLED
  1153.     mov     esi, str4
  1154.     call    debug_print_string
  1155. end if
  1156.  
  1157.     ; 1) Validate that we have an answer with > 0 responses
  1158.     ; 2) Find the answer record with TYPE 0001 ( host IP )
  1159.     ; 3) Finally, copy the IP address to the display
  1160.     ; Note: The response is in dnsMsg
  1161.     ;       The end of the buffer is pointed to by [dnsMsgLen]
  1162.  
  1163.     ; Clear the IP address text
  1164.     mov     [server_ip], dword 0
  1165.  
  1166.     mov     esi, dnsMsg
  1167.  
  1168.     ; Is this a response to my question?
  1169.     mov     al, [esi+2]
  1170.     and     al, 0x80
  1171.     cmp     al, 0x80
  1172.     jne     ctr002a
  1173.  
  1174.     ; Were there any errors?
  1175.     mov     al, [esi+3]
  1176.     and     al, 0x0F
  1177.     cmp     al, 0x00
  1178.     jne     ctr002a
  1179.  
  1180.     ; Is there ( at least 1 ) answer?
  1181.     mov     ax, [esi+6]
  1182.     cmp     ax, 0x00
  1183.     je      ctr002a
  1184.  
  1185.     ; Header validated. Scan through and get my answer
  1186.  
  1187. if DEBUGGING_STATE = DEBUGGING_ENABLED
  1188.     pusha
  1189.     mov     esi, str4
  1190.     call    debug_print_string
  1191.     popa
  1192. end if
  1193.  
  1194.     add     esi, 12             ; Skip to the question field
  1195.  
  1196.     ; Skip through the question field
  1197.     call    skipName
  1198.     add     esi, 4              ; skip past the questions qtype, qclass
  1199.  
  1200. ctr002z:
  1201.     ; Now at the answer. There may be several answers,
  1202.     ; find the right one ( TYPE = 0x0001 )
  1203.     call    skipName
  1204.     mov     ax, [esi]
  1205.     cmp     ax, 0x0100          ; Is this the IP address answer?
  1206.     jne     ctr002c
  1207.  
  1208.     ; Yes! Point esi to the first byte of the IP address
  1209.     add     esi, 10
  1210.  
  1211.     mov     eax, [esi]
  1212.     mov     [server_ip], eax
  1213.     ret
  1214.  
  1215.  
  1216. ctr002c:                        ; Skip through the answer, move to the next
  1217.     add     esi, 8
  1218.     movzx   eax, byte [esi+1]
  1219.     mov     ah, [esi]
  1220.     add     esi, eax
  1221.     add     esi, 2
  1222.  
  1223.     ; Have we reached the end of the msg?
  1224.     ; This is an error condition, should not happen
  1225.     cmp     esi, [dnsMsgLen]
  1226.     jl      ctr002z             ; Check next answer
  1227.     jmp     ctr002a             ; abort
  1228.  
  1229. ctr002a:
  1230.     jmp     ctr001
  1231.  
  1232. ctr003:                         ; redraw
  1233.     call    draw_window
  1234.     jmp     ctr001
  1235.  
  1236. ctr004:                         ; key
  1237.     mov     eax,2               ; just read it and ignore
  1238.     mcall
  1239.     jmp     ctr001
  1240.  
  1241. ctr005:                         ; button
  1242.     mov     eax,17              ; get id
  1243.     mcall
  1244.  
  1245.     mov     dl, ah
  1246.  
  1247.     ; close socket
  1248.     mov     eax, 53
  1249.     mov     ebx, 1
  1250.     mov     ecx, [socketNum]
  1251.     mcall
  1252.  
  1253.     cmp     dl, 1
  1254.     je      exit
  1255.  
  1256.     mov     [socketNum], dword 0xFFFF
  1257.     mov     [server_ip], dword 0
  1258.  
  1259.     ret
  1260.  
  1261.  
  1262.  
  1263. ;***************************************************************************
  1264. ;   Function
  1265. ;      skipName
  1266. ;
  1267. ;   Description
  1268. ;       Increment esi to the first byte past the name field
  1269. ;       Names may use compressed labels. Normally do.
  1270. ;       RFC 1035 page 30 gives details
  1271. ;
  1272. ;***************************************************************************
  1273. skipName:
  1274.     mov     al, [esi]
  1275.     cmp     al, 0
  1276.     je      sn_exit
  1277.     and     al, 0xc0
  1278.     cmp     al, 0xc0
  1279.     je      sn001
  1280.  
  1281.     movzx   eax, byte [esi]
  1282.     inc     eax
  1283.     add     esi, eax
  1284.     jmp     skipName
  1285.  
  1286. sn001:
  1287.     add     esi, 2                          ; A pointer is always at the end
  1288.     ret
  1289.  
  1290. sn_exit:
  1291.     inc     esi
  1292.     ret
  1293.  
  1294.  
  1295.  
  1296. if DEBUGGING_STATE = DEBUGGING_ENABLED
  1297.  
  1298. ;****************************************************************************
  1299. ;    Function
  1300. ;       debug_print_string
  1301. ;
  1302. ;   Description
  1303. ;       prints a string to the debug board, in quotes
  1304. ;
  1305. ;       esi holds ptr to msg to display, which is space or 0 terminated
  1306. ;
  1307. ;       Nothing preserved; I'm assuming a pusha/popa is done before calling
  1308. ;
  1309. ;****************************************************************************
  1310. debug_print_string:
  1311.     push    esi
  1312.     mov     cl, '"'
  1313.     mov     eax,63
  1314.     mov     ebx, 1
  1315.     mcall
  1316.     pop     esi
  1317.  
  1318. dps_000:
  1319.     mov     cl, [esi]
  1320.     cmp     cl, 0
  1321.     je      dps_exit
  1322.     cmp     cl, ' '
  1323.     je      dps_exit
  1324.     jmp     dps_001
  1325.  
  1326. dps_exit:
  1327.     mov     cl, '"'
  1328.     mov     eax,63
  1329.     mov     ebx, 1
  1330.     mcall
  1331.     mov     cl, 13
  1332.     mov     eax,63
  1333.     mov     ebx, 1
  1334.     mcall
  1335.     mov     cl, 10
  1336.     mov     eax,63
  1337.     mov     ebx, 1
  1338.     mcall
  1339.     ret
  1340.  
  1341. dps_001:
  1342.     mov     eax,63
  1343.     mov     ebx, 1
  1344.     push    esi
  1345.     mcall
  1346.  
  1347.     pop     esi
  1348.     inc     esi
  1349.     jmp     dps_000
  1350. end if
  1351.  
  1352.  
  1353. ;****************************************************************************
  1354. ;    Function
  1355. ;       print_text
  1356. ;
  1357. ;   Description
  1358. ;       display the url (full path) text
  1359. ;
  1360. ;****************************************************************************
  1361. print_text:
  1362.     ; Draw a bar to blank out previous text
  1363.     mov     eax,13
  1364.     mov     ebx,30*65536+URLMAXLEN*6  ; 50 should really be [len], and 103 [xa]
  1365.     mov     ecx,[ya]
  1366.     shl     ecx,16
  1367.     mov     cx,9
  1368.     mov     edx,0xFFFFFF
  1369.     mcall
  1370.  
  1371.     ; write text
  1372.     mov     eax,4
  1373.     mov     ebx,30*65536
  1374.     add     ebx,[ya]
  1375.     mov     ecx,0x000000
  1376.     mov     edx,[addr]
  1377.     mov     esi,URLMAXLEN
  1378.     mcall
  1379.  
  1380.     ret
  1381.  
  1382. ;   *********************************************
  1383. ;   *******  WINDOW DEFINITIONS AND DRAW ********
  1384. ;   *********************************************
  1385.  
  1386. draw_window:
  1387.     mov     eax,12                    ; function 12:tell os about windowdraw
  1388.     mov     ebx,1                     ; 1, start of draw
  1389.     mcall
  1390.  
  1391.                                    ; DRAW WINDOW
  1392.     mov     eax,0                     ; function 0 : define and draw window
  1393.     mov     ebx,50*65536+550          ; [x start] *65536 + [x size]
  1394.     mov     ecx,50*65536+400          ; [y start] *65536 + [y size]
  1395.     mov     edx,0x14ffffff            ; color of work area RRGGBB,8->color gl
  1396.     mov     edi,title                 ; WINDOW LABEL
  1397.     mcall
  1398.  
  1399.  
  1400.     mov     esi, URLMAXLEN            ; URL
  1401.     mov     eax,4                     ; function 4 : write text to window
  1402.     mov     ebx,30*65536+38           ; [x start] *65536 + [y start]
  1403.     mov     ecx,0x000000              ; color of text RRGGBB
  1404.     mov     edx,document_user         ; pointer to text beginning
  1405.     mcall
  1406.  
  1407.     mov     eax,38
  1408.     mov     ebx,5*65536+545
  1409.     mov     ecx,60*65536+60
  1410.     mov     edx,0x000000
  1411.     mcall
  1412.  
  1413.     ;mov     eax,38
  1414.     ;mov     ebx,5*65536+545
  1415.     mov     ecx,[winys]
  1416.     shl     ecx,16
  1417.     add     ecx,[winys]
  1418.     sub     ecx,26*65536+26
  1419.     ;mov     edx,0x000000
  1420.     mcall
  1421.                                    ; RELOAD
  1422.     mov     eax,8                     ; function 8 : define and draw button
  1423.     mov     ebx,388*65536+50          ; [x start] *65536 + [x size]
  1424.     mov     ecx,34*65536+14           ; [y start] *65536 + [y size]
  1425.     mov     edx,22                    ; button id
  1426.     mov     esi,0x5588dd              ; button color RRGGBB
  1427.     mcall
  1428.  
  1429.                                    ; URL
  1430.     ;mov     eax,8                     ; function 8 : define and draw button
  1431.     mov     ebx,10*65536+12          ; [x start] *65536 + [x size]
  1432.     mov     ecx,34*65536+12           ; [y start] *65536 + [y size]
  1433.     mov     edx,10                    ; button id
  1434.     ;mov     esi,0x5588dd              ; button color RRGGBB
  1435.     mcall
  1436.  
  1437.                                    ; STOP
  1438.     ;mov     eax,8                     ; function 8 : define and draw button
  1439.     mov     ebx,443*65536+50          ; [x start] *65536 + [x size]
  1440.     mov     ecx,34*65536+14           ; [y start] *65536 + [y size]
  1441.     mov     edx,24                    ; button id
  1442.     ;mov     esi,0x5588dd              ; button color RRGGBB
  1443.     mcall
  1444.  
  1445.                                    ; BUTTON TEXT
  1446.     mov     eax,4                     ; function 4 : write text to window
  1447.     mov     ebx,390*65536+38          ; [x start] *65536 + [y start]
  1448.     mov     ecx,0xffffff              ; color of text RRGGBB
  1449.     mov     edx,button_text           ; pointer to text beginning
  1450.     mov     esi,20                    ; text length
  1451.     mcall
  1452.  
  1453.     call    display_page
  1454.  
  1455.     mov     eax,12                    ; function 12:tell os about windowdraw
  1456.     mov     ebx,2                     ; 2, end of draw
  1457.     mcall
  1458.  
  1459.     ret
  1460.  
  1461.  
  1462. if DEBUGGING_STATE = DEBUGGING_ENABLED
  1463. str1:       db  "Resolving...",0
  1464. str3:       db  "Resolved",0
  1465. str2:       db  "GotIP",0
  1466. str4:       db  "GotResponse",0
  1467. end if
  1468.  
  1469. button_text     db      ' RELOAD    STOP       '
  1470. dpx             dd      25  ; x - start of html page in pixels in window
  1471. dpy             dd      65  ; for y
  1472. lastletter      db      0
  1473. pageyinc        dd      0
  1474. display_from    dd      20
  1475. pos             dd      0x0
  1476. pagex           dd      0x0
  1477. pagey           dd      0x0
  1478. pagexs          dd      80
  1479. command_on_off  dd      0x0
  1480. text_type       db      1
  1481. com2            dd      0x0
  1482. script          dd      0x0
  1483. socket          dd      0x0
  1484.  
  1485. addr            dd  0x0
  1486. ya              dd  0x0
  1487. len             dd  0x00
  1488.  
  1489. title         db      'HTTPC - PgUp/PgDown',0
  1490.  
  1491. server_ip:      db      207,44,212,20
  1492. dns_ip:         db      194,145,128,1
  1493. webAddr:        times 128 db ' '
  1494. document_user:  db      'Click on the button to the left to enter a URL',0
  1495. times  100      db      0x0
  1496. document:       db      '/'
  1497. times  100      db      ' '
  1498.  
  1499. string0:        db      'GET '
  1500.  
  1501. stringh:        db      ' HTTP/1.0',13,10,13,10
  1502. stringh_end:
  1503.  
  1504. status          dd      0x0
  1505. prev_status     dd      0x0
  1506.  
  1507. onoff           dd      0x0
  1508.  
  1509. nextupdate:     dd      0
  1510. winys:          dd      400
  1511.  
  1512. dnsMsgLen:      dd 0
  1513. socketNum:      dd 0xFFFF
  1514. dnsMsg:
  1515. I_END:
  1516.