📄 video.s
字号:
lmhx: xorw %bx, %bx # Else => mode ID in hexlmhex: lodsb orb %al, %al jz lmuse1 subb $0x30, %al jc lmbad cmpb $10, %al jc lmhx1 subb $7, %al andb $0xdf, %al cmpb $10, %al jc lmbad cmpb $16, %al jnc lmbadlmhx1: shlw $4, %bx orb %al, %bl jmp lmhexlmuse1: movw %bx, %ax jmp lmusemnusel: lodsb # Menu selection xorb %ah, %ah subb $0x30, %al jc lmbad cmpb $10, %al jc lmuse cmpb $0x61-0x30, %al jc lmbad subb $0x61-0x30-10, %al cmpb $36, %al jnc lmbadlmuse: call mode_set jc lmdeflmbad: leaw bootsym(unknt), %si call prtstr jmp mode_menulmdef: ret_setrec: jmp setrec # Ugly..._set_80x25: jmp set_80x25# Setting of user mode (AX=mode ID) => CF=successmode_set: movw %ax, bootsym(boot_vid_mode) movw %ax, %bx cmpw $VIDEO_VESA_BY_SIZE, %ax je setvesabysize testb $VIDEO_RECALC>>8, %ah jnz _setrec cmpb $VIDEO_FIRST_SPECIAL>>8, %ah jz setspc cmpb $VIDEO_FIRST_VESA>>8, %ah jnc check_vesa orb %ah, %ah jnz setbad jmp setmenusetbad: clc retsetspc: xorb %bh, %bh # Set special mode cmpb $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl jnc setbad addw %bx, %bx jmp *bootsym(spec_inits)(%bx)setmenu: orb %al, %al # 80x25 is an exception jz _set_80x25 pushw %bx # Set mode chosen from menu call mode_table # Build the mode table popw %ax shlw $3, %ax addw %ax, %si cmpw %di, %si jnc setbad movw (%si), %ax # Fetch mode ID jmp mode_setcheck_vesa: leaw vesa_glob_info, %di movw $0x4f00, %ax int $0x10 cmpw $0x004f, %ax jnz setbad leaw vesa_mode_info, %di subb $VIDEO_FIRST_VESA>>8, %bh movw %bx, %cx # Get mode information structure movw $0x4f01, %ax int $0x10 addb $VIDEO_FIRST_VESA>>8, %bh cmpw $0x004f, %ax jnz setbad movb (%di), %al # Check mode attributes. andb $0x99, %al cmpb $0x99, %al jnz _setbad # Doh! No linear frame buffer. subb $VIDEO_FIRST_VESA>>8, %bh orw $0x4000, %bx # Use linear frame buffer movw $0x4f02, %ax # VESA BIOS mode set call int $0x10 cmpw $0x004f, %ax # AL=4f if implemented jnz _setbad # AH=0 if OK movb $1, bootsym(graphic_mode) # flag graphic mode stc ret_setbad: jmp setbad # Ugly...# Recalculate vertical display end registers -- this fixes various# inconsistencies of extended modes on many adapters. Called when# the VIDEO_RECALC flag is set in the mode ID.setrec: subb $VIDEO_RECALC>>8, %ah # Set the base mode call mode_set jnc rct3 movw %gs:(0x485), %ax # Font size in pixels movb %gs:(0x484), %bl # Number of rows incb %bl mulb %bl # Number of visible decw %ax # scan lines - 1 movw $0x3d4, %dx movw %ax, %bx movb $0x12, %al # Lower 8 bits movb %bl, %ah outw %ax, %dx movb $0x07, %al # Bits 8 and 9 in the overflow register call inidx xchgb %al, %ah andb $0xbd, %ah shrb %bh jnc rct1 orb $0x02, %ahrct1: shrb %bh jnc rct2 orb $0x40, %ahrct2: movb $0x07, %al outw %ax, %dx stcrct3: retinidx: outb %al, %dx # Read from indexed VGA register incw %dx # AL=index, DX=index reg port -> AL=data inb %dx, %al decw %dx retsetvesabysize: call mode_table leaw modelist,%si1: add $8,%si cmpw $ASK_VGA,-8(%si) # End? je _setbad movw -6(%si),%ax cmpw %ax,bootsym(vesa_size)+0 jne 1b movw -4(%si),%ax cmpw %ax,bootsym(vesa_size)+2 jne 1b movw -2(%si),%ax cmpw %ax,bootsym(vesa_size)+4 jne 1b movw -8(%si),%ax movw %ax,%bx movw %ax,bootsym(boot_vid_mode) jmp check_vesa# Table of routines for setting of the special modes.spec_inits: .word bootsym(set_80x25) .word bootsym(set_8pixel) .word bootsym(set_80x43) .word bootsym(set_80x28) .word bootsym(set_current) .word bootsym(set_80x30) .word bootsym(set_80x34) .word bootsym(set_80x60)# Set the 80x25 mode. If already set, do nothing.set_80x25: movw $0x5019, bootsym(force_size) # Override possibly broken BIOSuse_80x25: movw $0x1202, %ax # Force 400 scan lines movb $0x30, %bl int $0x10 movw $0x0003, %ax # Mode 3 int $0x10 stc ret# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.set_8pixel: call use_80x25 # The base is 80x25set_8pt: movw $0x1112, %ax # Use 8x8 font xorb %bl, %bl int $0x10 movw $0x1200, %ax # Use alternate print screen movb $0x20, %bl int $0x10 movw $0x1201, %ax # Turn off cursor emulation movb $0x34, %bl int $0x10 movb $0x01, %ah # Define cursor scan lines 6-7 movw $0x0607, %cx int $0x10 stc ret# Set the 80x28 mode. This mode works on all VGA's, because it's a standard# 80x25 mode with 14-point fonts instead of 16-point.set_80x28: call use_80x25 # The base is 80x25set14: movw $0x1111, %ax # Use 9x14 font xorb %bl, %bl int $0x10 movb $0x01, %ah # Define cursor scan lines 11-12 movw $0x0b0c, %cx int $0x10set_current: stc ret# Set the 80x43 mode. This mode is works on all VGA's.# It's a 350-scanline mode with 8-pixel font.set_80x43: movw $0x1201, %ax # Set 350 scans movb $0x30, %bl int $0x10 movw $0x0003, %ax # Reset video mode int $0x10 jmp set_8pt # Use 8-pixel font# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.set_80x30: call use_80x25 # Start with real 80x25 movw $0x3cc, %dx # Get CRTC port inb %dx, %al movb $0xd4, %dl rorb %al # Mono or color? jc set48a movb $0xb4, %dlset48a: movw $0x0c11, %ax # Vertical sync end (also unlocks CR0-7) call outidx movw $0x0b06, %ax # Vertical total call outidx movw $0x3e07, %ax # (Vertical) overflow call outidx movw $0xea10, %ax # Vertical sync start call outidx movw $0xdf12, %ax # Vertical display end call outidx movw $0xe715, %ax # Vertical blank start call outidx movw $0x0416, %ax # Vertical blank end call outidx pushw %dx movb $0xcc, %dl # Misc output register (read) inb %dx, %al movb $0xc2, %dl # (write) andb $0x0d, %al # Preserve clock select bits and color bit orb $0xe2, %al # Set correct sync polarity outb %al, %dx popw %dx movw $0x501e, bootsym(force_size) stc # That's all. ret# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.set_80x34: call set_80x30 # Set 480 scans call set14 # And 14-pt font movw $0xdb12, %ax # VGA vertical display end movw $0x5022, bootsym(force_size)setvde: call outidx stc ret# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.set_80x60: call set_80x30 # Set 480 scans call set_8pt # And 8-pt font movw $0xdf12, %ax # VGA vertical display end movw $0x503c, bootsym(force_size) jmp setvde# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)outidx: outb %al, %dx pushw %ax movb %ah, %al incw %dx outb %al, %dx decw %dx popw %ax ret# Build the table of video modes (stored after the setup.S code at the# `modelist' label. Each video mode record looks like:# .word MODE-ID (our special mode ID (see above))# .byte rows (number of rows)# .byte columns (number of columns)# Returns address of the end of the table in DI, the end is marked# with a ASK_VGA ID.mode_table: movw bootsym(mt_end), %di # Already filled? orw %di, %di jnz mtab1 leaw modelist, %di # Store standard modes:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -