; rmmod.asm ; real mode module for HOS ; Author: Josh Holtrop ; Date: 09/20/04 ; Modified: 11/01/05 %define VIRT_OFFSET 0xC0000000 %define SIZEOF_RMPARAMS 20 %include "rmmod.inc" ; the bootstrap process will jump us to 0x0:0x5010 so we'd better be ready for it [org 0x5000] [bits 32] ;HOS module header, better be 16 bytes! dd 0x4D534F48 ; magic identifier "HOSM" dd 1 ; real mode module dd start ; start address dd 0 ; reserved ; ebx = return address ; ecx = where to store real mode parameter table start: jmp 24:start_pm16 ; uses KERNEL_CODE_BS16 from kernel/boot.asm [bits 16] start_pm16: ; in 16-bit protected mode mov ax, 32 mov ss, ax mov eax, cr0 and eax, 0x7FFFFFFE mov cr0, eax ; leave PM jmp 0:start_refreshed ; enter RM %include "conio.inc" %include "vesa.inc" start_refreshed: mov ax, cs ; 0 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax mov esp, 0x7000 mov [dat_rmadd], ecx mov [dat_retn], ebx mov ebx, ecx ; clear the rm_params mov cx, SIZEOF_RMPARAMS mov ax, 0 clear_rmparams_loop: mov [ebx], al inc ebx loop clear_rmparams_loop ; begin real-mode code initialization, etc... call con_clear ccall vesa_get_info, es, vbe_info_block cmp ax, 0 jnzfar no_vesa vesa_present: ccall con_putstring, txt_vesa xor ax, ax mov al, [VbeVersion + 1] ccall con_putHex, ax ccall con_putc, '.' | 0x0700 xor ax, ax mov al, [VbeVersion] ccall con_putHex, ax ccall con_putc, 10 xor ax, ax ; clear the scratch mem mov cx, 129 mov di, scratch_mem rep stosw push ds mov ax, [OemStringPtr + 2] mov si, [OemStringPtr] mov ds, ax mov di, scratch_mem mov cx, 128 rep movsw ; and copy the string there for display pop ds ccall con_putstring, scratch_mem ; write OEM string ccall con_putc, 10 mov ax, [VideoModePtr + 2] mov es, ax mov si, [VideoModePtr] xor dx, dx vesa_mode_loop: mov ax, [es:si] ; get next mode number cmp ax, 0xFFFF jzfar vesa_mode_loop_done ccall vesa_get_mode_info, ds, vbe_mode_info_block, ax cmp ax, 0 jnzfar vesa_mode_loop_next mov ax, [ModeAttributes] and ax, VESA_MODE_SUPPORTED | VESA_MODE_COLOR | VESA_MODE_GRAPHICS | VESA_MODE_LFB cmp ax, VESA_MODE_SUPPORTED | VESA_MODE_COLOR | VESA_MODE_GRAPHICS | VESA_MODE_LFB jnzfar vesa_mode_loop_next mov ax, [XResolution] cmp ax, 640 jlfar vesa_mode_loop_next mov ax, [YResolution] cmp ax, 480 jlfar vesa_mode_loop_next mov al, [BitsPerPixel] cmp al, 15 jz vesa_mode_good cmp al, 16 jz vesa_mode_good cmp al, 24 jz vesa_mode_good cmp al, 32 jnzfar vesa_mode_loop_next vesa_mode_good: mov ax, dx add ax, 0x0700 | 'a' ccall con_putc, ax ccall con_putstring, txt_vesa_mode1 ccall con_putDec, word [XResolution] ccall con_putc, 'x' | 0x0700 ccall con_putDec, word [YResolution] ccall con_putc, 'x' | 0x0700 xor ax, ax mov al, [BitsPerPixel] ccall con_putDec, ax ccall con_putstring, txt_vesa_mode2 mov ax, [es:si] ; mode number ccall con_putHex, ax ccall con_putc, 10 mov bx, dx shl bx, 1 mov [scratch_mem + bx], ax ; store modes in scratch_mem array inc dx vesa_mode_loop_next: add si, 2 jmp vesa_mode_loop vesa_mode_loop_done: ccall con_putstring, txt_vesa_end vesa_get_key_loop: call con_getkey mov ah, 0 cmp ax, '0' jz vesa_the_end cmp ax, 'a' ; first choice jb vesa_get_key_loop add dx, 'a' cmp ax, dx ; one past last choice jae vesa_get_key_loop ; ok, we have a valid video mode selection sub ax, 'a' shl ax, 1 mov bx, ax mov cx, [scratch_mem + bx] ccall vesa_get_mode_info, ds, vbe_mode_info_block, cx or cx, 0x4000 ; enable LFB ccall vesa_set_mode, cx ; turn on mode mov ebx, [dat_rmadd] ; pass mode info to kernel mov eax, [PhysBasePtr] mov [ebx + 0], eax xor eax, eax mov al, [BitsPerPixel] mov [ebx + 12], eax mov ax, [XResolution] mov [ebx + 4], eax mov ax, [YResolution] mov [ebx + 8], eax jmp vesa_the_end no_vesa: ccall con_putstring, txt_novesa call con_getkey vesa_the_end: end_rmmod: ; get ready to go back to pmode and return to kernel initialization mov ebx, [dat_retn] lgdt [gdtrlin32] mov eax, cr0 or eax, 0x01 mov cr0, eax jmp KERNEL_CODE_LIN32:segmented_start [bits 32] segmented_start: lgdt [gdtrbs32] jmp KERNEL_CODE_BS32:offset_continue+VIRT_OFFSET offset_continue: mov cx, KERNEL_DATA_BS32 mov ss, cx mov ds, cx mov es, cx mov gs, cx mov fs, cx jmp ebx [bits 16] ;------------------------------------------------------- gdtrlin32: dw gdt_endlin32-gdtlin32-1 dd gdtlin32 gdtlin32: ;null descriptor dd 0 dd 0 KERNEL_CODE_LIN32 equ $-gdtlin32 db 0xff ;limit 7:0 db 0xff ;limit 15:8 db 0x00 ;base 7:0 db 0x00 ;base 15:8 db 0x00 ;base 23:16 db 0x9a ;access db 0xcf ;flags / limit 19:16 db 0x00 ;base 31:24 KERNEL_DATA_LIN32 equ $-gdtlin32 db 0xff ;limit 7:0 db 0xff ;limit 15:8 db 0x00 ;base 7:0 db 0x00 ;base 15:8 db 0x00 ;base 23:16 db 0x92 ;access db 0xcf ;flags / limit 19:16 db 0x00 ;base 31:24 gdt_endlin32: ;------------------------------------------------------- gdtrbs32: dw gdt_endbs32-gdtbs32-1 dd gdtbs32 gdtbs32: ;null descriptor dd 0 dd 0 ;a base of 0x4000_0000, when added to 0xC000_0000 will produce 0x0000_0000 physical before paging in effect KERNEL_CODE_BS32 equ $-gdtbs32 db 0xff ;limit 7:0 db 0xff ;limit 15:8 db 0x00 ;base 7:0 db 0x00 ;base 15:8 db 0x00 ;base 23:16 db 0x9a ;access db 0xcf ;flags / limit 19:16 db 0x40 ;base 31:24 KERNEL_DATA_BS32 equ $-gdtbs32 db 0xff ;limit 7:0 db 0xff ;limit 15:8 db 0x00 ;base 7:0 db 0x00 ;base 15:8 db 0x00 ;base 23:16 db 0x92 ;access db 0xcf ;flags / limit 19:16 db 0x40 ;base 31:24 gdt_endbs32: txt_vesa: db "VESA found. VBE Version: ", 0 txt_vesa_mode1 db ". ", 0 txt_vesa_mode2 db ", mode 0x", 0 txt_vesa_end: db "Enter the letter of your selection or 0 for console mode:", 0 txt_novesa: db "VESA not found, using 80x25 console mode... press any key", 10, 0 dat_rmadd: dd 0 dat_retn: dd 0 vbe_info_block: VbeSignature: db "VBE2" VbeVersion: dw 0 OemStringPtr dd 0 Capabilities: times 4 db 0 VideoModePtr: dd 0 TotalMemory: dw 0 OemSoftwareRev: dw 0 OemVendorName: dd 0 OemProductName: dd 0 OemProductRev: dd 0 Reserved: times 478 db 0 vbe_mode_info_block: ModeAttributes: dw 0 WinAAttributes: db 0 WinBAttributes: db 0 WinGranularity: dw 0 WinSize: dw 0 WinASegment: dw 0 WinBSegment: dw 0 WinFuncPtr: dd 0 BytesPerScanline: dw 0 XResolution: dw 0 YResolution: dw 0 XCharSize: db 0 YCharSize: db 0 NumberOfPlanes: db 0 BitsPerPixel: db 0 NumberOfBanks: db 0 MemoryModel: db 0 BankSize: db 0 NumberOfImagePages: db 0 Reserved2: times 10 db 0 PhysBasePtr: dd 0 Reserved3: times 212 db 0 scratch_mem: