hos/rmmod/rmmod.asm

309 lines
6.2 KiB
NASM

; rmmod.asm
; real mode module for HOS
; Author: Josh Holtrop
; Date: 09/20/04
; Modified: 01/04/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 16]
;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 0:start_refreshed
%include "conio.inc"
%include "vesa.inc"
start_refreshed:
mov ax, cs ; 0
mov ds, ax
mov es, 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 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: