All pastes #96874 Raw Edit

Real Mode Code

public text v1 · immutable
#96874 ·published 2006-07-23 07:40 UTC
rendered paste body
; **********************************************************

;	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