diff options
author | Volker Ruppert <info@vruppert.de> | 2004-06-16 21:08:34 +0000 |
---|---|---|
committer | Volker Ruppert <info@vruppert.de> | 2004-06-16 21:08:34 +0000 |
commit | 96f6c96a190d261bf66132098748c28a13991ed7 (patch) | |
tree | f725b5fd8e15e272e42af9754d762d35c48b8189 | |
parent | 4f44ea89f36e4e4610e178b11d7c045bf97b02c3 (diff) | |
download | vgabios-96f6c96a190d261bf66132098748c28a13991ed7.tar.gz |
- applied suzu's cirrus extension patch. Cirrus SVGA detection, most of the
cirrus-specific modes and some basic VBE features are present now.
-rw-r--r-- | Makefile | 22 | ||||
-rw-r--r-- | clext.c | 1085 | ||||
-rw-r--r-- | vgabios.c | 12 |
3 files changed, 1118 insertions, 1 deletions
@@ -10,11 +10,13 @@ RELVERS = `pwd | sed "s-.*/--" | sed "s/vgabios//" | sed "s/-//"` VGABIOS_DATE = "-DVGABIOS_DATE=\"$(RELDATE)\"" -all: bios +all: bios cirrus-bios bios: vgabios.bin vgabios.debug.bin +cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin + clean: /bin/rm -f *.o *.s *.ld86 \ temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak @@ -46,3 +48,21 @@ vgabios.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetab rm -f _vgabios-debug_.s _vgabios-debug_.c vgabios-debug.s mv vgabios.debug.bin VGABIOS-lgpl-latest.debug.bin ls -l VGABIOS-lgpl-latest.debug.bin + +vgabios-cirrus.bin: vgabios.c vgabios.h vgafonts.h vgatables.h clext.c + gcc -E vgabios.c $(VGABIOS_VERS) -DCIRRUS $(VGABIOS_DATE) > _vgabios_.c + bcc -o vgabios.s -C-c -D__i86__ -S -0 _vgabios_.c + sed -e 's/^\.text//' -e 's/^\.data//' vgabios.s > _vgabios_.s + as86 _vgabios_.s -b vgabios.bin -u -w- -g -0 -j -O -l vgabios.txt + rm -f _vgabios_.s _vgabios_.c vgabios.s + mv vgabios.bin VGABIOS-lgpl-latest.cirrus.bin + ls -l VGABIOS-lgpl-latest.cirrus.bin + +vgabios-cirrus.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h clext.c + gcc -E vgabios.c $(VGABIOS_VERS) -DCIRRUS -DCIRRUS_DEBUG $(VGABIOS_DATE) > _vgabios-debug_.c + bcc -o vgabios-debug.s -C-c -D__i86__ -S -0 _vgabios-debug_.c + sed -e 's/^\.text//' -e 's/^\.data//' vgabios-debug.s > _vgabios-debug_.s + as86 _vgabios-debug_.s -b vgabios.debug.bin -u -w- -g -0 -j -O -l vgabios.debug.txt + rm -f _vgabios-debug_.s _vgabios-debug_.c vgabios-debug.s + mv vgabios.debug.bin VGABIOS-lgpl-latest.cirrus.debug.bin + ls -l VGABIOS-lgpl-latest.cirrus.debug.bin @@ -0,0 +1,1085 @@ +// +// QEMU Cirrus CLGD 54xx VGABIOS Extension. +// +// Copyright (c) 2004 Makoto Suzuki (suzu) +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +typedef struct +{ + /* + 0 */ + unsigned short mode; + unsigned short width; + unsigned short height; + unsigned short depth; + /* + 8 */ + unsigned short hidden_dac; /* 0x3c6 */ + unsigned short *seq; /* 0x3c4 */ + unsigned short *graph; /* 0x3ce */ + unsigned short *crtc; /* 0x3d4 */ + /* +16 */ + unsigned char bitsperpixel; + unsigned char vesacolortype; + unsigned char vesaredmask; + unsigned char vesaredpos; + unsigned char vesagreenmask; + unsigned char vesagreenpos; + unsigned char vesabluemask; + unsigned char vesabluepos; + /* +24 */ + unsigned char vesareservedmask; + unsigned char vesareservedpos; +} cirrus_mode_t; +#define CIRRUS_MODE_SIZE 26 + +/* VGA */ +unsigned short cseq_vga[] = {0x0007,0xffff}; +unsigned short cgraph_vga[] = {0x0009,0x000a,0x200b,0xffff}; +unsigned short ccrtc_vga[] = {0x001a,0x001b,0x001d,0xffff}; + +/* extensions */ +unsigned short cgraph_svgacolor[] = { +0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08, +0x0009,0x000a,0x200b, +0xffff +}; +/* 640x480x8 */ +unsigned short cseq_640x480x8[] = { +0x0100,0x2101,0x0f02,0x0003,0x0e04,0x1107, +0x580b,0x580c,0x580d,0x580e, +0x0412,0x0013,0x2017, +0x331b,0x331c,0x331d,0x331e, +0xffff +}; +unsigned short ccrtc_640x480x8[] = { +0x2c11, +0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, +0x4009,0x000c,0x000d, +0xea10,0xdf12,0x5013,0x0014,0xdf15,0x0b16,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 640x480x16 */ +unsigned short cseq_640x480x16[] = { +0x0100,0x2101,0x0f02,0x0003,0x0e04,0x1707, +0x580b,0x580c,0x580d,0x580e, +0x0412,0x0013,0x2017, +0x331b,0x331c,0x331d,0x331e, +0xffff +}; +unsigned short ccrtc_640x480x16[] = { +0x2c11, +0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, +0x4009,0x000c,0x000d, +0xea10,0xdf12,0xa013,0x0014,0xdf15,0x0b16,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 640x480x24 */ +unsigned short cseq_640x480x24[] = { +0x0100,0x2101,0x0f02,0x0003,0x0e04,0x1507, +0x580b,0x580c,0x580d,0x580e, +0x0412,0x0013,0x2017, +0x331b,0x331c,0x331d,0x331e, +0xffff +}; +unsigned short ccrtc_640x480x24[] = { +0x2c11, +0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, +0x4009,0x000c,0x000d, +0xea10,0xdf12,0x0013,0x0014,0xdf15,0x0b16,0xc317,0xff18, +0x001a,0x321b,0x001d, +0xffff +}; +/* 800x600x8 */ +unsigned short cseq_800x600x8[] = { +0x0100,0x2101,0x0f02,0x0003,0x0e04,0x1107, +0x230b,0x230c,0x230d,0x230e, +0x0412,0x0013,0x2017, +0x141b,0x141c,0x141d,0x141e, +0xffff +}; +unsigned short ccrtc_800x600x8[] = { +0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, +0x6009,0x000c,0x000d, +0x7d10,0x5712,0x6413,0x0014,0x5715,0x9816,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 800x600x16 */ +unsigned short cseq_800x600x16[] = { +0x0100,0x2101,0x0f02,0x0003,0x0e04,0x1707, +0x230b,0x230c,0x230d,0x230e, +0x0412,0x0013,0x2017, +0x141b,0x141c,0x141d,0x141e, +0xffff +}; +unsigned short ccrtc_800x600x16[] = { +0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, +0x6009,0x000c,0x000d, +0x7d10,0x5712,0xc813,0x0014,0x5715,0x9816,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 800x600x24 */ +unsigned short cseq_800x600x24[] = { +0x0100,0x2101,0x0f02,0x0003,0x0e04,0x1507, +0x230b,0x230c,0x230d,0x230e, +0x0412,0x0013,0x2017, +0x141b,0x141c,0x141d,0x141e, +0xffff +}; +unsigned short ccrtc_800x600x24[] = { +0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, +0x6009,0x000c,0x000d, +0x7d10,0x5712,0x2c13,0x0014,0x5715,0x9816,0xc317,0xff18, +0x001a,0x321b,0x001d, +0xffff +}; +/* 1024x768x8 */ +unsigned short cseq_1024x768x8[] = { +0x0100,0x2101,0x0f02,0x0003,0x0e04,0x1107, +0x760b,0x760c,0x760d,0x760e, +0x0412,0x0013,0x2017, +0x341b,0x341c,0x341d,0x341e, +0xffff +}; +unsigned short ccrtc_1024x768x8[] = { +0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, +0x6009,0x000c,0x000d, +0x0310,0xff12,0x8013,0x0014,0xff15,0x2416,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 1024x768x16 */ +unsigned short cseq_1024x768x16[] = { +0x0100,0x2101,0x0f02,0x0003,0x0e04,0x1707, +0x760b,0x760c,0x760d,0x760e, +0x0412,0x0013,0x2017, +0x341b,0x341c,0x341d,0x341e, +0xffff +}; +unsigned short ccrtc_1024x768x16[] = { +0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, +0x6009,0x000c,0x000d, +0x0310,0xff12,0x0013,0x0014,0xff15,0x2416,0xc317,0xff18, +0x001a,0x321b,0x001d, +0xffff +}; +/* 1024x768x24 */ +unsigned short cseq_1024x768x24[] = { +0x0100,0x2101,0x0f02,0x0003,0x0e04,0x1507, +0x760b,0x760c,0x760d,0x760e, +0x0412,0x0013,0x2017, +0x341b,0x341c,0x341d,0x341e, +0xffff +}; +unsigned short ccrtc_1024x768x24[] = { +0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, +0x6009,0x000c,0x000d, +0x0310,0xff12,0x8013,0x0014,0xff15,0x2416,0xc317,0xff18, +0x001a,0x321b,0x001d, +0xffff +}; + + +cirrus_mode_t cirrus_modes[] = +{ + {0x5f,640,480,8,0x00, + cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, + 4,0,0,0,0,0,0,0,0}, + {0x64,640,480,16,0xc1, + cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, + 6,5,11,6,5,5,0,0,0}, + {0x66,640,480,15,0xc0, + cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, + 6,5,10,5,5,5,0,1,15}, + {0x71,640,480,24,0xc5, + cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, + 6,8,16,8,8,8,0,0,0}, + + {0x5c,800,600,8,0x00, + cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, + 4,0,0,0,0,0,0,0,0}, + {0x65,800,600,16,0xc1, + cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, + 6,5,11,6,5,5,0,0,0}, + {0x67,800,600,15,0xc0, + cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, + 6,5,10,5,5,5,0,1,15}, + + {0x60,1024,768,8,0x00, + cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, + 4,0,0,0,0,0,0,0,0}, + {0x74,1024,768,16,0xc1, + cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, + 6,5,11,6,5,5,0,0,0}, + {0x68,1024,768,15,0xc0, + cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, + 6,5,10,5,5,5,0,1,15}, + + {0xe0,800,600,24,0xc5, + cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, + 6,8,16,8,8,8,0,0,0}, + {0xe1,1024,768,24,0xc5, + cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, + 6,8,16,8,8,8,0,0,0}, + + {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, + 0xff,0,0,0,0,0,0,0,0}, + {0xff,0,0,0,0,0,0,0,0, + 0xff,0,0,0,0,0,0,0,0}, +}; + +unsigned char cirrus_id_table[] = { + // 5430 + 0xA0, 0x32, + // 5446 + 0xB8, 0x39, + + 0xff, 0xff +}; + + +unsigned short cirrus_vesa_modelist[] = { +// 640x480x8 + 0x101, 0x5f, +// 640x480x15 + 0x110, 0x66, +// 640x480x16 + 0x111, 0x64, +// 640x480x24 + 0x112, 0x71, +// 800x600x8 + 0x103, 0x5c, +// 800x600x15 + 0x113, 0x67, +// 800x600x16 + 0x114, 0x65, +// 800x600x24 + 0x115, 0xe0, +// 1024x768x8 + 0x105, 0x60, +// 1024x768x15 + 0x116, 0x68, +// 1024x768x16 + 0x117, 0x74, +// 1024x768x24 +//0x118, 0xe1, +// invalid + 0xffff,0xffff +}; + + +ASM_START + +cirrus_installed: +.ascii "cirrus-compatible VGA is detected" +.byte 0x0d,0x0a +.byte 0x0d,0x0a,0x00 + +cirrus_not_installed: +.ascii "cirrus-compatible VGA is not detected" +.byte 0x0d,0x0a +.byte 0x0d,0x0a,0x00 + +cirrus_vesa_vendorname: +cirrus_vesa_productname: +cirrus_vesa_oemname: +.ascii "VGABIOS Cirrus extension" +.byte 0 +cirrus_vesa_productrevision: +.ascii "1.0" +.byte 0 + +cirrus_init: + call cirrus_check + jnz no_cirrus + SET_INT_VECTOR(0x10, #0xC000, #cirrus_int10_handler) + mov al, #0x0f + mov dx, #0x3C4 + out dx, al + inc dx + in al, dx + and al, #0x18 + mov ah, al + mov al, #0x0a + dec dx + out dx, ax +no_cirrus: + ret + +cirrus_display_info: + push ds + push si + push cs + pop ds + call cirrus_check + mov si, #cirrus_not_installed + jnz cirrus_msgnotinstalled + mov si, #cirrus_installed + +cirrus_msgnotinstalled: + call _display_string + pop si + pop ds + ret + +cirrus_check: + push ax + push dx + mov ax, #0x9206 + mov dx, #0x3C4 + out dx, ax + inc dx + in al, dx + cmp al, #0x12 + pop dx + pop ax + ret + + +cirrus_int10_handler: + pushf + push bp + cmp ah, #0x00 ;; set video mode + jz cirrus_set_video_mode + cmp ah, #0x12 ;; cirrus extension + jz cirrus_extbios + cmp ah, #0x4F ;; VESA extension + jz cirrus_vesa + +cirrus_unhandled: + pop bp + popf + jmp vgabios_int10_handler + +cirrus_return: +#ifdef CIRRUS_DEBUG + call cirrus_debug_dump +#endif + pop bp + popf + iret + +cirrus_set_video_mode: +#ifdef CIRRUS_DEBUG + call cirrus_debug_dump +#endif + push si + push ax + push bx + push ds + mov si, # BIOSMEM_SEG + mov ds, si + xor bx, bx + mov [BIOSMEM_VBE_MODE], bx + pop ds + pop bx + call cirrus_get_modeentry + jnc cirrus_set_video_mode_extended + mov al, #0xfe + call cirrus_get_modeentry_nomask + call cirrus_switch_mode + pop ax + pop si + jmp cirrus_unhandled + +cirrus_extbios: +#ifdef CIRRUS_DEBUG + call cirrus_debug_dump +#endif + cmp bl, #0x80 + jb cirrus_unhandled + cmp bl, #0xAF + ja cirrus_unhandled + push bx + and bx, #0x7F + shl bx, 1 + db 0x2e ;; cs: + mov bp, cirrus_extbios_handlers[bx] + pop bx + push #cirrus_return + push bp + ret + +cirrus_vesa: +#ifdef CIRRUS_DEBUG + call cirrus_debug_dump +#endif + cmp al, #0x0F + ja cirrus_vesa_not_handled + push bx + xor bx, bx + mov bl, al + shl bx, 1 + db 0x2e ;; cs: + mov bp, cirrus_vesa_handlers[bx] + pop bx + push #cirrus_return + push bp + ret + +cirrus_vesa_not_handled: + mov ax, #0x014F ;; not implemented + jmp cirrus_return + +#ifdef CIRRUS_DEBUG +cirrus_debug_dump: + push es + push ds + pusha + mov bx, #0xc000 + mov ds, bx + call _cirrus_debugmsg + popa + pop ds + pop es + ret +#endif + +cirrus_set_video_mode_extended: + call cirrus_switch_mode + pop ax ;; mode + and al, #0x7f + + push ds + mov si, # BIOSMEM_SEG + mov ds, si + mov [BIOSMEM_CURRENT_MODE], al + pop ds + + mov al, #0x20 + + pop si + jmp cirrus_return + +; in si:mode table +cirrus_switch_mode: + push ds + push bx + push dx + push cs + pop ds + + mov bx, [si+10] ;; seq + mov dx, #0x3c4 + mov ax, #0x1206 + out dx, ax ;; Unlock cirrus special + call cirrus_switch_mode_setregs + + mov bx, [si+12] ;; graph + mov dx, #0x3ce + call cirrus_switch_mode_setregs + + mov bx, [si+14] ;; crtc + call cirrus_get_crtc + call cirrus_switch_mode_setregs + + mov dx, #0x3c6 + mov al, #0x00 + out dx, al + in al, dx + in al, dx + in al, dx + in al, dx + mov al, [si+8] ;; hidden dac + out dx, al + mov al, #0xff + out dx, al + + mov al, #0x00 + mov bl, [si+17] ;; memory model + or bl, bl + jz is_text_mode + mov al, #0x01 + cmp bl, #0x03 + jnz is_text_mode + or al, #0x40 +is_text_mode: + mov bl, #0x10 + call biosfn_get_single_palette_reg + and bh, #0xfe + or bh, al + call biosfn_set_single_palette_reg + + pop dx + pop bx + pop ds + ret + +cirrus_enable_dualbank: + push ax + push dx + mov dx, #0x3ce + mov al, #0x0b + out dx, al + inc dx + in al, dx + or al, #0x01 ;; enable dual bank + out dx, al + pop dx + pop ax + ret + +cirrus_switch_mode_setregs: +csms_1: + mov ax, [bx] + cmp ax, #0xffff + jz csms_2 + out dx, ax + add bx, #0x2 + jmp csms_1 +csms_2: + ret + +cirrus_extbios_80h: + push dx + call cirrus_get_crtc + mov al, #0x27 + out dx, al + inc dx + in al, dx + mov bx, #_cirrus_id_table +c80h_1: + db 0x2e ;; cs: + mov ah, [bx] + cmp ah, al + jz c80h_2 + cmp ah, #0xff + jz c80h_2 + inc bx + inc bx + jmp c80h_1 +c80h_2: + db 0x2e ;; cs: + mov al, 0x1[bx] + pop dx + mov ah, #0x00 + xor bx, bx + ret + +cirrus_extbios_81h: + mov ax, #0x100 ;; XXX + ret +cirrus_extbios_82h: + push dx + call cirrus_get_crtc + xor ax, ax + mov al, #0x27 + out dx, al + inc dx + in al, dx + and al, #0x03 + mov ah, #0xAF + pop dx + ret + +cirrus_extbios_85h: + push cx + push dx + mov dx, #0x3C4 + mov al, #0x0f ;; get DRAM band width + out dx, al + inc dx + in al, dx + ;; al = 4 << bandwidth + mov cl, al + shr cl, #0x03 + and cl, #0x03 + mov al, #0x04 + shl al, cl + pop dx + pop cx + ret + +cirrus_extbios_9Ah: + mov ax, #0x4060 + mov cx, #0x1132 + ret + +cirrus_extbios_A0h: + call cirrus_get_modeentry + mov ah, #0x01 + sbb ah, #0x00 + mov bx, cirrus_extbios_A0h_callback + mov si, #0xffff + mov di, bx + mov ds, bx + mov es, bx + ret + +cirrus_extbios_A0h_callback: + ;; fatal: not implemented yet + cli + hlt + retf + +cirrus_extbios_A1h: + mov bx, #0x0E00 ;; IBM 8512/8513, color + ret + +cirrus_extbios_A2h: + mov al, #0x07 ;; HSync 31.5 - 64.0 kHz + ret + +cirrus_extbios_AEh: + mov al, #0x01 ;; High Refresh 75Hz + ret + +cirrus_extbios_unimplemented: + ret + +cirrus_vesa_00h: + push ds + push si + mov bp, di + push es + pop ds + cld + mov ax, [di] + cmp ax, #0x4256 ;; VB + jnz cv00_1 + mov ax, [di+2] + cmp ax, #0x3245 ;; E2 + jnz cv00_1 + ;; VBE2 + lea di, 0x14[bp] + mov ax, #0x0100 ;; soft ver. + stosw + mov ax, # cirrus_vesa_vendorname + stosw + mov ax, cs + stosw + mov ax, # cirrus_vesa_productname + stosw + mov ax, cs + stosw + mov ax, # cirrus_vesa_productrevision + stosw + mov ax, cs + stosw +cv00_1: + mov di, bp + mov ax, #0x4556 ;; VE + stosw + mov ax, #0x4153 ;; SA + stosw + mov ax, #0x0200 ;; v2.00 + stosw + mov ax, # cirrus_vesa_oemname + stosw + mov ax, cs + stosw + xor ax, ax ;; caps + stosw + stosw + lea ax, 0x40[bp] + stosw + mov ax, es + stosw + call cirrus_extbios_85h ;; vram in 64k + mov ah, #0x00 + stosw + + push cs + pop ds + lea di, 0x40[bp] + mov si, #_cirrus_vesa_modelist +cv00_2: + lodsw + stosw + add si, #2 + cmp ax, #0xffff + jnz cv00_2 + + mov ax, #0x004F + mov di, bp + pop si + pop ds + ret + +cirrus_vesa_01h: + mov ax, cx + call cirrus_vesamode_to_mode + cmp ax, #0xffff + jnz cirrus_vesa_01h_1 + jmp cirrus_vesa_unimplemented +cirrus_vesa_01h_1: + push ds + push si + push cx + push dx + push bx + mov bp, di + cld + push cs + pop ds + call cirrus_get_modeentry_nomask + + push di + xor ax, ax + mov cx, #0x80 + rep + stosw ;; clear buffer + pop di + + mov ax, #0x003b ;; mode XXX:LFB support + stosw + mov ax, #0x0707 ;; attr XXX:LFB support + stosw + mov ax, #0x0010 ;; granularity =16K + stosw + mov ax, #0x0020 ;; size =32K + stosw + mov ax, #0xA000 ;; segment A + stosw + mov ax, #0xA400 ;; segment B + stosw + mov ax, #cirrus_vesa_05h_farentry + stosw + mov ax, cs + stosw + mov al, [si+16] + cmp al, #0x18 + jne no_24bpp + mov ax, [si+2] + cmp ax, #0x280 + jne no_24bpp + mov ax, #0x800 + jmp store_bpsl +no_24bpp: + mov ax, [si+2] + shr ax, #0x3 + xor cx, cx + mov cl, [si+16] + mul cx +store_bpsl: + stosw ;; bytes per scan line + mov ax, [si+2] ;; width + stosw + mov ax, [si+4] ;; height + stosw + mov ax, #0x08 + stosb + mov ax, #0x10 + stosb + mov al, #1 ;; count of planes + stosb + mov al, [si+6] ;; bpp + stosb + mov al, #0x1 ;; XXX number of banks + stosb + mov al, [si+17] + stosb ;; memory model + mov al, #0x0 ;; XXX size of bank in K + stosb + mov ax, [si+2] + shr ax, #3 + xor bx, bx + mov bl, [si+16] + mul bx + mov bx, [si+4] + mul bx ;; dx:ax=vramdisp + or ax, ax + jz cirrus_vesa_01h_3 + inc dx +cirrus_vesa_01h_3: + call cirrus_extbios_85h ;; ax=vram in 64k + mov ah, #0x00 + mov cx, dx + xor dx, dx + div cx + dec ax + stosb ;; number of image pages = vramtotal/vramdisp-1 + mov al, #0x00 + stosb + + ;; v1.2+ stuffs + push si + add si, #18 + movsw + movsw + movsw + movsw + pop si + + mov ah, [si+16] + mov al, #0x0 + sub ah, #9 + rcl al, #1 ; bit 0=palette flag + stosb ;; direct screen mode info + + ;; v2.0+ stuffs + ;; XXX 32-bit LFB address + xor ax, ax + stosw + stosw + xor ax, ax + stosw ; reserved + stosw ; reserved + stosw ; reserved + + mov ax, #0x004F + mov di, bp + pop bx + pop dx + pop cx + pop si + pop ds + ret + +cirrus_vesa_02h: + test bx, #0x3e00 + jnz cirrus_vesa_02h_2 ;; unknown flags + mov ax, bx + and ax, #0x1ff ;; bit 8-0 mode + call cirrus_vesamode_to_mode + cmp ax, #0xffff + jnz cirrus_vesa_02h_1 +cirrus_vesa_02h_2: + jmp cirrus_vesa_unimplemented +cirrus_vesa_02h_1: + push si + push ax + call cirrus_get_modeentry_nomask + call cirrus_switch_mode + test bx, #0x4000 ;; LFB + jz cirrus_vesa_02h_3 + call cirrus_enable_dualbank +cirrus_vesa_02h_3: + pop ax + push ds + mov si, # BIOSMEM_SEG + mov ds, si + mov [BIOSMEM_CURRENT_MODE], al + mov [BIOSMEM_VBE_MODE], bx + pop ds + pop si + mov ax, #0x004F + ret + +cirrus_vesa_03h: + push ds + mov ax, # BIOSMEM_SEG + mov ds, ax + mov bx, # BIOSMEM_VBE_MODE + mov ax, [bx] + mov bx, ax + test bx, bx + jnz cirrus_vesa_03h_1 + mov bx, # BIOSMEM_CURRENT_MODE + mov al, [bx] + mov bl, al + xor bh, bh +cirrus_vesa_03h_1: + mov ax, #0x004f + pop ds + ret + +cirrus_vesa_05h_farentry: + call cirrus_vesa_05h + retf + +cirrus_vesa_05h: + cmp bl, #0x01 + ja cirrus_vesa_05h_1 + cmp bh, #0x00 + jz cirrus_vesa_05h_setmempage + cmp bh, #0x01 + jz cirrus_vesa_05h_getmempage +cirrus_vesa_05h_1: + jmp cirrus_vesa_unimplemented +cirrus_vesa_05h_setmempage: + or dh, dh ; address must be < 0x100 + jnz cirrus_vesa_05h_1 + push dx + mov al, bl ;; bl=bank number + add al, #0x09 + mov ah, dl ;; dx=window address in granularity + mov dx, #0x3ce + out dx, ax + pop dx + mov ax, #0x004F + ret +cirrus_vesa_05h_getmempage: + mov al, bl ;; bl=bank number + add al, #0x09 + mov dx, #0x3ce + out dx, al + inc dx + in al, dx + xor dx, dx + mov dl, al ;; dx=window address in granularity + mov ax, #0x004F + ret + +cirrus_vesa_unimplemented: + mov ax, #0x014F ;; not implemented + ret + + +;; in ax:vesamode, out ax:cirrusmode +cirrus_vesamode_to_mode: + push ds + push cx + push si + push cs + pop ds + mov cx, #0xffff + mov si, #_cirrus_vesa_modelist +cvtm_1: + cmp [si],ax + jz cvtm_2 + cmp [si],cx + jz cvtm_2 + add si, #4 + jmp cvtm_1 +cvtm_2: + mov ax,[si+2] + pop si + pop cx + pop ds + ret + + ; cirrus_get_crtc +cirrus_get_crtc: + push ds + xor dx, dx + mov ds, dx + mov dx, [0x463] ;; CRTC register + pop ds + ret + +;; in - al:mode, out - cflag:result, si:table, ax:destroyed +cirrus_get_modeentry: + and al, #0x7f +cirrus_get_modeentry_nomask: + mov si, #_cirrus_modes +cgm_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_1 +cgm_4: + xor si, si + stc ;; video mode is not supported + jmp cgm_3 +cgm_2: + clc ;; video mode is supported +cgm_3: + ret + +cirrus_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_unimplemented + +cirrus_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_unimplemented + dw cirrus_vesa_unimplemented + ;; 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 + + + +ASM_END + +#ifdef CIRRUS_DEBUG +static 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)) + printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX); +} +#endif @@ -214,6 +214,10 @@ vgabios_init_func: ;; set int10 vect SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler) +#ifdef CIRRUS + call cirrus_init +#endif + ;; display splash screen call _display_splash_screen @@ -229,6 +233,10 @@ vgabios_init_func: call vbe_display_info #endif +#ifdef CIRRUS +;; show cirrus info + call cirrus_display_info +#endif retf ASM_END @@ -3562,6 +3570,10 @@ void printf(s) #include "vbe.c" #endif +#ifdef CIRRUS +#include "clext.c" +#endif + // -------------------------------------------------------------------------------------------- ASM_START |