diff --git a/kernel/branches/flat_kernel/drivers/build.bat b/kernel/branches/flat_kernel/drivers/build.bat new file mode 100644 index 0000000000..f3573673d8 --- /dev/null +++ b/kernel/branches/flat_kernel/drivers/build.bat @@ -0,0 +1,6 @@ +@fasm sound.asm sound.obj +@fasm sis.asm sis.obj +@fasm infinity.asm infinity.obj +@fasm ati2d.asm ati2d.obj +@fasm vmode.asm vmode.mdr +@pause \ No newline at end of file diff --git a/kernel/branches/flat_kernel/drivers/comport.asm b/kernel/branches/flat_kernel/drivers/uart.inc similarity index 86% rename from kernel/branches/flat_kernel/drivers/comport.asm rename to kernel/branches/flat_kernel/drivers/uart.inc index b7852e0a6d..e8e1812562 100644 --- a/kernel/branches/flat_kernel/drivers/comport.asm +++ b/kernel/branches/flat_kernel/drivers/uart.inc @@ -125,9 +125,11 @@ struc UART .mode dd ? .state dd ? + .rcvr_buff dd ? .rcvr_rp dd ? .rcvr_wp dd ? - .rcvr_cnt dd ? + .rcvr_count dd ? + .rcvr_top dd ? .xmit_buff dd ? .xmit_rp dd ? @@ -140,7 +142,7 @@ virtual at 0 UART UART end virtual -UART_SIZE equ 16*4 +UART_SIZE equ 18*4 struc CONNECTION { @@ -178,10 +180,15 @@ init_uart_service: mov eax, [com1] mov [eax+UART.base], COM_1_BASE - stdcall alloc_kernel_space, 16384 + stdcall alloc_kernel_space, 32768 mov edi, [com1] mov edx, eax + + mov [edi+UART.rcvr_buff], eax + add eax, 8192 + mov [edi+UART.rcvr_top], eax + add eax, 8192 mov [edi+UART.xmit_buff], eax add eax, 8192 mov [edi+UART.xmit_top], eax @@ -203,11 +210,31 @@ init_uart_service: mov [page_tabs+edx*4+4], eax mov [page_tabs+edx*4+12], eax - mov eax, [edi+UART.xmit_buff] + call alloc_page + test eax, eax + jz .fail + + or eax, PG_SW + mov [page_tabs+edx*4+16], eax + mov [page_tabs+edx*4+24], eax + + call alloc_page + test eax, eax + jz .fail + + or eax, PG_SW + mov [page_tabs+edx*4+20], eax + mov [page_tabs+edx*4+28], eax + + mov eax, [edi+UART.rcvr_buff] invlpg [eax] invlpg [eax+0x1000] invlpg [eax+0x2000] invlpg [eax+0x3000] + invlpg [eax+0x4000] + invlpg [eax+0x5000] + invlpg [eax+0x6000] + invlpg [eax+0x7000] mov eax, edi call uart_reset.internal ;eax= uart @@ -374,24 +401,27 @@ align 4 in al, dx jmp .clear_IIR .done: - mov edi, [esi+UART.xmit_buff] + mov edi, [esi+UART.rcvr_buff] mov ecx, 8192/4 xor eax, eax + mov [esi+UART.rcvr_rp], edi + mov [esi+UART.rcvr_wp], edi + mov [esi+UART.rcvr_count], eax + + cld + rep stosd + + mov edi, [esi+UART.xmit_buff] + mov ecx, 8192/4 + mov [esi+UART.xmit_rp], edi mov [esi+UART.xmit_wp], edi mov [esi+UART.xmit_count], eax mov [esi+UART.xmit_free], 8192 - cld rep stosd - - -; mov [esi+UART.rcvr_rp], eax -; mov [esi+UART.rcvr_wp], eax -; mov [esi+UART.rcvr_cnt], eax - - ret + ret ;eax= 0 .fail: or eax, -1 ret @@ -685,7 +715,7 @@ uart_read: jz .fail mov ebx, [esi+8] ;dst size - mov ecx, [eax+UART.rcvr_cnt] + mov ecx, [eax+UART.rcvr_count] cmp ecx, ebx jbe @F mov ecx, ebx @@ -694,26 +724,23 @@ uart_read: test ecx, ecx jz .done - sub [eax+UART.rcvr_cnt], ecx + push ecx - push eax mov edi, [esi+4] ;dst - ; lea esi, [eax+RCVR_OFFSET] - mov ebx, [eax+UART.rcvr_rp] + mov esi, [eax+UART.rcvr_rp] cld -@@: - and ebx, 127 - mov al, [esi+ebx] - stosb - inc ebx - dec ecx - jnz @B + rep movsb + pop ecx - pop eax - mov [eax+UART.rcvr_rp], ebx + cmp esi, [eax+UART.rcvr_top] + jb @F + sub esi, 8192 +@@: + mov [eax+UART.rcvr_rp], esi + sub [eax+UART.rcvr_count], ecx .done: xor eax, eax - rep + ret .fail: or eax, -1 ret @@ -832,8 +859,29 @@ isr_line: align 4 isr_recieve: + mov esi, [ebx+UART.base] + add esi, LSR_REG + mov edi, [ebx+UART.rcvr_wp] + xor ecx, ecx + cld +.read: + mov edx, esi + in al, dx + test eax, LSR_DR + jz .done + mov edx, [ebx+UART.base] in al, dx + stosb + inc ecx + jmp .read +.done: + cmp edi, [ebx+UART.rcvr_top] + jb @F + sub edi, 8192 +@@: + mov [ebx+UART.rcvr_wp], edi + add [ebx+UART.rcvr_count], ecx ret align 4 diff --git a/kernel/branches/flat_kernel/drivers/vmode.asm b/kernel/branches/flat_kernel/drivers/vmode.asm new file mode 100644 index 0000000000..8bf7d8379b --- /dev/null +++ b/kernel/branches/flat_kernel/drivers/vmode.asm @@ -0,0 +1,736 @@ +; +; MenuetOS Driver (vmode.mdr) +; Target: Vertical Refresh Rate programming and videomode changing +; +; Author: Trans <<<<<13>>>>> +; Date: 20.07.2003 +; +; Version: 1.0 +; OS: MenuetOS +; Compiler: FASM +; + +OS_BASE equ 0x80000000 + +use32 + +macro align value { rb (value-1) - ($ + value-1) mod value } + + org 0x80760000 + +headerstart=$ + +mdid db 'MDAZ' ; 4 byte id +mdhver dd 0x00 ; header version +mdcode dd MDSTART ; start of code +mdver dd 0x00000001 ; driver version (subversion*65536+version) +mdname db 'Trans VideoDriver' ; 32 bytes of full driver name + times (32-($-mdname)) db ' ' ; + +headerlen=$-headerstart + times (256-headerlen) db 0 ; reserved area for future + +MDSTART: ; start of driver code ( base_adr+256 bytes) +; ebx(=ecx in program): +; 1 - Get DriverInfo and Driver Initial Set +; 2 - Get Current Video Mode With Vertical Refresh Rate +; 3 - Change Video Mode +; 4 - Return at Start System Video Mode +; 5 - Change vertical and horizontal size of visible screen area +; 6 - Change Vert/Hor position visible area on screen (not complete yet) +; +; MAXF - ... +MAXF=5 + +;-------Main Manager------------- + pushad + cmp ebx,1 + jb mdvm_00 + cmp ebx,MAXF + ja mdvm_00 + shl ebx,2 + add ebx,mdvm_func_table + call dword [ebx] + mov [esp+28],eax + mov [esp+24],ecx + mov [esp+20],edx + mov [esp+16],ebx + popad + retn +mdvm_00: + popad + xor eax,eax + dec eax + retn + +; ------Drivers Functions---------- + +align 4 + +; EBX=1 (in applications ECX=1)- Get DriverInfo and Driver Initial Set +; +; IN: ecx (in app. edx) - pointer to 512-bytes info area in application +; OUT: +; +vm_info_init: + push ecx + cmp [mdrvm],dword 0 + jnz .vmii_00 + call vm_safe_reg + call vm_get_initial_videomode + mov eax,[initvm] + mov [currvm],eax + call vm_search_sys_func_table + call vm_get_cur_vert_rate + mov [initrr],eax + call vm_calc_pixelclock + call vm_calc_refrate + inc [mdrvm] +.vmii_00: + pop ecx + call vm_transfer_drv_info + mov ebx,dword [refrate] + mov eax,dword [mdid] ;dword [systlb] + retn + + +align 4 + +; EBX=2 (in applications ECX=2)- Get Current Video Mode +; +; OUT: eax = X_screen*65536+Y_screen +; ebx = current vertical rate +; ecx = current video mode (number) +vm_get_cur_mode: + cmp [mdrvm],dword 0 + jz .vmgcm_00 + call vm_get_cur_vert_rate + mov eax,[OS_BASE+0FE00h] + mov ebx,[OS_BASE+0FE04h] + shl eax,16 + add eax,ebx + add eax,00010001h + mov ebx,[refrate] + mov ecx,[currvm] + retn +.vmgcm_00: + xor eax,eax + dec eax + retn + + +align 4 + +; EBX=3 (in applications ECX=3)- Change Video Mode +; +; IN: ecx = VertRate*65536+VideoMode +; OUT: eax = 0 if no error +; +vm_set_video_mode: + cmp [mdrvm],dword 0 + jz .vmsvm_00 + call vm_set_selected_mode +; xor eax,eax + retn +.vmsvm_00: + xor eax,eax + dec eax + retn + + +align 4 + +; EBX=4 (in applications ECX=4)- Return at Start System Video Mode +; +; IN: +; OUT: eax = = 0 if no error +; +vm_restore_init_video_mode: + cmp [mdrvm],dword 0 + jz .vmrivm_00 + call vm_restore_reg + xor eax,eax + retn +.vmrivm_00: + xor eax,eax + dec eax + retn + + +align 4 + +; EBX=5 (in applications ECX=5)- Change vertical and horizontal size +; of visible screen area +; IN: ecx (in app. edx) = 0/1 - -/+ horizontal size on 1 position +; = 2/3 - -/+ vertical size on 1 position (8 pixels) +; ^-^----- not complete yet +; OUT: eax = = 0 if no error +; +vm_change_screen_size: + cmp [mdrvm],dword 0 + jz .vmcss_00 + cmp cl,1 + ja .vmcss_01 + mov eax,ecx + call vm_inc_dec_width + xor eax,eax + retn +.vmcss_01: + and ecx,01h + mov eax,ecx +; call vm_inc_dec_high ; not complete yet + xor eax,eax + retn +.vmcss_00: + xor eax,eax + dec eax + retn + + +align 4 + +; EBX=6 (in applications ECX=6)- Change Vert/Hor position visible area on screen +; +; IN: ecx (in app. edx) = 0/1 - -/+ horizontal position on 1 point +; = 2/3 - -/+ vertical position on 1 pixel +; ^-^----- not complete yet +; OUT: eax = 0 if no error +; +vm_change_position_screen: + cmp [mdrvm],dword 0 + jz .vmcps_00 + ; ... + xor eax,eax + retn +.vmcps_00: + xor eax,eax + dec eax + retn + + +;-----Drivers Subfunctions--------- + +; +; Searching i40 system functions pointer table in kernel area location +; +vm_search_sys_func_table: + push eax ; eax - current value + push ecx ; ecx - will be counter of equevalent value + push edx ; edx - last value + push esi ; esi - current address + xor ecx,ecx + mov esi,OS_BASE+010000h ; Start address of kernel location + lodsd + mov edx,eax + cld +.vmssft_00: + cmp esi,OS_BASE+30000h + ja .vmssft_03 + inc ecx + lodsd + cmp edx,eax + mov edx,eax + je .vmssft_00 + cmp ecx,128 + ja .vmssft_02 +.vmssft_01: + xor ecx,ecx + jmp .vmssft_00 +.vmssft_02: + cmp edx,0 + je .vmssft_01 + sub esi,256*4-1 + mov [systlb],esi + xor ecx,ecx +.vmssft_03_0: + inc ecx + lodsd + cmp edx,eax + mov edx,eax + jne .vmssft_03_0 + mov esi,dword [systlb] + cmp cx,60 + jae .vmssft_03 + add esi,256*4-4 + lodsb + mov edx,eax + jmp .vmssft_01 +.vmssft_03: + mov [systlb],esi + pop esi + pop edx + pop ecx + pop eax + retn + +; IN: +; OUT: eax= vertical rate in Hz +vm_get_cur_vert_rate: + push edx + push ebx + xor eax,eax + mov edx,eax + mov ebx,eax + mov dx,03DAh +.vmgcvt_00: + in al,dx + test al,8 + jz .vmgcvt_00 +.vmgcvt_01: + in al,dx + test al,8 + jnz .vmgcvt_01 + mov ebx,edx + rdtsc + mov edx,ebx + mov ebx,eax +.vmgcvt_02: + in al,dx + test al,8 + jz .vmgcvt_02 +.vmgcvt_03: + in al,dx + test al,8 + jnz .vmgcvt_03 + rdtsc + sub eax,ebx + mov ebx,eax + mov eax,[OS_BASE+0F600h] + xor edx,edx + div ebx + inc eax + mov [refrate],eax + pop ebx + pop edx + retn + +vm_calc_pixelclock: + push ebx + push edx + xor eax,eax + mov al,[_00] + add ax,5 + shl eax,3 + xor ebx,ebx + mov bl,[_06] + mov bh,[_07] + and bh,00100001b + btr bx,13 + jnc .vmcpc_00 + or bh,2 +.vmcpc_00: + xor edx,edx + mul ebx + xor edx,edx + mul [initrr] + mov [pclock],eax + pop edx + pop ebx + retn + +; +; Safe of initial CRTC state +; +vm_safe_reg: + push edx + push ebx + push ecx + push edi + cli + mov dx,3d4h ; CRTC + mov al,11h + out dx,al + inc dx + in al,dx + and al,7fh + out dx,al ; Clear protection bit + dec dx + xor ecx,ecx + mov cl,19h + xor bl,bl + mov edi,CRTCreg +.vmsr_00: + mov al,bl + out dx,al + inc dx + in al,dx + dec dx + stosb + inc bl + loop .vmsr_00 + sti + pop edi + pop ecx + pop ebx + pop edx + retn + +; +; Restore of initial CRTC state +; +vm_restore_reg: + push eax + push ebx + push edx + push esi + mov eax,[oldX] + mov [OS_BASE+0FE00h],eax + mov eax,[oldY] + mov [OS_BASE+0FE04h],eax + mov dx,03dah +.vmrr_00: + in al,dx + test al,8 + jnz .vmrr_00 +.vmrr_01: + in al,dx + test al,8 + jnz .vmrr_01 + cli + mov dx,03c4h + mov ax,0101h + out dx,ax + mov dx,3d4h ; CRTC + mov al,11h + out dx,al + inc dx + in al,dx + and al,7fh ; Clear Protection bit + out dx,al + dec dx + xor ecx,ecx + mov cl,19h + mov esi,CRTCreg + xor bl,bl +.vmrr_02: + lodsb + mov ah,al + mov al,bl + out dx,ax + inc bl + loop .vmrr_02 + sti +; call ref_screen + pop esi + pop edx + pop ecx + pop eax + retn + +; Calculate of possible vertical refrash rate +; (light version of function) +vm_calc_refrate: + push ebx + push ecx + push edx + push edi + push esi + mov eax,[pclock] + xor edx,edx + mov edi,_m1 + mov ebx,eax + mov ecx,(1696*1065) + div ecx + xor edx,edx + stosw + add edi,8 + mov eax,ebx + mov ecx,(1344*804) + div ecx + xor edx,edx + stosw + add edi,8 + mov eax,ebx + mov ecx,(1056*636) + div ecx + xor edx,edx + stosw + add edi,8 + mov eax,ebx + mov ecx,(800*524) + div ecx + xor edx,edx + stosw + mov edi,_m1 + mov esi,edi + mov ecx,5*4 +.vmcrr_00: + lodsw + cmp ax,55 + jb .vmcrr_01 + stosw + loop .vmcrr_00 + pop esi + pop edi + pop edx + pop ecx + pop ebx + retn +.vmcrr_01: + xor ax,ax + stosw + loop .vmcrr_00 + pop esi + pop edi + pop edx + pop ecx + pop ebx + retn + +vm_get_initial_videomode: + push eax + mov eax,dword [OS_BASE+0FE00h] + mov [oldX],eax + mov eax,dword [OS_BASE+0FE04h] + mov [oldY],eax + mov eax,dword [OS_BASE+0FE0Ch] ; initial video mode + and ax,01FFh + mov dword [initvm],eax + pop eax + retn + + +; IN: eax = 0/1 - -/+ 1 position of width +vm_inc_dec_width: + push ebx + push edx + mov ebx,eax + mov dx,3d4h ; CRTC + mov al,11h + out dx,al + inc dx + in al,dx + and al,7fh ; Clear Protection bit + out dx,al + dec dx + xor al,al + out dx,al + inc dx + in al,dx + dec al + cmp bl,0 + jnz .vmidr_00 + inc al + inc al +.vmidr_00: + out dx,al + pop edx + pop ebx + retn + +; +; Copy driver info to application area +; +; IN: ecx (in app. edx) - pointer to 512-bytes info area in application +; OUT: +vm_transfer_drv_info: + push ecx + push edi + push esi + mov eax,ecx + xor ecx,ecx + mov cl,32/4 + mov esi,mdname + mov edi,drvname + rep movsd + mov ecx,eax + mov eax,[mdver] + mov [drvver],eax + mov edi,[OS_BASE+3010h] + mov edi,[edi+10h] + add edi,ecx + mov esi,drvinfo + xor ecx,ecx + mov cx,512 + rep movsb + pop esi + pop edi + pop ecx + retn + + +; +; Set selected video mode +; (light version) +; +; IN: ecx = VertRate*65536+VideoMode +; +vm_set_selected_mode: + push edx + push ecx + push esi + ror ecx,16 + cmp cx,00h + je .vmssm_03 + rol ecx,16 + mov eax,ecx + shl eax,16 + shr eax,16 + mov [currvm],eax + cmp cx,112h + jne .vmssm_00 + mov esi,mode0 + mov ecx,639 + mov edx,479 + jmp .vmssm_st00 +.vmssm_00: + cmp cx,115h + jne .vmssm_01 + mov esi,mode1 + mov ecx,799 + mov edx,599 + jmp .vmssm_st00 +.vmssm_01: + cmp cx,118h + jne .vmssm_02 + mov esi,mode2 + mov ecx,1023 + mov edx,767 + jmp .vmssm_st00 +.vmssm_02: + cmp cx,11Bh + jne .vmssm_03 + mov esi,mode2 + mov ecx,1279 + mov edx,1023 + jmp .vmssm_st00 +.vmssm_03: + xor eax,eax + dec eax + pop esi + pop ecx + pop edx + retn +.vmssm_st00: + mov [OS_BASE+0FE00h],ecx + mov [OS_BASE+0FE04h],edx + cli + mov dx,03c4h + lodsw + out dx,ax + mov dx,03d4h + mov al,11h + out dx,al + inc dx + in al,dx + and al,7fh + out dx,al + dec dx + mov ecx,13 +.vmssm_st01: + lodsw + out dx,ax + loop .vmssm_st01 + sti + xor eax,eax + pop esi + pop ecx + pop edx + retn + + +;------------DATA AREA--------------- +align 4 + +mdvm_func_table: + dd MDSTART + dd vm_info_init, vm_get_cur_mode + dd vm_set_video_mode, vm_restore_init_video_mode + dd vm_change_screen_size, vm_change_position_screen + + +CRTCreg: +_00 db ? +_01 db ? +_02 db ? +_03 db ? +_04 db ? +_05 db ? +_06 db ? +_07 db ? +_08 db ? +_09 db ? +_0a db ? +_0b db ? +_0c db ? +_0d db ? +_0e db ? +_0f db ? +_10 db ? +_11 db ? +_12 db ? +_13 db ? +_14 db ? +_15 db ? +_16 db ? +_17 db ? +_18 db ? +_19 db ? + +align 4 + +oldX dd ? +oldY dd ? +initvm dd ? +currvm dd 0 +refrate dd 0 +initrr dd 0 +systlb dd 0 +pclock dd ? +mdrvm dd 0 ; 0 - not drv init yet, 1 - already drv init + + +drvinfo: +drvname: times 32 db ' ' +drvver dd 0 + times (32-($-drvver))/4 dd 0 +drvmode dw 011Bh,0118h,0115h,0112h + times (64-($-drvmode))/2 dw 00h +_m1 dw 0,0,0,0,0 +_m2 dw 0,0,0,0,0 +_m3 dw 0,0,0,0,0 +_m4 dw 0,0,0,0,0 +_m5 dw 0,0,0,0,0 + times (512-($-drvinfo)) db 0 +drvinfoend: + + +;1280x1024 - 11Bh +mode3: + dw 0101h + dw 0d000h,9f01h,9f02h,9303h,0a904h,1905h,2806h,5a07h + dw 0110h,8411h,0ff12h,0ff15h,2916h + +;1024x768 - 118h +mode2: + dw 0101h + dw 0a400h,7f01h,7f02h,8703h,8404h,9505h,2406h,0f507h + dw 0310h,8911h,0ff12h,0ff15h,2516h + +;800x600 - 115h +mode1: + dw 0101h + dw 8000h,6301h,6302h,8303h,6a04h,1a05h,7206h,0f007h + dw 5910h,8d11h,5712h,5715h,7316h + +;640x480 - 112h, 12h +mode0: + dw 0101h + dw 6000h,4f01h,4f02h,8303h,5304h,9f05h,00b06h,3e07h + dw 0ea10h,8c11h,0df12h,0df15h,0c16h + +; 640x400 +;mymode0: +; dw 0101h +;_0_7 dw 5f00h,4f01h,4f02h,8303h,5304h,9f05h,0BF06h,1f07h +; dw 9c10h,8e11h,8f12h,9615h,0B916h ;,4013h + +; 640x800 +;mymode1: +; dw 0101h +; dw 5f00h,4f01h,4f02h,8003h,5004h,9f05h,06006h,0FF07h +; dw 2d10h,8f11h,2012h,2615h,05716h ;,4013h + + +DRVM_END: + diff --git a/kernel/branches/flat_kernel/vmodeint.inc b/kernel/branches/flat_kernel/vmodeint.inc index ffda6510e6..90f4ecc926 100644 --- a/kernel/branches/flat_kernel/vmodeint.inc +++ b/kernel/branches/flat_kernel/vmodeint.inc @@ -19,7 +19,7 @@ endg pushd [ScreenWidth] [ScreenHeight] popd [old_screen_height] [old_screen_width] or eax,-1 ; If driver is absent then eax does not change - call 0x760100 ; Entry point of video driver + call OS_BASE+0x760100 ; Entry point of video driver mov [esp+36],eax mov [esp+24],ebx mov [esp+32],ecx