aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Ruppert <info@vruppert.de>2004-06-16 21:08:34 +0000
committerVolker Ruppert <info@vruppert.de>2004-06-16 21:08:34 +0000
commit96f6c96a190d261bf66132098748c28a13991ed7 (patch)
treef725b5fd8e15e272e42af9754d762d35c48b8189
parent4f44ea89f36e4e4610e178b11d7c045bf97b02c3 (diff)
downloadvgabios-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--Makefile22
-rw-r--r--clext.c1085
-rw-r--r--vgabios.c12
3 files changed, 1118 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index bba1598..1fb0abc 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/clext.c b/clext.c
new file mode 100644
index 0000000..a86b80e
--- /dev/null
+++ b/clext.c
@@ -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
diff --git a/vgabios.c b/vgabios.c
index bf0e2cc..f54d20d 100644
--- a/vgabios.c
+++ b/vgabios.c
@@ -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