Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 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]    ; 
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]    ; 
490
    cmp     eax,'
491
    jne     no_script_start
492
    mov     [script],1
493
 
494
no_script_start:
495
    mov     eax,[esi+0x10000]    ; /script>
496
    cmp     eax,'
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,''
574
    jne     no_bold_end
575
    mov     [text_type],1
576
    add     esi,2
577
 
578
no_bold_end:
579
    mov     ax,[esi+0x10000]    ; 
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
;       address
821
;        is optional, removed and ignored - only http supported
822
;       
is required. It can be an ip address or web address
823
;        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: