⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vga.inc

📁 MenuetOS是一个用汇编开发的32/64位PC操作系统
💻 INC
📖 第 1 页 / 共 2 页
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                        ;;
;;  VGA.INC                                               ;;
;;  640x480 mode 0x12 VGA functions for MenuetOS          ;;
;;  Paul Butcher, paul.butcher@asa.co.uk                  ;;
;;                                                        ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   
paletteVGA:
   
    ; 16 colour palette

    mov   dx,0x3c8
    mov   al,0
    out   dx,al
   
    mov   ecx,16
    mov   dx,0x3c9
    xor   eax,eax
   
  palvganew:
   
    mov   al,0
    test  ah,4
    jz    palvgalbl1
    add   al,31
    test  ah,8
    jz    palvgalbl1
    add   al,32

  palvgalbl1:

    out   dx,al  ; red 0,31 or 63
    mov   al,0
    test  ah,2
    jz    palvgalbl2
    add   al,31
    test  ah,8
    jz    palvgalbl2
    add   al,32

  palvgalbl2:

    out   dx,al  ; blue 0,31 or 63
    mov   al,0
    test  ah,1
    jz    palvgalbl3
    add   al,31
    test  ah,8
    jz    palvgalbl3
    add   al,32

  palvgalbl3:

    out   dx,al  ; green 0,31 or 63
    add   ah,1
    loop  palvganew
   
    ret
   
vga_putimage:
   
    push  ebp ;
    push  esi ;
    push  edi ;
   
    push  eax ;
    push  ebx ; +8 [ptrImage]
    push  ecx ; +4 [BH]
    push  edx ; +0 [xy]
   
    movzx eax,word [esp+2]   ; eax:=x
    movzx ebx,word [esp+0]   ; ebx:=y
    mov   ecx,[0x3010]       ;
    add   eax,[ecx-twdw]     ; eax+=Xwin
    add   ebx,[ecx-twdw+4]   ; ebx+=Ywin
    mov   ecx,ebx            ; ecx = y+Ywin
    mov   edx,eax            ; edx = x+Xwin
   
    imul  ebx, 640*4          ; (y+Ywin)*BytesPerScanLine
    shl   eax,2               ; (x+Xwin)*BytesPerPixel
    add   eax,ebx             ;
    mov   edi,eax             ; store copy
    add   eax,[0xfe80]        ; +AddrLFB

    ;entry point in LFB >> EAX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrLFB
   
    shr   edi,5                ; change from 4 to 1/8 BytesPerPixel
    add   edi,0xa0000          ; + VGABasePtr

    ;VGA start address >> EDI:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrVGA
   
    mov   ebx, [0xfe00]        ; ScreenXSize
    inc   ebx                  ; +1
    imul  ebx,ecx              ; *(y+Ywin)
    mov   ebp, ebx             ;
    add   ebp, edx             ; +(x+Xwin)
    add   ebp, 0x400000        ; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
   
    mov   esi,[esp+8] ; esi:=AddrImg
    movzx ecx,word [esp+6] ; ecx:=B
    movzx ebx,word [esp+4] ; ebx:=H
   
    ; Check limits while draw ?
   
    push  ecx ; B
    push  eax ; LFB address
   
    mov   eax,[0x3010]
    mov   ecx,[eax+draw_data-0x3000+0]
    cmp   ecx,0
    jnz   dbcblimitlset_vga
   
    mov   ecx,[eax+draw_data-0x3000+4]
    cmp   ecx,0
    jnz   dbcblimitlset_vga
   
    mov   ecx,[eax+draw_data-0x3000+8]
    cmp   ecx,[0xfe00] ; ecx <> Screen X size
    jnz   dbcblimitlset_vga
   
    mov   ecx,[eax+draw_data-0x3000+12]
    cmp   ecx,[0xfe04] ; ecx <> Screen Y size
    jnz   dbcblimitlset_vga
   
    pop   eax ; LFB address
    pop   ecx ; B
   
    push  dword 0
   
    jmp   pimvga
   
  dbcblimitlset_vga:
   
    pop   eax ; LFB address
    pop   ecx ; B
   
    push  dword 1
   
pimvga:

    push  edi
    push  esi
    push  eax  ; LFB address
    push  ecx  ; B
    push  ebx  ; H
    push  edx  ; x+Xwin
   
    mov   ebx,[0x3010]
    mov   bl,[ebx+0xe]
    mov   bh,[esp+6*4]
   
    cld
   
 npvga:
   
    cmp   bl,[ds:ebp]
    jnz   impvgano
   
    cmp   bh,0
    jz    impvgayes
   
    call  voodoodbcplimit
    jnz   impvgano
   
 impvgayes:
   
    push  eax  ; LFB address
    push  ebx  ; app no.
    push  ecx  ; B
    push  edx  ; x+Xwin
   
    mov   edx,[esi] ; color
    mov   [eax],dx
    shr   edx,16
    mov   [eax+2],dl
   
    mov   eax,[esi]   ; color
    mov   ecx,[esp]   ; x+Xwin
    and   ecx,0x07    ; modulo 8
    call  setvgapixel ; eax=color, ecx=x%8, edi=VGA address
   
    pop   edx
    pop   ecx
    pop   ebx
    pop   eax
   
  impvgano:
   
    add   esi,3 ; esi+=3 ptrImage+=3
    add   eax,4 ; eax+=4 LFBaddr +=4
    inc   ebp
    inc   edx ; x+Xwin+n
   
    test  edx,0x07  ; test modulo 8
    jnz   impvgacont
    inc   edi
   
  impvgacont:

    dec   ecx ; B--
    jnz   npvga
   
    pop   edx
    pop   ebx
    pop   ecx
    pop   eax
    pop   esi
    pop   edi
   
    add   edi,640/8  ; add one VGA line
    add   eax,640*4  ; add one LFB line
   
    sub   ebp, ecx ;  -B
    add   ebp, [0xfe00] ;
    inc   ebp ; ptrBuffer:=ptrBuffer-B+Screen_Xsize+1
   
    push  ecx
    lea   ecx,[ecx+ecx*2] ;
    add   esi,ecx ; ptrImage:=ptrImage+B*3
    pop   ecx
 
    dec   ebx ; H--
    jnz   near pimvga
   
    add   esp,4  ; jump saved limit byte
    pop   edx
    pop   ecx
    pop   ebx
    pop   eax
    pop   edi
    pop   esi
    pop   ebp
   
    ret
   
   
VGA_putpixel:
   
    ; eax = x
    ; ebx = y
   
    mov   ecx,eax
    mov   eax, [esp+32-8+4] ; color
   
    imul  ebx, 640*4        ; y*BytesPerLine (Vesa2.0 32)
    lea   edx, [ebx+ecx*4]  ; + x*BytesPerPixel (Vesa2.0 32)
   
    mov   edi,edx
    add   edi, [0xfe80]     ; + LFB address
    mov   [edi], eax        ; write to LFB for Vesa2.0
   
    shr   edx,5             ; change BytesPerPixel to 1/8
    mov   edi,edx
    add   edi, 0x0a0000     ; address of pixel in VGA area
   
    and   ecx,0x07          ; bit no. (modulo 8)
   
setvgapixel:
   
    ; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8)
   
    push  eax
    mov   ebx,eax            ; color
   
    ;mov    al,0x08
    ;mov    dx,0x03ce
    ;out    dx,al            ; select GDC bit mask register
   
    inc   cl
    mov   ax, 0x100
    shr   ax,cl
    mov   dx,0x03cf
    out   dx,al              ; set bit mask for pixel
   
    mov   dl,0
    mov   eax,ebx
    and   eax,0x000000ff     ; blue
    cmp   eax,85
    jle   p13green
    or    dl,0x01
    cmp   eax,170
    jle   p13green
    or    dl,0x08
   
p13green:

    and   ebx,0x0000ff00     ; green
    cmp   ebx,85*256
    jle   p13red
    or    dl,0x02
    cmp   ebx,170*256
    jle   p13red
    or    dl,0x08
   
p13red:

    pop   ebx
    and   ebx,0x00ff0000     ; red
    cmp   ebx,85*256*256
    jle   p13cont
    or    dl,0x04
    cmp   ebx,170*256*256
    jle   p13cont
    or    dl,0x08
   
p13cont:

    mov   al,[edi]           ; dummy read
    mov   [edi],dl
   
    ret
   
vga_drawbar:
   
    sub   edx,ebx ; edx:=Yend-Ystart=H
    sub   ecx,eax ; ecx:=Xend-Xstat=B
   
    push  ebp ; +24
    push  esi ; +20
    push  edi ; +16
    push  eax ; +12
    push  ebx ; +8
    push  ecx ; +4
    push  edx ; +0
   
    mov   ecx,[0x3010] ;
    add   eax,[ecx-twdw] ; eax:=Xwin+x
    add   ebx,[ecx-twdw+4] ; ebx:=Ywin+y
    mov   ecx, eax ; ecx:=(x+Xwin)
    mov   edx, ebx ; edx:=(y+Ywin)
   
    imul  ebx, 640/8  ;
    mov   edi, ebx ; edi:=BytesPerScanLine*(y+Ywin)
    shr   eax, 3 ;
    add   edi, eax ;  + (x+Xwin)*BytesPerPixel
    add   edi,0xa0000  ; + VGAbaseaddress
   
    mov   eax, [0xfe00] ; ScreenXSize
    inc   eax           ; +1
    imul  eax,edx       ; *(y+Ywin)
    mov   ebp, eax      ;
    add   ebp, ecx      ; +(x+Win)
    add   ebp, 0x400000 ; +AddrBuffer
   
    mov   eax, [0xfe08]  ; BytesPerScanLine - LFB
    mul   edx            ; *(y+Ywin)
    mov   esi,eax
    add   esi,ecx
    add   esi,ecx
    add   esi,ecx
    add   esi,ecx        ; + 4*(x+Xwin)
    add   esi,[0xfe80]   ; +AddrLFB
   
; edi:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel + AddrVGA
; esi:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel + AddrLFB
; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
   
; x size
   
    mov   eax,[esp+4] ; B [esp+4]
    mov   ebx,[esp+0] ; H
   
    mov   edx,[esp+16] ; color
    test  edx,0x80000000
    jz    nodbglvga
   
    ; no color glide for VGA - set to half glide

    shr   ebx,1  ; H/2
    sub   edx,ebx
    mov   [esp+16],edx
    mov   ebx,[esp+0] ; reset to H
   
   nodbglvga:

    ; check limits ?
   
    push  eax
    push  ecx
   
    mov   eax,[0x3010]
   
    mov   ecx,[eax+draw_data-0x3000+0]
    cmp   ecx,0
    jnz   dbcblimitlset_vga2
   
    mov   ecx,[eax+draw_data-0x3000+4]
    cmp   ecx,0
    jnz   dbcblimitlset_vga2
   
    mov   ecx,[eax+draw_data-0x3000+8]
    cmp   ecx,[0xfe00]
    jnz   dbcblimitlset_vga2
   
    mov   ecx,[eax+draw_data-0x3000+12]
    cmp   ecx,[0xfe04]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -