Subversion Repositories Kolibri OS

Rev

Rev 485 | Go to most recent revision | Details | Compare with Previous | 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
661 ataualpa 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
31 halyavin 34
 
35
include 'lang.inc'
661 ataualpa 36
include 'macros.inc'
31 halyavin 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
485 heavyiron 52
    mcall
31 halyavin 53
 
485 heavyiron 54
red:                    ; redraw
31 halyavin 55
    call    draw_window
56
 
57
still:
58
    mov     eax,23                 ; wait here for event
59
    mov     ebx,1
485 heavyiron 60
    mcall
31 halyavin 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]
485 heavyiron 78
    mcall
31 halyavin 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]
485 heavyiron 105
    mcall
31 halyavin 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
485 heavyiron 116
    mcall
31 halyavin 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
485 heavyiron 137
    mcall
31 halyavin 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]
485 heavyiron 146
    mcall
31 halyavin 147
 
148
;dpd eax
149
;dps <13,10>
150
 
151
exit:
152
    or      eax,-1                 ; close this program
485 heavyiron 153
    mcall
31 halyavin 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
485 heavyiron 188
    mcall
31 halyavin 189
    cmp     eax,2 ; key?
190
    jz      fbu
191
    jmp     still
192
 
193
fbu:
194
    mov     eax,2
485 heavyiron 195
    mcall  ; get key
31 halyavin 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
485 heavyiron 257
    mcall
31 halyavin 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
485 heavyiron 271
    mcall
31 halyavin 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
485 heavyiron 278
    mcall
31 halyavin 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
485 heavyiron 297
    mcall
31 halyavin 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
485 heavyiron 312
    mcall
31 halyavin 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
485 heavyiron 320
    mcall
31 halyavin 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
485 heavyiron 328
    mcall
31 halyavin 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]
485 heavyiron 355
    mcall
31 halyavin 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]
485 heavyiron 364
    mcall
31 halyavin 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
485 heavyiron 378
    mcall
31 halyavin 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]    ; 
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]    ; 
486
    cmp     eax,'
487
    jne     no_script_start
488
    mov     [script],1
489
 
490
no_script_start:
491
    mov     eax,[esi+0x10000]    ; /script>
492
    cmp     eax,'
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,''
570
    jne     no_bold_end
571
    mov     [text_type],1
572
    add     esi,2
573
 
574
no_bold_end:
575
    mov     ax,[esi+0x10000]    ; 
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
485 heavyiron 674
    mcall
31 halyavin 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
 
485 heavyiron 714
    mcall
31 halyavin 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
485 heavyiron 762
        mcall
31 halyavin 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
485 heavyiron 772
    mcall
31 halyavin 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]
485 heavyiron 790
    mcall
31 halyavin 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
;       address
817
;        is optional, removed and ignored - only http supported
818
;       
is required. It can be an ip address or web address
819
;        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
485 heavyiron 1067
        mcall
31 halyavin 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]
485 heavyiron 1077
    mcall
31 halyavin 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
485 heavyiron 1087
    mcall
31 halyavin 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
485 heavyiron 1101
    mcall
31 halyavin 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]
485 heavyiron 1115
    mcall
31 halyavin 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]
485 heavyiron 1125
    mcall                ; read byte - block (high byte)
31 halyavin 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]
485 heavyiron 1135
    mcall                ; any more data?
31 halyavin 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]
485 heavyiron 1144
    mcall
31 halyavin 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
485 heavyiron 1238
    mcall
31 halyavin 1239
    jmp     ctr001
1240
 
1241
ctr005:                         ; button
1242
    mov     eax,17              ; get id
485 heavyiron 1243
    mcall
31 halyavin 1244
 
1245
    mov     dl, ah
1246
 
1247
    ; close socket
1248
    mov     eax, 53
1249
    mov     ebx, 1
1250
    mov     ecx, [socketNum]
485 heavyiron 1251
    mcall
31 halyavin 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
485 heavyiron 1315
    mcall
31 halyavin 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
485 heavyiron 1330
    mcall
31 halyavin 1331
    mov     cl, 13
1332
    mov     eax,63
1333
    mov     ebx, 1
485 heavyiron 1334
    mcall
31 halyavin 1335
    mov     cl, 10
1336
    mov     eax,63
1337
    mov     ebx, 1
485 heavyiron 1338
    mcall
31 halyavin 1339
    ret
1340
 
1341
dps_001:
1342
    mov     eax,63
1343
    mov     ebx, 1
1344
    push    esi
485 heavyiron 1345
    mcall
31 halyavin 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
485 heavyiron 1369
    mcall
31 halyavin 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
485 heavyiron 1378
    mcall
31 halyavin 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
485 heavyiron 1389
    mcall
31 halyavin 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]
661 ataualpa 1395
    mov     edx,0x14ffffff            ; color of work area RRGGBB,8->color gl
485 heavyiron 1396
    mov     edi,title                 ; WINDOW LABEL
1397
    mcall
31 halyavin 1398
 
661 ataualpa 1399
 
31 halyavin 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
485 heavyiron 1405
    mcall
31 halyavin 1406
 
1407
    mov     eax,38
1408
    mov     ebx,5*65536+545
1409
    mov     ecx,60*65536+60
1410
    mov     edx,0x000000
485 heavyiron 1411
    mcall
31 halyavin 1412
 
485 heavyiron 1413
    ;mov     eax,38
1414
    ;mov     ebx,5*65536+545
31 halyavin 1415
    mov     ecx,[winys]
1416
    shl     ecx,16
1417
    add     ecx,[winys]
1418
    sub     ecx,26*65536+26
485 heavyiron 1419
    ;mov     edx,0x000000
1420
    mcall
31 halyavin 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
485 heavyiron 1427
    mcall
31 halyavin 1428
 
1429
                                   ; URL
485 heavyiron 1430
    ;mov     eax,8                     ; function 8 : define and draw button
31 halyavin 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
485 heavyiron 1434
    ;mov     esi,0x5588dd              ; button color RRGGBB
1435
    mcall
31 halyavin 1436
 
1437
                                   ; STOP
485 heavyiron 1438
    ;mov     eax,8                     ; function 8 : define and draw button
31 halyavin 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
485 heavyiron 1442
    ;mov     esi,0x5588dd              ; button color RRGGBB
1443
    mcall
31 halyavin 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
485 heavyiron 1451
    mcall
31 halyavin 1452
 
1453
    call    display_page
1454
 
1455
    mov     eax,12                    ; function 12:tell os about windowdraw
1456
    mov     ebx,2                     ; 2, end of draw
485 heavyiron 1457
    mcall
31 halyavin 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
 
485 heavyiron 1489
title         db      'HTTPC - PgUp/PgDown',0
31 halyavin 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: