Subversion Repositories Kolibri OS

Rev

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