Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                        ;;
  3. ;;  VGA.INC                                               ;;
  4. ;;                                                        ;;
  5. ;;  640x480 mode 0x12 VGA functions for MenuetOS          ;;
  6. ;;                                                        ;;
  7. ;;  Paul Butcher, paul.butcher@asa.co.uk                  ;;
  8. ;;                                                        ;;
  9. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10.  
  11.  
  12.  
  13. paletteVGA:
  14.  
  15. ;16 colour palette
  16.        mov    dx,0x3c8
  17.        mov    al,0
  18.        out    dx,al
  19.  
  20.        mov    ecx,16
  21.        mov    dx,0x3c9
  22.        xor    eax,eax
  23.  
  24.      palvganew:
  25.  
  26.        mov al,0
  27.        test ah,4
  28.        jz palvgalbl1
  29.        add al,31
  30.        test ah,8
  31.        jz palvgalbl1
  32.        add al,32
  33.      palvgalbl1:
  34.        out dx,al  ; red 0,31 or 63
  35.        mov al,0
  36.        test ah,2
  37.        jz palvgalbl2
  38.        add al,31
  39.        test ah,8
  40.        jz palvgalbl2
  41.        add al,32
  42.      palvgalbl2:
  43.        out dx,al  ; blue 0,31 or 63
  44.        mov al,0
  45.        test ah,1
  46.        jz palvgalbl3
  47.        add al,31
  48.        test ah,8
  49.        jz palvgalbl3
  50.        add al,32
  51.      palvgalbl3:
  52.        out dx,al  ; green 0,31 or 63
  53.        add ah,1
  54.        loop palvganew
  55.  
  56.        ret
  57.  
  58.  
  59. vga_putimage:
  60.  
  61.  push ebp ;
  62.  push esi ;
  63.  push edi ;
  64.  
  65.  push eax ;
  66.  push ebx ; +8 [ptrImage]
  67.  push ecx ; +4 [BH]
  68.  push edx ; +0 [xy]
  69.  
  70.  movzx eax,word [esp+2]   ; eax:=x
  71.  movzx ebx,word [esp+0]   ; ebx:=y
  72.  mov ecx,[0x3010]         ;
  73.  add eax,[ecx-twdw]     ; eax+=Xwin
  74.  add ebx,[ecx-twdw+4]   ; ebx+=Ywin
  75.  mov ecx,ebx              ; ecx = y+Ywin
  76.  mov edx,eax              ; edx = x+Xwin
  77.  
  78.  imul ebx, 640*4          ; (y+Ywin)*BytesPerScanLine
  79.  shl eax,2                ; (x+Xwin)*BytesPerPixel
  80.  add eax,ebx              ;
  81.  mov edi,eax              ; store copy
  82.         add eax,[0xfe80]         ; +AddrLFB
  83.  ;entry point in LFB >> EAX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrLFB
  84.  
  85.  shr edi,5                ; change from 4 to 1/8 BytesPerPixel
  86.  add edi,0xa0000          ; + VGABasePtr
  87.  ;VGA start address >> EDI:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrVGA
  88.  
  89.  mov ebx, [0xfe00]        ; ScreenXSize
  90.  inc ebx                  ; +1
  91.  imul ebx,ecx             ; *(y+Ywin)
  92.  mov ebp, ebx             ;
  93.  add ebp, edx             ; +(x+Xwin)
  94.  add ebp, WinMapAddress   ; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
  95.  
  96.  mov esi,[esp+8] ; esi:=AddrImg
  97.  movzx ecx,word [esp+6] ; ecx:=B
  98.  movzx ebx,word [esp+4] ; ebx:=H
  99.  
  100.  ; check limits while draw ?
  101.  
  102.  push ecx ; B
  103.  push eax ; LFB address
  104.  
  105.  mov eax,[0x3010]
  106.  mov ecx,[eax+draw_data-0x3000+0]
  107.  cmp ecx,0
  108.  jnz dbcblimitlset_vga
  109.  
  110.  mov ecx,[eax+draw_data-0x3000+4]
  111.  cmp ecx,0
  112.  jnz dbcblimitlset_vga
  113.  
  114.  mov ecx,[eax+draw_data-0x3000+8]
  115.  cmp ecx,[0xfe00] ; ecx <> Screen X size
  116.  jnz dbcblimitlset_vga
  117.  
  118.  mov ecx,[eax+draw_data-0x3000+12]
  119.  cmp ecx,[0xfe04] ; ecx <> Screen Y size
  120.  jnz dbcblimitlset_vga
  121.  
  122.  pop eax ; LFB address
  123.  pop ecx ; B
  124.  
  125.  push dword 0
  126.  
  127.  jmp pimvga
  128.  
  129.       dbcblimitlset_vga:
  130.  
  131.  pop eax ; LFB address
  132.  pop ecx ; B
  133.  
  134.  push dword 1
  135.  
  136. pimvga:
  137.  push edi
  138.  push esi
  139.  push eax  ; LFB address
  140.  push ecx  ; B
  141.  push ebx  ; H
  142.  push edx  ; x+Xwin
  143.  
  144.  mov ebx,[0x3010]
  145.  mov bl,[ebx+0xe]
  146.  mov bh,[esp+6*4]
  147.  
  148.  cld
  149.  
  150.  npvga:
  151.  
  152.    cmp bl,[ds:ebp]
  153.    jnz impvgano
  154.  
  155. ;   cmp bh,0
  156. ;   jz impvgayes
  157.  
  158. ;   call voodoodbcplimit
  159. ;   jnz impvgano
  160.  
  161. ; impvgayes:
  162.  
  163.    push eax  ; LFB address
  164.    push ebx  ; app no.
  165.    push ecx  ; B
  166.    push edx  ; x+Xwin
  167.  
  168.    mov edx,[esi] ; color
  169.    mov [eax],dx
  170.    shr edx,16
  171.    mov [eax+2],dl
  172.  
  173.    mov eax,[esi] ; color
  174.    mov ecx,[esp] ; x+Xwin
  175.    and ecx,0x07  ; modulo 8
  176.    call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
  177.  
  178.    pop edx
  179.    pop ecx
  180.    pop ebx
  181.    pop eax
  182.  
  183.  impvgano:
  184.  
  185.    add esi,3 ; esi+=3 ptrImage+=3
  186.    add eax,4 ; eax+=4 LFBaddr +=4
  187.    inc ebp
  188.    inc edx ; x+Xwin+n
  189.  
  190.    test edx,0x07  ; test modulo 8
  191.    jnz impvgacont
  192.    inc edi
  193.  
  194.         impvgacont:
  195.    dec ecx ; B--
  196.    jnz npvga
  197.  
  198.       pop edx
  199.       pop ebx
  200.       pop ecx
  201.       pop eax
  202.       pop esi
  203.       pop edi
  204.  
  205.       add edi,640/8  ; add one VGA line
  206.       add eax,640*4  ; add one LFB line
  207.  
  208.       sub ebp, ecx ;  -B
  209.       add ebp, [0xfe00] ;
  210.       inc ebp ; ptrBuffer:=ptrBuffer-B+Screen_Xsize+1
  211.  
  212.       push ecx
  213.       lea ecx,[ecx+ecx*2] ;
  214.       add esi,ecx ; ptrImage:=ptrImage+B*3
  215.       pop ecx
  216.  
  217.       dec ebx ; H--
  218.       jnz near pimvga
  219.  
  220.       add esp,4  ; jump saved limit byte
  221.       pop edx
  222.       pop ecx
  223.       pop ebx
  224.       pop eax
  225.       pop edi
  226.       pop esi
  227.       pop ebp
  228.  
  229.       ret
  230.  
  231.  
  232. VGA_putpixel:
  233.  
  234.  ; eax = x
  235.  ; ebx = y
  236.  
  237.  mov     ecx,eax
  238.  mov     eax, [esp+32-8+4] ; color
  239.  
  240.  imul    ebx, 640*4        ; y*BytesPerLine (Vesa2.0 32)
  241.  lea     edx, [ebx+ecx*4]  ; + x*BytesPerPixel (Vesa2.0 32)
  242.  
  243.  mov     edi,edx
  244.  add     edi, [0xfe80]     ; + LFB address
  245.  mov     [edi], eax        ; write to LFB for Vesa2.0
  246.  
  247.  shr     edx,5             ; change BytesPerPixel to 1/8
  248.  mov     edi,edx
  249.  add     edi, 0x0a0000     ; address of pixel in VGA area
  250.  
  251.  and     ecx,0x07          ; bit no. (modulo 8)
  252.  
  253. setvgapixel:
  254.  
  255.  ; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8)
  256.  
  257.  push   eax
  258.  mov    ebx,eax            ; color
  259.  
  260.  ;mov    al,0x08
  261.  ;mov    dx,0x03ce
  262.  ;out    dx,al             ; select GDC bit mask register
  263.  
  264.  inc    cl
  265.  mov    ax, 0x100
  266.  shr    ax,cl
  267.  mov    dx,0x03cf
  268.  out    dx,al              ; set bit mask for pixel
  269.  
  270.  mov    dl,0
  271.  mov    eax,ebx
  272.  and    eax,0x000000ff     ; blue
  273.  cmp    eax,85
  274.  jle    p13green
  275.  or     dl,0x01
  276.  cmp    eax,170
  277.  jle    p13green
  278.  or     dl,0x08
  279.  
  280. p13green:
  281.  and    ebx,0x0000ff00     ; green
  282.  cmp    ebx,85*256
  283.  jle    p13red
  284.  or     dl,0x02
  285.  cmp    ebx,170*256
  286.  jle    p13red
  287.  or     dl,0x08
  288.  
  289. p13red:
  290.  pop    ebx
  291.  and    ebx,0x00ff0000     ; red
  292.  cmp    ebx,85*256*256
  293.  jle    p13cont
  294.  or     dl,0x04
  295.  cmp    ebx,170*256*256
  296.  jle    p13cont
  297.  or     dl,0x08
  298.  
  299. p13cont:
  300.  mov    al,[edi]           ; dummy read
  301.  mov    [edi],dl
  302.  
  303.  ret
  304.  
  305.  
  306. vga_drawbar:
  307.  
  308.      sub edx,ebx ; edx:=Yend-Ystart=H
  309.      sub ecx,eax ; ecx:=Xend-Xstat=B
  310.  
  311.      push ebp ; +24
  312.      push esi ; +20
  313.      push edi ; +16
  314.      push eax ; +12
  315.      push ebx ; +8
  316.      push ecx ; +4
  317.      push edx ; +0
  318.  
  319.      mov ecx,[0x3010] ;
  320.      add eax,[ecx-twdw] ; eax:=Xwin+x
  321.      add ebx,[ecx-twdw+4] ; ebx:=Ywin+y
  322.      mov ecx, eax ; ecx:=(x+Xwin)
  323.      mov edx, ebx ; edx:=(y+Ywin)
  324.  
  325.      imul ebx, 640/8  ;
  326.      mov edi, ebx ; edi:=BytesPerScanLine*(y+Ywin)
  327.      shr eax, 3 ;
  328.      add edi, eax ;  + (x+Xwin)*BytesPerPixel
  329.      add edi,0xa0000  ; + VGAbaseaddress
  330.  
  331.      mov eax, [0xfe00] ; ScreenXSize
  332.      inc eax ; +1
  333.      imul eax,edx ; *(y+Ywin)
  334.      mov ebp, eax ;
  335.      add ebp, ecx ; +(x+Win)
  336.      add ebp, WinMapAddress ; +AddrBuffer
  337.  
  338.      mov eax, [0xfe08]  ; BytesPerScanLine - LFB
  339.      mul edx            ; *(y+Ywin)
  340.      mov esi,eax
  341.      add esi,ecx
  342.      add esi,ecx
  343.      add esi,ecx
  344.      add esi,ecx        ; + 4*(x+Xwin)
  345.      add esi,[0xfe80]   ; +AddrLFB
  346.  
  347. ; edi:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel + AddrVGA
  348. ; esi:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel + AddrLFB
  349. ; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
  350.  
  351. ; x size
  352.  
  353.      mov eax,[esp+4] ; B [esp+4]
  354.      mov ebx,[esp+0] ; H
  355.  
  356.      mov edx,[esp+16] ; color
  357.      test edx,0x80000000
  358.      jz nodbglvga
  359.  
  360.      ; no color glide for VGA - set to half glide
  361.      shr ebx,1  ; H/2
  362.      sub edx,ebx
  363.      mov [esp+16],edx
  364.      mov ebx,[esp+0] ; reset to H
  365.  
  366.    nodbglvga:
  367.      ; check limits ?
  368.  
  369.      push eax
  370.      push ecx
  371.  
  372.      mov eax,[0x3010]
  373.  
  374.      mov ecx,[eax+draw_data-0x3000+0]
  375.      cmp ecx,0
  376.      jnz dbcblimitlset_vga2
  377.  
  378.      mov ecx,[eax+draw_data-0x3000+4]
  379.      cmp ecx,0
  380.      jnz dbcblimitlset_vga2
  381.  
  382.      mov ecx,[eax+draw_data-0x3000+8]
  383.      cmp ecx,[0xfe00]
  384.      jnz dbcblimitlset_vga2
  385.  
  386.      mov ecx,[eax+draw_data-0x3000+12]
  387.      cmp ecx,[0xfe04]
  388.      jnz dbcblimitlset_vga2
  389.  
  390.      pop ecx
  391.      pop eax
  392.  
  393.      push dword 0
  394.  
  395.      jmp dbnewpivga
  396.  
  397.    dbcblimitlset_vga2:
  398.  
  399.      pop ecx ; x+Xwin
  400.      pop eax ; B
  401.  
  402.      push dword 1
  403.  
  404.    dbnewpivga:
  405.  
  406.      push eax; B
  407.      push ebx ; H
  408.      push edi
  409.      push esi
  410.      push ecx ; x+Xwin
  411.  
  412.      mov   ebx,[0x3010]
  413.      movzx ebx,byte[ebx+0xe]
  414.  
  415.      cld
  416.  
  417.      dbnpvga:
  418.  
  419.        mov dl,[ds:ebp]
  420.  
  421.        cmp dl,bl
  422.        jnz dbimpvgano
  423.  
  424. ;       mov edx,[esp+5*4] ; check limit?
  425. ;       cmp edx,0
  426. ;       jz dbimpvgayes
  427.  
  428. ;       call voodoodbcplimit
  429. ;       jnz  dbimpvgano
  430.  
  431. ;     dbimpvgayes:
  432.  
  433.        push eax ; B
  434.        push ebx
  435.        push ecx ; x+Xwin
  436.  
  437.        mov eax,[esp+12+20+16+4] ; color
  438.        mov ebx,eax
  439.  
  440.        mov [esi],bx    ; write LFB pixel
  441.        shr  ebx,16
  442.        mov  [esi+2],bl
  443.  
  444.        and ecx,0x07 ; modulo 8
  445.        call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
  446.  
  447.        pop ecx
  448.        pop ebx
  449.        pop eax
  450.  
  451.      dbimpvgano:
  452.  
  453.        add esi,4    ; ptrLFB+=4
  454.        inc ebp  ; address buffer
  455.        inc ecx  ; x posn++
  456.        test ecx,0x07  ; test modulo 8
  457.        jnz dbvgacont
  458.        inc edi  ; VGA screen ptr++
  459.  
  460.      dbvgacont:
  461.        dec eax  ; B--  NB ecx in Vesa20 fn?
  462.        jnz dbnpvga
  463.  
  464.    dbnpvgad:
  465.  
  466.      pop ecx
  467.      pop esi
  468.      pop edi
  469.      pop ebx
  470.      pop eax
  471.  
  472.      add esi,[0xfe08]            ; ptrLFB+=BytesPerScanLine
  473.      add edi,640/8               ; ptrScreen+=BytesPerScanLine
  474.  
  475.      add ebp,[0xfe00]            ;
  476.      sub ebp, eax                ; was ecx in vesa20 fn?
  477.      inc ebp                     ; ptrBuffer:=ptrBuffer-B+BytesPerLine+1
  478.  
  479.      dec ebx                     ; H--
  480.      jz nodbnewpivga             ; H<>0
  481.  
  482.      jmp dbnewpivga
  483.  
  484.    nodbnewpivga:
  485.  
  486.      add esp,7*4   ; NB includes limit check flag
  487.      ;pop ebx
  488.      ;pop eax
  489.      ;pop edi
  490.      ;pop esi
  491.      pop ebp
  492.  
  493.      ;pop edx
  494.      ;pop ecx
  495.  
  496.      ret
  497.  
  498.  
  499. vga_drawbackground_tiled:
  500.  
  501.      push ebp
  502.      push eax
  503.      push ebx
  504.      push ecx
  505.      push edx
  506.  
  507.      mov edx,dword [0x400000-8] ; B
  508.      add edx,dword [WinMapAddress-8] ; +B
  509.      add edx,dword [WinMapAddress-8] ; +B
  510.      push edx
  511.  
  512.      mov eax,[draw_data+32+0] ; x start:=(x+Xwin)
  513.      mov ebx,[draw_data+32+4] ; y start:=(y+Ywin)
  514.      mov ecx,eax
  515.      mov edx,ebx
  516.  
  517.      imul edx, 640*4          ; (y+Ywin)*BytesPerScanLine
  518.      shl ecx,2                ; (x+Xwin)*BytesPerPixel
  519.      add ecx,edx              ;
  520.      mov ebp,ecx              ; store copy
  521.      add ecx,[0xfe80]         ; +AddrLFB
  522.   ;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
  523.  
  524.      shr ebp,5                ; change from 4 to 1/8 BytesPerPixel
  525.      add ebp,0xa0000          ; + VGABasePtr
  526.   ;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrV
  527.  
  528.  
  529.      call calculate_edi
  530.  
  531.    dp3vga:                            ; MAIN LOOP
  532.  
  533.      cmp [edi+WinMapAddress],byte 1     ; ptrBuffer^<>byte(1)
  534.      je  ybgpvga
  535.  
  536.      jmp nbgpvga
  537.  
  538.    ybgpvga:
  539.  
  540.      push eax  ; x
  541.      push ebx  ; y
  542.      push ecx  ; LFB address
  543.  
  544.      mov ecx,dword [WinMapAddress-8]    ; B
  545.      xor edx,edx                   ; edx:=0
  546.      div ecx                       ; Xstart/B
  547.  
  548.      ; eax=Int(qn) edx:=Rem
  549.  
  550.      lea esi,[edx+edx*2]           ; esi:=edx*3
  551.  
  552.      mov ecx,dword [WinMapAddress-4]    ; ecx:=H
  553.      mov eax,[esp+4]               ; eax:=Ystart
  554.      xor edx,edx                   ;
  555.      div ecx                       ; Ystart/H
  556.  
  557.      mov eax,edx                   ; eax:=Rem
  558.      xor edx,edx                   ;
  559.      mov ebx,[esp+12]              ; ebx:=B*3
  560.      mul ebx                       ;
  561.      add esi,eax                   ;
  562.  
  563.      mov eax,[esi+0x300000]        ; color
  564.      and eax,0xffffff
  565.  
  566.      mov ecx, [esp]   ; LFB address
  567.      mov ebx,eax      ; copy color
  568.      mov [ecx],bx
  569.      shr ebx,16
  570.      mov [ecx+2],bl
  571.  
  572.      xchg edi, ebp
  573.      mov  ecx,[esp+8]     ; x position
  574.      and  ecx,0x07        ; x modulo 8
  575.      call setvgapixel     ; eax=color, ecx=x%8, edi=VGA address
  576.      xchg ebp, edi
  577.  
  578.      pop ecx
  579.      pop ebx
  580.      pop eax
  581.  
  582.    nbgpvga:
  583.  
  584.      inc eax                       ; x++
  585.      cmp eax,[draw_data+32+8]         ; X > xend?
  586.      jg  nodp3vga
  587.  
  588.      test eax,0x07                 ; x test modulo 8
  589.      jnz hook1vga
  590.      inc ebp                       ; VGA address++
  591.  
  592.    hook1vga:
  593.      add ecx,4                     ; LFB address += 4
  594.      inc edi                       ; ptrBuffer++
  595.      add esi,3                     ; ptrImage+=3
  596.      jmp dp3vga
  597.  
  598.    nodp3vga:
  599.  
  600.      mov eax,[draw_data+32+0]         ; x+Xwin
  601.      inc ebx                       ; y position
  602.      mov ecx,eax
  603.      mov edx,ebx
  604.  
  605.      imul edx, 640*4          ; (y+Ywin)*BytesPerScanLine
  606.      shl ecx,2                ; (x+Xwin)*BytesPerPixel
  607.      add ecx,edx              ;
  608.      mov ebp,ecx              ; store copy
  609.      add ecx,[0xfe80]         ; +AddrLFB
  610.     ;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
  611.  
  612.  
  613.      shr ebp,5                ; change from 4 to 1/8 BytesPerPixel
  614.      add ebp,0xa0000          ; + VGABasePtr
  615.    ;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrV
  616.  
  617.  
  618.      call calculate_edi
  619.  
  620.      cmp ebx,[draw_data+32+12]         ; Y > yend
  621.      jg  dp4vga
  622.  
  623.      jmp dp3vga
  624.  
  625.    dp4vga:
  626.  
  627.      add esp,4
  628.  
  629.      pop edx
  630.      pop ecx
  631.      pop ebx
  632.      pop eax
  633.      pop ebp
  634.  
  635.      ret
  636.  
  637. ; ----------
  638.  
  639.  
  640.  
  641. vga_drawbackground_stretch:
  642.  
  643.  
  644.      push ebp
  645.      push eax
  646.      push ebx
  647.      push ecx
  648.      push edx
  649.  
  650.      mov edx,dword [WinMapAddress-8] ; B
  651.      add edx,dword [WinMapAddress-8] ; +B
  652.      add edx,dword [WinMapAddress-8] ; +B
  653.      push edx
  654.  
  655.      mov eax,[draw_data+32+0] ; x start:=(x+Xwin)
  656.      mov ebx,[draw_data+32+4] ; y start:=(y+Ywin)
  657.      mov ecx,eax
  658.      mov edx,ebx
  659.  
  660.      imul edx, 640*4          ; (y+Ywin)*BytesPerScanLine
  661.      shl ecx,2                ; (x+Xwin)*BytesPerPixel
  662.      add ecx,edx              ;
  663.      mov ebp,ecx              ; store copy
  664.      add ecx,[0xfe80]         ; +AddrLFB
  665.    ;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
  666.  
  667.      shr ebp,5                ; change from 4 to 1/8 BytesPerPixel
  668.      add ebp,0xa0000          ; + VGABasePtr
  669.    ;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrV
  670.  
  671.  
  672.      call calculate_edi
  673.  
  674.    sdp3vga:                            ; MAIN LOOP
  675.  
  676.      cmp [edi+WinMapAddress],byte 1     ; ptrBuffer^<>byte(1)
  677.      je  sybgpvga
  678.  
  679.      jmp snbgpvga
  680.  
  681.    sybgpvga:
  682.  
  683.      push eax   ; x
  684.      push ebx   ; y
  685.      push ecx   ; LFB address
  686.  
  687.      mov   eax,dword [WinMapAddress-8]  ; B
  688.      xor   edx,edx
  689.      mov   ebx,[esp+8]             ; Xstart
  690.      mul   ebx                     ; B*Xstart
  691.      xor   edx,edx
  692.      mov   ebx,[0xfe00]            ; x screen width
  693.      div   ebx                     ; B*Xstart/xwidth
  694.      lea   esi,[eax+eax*2]         ; *3
  695.      mov   eax,dword [WinMapAddress-4]  ; H
  696.      xor   edx,edx
  697.      mov   ebx,[esp+4]             ; Ystart
  698.      mul   ebx                     ; H*Ystart
  699.      xor   edx,edx
  700.      mov   ebx,[0xfe04]            ; y screen height
  701.      div   ebx                     ; H*Ystart/yheight
  702.  
  703.      xor   edx,edx
  704.      mov   ebx,[esp+12]             ; B*3
  705.      mul   ebx                     ;
  706.      add   esi,eax
  707.      mov   eax,[esi+0x300000]      ; color
  708.      and   eax,0xffffff
  709.  
  710.      mov   ecx, [esp]   ; LFB address
  711.      mov   ebx,eax      ; copy color
  712.      mov   [ecx],bx
  713.      shr   ebx,16
  714.      mov   [ecx+2],bl
  715.  
  716.      xchg  edi, ebp
  717.      mov   ecx,[esp+8]     ; x position
  718.      and   ecx,0x07        ; x modulo 8
  719.      call  setvgapixel     ; eax=color, ecx=x%8, edi=VGA address
  720.      xchg  ebp, edi        ; ebp+=3
  721.  
  722.      pop ecx
  723.      pop ebx
  724.      pop eax
  725.  
  726.    snbgpvga:
  727.  
  728.      inc eax                       ; x++
  729.      cmp eax,[draw_data+32+8]         ; X > xend?
  730.      jg  snodp3vga
  731.  
  732.      test eax,0x07                 ; x test modulo 8
  733.      jnz shook1vga
  734.      inc ebp                       ; VGA address++
  735.  
  736.    shook1vga:
  737.      add ecx,4                     ; LFB address += 4
  738.      inc edi                       ; ptrBuffer++
  739.      add esi,3                     ; ptrImage+=3
  740.      jmp sdp3vga
  741.  
  742.    snodp3vga:
  743.  
  744.      mov eax,[draw_data+32+0]         ; x+Xwin
  745.      inc ebx                       ; y position
  746.      mov ecx,eax
  747.      mov edx,ebx
  748.  
  749.      imul edx, 640*4          ; (y+Ywin)*BytesPerScanLine
  750.      shl ecx,2                ; (x+Xwin)*BytesPerPixel
  751.      add ecx,edx              ;
  752.      mov ebp,ecx              ; store copy
  753.      add ecx,[0xfe80]         ; +AddrLFB
  754.   ;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
  755.  
  756.  
  757.      shr ebp,5                ; change from 4 to 1/8 BytesPerPixel
  758.      add ebp,0xa0000          ; + VGABasePtr
  759.           ;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+A
  760.  
  761.  
  762.      call calculate_edi
  763.  
  764.      cmp ebx,[draw_data+32+12]        ; Y > yend
  765.      jg  sdp4vga
  766.  
  767.      jmp sdp3vga
  768.  
  769.    sdp4vga:
  770.  
  771.      add esp,4
  772.  
  773.      pop edx
  774.      pop ecx
  775.      pop ebx
  776.      pop eax
  777.      pop ebp
  778.  
  779.      ret
  780.  
  781.  
  782.