Mirai's Miscellaneous Misadventures

M19 / x86 / vbe.s

# copyright 2022 zamfofex
# license: AGPLv3 or later

.intel_syntax noprefix
.code16

.section vbe

.global mimimi_vbe_set_mode
.global mimimi_vbe_next_mode

mimimi_vbe_set_mode:
	push es
	mov ax, 0x4F00
	mov di, offset vbe_info
	int 0x10
	pop es
	
	cmp ax, 0x4F
	jne error

reset_mode:
	mov ax, [vbe_info.video_modes]
	mov [offset_], ax
	mov ax, [vbe_info.video_modes + 2]
	mov [segment], ax

mimimi_vbe_next_mode:
	mov ax, [segment]
	mov fs, ax
	mov si, [offset_]
	mov dx, fs:[si]
	
	add si, 2
	mov [offset_], si
	mov [mode], dx
	mov ax, 0
	mov fs, ax
	
	cmp [word ptr mode], 0xFFFF
	je reset_mode
	
	push es
	mov ax, 0x4F01
	mov cx, [mode]
	mov di, offset vbe_mode_info
	int 0x10
	pop es
	
	cmp ax, 0x4F
	jne error
	
	mov al, 32
	cmp al, [vbe_mode_info.bpp]
	jne mimimi_vbe_next_mode
	
	mov ax, [vbe_mode_info.width]
	mov [vbe_screen.width], ax
	mov ax, [vbe_mode_info.height]
	mov [vbe_screen.height], ax
	mov eax, [vbe_mode_info.framebuffer]
	mov [vbe_screen.buffer], eax
	mov ax, [vbe_mode_info.pitch]
	mov [vbe_screen.bytes_per_line], ax
	mov eax, 0
	mov al, [vbe_mode_info.bpp]
	shr eax, 3
	mov [vbe_screen.bytes_per_pixel], eax
	
	push es
	mov ax, 0x4F02
	mov bx, [mode]
	or bx, 0x4000
	mov di, 0
	int 0x10
	pop es
	
	cmp ax, 0x4F
	jne error
	
	clc
	ret

next_mode:
	mov ax, [segment]
	mov fs, ax
	mov si, [offset_]
	jmp mimimi_vbe_next_mode

error:
	jmp mimimi_x86_exit

width: .zero 2
height: .zero 2
segment: .zero 2
offset_: .zero 2
mode: .zero 2

vbe_info:
vbe_info.signature: .ascii "VBE2"
vbe_info.version: .zero 2
vbe_info.oem: .zero 4
vbe_info.capabilities: .zero 4
vbe_info.video_modes: .zero 4
vbe_info.video_memory: .zero 2
vbe_info.software_rev: .zero 2
vbe_info.vendor: .zero 4
vbe_info.product_name: .zero 4
vbe_info.product_rev: .zero 4
vbe_info.reserved: .zero 222
vbe_info.oem_data: .zero 256

vbe_mode_info:
vbe_mode_info.attributes: .zero 2
vbe_mode_info.window_a: .zero 1
vbe_mode_info.window_b: .zero 1
vbe_mode_info.granularity: .zero 2
vbe_mode_info.window_size: .zero 2
vbe_mode_info.segment_a: .zero 2
vbe_mode_info.segment_b: .zero 2
vbe_mode_info.win_func_ptr: .zero 4
vbe_mode_info.pitch: .zero 2
vbe_mode_info.width: .zero 2
vbe_mode_info.height: .zero 2
vbe_mode_info.w_char: .zero 1
vbe_mode_info.y_char: .zero 1
vbe_mode_info.planes: .zero 1
vbe_mode_info.bpp: .zero 1
vbe_mode_info.banks: .zero 1
vbe_mode_info.memory_model: .zero 1
vbe_mode_info.bank_size: .zero 1
vbe_mode_info.image_pages: .zero 1
vbe_mode_info.reserved0: .zero 1
vbe_mode_info.red_mask: .zero 1
vbe_mode_info.red_position: .zero 1
vbe_mode_info.green_mask: .zero 1
vbe_mode_info.green_position: .zero 1
vbe_mode_info.blue_mask: .zero 1
vbe_mode_info.blue_position: .zero 1
vbe_mode_info.reserved_mask: .zero 1
vbe_mode_info.reserved_position: .zero 1
vbe_mode_info.direct_color_attributes: .zero 1
vbe_mode_info.framebuffer: .zero 4
vbe_mode_info.off_screen_mem_off: .zero 4
vbe_mode_info.off_screen_mem_size: .zero 2
vbe_mode_info.reserved1: .zero 206

.global mimimi_vbe_screen
mimimi_vbe_screen:

vbe_screen:
vbe_screen.buffer: .zero 4
vbe_screen.width: .zero 2
vbe_screen.height: .zero 2
vbe_screen.bytes_per_line: .zero 2
vbe_screen.bytes_per_pixel: .zero 2