Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37833569
en ru br
Репозитории ALT
S:4.04-alt19
D:3.61-alt1
5.1: 3.63-alt4
4.1: 3.36-alt2
4.0: 3.36-alt2
3.0: 2.11-alt1
www.altlinux.org/Changes

Группа :: Система/Ядро и оборудование
Пакет: syslinux

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: syslinux-2.11.patch
Скачать


--- add_crc
+++ add_crc
@@ -0,0 +1,49 @@
+#! /usr/bin/perl
+
+use integer;
+
+# patch crc over first sector - 64 bytes into isolinux
+
+$file = shift;
+$list = "$file";
+$list =~ s/\.bin$/.lst/;
+
+open F, $list;
+
+while(<F>) {
+  if(/^\s*\d+\s*(\S+)\s*0+\s*(\<\d+\>\s*)?csum_value\s*dd\s*0/) {
+    $ofs = hex $1;
+  }
+}
+close F;
+
+die "oops 1\n" unless $ofs && !($ofs & 3);
+
+# print "$ofs\n";
+
+open F, $file or die "$file: $!\n";
+
+$file_size = -s $file;
+
+sysread F, $buf, $file_size;
+
+close F;
+
+die "oops 1\n" if $file_size != length($buf);
+
+@x = unpack "V512", $buf;
+
+for ($sum = 0, $i = 16; $i < 512; $i++) {
+  $sum += $x[$i];
+}
+
+# printf "0x%08x\n", $sum;
+
+$ns = pack "V", -$sum;
+
+substr($buf, $ofs, 4) = $ns;
+
+open F, ">$file" or die "$file: $!\n";
+
+syswrite F, $buf;
+
--- bcopy32.inc
+++ bcopy32.inc
@@ -65,7 +65,17 @@
 ;	EDI	- first byte after target
 ;	ECX	- zero
 ;
-bcopy:		push eax
+bcopy:
+%if do_test
+		add esi,ecx
+		add edi,ecx
+		mov ecx,1000000*100
+.delay:
+		a32			; NOT at the same line as the loop!
+		loop .delay
+		ret
+%endif
+		push eax
 		pushf			; Saves, among others, the IF flag
 		push gs
 		push fs
--- config.inc
+++ config.inc
@@ -20,6 +20,8 @@
 %ifndef _CONFIG_INC
 %define _CONFIG_INC
 
+%define do_test 0
+
 max_cmd_len	equ 255			; Must be odd; 255 is the kernel limit
 HIGHMEM_MAX	equ 037FFFFFFh		; DEFAULT highest address for an initrd
 DEFAULT_BAUD	equ 9600		; Default baud rate for serial port
--- conio.inc
+++ conio.inc
@@ -46,6 +46,13 @@
 ;               set by routine searchdir
 ;
 get_msg_file:
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		; don't load if we have a graphics image
+		ret
+.nogfx:
+%endif
 		push es
 		shl edx,16			; EDX <- DX:AX (length of file)
 		mov dx,ax
@@ -323,6 +330,9 @@
 		RESET_IDLE
 .again:
 		DO_IDLE
+%ifdef WITH_GFX
+		call chk_update
+%endif
 		mov ah,1		; Poll keyboard
 		int 16h
 		jnz .kbd		; Keyboard input?
--- fixofs
+++ fixofs
@@ -0,0 +1,4 @@
+#! /usr/bin/perl -p
+
+$ok = 1 if /org\s+7c00h/i;
+s/^(\s*(\d+)\s+)([0-9A-Fa-f]{8})/$1 . sprintf("%08X", hex($3)+0x7c00)/e if $ok;
--- gethostip.c
+++ gethostip.c
@@ -120,7 +120,7 @@
 
     if ( output & 4 ) {
       unsigned long addr = 
-	(((unsigned char *)host->h_addr)[0] << 24UL) +
+	((unsigned long) ((unsigned char *)host->h_addr)[0] << 24UL) +
 	(((unsigned char *)host->h_addr)[1] << 16UL) +
 	(((unsigned char *)host->h_addr)[2] <<  8UL) +
 	(((unsigned char *)host->h_addr)[3]);
--- gfxlogo.inc
+++ gfxlogo.inc
@@ -0,0 +1,637 @@
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; gfx stuff
+;
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+; != 0 -> everything's fine
+; note: moved to ldlinux.asm/isolinux.asm
+; gfx_ok		db 0
+
+gfx_mem_end_seg		dw 0
+
+			align 4, db 0
+; the memory area we are working with
+gfx_mem			dd 0		; linear address
+gfx_mem_align		dd 0		; aligned data start
+gfx_mem_file		dd 0		; aligned gfx data start
+gfx_mem_max		dd 0		; end address
+gfx_mem_free		dd 0		; start of free area for malloc (after pcx image)
+
+; interface to loadable gfx extension (seg:ofs values)
+gfx_bc_jt		dd 0
+
+gfx_bc_init		dd 0
+gfx_bc_done		dd 0
+gfx_bc_input		dd 0
+gfx_bc_menu_init	dd 0
+gfx_bc_infobox_init	dd 0
+gfx_bc_infobox_done	dd 0
+gfx_bc_progress_init	dd 0
+gfx_bc_progress_done	dd 0
+gfx_bc_progress_update	dd 0
+gfx_bc_progress_limit	dd 0
+gfx_bc_password_init	dd 0
+gfx_bc_password_done	dd 0
+
+gfx_menu_max_entries	equ 16
+gfx_menu_tmp		equ mi_buf	; a reasonably sized buffer
+gfx_menu_def		zb 13
+gfx_menu_entry		zb 13 * gfx_menu_max_entries
+
+%if 0
+gfx_password_buf	zb 32
+gfx_msg_wrong_image	db 'Could not find kernel image: ', 0
+gfx_msg_wrong_password	db 'Sorry, incorrect password.', 0
+%endif
+
+; menu entry descriptor
+menu_entries		equ 0
+menu_default		equ 2		; seg:ofs
+menu_ent_list		equ 6		; seg:ofs
+menu_ent_size		equ 10
+menu_arg_list		equ 12		; seg:ofs
+menu_arg_size		equ 16
+sizeof_menu_desc	equ 18
+
+menu_desc		zb sizeof_menu_desc
+
+; system config data
+gfx_sysconfig		equ $
+gfx_bootloader		db 1
+gfx_update		db 0
+gfx_video_mode_list	dw fb_mode_list
+gfx_video_modes		db fb_mode_entries
+gfx_boot_drive		db 0
+gfx_reload_fs		db 0
+gfx_user_note		dw 0
+gfx_reserved		zb 3
+gfx_user_info_0		dd 0
+gfx_user_info_1		dd 0
+gfx_mem_size		dd 0
+
+%macro		lin2segofs 3
+		push %1
+		call gfx_l2so
+		pop %3
+		pop %2
+%endmacro
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; must not change registers!
+;
+gfx_get_sysconfig:
+		push ax
+		mov al,[wants_update]
+		mov [gfx_update],al
+%if IS_ISOLINUX
+		mov al,[DriveNo]
+%else
+		mov al,[bsDriveNumber]
+%endif
+		mov [gfx_boot_drive],al
+		push dword [HighMemSize]
+		pop dword [gfx_mem_size]
+		pop ax
+		ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_set_sysconfig:
+		push ax
+		mov al,[gfx_update]
+		mov [wants_update],al
+		pop ax
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Initialize graphics code. Load and display graphics data.
+;
+;  dx:ax	file length
+;  si		start cluster
+;
+;  return:	[gfx_ok] = 0/1
+;
+gfx_init:
+		push es
+
+		cld
+
+		movzx ecx,word [gfx_mem_end_seg]
+		shl ecx,4
+		jz near gfx_init_80
+
+		; define our memory area
+		; gfx_mem _must_ be 16-byte aligned
+		mov dword [gfx_mem],10000h
+		mov dword [gfx_mem_free],10000h
+		mov dword [gfx_mem_max],ecx
+
+		call gfx_read_file
+		cmp byte [gfx_ok],0
+		jz near gfx_init_90
+
+		; align 4
+		mov eax,[gfx_mem_free]
+		add eax,3
+		and eax,~3
+		mov [gfx_mem_free],eax
+
+		; setup jump table
+		les bx,[gfx_bc_jt]
+
+		mov ax,[es:bx]
+		mov [gfx_bc_init],ax
+		mov [gfx_bc_init+2],es
+
+		mov ax,[es:bx+2]
+		mov [gfx_bc_done],ax
+		mov [gfx_bc_done+2],es
+
+		mov ax,[es:bx+4]
+		mov [gfx_bc_input],ax
+		mov [gfx_bc_input+2],es
+
+		mov ax,[es:bx+6]
+		mov [gfx_bc_menu_init],ax
+		mov [gfx_bc_menu_init+2],es
+
+		mov ax,[es:bx+8]
+		mov [gfx_bc_infobox_init],ax
+		mov [gfx_bc_infobox_init+2],es
+
+		mov ax,[es:bx+10]
+		mov [gfx_bc_infobox_done],ax
+		mov [gfx_bc_infobox_done+2],es
+
+		mov ax,[es:bx+12]
+		mov [gfx_bc_progress_init],ax
+		mov [gfx_bc_progress_init+2],es
+
+		mov ax,[es:bx+14]
+		mov [gfx_bc_progress_done],ax
+		mov [gfx_bc_progress_done+2],es
+
+		mov ax,[es:bx+16]
+		mov [gfx_bc_progress_update],ax
+		mov [gfx_bc_progress_update+2],es
+
+		mov ax,[es:bx+18]
+		mov [gfx_bc_progress_limit],ax
+		mov [gfx_bc_progress_limit+2],es
+
+		mov ax,[es:bx+20]
+		mov [gfx_bc_password_init],ax
+		mov [gfx_bc_password_init+2],es
+
+		mov ax,[es:bx+22]
+		mov [gfx_bc_password_done],ax
+		mov [gfx_bc_password_done+2],es
+
+		mov eax,[gfx_mem_file]
+		mov ebx,[gfx_mem_free]
+		mov ecx,[gfx_mem_max]
+		mov edi,[gfx_mem_align]
+		mov dx,cs
+
+		mov si,gfx_sysconfig
+		call far [gfx_bc_init]
+		jc gfx_init_80
+
+		call highmemsize
+
+		mov byte [gfx_ok],1
+
+		jmp gfx_init_90
+
+gfx_init_80:
+		mov byte [gfx_ok],0
+gfx_init_90:
+		pop es
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Back to text mode.
+;
+;  return:	[gfx_ok] = 0
+;
+gfx_done:
+		cmp byte [gfx_ok],0
+		jz gfx_done_90
+		call far [gfx_bc_done]
+		mov byte [gfx_ok],0
+		call gfx_set_sysconfig
+gfx_done_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_input:
+		cmp byte [gfx_ok],0
+		jz gfx_input_90
+		call gfx_get_sysconfig
+		call far [gfx_bc_input]
+		pushf
+		call gfx_set_sysconfig
+		popf
+		jnc gfx_input_50
+		mov ax,1
+gfx_input_50:
+		cmp ax,1
+		jnz gfx_input_90
+		push ax
+		call gfx_done
+		pop ax
+gfx_input_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_setup_menu:
+		cmp byte [gfx_ok],0
+		jz gfx_setup_menu_90
+
+		push ds
+		pop es
+		mov si,default_cmd
+		mov di,gfx_menu_tmp
+		call mangle_name
+		mov si,gfx_menu_tmp
+		mov di,gfx_menu_def
+		call unmangle_name
+		mov ax,[VKernelCtr]
+		cmp ax,gfx_menu_max_entries
+		jb gfx_setup_menu_10
+		mov ax,gfx_menu_max_entries
+gfx_setup_menu_10:
+		mov [menu_desc+menu_entries],ax
+		or ax,ax
+		jz gfx_setup_menu_90
+		xor si,si
+		mov di,gfx_menu_entry
+gfx_setup_menu_20:
+		push di
+		push si
+		shl si,vk_shift
+		push ds
+		push word vk_seg
+		pop ds
+		mov bx,[si+vk_appendlen]
+		mov byte [bx+si+vk_append],0	; make it zero terminated
+		call unmangle_name
+		pop ds
+		pop si
+		pop di
+		add di,13
+		inc si
+		cmp si,[menu_desc+menu_entries]
+		jb gfx_setup_menu_20
+
+		mov si,menu_desc
+
+		mov word [si+menu_default],gfx_menu_def
+		mov [si+menu_default+2],ds
+
+		mov word [si+menu_ent_list],gfx_menu_entry
+		mov [si+menu_ent_list+2],ds
+		mov word [si+menu_ent_size],13
+
+		mov word [si+menu_arg_list],vk_append
+		mov word [si+menu_arg_list+2],vk_seg
+		mov word [si+menu_arg_size],vk_size
+
+		push ds
+		pop es
+
+		call gfx_get_sysconfig
+		call far [gfx_bc_menu_init]
+
+gfx_setup_menu_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_infobox:
+		pushad
+		cmp byte [gfx_ok],0
+		jz gfx_infobox_90
+		call far [gfx_bc_infobox_init]
+		xor di,di
+		xor ax,ax
+		call far [gfx_bc_input]
+		call far [gfx_bc_infobox_done]
+gfx_infobox_90:
+		popad
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_progress_init:
+		pushad
+		cmp byte [gfx_ok],0
+		jz gfx_progress_init_90
+		movzx eax,ax
+		call far [gfx_bc_progress_init]
+gfx_progress_init_90:
+		popad
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_progress_done:
+		pushad
+		cmp byte [gfx_ok],0
+		jz gfx_progress_done_90
+		call far [gfx_bc_progress_done]
+gfx_progress_done_90:
+		popad
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_progress_update:
+		pushad
+		cmp byte [gfx_ok],0
+		jz gfx_progress_update_90
+		movzx eax,cx
+		call far [gfx_bc_progress_update]
+gfx_progress_update_90:
+		popad
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_progress_limit:
+		pushad
+		cmp byte [gfx_ok],0
+		jz gfx_progress_limit_90
+		movzx eax,ax
+		movzx edx,dx
+		call far [gfx_bc_progress_limit]
+gfx_progress_limit_90:
+		popad
+		ret
+
+
+%if 0
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_password:
+		pushad
+		cmp byte [gfx_ok],0
+		stc
+		jz gfx_password_90
+		call far [gfx_bc_password_init]
+		mov di,gfx_password_buf
+		mov cx,32
+		xor ax,ax
+		call far [gfx_bc_input]
+		mov si,gfx_password_buf
+		call far [gfx_bc_password_done]
+		jnc gfx_password_90
+		mov si,gfx_msg_wrong_password
+		xor di,di
+		mov al,0
+		call far [gfx_bc_infobox_init]
+		xor di,di
+		xor ax,ax
+		call far [gfx_bc_input]
+		call far [gfx_bc_infobox_done]
+		stc
+gfx_password_90:
+                popad
+                ret
+%endif
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Read graphics data and store them at [gfx_mem].
+;
+;  dx:ax	file length
+;  si		start cluster
+;
+;  return:	[gfx_ok] = 0/1
+;
+gfx_read_file:
+		push es
+		mov byte [gfx_ok],0
+		mov edi,[gfx_mem]
+		push dx                         ; DX:AX = length of file
+                push ax
+		pop edx
+		mov eax,[gfx_mem_free]
+		lea eax,[eax+edx+0fh]		; add space for alignment
+		cmp eax,[gfx_mem_max]		; max. length
+		ja near gfx_read_file_90
+		mov [gfx_mem_free],eax
+
+gfx_read_file_10:
+		mov bx,trackbuf
+		mov cx,[BufSafe]
+		push edi
+		push edx
+		call getfssec
+		pop edx
+		pop edi
+		movzx ecx,word [BufSafeBytes]
+		cmp edx,ecx
+		jae gfx_read_file_20
+		mov ecx,edx
+gfx_read_file_20:
+		push ecx
+		push edi
+		push si				; Save current cluster
+		push es
+		mov si,trackbuf
+		push edi
+		call gfx_l2so
+		pop di
+		pop es
+		rep movsb
+		pop es
+		pop si
+		pop edi
+		pop ecx
+		add edi,ecx
+		sub edx,ecx
+		ja gfx_read_file_10
+
+		call find_file
+		or eax,eax
+		jz gfx_read_file_90
+		push edi
+		push eax
+		add eax,edi
+		call align_it
+		pop eax
+		pop edi
+		sub edi,[gfx_mem]
+		add edi,[gfx_mem_align]
+		mov [gfx_mem_file],edi
+		add eax,edi
+		shr eax,4
+		mov [gfx_bc_jt+2],ax
+
+		mov byte [gfx_ok],1
+
+gfx_read_file_90:
+		pop es
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; locate graphics file
+;
+; return:	eax: code offset (0 -> no file found)
+; 		edi: gfx file start
+;
+find_file:
+		mov edi,[gfx_mem]
+		lin2segofs edi,es,bx
+		call magic_ok
+		or eax,eax
+		jnz find_file_90
+
+		; ok, maybe it's a cpio archive
+
+		; note: edi must be properly aligned (2)!
+
+find_file_20:
+		mov ecx,[gfx_mem_free]
+		sub ecx,26 + 12			; min cpio header + gfx header
+		cmp edi,ecx
+		jae find_file_90
+
+		lin2segofs edi,es,bx
+		cmp word [es:bx],71c7h
+		jnz find_file_90		; no cpio record
+
+		movzx esi,word [es:bx+20]	; file name size
+
+		inc si
+		and si,~1			; align
+
+		mov ecx,[es:bx+22]		; data size
+		rol ecx,16			; get word order right
+
+		inc ecx
+		and ecx,byte ~1			; align
+
+		add si,26			; skip header
+
+		add edi,esi
+		add bx,si
+		call magic_ok
+		or eax,eax
+		jnz find_file_90
+
+		add edi,ecx
+		jmp find_file_20
+
+find_file_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+;  es:bx	file start
+;
+;  return:	eax:	offset to code entry
+;
+; Notes:
+;  - changes no regs except eax
+;
+magic_ok:
+		xor eax,eax
+		cmp dword [es:bx],0b2d97f00h	; header.magic_id
+		jnz magic_ok_90
+		cmp byte [es:bx+4],5		; header.version
+		jnz magic_ok_90
+		mov eax,[es:bx+8]
+magic_ok_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+;  eax		address to be aligned
+;
+align_it:
+		push dword [gfx_mem]
+		pop dword [gfx_mem_align]
+		neg al
+		and eax,byte 0fh
+		jz align_it_90
+		add [gfx_mem_align],eax
+		mov esi,[gfx_mem]
+		mov ebx,[gfx_mem_free]
+		sub ebx,esi
+		sub ebx,byte 0fh
+		add esi,ebx
+		dec esi
+
+		std
+
+align_it_30:
+		or ebx,ebx
+		jz align_it_60
+		mov ecx,ebx
+		cmp ebx,8000h
+		jb align_it_40
+		mov ecx,8000h
+align_it_40:
+		push esi
+		sub ebx,ecx
+		sub [esp],ecx
+		push esi
+		call gfx_l2so
+		pop si
+		add si,8000h
+		sub word [esp],(8000h >> 4)
+		pop es
+		mov di,si
+		add di,ax
+		es rep movsb
+		pop esi
+		jmp align_it_30
+align_it_60:
+
+		cld
+
+align_it_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Convert 32bit linear address to seg:ofs.
+;
+;  dword [esp + 2]:	linear address
+;
+; return:
+;  dword [esp + 2]:	seg:ofs
+;
+; Notes:
+;  - changes no regs
+;
+gfx_l2so:
+		push eax
+		mov eax,[esp + 6]
+		shr eax,4
+		mov [esp + 8],ax
+		and word [esp + 6],byte 0fh
+		pop eax
+		ret
+
--- isolinux.asm
+++ isolinux.asm
@@ -20,6 +20,10 @@
 ; ****************************************************************************
 
 %define IS_ISOLINUX 1
+
+%define WITH_GFX 1
+; %define DEBUG_DISKIO
+
 %include "macros.inc"
 %include "config.inc"
 %include "kernel.inc"
@@ -58,9 +62,9 @@
 ;
 ; Note: this structure can be added to, but it must 
 ;
-%define vk_power	6		; log2(max number of vkernels)
+%define vk_power	5		; log2(max number of vkernels)
 %define	max_vk		(1 << vk_power)	; Maximum number of vkernels
-%define vk_shift	(16-vk_power)	; Number of bits to shift
+%define vk_shift	(15-vk_power)	; Number of bits to shift
 %define vk_size		(1 << vk_shift)	; Size of a vkernel buffer
 
 		struc vkernel
@@ -74,7 +78,7 @@
 		endstruc
 
 %ifndef DEPEND
-%if (vk_end > vk_size) || (vk_size*max_vk > 65536)
+%if (vk_end > vk_size) || (vk_size*max_vk > 8000h)
 %error "Too many vkernels defined, reduce vk_power"
 %endif
 %endif
@@ -83,9 +87,9 @@
 ; Segment assignments in the bottom 640K
 ; 0000h - main code/data segment (and BIOS segment)
 ;
-real_mode_seg	equ 3000h
-vk_seg          equ 2000h		; Virtual kernels
-xfer_buf_seg	equ 1000h		; Bounce buffer for I/O to high mem
+real_mode_seg	equ 7000h
+vk_seg          equ 6800h		; Virtual kernels
+xfer_buf_seg	equ 8000h		; Bounce buffer for I/O to high mem
 comboot_seg	equ real_mode_seg	; COMBOOT image loading zone
 
 ;
@@ -221,9 +225,21 @@
 		alignb 4
 default_cmd	resb max_cmd_len+1	; "default" command line
 
+InitRDClust	resw 1			; Initrd size in clusters
+InitRDSize	resd 1			; Initrd size in bytes
+Splashat	resd 1			; Load address (linear) for splash
+SplashClust	resw 1			; Splash size in clusters
+SplashName	resb FILENAME_MAX	; Mangled Splash image name
+SplashCName	resb FILENAME_MAX	; Unmangled Splash image name
+
 		alignb open_file_t_size
 Files		resb MAX_OPEN*open_file_t_size
 
+vbe_buf		resb 200h		; VBE2 buffer
+ddc_buf		resb 80h		; for DDC info
+mi_buf		resb 200h		; VBE mode info & disk buffer
+mi_list		resb 100h		; VBE mode list
+
 		section .text
                 org 7C00h
 ;;
@@ -290,6 +306,21 @@
 		mov [ImageSectors],ax		; boot file sectors
 
 		mov [DriveNo],dl
+
+		; check whether the BIOS did load us correctly
+		cmp dl,80h			; some BIOSes try to do floppy emulation...
+		jb bios_err
+		cmp dword [FirstSecSum], byte 0
+		jz bios_ok
+bios_err:
+		mov si,broken_bios_msg
+		call writemsg
+		jmp short $
+broken_bios_msg	db 13, 10, 'Cannot boot from this CD. Please use CD2 or try a BIOS update.', 13, 10, 0
+		align 4
+csum_value	dd 0
+bios_ok:
+
 %ifdef DEBUG_MESSAGES
 		mov si,startup_msg
 		call writemsg
@@ -298,6 +329,9 @@
 		call crlf
 %endif
 
+%if 0
+		; Some BIOSes don't like that call.
+
 		; Now figure out what we're actually doing
 		; Note: use passed-in DL value rather than 7Fh because
 		; at least some BIOSes will get the wrong value otherwise
@@ -318,6 +352,8 @@
 		call crlf
 %endif
 
+%endif
+
 found_drive:
 		; Some BIOSes apparently have limitations on the size 
 		; that may be loaded (despite the El Torito spec being very
@@ -390,6 +426,9 @@
 %endif
 		jmp all_read			; Jump to main code
 
+%if 0
+		; doesn't work anyway, see above
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Start of BrokenAwardHack --- 10-nov-2002           Knut_Petersen@t-online.de
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -571,6 +610,7 @@
 		call writehex2
 		call crlf
 		jmp .found_drive		; Pray that this works...
+%endif
 
 fatal_error:
 		mov si,nothing_msg
@@ -630,10 +670,17 @@
 ;
 getlinsec:
 		mov si,dapa			; Load up the DAPA
-		mov [si+4],bx
-		mov bx,es
-		mov [si+6],bx
 		mov [si+8],eax
+		; seems that some BIOSes have problems if the target
+		; segment is 0 (don't ask); to avoid this, we normalize
+		; the buffer address here
+		; -> seen on Acer TravelMate C102Ti
+		mov [si+4],bx
+		and word [si+4],0fh
+		mov ax,es
+		shr bx,4
+		add ax,bx
+		mov [si+6],ax
 .loop:
 		push bp				; Sectors left
 		cmp bp,[MaxTransfer]
@@ -660,14 +707,72 @@
 		; INT 13h with retry
 xint13:		mov byte [RetryCount],retry_count
 .try:		pushad
+%ifdef DEBUG_DISKIO
+		pushad
+		mov cx,16
+.zap:
+		lodsb
+		call writehex2
+		mov al,' '
+		call writechr
+		loop .zap
+		mov ah,0
+		int 16h
+		popad
+%endif
+		; seen buggy bios that overwrites buffer address on error...
+		push dword [dapa + 4]
 		int 13h
+		pop dword [dapa + 4]
+%ifdef DEBUG_DISKIO   
+		pushad
+		pushf
+		push ax
+		mov al,':'
+		call writechr
+		mov al,' '
+		call writechr
+		pop ax
+		sbb al,al
+		call writehex4
+		call crlf
+		mov ah,0
+		int 16h
+		popf
+		popad
+%endif
 		jc .error
+.noerror:
 		add sp,byte 8*4			; Clean up stack
 		ret
 .error:
+		or ah,ah
+		jz .noerror
 		mov [DiskError],ah		; Save error code
 		popad
 		mov [DiskSys],ax		; Save system call number
+
+		test byte [gfx_user_note],1
+		jz .noeject
+		cmp byte [RetryCount],4
+		ja .noeject
+		cmp byte [DiskError],0aah	; drive not ready
+		jnz .noeject
+		; might have been cdrom eject, wait a bit
+		cmp byte [gfx_ok],0
+		jz .noeject
+		push si
+		push di
+		push ax
+		mov si,err_not_ready
+		xor di,di
+		mov al,0
+		call gfx_infobox
+		pop ax
+		pop di
+		pop si
+.noeject:
+
 		dec byte [RetryCount]
 		jz .real_error
 		push ax
@@ -716,6 +821,17 @@
 		mov fs,ax
 		mov gs,ax
 		sti
+
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		mov si,err_failed_gfx
+		xor di,di
+		mov al,1
+		call gfx_infobox
+		call gfx_done
+		call do_reboot
+.nogfx:
+
 		mov si,err_bootfailed
 		call cwritestr
 		call getchar
@@ -765,6 +881,9 @@
 crlf_msg	db CR, LF
 null_msg	db 0
 
+err_failed_gfx	db 'Error reading boot CD.', 0
+err_not_ready	db 'CDROM drive not ready.', 0
+
 ;
 ; El Torito spec packet
 ;
@@ -912,12 +1031,21 @@
 		inc al
 		loop mkkeymap
 
+		test byte [KbdFlags],3
+		jpe .nogfx			; left xor right shift: skip BIOS calls/no gfx
+		mov byte [do_nogfx],1
+		mov byte [no_fkeys],1		; no special F-key processing
+.nogfx:
+
 ;
 ; Now, we need to sniff out the actual filesystem data structures.
 ; mkisofs gave us a pointer to the primary volume descriptor
 ; (which will be at 16 only for a single-session disk!); from the PVD
 ; we should be able to find the rest of what we need to know.
 ; 
+		call get_fs_structures
+		jmp get_fs_struct_done
+
 get_fs_structures:
 		mov eax,[bi_pvd]
 		mov bx,trackbuf
@@ -967,6 +1095,9 @@
 		call crlf
 %endif
 .no_isolinux_dir:
+		ret
+
+get_fs_struct_done:
 
 ;
 ; Locate the configuration file
@@ -1562,6 +1693,10 @@
 %include "strcpy.inc"		; strcpy()
 %include "rawcon.inc"		; Console I/O w/o using the console functions
 
+%include "suse.inc"		; most of the new stuff is in suse.inc
+%include "gfxlogo.inc"		; add gfx things
+
+
 ; -----------------------------------------------------------------------------
 ;  Begin data section
 ; -----------------------------------------------------------------------------
@@ -1581,7 +1716,8 @@
 		db 'booting, and I will take your word for it.', CR, LF, 0
 err_badcfg      db 'Unknown keyword in config file.', CR, LF, 0
 err_noparm      db 'Missing parameter in config file.', CR, LF, 0
-err_noinitrd    db CR, LF, 'Could not find ramdisk image: ', 0
+err_noinitrd    db CR, LF
+err_noinitrda	db 'Could not find ramdisk image: ', 0
 err_nohighmem   db 'Not enough memory to load specified kernel.', CR, LF, 0
 err_highload    db CR, LF, 'Kernel transfer failure.', CR, LF, 0
 err_oldkernel   db 'Cannot load a ramdisk with an old kernel image.'
@@ -1606,6 +1742,7 @@
 default_len	equ ($-default_str)
 boot_dir	db '/boot'			; /boot/isolinux
 isolinux_dir	db '/isolinux', 0
+		zb 64
 ConfigName	equ $
 isolinux_cfg	db 'isolinux.cfg', 0
 err_disk_image	db 'Cannot load disk image (invalid file)?', CR, LF, 0
@@ -1672,7 +1809,6 @@
 OnerrorLen	dw 0			; Bytes in onerror command
 KbdTimeOut      dw 0                    ; Keyboard timeout (if any)
 CmdLinePtr	dw cmd_line_here	; Command line advancing pointer
-initrd_flag	equ $
 initrd_ptr	dw 0			; Initial ramdisk pointer/flag
 VKernelCtr	dw 0			; Number of registered vkernels
 ForcePrompt	dw 0			; Force prompt
@@ -1719,6 +1855,8 @@
 end_of_code	equ (ldlinux_end-bootsec)+7C00h
 getcbuf		equ (end_of_code + 511) & 0FE00h
 
+;		dd getcbuf + trackbufsize
+
 ; VGA font buffer at the end of memory (so loading a font works even
 ; in graphics mode.)
 vgafontbuf	equ 0E000h
--- keywords
+++ keywords
@@ -29,3 +29,10 @@
 f10
 f11
 f12
+initrdsize
+readinfo
+framebuffer
+verbose
+gfxboot
+notice
+disksize
--- keywords.inc
+++ keywords.inc
@@ -77,6 +77,17 @@
 %if IS_PXELINUX || IS_ISOLINUX
 		keyword localboot, pc_localboot
 %endif
+%ifdef WITH_GFX
+		keyword initrdsize,  pc_setint16, ExpInitRDClust
+		keyword readinfo,    pc_setint16, ReadInfo
+		keyword framebuffer, pc_setint16, FrameBuffer
+		keyword verbose,     pc_setint16, do_write_msg
+		keyword gfxboot,     pc_filecmd,  get_gfx_file
+		keyword notice,      pc_setint16, gfx_user_note
+%if IS_SYSLINUX
+		keyword disksize,    pc_disksize, DiskSize
+%endif
+%endif
 
 keywd_count	equ ($-keywd_table)/keywd_size
 
--- ldlinux.asm
+++ ldlinux.asm
@@ -29,6 +29,9 @@
 %ifndef IS_MDSLINUX
 %define IS_SYSLINUX 1
 %endif
+
+%define WITH_GFX 1
+
 %include "macros.inc"
 %include "config.inc"
 %include "kernel.inc"
@@ -63,9 +66,9 @@
 ;
 ; Note: this structure can be added to, but it must 
 ;
-%define vk_power	7		; log2(max number of vkernels)
+%define vk_power	6		; log2(max number of vkernels)
 %define	max_vk		(1 << vk_power)	; Maximum number of vkernels
-%define vk_shift	(16-vk_power)	; Number of bits to shift
+%define vk_shift	(15-vk_power)	; Number of bits to shift
 %define vk_size		(1 << vk_shift)	; Size of a vkernel buffer
 
 		struc vkernel
@@ -79,7 +82,7 @@
 		endstruc
 
 %ifndef DEPEND
-%if (vk_end > vk_size) || (vk_size*max_vk > 65536)
+%if (vk_end > vk_size) || (vk_size*max_vk > 8000h)
 %error "Too many vkernels defined, reduce vk_power"
 %endif
 %endif
@@ -91,10 +94,10 @@
 ;
 ; 0000h - main code/data segment (and BIOS segment)
 ;
-real_mode_seg	equ 5000h
-fat_seg		equ 3000h		; 128K area for FAT (2x64K)
-vk_seg          equ 2000h		; Virtual kernels
-xfer_buf_seg	equ 1000h		; Bounce buffer for I/O to high mem
+real_mode_seg	equ 7000h
+fat_seg		equ 4800h		; up to 128K area for FAT (2x64K)
+vk_seg          equ 6800h		; Virtual kernels
+xfer_buf_seg	equ 8000h		; Bounce buffer for I/O to high mem
 comboot_seg	equ real_mode_seg	; COMBOOT image loading zone
 
 ; ---------------------------------------------------------------------------
@@ -110,6 +113,9 @@
 ;		trackbuf ends at 5000h
 
 
+; VGA font buffer
+vgafontbuf	equ 5000h
+
 ;
 ; Constants for the xfer_buf_seg
 ;
@@ -122,7 +128,7 @@
 xbs_vgatmpbuf	equ 2*trackbufsize
 
 
-                absolute 5000h          ; Here we keep our BSS stuff
+                absolute 7000h          ; Here we keep our BSS stuff
 VKernelBuf:	resb vk_size		; "Current" vkernel
 		alignb 4
 AppendBuf       resb max_cmd_len+1	; append=
@@ -219,6 +225,15 @@
 		alignb 4
 default_cmd	resb max_cmd_len+1	; "default" command line
 
+InitRDClust	resw 1			; Initrd size in clusters
+InitRDSize	resd 1			; Initrd size in bytes
+Splashat	resd 1			; Load address (linear) for splash
+SplashClust	resw 1			; Splash size in clusters
+SplashName	resb 11			; Mangled Splash image name
+SplashCName	resb 13			; Unmangled Splash image name
+FATSegment	resb 2			; FAT segment
+
+
 		section .text
                 org 7C00h
 ;
@@ -712,6 +727,7 @@
 ; We can really only rely on a single sector having been loaded.  Hence
 ; we should load the FAT into RAM and start chasing pointers...
 ;
+
 		xor ax,ax
 		cwd
 		inc dx				; DX:AX <- 64K
@@ -719,13 +735,26 @@
 		mov si,ax
 
 		push es
-		mov bx,fat_seg			; Load into fat_seg:0000
-		mov es,bx
 		
 		mov eax,[bsHidden]		; Hidden sectors
 		add edx,[bxResSectors]
 		add eax,edx
 		mov ecx,[bxFATsecs]		; Sectors/FAT
+
+		mov bx,fat_seg			; Load into fat_seg:0000
+
+		; calculate start of fat buffer segment
+		cmp ch,1			; oops, > 128k?
+		jae update_fat_50
+		mov bx,cx
+		shl bx,5
+		neg bx
+		add bx,fat_seg + 2000h
+update_fat_50:
+
+		mov [FATSegment],bx
+		mov es,bx
+
 fat_load_loop:	
 		mov ebp,ecx			; Make sure high EBP = 0
 		cmp bp,si
@@ -869,7 +898,7 @@
 		mov bp,si			; Remaining sector count
 		jmp short .getchunk
 .lastchunk:	pop eax
-		call getlinsec
+		call getlinsec2
 		pop cx
 		pop si
 		popf
@@ -881,10 +910,13 @@
 ; getlinsecsr: save registers, call getlinsec, restore registers
 ;
 getlinsecsr:	pushad
-		call getlinsec
+		call getlinsec2
 		popad
 		ret
 
+getlinsec2:
+		jmp near getlinsec
+
 ;
 ; nextcluster: Advance a cluster pointer in SI to the next cluster
 ;	       pointed at in the FAT tables.  CF=0 on return if end of file.
@@ -895,7 +927,7 @@
 nextcluster_fat12:
 		push bx
 		push ds
-		mov bx,fat_seg
+		mov bx,[FATSegment]
 		mov ds,bx
 		mov bx,si			; Multiply by 3/2
 		shr bx,1			; CF now set if odd
@@ -916,10 +948,11 @@
 nextcluster_fat16:
 		push ax
 		push ds
-		mov ax,fat_seg
+		mov ax,[FATSegment]
 		shl si,1
 		jnc .seg0
-		mov ax,fat_seg+1000h
+		mov ax,[FATSegment]
+		add ax,1000h
 .seg0:		mov ds,ax
 		mov si,[si]
 		cmp si,0FFF0h
@@ -1054,6 +1087,12 @@
 		inc al
 		loop mkkeymap
 
+		test byte [KbdFlags],3
+		jpe .no_gfx			; left xor right shift: skip BIOS calls/no gfx
+		mov byte [do_nogfx],1
+		mov byte [no_fkeys],1		; no special F-key processing
+.no_gfx:
+
 ;
 ; Load configuration file
 ;
@@ -1088,6 +1127,10 @@
 ; abort_check: let the user abort with <ESC> or <Ctrl-C>
 ;
 abort_check:
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		ret
+.nogfx:
 		call pollchar
 		jz ac_ret1
 		pusha
@@ -1173,7 +1216,7 @@
 		mov [EndofDirSec],ax	; End of loaded
 		pop eax
 		mov bx,trackbuf
-		call getlinsecsr
+		call dir_cache
 		mov si,trackbuf
 dir_test_name:	cmp byte [si],0		; Directory high water mark
 		je dir_return		; Failed
@@ -1203,6 +1246,63 @@
 		pop bp
 		ret
 
+; like getlinsecsr, but read from cache, if possible
+dir_cache:
+		cmp byte [UserFont],0
+		jz dir_cache_20
+		jmp getlinsecsr		; cache is shared with vgafontbuf
+dir_cache_20:
+		cmp eax,[DirCacheStart]
+		jnz dir_cache_50
+		cmp bp,[DirCacheSectors]
+		jnz dir_cache_50
+		or bp,bp
+		jz dir_cache_50
+
+		pusha
+		mov di,bx
+		mov si,vgafontbuf
+		mov ax,[bsBytesPerSec]
+		mul bp
+		xchg ax,cx
+		rep movsb
+		popa
+
+		ret
+dir_cache_50:
+		call getlinsecsr
+
+		pusha
+		xchg ax,cx
+		mov ax,[bsBytesPerSec]
+		mul bp
+		xchg ax,cx
+		or cx,cx
+		jz dir_cache_80
+		cmp cx,1000h		; smaller than vgafontbuf and trackbuf
+		ja dir_cache_80
+
+		mov [DirCacheStart],eax
+		mov [DirCacheSectors],bp
+		
+		mov di,vgafontbuf
+		mov si,bx
+		push ds
+		push es
+
+		push es
+		push ds
+		pop es
+		pop ds
+		rep movsb
+
+		pop es
+		pop ds
+dir_cache_80:
+		popa
+
+		ret
+
 ;
 ; writechr:	Write a single character in AL to the console without
 ;		mangling any registers; handle video pages correctly.
@@ -1225,6 +1325,15 @@
 ;	   starting with "kaboom.patch" with this part
 
 kaboom2:
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		mov si,err_failed_gfx
+		xor di,di
+		mov al,1
+		call gfx_infobox
+		call gfx_done
+		call do_reboot
+.nogfx:
 		mov si,err_bootfailed
 		call cwritestr
 		call getchar
@@ -1358,6 +1467,9 @@
 %include "highmem.inc"		; High memory sizing
 %include "strcpy.inc"           ; strcpy()
 
+%include "suse.inc"		; most of the new stuff is in suse.inc
+%include "gfxlogo.inc"		; add gfx things
+
 ; -----------------------------------------------------------------------------
 ;  Begin data section
 ; -----------------------------------------------------------------------------
@@ -1389,7 +1501,8 @@
 		db 'booting, and I will take your word for it.', CR, LF, 0
 err_badcfg      db 'Unknown keyword in syslinux.cfg.', CR, LF, 0
 err_noparm      db 'Missing parameter in syslinux.cfg.', CR, LF, 0
-err_noinitrd    db CR, LF, 'Could not find ramdisk image: ', 0
+err_noinitrd    db CR, LF
+err_noinitrda   db 'Could not find ramdisk image: ', 0
 err_nohighmem   db 'Not enough memory to load specified kernel.', CR, LF, 0
 err_highload    db CR, LF, 'Kernel transfer failure.', CR, LF, 0
 err_oldkernel   db 'Cannot load a ramdisk with an old kernel image.'
@@ -1399,6 +1512,7 @@
 err_a20		db CR, LF, 'A20 gate not responding!', CR, LF, 0
 err_bootfailed	db CR, LF, 'Boot failed: please change disks and press '
 		db 'a key to continue.', CR, LF, 0
+err_failed_gfx	db 'Error reading from disk.', 0
 ready_msg	db 'Ready.', CR, LF, 0
 crlfloading_msg	db CR, LF
 loading_msg     db 'Loading ', 0
@@ -1447,7 +1561,6 @@
 OnerrorLen	dw 0			; Bytes in onerror command
 KbdTimeOut      dw 0                    ; Keyboard timeout (if any)
 CmdLinePtr	dw cmd_line_here	; Command line advancing pointer
-initrd_flag	equ $
 initrd_ptr	dw 0			; Initial ramdisk pointer/flag
 VKernelCtr	dw 0			; Number of registered vkernels
 ForcePrompt	dw 0			; Force prompt
@@ -1457,6 +1570,9 @@
 VGAFontSize	dw 16			; Defaults to 16 byte font
 UserFont	db 0			; Using a user-specified font
 ScrollAttribute	db 07h			; White on black (for text mode)
+DirCacheStart	dd 0			; first cached dir sector
+DirCacheSectors	dw 0			; cached sectors
+
 ;
 ; Stuff for the command line; we do some trickery here with equ to avoid
 ; tons of zeros appended to our file and wasting space
@@ -1473,13 +1589,15 @@
 end_of_code	equ (ldlinux_end-bootsec)+7C00h
 getcbuf		equ (end_of_code + 511) & 0FE00h
 
-; VGA font buffer at the end of memory (so loading a font works even
-; in graphics mode.)
-vgafontbuf	equ 0E000h
+		absolute getcbuf + trackbufsize
+vbe_buf		resb 200h		; VBE2 buffer
+ddc_buf		resb 80h		; for DDC info
+mi_buf		resb 200h		; VBE mode info & disk buffer
+mi_list		resb 100h		; VBE mode list
 
 ; This is a compile-time assert that we didn't run out of space
 %ifndef DEPEND
-%if (getcbuf+trackbufsize) > vgafontbuf
+%if getcbuf < 7c00h || $ > 10000h
 %error "Out of memory, better reorganize something..."
 %endif
 %endif
--- loadhigh.inc
+++ loadhigh.inc
@@ -43,10 +43,21 @@
 .read_loop:
 		and si,si			; If SI == 0 then we have end of file
 		jz .eof
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jnz .isgfx
+%endif
+
 		push si
 		mov si,dot_msg
 		call cwritestr
 		pop si
+
+%ifdef WITH_GFX
+.isgfx:
+%endif
+
 		call abort_check
 
 		push eax			; <A> Total bytes to transfer
@@ -65,6 +76,14 @@
 		push edi			; <C> Target buffer
 		mov cx,ax
 		xor bx,bx			; ES:0
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		call gfx_progress_update
+.nogfx:
+%endif
+
 		call getfssec			; Load the data into xfer_buf_seg
 		pop edi				; <C> Target buffer
 		pop ecx				; <B> Byte count this round
--- Makefile
+++ Makefile
@@ -18,7 +18,7 @@
 OSTYPE   = $(shell uname -msr)
 CC	 = gcc
 INCLUDE  =
-CFLAGS   = -W -Wall -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
+CFLAGS   = -W -Wall -O2 -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
 PIC      = -fPIC
 LDFLAGS  = -O2 -s
 AR	 = ar
@@ -26,7 +26,7 @@
 
 NASM	 = nasm -O99
 NINCLUDE = 
-BINDIR   = /usr/bin
+BINDIR   = /usr/sbin
 LIBDIR   = /usr/lib
 AUXDIR   = $(LIBDIR)/syslinux
 INCDIR   = /usr/include
@@ -55,7 +55,7 @@
 # mingw suite installed
 BTARGET = kwdhash.gen version.gen ldlinux.bss ldlinux.sys ldlinux.bin \
 	  pxelinux.0 mbr.bin isolinux.bin isolinux-debug.bin \
-	  libsyslinux.a syslinux.exe $(LIB_SO) 
+	  libsyslinux.a $(LIB_SO) 
 ITARGET = syslinux.com syslinux syslinux-nomtools copybs.com gethostip \
 	  mkdiskimage
 DOCS    = COPYING NEWS README TODO BUGS *.doc sample menu com32
@@ -68,7 +68,7 @@
 INSTALL_BIN   =	syslinux gethostip ppmtolss16 lss16toppm
 # Things to install in /usr/lib/syslinux
 INSTALL_AUX   =	pxelinux.0 isolinux.bin isolinux-debug.bin \
-		syslinux.com syslinux.exe copybs.com memdisk/memdisk
+		syslinux.com copybs.com memdisk/memdisk
 # Things to install in /usr/lib
 INSTALL_LIB   = $(LIB_SO) libsyslinux.a
 # Things to install in /usr/include
@@ -104,7 +104,7 @@
 kwdhash.gen: keywords genhash.pl
 	$(PERL) genhash.pl < keywords > kwdhash.gen
 
-ldlinux.bin: ldlinux.asm kwdhash.gen version.gen
+ldlinux.bin: ldlinux.asm kwdhash.gen version.gen suse.inc gfxlogo.inc
 	$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
 		-l ldlinux.lst -o ldlinux.bin ldlinux.asm
 
@@ -112,17 +112,19 @@
 	$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
 		-l pxelinux.lst -o pxelinux.bin pxelinux.asm
 
-isolinux.bin: isolinux.asm kwdhash.gen version.gen
+isolinux.bin: isolinux.asm kwdhash.gen version.gen suse.inc gfxlogo.inc
 	$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
 		-l isolinux.lst -o isolinux.bin isolinux.asm
+	./add_crc $@
 
 pxelinux.0: pxelinux.bin
 	cp pxelinux.bin pxelinux.0
 
 # Special verbose version of isolinux.bin
-isolinux-debug.bin: isolinux-debug.asm kwdhash.gen
+isolinux-debug.bin: isolinux-debug.asm kwdhash.gen suse.inc gfxlogo.inc
 	$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
 		-l isolinux-debug.lst -o isolinux-debug.bin isolinux-debug.asm
+	./add_crc $@
 
 ldlinux.bss: ldlinux.bin
 	dd if=ldlinux.bin of=ldlinux.bss bs=512 count=1
@@ -212,7 +214,7 @@
 
 dist: tidy
 	for dir in . sample memdisk ; do \
-		( cd $$dir && rm -f *~ \#* core ) ; \
+		( cd $$dir && rm -f *~ \#* core *.lst ) ; \
 	done
 
 local-spotless:
--- memdisk/init.S16
+++ memdisk/init.S16
@@ -42,7 +42,7 @@
 _start:
 		jmp	start
 
- # This is the setup header, and it must start at %cs:2 (old 0x9020:2)
+/* This is the setup header, and it must start at %cs:2 (old 0x9020:2) */
 	
 		.ascii	"HdrS"		# header signature
 		.word	0x0203		# header version number (>= 0x0105)
@@ -57,7 +57,7 @@
 					# See Documentation/i386/boot.txt for
 					# assigned ids
 	
- # flags, unused bits must be zero (RFU) bit within loadflags
+/* flags, unused bits must be zero (RFU) bit within loadflags */
 loadflags:
 LOADED_HIGH	= 1			# If set, the kernel is loaded high
 CAN_USE_HEAP	= 0x80			# If set, the loader also has set
--- memdisk/Makefile
+++ memdisk/Makefile
@@ -20,7 +20,7 @@
 ALIGN   := $(call gcc_ok,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0)
 
 CC       = gcc $(M32)
-CFLAGS   = -g -W -Wall -Os -fomit-frame-pointer -march=i386 $(ALIGN) \
+CFLAGS   = -g -W -Wall -O2 -fomit-frame-pointer -march=i386 $(ALIGN) \
 	   -DVERSION='"$(VERSION)"' -DDATE='"$(DATE)"'
 LDFLAGS  = -g
 INCLUDE  = -I../com32/include
--- parseconfig.inc
+++ parseconfig.inc
@@ -266,6 +266,20 @@
 ;
 pc_comment	equ pc_getline			; Get a line and discard
 
+%if IS_SYSLINUX
+;
+; like pc_setint16, but patch sector read funtion, too
+;
+pc_disksize:
+		push ax
+		call getint
+		pop si
+		jc .err
+		mov [si],bx
+		mov word [getlinsec2 + 1], getlinsec3 - getlinsec2 - 3
+.err:		ret
+%endif
+
 ;
 ; Common subroutine: load line into trackbuf; returns with SI -> trackbuf
 ;
--- README.SuSE
+++ README.SuSE
@@ -0,0 +1,50 @@
+syslinux/isolinux support a graphical boot screen using VESA BIOS
+extensions. (Note that this is different from the graphics support that
+syslinux comes with which uses a 640x480, 16 colors VGA mode).
+
+To use it you have to prepare a special boot logo file and put a line like
+this into syslinux.cfg/iso.linux.cfg:
+
+  gfxboot bootscreen
+
+The tools to create 'bootscreen' from the above example are in the
+gfxboot package. Please _do_ have a look at its documentation before
+you begin.
+
+Note that you cannot use comboot images and graphics at the same time as the
+memory used for the picture overlaps the comboot loading area.
+
+
+Before starting the Linux kernel syslinux will get some info from the BIOS.
+To control this, there are some new options in syslinux.cfg:
+
+  - readinfo
+
+    "readinfo 1" enables the above feature; the default is 0
+    "readinfo 2" enables even features
+
+  - framebuffer
+
+    "framebuffer 1" will get a video mode list from the VESA
+    BIOS and select an appropriate video mode for the linux kernel
+
+  - verbose
+
+    "verbose 1" enables some debug messages
+
+You can have a boot disk with a file system that spans several disks.
+syslinux will ask you for disk changes if necessary. To enable this feature,
+use
+
+  - disksize <size_of_single_disk_in_sectors>
+
+Note that every individual disk must have at least a valid FAT boot sector.
+syslinux will use the serial number stored there to verify that the correct
+disk has been inserted (its last hex digit is the zero based disk number).
+
+
+To make room for the graphics the maximum number of menu entries had to be
+reduced. syslinux can have 64, isolinux 32 entries (used to be 128 and 64
+resp.). If you need more you can apply more-menu-entries.dif (included in
+the syslinux source rpm) and get the original number back.
+
--- runkernel.inc
+++ runkernel.inc
@@ -52,8 +52,20 @@
 kernel_sane:	push ax
 		push dx
 		push si
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jnz .isgfx
+		call hide_vmode
+%endif
+
 		mov si,loading_msg
                 call cwritestr
+
+%ifdef WITH_GFX
+.isgfx:
+%endif
+
 ;
 ; Now start transferring the kernel
 ;
@@ -116,6 +128,56 @@
                 mov si,KernelCName       	; Unmangled kernel name
                 mov cx,[KernelCNameLen]
                 rep movsb
+
+%ifdef WITH_GFX
+;
+; Insert special linuxrc data here
+;
+		cmp byte [lxrc_data1],0
+		jz .nosusedata
+		mov si,lxrc_data
+		call str_copy
+.nosusedata:
+
+		cmp byte [gfx_ok],0
+		jnz .isgfx
+
+		cmp byte [video_mode],0
+		jnz .vmode_10
+		mov si,opt_textmode
+		call str_copy
+.vmode_10:
+		cmp byte [video_mode],1
+		jnz .vmode_20
+		mov eax,640 + (480 << 16)
+		jmp .vmode_40
+.vmode_20:
+		cmp byte [video_mode],2
+		jnz .vmode_30
+		mov eax,800 + (600 << 16)
+		jmp .vmode_40
+.vmode_30:
+		cmp byte [video_mode],3
+		jnz .vmode_90
+		mov eax,1024 + (768 << 16)
+.vmode_40:
+		push di
+		call find_fb
+		pop di
+		or cx,cx
+		jz .vmode_90
+		mov si,opt_video_mode
+		xchg ax,cx
+		xchg al,ah
+		call byte_to_hex
+		mov al,ah
+		call byte_to_hex
+		mov si,opt_video
+		call str_copy
+.vmode_90:
+.isgfx:
+%endif
+
                 mov al,' '                      ; Space
                 stosb
 
@@ -124,6 +186,18 @@
                 mov si,[CmdOptPtr]              ; Options from user input
 		call strcpy
 
+%ifdef WITH_GFX
+; debug: print final kernel command line
+		push ds
+		push es
+		pop ds
+		mov si,cmd_line_here
+		call xwritestr
+		pop ds
+		mov si,crlf_msg
+		call xwritestr
+%endif
+
 ;
 ; Scan through the command line for anything that looks like we might be
 ; interested in.  The original version of this code automatically assumed
@@ -144,6 +218,12 @@
 		je is_vga_cmd
                 cmp eax,'mem='
 		je is_mem_cmd
+
+%ifdef WITH_GFX
+		cmp eax,'SLX='
+		je is_slx_cmd
+%endif
+
 %if IS_PXELINUX
 		cmp eax,'keep'			; Is it "keeppxe"?
 		jne .notkeep
@@ -199,11 +279,58 @@
 %endif
 		mov [cs:HighMemSize],ebx
 		jmp short skip_this_opt
+
+%ifdef WITH_GFX
+is_slx_cmd:
+                add si,byte 4
+                call parseint
+		jc skip_this_opt		; Not an integer
+		mov [cs:SLXOption],bx
+		jmp short skip_this_opt
+%endif
+
 cmdline_end:
                 push cs                         ; Restore standard DS
                 pop ds
 		sub si,cmd_line_here
 		mov [CmdLineLen],si		; Length including final null
+
+%ifdef WITH_GFX
+		call boot_hd
+		jnc start_hd_90
+		cmp byte [gfx_ok],0
+		jz start_hd_50
+		mov al,0
+		mov si,err_bad_mbr2
+		xor di,di
+		call gfx_infobox
+		mov si,no_msg
+		jmp abort_load
+start_hd_50:
+		mov si,err_bad_mbr1
+		call cwritestr
+                mov si,crlf_msg
+                jmp abort_load
+start_hd_90:
+
+		call lookup_initrd
+		jnc start_loading
+		cmp word [ExpInitRDClust],byte 0
+		jz near initrd_notthere
+
+start_loading:
+
+		call lookup_splash
+		cmp byte [gfx_ok],0
+		jz kernel_nogfx
+		mov ax,[KernelClust]
+		add ax,[InitRDClust]
+		add ax,[SplashClust]
+		mov si,KernelCName
+		call gfx_progress_init
+kernel_nogfx:
+%endif
+
 ;
 ; Now check if we have a large kernel, which needs to be loaded high
 ;
@@ -241,11 +368,21 @@
 ; jumping to it.
 ;
 read_kernel:
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jnz .isgfx
+%endif
+
                 mov si,KernelCName		; Print kernel name part of
                 call cwritestr                  ; "Loading" message
                 mov si,dotdot_msg		; Print dots
                 call cwritestr
 
+%ifdef WITH_GFX
+.isgfx:
+%endif
+
                 mov eax,[HighMemSize]
 		sub eax,100000h			; Load address
 		cmp eax,[KernelSize]
@@ -266,8 +403,18 @@
 
 		; On exit EDI -> where to load the rest
 
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jnz .isgfx2
+%endif
+
                 mov si,dot_msg			; Progress report
                 call cwritestr
+
+%ifdef WITH_GFX
+.isgfx2:
+%endif
+
                 call abort_check
 
 		pop ecx				; Number of bytes in the initial portion
@@ -282,17 +429,75 @@
                 mov ax,real_mode_seg		; Set to real mode seg
                 mov es,ax
 
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jnz .isgfx3
+%endif
+
                 mov si,dot_msg
                 call cwritestr
 
+%ifdef WITH_GFX
+.isgfx3:
+%endif
+
+
 ;
 ; Now see if we have an initial RAMdisk; if so, do requisite computation
 ; We know we have a new kernel; the old_kernel code already will have objected
 ; if we tried to load initrd using an old kernel
 ;
+
+%ifdef WITH_GFX
+%if IS_SYSLINUX
+		cmp byte [InitRDMissing],0
+		jz load_initrd
+
+		; ok, the initrd is missing, ask user to replace disk
+
+		cmp byte [gfx_ok],0
+		jz load_i_10
+		mov al,0
+		mov si,mod_disk_msga
+		xor di,di
+		call gfx_infobox
+		jmp load_i_20
+load_i_10:
+		mov si,clrln_msg
+		call cwritestr
+		mov si,mod_disk_msg
+		call cwritestr
+		call wait_for_key
+
+load_i_20:
+		call detach_cd
+		; call reload_boot
+		; call update_fat
+		call lookup_initrd
+		pushf
+		cmp byte [gfx_ok],0
+		jnz load_i_50
+		mov si,clrln_msg
+		call cwritestr
+load_i_50:
+		popf
+		jc initrd_notthere
+%endif
+%endif
+
 load_initrd:
                 test byte [initrd_flag],1
                 jz nk_noinitrd
+
+%ifdef WITH_GFX
+		call lookup_splash		; find splash and add size
+		mov edx,[InitRDSize]
+		add edx,3
+		and edx,~3
+		push edx
+		add edx,[splashlen]
+		mov [es:su_ramdisklen],edx
+%else
                 push es                         ; ES->real_mode_seg
                 push ds
                 pop es                          ; We need ES==DS
@@ -307,6 +512,8 @@
 		jz initrd_notthere
 		mov [es:su_ramdisklen1],ax	; Ram disk length
 		mov [es:su_ramdisklen2],dx
+%endif
+
 		mov edx,[HighMemSize]		; End of memory
 		dec edx
 		mov eax,[RamdiskMax]		; Highest address allowed by kernel
@@ -319,10 +526,37 @@
 		sub edx,[es:su_ramdisklen]	; Subtract size of ramdisk
                 xor dx,dx			; Round down to 64K boundary
                 mov [es:su_ramdiskat],edx	; Load address
+
+%ifdef WITH_GFX
+		pop eax
+		add edx,eax
+		mov [Splashat],edx		; Load address for splash
+		mov si,[initrd_ptr]
+%endif
+
 		call loadinitrd			; Load initial ramdisk
+
+%ifdef WITH_GFX
+		cmp word [SplashClust],0
+		jz short initrd_end
+		call loadsplash
+%endif
+
 		jmp short initrd_end
 
 initrd_notthere:
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		mov si,err_noinitrda
+		mov di,InitRDCName
+		mov al,1
+		call gfx_infobox
+		call do_reboot
+.nogfx:
+%endif
+
                 mov si,err_noinitrd
                 call cwritestr
                 mov si,InitRDCName
@@ -330,18 +564,70 @@
                 mov si,crlf_msg
                 jmp abort_load
 
-no_high_mem:    mov si,err_nohighmem		; Error routine
-                jmp abort_load
+no_high_mem:
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		mov si,err_nohighmem
+		xor di,di
+		mov al,1
+		call gfx_infobox
+		call do_reboot
+.nogfx:
+%endif
+
+		mov si,err_nohighmem		; Error routine
+		jmp abort_load
 
 initrd_end:
 nk_noinitrd:
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		call gfx_progress_done
+		call abort_check
+		jmp update_disk
+.nogfx:
+%endif
+
 ;
 ; Abandon hope, ye that enter here!  We do no longer permit aborts.
 ;
                 call abort_check        	; Last chance!!
 
+%ifdef WITH_GFX
+		mov si,clrln_msg
+%else
 		mov si,ready_msg
+%endif
+
+		call cwritestr
+
+%ifdef WITH_GFX
+update_disk:
+;
+; if the user has an update disk, give him a chance to insert it now
+;
+		cmp byte [wants_update],0
+		jz .update_done
+
+		cmp byte [gfx_ok],0
+		jz .update_20
+
+		mov al,0
+		mov si,upd_msg_1a
+		xor di,di
+		call gfx_infobox
+		jmp .update_done
+.update_20:
+		mov si,upd_msg_1
 		call cwritestr
+		call wait_for_key
+.update_done:	
+		call gfx_done
+%endif
 
 		call vgaclearmode		; We can't trust ourselves after this
 
@@ -474,6 +760,14 @@
                 xor ax,ax
                 int 16h
 %endif
+
+%if do_test
+		mov si,test_ok_msg
+		call cwritestr
+		jmp $
+test_ok_msg	db 'done.', 0
+%endif
+
 ;
 ; Set up segment registers and the Linux real-mode stack
 ; Note: es == the real mode segment
@@ -514,7 +808,7 @@
 ;
 ; Need to be set:
 ;	su_ramdiskat	- Where in memory to load
-;	su_ramdisklen	- Size of file
+;	su_ramdisklen	- Size of file		(WITH_GFX: InitRDSize)
 ;	SI		- initrd filehandle/cluster pointer
 ;
 loadinitrd:
@@ -522,8 +816,22 @@
 		mov ax,real_mode_seg
                 mov es,ax
                 mov edi,[es:su_ramdiskat]	; initrd load address
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jnz .isgfx
+%endif
+
 		push si
+
+%ifdef WITH_GFX
+		mov si,clrln_msg
+		call cwritestr
+		mov si,loading_msg		; Write "Loading "
+%else
 		mov si,crlfloading_msg		; Write "Loading "
+%endif
+
 		call cwritestr
                 mov si,InitRDCName		; Write ramdisk name
                 call cwritestr
@@ -531,9 +839,296 @@
                 call cwritestr
 		pop si
 
+%ifdef WITH_GFX
+.isgfx:
+		mov eax,[InitRDSize]
+%else
 		mov eax,[es:su_ramdisklen]
+%endif
+
 		call load_high			; Load the file
 
+%ifndef WITH_GFX
 		call crlf
+%endif
+
                 pop es                          ; Restore original ES
                 ret
+
+
+%ifdef WITH_GFX
+
+;
+; terminate cdrom boot floppy emulation
+;
+detach_cd:
+		test byte [SLXOption],1		; just make it configurable
+		jnz detach_cd_90
+		push es				; you never know...
+		mov si,trackbuf
+		mov ax,4b00h
+                mov byte [si],13h		; packet size
+		xor dx,dx			; dl: drive 0
+		int 13h				; terminate floppy emulation
+		pop es
+detach_cd_90:
+		ret
+
+;
+; boot mbr, if SLXOption says so
+;
+; CF = 1 if failed
+;
+boot_hd:
+		mov ax,[SLXOption]
+		test al,2		; should we do it?
+		jz boot_hd_90
+		push es
+		shr ax,2
+%if IS_SYSLINUX
+		xchg [bsDriveNumber],al
+%endif
+		push ax
+		call detach_cd
+%if IS_SYSLINUX
+		xor eax,eax
+		mov es,ax
+		mov bx,trackbuf
+		push bx
+		call getonesec
+%elif IS_ISOLINUX
+		pop dx
+		mov ax,0201h
+		xor cx,cx
+		mov es,cx
+		inc cx
+		xor dh,dh
+		mov bx,trackbuf
+		push bx
+		int 13h
+%endif
+		pop si
+		cmp word [si+0x1fe],0aa55h
+		jnz boot_hd_80
+		cmp word [si], byte 0
+		jz boot_hd_80
+		mov di,7c00h
+		push di
+		mov cx,0x100
+		cld
+		rep movsw
+		call gfx_done
+		ret
+boot_hd_80:
+%if IS_SYSLINUX
+		pop ax
+		mov [bsDriveNumber],al
+%endif
+		pop es
+		and word [SLXOption],byte 0
+		stc
+boot_hd_90:
+		ret
+
+%if 0
+;
+; Doesn't work anyway: FAT area size has been made to fit the initial FAT.
+;
+
+;
+; reload boot block
+;
+reload_boot:
+		push es
+		xor ax,ax
+		xor dx,dx
+		mov es,ax
+		mov bx,trackbuf
+		push bx
+		call getonesec
+		pop si
+		add si,superblock-bootsec
+		mov di,superblock
+		mov cx,superblock_len
+		cld
+		rep movsb
+
+		; we can't reuse the bootblock code, it wouldn't fit :-((
+
+		; expand the superblock to dwords
+		xor eax,eax
+		mov si,superblock
+		mov di,SuperInfo
+		mov cx,superinfo_size
+.loop:
+		lodsw
+		dec si
+		stosd				; Store expanded word
+		xor ah,ah
+		stosd				; Store expanded byte
+		loop .loop
+
+		; rework things below
+
+		movzx ax,[bsFATs]	; Number of FATs
+		mul word [bsFATsecs]	; Get the size of the FAT area
+		add ax,[bsHidden1]	; Add hidden sectors
+		adc dx,[bsHidden2]
+		add ax,[bsResSectors]	; And reserved sectors
+		adc dx,byte 0
+
+		mov [RootDir1],ax	; Location of root directory
+		mov [RootDir2],dx
+		mov [DataArea1],ax
+		mov [DataArea2],dx
+
+		mov ax,32		; Size of a directory entry
+		mul word [bsRootDirEnts]
+		mov bx,[bsBytesPerSec]
+		add ax,bx		; Round up, not down
+		dec ax
+		div bx			; Now we have the size of the root dir
+		mov [RootDirSize],ax
+
+		add [DataArea1],ax
+		adc word [DataArea2],byte 0
+
+reload_boot_90:
+		pop es
+		ret
+%endif
+
+;
+; look for initrd, get its size and prepare for loading it
+; return: CF = 1 if it wasn't found
+;
+lookup_initrd:
+		and word [InitRDClust], byte 0
+                test byte [initrd_flag],1
+                jz lookup_initrd_90
+		push word [ExpInitRDClust]
+		pop word [InitRDClust]
+                push es                         ; ES->real_mode_seg
+                push ds
+                pop es                          ; We need ES==DS
+                mov si,InitRD
+                mov di,InitRDCName
+                call unmangle_name              ; Create human-readable name
+                sub di,InitRDCName
+                mov [InitRDCNameLen],di
+                mov di,InitRD
+                call searchdir                  ; Look for it in directory
+                pop es
+		stc
+		mov byte [InitRDMissing],1	; remember for later
+		jz lookup_initrd_90
+		mov byte [InitRDMissing],0
+		mov [initrd_ptr],si		; Save cluster pointer
+		mov [InitRDSize],ax		; Size in bytes
+		mov [InitRDSize + 2],dx
+		div word [ClustSize]
+		and dx,dx			; Round up
+		setnz dl
+		movzx dx,dl
+		add ax,dx
+		mov [InitRDClust],ax		; Ramdisk clusters
+lookup_initrd_90:
+		ret
+
+;
+; look for splash, get its size and prepare for loading it
+; return: CF = 1 if it wasn't found
+;
+lookup_splash:
+		and	word [SplashClust], byte 0
+		test	byte [initrd_flag],1
+		jz	lookup_splash_90
+		mov	ax,[es:bs_vidmode]
+		mov	si,fb_mode_list
+		mov	cx,fb_mode_entries
+lookup_splash_10:
+		cmp	[si+fb_mode],ax
+		jz	lookup_splash_20
+		add	si,sizeof_fb_entry
+		loop	lookup_splash_10
+		jmp	lookup_splash_90
+lookup_splash_20:
+		mov	ax,[si+fb_width]
+		call	lookup_splash_to_dec
+		mov	[SplashCName], eax
+		mov	ax,[si+fb_height]
+		call	lookup_splash_to_dec
+		mov	[SplashCName+4], eax
+		mov	[SplashCName+8], dword '.spl'
+		mov	[SplashCName+12], byte 0
+		push	es
+		push	ds
+		pop	es
+		mov	si,SplashCName
+		mov	di,SplashName
+		call	mangle_name
+		mov	di,SplashName
+		call	searchdir
+		pop	es
+		stc
+		jz lookup_splash_90
+		mov [splash_ptr],si		; Save cluster pointer
+		mov [splashlen],ax
+		mov [splashlen+2],dx
+		div word [ClustSize]
+		and dx,dx			; Round up
+		setnz dl
+		movzx dx,dl
+		add ax,dx
+		mov [SplashClust],ax		; Splash clusters
+lookup_splash_90:
+		ret
+
+lookup_splash_to_dec:
+		push	dx
+		push	bx
+		push	ecx
+		xor	cx,cx
+		xor	dx,dx
+		mov	bx,10
+		div	bx
+		xchg	ch,dl
+		div	bx
+		xchg	cl,dl
+		shl	ecx,8
+		div	bx
+		xchg	cl,dl
+		shl	ecx,8
+		mov	cl,al
+		mov	eax,ecx
+		pop	ecx
+		pop	bx
+		pop	dx
+		add	eax,0x30303030
+		ret
+
+
+;
+; Load Splash into high memory
+;
+loadsplash:
+		cmp byte [gfx_ok],0
+		jnz .isgfx
+
+		mov si,clrln_msg
+		call cwritestr
+		mov si,loading_msg		; Write "Loading "
+		call cwritestr
+                mov si,SplashCName		; Write splash name
+                call cwritestr
+                mov si,dotdot_msg		; Write dots
+                call cwritestr
+
+.isgfx:
+                mov si,[splash_ptr]
+                mov edi,[Splashat]		; splash load address
+		mov eax,[splashlen]
+		call load_high			; Load the file
+		ret
+
+%endif
--- suse.inc
+++ suse.inc
@@ -0,0 +1,1346 @@
+;
+; some extra functionality for syslinux
+;
+
+msg_0		db ' ', 0
+msg_1		db 10, 0
+
+vbe_msg_0	db 'looking for VBE...', 13, 10, 0
+vbe_msg_1	db 'VBE ok', 13, 10, 0
+vbe_msg_2	db 'DDC supported', 13, 10, 0
+vbe_msg_3	db 'got EDID record', 13, 10, 0
+vbe_msg_4	db 'VBE >= 2.0, looking for fb modes...', 13, 10, 0
+vbe_msg_5	db ' mode found', 13, 10, 0
+vbe_msg_6	db 'x', 0,
+vbe_msg_7	db 'fb modes broken', 13, 10, 0
+apm_msg_0	db 'looking for APM...', 13, 10, 0
+apm_msg_1	db 'APM ok', 13, 10, 0
+hd_msg_0	db 'reading mbr...', 13, 10, 0
+hd_msg_1	db 'got mbr', 13, 10, 0
+hd_msg_2	db 'edd?', 13, 10, 0
+hd_msg_3	db 'edd ok', 13, 10, 0
+hd_msg_4	db 'drive 8'
+hd_msg_4a	db '0h ok', 13, 10, 0
+hd_msg_5	db 'cd type 4 boot', 13, 10, 0
+kbd_msg_0	db 'kbd id?', 13, 10, 0
+kbd_msg_1	db 'got kbd id', 13, 10, 0
+upd_msg_0	db '       Update floppy', 0
+upd_msg_1	db 13, '                                                                               '
+		db 13, 'Please insert the driver update floppy/CDROM; then press ENTER to continue.', 0
+upd_msg_1a	db 'Please insert the driver update floppy/CDROM.', 0
+mod_disk_msg	db 'Please insert module disk 1; then press ENTER to continue.', 0
+mod_disk_msga	db 'Please insert module disk 1.', 0
+boot_disk_msg	db 'Please insert boot disk '
+boot_disk_msg0	db '0; then press ENTER to continue.', 0
+boot_ndisk_msg	db 'This is not boot disk '
+boot_ndisk_msg0	db '0. Press ENTER to continue.', 0
+%if 0
+prod_excl	db 'VMware', 0
+prod_excl_end	equ $-1
+%endif
+
+do_write_msg	db 0, 0					; set to get some debug messages
+wants_update	db 0
+do_nogfx	db 0
+no_fkeys	db 0
+vmode_shown	db 0
+hd_disk		db 80h
+dec_buf		zb 10h
+opt_textmode	db ' textmode=1', 0
+opt_video	db ' vga=0x'
+opt_video_mode	db '0000', 0
+ddc_timings	dw 0		; standard ddc timing info
+ddc_xtimings	dd 0, 0, 0, 0
+ddc_mult	dd 0, 1		; needed for ddc timing calculation
+		dd 3, 4
+		dd 4, 5
+		dd 9, 16
+video_mem	dw 0		; video memory size in 64k units
+video_mode	db 1		; mode index: 0:text, 1:640x480, 2:800x600, 3:1024x768
+video_mode_mask db 0		; supported modes: bit 2:800x600, bit 3:1024x768
+video_mode_num	dw 0		; mode number
+xread_pack	db 10h		; packet size
+		db 0		; reserved
+		dw 1		; sector count
+		dw mi_buf	; buffer offset
+xread_pack_seg	dw 0		; buffer segment
+		dd 0, 0		; sector number
+
+; framebuffer mode list
+; Don't rearrange offsets, they're used in gfxboot, too!
+fb_mode		equ 0		; word
+fb_width	equ 2		; word
+fb_height	equ 4		; word, must follow fb_width
+fb_bits		equ 6		; byte
+fb_ok		equ 7		; monitor supports it
+sizeof_fb_entry	equ 8
+
+fb_mode_entries	equ 16
+fb_mode_list	times fb_mode_entries * sizeof_fb_entry db 0
+
+lxrc_ptr	dw lxrc_data1
+lxrc_data	db 0
+lxrc_data1	zb 0fah
+
+splash_ptr	dw 0			; splash pointer
+splashlen	dd 0			; splash len
+FrameBuffer	dw 0			; Add an appropriate vga= line for kernel fb's
+ReadInfo	dw 0			; Get some info from BIOS
+ExpInitRDClust	dw 0			; Expected ramdisk size in clusters
+InitRDMissing	db 0			; Set if it was missig
+initrd_flag	db 0			; used to be overlayed with initrd_ptr !?
+SLXOption	dw 0			; control sysliux via cmdline
+DiskSize	dw 0			; unlimited
+CurrentDisk	db 0			; current disk
+
+err_bad_mbr1	db CR, LF,
+err_bad_mbr2	db 'Failed to start from Harddisk', 0
+load_gfx_msg	db 'Loading...', 0
+no_msg		db 0
+clrln_msg	db 0dh, '                                                            ', 0dh, 0
+gfx_ok		db 0
+
+;
+; Read VBE info.
+;
+; es = ds!
+;
+get_vbe_info:
+		mov di,vbe_buf
+		mov dword [di],32454256h	; 'VBE2'
+		and word [di+4],byte 0		; just in case
+		mov ax,4f00h
+		int 10h
+		cmp ax,4fh
+		jz get_vbe_info_90
+		; no vbe support: set vbe version to 0
+		and word [di+4],byte 0
+		stc
+get_vbe_info_90:
+		ret
+;
+; Read EDID record via DDC
+;
+read_ddc:
+		pushad				; don't modify any regs
+		push es
+		push ds
+		pop es
+		mov si,vbe_msg_0
+		call xwritestr
+		call get_vbe_info
+		jc near read_ddc_done
+		mov ax,[vbe_buf+12h]
+		mov [video_mem],ax
+		mov si,vbe_msg_1
+		call xwritestr
+		xor cx,cx
+		xor dx,dx
+		mov ax,4f15h
+		mov bl,0
+		int 10h
+		cmp ax,4fh
+		jnz near read_ddc_done
+		mov si,vbe_msg_2
+		call xwritestr
+		push ds
+		pop es
+		mov di,ddc_buf
+		push di
+		mov cx,80h
+		xor ax,ax
+		rep stosb
+		pop di
+		mov ax,4f15h
+		mov bl,1
+		xor cx,cx
+		xor dx,dx
+		int 10h
+		cmp ax,4fh
+		jnz near read_ddc_done
+		mov si,vbe_msg_3
+		call xwritestr
+		mov bx,ddc_buf
+
+		mov al,[bx+23h]
+		mov [ddc_timings],al
+		mov al,[bx+24h]
+		mov [ddc_timings+1],al
+
+		mov cx,4
+		lea si,[bx+26h]
+		mov di,ddc_xtimings
+read_ddc_40:
+		lodsb
+		cmp al,1
+		jbe read_ddc_70
+		
+		movzx ebp,al
+		add bp,byte 31
+		shl bp,3
+
+		mov al,[si]
+		shr al,6
+		jz read_ddc_70
+		movzx bx,al
+		shl bx,3
+
+		mov eax,ebp
+		mul dword [bx+ddc_mult]
+		div dword [bx+ddc_mult+4]
+		
+		jz read_ddc_70
+
+		shl eax,16
+		add eax,ebp
+		mov [di],eax
+
+read_ddc_70:
+		inc si
+		add di,4
+		loop read_ddc_40
+
+read_ddc_done:
+		pop es
+		popad
+		ret
+
+; get apm capabilities & VBE video memory size
+read_apm:
+		pushad				; don't modify any regs
+		push es
+		push ds
+		pop es
+
+		mov si,[lxrc_ptr]
+		mov byte [si],','
+		inc word [lxrc_ptr]
+
+		mov si,apm_msg_0
+		call xwritestr
+		mov ax,5300h
+		xor bx,bx
+		int 15h
+		jc read_apm_done
+		push cx
+		push ax
+		mov si,apm_msg_1
+		call xwritestr
+		pop ax
+
+		mov si,[lxrc_ptr]
+
+		shl ah,4
+		and al,0fh
+		or al,ah
+		call byte_to_hex
+
+		pop ax
+		call byte_to_hex
+
+		; add VBE version info
+
+		mov ax,[vbe_buf+4]
+		shl ah,4
+		and al,0fh
+		or al,ah
+		call byte_to_hex
+
+		; add video mem size
+
+		mov ax,[vbe_buf+12h]
+		xchg al,ah
+		call byte_to_hex
+		xchg al,ah
+		call byte_to_hex
+
+		mov [lxrc_ptr],si
+		mov byte [si],0
+
+read_apm_done:
+		pop es
+		popad
+		ret
+
+; read 1st hd sector & compute crc
+read_hd:
+		pushad				; don't modify any regs
+		push es
+		push ds
+		pop es
+
+		mov si,[lxrc_ptr]
+		mov byte [si],','
+		inc word [lxrc_ptr]
+		mov byte [si + 1],0
+
+		; maybe we booted from cdrom with an hd image
+		; (special magic from our mbr loader)
+		cmp byte [7c03h],19
+		jnz read_hd_03
+		mov byte [hd_disk],81h
+		mov byte [hd_msg_4a],'1'
+		mov si,hd_msg_5
+		call xwritestr
+read_hd_03:
+
+		mov si,hd_msg_2
+		call xwritestr
+
+		mov ah,41h
+		mov bx,55aah
+		mov dl,[hd_disk]
+		int 13h
+		mov bp,0
+		jc read_hd_05
+		cmp bx,0aa55h
+		jnz read_hd_05
+		test cl,1
+		jz read_hd_05
+
+		inc bp
+
+		mov si,hd_msg_3
+		call xwritestr
+
+read_hd_05:
+		mov si,hd_msg_0
+		call xwritestr
+
+		mov ah,10h
+		mov dl,[hd_disk]
+		push bp
+		int 13h
+		pop bp
+		jc near read_hd_done
+		cmp ah,0
+		jnz near read_hd_done
+
+		mov si,hd_msg_4
+		call xwritestr
+
+		mov ax,0201h
+		mov cx,1
+		mov dh,ch		; dh = 0
+		mov dl,[hd_disk]
+		mov bx,mi_buf
+		push bp
+		int 13h
+		pop bp
+		jc near read_hd_done
+
+		mov si,hd_msg_1
+		call xwritestr
+
+		mov si,mi_buf
+		xor ebx,ebx
+		mov cx,200h
+		mov edi,57
+		stc
+		sbb eax,eax
+read_hd_20:
+		mov bl,[si]
+		inc si
+		add eax,ebx
+		mul edi
+		dec cx
+		jnz read_hd_20
+
+		mov si,[lxrc_ptr]
+
+		mov bx,4
+read_hd_40:
+		rol eax,8
+		call byte_to_hex
+		dec bx
+		jnz read_hd_40
+
+		or bp,bp
+		jz read_hd_90
+		mov byte [si],'.'
+		inc si
+
+
+		; get device path info
+
+		push si
+		mov ax,4800h
+		mov dl,[hd_disk]
+		mov si,mi_buf
+		mov di,si
+		push ds
+		pop es
+		mov cx,100h
+		rep stosb
+		; some BIOSes use only one byte as buffer len
+		mov word [si],0ffh
+		int 13h
+		pop si
+		jc read_hd_90
+
+		mov bx,mi_buf
+		cmp word [bx],38h
+		jb read_hd_90
+
+		cmp word [bx+1eh],0beddh
+		jnz read_hd_90
+
+		cmp dword [bx+24h],20494350h	; 'PCI '
+		jnz read_hd_90
+
+		mov al,[bx+30h]
+		call byte_to_hex
+		mov al,[bx+31h]
+		call byte_to_hex
+		mov al,[bx+32h]
+		call byte_to_hex
+
+read_hd_90:
+		mov [lxrc_ptr],si
+		mov byte [si],0
+
+read_hd_done:
+		pop es
+		popad
+		ret
+
+; read keyboard id
+read_kbd:
+		pushad				; don't modify any regs
+		push es
+		push ds
+		pop es
+
+		mov si,[lxrc_ptr]
+		mov byte [si],','
+		inc word [lxrc_ptr]
+
+		mov si,kbd_msg_0
+		call xwritestr
+		mov ax,900h
+		int 16h
+		test al,10h
+		jz read_kbd_done
+
+		mov si,kbd_msg_1
+		call xwritestr
+		mov ah,0ah
+		xor bx,bx
+		int 16h
+
+		mov si,[lxrc_ptr]
+		mov al,bh
+		call byte_to_hex
+		mov al,bl
+		call byte_to_hex
+
+		mov [lxrc_ptr],si
+		mov byte [si],0
+
+read_kbd_done:
+		pop es
+		popad
+		ret
+
+;
+; Read VBE2 mode info
+;
+; We use the VBE record returned earlier by the DDC calls.
+;
+; Go through the mode list and look for a video mode with frame buffer
+; support.
+;
+read_vbe_modes:
+		pushad				; don't modify any regs
+		push es
+		push gs
+		push ds
+		pop es
+
+		; always support this mode
+		mov eax,640 + (480 << 16)
+		xor cx,cx
+		mov dh,4
+		call add_fb_to_list2
+		call enable_fb
+
+		cmp word [FrameBuffer],byte 0
+		jz near read_vbe_done
+		cmp word [vbe_buf+4],200h
+		jb near read_vbe_done
+		mov si,vbe_msg_4
+		call xwritestr
+		; do it again, data structures may have been overwritten
+		; by ddc call
+		call get_vbe_info
+		jc near read_vbe_done
+
+%if 0
+		xor ebx,ebx
+		lgs bx,[vbe_buf+1ah]
+		mov eax,gs
+		shl eax,4
+		add eax,ebx
+		or eax,eax
+		jz read_vbe_10
+		cmp eax,100000h
+		jae read_vbe_10
+		call check_prod_excl
+		jc read_vbe_10
+		mov si,vbe_msg_7
+		call xwritestr
+		jmp near read_vbe_done
+read_vbe_10:
+%endif
+
+		; copy the list
+		lgs si,[vbe_buf+0eh]
+		mov cx,127			; buffer has 128 entries
+		push ds
+		pop es
+		mov di,mi_list
+		mov bx,di
+		cld
+read_vbe_15:
+		gs lodsw
+		stosw
+		cmp ax,0xffff
+		jz read_vbe_17
+		loop read_vbe_15
+read_vbe_17:
+		mov word [di],0xffff
+read_vbe_20:
+		mov cx,[bx]
+		inc bx
+		inc bx
+		cmp cx,0xffff
+		jz read_vbe_50
+
+		mov ax,4f01h
+		mov di,mi_buf
+		push cx
+		int 10h
+		pop cx
+		cmp ax,4fh
+		jnz read_vbe_20
+
+		test byte [mi_buf],1		; mode supported?
+		jz read_vbe_20
+		cmp dword [mi_buf+28h],byte 0	; frame buffer start
+		jz read_vbe_20
+
+		mov eax,[mi_buf+12h]		; size
+		mov dl,[mi_buf+1bh]		; color mode (aka memory model)
+		mov dh,[mi_buf+19h]		; color depth
+		cmp dl,6			; direct color
+		jnz read_vbe_30
+		sub dh,[mi_buf+25h]		; reserved color bits
+		jmp read_vbe_40
+read_vbe_30:
+		cmp dl,4			; PL8
+		jnz read_vbe_20
+		mov dh,8
+read_vbe_40:
+
+		; cx	mode
+		; eax	resolution
+		; dh	color bits
+
+		call add_fb_to_list
+		jmp read_vbe_20
+
+read_vbe_50:
+		mov eax,640 + (480 << 16)
+		call enable_fb
+
+		test word [ddc_timings],0ef03h
+		jnz read_vbe_51
+		cmp word [video_mem],0x3e		; at least 4MB-128k
+		jb read_vbe_52
+read_vbe_51:
+		mov eax,800 + (600 << 16)
+		call enable_fb
+
+read_vbe_52:
+		test word [ddc_timings],0f00h
+		jnz read_vbe_53
+		cmp word [video_mem],0x200		; at least 32MB
+		jb read_vbe_54
+read_vbe_53:
+		mov eax,1024 + (768 << 16)
+		call enable_fb
+
+read_vbe_54:
+		test word [ddc_timings],0100h
+		jz read_vbe_56
+		mov eax,1280 + (1024 << 16)
+		call enable_fb
+
+read_vbe_56:
+		mov cx,4
+		mov si,ddc_xtimings
+read_vbe_58:
+		lodsd
+		push si
+		push cx
+		call enable_fb
+		pop cx
+		pop si
+		loop read_vbe_58
+
+		; preselect mode for text interface
+
+		mov eax,800 + (600 << 16)
+		call find_fb
+		cmp dl,1
+		jb read_vbe_60
+		or byte [video_mode_mask],1 << 2
+		cmp dl,2
+		jb read_vbe_60
+		mov byte [video_mode],2
+read_vbe_60:
+
+		mov eax,1024 + (768 << 16)
+		call find_fb
+		cmp dl,1
+		jb read_vbe_62
+		or byte [video_mode_mask],1 << 3
+		cmp dl,2
+		jb read_vbe_62
+		mov byte [video_mode],3
+read_vbe_62:
+
+read_vbe_done:
+		pop gs
+		pop es
+		popad
+		ret
+
+
+%if 0
+; go through exclude list
+;
+; in:  gs:bx		product string
+; out: CF 0/1		found/not found
+;
+check_prod_excl:
+		cld
+		mov si,prod_excl
+check_prod_excl_20:
+		mov di,bx
+		dec di
+check_prod_excl_30:
+		inc di
+		lodsb
+		or al,al
+		jz check_prod_excl_90
+		cmp al,[gs:di]
+		jz check_prod_excl_30
+check_prod_excl_40:
+		lodsb
+		or al,al
+		jnz check_prod_excl_40
+		cmp si,prod_excl_end
+		jb check_prod_excl_20
+		stc
+check_prod_excl_90:
+		ret
+%endif
+
+
+; add fb mode to mode list
+;
+; cx	mode
+; eax	resolution
+; dh	color bits
+;
+; only added if color bits are 8 or 16 and resolution is at least 640x480
+;
+; must not change bx & eax
+;
+add_fb_to_list:
+		cmp dh,8
+		jz add_fb_10
+		cmp dh,16
+		jnz add_fb_90
+add_fb_to_list2:
+add_fb_10:
+		cmp ax,640
+		jb add_fb_90
+		mov esi,eax
+		shr esi,16
+		cmp si,480
+		jb add_fb_90
+		mov si,fb_mode_list
+		mov bp,fb_mode_entries
+add_fb_20:
+		cmp eax,[si+fb_width]
+		jz add_fb_40
+		cmp byte [si+fb_bits],0
+		jz add_fb_40
+		add si,sizeof_fb_entry
+		dec bp
+		jnz add_fb_20
+		jmp add_fb_90
+add_fb_40:
+		cmp [si+fb_bits],dh
+		jae add_fb_90
+		mov [si+fb_mode],cx
+		or cx,cx
+		jz add_fb_50
+		add byte [si+fb_mode+1],2	; for linux kernel
+add_fb_50:
+		mov [si+fb_width],eax
+		mov [si+fb_bits],dh
+add_fb_90:
+		ret
+
+
+; tag fb mode as supported
+;
+; eax	resolution
+;
+enable_fb:
+		mov si,fb_mode_list
+		mov bp,fb_mode_entries
+		mov edx,eax
+		shr edx,16
+enable_fb_10:
+		cmp byte [si+fb_bits],0
+		jz enable_fb_90
+		cmp [si+fb_width],ax
+		ja enable_fb_50
+		cmp [si+fb_height],dx
+		ja enable_fb_50
+		mov byte [si+fb_ok],1
+enable_fb_50:
+		add si,sizeof_fb_entry
+		dec bp
+		jnz enable_fb_10
+enable_fb_90:
+		ret
+
+
+; find fb mode
+;
+; eax	resolution
+;
+; return:
+;  dl	0: not found, 1: found but not supp, 2: ok
+;  cx	mode number
+;
+find_fb:
+		mov si,fb_mode_list
+		mov bp,fb_mode_entries
+		xor dl,dl
+		xor cx,cx
+find_fb_10:
+		cmp byte [si+fb_bits],0
+		jz find_fb_90
+		cmp [si+fb_width],eax
+		jnz find_fb_50
+		mov dl,[si+fb_ok]
+		inc dx
+		mov cx,[si+fb_mode]
+find_fb_50:
+		add si,sizeof_fb_entry
+		dec bp
+		jnz find_fb_10
+find_fb_90:
+		ret
+
+
+; unpack EISA ID
+; ax -> [si]
+;
+unpack_eisa:
+		mov cx,ax
+		shr cx,10
+		and cl,1fh
+		add cl,'A'-1
+		mov [si],cl
+		mov cx,ax
+		shr cx,5
+		and cl,1fh
+		add cl,'A'-1
+		mov [si+1],cl
+		mov cx,ax
+		and cl,1fh
+		add cl,'A'-1
+		mov [si+2],cl
+		add si,3
+		ret
+
+; al -> to hex
+;
+byte_to_hex:
+		mov cl,al
+		shr cl,4
+		call byte_to_hex_10
+		mov cl,al
+		and cl,0fh
+byte_to_hex_10:
+		cmp cl,10
+		jb byte_to_hex_20
+		add cl,7
+byte_to_hex_20:
+		add cl,'0'
+		mov [si],cl
+		inc si
+		ret
+
+;
+; write function
+;
+xwritestr:
+		cmp byte [cs:do_write_msg],0
+		jz xwritestr_10
+		call cwritestr
+xwritestr_10:
+		ret
+
+;
+; ax: Number
+;
+xwritedec:
+		pusha
+		mov si,dec_buf+0fh
+		mov byte [si],0
+xwritedec_20:
+		xor dx,dx
+		mov cx,10
+		div cx
+		add dl,'0'
+		dec si
+		mov [si],dl
+		or ax,ax
+		jnz xwritedec_20
+		call xwritestr
+		popa
+		ret
+
+;
+; see if user wants to use an update disk
+;
+chk_update:
+		cmp byte [gfx_ok],0
+		jz chk_update_nogfx
+		ret
+chk_update_nogfx:		
+		pusha
+		clc
+		mov ah,12h
+		int 16h
+		jc chk_update_90
+
+		cmp byte [wants_update],0
+		jnz chk_update_90
+		test ah,0ah		; left or right ALT key
+		jz chk_update_90
+		mov byte [wants_update],1
+		mov cx,183bh
+		mov si,upd_msg_0
+		push ax
+		call cwritestr_xy
+		pop ax
+
+chk_update_90:
+		popa
+		ret
+
+;
+; cl, ch: x,y
+; si: text
+;
+cwritestr_xy:
+		push ds
+		pusha
+		push cx
+		mov ah,3
+		mov bh,0
+		int 10h
+		pop cx
+		push dx
+		mov dx,cx
+		mov ah,2
+		mov bh,0
+		int 10h
+		call cwritestr
+cwritestr_xy_80:
+		pop dx
+		mov ah,2
+		mov bh,0
+		int 10h
+cwritestr_xy_90:
+		popa
+		pop ds
+		ret
+
+;
+; wait for 'enter' key pressed
+;
+wait_for_key:
+		pusha
+wait_for_key_10:
+		mov ah,0
+		int 16h
+		cmp al,13
+		jnz wait_for_key_10
+		popa
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+vmode_msg_0	db 'F2=Text mode'
+vmode_msg_1	db 'F3=640x480'
+vmode_msg_2	db 'F4=800x600'
+vmode_msg_3	db 'F5=1024x768'
+vmode_msg_clr	times vmode_msg_clr - vmode_msg_0 + 3 * 3 db ' '
+vmode_msg_end	equ $
+
+show_vmode:
+		push es
+		pusha
+
+		cmp byte [no_fkeys],0
+		jnz near show_vmode_95
+
+		mov ah,3
+		mov bh,0
+		int 10h
+		push dx
+
+		mov byte [vmode_shown],1
+
+		push ds
+		pop es
+
+		mov dx,1800h
+		mov cx,vmode_msg_1 - vmode_msg_0
+		mov bp,vmode_msg_0
+		mov bx,07h
+		cmp byte [video_mode],0
+		jnz show_vmode_10
+		mov bl,70h
+show_vmode_10:
+		mov ax,1300h
+		int 10h
+
+		mov dh,18h
+		mov dl,vmode_msg_1 - vmode_msg_0 + 3
+		mov cx,vmode_msg_2 - vmode_msg_1
+		mov bp,vmode_msg_1
+		mov bx,07h
+		cmp byte [video_mode],1
+		jnz show_vmode_20
+		mov bl,70h
+show_vmode_20:
+		mov ax,1300h
+		int 10h
+
+
+		test byte [video_mode_mask],1 << 2
+		jz show_vmode_40
+
+		mov dh,18h
+		mov dl,vmode_msg_2 - vmode_msg_0 + 2 * 3
+		mov cx,vmode_msg_3 - vmode_msg_2
+		mov bp,vmode_msg_2
+		mov bx,07h
+		cmp byte [video_mode],2
+		jnz show_vmode_30
+		mov bl,70h
+show_vmode_30:
+		mov ax,1300h
+		int 10h
+show_vmode_40:
+
+		test byte [video_mode_mask],1 << 3
+		jz show_vmode_60
+
+		mov dh,18h
+		mov dl,vmode_msg_3 - vmode_msg_0 + 3 * 3
+		mov cx,vmode_msg_clr - vmode_msg_3
+		mov bp,vmode_msg_3
+		mov bx,07h
+		cmp byte [video_mode],3
+		jnz show_vmode_50
+		mov bl,70h
+show_vmode_50:
+		mov ax,1300h
+		int 10h
+show_vmode_60:
+
+
+show_vmode_90:
+		pop dx
+		mov ah,2
+		mov bh,0
+		int 10h
+
+show_vmode_95:
+
+		popa
+		pop es
+		ret
+
+hide_vmode:
+		pusha
+		cmp byte [vmode_shown],0
+		jz hide_vmode_90
+
+		mov ah,3
+		mov bh,0
+		int 10h
+		push dx
+
+		mov dx,1800h
+		mov cx,vmode_msg_end - vmode_msg_clr
+		mov bp,vmode_msg_clr
+		mov bx,07h
+		mov ax,1300h
+		int 10h
+
+		pop dx
+		mov ah,2
+		mov bh,0
+		int 10h
+
+hide_vmode_90:
+		popa
+		ret
+
+process_fkeys:
+		cmp al,1
+		jb process_fkeys_90
+		cmp al,5
+		cmc
+		jc process_fkeys_90
+
+		cmp al,3
+		jnz process_fkeys_20
+		test byte [video_mode_mask],1 << 2
+		jz process_fkeys_90
+process_fkeys_20:
+		cmp al,4
+		jnz process_fkeys_30
+		test byte [video_mode_mask],1 << 3
+		jz process_fkeys_90
+process_fkeys_30:
+
+		mov [video_mode],al
+		sub byte [video_mode],1
+		call show_vmode
+		clc
+process_fkeys_90:
+		ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; string copy
+;
+; ds:si -> es:di
+;
+str_copy:
+		lodsb
+		stosb
+		or al,al
+		jnz str_copy
+		dec di
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; do a reboot
+;
+do_reboot:
+		call gfx_done
+		mov word [472h],1234h
+		push word 0ffffh
+		push word 0
+		retf
+		int 19h
+		jmp $
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; look for a fsc notebook lcd panel and set ddc_timings
+read_fsc:
+		pushad
+		push es
+		push ds
+		cmp word [ddc_timings],byte 0
+		jnz read_fsc_90
+
+		push word 0xf000
+		pop ds
+		xor di,di
+read_fsc_10:
+		cmp dword [di],0x696a7546
+		jnz read_fsc_30
+		cmp dword [di+4],0x20757374
+		jnz read_fsc_30
+		mov cx,0x20
+		xor bx,bx
+		mov si,di
+read_fsc_20:
+		lodsb
+		add bl,al
+		dec cx
+		jnz read_fsc_20
+		or bl,bl
+		jnz read_fsc_30
+		mov al,[di+23]
+		and al,0xf0
+		jnz read_fsc_90
+		mov bl,[di+21]
+		and bx,0xf0
+		shr bx,3
+		mov ax,[cs:bx+fsc_bits]
+		mov [cs:ddc_timings],ax
+		jmp read_fsc_90
+read_fsc_30:
+		add di,0x10
+		jnz read_fsc_10
+read_fsc_90:
+		pop ds
+		pop es
+		popad
+		ret
+
+fsc_bits:
+		dw 0, 0x0004, 0x4000, 0x0200, 0x0100, 0x0200, 0, 0x4000
+		dw 0x0200, 0, 0, 0, 0, 0, 0, 0
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; read gfx data
+get_gfx_file:
+		cmp byte [do_nogfx],0
+		jnz .done
+		push si
+		mov si,load_gfx_msg
+		call cwritestr
+		pop si
+%if IS_SYSLINUX
+		push word [FATSegment]
+		pop word [gfx_mem_end_seg]
+%elif IS_ISOLINUX
+		mov word [gfx_mem_end_seg],vk_seg
+%endif
+		call gfx_init			; Load and display file
+		cmp byte [gfx_ok],0
+		jz .done
+		mov si,crlf_msg
+		call cwritestr
+.done:
+		ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; Use VESA 2.0 calls to read the EDID monitor record. The Data will
+; later be appended to the kernel command line.
+;
+; Get the APM status from the BIOS.
+;
+get_bios_info:
+		inc byte [no_fkeys]
+		cmp word [ReadInfo],0
+		jz .done
+		dec byte [no_fkeys]
+		mov al,[KbdFlags]
+		and al,3
+		jpo .done			; left xor right shift: skip BIOS calls
+		jz .not_verbose			; !(left and right shift)
+		mov byte [do_write_msg],1
+.not_verbose:
+		call read_ddc			; read Display Data Channel
+		call read_fsc
+		call read_apm			; get APM status
+		cmp word [ReadInfo],1
+		jb .no_disk_read
+		call read_hd			; get crc of 1st hd block
+.no_disk_read:
+		call read_kbd
+		call read_vbe_modes		; get VBE2 mode support
+		mov si,lxrc_data + 1
+		call xwritestr
+		mov si,crlf_msg
+		call xwritestr
+.done:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; read from disk, ask for disk change, if necessary
+
+;       EAX     - Linear sector number
+;       ES:BX   - Target buffer
+;       BP      - Sector count
+;
+;       (es:)bx gets updated
+
+%if IS_SYSLINUX
+
+; %define DEBUG_XXX
+
+getlinsec3:
+%ifdef DEBUG_XXX
+		mov si,txt0
+		call dump_params
+		call crlf
+%endif
+		mov cx,[DiskSize]
+		or cx,cx
+		jz getlinsec3_70		; unlimited
+
+		xor dx,dx
+		div cx
+		xchg ax,dx
+		movzx eax,ax
+
+		mov si,ax
+		add si,bp
+		sub si,cx
+		jbe getlinsec3_40
+		; split
+
+		sub bp,si
+		movzx ebp,bp
+		push ebp
+		push eax
+		push si
+		push dx
+		call getlinsec3_40
+		pop dx
+		pop bp
+		pop eax
+		pop esi
+		add eax,esi
+		movzx ebp,bp
+		inc dl
+
+getlinsec3_40:
+		push es
+		pushad
+		call disk_change
+		popad
+		pop es
+		jc kaboom
+getlinsec3_70:
+%ifdef DEBUG_XXX
+		mov si,txt1
+		call dump_params
+		mov si,txt3
+		call cwritestr
+		push ax
+		mov al,[CurrentDisk]
+		call writehex2
+		pop ax
+		call crlf
+		pushad
+		call getchar
+		popad
+%endif
+		call getlinsec
+		ret
+
+%ifdef DEBUG_XXX
+dump_params:
+		push eax
+		call cwritestr
+		mov ax,es
+		call writehex4
+		mov si,txt2
+		call cwritestr
+		mov ax,bx
+		call writehex4
+		mov si,txt3
+		call cwritestr
+		pop eax
+		push eax
+		call writehex8
+		mov si,txt3
+		call cwritestr
+		mov ax,bp
+		call writehex4
+		pop eax
+		ret
+
+txt0		db 'linsec3: ', 0
+txt1		db 'linsec:  ', 0
+txt2		db ':', 0
+txt3		db ', ', 0
+
+%include "writehex.inc"
+
+%endif
+
+boot_disk_msg1	db ''
+
+; dl: new disk
+; return: CF = 1 -> error
+disk_change:
+		cmp dl,[CurrentDisk]
+		jz disk_change_90
+
+		mov [CurrentDisk],dl
+		movzx eax,dl
+		mov [gfx_user_info_0],eax
+		add dl,'1'
+		mov [boot_disk_msg0],dl
+		mov [boot_ndisk_msg0],dl
+
+disk_change_20:
+		cmp byte [gfx_ok],0
+		jz disk_change_40
+		mov al,3
+		xor di,di
+		xor si,si
+		call gfx_infobox
+
+		jmp disk_change_50
+disk_change_40:
+		mov si,clrln_msg
+		call cwritestr
+		mov si,boot_disk_msg
+		call cwritestr
+		call wait_for_key
+		mov si,clrln_msg
+		call cwritestr
+disk_change_50:
+		xor eax,eax
+		mov bp,1
+		push bx
+		call getlinsec
+		pop bx
+		mov eax,[es:bx+27h]
+		sub eax,[bxVolumeID]
+		movzx edx,byte [CurrentDisk]
+		cmp eax,edx
+		jz disk_change_90
+		mov [gfx_user_info_1],eax
+
+		cmp byte [gfx_ok],0
+		jz disk_change_70
+		mov al,4
+		xor di,di
+		xor si,si
+		call gfx_infobox
+
+		jmp disk_change_50
+disk_change_70:
+		mov si,clrln_msg
+		call cwritestr
+		mov si,boot_ndisk_msg
+		call cwritestr
+;		mov eax,[es:bx+27h]
+;		call writehex8
+		call wait_for_key
+		mov si,clrln_msg
+		call cwritestr
+
+		jmp disk_change_20
+disk_change_90:
+		ret
+
+%endif
+
--- ui.inc
+++ ui.inc
@@ -16,6 +16,15 @@
 ;
 		call parse_config		; Parse configuration file
 no_config_file:
+
+%ifdef WITH_GFX
+		; vbe things and such
+		call get_bios_info
+
+		; build gfx menu
+		call gfx_setup_menu
+%endif
+
 ;
 ; Check whether or not we are supposed to display the boot prompt.
 ;
@@ -26,9 +35,27 @@
 		jz auto_boot			; If neither, default boot
 
 enter_command:
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		mov di,command_line
+		mov cx,max_cmd_len
+		xor ax,ax
+		xchg ax,[KbdTimeOut]		; only the first time
+		call gfx_input
+		cmp ax,1
+		jnz load_kernel
+.nogfx:
+%endif
+
 		mov si,boot_prompt
 		call cwritestr
 
+%ifdef WITH_GFX
+		call show_vmode
+%endif
+
 		mov byte [FuncFlag],0		; <Ctrl-F> not pressed
 		mov di,command_line
 ;
@@ -53,6 +80,11 @@
 						; know the appropriate DX value
 time_loop:	push cx
 tick_loop:	push dx
+
+%ifdef WITH_GFX
+		call chk_update
+%endif
+
 		call pollchar
 		jnz get_char_pop
 		mov dx,[BIOS_timer]		; Get time "of day"
@@ -139,6 +171,12 @@
 		sub al,59			; F1
 		jb short get_char_2
 show_help:	; AX = func key # (0 = F1, 9 = F10)
+
+%ifdef WITH_GFX
+		call process_fkeys
+		jnc get_char_2
+%endif
+
 		push di				; Save end-of-cmdline pointer
 		shl ax,FILENAME_MAX_LG2		; Convert to pointer
 		add ax,FKeyName
@@ -190,6 +228,17 @@
 		stosb
 
 load_kernel:					; Load the kernel now
+
+%if IS_ISOLINUX
+		test byte [gfx_user_note],1
+		jz .noreload
+		pushad
+		; Maybe clear Files, too?
+		call get_fs_structures
+		popad
+.noreload:
+%endif
+
 ;
 ; First we need to mangle the kernel name the way DOS would...
 ;
@@ -309,6 +358,18 @@
 		push di
                 call unmangle_name              ; Get human form
 		mov si,err_notfound		; Complain about missing kernel
+
+%ifdef WITH_GFX
+		cmp byte [gfx_ok],0
+		jz .nogfx
+		pop di
+		mov al,2
+		call gfx_infobox
+		mov si,no_msg
+		jmp abort_load
+.nogfx:
+%endif
+
 		call cwritestr
 		pop si				; KernelCName
                 call cwritestr
@@ -359,9 +420,21 @@
 		push word real_mode_seg
 		pop es
 		mov di,cmd_line_here
+
+%ifdef WITH_GFX
+		; gfx code includes them
+		cmp byte [gfx_ok],0
+		jnz .isgfx
+%endif
+
 		mov si,VKernelBuf+vk_append
 		mov cx,[VKernelBuf+vk_appendlen]
 		rep movsb
+
+%ifdef WITH_GFX
+.isgfx:
+%endif
+
 		mov [CmdLinePtr],di		; Where to add rest of cmd
 		pop es
                 pop di                          ; DI -> KernelName
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin