📄 vga.inc
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 + -