;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; 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 ; mov dx, 3ceh ; mov ax, 0005h ; out dx, ax ret palette320x200: mov edx,0x3c8 xor eax, eax out dx,al mov ecx,256 mov edx,0x3c9 xor eax,eax palnew: mov al,0 test ah,64 jz pallbl1 add al,21 pallbl1: test ah,128 jz pallbl2 add al,42 pallbl2: out dx,al mov al,0 test ah,8 jz pallbl3 add al,8 pallbl3: test ah,16 jz pallbl4 add al,15 pallbl4: test ah,32 jz pallbl5 add al,40 pallbl5: out dx,al mov al,0 test ah,1 jz pallbl6 add al,8 pallbl6: test ah,2 jz pallbl7 add al,15 pallbl7: test ah,4 jz pallbl8 add al,40 pallbl8: out dx,al add ah,1 loop palnew ret uglobal novesachecksum dd 0x0 EGA_counter db 0 VGA_drawing_screen db 0 VGA_8_pixels: rb 16 temp: .cx dd 0 endg checkVga_N13: cmp [0xfe0c],dword 0x13 jne @f ; cnvl: pushad cmp [EGA_counter],1 je novesal mov ecx,[0xfb0a] cmp ecx,[novesachecksum] jne novesal popad @@: ret novesal: mov [novesachecksum],ecx mov ecx,0 movzx eax,word [0xfb0c] cmp eax,100 jge m13l3 mov eax,100 m13l3: cmp eax,480-100 jbe m13l4 mov eax,480-100 m13l4: sub eax,100 imul eax,640*4 add ecx,eax movzx eax,word [0xfb0a] cmp eax,160 jge m13l1 mov eax,160 m13l1: cmp eax,640-160 jbe m13l2 mov eax,640-160 m13l2: sub eax,160 shl eax,2 add ecx,eax mov esi,[0xfe80] add esi,ecx mov edi,0xa0000 mov edx,200 mov ecx,320 cld m13pix: lodsd cmp eax,0 je .save_pixel push eax mov ebx,eax and eax,(128+64+32) ; blue shr eax,5 and ebx,(128+64+32)*256 ; green shr ebx,8+2 add eax,ebx pop ebx and ebx,(128+64)*256*256 ; red shr ebx,8+8 add eax,ebx .save_pixel: stosb loop m13pix mov ecx,320 add esi,4*(640-320) dec edx jnz m13pix mov [EGA_counter],0 popad ret VGA_drawbackground: ; draw all cmp [0xfe0c],dword 0x12 jne .end pushad mov esi,[0xfe80] mov edi,0xa0000 mov ebx,640/32 ; 640*480/(8*4) mov edx,480 @@: push ebx edx esi edi shl edx,9 lea edx,[edx+edx*4] add esi,edx shr edx,5 add edi,edx call VGA_draw_long_line pop edi esi edx ebx dec edx jnz @r call VGA_draw_long_line_1 popad .end: ret VGA_draw_long_line: mov dx,3ceh mov ax,0ff08h cli out dx, ax mov ax,0005h out dx, ax m12pix: call VGA_draw_32_pixels dec ebx jnz m12pix mov dx,3c4h mov ax,0ff02h out dx,ax mov dx,3ceh mov ax,0205h out dx,ax mov dx,3ceh mov al,08h out dx,al sti ret VGA_draw_32_pixels: xor eax,eax mov ebp,VGA_8_pixels mov [ebp],eax mov [ebp+4],eax mov [ebp+8],eax mov [ebp+12],eax mov ch,4 .main_loop: mov cl,8 .convert_pixels_to_VGA: lodsd ; eax = 24bit colour cmp eax,0 je .end rol eax,8 mov al,ch ror eax,8 mov ch,1 dec cl shl ch,cl cmp al,85 jbe .p13green or [ebp],ch cmp al,170 jbe .p13green or [ebp+12],ch .p13green: cmp ah,85 jbe .p13red or [ebp+4],ch cmp ah,170 jbe .p13red or [ebp+12],ch .p13red: shr eax,8 cmp ah,85 jbe .p13cont or [ebp+8],ch cmp ah,170 jbe .p13cont or [ebp+12],ch .p13cont: ror eax,8 mov ch,ah inc cl .end: dec cl jnz .convert_pixels_to_VGA inc ebp dec ch jnz .main_loop push esi sub ebp,4 mov esi,ebp mov dx, 3c4h mov ah, 1h @@: mov al, 02h out dx,ax xchg ax,bp lodsd mov [edi],eax xchg ax,bp shl ah, 1 cmp ah, 10h jnz @r add edi,4 pop esi ret VGA_putpixel: ; eax = x ; ebx = y mov ecx,eax mov eax, [esp+32-8+4] ; color shl ebx,9 lea ebx,[ebx+ebx*4] ; умножение на 5 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) pushfd ; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8) xor edx,edx cmp eax,0 je .p13cont cmp al,85 jbe .p13green or dl,0x01 cmp al,170 jbe .p13green or dl,0x08 .p13green: cmp ah,85 jbe .p13red or dl,0x02 cmp ah,170 jbe .p13red or dl,0x08 .p13red: shr eax,8 cmp ah,85 jbe .p13cont or dl,0x04 cmp ah,170 jbe .p13cont or dl,0x08 .p13cont: ror edx,8 inc cl xor eax,eax inc ah shr ax,cl mov dx,3cfh cli out dx,al mov al,[edi] ; dummy read rol edx,8 mov [edi],dl popfd ;.end: ret VGA__putimage: ; ecx = size [x|y] ; edx = coordinates [x|y] cmp [0xfe0c],dword 0x12 jne @f pushad rol edx,16 movzx eax,dx rol edx,16 movzx ebx,dx movzx edx,cx rol ecx,16 movzx ecx,cx call VGA_draw_bar_1 popad @@: ret VGA_draw_bar: ; eax cx ; ebx cy ; ecx xe ; edx ye cmp [0xfe0c],dword 0x12 jne @f pushad sub ecx,eax sub edx,ebx and eax,0xffff and ebx,0xffff and ecx,0xffff and edx,0xffff call VGA_draw_bar_1 popad @@: ret VGA_draw_bar_1: mov [temp.cx],eax mov eax, [0x3010] add ebx, [eax-twdw + 4] mov eax, [eax-twdw + 0] add eax, [temp.cx] and eax,0xfff8 shl ebx,9 lea ebx,[ebx+ebx*4] ; умножение на 5 lea ebx, [ebx+eax*4] ; + x*BytesPerPixel (Vesa2.0 32) mov esi,ebx add esi, [0xfe80] ; + LFB address shr ebx,5 ; change BytesPerPixel to 1/8 mov edi,ebx add edi, 0x0a0000 ; address of pixel in VGA area mov ebx,ecx shr ebx,5 inc ebx .main_loop: call VGA_draw_long_line_1 dec edx jnz .main_loop call VGA_draw_long_line_1 ret VGA_draw_long_line_1: push ebx edx esi edi shl edx,9 lea edx,[edx+edx*4] add esi,edx shr edx,5 add edi,edx call VGA_draw_long_line pop edi esi edx ebx ret