📄 clext.c
字号:
mov ax, #0x0100 retcirrus_vesa_07h_1: push dx call cirrus_get_bpp_bytes mov bl, al xor bh, bh mov ax, cx mul bx pop bx push ax call cirrus_get_line_offset mul bx pop bx add ax, bx jnc cirrus_vesa_07h_3 inc dxcirrus_vesa_07h_3: push dx and dx, #0x0003 mov bx, #0x04 div bx pop dx shr dx, #2 call cirrus_set_start_addr mov ax, #0x004f retcirrus_vesa_07h_2: call cirrus_get_start_addr shl dx, #2 push dx mov bx, #0x04 mul bx pop bx or dx, bx push ax call cirrus_get_line_offset mov bx, ax pop ax div bx push ax push dx call cirrus_get_bpp_bytes mov bl, al xor bh, bh pop ax xor dx, dx div bx mov cx, ax pop dx mov ax, #0x004f retcirrus_vesa_10h: ;; Power management functions ;; Set up DS to read stored power info from RAM push ds#ifdef CIRRUS_VESA3_PMINFO db 0x2e ;; cs: mov ax, [cirrus_vesa_sel0000_data]#else xor ax, ax#endif mov ds, ax ;; Now choose the right function cmp bl, #0x00 ja cirrus_vesa_10h_01 ;; ;; Function 00h: Get capabilities ;; mov bx, #0x0720 ;; 07: standby/suspend/off, 20: VBE/PM 2.0 mov ax, #0x004f jmp cirrus_vesa_10h_donecirrus_vesa_10h_01: cmp bl, #0x01 ja cirrus_vesa_10h_02 ;; ;; Function 01h: Set power state ;; mov ax, bx mov bx, # PM_BIOSMEM_VBE_POWER mov [bx], ah mov ax, #0x004f jmp cirrus_vesa_10h_donecirrus_vesa_10h_02: cmp bl, #0x02 ja cirrus_vesa_10h_unimplemented ;; ;; Function 02h: Get power state ;; mov bx, # PM_BIOSMEM_VBE_POWER mov bh, [bx] mov ax, #0x004f jmp cirrus_vesa_10h_donecirrus_vesa_10h_unimplemented: mov ax, #0x014F ;; not implementedcirrus_vesa_10h_done: pop ds retcirrus_vesa_unimplemented: mov ax, #0x014F ;; not implemented ret;; in ax:vesamode, out ax:cirrusmodecirrus_vesamode_to_mode: push ds push cx push si push cs pop ds mov cx, #0xffff mov si, #_cirrus_vesa_modelistcvtm_1: cmp [si],ax jz cvtm_2 cmp [si],cx jz cvtm_2 add si, #4 jmp cvtm_1cvtm_2: mov ax,[si+2] pop si pop cx pop ds ret ; cirrus_get_crtc ;; NOTE - may be called in protected modecirrus_get_crtc: push ds push ax mov dx, #0x3cc in al, dx and al, #0x01 shl al, #5 mov dx, #0x3b4 add dl, al pop ax pop ds ret;; in - al:mode, out - cflag:result, si:table, ax:destroyedcirrus_get_modeentry: and al, #0x7fcirrus_get_modeentry_nomask: mov si, #_cirrus_modescgm_1: db 0x2e ;; cs: mov ah, [si] cmp al, ah jz cgm_2 cmp ah, #0xff jz cgm_4 add si, # CIRRUS_MODE_SIZE jmp cgm_1cgm_4: xor si, si stc ;; video mode is not supported jmp cgm_3cgm_2: clc ;; video mode is supportedcgm_3: ret ; get LFB address ; out - ax:LFB address (high 16 bit) ;; NOTE - may be called in protected modecirrus_get_lfb_addr: push cx push dx push eax xor cx, cx mov dl, #0x00 call cirrus_pci_read cmp ax, #0xffff jz cirrus_get_lfb_addr_5 cirrus_get_lfb_addr_3: mov dl, #0x00 call cirrus_pci_read cmp ax, #0x1013 ;; cirrus jz cirrus_get_lfb_addr_4 add cx, #0x8 cmp cx, #0x200 ;; search bus #0 and #1 jb cirrus_get_lfb_addr_3 cirrus_get_lfb_addr_5: xor dx, dx ;; no LFB jmp cirrus_get_lfb_addr_6 cirrus_get_lfb_addr_4: mov dl, #0x10 ;; I/O space #0 call cirrus_pci_read test ax, #0xfff1 jnz cirrus_get_lfb_addr_5 shr eax, #16 mov dx, ax ;; LFB address cirrus_get_lfb_addr_6: pop eax mov ax, dx pop dx pop cx retcirrus_pci_read: mov eax, #0x00800000 mov ax, cx shl eax, #8 mov al, dl mov dx, #0xcf8 out dx, eax add dl, #4 in eax, dx ret;; out - al:bytes per pixelcirrus_get_bpp_bytes: push dx mov dx, #0x03c4 mov al, #0x07 out dx, al inc dx in al, dx and al, #0x0e cmp al, #0x06 jne cirrus_get_bpp_bytes_1 and al, #0x02cirrus_get_bpp_bytes_1: shr al, #1 cmp al, #0x04 je cirrus_get_bpp_bytes_2 inc alcirrus_get_bpp_bytes_2: pop dx ret;; in - ax: new line offsetcirrus_set_line_offset: shr ax, #3 push ax call cirrus_get_crtc mov al, #0x13 out dx, al inc dx pop ax out dx, al dec dx mov al, #0x1b out dx, al inc dx shl ah, #4 in al, dx and al, #ef or al, ah out dx, al ret;; out - ax: active line offsetcirrus_get_line_offset: push dx push bx call cirrus_get_crtc mov al, #0x13 out dx, al inc dx in al, dx mov bl, al dec dx mov al, #0x1b out dx, al inc dx in al, dx mov ah, al shr ah, #4 and ah, #0x01 mov al, bl shl ax, #3 pop bx pop dx ret;; in - si: table;; out - ax: line offset for modecirrus_get_line_offset_entry: push bx mov bx, [si+14] ;; crtc table push bxoffset_loop1: mov ax, [bx] cmp al, #0x13 je offset_found1 inc bx inc bx jnz offset_loop1offset_found1: xor al, al shr ax, #5 pop bx push axoffset_loop2: mov ax, [bx] cmp al, #0x1b je offset_found2 inc bx inc bx jnz offset_loop2offset_found2: pop bx and ax, #0x1000 shr ax, #1 or ax, bx pop bx ret;; in - new address in DX:AXcirrus_set_start_addr: push bx push dx push ax call cirrus_get_crtc mov al, #0x0d out dx, al inc dx pop ax out dx, al dec dx mov al, #0x0c out dx, al inc dx mov al, ah out dx, al dec dx mov al, #0x1d out dx, al inc dx in al, dx and al, #0x7f pop bx mov ah, bl shl bl, #4 and bl, #0x80 or al, bl out dx, al dec dx mov bl, ah and ah, #0x01 shl bl, #1 and bl, #0x0c or ah, bl mov al, #0x1b out dx, al inc dx in al, dx and al, #0xf2 or al, ah out dx, al pop bx ret;; out - current address in DX:AXcirrus_get_start_addr: push bx call cirrus_get_crtc mov al, #0x0c out dx, al inc dx in al, dx mov ah, al dec dx mov al, #0x0d out dx, al inc dx in al, dx push ax dec dx mov al, #0x1b out dx, al inc dx in al, dx dec dx mov bl, al and al, #0x01 and bl, #0x0c shr bl, #1 or bl, al mov al, #0x1d out dx, al inc dx in al, dx and al, #0x80 shr al, #4 or bl, al mov dl, bl xor dh, dh pop ax pop bx retcirrus_clear_vram: pusha push es mov si, ax call cirrus_enable_16k_granularity call cirrus_extbios_85h shl al, #2 mov bl, al xor ah,ahcirrus_clear_vram_1: mov al, #0x09 mov dx, #0x3ce out dx, ax push ax;; Windows Vista appears to be emulating this sequence as part of changing ;; screen resolution, but it generates 4096 writes per iteration.;; Instead, use a magic register sequence to write the whole bank.;;mov cx, #0xa000;;mov es, cx;;xor di, di;;mov ax, si;;mov cx, #8192;;cld;;rep;; stosw mov ax, si shl ax, #8 mov al, #0xfe out dx, ax ;; Low byte of value to be written to the bank mov ax, si mov al, #0xff out dx, ax ;; High byte and trigger the write pop ax inc ah cmp ah, bl jne cirrus_clear_vram_1 xor ah,ah mov dx, #0x3ce out dx, ax pop es popa retcirrus_extbios_handlers: ;; 80h dw cirrus_extbios_80h dw cirrus_extbios_81h dw cirrus_extbios_82h dw cirrus_extbios_unimplemented ;; 84h dw cirrus_extbios_unimplemented dw cirrus_extbios_85h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 88h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 8Ch dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 90h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 94h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 98h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_9Ah dw cirrus_extbios_unimplemented ;; 9Ch dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; A0h dw cirrus_extbios_A0h dw cirrus_extbios_A1h dw cirrus_extbios_A2h dw cirrus_extbios_unimplemented ;; A4h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; A8h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; ACh dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_AEh dw cirrus_extbios_unimplementedcirrus_vesa_handlers: ;; 00h dw cirrus_vesa_00h dw cirrus_vesa_01h dw cirrus_vesa_02h dw cirrus_vesa_03h ;; 04h dw cirrus_vesa_unimplemented dw cirrus_vesa_05h dw cirrus_vesa_06h dw cirrus_vesa_07h ;; 08h dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented ;; 0Ch dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented ;; 10h dw cirrus_vesa_10hASM_END#ifdef CIRRUS_VESA3_PMINFOASM_STARTcirrus_vesa_pminfo: /* + 0 */ .byte 0x50,0x4d,0x49,0x44 ;; signature[4] /* + 4 */ dw cirrus_vesa_pmbios_entry ;; entry_bios dw cirrus_vesa_pmbios_init ;; entry_init /* + 8 */cirrus_vesa_sel0000_data: dw 0x0000 ;; sel_00000cirrus_vesa_selA000_data: dw 0xA000 ;; sel_A0000 /* +12 */cirrus_vesa_selB000_data: dw 0xB000 ;; sel_B0000cirrus_vesa_selB800_data: dw 0xB800 ;; sel_B8000 /* +16 */cirrus_vesa_selC000_data: dw 0xC000 ;; sel_C0000cirrus_vesa_is_protected_mode: ;; protected mode flag and checksum dw (~((0xf2 + (cirrus_vesa_pmbios_entry >> 8) + (cirrus_vesa_pmbios_entry) \ + (cirrus_vesa_pmbios_init >> 8) + (cirrus_vesa_pmbios_init)) & 0xff) << 8) + 0x01ASM_END#endif // CIRRUS_VESA3_PMINFO#ifdef CIRRUS_DEBUGstatic void cirrus_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;{ if((GET_AH()!=0x0E)&&(GET_AH()!=0x02)&&(GET_AH()!=0x09)&&(AX!=0x4F05)) printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -