; ********************************************************** ; Name: Load Process API ; Autor: Toaster Burger ; Version: 1.00 (rewrite) ; Date: 22.01.2006 ; last Update: Monday, 17th April 2006 ; ********************************************************** CPU 386 %define Type_System %include "interface.asm" %include "Lp Macros.asm" %include "Lp Global Tables.asm" ; set the gates for the functions to export [bits 16] jmp dword Reboot jmp dword Reboot_keypress jmp dword Print_Text jmp dword Activate_A20_Gate jmp dword Protected_Mode_jump [bits 32] jmp dword Enable_Paging jmp dword Clear_screen jmp dword Scroll_up jmp dword Extended_Print_Char jmp dword Extended_Print_Text jmp dword IntToStrText jmp dword HexToStrText jmp dword Input_Question jmp dword Leave_Paging_Mode jmp dword Leave_Protected_Mode jmp dword Leave_Protected_Virtual_Address_Mode jmp dword Extended_Reboot jmp dword Processor_Reset jmp dword Processor_Shutdown jmp dword Input_Key [bits 16] Reboot: ; this code jumps to the BIOS reboot db 0EAh dw 0000h dw 0FFFFh Reboot_keypress: ; reboot after a key press xor ah,ah int 16h ; this code jumps to the BIOS reboot db 0EAh dw 0000h dw 0FFFFh ; a function to write a text onto the screen (si = text) Print_Text: mov bx,0007h ; Page Number = 0, Attribute = 07h mov ah,0Eh ; function 0Eh: Teletype Output lodsb ; load the first character Next_Char_1: int 10h lodsb ; al = next character or al,al ; last letter? jnz Next_Char_1 ; if not print next letter retf Activate_A20_Gate: ; activate the 20th address Gate ; wait to send a command Wait_Keyboard: in al,64h test al,00000010b jnz Wait_Keyboard ; send the command mov al,0D0h out 64h,al ; wait for the output byte Wait_Byte: in al,64h test al,00000001b jz Wait_Byte ; read the state byte in al,60h or al,00000010b mov bl,al ; wait to send a command Wait_Keyboard_2: in al,64h test al,00000010b jnz Wait_Keyboard_2 ; send the command mov al,0D1h out 64h,al ; wait to send the state byte Wait_Keyboard_3: in al,64h test al,00000010b jnz Wait_Keyboard_3 ; send the state byte mov al,bl out 60h,al retf Protected_Mode_jump: xor ax,ax mov ds,ax ; Set the Tables ; descriptor 0: zero descriptor mov [GDT_zero1],word GDT_zero1_d mov [GDT_zero2],word GDT_zero2_d mov [GDT_zero3],word GDT_zero3_d mov [GDT_zero4],word GDT_zero4_d ; descriptor 1: System Code mov [GDT_descriptor2_1],word GDT_descriptor2_1_d mov [GDT_descriptor2_2],word GDT_descriptor2_2_d mov [GDT_descriptor2_3],word GDT_descriptor2_3_d mov [GDT_descriptor2_4],word GDT_descriptor2_4_d ; descriptor 2: System Data mov [GDT_descriptor3_1],word GDT_descriptor3_1_d mov [GDT_descriptor3_2],word GDT_descriptor3_2_d mov [GDT_descriptor3_3],word GDT_descriptor3_3_d mov [GDT_descriptor3_4],word GDT_descriptor3_4_d ; descriptor 3: User Code mov [GDT_descriptor4_1],word GDT_descriptor4_1_d mov [GDT_descriptor4_2],word GDT_descriptor4_2_d mov [GDT_descriptor4_3],word GDT_descriptor4_3_d mov [GDT_descriptor4_4],word GDT_descriptor4_4_d ; descriptor 4: User Data mov [GDT_descriptor5_1],word GDT_descriptor5_1_d mov [GDT_descriptor5_2],word GDT_descriptor5_2_d mov [GDT_descriptor5_3],word GDT_descriptor5_3_d mov [GDT_descriptor5_4],word GDT_descriptor5_4_d ; descriptor 5: TSS mov [GDT_TSS_1],word GDT_TSS_1_data mov [GDT_TSS_2],word GDT_TSS_2_data mov [GDT_TSS_3],word GDT_TSS_3_data mov [GDT_TSS_4],word GDT_TSS_4_data ; descriptor 6: Call Gate mov [GDT_Call_Gate_1],word GDT_Call_Gate_1_d mov [GDT_Call_Gate_2],word GDT_Call_Gate_2_d mov [GDT_Call_Gate_3],word GDT_Call_Gate_3_d mov [GDT_Call_Gate_4],word GDT_Call_Gate_4_d ; VESA GUI descriptor 7: (obsolete) 16 Bit Code mov [GDT_descriptor8_1],word GDT_descriptor8_1_d mov [GDT_descriptor8_2],word GDT_descriptor8_2_d mov [GDT_descriptor8_3],word GDT_descriptor8_3_d mov [GDT_descriptor8_4],word GDT_descriptor8_4_d ; descriptor 8: TSS for vm86 mov [TSS_vm86_1],word TSS_vm86_1_data mov [TSS_vm86_2],word TSS_vm86_2_data mov [TSS_vm86_3],word TSS_vm86_3_data mov [TSS_vm86_4],word TSS_vm86_4_data ; set the GDTR and IDTR (use the stack) sub esp,06h ; load the GDT Register mov [esp],word GDT_Limit mov [esp+02h],dword GDT_Base lgdt [esp] ; load the IDT Register mov [esp],word IDT_Limit mov [esp+02h],dword IDT_Base lidt [esp] ; restore the original stack pointer add esp,06h ; jump into the Protected Mode ; now jump into the Protected Mode mov eax,cr0 or eax,01b mov cr0,eax jmp dword Code_Selector:Protected_Mode+Lp_API [bits 32] Protected_Mode: ; set the Segments mov ax,Data_Selector mov ds,ax mov ss,ax mov es,ax xor ax,ax mov fs,ax mov gs,ax ret Enable_Paging: ; create paging structures ; override the whole Page Directory whith 0 mov edi,System_Page_Directory mov ecx,1024 ; 1024 * 32 Bit entries xor eax,eax rep stosd ; map the 7 System Page Tables with the correct memory mov ecx,(1024*7) mov ebx,dword (System_Page_Table_1+1024*1024) mov eax,dword (1024*1024)+Page_TF_entry_S_g Link_Page_Table_entrys: mov [ebx],eax ; store the entry add ebx,04h ; next Page Frame entry Offset add eax,dword 4096 loop Link_Page_Table_entrys ; override the whole Page Table 8 whith 0 mov edi,System_Page_Table_8_address mov ecx,1024 ; 1024 * 32 Bit entries xor eax,eax rep stosd ; create the Page Frames for the UDA mov [User_Data_Area_entry],dword Page_TF_entry_U+User_Data_Area_address mov [API_Buffer_entry],dword Page_TF_entry_S+API_Buffer_address mov [Message_Queue_entry],dword Page_TF_entry_S+Message_Queue_address mov [System_Page_Table_8_entry],dword Page_TF_entry_S+System_Page_Table_8_address ; map the GDT and IDT into the Kernel memory mov [System_Page_Table_1+1024*1024],dword Page_TF_entry_S_g+00000000h ; map the Texmode Buffer int the Kernel memory mov [Textmode_Buffer_entry],dword Page_TF_entry_S_g+0B8000h ; map the Lp module into the Kernel memory mov [Lp_module_PM_entry_1],dword Page_TF_entry_S_g+10000h mov [Lp_module_PM_entry_2],dword Page_TF_entry_S_g+11000h mov [Lp_module_PM_entry_3],dword Page_TF_entry_S_g+12000h mov [Lp_module_PM_entry_4],dword Page_TF_entry_S_g+13000h ; map the copy of the GDT and IDT into the Kernel memory mov [Tables_copy_entry],dword Page_TF_entry_S_g+00000000h ; link the Page Tables with the Page Directory lea edi,[System_Page_Directory] mov eax,Sys_PT_1 stosd mov eax,Sys_PT_2 stosd mov eax,Sys_PT_3 stosd mov eax,Sys_PT_4 stosd mov eax,Sys_PT_5 stosd mov eax,Sys_PT_6 stosd mov eax,Sys_PT_7 stosd mov eax,System_Page_Table_8_address+Page_TF_entry_U_nc stosd ; link the CR3 with the Page Directory mov eax,System_Page_Directory mov cr3,eax ; map this code temporary into the Kernel memory (for the paging switch) mov edx,[System_Page_Table_1+1024*1024+10000b*04h] mov [System_Page_Table_1+1024*1024+10000b*04h],dword 10000h+Page_TF_entry_S_nc ;mov edx,[System_Page_Table_1+1024*1024+10001b*04h] ;mov [System_Page_Table_1+1024*1024+10001b*04h],dword 11000h+Page_TF_entry_S_nc ; store the return address temporary (because the stack will invalidate) pop ecx ; enable Paging mov eax,cr0 or eax,80000000h mov cr0,eax ; enable the Global Page Extension mov eax,cr4 or eax,010000000b mov cr4,eax ; jump into the mapped code mov eax,Protected_Virtual_Address_Mode+Lp_API_PM jmp eax Protected_Virtual_Address_Mode: ; write back the (original) for-switch-using Page Frame mov [System_Page_Table_1+10000b*04h],edx ;mov [System_Page_Table_1+10001b*04h],edx ; reset the Stack Pointer (currently temporary) mov esp,Unused_1_2 ; restore the return address to the new stack push ecx ret Clear_screen: ; Lp_API Clear_screen Enter_System_Environment mov ecx,2000 xor eax,eax mov edi,Textmode_Buffer rep stosw mov [Screen_posx + Lp_API_PM],dword 00h mov [Screen_posy + Lp_API_PM],dword 00h Leave_System_Environment ret Scroll_up: ; Lp_API Scroll_up Enter_System_Environment mov edi,Textmode_Buffer mov esi,Textmode_Buffer+160 mov ecx,1920 rep movsw mov ecx,80 xor eax,eax rep stosw Leave_System_Environment ret Extended_Print_Text: ; Lp_API Extended_Print_Text, String Enter_System_Environment mov esi,[Param1] Next_Char: cmp [Screen_posx + Lp_API_PM],dword 80 jl Position_x_ok mov [Screen_posx + Lp_API_PM],dword 00h inc dword [Screen_posy + Lp_API_PM] Position_x_ok: cmp [Screen_posy + Lp_API_PM],dword 25 jl Position_y_ok call Scroll_up mov [Screen_posy + Lp_API_PM],dword 24 Position_y_ok: lodsb or al,al jz Last_Char Write_Char: cmp al,9 jne Char_no_9 add [Screen_posx + Lp_API_PM],dword 04h jmp Next_Char Char_no_9: cmp al,10 jne Char_no_10 inc dword [Screen_posy + Lp_API_PM] jmp Next_Char Char_no_10: cmp al,13 jne Char_no_13 mov [Screen_posx + Lp_API_PM],dword 00h jmp Next_Char Char_no_13: push ax ; calculate the y-position mov eax,[Screen_posy + Lp_API_PM] mov edx,160 mul edx ; calculate the x-position mov ebx,[Screen_posx + Lp_API_PM] shl ebx,01h add eax,ebx ; set the pointer to the correct letter in the Textmode Buffer mov edi,eax add edi,Textmode_Buffer ; write the letter pop ax and ax,00FFh or ax,0700h stosw inc dword [Screen_posx + Lp_API_PM] jmp Next_Char Last_Char: Leave_System_Environment ret Extended_Print_Char: ; Lp_API Extended_Print_Char, Character ; Character = ASCII Code, (non wheel code) Enter_System_Environment cmp [Screen_posx + Lp_API_PM],dword 80 jl Position_x_ok_1 mov [Screen_posx + Lp_API_PM],dword 00h inc dword [Screen_posy + Lp_API_PM] Position_x_ok_1: cmp [Screen_posy + Lp_API_PM],dword 25 jl Position_y_ok_1 call Scroll_up mov [Screen_posy + Lp_API_PM],dword 24 Position_y_ok_1: cmp [Param1],byte 00h jz Last_Char_1 ; calculate the y-position mov eax,[Screen_posy + Lp_API_PM] mov edx,160 mul edx ; calculate the x-position mov ebx,[Screen_posx + Lp_API_PM] shl ebx,01h add eax,ebx ; set the pointer to the correct letter in the Textmode Buffer mov edi,eax add edi,Textmode_Buffer ; write the letter mov eax,[Param1] and ax,00FFh or ax,0700h stosw inc dword [Screen_posx + Lp_API_PM] Last_Char_1: Leave_System_Environment ret IntToStrText: ; Integer to String (32 Bit with Text return) ; Lp_API IntToStrText, Number ; Number (full 32 bit) ; Return = pointer to string Enter_System_Environment xor edx,edx mov edi,IntToStr_ret + Lp_API_PM mov eax,[Param1] ; calculate figure 10 mov ebx,1000000000 div ebx xchg eax,edx add dl,30h mov [edi],dl inc edi ; calculate figure 9 xor edx,edx mov ebx,100000000 div ebx xchg eax,edx add dl,30h mov [edi],dl inc edi ; calculate figure 8 xor edx,edx mov ebx,10000000 div ebx xchg eax,edx add dl,30h mov [edi],dl inc edi ; calculate figure 7 xor edx,edx mov ebx,1000000 div ebx xchg eax,edx add dl,30h mov [edi],dl inc edi ; calculate figure 6 xor edx,edx mov ebx,100000 div ebx xchg eax,edx add dl,30h mov [edi],dl inc edi ; calculate figure 5 xor edx,edx mov ebx,10000 div ebx xchg eax,edx add dl,30h mov [edi],dl inc edi ; calculate figure 4 xor edx,edx mov ebx,1000 div ebx xchg eax,edx add dl,30h mov [edi],dl inc edi ; calculate figure 3 xor edx,edx mov ebx,100 div ebx xchg eax,edx add dl,30h mov [edi],dl inc edi ; calculate figure 2 and 1 xor edx,edx mov ebx,10 div ebx add al,30h mov [edi],al inc edi add dl,30h mov [edi],dl inc edi mov eax,IntToStr_ret + Lp_API_PM Leave_System_Environment ret Store_hex: ; dl = Number (0-15) to store to edi cmp dl,0Ah jnc Store_hex_h add dl,30h mov [edi],dl inc edi ret Store_hex_h: add dl,(41h-10) mov [edi],dl inc edi ret HexToStrText: ; Lp_API HexToStrText_align, Number ; Number (full 32 bit) ; Return = pointer to string Enter_System_Environment mov edi,FloatToStr_ret + Lp_API_PM mov eax,[Param1] ; calculate figure 8 xor edx,edx mov ebx,010000000h div ebx xchg eax,edx call Store_hex ; calculate figure 7 xor edx,edx mov ebx,01000000h div ebx xchg eax,edx call Store_hex ; calculate figure 6 xor edx,edx mov ebx,0100000h div ebx xchg eax,edx call Store_hex ; calculate figure 5 xor edx,edx mov ebx,010000h div ebx xchg eax,edx call Store_hex ; calculate figure 4 xor edx,edx mov ebx,01000h div ebx xchg eax,edx call Store_hex ; calculate figure 3 xor edx,edx mov ebx,0100h div ebx xchg eax,edx call Store_hex ; calculate figure 2 and 1 (and 0) xor edx,edx mov ebx,010h div ebx xchg eax,edx call Store_hex xchg eax,edx call Store_hex ; store the "h" and terminate the string mov [edi],byte 68h inc edi mov [edi],byte 00h ; change the zeros to white spaces mov esi,FloatToStr_ret + Lp_API_PM mov ecx,06h Change_Zeros: lodsb cmp al,30h jne HexToStrText_finish dec esi mov [esi],byte 20h inc esi loop Change_Zeros HexToStrText_finish: mov eax,FloatToStr_ret + Lp_API_PM Leave_System_Environment ret ; following code for deleting zeros, not to change them into white spaces ;Delete_Zeros: ;lodsb ;cmp al,30h ;jne HexToStrText_finish ;loop Delete_Zeros ; ; ;HexToStrText_finish: ;dec esi ;mov eax,esi ;Leave_System_Environment ; ;ret Input_Question: ; Lp_API Input_Question, Value_1, Value2 ; Value1, Value2 = values of valid keys ; Return = byte character Enter_System_Environment ; input the key Check_Key: in al,64h test al,00000001b jz Check_Key in al,60h cmp al,[Param1] je Input_Question_Exit cmp al,[Param2] jne Check_Key Input_Question_Exit: Leave_System_Environment ret Input_Key: ; Lp_API Input_Key ; Return = (valid) byte character Enter_System_Environment Wait_Key: in al,64h test al,00000001b jz Wait_Key in al,60h Leave_System_Environment ret Leave_Paging_Mode: ; map this code temporary into the Kernel memory (for the leave-paging switch) ;mov [System_Page_Table_1+10001b*04h],dword 11000h+Page_TF_entry_S_nc mov [System_Page_Table_1+10000b*04h],dword 10000h+Page_TF_entry_S_nc jmp dword Leave_Paging_Mode_1+Lp_module Leave_Paging_Mode_1: ; disable the Global Page Extension mov eax,cr4 or eax,010000000b xor eax,010000000b mov cr4,eax ; disable Paging mov eax,cr0 or eax,80000000h xor eax,80000000h mov cr0,eax ret Leave_Protected_Mode: ; leave the Protected Mode mov eax,cr0 or eax,1b xor eax,1b mov cr0,eax ret Leave_Protected_Virtual_Address_Mode: ; bx:dx = return address (Real Mode) ; map this code temporary into the Kernel memory (for the leave-paging switch) ;mov [System_Page_Table_1+10001b*04h],dword 11000h+Page_TF_entry_S_nc mov [System_Page_Table_1+10000b*04h],dword 10000h+Page_TF_entry_S_nc mov eax,Leave_Paging_Mode_2+Lp_module jmp eax Leave_Paging_Mode_2: ; disable the Global Page Extension mov eax,cr4 or eax,010000000b xor eax,010000000b mov cr4,eax ; disable Paging mov eax,cr0 or eax,80000000h xor eax,80000000h mov cr0,eax xor eax,eax mov cr3,eax ; leave the Protected Mode mov eax,cr0 or eax,1b xor eax,1b mov cr0,eax jmp 1000h:Leave_Protected_Virtual_Address_Mode_1 [bits 16] Leave_Protected_Virtual_Address_Mode_1: ; return (to bx:dx) push bx push dx retf [bits 32] Extended_Reboot: ; leave the PVAM mov ebx,1000h mov edx,Extended_Reboot_RM+Lp_module jmp Leave_Protected_Virtual_Address_Mode Extended_Reboot_RM: ; jump to the BIOS reboot db 0EAh dd 0000h dw 0FFFFh Processor_Reset: ; reset the Processor mov al,0FEh out 64h,al Processor_Shutdown: ; deactivate Interrupts cli ; Halt on the Processor hlt ; the public data Screen_posx dd 00h Screen_posy dd 00h IntToStr_ret db "4294967295", 0 FloatToStr_ret db "FFFFFFFFh", 0