Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37772748
en ru br
Репозитории ALT
S:1.62-alt4.1.qa1
5.1: 1.62-alt4.1
4.1: 1.62-alt4.1
4.0: 1.62-alt4
3.0: 1.62-alt4
www.altlinux.org/Changes

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

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

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


diff -Naur syslinux-1.62.orig/add_crc syslinux-1.62/add_crc
--- syslinux-1.62.orig/add_crc	1970-01-01 03:00:00 +0300
+++ syslinux-1.62/add_crc	2003-02-25 13:52:09 +0300
@@ -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*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;
+
diff -Naur syslinux-1.62.orig/fixofs syslinux-1.62/fixofs
--- syslinux-1.62.orig/fixofs	1970-01-01 03:00:00 +0300
+++ syslinux-1.62/fixofs	2003-02-25 13:52:09 +0300
@@ -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;
diff -Naur syslinux-1.62.orig/gfxlogo.inc syslinux-1.62/gfxlogo.inc
--- syslinux-1.62.orig/gfxlogo.inc	1970-01-01 03:00:00 +0300
+++ syslinux-1.62/gfxlogo.inc	2003-02-25 13:52:41 +0300
@@ -0,0 +1,495 @@
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; gfx stuff
+;
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+; != 0 -> everything's fine
+; note: moved to ldlinux.asm/isolinux.asm
+; gfx_ok			db 0
+
+			align 4, db 0
+; the memory area we are working with
+gfx_mem			dd 0		; linear address
+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_entries	db 0
+gfx_menu_tmp		equ mi_buf	; a reasonably sized buffer
+gfx_menu_def		zb 13
+gfx_menu_entry		zb 13 * gfx_menu_max_entries
+gfx_args_entry		zb 1 * 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
+
+; system config data
+gfx_sysconfig		equ $
+gfx_sc_vmode		db 0
+gfx_sc_modes		db 0
+gfx_bootloader		db 1
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; must not change registers!
+;
+gfx_get_sysconfig:
+		push ax
+
+		mov al,[video_mode]
+		mov [gfx_sc_vmode],al
+
+		mov al,3
+%if 0
+		mov al,1
+		cmp word [fb_mode_0],byte 0
+		setnz ah
+		shl ah,1
+		or al,ah
+%endif
+		cmp word [fb_mode_1],byte 0
+		setnz ah
+		shl ah,2
+		or al,ah
+		cmp word [fb_mode_2],byte 0
+		setnz ah
+		shl ah,3
+		or al,ah
+		mov [gfx_sc_modes],al
+
+		cmp byte [wants_update],0
+		setnz al
+		shl al,7
+		or [gfx_sc_vmode],al
+
+		pop ax
+		ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_set_sysconfig:
+		push ax
+		mov al,[gfx_sc_vmode]
+		test al,80h
+		setnz ah
+		mov [wants_update],ah
+		and al,0fh
+		mov [video_mode],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
+
+		; 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],40000h
+
+		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]
+		mov ebx,[gfx_mem_free]
+		mov ecx,[gfx_mem_max]
+		mov dx,cs
+
+		mov si,gfx_sysconfig
+		call far [gfx_bc_init]
+		jc gfx_init_80
+
+		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]
+		mov [gfx_menu_entries],al
+		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
+		call unmangle_name
+		pop ds
+		pop si
+		pop di
+		add di,13
+		inc si
+		cmp si,byte gfx_menu_max_entries
+		jae gfx_setup_menu_40
+		cmp si,[VKernelCtr]
+		jb gfx_setup_menu_20
+
+gfx_setup_menu_40:
+		mov si,gfx_menu_def
+		mov di,gfx_menu_entry
+		mov bx,gfx_args_entry
+		mov al,[gfx_menu_entries]
+		mov ah,0xff
+		mov dx,13
+		mov cx,1
+
+		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]
+		add eax,edx
+		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
+
+		push dword [gfx_mem]
+		call gfx_l2so
+		pop bx
+		pop es
+
+		cmp dword [es:bx],0b2d97f00h	; header.magic_id
+		jnz gfx_read_file_90
+		mov al,[es:bx+4]		; header.version
+		cmp al,1
+		jb gfx_read_file_90
+		cmp al,3
+		ja gfx_read_file_90
+
+		mov eax,[es:bx+8]
+		or eax,eax
+		jz gfx_read_file_90
+		add eax,[gfx_mem]
+		test al,0fh
+		jnz gfx_read_file_90
+		shr eax,4
+		mov [gfx_bc_jt+2],ax
+
+		mov byte [gfx_ok],1
+
+gfx_read_file_90:
+		pop es
+		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
+
diff -Naur syslinux-1.62.orig/isolinux.asm syslinux-1.62/isolinux.asm
--- syslinux-1.62.orig/isolinux.asm	2001-04-24 22:36:14 +0400
+++ syslinux-1.62/isolinux.asm	2003-02-25 13:52:36 +0300
@@ -23,6 +23,8 @@
 ; %define DEBUG_TRACERS			; Uncomment to get debugging tracers
 ; %define DEBUG_MESSAGES		; Uncomment to get debugging messages
 
+%define do_test 0
+
 %ifdef DEBUG_TRACERS
 
 %macro TRACER	1
@@ -164,7 +166,7 @@
 ; 5000h - real_mode_seg
 ;
 vk_seg          equ 4000h		; Virtual kernels
-xfer_buf_seg	equ 3000h		; Bounce buffer for I/O to high mem
+xfer_buf_seg	equ 8000h		; Bounce buffer for I/O to high mem
 comboot_seg	equ 2000h		; COMBOOT image loading zone
 
 ;
@@ -365,6 +367,15 @@
 		alignb open_file_t_size
 Files		resb MAX_OPEN*open_file_t_size
 
+		alignb 4
+; VBE2 buffer
+vbe_buf		resb 200h
+; for DDC info
+ddc_buf		resb 80h
+; VBE mode info & disk buffer 
+mi_buf		resb 200h   
+
+
 		section .text
                 org 7C00h
 ;;
@@ -429,6 +440,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
@@ -437,6 +463,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
@@ -457,7 +486,15 @@
 		call crlf
 %endif
 
+%endif
+
+
 found_drive:
+
+%if 0
+		; We cannot handle != 2k sectors anyway and
+		; some BIOSes don't like that call either.
+
 		; Get drive information
 		mov ah,48h
 		mov dl,[DriveNo]
@@ -483,6 +520,8 @@
 		call crlf
 %endif
 
+%endif
+
 load_image:
 		; Some BIOSes apparently have limitations on the size 
 		; that may be loaded (despite the El Torito spec being very
@@ -555,6 +594,9 @@
 %endif
 		jmp all_read			; Jump to main code
 
+%if 0
+		; does not work anyway, see above
+
 		; INT 13h, AX=4B01h, DL=7Fh failed.  Try to scan the
 		; entire 80h-FFh from the end.
 spec_query_failed:
@@ -588,6 +630,7 @@
 .still_broken:	dec dx
 		cmp dl, 80h
 		jnb .test_loop
+%endif
 
 fatal_error:
 		mov si,nothing_msg
@@ -740,9 +783,12 @@
 .try:		pushad
 		int 13h
 		jc .error
+.noerror:
 		add sp,byte 8*4			; Clean up stack
 		ret
-.error:		mov [DiskError],ah		; Save error code
+.error:		or ah,ah
+		jz .noerror
+		mov [DiskError],ah		; Save error code
 		popad
 		dec byte [RetryCount]
 		jnz .try
@@ -770,6 +816,16 @@
 		mov fs,ax
 		mov gs,ax
 		sti
+
+		cmp byte [gfx_ok],0
+		jz kaboom_nogfx
+		mov si,err_failed_gfx
+		xor di,di
+		mov al,1
+		call gfx_infobox
+		call gfx_done
+		call do_reboot
+kaboom_nogfx:
 		mov si,err_bootfailed
 		call cwritestr
 		call getchar
@@ -803,9 +859,11 @@
 nothing_msg:	db 'Failed to access CD-ROM device; boot failed.', CR, LF, 0
 checkerr_msg:	db 'Image checksum error, sorry...', CR, LF, 0
 
+err_failed_gfx	db 'Error reading boot CD.', 0
 err_bootfailed	db CR, LF, 'Boot failed: press a key to retry...'
 bailmsg		equ err_bootfailed
 crlf_msg	db CR, LF, 0
+gfx_ok		db 0
 
 ;
 ; El Torito spec packet
@@ -1019,6 +1077,12 @@
 		inc al
 		loop mkkeymap
 
+		test byte [KbdFlags],3
+		jpe do_nogfx_10			; left xor right shift: skip BIOS calls/no gfx
+		mov byte [do_nogfx],1
+		mov byte [no_fkeys],1		; no special F-key processing
+do_nogfx_10:
+
 ;
 ; Now, we need to sniff out the actual filesystem data structures.
 ; mkisofs gave us a pointer to the primary volume descriptor
@@ -1120,6 +1184,14 @@
 		je near pc_say
 		cmp ax,'lo'			; LOcalboot
 		je pc_localboot
+		cmp ax,'fr'			; FRamebuffer
+		je near pc_fb
+		cmp ax,'re'			; REadinfo
+		je near pc_info
+		cmp ax,'ve'			; VErbose
+		je near pc_verbose
+		cmp ax,'gf'			; GFxboot
+		je near pc_gfxboot
 		cmp al,'f'			; F-key
 		jne parse_config
 		jmp pc_fkey
@@ -1128,7 +1200,7 @@
 		call getline
 		xor al,al
 		stosb				; null-terminate
-		jmp short parse_config
+		jmp near parse_config
 
 pc_append:      cmp word [VKernelCtr],byte 0	; "append" command
 		ja pc_append_vk
@@ -1175,6 +1247,9 @@
 
 pc_display:	call pc_getfile			; "display" command
 		jz parse_config_2		; File not found?
+		cmp byte [gfx_ok],0
+		jnz parse_config_2
+		; don't load if we have a graphics image
 		call get_msg_file		; Load and display file
 		jmp short parse_config_2
 
@@ -1183,23 +1258,59 @@
 		mov [ForcePrompt],bx
 		jmp short parse_config_2
 
+pc_fb:		call getint			; "framebuffer" command
+		jc parse_config_2
+		mov [FrameBuffer],bx
+		call skipspace
+		jc parse_config_2
+		call ungetc
+		call getint
+		jc parse_config_2
+		mov [FrameBufferBits],bx
+		jmp short parse_config_2
+
+pc_info:	call getint			; "readinfo" command
+		jc parse_config_2
+		mov [ReadInfo],bx
+		jmp short parse_config_2
+
+pc_verbose:	call getint			; "verbose" command
+		jc parse_config_2
+		mov [do_write_msg],bl
+		jmp short parse_config_2
+
+pc_gfxboot:	call pc_getfile			; "gfxboot" command
+		jz parse_config_2		; File not found?
+		cmp byte [do_nogfx],0
+		jnz parse_config_2
+		push si
+		mov si,load_gfx_msg
+		call cwritestr
+		pop si
+		call gfx_init			; Load and display file
+		cmp byte [gfx_ok],0
+		jnz parse_config_2
+		mov si,crlf_msg
+		call cwritestr
+		jmp short parse_config_2
+
 pc_implicit:    call getint                     ; "implicit" command
                 jc parse_config_2
                 mov [AllowImplicit],bx
-                jmp short parse_config_2
+                jmp near parse_config_2
 
 pc_serial:	call getint			; "serial" command
-		jc parse_config_2
+		jc near parse_config_2
 		push bx				; Serial port #
 		call skipspace
-		jc parse_config_2
+		jc near parse_config_2
 		call ungetc
 		call getint
 		jnc .valid_baud
 		mov ebx,DEFAULT_BAUD		; No baud rate given
 .valid_baud:	pop di				; Serial port #
 		cmp ebx,byte 75
-		jb parse_config_2		; < 75 baud == bogus
+		jb near parse_config_2		; < 75 baud == bogus
 		mov eax,BAUD_DIVISOR
 		cdq
 		div ebx
@@ -1336,7 +1447,43 @@
 end_config_file:
 		call commit_vk			; Commit any current vkernel
 no_config_file:
+
+; 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.
 ;
+		inc byte [no_fkeys]
+		cmp word [ReadInfo],0
+		jz skip_bios_calls
+		dec byte [no_fkeys]
+		mov al,[KbdFlags]
+		and al,3
+		jpo skip_bios_calls		; left xor right shift: skip BIOS calls
+		jz no_verbose			; !(left and right shift)
+		mov byte [do_write_msg],1
+no_verbose:
+		call read_ddc			; read Display Data Channel
+		call read_fsc
+		call read_apm			; get APM status
+		cmp word [ReadInfo],1
+		jb skip_read_hd
+		call read_hd			; get crc of 1st hd block
+skip_read_hd:
+		call read_kbd
+		call read_vbe_modes		; get VBE2 mode support
+		mov si,lxrc_data + 1
+		call xwritestr
+		mov si,crlf_msg
+		call xwritestr
+skip_bios_calls:
+
+		call chk_update
+
+		cmp byte [gfx_ok],0
+		jz check_for_key
+		call gfx_setup_menu
+
 ; Check whether or not we are supposed to display the boot prompt.
 ;
 check_for_key:
@@ -1346,8 +1493,21 @@
 		jz near auto_boot		; If neither, default boot
 
 enter_command:
+		cmp byte [gfx_ok],0
+		jz enter_command_10
+		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
+		jz enter_command_10
+		jmp load_kernel
+enter_command_10:
+
 		mov si,boot_prompt
 		call cwritestr
+		call show_vmode
 
 		mov byte [FuncFlag],0		; <Ctrl-F> not pressed
 		mov di,command_line
@@ -1372,6 +1532,7 @@
 						; know the appropriate DX value
 time_loop:	push cx
 tick_loop:	push dx
+		call chk_update
 		call pollchar
 		jnz get_char_pop
 		mov dx,[BIOS_timer]		; Get time "of day"
@@ -1443,6 +1604,10 @@
 		jb get_char_2
 		shr ax,8
 show_help:	; AX = func key # (0 = F1, 9 = F10)
+
+		call process_fkeys
+		jnc fk_done
+
 		mov cl,al
 		shl ax,FILENAME_MAX_LG2		; Convert to offset
 		mov bx,1
@@ -1468,8 +1633,9 @@
 		mov byte [di],0			; Null-terminate command line
 		mov si,command_line
 		call cwritestr			; Write command line so far
+fk_done:
 		pop di
-		jmp short get_char_2
+		jmp near get_char_2
 auto_boot:
 		mov si,default_cmd
 		mov di,command_line
@@ -1483,6 +1649,8 @@
 		xor al,al			; Store a final null
 		stosb
 
+
+		call chk_update
 load_kernel:					; Load the kernel now
 ;
 ; First we need to mangle the kernel name the way DOS would...
@@ -1530,7 +1698,7 @@
 ; Not a "virtual kernel" - check that's OK and construct the command line
 ;
                 cmp word [AllowImplicit],byte 0
-                je bad_implicit
+                je near bad_implicit
                 push es
                 push si
                 push di
@@ -1574,6 +1742,14 @@
 		push di
                 call unmangle_name              ; Get human form
 		mov si,err_notfound		; Complain about missing kernel
+		cmp byte [gfx_ok],0
+		jz bad_kernel_no_gfx
+		pop di
+		mov al,0
+		call gfx_infobox
+		mov si,no_msg
+		jmp abort_load
+bad_kernel_no_gfx:
 		call cwritestr
 		pop si				; KernelCName
                 call cwritestr
@@ -1688,8 +1864,12 @@
 kernel_sane:	push ax
 		push dx
 		push si
+		cmp byte [gfx_ok],0
+		jnz kernel_sane_gfx
+		call hide_vmode
 		mov si,loading_msg
                 call cwritestr
+kernel_sane_gfx:
 ;
 ; Now start transferring the kernel
 ;
@@ -1824,6 +2004,38 @@
                 mov si,KernelCName       	; Unmangled kernel name
                 mov cx,[KernelCNameLen]
                 rep movsb
+
+;
+; Insert special linuxrc data here
+;
+		cmp byte [lxrc_data1],0
+		jz no_lxrc_data
+		mov si,lxrc_data
+		mov ax,[lxrc_vga_ptr]
+		sub ax,si
+		add ax,di
+		mov [vga_txt_ofs],ax
+		mov [vga_txt_seg],es
+store_lxrc_data:
+		lodsb
+		or al,al
+		jz no_lxrc_data
+		stosb
+		jmp store_lxrc_data
+no_lxrc_data:		
+
+		mov si,expert_txt
+store_expert_data:
+		lodsb
+		or al,al
+		jz expert_data_end
+		stosb
+		jmp store_expert_data
+expert_data_end:
+		lea ax,[di-1]
+		mov [expert_txt_ofs],ax
+		mov [expert_txt_seg],es
+
                 mov al,' '                      ; Space
                 stosb
 
@@ -1831,6 +2043,17 @@
                 mov si,[CmdOptPtr]              ; Options from user input
 		mov cx,(kern_cmd_len+3) >> 2
 		rep movsd
+
+; 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
+
 ;
 ; Scan through the command line for anything that looks like we might be
 ; interested in.  The original version of this code automatically assumed
@@ -1851,6 +2074,8 @@
 		je is_vga_cmd
                 cmp eax,'mem='
 		je is_mem_cmd
+                cmp eax,'SLX='
+		je is_slx_cmd
                 push es                         ; Save ES -> real_mode_seg
                 push cs
                 pop es                          ; Set ES <- normal DS
@@ -1871,6 +2096,7 @@
                 dec si
                 jmp short get_next_opt
 is_vga_cmd:
+		inc byte [cs:vga_parm_cnt]
                 add si,byte 4
                 mov eax,[si]
                 mov bx,-1
@@ -1894,11 +2120,55 @@
 		sub ebx,HIGHMEM_SLOP
 		mov [cs:HighMemSize],ebx
 		jmp short skip_this_opt
+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
 cmdline_end:
                 push cs                         ; Restore standard DS
                 pop ds
 		sub si,cmd_line_here
 		mov [CmdLineLen],si		; Length including final null
+
+		call boot_hd
+
+		and word [InitRDClust], byte 0
+                test byte [initrd_flag],1
+                jz kernel_noinitrd
+
+                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
+		jz near initrd_notthere
+		mov [initrd_ptr],si		; Save cluster pointer
+		mov [es:su_ramdisklen1],ax	; Ram disk length
+		mov [es:su_ramdisklen2],dx
+		div word [ClustSize]
+		and dx,dx			; Round up
+		setnz dl
+		movzx dx,dl
+		add ax,dx
+		mov [InitRDClust],ax		; Ramdisk clusters
+
+kernel_noinitrd:
+		cmp byte [gfx_ok],0
+		jz kernel_nogfx
+		mov ax,[KernelClust]
+		add ax,[InitRDClust]
+		mov si,KernelCName
+		call gfx_progress_init
+kernel_nogfx:
+
 ;
 ; Now check if we have a large kernel, which needs to be loaded high
 ;
@@ -1930,10 +2200,13 @@
 ; jumping to it.
 ;
 read_kernel:
+		cmp byte [gfx_ok],0
+		jnz read_kernel_nogfx
                 mov si,KernelCName		; Print kernel name part of
                 call cwritestr                  ; "Loading" message
                 mov si,dotdot_msg		; Print dots
                 call cwritestr
+read_kernel_nogfx:
 
                 mov eax,[HighMemSize]
 		sub eax,100000h			; Load address
@@ -1957,8 +2230,12 @@
                 push word xfer_buf_seg		; Transfer buffer segment
                 pop es
 high_load_loop: 
+		cmp byte [gfx_ok],0
+		jnz high_load_loop_nogfx
                 mov si,dot_msg			; Progress report
                 call cwritestr
+high_load_loop_nogfx:
+		call chk_update
                 call abort_check
                 mov cx,[KernelClust]
 		cmp cx,[ClustPerMoby]
@@ -1966,6 +2243,10 @@
 		mov cx,[ClustPerMoby]
 high_last_moby:
 		sub [KernelClust],cx
+		cmp byte [gfx_ok],0
+		jz high_last_moby_nogfx
+		call gfx_progress_update
+high_last_moby_nogfx:
 		xor bx,bx			; Load at offset 0
                 pop si                          ; Restore cluster pointer
 		call getfssec
@@ -1986,39 +2267,22 @@
                 mov ax,real_mode_seg		; Set to real mode seg
                 mov es,ax
 
-                mov si,dot_msg
-                call cwritestr
+		cmp byte [gfx_ok],0
+		jnz high_load_done_gfx
+		mov si,clrln_msg
+		call cwritestr
+high_load_done_gfx:
+		
 
-		call crlf
 ;
 ; 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
 ;
 load_initrd:
-                test byte [initrd_flag],1
-                jz nk_noinitrd
-                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
-		jz initrd_notthere
-		mov [initrd_ptr],si		; Save cluster pointer
-		mov [es:su_ramdisklen1],ax	; Ram disk length
-		mov [es:su_ramdisklen2],dx
-		div word [ClustSize]
-		and dx,dx			; Round up
-		setnz dl
-		movzx dx,dl
-		add ax,dx
-		mov [InitRDClust],ax		; Ramdisk clusters
+                cmp word [initrd_ptr],byte 0
+                jz near nk_noinitrd
+
 		mov edx,[HighMemSize]		; End of memory
 		mov eax,HIGHMEM_MAX		; Limit imposed by kernel
 		cmp edx,eax
@@ -2032,6 +2296,14 @@
 		jmp short initrd_end
 
 initrd_notthere:
+		cmp byte [gfx_ok],0
+		jz initrd_notthere_nogfx
+		mov si,err_noinitrda
+		mov di,InitRDCName
+		mov al,1
+		call gfx_infobox
+		call do_reboot
+initrd_notthere_nogfx:
                 mov si,err_noinitrd
                 call cwritestr
                 mov si,InitRDCName
@@ -2039,18 +2311,124 @@
                 mov si,crlf_msg
                 jmp abort_load
 
-no_high_mem:    mov si,err_nohighmem		; Error routine
+no_high_mem:
+		cmp byte [gfx_ok],0
+		jz no_high_mem_nogfx
+		mov si,err_nohighmem
+		xor di,di
+		mov al,1
+		call gfx_infobox
+		call do_reboot
+no_high_mem_nogfx:
+		mov si,err_nohighmem		; Error routine
                 jmp abort_load
 
 initrd_end:
 nk_noinitrd:
+
+		cmp byte [gfx_ok],0
+		jz initrd_end_nogfx
+		call gfx_progress_done
+
+                call abort_check        	; Last chance!!
+		jmp update_disk_05
+
+initrd_end_nogfx:
+
 ;
 ; Abandon hope, ye that enter here!  We do no longer permit aborts.
 ;
                 call abort_check        	; Last chance!!
 
-		mov si,ready_msg
+		mov si,clrln_msg
+		call cwritestr
+
+update_disk_05:
+
+;
+; if the user has an update disk, give him a chance to insert it now
+;
+		cmp byte [wants_update],0
+		jnz update_disk_10
+		cmp byte [gfx_ok],0
+		jnz update_disk_90
+		mov si,crlf_msg
+		call cwritestr
+		jmp update_disk_90
+update_disk_10:
+		cmp byte [gfx_ok],0
+		jz update_disk_20
+		mov al,0
+		mov si,upd_msg_1a
+		xor di,di
+		call gfx_infobox
+		jmp update_disk_90
+update_disk_20:
+		mov si,upd_msg_1
 		call cwritestr
+		call wait_for_key
+update_disk_90:	
+		call gfx_done
+
+		push word real_mode_seg
+		pop fs
+
+		mov al,[wants_serial]
+		shl al,1
+		or al,[wants_update]
+		shl al,1
+		cmp byte [video_mode],0
+		setz ah
+		or al,ah
+		les bx,[expert_txt_ofs]
+		add [es:bx],al
+
+		cmp byte [vga_parm_cnt],2	; override via cmdline
+		jae vid_mode_90
+		cmp word [lxrc_vga_ptr],0
+		jz vid_mode_90
+		les di,[vga_txt_ofs]
+		mov cx,[lxrc_vga_len]
+		or cx,cx
+		jz vid_mode_90
+		cmp byte [video_mode],0
+		jz vid_mode_50
+		add di,cx
+		sub di,4
+
+		mov al,[video_mode]
+		mov cx,[fb_mode_0]
+		dec al
+		jz vid_mode_30		; 1
+		mov cx,[fb_mode_1]
+		dec al
+		jz vid_mode_30		; 2
+		mov cx,[fb_mode_2]
+		dec al
+		jnz vid_mode_50		; 0, > 3
+vid_mode_30:
+		or cx,cx
+		jz vid_mode_50
+
+		mov si,di
+		add ch,2
+		mov [fs:bs_vidmode],cx
+		mov al,ch
+		push ds
+		push es
+		pop ds
+		push cx
+		call byte_to_hex
+		pop ax
+		call byte_to_hex
+		pop ds
+		jmp vid_mode_90
+vid_mode_50:
+		mov al,' '
+		rep stosb
+		mov word [fs:bs_vidmode],-1
+vid_mode_90:
+
 
 		call vgaclearmode		; We can't trust ourselves after this
 
@@ -2186,6 +2564,7 @@
 		mov dx,03F2h
 		xor al,al
 		call slow_out
+
 ;
 ; If we're debugging, wait for a keypress so we can read any debug messages
 ;
@@ -2193,6 +2572,11 @@
                 xor ax,ax
                 int 16h
 %endif
+
+%if do_test
+		jmp $
+%endif
+
 ;
 ; Set up segment registers and the Linux real-mode stack
 ; Note: bx == the real mode segment
@@ -2397,7 +2781,11 @@
 		dd 00009300h		; present, dpl 0, cover 64K
 bcopy_gdt_size:	equ $-bcopy_gdt
 
-bcopy:		push eax
+bcopy:
+%if do_test
+		ret
+%endif
+		push eax
 		pushf			; Saves, among others, the IF flag
 		push gs
 		push fs
@@ -2686,6 +3074,60 @@
 		ret
 
 ;
+; 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
+		mov dl,7fh			; 7fh: all drives
+		int 13h				; terminate floppy emulation
+		pop es
+detach_cd_90:
+		ret
+
+;
+; boot mbr, if SLXOption says so
+;
+boot_hd:
+		mov ax,[SLXOption]
+		test al,2		; should we do it?
+		jz boot_hd_90
+		push es
+		shr ax,2
+		push ax
+		call detach_cd
+		pop dx
+		mov ax,0201h
+		xor cx,cx
+		mov es,cx
+		inc cx
+		xor dh,dh
+		mov bx,trackbuf
+		push bx
+		int 13h
+		pop si
+		jc boot_hd_80
+		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:
+		pop es
+boot_hd_90:
+		ret
+
+;
 ; Load RAM disk into high memory
 ;
 loadinitrd:
@@ -2696,6 +3138,8 @@
                 mov edi,[InitRDat]		; initrd load address
 		mov [es:su_ramdiskat],edi	; Offset for ram disk
 		push si
+		cmp byte [gfx_ok],0
+		jnz rd_load_loop
                 mov si,loading_msg
                 call cwritestr
                 mov si,InitRDCName		; Write ramdisk name
@@ -2703,9 +3147,13 @@
                 mov si,dotdot_msg		; Write dots
                 call cwritestr
 rd_load_loop:	
+		cmp byte [gfx_ok],0
+		jnz rd_load_loop_gfx
 		mov si,dot_msg			; Progress report
                 call cwritestr
+rd_load_loop_gfx:
 		pop si				; Restore cluster pointer
+		call chk_update
                 call abort_check
                 mov cx,[InitRDClust]
 		cmp cx,[ClustPerMoby]
@@ -2713,6 +3161,10 @@
 		mov cx,[ClustPerMoby]
 rd_last_moby:
 		sub [InitRDClust],cx
+		cmp byte [gfx_ok],0
+		jz rd_last_moby_nogfx
+		call gfx_progress_update
+rd_last_moby_nogfx:
 		xor bx,bx			; Load at offset 0
                 push word xfer_buf_seg		; Bounce buffer segment
 		pop es
@@ -2730,7 +3182,13 @@
 		jne rd_load_loop		; Apparently not
 rd_load_done:
                 pop si                          ; Clean up the stack
-		call crlf
+		cmp byte [gfx_ok],0
+		jnz rd_load_done_gfx
+		push si
+		mov si,clrln_msg
+		call cwritestr
+		pop si
+rd_load_done_gfx:
                 pop es                          ; Restore original ES
                 ret
 
@@ -2738,6 +3196,10 @@
 ; abort_check: let the user abort with <ESC> or <Ctrl-C>
 ;
 abort_check:
+		cmp byte [gfx_ok],0
+		jz abort_check_nogfx
+		ret
+abort_check_nogfx:
 		call pollchar
 		jz ac_ret1
 		pusha
@@ -3439,7 +3901,8 @@
 ; getchar: Read a character from keyboard or serial port
 ;
 getchar:
-.again:		mov ah,1		; Poll keyboard
+.again:		call chk_update
+		mov ah,1		; Poll keyboard
 		int 16h
 		jnz .kbd		; Keyboard input?
 		mov bx,[SerialPort]
@@ -4192,6 +4655,18 @@
 linear_color	db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
 UsingVGA	db 0
 
+
+;
+; most of the new stuff is now in suse.inc
+;
+%include	"suse.inc"
+
+;
+; add gfx stuff
+;
+%include	"gfxlogo.inc"
+
+
 ; ----------------------------------------------------------------------------------
 ;  Begin data section
 ; ----------------------------------------------------------------------------------
@@ -4223,7 +4698,8 @@
 		db 'booting, and I will take your word for it.', 0Dh, 0Ah, 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.'
@@ -4246,7 +4722,11 @@
 default_str	db 'default', 0
 default_len	equ ($-default_str)
 isolinux_dir	db '/isolinux', 0
+		zb 64
 isolinux_cfg	db 'isolinux.cfg', 0
+load_gfx_msg	db 'Loading...', 0
+no_msg		db 0
+clrln_msg	db 0dh, '                                                            ', 0dh, 0
 
 %ifdef DEBUG_MESSAGES
 dbg_rootdir_msg	db 'Root directory at LBA = ', 0
@@ -4290,6 +4770,12 @@
 		; PXELINUX specific options...
 		db 'ip' ; ipappend
 		db 'lo' ; localboot
+
+		db 'fr' ; framebuffer
+		db 're' ; readinfo
+		db 've' ; verbose
+		db 'gf' ; gfxboot
+
 		dw 0
 ;
 ; Extensions to search for (in *forward* order).
@@ -4320,6 +4806,10 @@
 A20DList	dw a20d_dunno, a20d_none, a20d_bios, a20d_kbc, a20d_fast
 A20Type		dw A20_DUNNO		; A20 type unknown
 VGAFontSize	dw 16			; Defaults to 16 byte font
+FrameBuffer	dw 0			; Add an appropriate vga= line for kernel fb's
+FrameBufferBits	dw 8			; Color depth for the fb
+ReadInfo	dw 0			; Get some info from BIOS
+SLXOption	dw 0			; control sysliux via cmdline
 ScrollAttribute	db 07h			; White on black (for text mode)
 
 ;
diff -Naur syslinux-1.62.orig/ldlinux.asm syslinux-1.62/ldlinux.asm
--- syslinux-1.62.orig/ldlinux.asm	2001-04-24 22:36:14 +0400
+++ syslinux-1.62/ldlinux.asm	2003-02-28 15:05:33 +0300
@@ -26,6 +26,8 @@
 ; 
 ; ****************************************************************************
 
+%define do_test 0
+
 ;
 ; Some semi-configurable constants... change on your own risk.  Most are imposed
 ; by the kernel.
@@ -153,7 +155,7 @@
 ;
 fat_seg		equ 5000h		; 128K area for FAT (2x64K)
 vk_seg          equ 4000h		; Virtual kernels
-xfer_buf_seg	equ 3000h		; Bounce buffer for I/O to high mem
+xfer_buf_seg	equ 8000h		; Bounce buffer for I/O to high mem
 comboot_seg	equ 2000h		; COMBOOT image loading zone
 
 ;
@@ -245,6 +247,9 @@
 trackbufsize	equ 16384		; Safe size of track buffer
 ;		trackbuf ends at 5000h
 
+; VGA font buffer at the end of memory (so loading a font works even
+; in graphics mode.)
+vgafontbuf	equ 5000h
 
 ;
 ; Constants for the xfer_buf_seg
@@ -258,7 +263,8 @@
 xbs_vgatmpbuf	equ 2*trackbufsize
 
 
-                absolute 5000h          ; Here we keep our BSS stuff
+		; leave enough room for stack (8k)
+                absolute 7000h          ; Here we keep our BSS stuff
 StackBuf	equ $			; Start the stack here (grow down - 4K)
 VKernelBuf:	resb vk_size		; "Current" vkernel
 		alignb 4
@@ -339,6 +345,15 @@
 VGAFileBufEnd	equ $
 VGAFileMBuf	resb 11			; Mangled VGA image name
 
+		alignb 4
+; VBE2 buffer
+vbe_buf		resb 200h
+; for DDC info
+ddc_buf		resb 80h
+; VBE mode info & disk buffer 
+mi_buf		resb 200h   
+
+
 		section .text
                 org 7C00h
 ;
@@ -782,6 +797,10 @@
 ; We can really only rely on a single sector having been loaded.  Hence
 ; we should load the FAT into RAM and start chasing pointers...
 ;
+		call update_fat
+		jmp near load_rest
+
+update_fat:
 		mov dx,1			; 64K
 		xor ax,ax
 		div word [bsBytesPerSec]	; sectors/64K
@@ -876,6 +895,8 @@
 have_fat12:	mov ax,nextcluster_fat12
 have_fat_type:	mov word [NextCluster],ax
 
+		ret
+
 ;
 ; Now we read the rest of LDLINUX.SYS.	Don't bother loading the first
 ; cluster again, though.
@@ -1201,6 +1222,11 @@
 		inc al
 		loop mkkeymap
 
+		test byte [KbdFlags],3
+		jpe do_nogfx_10			; left xor right shift: skip BIOS calls/no gfx
+		mov byte [do_nogfx],1
+		mov byte [no_fkeys],1		; no special F-key processing
+do_nogfx_10:
 ;
 ; Load configuration file
 ;
@@ -1232,6 +1258,16 @@
                 je near pc_implicit
 		cmp ax,'se'			; SErial
 		je near pc_serial
+		cmp ax,'fr'			; FRamebuffer
+		je near pc_fb
+		cmp ax,'re'			; REadinfo
+		je near pc_info
+		cmp ax,'ve'			; VErbose
+		je near pc_verbose
+		cmp ax,'gf'			; GFxboot
+		je near pc_gfxboot
+		cmp ax,'in'			; INitrdsize
+		je near pc_initrdsize
 		cmp al,'f'			; F-key
 		jne parse_config
 		jmp pc_fkey
@@ -1240,7 +1276,7 @@
 		call getline
 		xor al,al
 		stosb				; null-terminate
-		jmp short parse_config
+		jmp near parse_config
 
 pc_append:      cmp word [VKernelCtr],byte 0	; "append" command
 		ja pc_append_vk
@@ -1248,7 +1284,7 @@
 		call getline
                 sub di,AppendBuf
 pc_app1:        mov [AppendLen],di
-                jmp short parse_config
+                jmp near parse_config
 pc_append_vk:	mov di,VKernelBuf+vk_append	; "append" command (vkernel)
 		call getline
 		sub di,VKernelBuf+vk_append
@@ -1278,8 +1314,16 @@
 		mov [KbdTimeOut],bx
 		jmp short parse_config_2
 
+pc_initrdsize:	call getint			; "initrdsize" command
+		jc parse_config_2
+		mov [ExpInitRDClust],bx
+		jmp short parse_config_2
+
 pc_display:	call pc_getfile			; "display" command
 		jz parse_config_2		; File not found?
+		cmp byte [gfx_ok],0
+		jnz parse_config_2
+		; don't load if we have a graphics image
 		call get_msg_file		; Load and display file
 parse_config_2: jmp parse_config
 
@@ -1288,6 +1332,42 @@
 		mov [ForcePrompt],bx
 		jmp short parse_config_2
 
+pc_fb:		call getint			; "framebuffer" command
+		jc parse_config_2
+		mov [FrameBuffer],bx
+		call skipspace
+		jc parse_config_2
+		call ungetc
+		call getint
+		jc parse_config_2
+		mov [FrameBufferBits],bx
+		jmp short parse_config_2
+
+pc_info:	call getint			; "readinfo" command
+		jc parse_config_2
+		mov [ReadInfo],bx
+		jmp short parse_config_2
+
+pc_verbose:	call getint			; "verbose" command
+		jc parse_config_2
+		mov [do_write_msg],bl
+		jmp short parse_config_2
+
+pc_gfxboot:	call pc_getfile			; "gfxboot" command
+		jz parse_config_2		; File not found?
+		cmp byte [do_nogfx],0
+		jnz parse_config_2
+		push si
+		mov si,load_gfx_msg
+		call cwritestr
+		pop si
+		call gfx_init			; Load and display file
+		cmp byte [gfx_ok],0
+		jnz parse_config_2
+		mov si,crlf_msg
+		call cwritestr
+		jmp short parse_config_2
+
 pc_implicit:    call getint                     ; "implicit" command
                 jc parse_config_2
                 mov [AllowImplicit],bx
@@ -1297,14 +1377,14 @@
 		jc parse_config_2
 		push bx				; Serial port #
 		call skipspace
-		jc parse_config_2
+		jc near parse_config_2
 		call ungetc
 		call getint
 		jnc .valid_baud
 		mov ebx,DEFAULT_BAUD		; No baud rate given
 .valid_baud:	pop di				; Serial port #
 		cmp ebx,byte 75
-		jb parse_config_2		; < 75 baud == bogus
+		jb near parse_config_2		; < 75 baud == bogus
 		mov eax,BAUD_DIVISOR
 		cdq
 		div ebx
@@ -1431,6 +1511,42 @@
 end_config_file:
 		call commit_vk			; Commit any current vkernel
 no_config_file:
+
+; 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.
+;
+		inc byte [no_fkeys]
+		cmp word [ReadInfo],0
+		jz skip_bios_calls
+		dec byte [no_fkeys]
+		mov al,[KbdFlags]
+		and al,3
+		jpo skip_bios_calls		; left xor right shift: skip BIOS calls
+		jz no_verbose			; !(left and right shift)
+		mov byte [do_write_msg],1
+no_verbose:
+		call read_ddc			; read Display Data Channel
+		call read_fsc
+		call read_apm			; get APM status
+		cmp word [ReadInfo],1
+		jb skip_read_hd
+		call read_hd			; get crc of 1st hd block
+skip_read_hd:
+		call read_kbd
+		call read_vbe_modes		; get VBE2 mode support
+		mov si,lxrc_data + 1
+		call xwritestr
+		mov si,crlf_msg
+		call xwritestr
+skip_bios_calls:
+
+		call chk_update
+
+		cmp byte [gfx_ok],0
+		jz check_for_key
+		call gfx_setup_menu
 ;
 ; Check whether or not we are supposed to display the boot prompt.
 ;
@@ -1441,8 +1557,21 @@
 		jz near auto_boot		; If neither, default boot
 
 enter_command:
+		cmp byte [gfx_ok],0
+		jz enter_command_10
+		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
+		jz enter_command_10
+		jmp load_kernel
+enter_command_10:
+
 		mov si,boot_prompt
 		call cwritestr
+		call show_vmode
 
 		mov byte [FuncFlag],0		; <Ctrl-F> not pressed
 		mov di,command_line
@@ -1467,6 +1596,7 @@
 						; know the appropriate DX value
 time_loop:	push cx
 tick_loop:	push dx
+		call chk_update
 		call pollchar
 		jnz get_char_pop
 		xor ax,ax
@@ -1509,7 +1639,7 @@
 get_char_2:	jmp short get_char
 not_ascii:	mov byte [FuncFlag],0
 		cmp al,0Dh			; Enter
-		je command_done
+		je near command_done
 		cmp al,06h			; <Ctrl-F>
 		je set_func_flag
 		cmp al,08h			; Backspace
@@ -1539,6 +1669,10 @@
 		jb get_char_2
 		shr ax,8
 show_help:	; AX = func key # (0 = F1, 9 = F10)
+
+		call process_fkeys
+		jnc fk_done
+
 		mov cl,al
 		shl ax,4			; Convert to x16
 		mov bx,1
@@ -1564,8 +1698,9 @@
 		mov byte [di],0			; Null-terminate command line
 		mov si,command_line
 		call cwritestr			; Write command line so far
+fk_done:
 		pop di
-		jmp short get_char_2
+		jmp near get_char_2
 auto_boot:
 		mov si,default_cmd
 		mov di,command_line
@@ -1579,6 +1714,8 @@
 		xor al,al			; Store a final null
 		stosb
 
+
+		call chk_update
 load_kernel:					; Load the kernel now
 ;
 ; First we need to mangle the kernel name the way DOS would...
@@ -1626,7 +1763,7 @@
 ; Not a "virtual kernel" - check that's OK and construct the command line
 ;
                 cmp word [AllowImplicit],byte 0
-                je bad_implicit
+                je near bad_implicit
                 push es
                 push si
                 push di
@@ -1662,6 +1799,14 @@
 		push di
                 call unmangle_name              ; Get human form
 		mov si,err_notfound		; Complain about missing kernel
+		cmp byte [gfx_ok],0
+		jz bad_kernel_no_gfx
+		pop di
+		mov al,0
+		call gfx_infobox
+		mov si,no_msg
+		jmp abort_load
+bad_kernel_no_gfx:
 		call cwritestr
 		pop si				; KernelCName
                 call cwritestr
@@ -1765,8 +1910,12 @@
 kernel_sane:	push ax
 		push dx
 		push si
+		cmp byte [gfx_ok],0
+		jnz kernel_sane_gfx
+		call hide_vmode
 		mov si,loading_msg
                 call cwritestr
+kernel_sane_gfx:
 ;
 ; Now start transferring the kernel
 ;
@@ -1899,11 +2048,64 @@
                 mov si,KernelCName       	; Unmangled kernel name
                 mov cx,[KernelCNameLen]
                 rep movsb
+
+;
+; Insert special linuxrc data here
+;
+;		cmp byte [lxrc_data1],0
+;		jz no_lxrc_data
+;		mov si,lxrc_data
+;		mov ax,[lxrc_vga_ptr]
+;		sub ax,si
+;		add ax,di
+;		mov [vga_txt_ofs],ax
+;		mov [vga_txt_seg],es
+
+		cmp byte [lxrc_data1],0
+		jz no_lxrc_data
+		mov si,lxrc_data
+		mov ax,[lxrc_vga_ptr]
+		sub ax,si
+		add ax,di
+		mov [vga_txt_ofs],ax
+		mov [vga_txt_seg],es
+
+store_lxrc_data:
+		lodsb
+		or al,al
+		jz no_lxrc_data
+		stosb
+		jmp store_lxrc_data
+no_lxrc_data:		
+
+		mov si,expert_txt
+store_expert_data:
+		lodsb
+		or al,al
+		jz expert_data_end
+		stosb
+		jmp store_expert_data
+expert_data_end:
+		lea ax,[di-1]
+		mov [expert_txt_ofs],ax
+		mov [expert_txt_seg],es
+
                 mov al,' '                      ; Space
                 stosb
                 mov si,[CmdOptPtr]              ; Options from user input
 		mov cx,(kern_cmd_len+3) >> 2
 		rep movsd
+
+; 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
+
 ;
 %ifdef debug
                 push ds                         ; DEBUG DEBUG DEBUG
@@ -1934,6 +2136,8 @@
 		je is_vga_cmd
                 cmp eax,'mem='
 		je is_mem_cmd
+                cmp eax,'SLX='
+		je is_slx_cmd
                 push es                         ; Save ES -> real_mode_seg
                 push ss
                 pop es                          ; Set ES <- normal DS
@@ -1954,6 +2158,7 @@
                 dec si
                 jmp short get_next_opt
 is_vga_cmd:
+		inc byte [cs:vga_parm_cnt]
                 add si,byte 4
                 mov eax,[si]
                 mov bx,-1
@@ -1976,11 +2181,34 @@
 		jc skip_this_opt		; Not an integer
 		mov [cs:HighMemSize],ebx
 		jmp short skip_this_opt
+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
 cmdline_end:
                 push cs                         ; Restore standard DS
                 pop ds
 		sub si,cmd_line_here
 		mov [CmdLineLen],si		; Length including final null
+
+		call boot_hd
+		call lookup_initrd
+		jnc start_loading
+		cmp word [ExpInitRDClust],byte 0
+		jz near initrd_notthere
+
+start_loading:
+
+		cmp byte [gfx_ok],0
+		jz kernel_nogfx
+		mov ax,[KernelClust]
+		add ax,[InitRDClust]
+		mov si,KernelCName
+		call gfx_progress_init
+kernel_nogfx:
+
 ;
 ; Now check if we have a large kernel, which needs to be loaded high
 ;
@@ -2001,60 +2229,9 @@
 		movzx ax,byte [es:bs_setupsecs]	; Variable # of setup sectors
 		mov [SetupSecs],ax
 ;
-; Now see if we have an initial RAMdisk; if so, do requisite computation
-;
-                test byte [initrd_flag],1
-                jz nk_noinitrd
-                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
-		jz initrd_notthere
-		mov [initrd_ptr],si		; Save cluster pointer
-		mov [es:su_ramdisklen1],ax	; Ram disk length
-		mov [es:su_ramdisklen2],dx
-		div word [ClustSize]
-		and dx,dx			; Round up
-		setnz dl
-		movzx dx,dl
-		add ax,dx
-		mov [InitRDClust],ax		; Ramdisk clusters
-		mov edx,[HighMemSize]		; End of memory (64K chunks)
-		mov eax,HIGHMEM_MAX		; Limit imposed by kernel
-		cmp edx,eax
-		jna memsize_ok
-		mov edx,eax			; Adjust to fit inside limit
-memsize_ok:
-                xor dx,dx			; Round down to 64K boundary
-		sub edx,[es:su_ramdisklen]	; Subtract size of ramdisk
-                xor dx,dx			; Round down to 64K boundary
-                mov [InitRDat],edx		; Load address
-		call loadinitrd			; Load initial ramdisk
-		jmp short initrd_end
-
-initrd_notthere:
-                mov si,err_noinitrd
-                call cwritestr
-                mov si,InitRDCName
-                call cwritestr
-                mov si,crlf_msg
-                jmp abort_load
-
-no_high_mem:    mov si,err_nohighmem		; Error routine
-                jmp abort_load
-;
 ; About to load the kernel.  This is a modern kernel, so use the boot flags
 ; we were provided.
 ;
-nk_noinitrd:
-initrd_end:
                 mov al,[es:su_loadflags]
 		mov [LoadFlags],al
 ;
@@ -2063,15 +2240,18 @@
 ; jumping to it.
 ;
 read_kernel:
+		cmp byte [gfx_ok],0
+		jnz read_kernel_nogfx
                 mov si,KernelCName		; Print kernel name part of
                 call cwritestr                  ; "Loading" message
                 mov si,dotdot_msg		; Print dots
                 call cwritestr
+read_kernel_nogfx:
 
                 mov eax,[HighMemSize]
 		sub eax,100000h			; Load address
 		cmp eax,[KernelSize]
-		jb no_high_mem			; Not enough high memory
+		jb near no_high_mem		; Not enough high memory
 ;
 ; Move the stuff beyond the setup code to high memory at 100000h
 ;
@@ -2090,8 +2270,12 @@
                 push word xfer_buf_seg		; Transfer buffer segment
                 pop es
 high_load_loop: 
+		cmp byte [gfx_ok],0
+		jnz high_load_loop_nogfx
                 mov si,dot_msg			; Progress report
                 call cwritestr
+high_load_loop_nogfx:
+		call chk_update
                 call abort_check
                 mov cx,[KernelClust]
 		cmp cx,[ClustPerMoby]
@@ -2099,9 +2283,13 @@
 		mov cx,[ClustPerMoby]
 high_last_moby:
 		sub [KernelClust],cx
+		cmp byte [gfx_ok],0
+		jz high_last_moby_nogfx
+		call gfx_progress_update
+high_last_moby_nogfx:
 		xor bx,bx			; Load at offset 0
                 pop si                          ; Restore cluster pointer
-                call getfssec
+		call getfssec
                 push si                         ; Save cluster pointer
                 pushf                           ; Save EOF
                 xor bx,bx
@@ -2119,15 +2307,202 @@
                 mov ax,real_mode_seg		; Set to real mode seg
                 mov es,ax
 
-                mov si,dot_msg
-                call cwritestr
+		cmp byte [gfx_ok],0
+		jnz high_load_done_gfx
+                mov si,clrln_msg
+		call cwritestr
+high_load_done_gfx:
+		
+
+;
+; 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
 ;
+
+		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
+
+load_initrd:
+                cmp word [initrd_ptr],byte 0
+                jz nk_noinitrd
+
+		mov edx,[HighMemSize]		; End of memory
+		mov eax,HIGHMEM_MAX		; Limit imposed by kernel
+		cmp edx,eax
+		jna memsize_ok
+		mov edx,eax			; Adjust to fit inside limit
+memsize_ok:
+		sub edx,[es:su_ramdisklen]	; Subtract size of ramdisk
+                xor dx,dx			; Round down to 64K boundary
+                mov [InitRDat],edx		; Load address
+		call loadinitrd			; Load initial ramdisk
+		jmp short initrd_end
+
+initrd_notthere:
+		cmp byte [gfx_ok],0
+		jz initrd_notthere_nogfx
+		mov si,err_noinitrda
+		mov di,InitRDCName
+		mov al,1
+		call gfx_infobox
+		call do_reboot
+initrd_notthere_nogfx:
+                mov si,err_noinitrd
+                call cwritestr
+                mov si,InitRDCName
+                call cwritestr
+                mov si,crlf_msg
+                jmp abort_load
+
+no_high_mem:
+		cmp byte [gfx_ok],0
+		jz no_high_mem_nogfx
+		mov si,err_nohighmem
+		xor di,di
+		mov al,1
+		call gfx_infobox
+		call do_reboot
+no_high_mem_nogfx:
+		mov si,err_nohighmem		; Error routine
+                jmp abort_load
+
+initrd_end:
+nk_noinitrd:
+
+		cmp byte [gfx_ok],0
+		jz initrd_end_nogfx
+		call gfx_progress_done
+
+                call abort_check        	; Last chance!!
+		jmp update_disk_05
+
+initrd_end_nogfx:
+
+
 ; Abandon hope, ye that enter here!  We do no longer permit aborts.
 ;
                 call abort_check        	; Last chance!!
 
-		mov si,ready_msg
+		mov si,clrln_msg
+		call cwritestr
+
+update_disk_05:
+
+;
+; if the user has an update disk, give him a chance to insert it now
+;
+		cmp byte [wants_update],0
+		jnz update_disk_10
+		cmp byte [gfx_ok],0
+		jnz update_disk_90
+		mov si,crlf_msg
+		call cwritestr
+		jmp update_disk_90
+update_disk_10:
+		cmp byte [gfx_ok],0
+		jz update_disk_20
+		mov al,0
+		mov si,upd_msg_1a
+		xor di,di
+		call gfx_infobox
+		jmp update_disk_90
+update_disk_20:
+		mov si,upd_msg_1
 		call cwritestr
+		call wait_for_key
+update_disk_90:	
+		call gfx_done
+
+		push word real_mode_seg
+		pop fs
+
+		mov al,[wants_serial]
+		shl al,1
+		or al,[wants_update]
+		shl al,1
+		cmp byte [video_mode],0
+		setz ah
+		or al,ah
+		les bx,[expert_txt_ofs]
+		add [es:bx],al
+
+		cmp byte [vga_parm_cnt],2	; override via cmdline
+		jae vid_mode_90
+		cmp word [lxrc_vga_ptr],0
+		jz vid_mode_90
+		les di,[vga_txt_ofs]
+		mov cx,[lxrc_vga_len]
+		or cx,cx
+		jz vid_mode_90
+		cmp byte [video_mode],0
+		jz vid_mode_50
+		add di,cx
+		sub di,4
+
+		mov al,[video_mode]
+		mov cx,[fb_mode_0]
+		dec al
+		jz vid_mode_30		; 1
+		mov cx,[fb_mode_1]
+		dec al
+		jz vid_mode_30		; 2
+		mov cx,[fb_mode_2]
+		dec al
+		jnz vid_mode_50		; 0, > 3
+vid_mode_30:
+		or cx,cx
+		jz vid_mode_50
+
+		mov si,di
+		add ch,2
+		mov [fs:bs_vidmode],cx
+		mov al,ch
+		push ds
+		push es
+		pop ds
+		push cx
+		call byte_to_hex
+		pop ax
+		call byte_to_hex
+		pop ds
+		jmp vid_mode_90
+vid_mode_50:
+		mov al,' '
+		rep stosb
+		mov word [fs:bs_vidmode],-1
+vid_mode_90:
+
 
 		call vgaclearmode		; We can't trust ourselves after this
 ;
@@ -2257,6 +2632,7 @@
 		mov dx,03F2h
 		xor al,al
 		call slow_out
+
 ;
 ; If we're debugging, wait for a keypress so we can read any debug messages
 ;
@@ -2264,6 +2640,11 @@
                 xor ax,ax
                 int 16h
 %endif
+
+%if do_test
+		jmp $
+%endif
+
 ;
 ; Set up segment registers and the Linux real-mode stack
 ; Note: bx == the real mode segment
@@ -2479,7 +2860,11 @@
 		dd 00009300h		; present, dpl 0, cover 64K
 bcopy_gdt_size:	equ $-bcopy_gdt
 
-bcopy:		push eax
+bcopy:
+%if do_test
+		ret
+%endif
+		push eax
 		pushf			; Saves, among others, the IF flag
 		push gs
 		push fs
@@ -2765,6 +3150,143 @@
 		ret
 
 ;
+; 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
+;
+boot_hd:
+		mov ax,[SLXOption]
+		test al,2		; should we do it?
+		jz boot_hd_90
+		push es
+		shr ax,2
+		xchg [bsDriveNumber],al
+		push ax
+		call detach_cd
+		xor ax,ax
+		xor dx,dx
+		mov es,ax
+		mov bx,trackbuf
+		push bx
+		call getonesec
+		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:
+		pop ax
+		mov [bsDriveNumber],al
+		pop es
+boot_hd_90:
+		ret
+
+;
+; 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 :-((
+
+		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
+
+;
+; 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 [es:su_ramdisklen1],ax	; Ram disk length
+		mov [es:su_ramdisklen2],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
+
+;
 ; Load RAM disk into high memory
 ;
 loadinitrd:
@@ -2775,14 +3297,22 @@
                 mov edi,[InitRDat]		; initrd load address
 		mov [es:su_ramdiskat],edi	; Offset for ram disk
 		push si
+		cmp byte [gfx_ok],0
+		jnz rd_load_loop
+                mov si,loading_msg
+                call cwritestr
                 mov si,InitRDCName		; Write ramdisk name
                 call cwritestr
                 mov si,dotdot_msg		; Write dots
                 call cwritestr
 rd_load_loop:	
+		cmp byte [gfx_ok],0
+		jnz rd_load_loop_gfx
 		mov si,dot_msg			; Progress report
                 call cwritestr
+rd_load_loop_gfx:
 		pop si				; Restore cluster pointer
+		call chk_update
                 call abort_check
                 mov cx,[InitRDClust]
 		cmp cx,[ClustPerMoby]
@@ -2790,6 +3320,10 @@
 		mov cx,[ClustPerMoby]
 rd_last_moby:
 		sub [InitRDClust],cx
+		cmp byte [gfx_ok],0
+		jz rd_last_moby_nogfx
+		call gfx_progress_update
+rd_last_moby_nogfx:
 		xor bx,bx			; Load at offset 0
                 push word xfer_buf_seg		; Bounce buffer segment
 		pop es
@@ -2807,9 +3341,13 @@
 		jne rd_load_loop		; Apparently not
 rd_load_done:
                 pop si                          ; Clean up the stack
-		call crlf
-                mov si,loading_msg		; Write new "Loading " for
-                call cwritestr                  ; the benefit of the kernel
+		cmp byte [gfx_ok],0
+		jnz rd_load_done_gfx
+		push si
+		mov si,clrln_msg
+		call cwritestr
+		pop si
+rd_load_done_gfx:
                 pop es                          ; Restore original ES
                 ret
 
@@ -2817,6 +3355,10 @@
 ; abort_check: let the user abort with <ESC> or <Ctrl-C>
 ;
 abort_check:
+		cmp byte [gfx_ok],0
+		jz abort_check_nogfx
+		ret
+abort_check_nogfx:
 		call pollchar
 		jz ac_ret1
 		pusha
@@ -3398,7 +3940,8 @@
 ; getchar: Read a character from keyboard or serial port
 ;
 getchar:
-.again:		mov ah,1		; Poll keyboard
+.again:		call chk_update
+		mov ah,1		; Poll keyboard
 		int 16h
 		jnz .kbd		; Keyboard input?
 		mov bx,[SerialPort]
@@ -3426,6 +3969,15 @@
 ;	   starting with "kaboom.patch" with this part
 
 kaboom2:
+		cmp byte [gfx_ok],0
+		jz kaboom2_nogfx
+		mov si,err_failed_gfx
+		xor di,di
+		mov al,1
+		call gfx_infobox
+		call gfx_done
+		call do_reboot
+kaboom2_nogfx:
 		mov si,err_bootfailed
 		call cwritestr
 		call getchar
@@ -4162,6 +4714,18 @@
 linear_color	db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
 UsingVGA	db 0
 
+
+;
+; most of the new stuff is now in suse.inc
+;
+%include	"suse.inc"
+
+;
+; add gfx stuff
+;
+%include	"gfxlogo.inc"
+
+
 ; ----------------------------------------------------------------------------------
 ;  Begin data section
 ; ----------------------------------------------------------------------------------
@@ -4205,7 +4769,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.'
@@ -4224,6 +4789,12 @@
 crlf_msg	db CR, LF, 0
 crff_msg	db CR, FF, 0
 syslinux_cfg	db 'SYSLINUXCFG'
+err_failed_gfx	db 'Error reading from disk.', 0
+load_gfx_msg	db 'Loading...', 0
+no_msg		db 0
+clrln_msg	db 0dh, '                                                            ', 0dh, 0
+gfx_ok		db 0
+
 ;
 ; Command line options we'd like to take a look at
 ;
@@ -4255,6 +4826,13 @@
 		db 'f8' ; F8
 		db 'f9' ; F9
 		db 'f0' ; F10
+
+		db 'fr' ; framebuffer
+		db 're' ; readinfo
+		db 've' ; verbose
+		db 'gf' ; gfxboot
+		db 'in' ; initrdsize
+
 		dw 0
 ;
 ; Extensions to search for (in *reverse* order).  Note that the last
@@ -4280,7 +4858,6 @@
 KbdTimeOut      dw 0                    ; Keyboard timeout (if any)
 FKeyMap		dw 0			; Bitmap for F-keys loaded
 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
@@ -4290,6 +4867,13 @@
 A20DList	dw a20d_dunno, a20d_none, a20d_bios, a20d_kbc, a20d_fast
 A20Type		dw A20_DUNNO		; A20 type unknown
 VGAFontSize	dw 16			; Defaults to 16 byte font
+FrameBuffer	dw 0			; Add an appropriate vga= line for kernel fb's
+FrameBufferBits	dw 8			; Color depth for the fb
+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
 ScrollAttribute	db 07h			; White on black (for text mode)
 ;
 ; Stuff for the command line; we do some trickery here with equ to avoid
@@ -4311,11 +4895,8 @@
 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
-
 ; This is a compile-time assert that we didn't run out of space
-%if (getcbuf+trackbufsize) > vgafontbuf
-%error "Out of memory, better reorganize something..."
-%endif
+; vgafontbuf is now at 0:5000h
+; %if (getcbuf+trackbufsize) > vgafontbuf
+; %error "Out of memory, better reorganize something..."
+; %endif
diff -Naur syslinux-1.62.orig/Makefile syslinux-1.62/Makefile
--- syslinux-1.62.orig/Makefile	2001-04-24 22:36:15 +0400
+++ syslinux-1.62/Makefile	2003-02-25 13:52:09 +0300
@@ -20,7 +20,7 @@
 CFLAGS	= -Wall -O2 -fomit-frame-pointer
 LDFLAGS	= -O2 -s
 
-BINDIR  = /usr/bin
+BINDIR  = $(RPM_BUILD_ROOT)/usr/sbin
 
 VERSION = $(shell cat version)
 
@@ -34,7 +34,7 @@
 #
 SOURCES = ldlinux.asm syslinux.asm syslinux.c copybs.asm \
 	  pxelinux.asm pxe.inc mbr.asm gethostip.c \
-	  isolinux.asm
+	  isolinux.asm suse.inc gfxlogo.inc
 BTARGET = bootsect.bin ldlinux.sys ldlinux.bin ldlinux.lst \
 	  pxelinux.0 mbr.bin isolinux.bin isolinux-debug.bin
 ITARGET = syslinux.com syslinux copybs.com gethostip
@@ -65,7 +65,7 @@
 DATE    := $(HEXDATE)
 endif
 
-ldlinux.bin: ldlinux.asm
+ldlinux.bin: ldlinux.asm suse.inc gfxlogo.inc
 	$(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
 		-dHEXDATE="$(HEXDATE)" \
 		-l ldlinux.lst -o ldlinux.bin ldlinux.asm
@@ -76,16 +76,18 @@
 		-dHEXDATE="$(HEXDATE)" \
 		-l pxelinux.lst -o pxelinux.0 pxelinux.asm
 
-isolinux.bin: isolinux.asm
+isolinux.bin: isolinux.asm suse.inc gfxlogo.inc
 	$(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
 		-dHEXDATE="$(HEXDATE)" \
 		-l isolinux.lst -o isolinux.bin isolinux.asm
+	./add_crc isolinux.bin
 
 # Special verbose version of isolinux.bin
-isolinux-debug.bin: isolinux.asm
+isolinux-debug.bin: isolinux.asm suse.inc gfxlogo.inc
 	$(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
 		-dHEXDATE="$(HEXDATE)" -dDEBUG_MESSAGES \
 		-l isolinux-debug.lst -o isolinux-debug.bin isolinux.asm
+	./add_crc isolinux-debug.bin
 
 bootsect.bin: ldlinux.bin
 	dd if=ldlinux.bin of=bootsect.bin bs=512 count=1
@@ -143,7 +145,7 @@
 	rm -f *~ \#* core
 
 spotless: clean dist
-	rm -f $(BTARGET)
+	rm -f $(BTARGET) mbr.lst
 
 #
 # Hook to add private Makefile targets for the maintainer.
diff -Naur syslinux-1.62.orig/README.SuSE syslinux-1.62/README.SuSE
--- syslinux-1.62.orig/README.SuSE	1970-01-01 03:00:00 +0300
+++ syslinux-1.62/README.SuSE	2003-02-25 13:52:27 +0300
@@ -0,0 +1,51 @@
+syslinux/isolinux now 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-devel package. Please _do_ have a look at its documentation before
+you begin.
+
+Note that you currently 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 the mode number for 640x480x8 from the VESA
+    BIOS and adds an appropriate vga= line the kernel cmd line.
+
+    "framebuffer <width> <color_bits>" does the same but for the chosen
+    mode. E.g.  "framebuffer 1024 16" sets the frame buffer to 1024x768x16. 
+    Note: this causes problems on some cards as only the mode width is
+    compared.
+
+  - verbose
+
+    "verbose 1" enables some debug messages
+
+It is possible to have the initrd on a different disk as the kernel.
+syslinux will then ask for a disk change if it doesn't find the initrd. To
+use that feature, put a line with
+
+    initrdsize <size_in_sectors>
+
+into syslinux.cfg (Note: this feature is not available in isolinux).
+<size_in_sectors> must be > 0 and should be an approximation of the initrd
+size. (The value is used to adjust the progress bar only.)
+
+
+                                        Steffen Winterfeldt <wfeldt@suse.de>
diff -Naur syslinux-1.62.orig/suse.inc syslinux-1.62/suse.inc
--- syslinux-1.62.orig/suse.inc	1970-01-01 03:00:00 +0300
+++ syslinux-1.62/suse.inc	2003-05-19 19:53:28 +0400
@@ -0,0 +1,1040 @@
+;
+; some extra functionality for syslinux
+;
+
+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 version >= 2.0, looking for frame buffer 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 a key to continue.', 0
+upd_msg_1a	db 'Please insert the Driver Update floppy/CDROM.', 0
+upd_msg_2	db '     Text mode install', 0
+upd_msg_3	db '    Install via serial line', 0
+mod_disk_msg	db 'Please insert module disk 1; then press a key to continue.', 0
+mod_disk_msga	db 'Please insert module disk 1.', 0
+prod_excl	db 'VMware', 0
+prod_excl_end	equ $-1
+
+do_write_msg	db 0					; set to get some debug messages
+wants_update	db 0
+wants_serial	db 0
+do_nogfx	db 0
+no_fkeys	db 0
+vmode_shown	db 0
+hd_disk		db 80h
+expert_txt	db ' ', 0
+expert_txt_ofs	dw 0
+expert_txt_seg	dw 0
+dec_buf		zb 10h
+vbe_mode_parm	db ' vga=0x', 0
+; buffer for our added command line parametes
+lxrc_vga_ptr	dw 0
+lxrc_vga_len	dw 0
+vga_txt_ofs	dw 0
+vga_txt_seg	dw 0
+ddc_timings	dw 0
+video_mem	dw 0
+fb_mode_0	dw 0		; 640x480
+fb_mode_1	dw 0		; 800x600
+fb_mode_2	dw 0		; 1024x768
+fb_bits_0	db 0
+fb_bits_1	db 0
+fb_bits_2	db 0
+video_mode	db 1
+vga_parm_cnt	db 0
+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
+
+lxrc_ptr	dw lxrc_data1
+lxrc_data	db ' altcode='
+lxrc_data1	zb 0fah
+
+;
+; Read EDID record via DDC and create an appropriate
+; lxrc=... command line entry.
+;
+read_ddc:
+		pushad				; don't modify any regs
+		push es
+		push ds
+		pop es
+		mov si,vbe_msg_0
+		call xwritestr
+		mov di,vbe_buf
+		mov dword [di],32454256h	; 'VBE2'
+		mov ax,4f00h
+		int 10h
+		cmp ax,4fh
+		jnz 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 si,[lxrc_ptr]
+		mov bx,ddc_buf
+
+%if 0
+		mov ax,[bx+08h]
+		xchg al,ah		; big endian!
+		call unpack_eisa
+
+		mov al,[bx+0bh]
+		call byte_to_hex
+		mov al,[bx+0ah]
+		call byte_to_hex
+		mov al,[bx+15h]
+		call byte_to_hex
+		mov al,[bx+16h]
+		call byte_to_hex
+%endif
+		mov al,[bx+23h]
+		mov [ddc_timings],al
+%if 0
+		call byte_to_hex
+%endif
+		mov al,[bx+24h]
+		mov [ddc_timings+1],al
+%if 0
+		call byte_to_hex
+		xor di,di
+read_ddc_50:
+		mov ax,[bx+di+26h]
+		cmp ax,0000h
+		jz read_ddc_60
+		cmp ax,0101h
+		jz read_ddc_60
+		call byte_to_hex
+		mov al,ah
+		call byte_to_hex
+		inc di
+		inc di
+		cmp di,10h
+		jb read_ddc_50
+read_ddc_60:
+		mov al,[bx+11h]
+		call byte_to_hex
+		xor di,di
+read_ddc_61:
+		mov eax,[bx+di+36h]
+		shl eax,8
+		jnz read_ddc_69
+		mov al,[bx+di+36h+3]
+		cmp al,0fch
+		jb read_ddc_69
+		sub al,0fch
+		mov byte [si],'^'
+		inc si
+		mov [si],al
+		add byte [si],'0'
+		inc si
+		cmp al,1
+		jnz read_ddc_62
+		mov al,[bx+di+36h+5]
+		call byte_to_hex
+		mov al,[bx+di+36h+6]
+		call byte_to_hex
+		mov al,[bx+di+36h+7]
+		call byte_to_hex
+		mov al,[bx+di+36h+8]
+		call byte_to_hex
+		jmp read_ddc_69
+read_ddc_62:
+		push di
+		lea di,[bx+di+36h+5]
+		mov dx,0dh
+read_ddc_63:
+		mov al,[di]
+		inc di
+		cmp al,0
+		jz read_ddc_65
+		cmp al,0ah
+		jz read_ddc_65
+		cmp al,20h
+		ja read_ddc_64
+		mov al,'_'
+read_ddc_64:
+		mov [si],al
+		inc si
+		dec dx
+		jnz read_ddc_63
+read_ddc_65:
+		pop di
+read_ddc_69:
+		add di,12h
+		cmp di,4*12h
+		jb read_ddc_61
+%endif
+
+		mov [lxrc_ptr],si
+		mov byte [si],0
+
+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 read_hd_done
+		cmp ah,0
+		jnz 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
+
+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
+
+		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
+		xor ebx,ebx
+		lgs bx,[vbe_buf+1ah]
+		mov eax,gs
+		shl eax,4
+		add eax,ebx
+		or eax,eax
+		jz read_vbe_05
+		cmp eax,100000h
+		jae read_vbe_05
+		call check_prod_excl
+		jc read_vbe_05
+		mov si,vbe_msg_7
+		call xwritestr
+		jmp near read_vbe_done
+read_vbe_05:
+		lgs bx,[vbe_buf+0eh]
+read_vbe_10:
+		mov cx,[gs:bx]
+		inc bx
+		inc bx
+		cmp cx,0xffff
+		jz near read_vbe_25
+
+		mov ax,4f01h
+		mov di,mi_buf
+		push cx
+		int 10h
+		pop cx
+		cmp ax,4fh
+		jnz read_vbe_10
+
+read_vbe_15:
+		test byte [mi_buf],1		; mode supported?
+		jz read_vbe_10
+		cmp dword [mi_buf+28h],byte 0	; frame buffer start
+		jz read_vbe_10
+
+		mov esi,[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_16
+		sub dh,[mi_buf+25h]		; reserved color bits
+		jmp read_vbe_17
+read_vbe_16:
+		cmp dl,4			; PL8
+		jnz read_vbe_10
+		mov dh,8
+read_vbe_17:
+
+		cmp esi,640 + (400 << 16)
+		jz read_vbe_10			; skip 640x400 mode
+
+		mov ax,[FrameBuffer]
+		cmp ax,1
+		jz read_vbe_20
+
+		cmp si,ax
+		jnz read_vbe_10
+
+		mov ax,[FrameBufferBits]
+		cmp al,dh
+		jnz read_vbe_10
+
+		mov [fb_mode_0],cx
+		mov [fb_bits_0],dh
+
+		jmp read_vbe_25
+
+read_vbe_20:
+		cmp dh,8			; color bits: 8 or 16
+		jz read_vbe_205
+		cmp dh,16
+		jnz read_vbe_10
+
+read_vbe_205:
+		cmp dh,[fb_bits_0]
+		jbe read_vbe_21
+		cmp esi,640 + (480 << 16)
+		jnz read_vbe_21
+		mov [fb_mode_0],cx
+		mov [fb_bits_0],dh
+read_vbe_21:
+		cmp dh,[fb_bits_1]
+		jbe read_vbe_22
+		cmp esi,800 + (600 << 16)
+		jnz read_vbe_22
+		mov [fb_mode_1],cx
+		mov [fb_bits_1],dh
+read_vbe_22:
+		cmp dh,[fb_bits_2]
+		jbe read_vbe_23
+		cmp esi,1024 + (768 << 16)
+		jnz read_vbe_23
+		mov [fb_mode_2],cx
+		mov [fb_bits_2],dh
+read_vbe_23:
+		xor ax,ax
+		xor cx,cx
+		cmp byte [fb_bits_0],16
+		adc ax,cx
+		cmp byte [fb_bits_1],16
+		adc ax,cx
+		cmp byte [fb_bits_2],16
+		adc ax,cx
+		; early out if all 3 modes have been found
+		jnz near read_vbe_10
+
+read_vbe_25:
+		mov cx,[fb_mode_0]
+		or cx,cx
+		jz read_vbe_done
+
+		cmp word [fb_mode_1],byte 0
+		jz read_vbe_28
+		test word [ddc_timings],0f7c0h
+		jnz read_vbe_27
+		cmp word [video_mem],0x3e		; at least 4MB-128k
+		jb read_vbe_28
+read_vbe_27:
+		mov cx,[fb_mode_1]
+		mov byte [video_mode],2
+read_vbe_28:
+
+		cmp word [fb_mode_2],byte 0
+		jz read_vbe_29
+		test word [ddc_timings],0f000h
+		jz read_vbe_29
+		mov cx,[fb_mode_2]
+		mov byte [video_mode],3
+read_vbe_29:
+
+%if 0
+		mov ax,[mi_buf+12h]
+		call xwritedec
+		mov si,vbe_msg_6
+		call xwritestr
+		mov ax,[mi_buf+14h]
+		call xwritedec
+		mov si,vbe_msg_6
+		call xwritestr
+		mov ax,[FrameBufferBits]
+		call xwritedec
+		mov si,vbe_msg_5
+		call xwritestr
+%endif
+		add ch,2			; for linux kernel
+
+		mov di,[lxrc_ptr]
+
+		; check if the SuSE string is empty
+		cmp di,lxrc_data1
+		jnz read_vbe_70
+		mov di,lxrc_data
+read_vbe_70:
+
+		mov si,vbe_mode_parm
+		mov [lxrc_vga_ptr],di
+read_vbe_80:
+		lodsb
+		stosb
+		or al,al
+		jnz read_vbe_80
+		lea si,[di-1]
+		xchg ax,cx
+		xchg al,ah
+		call byte_to_hex
+		mov al,ah
+		call byte_to_hex
+
+		mov [lxrc_ptr],si
+		mov byte [si],0
+		sub si,[lxrc_vga_ptr]
+		mov [lxrc_vga_len],si
+
+read_vbe_done:
+		pop gs
+		pop es
+		popad
+		ret
+
+
+; 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
+
+; 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_serial],0
+		jnz chk_update_20
+		test ah,08h		; right ALT key
+		jz chk_update_20
+		mov byte [wants_serial],1
+		mov cx,1737h
+		mov si,upd_msg_3
+		push ax
+		call cwritestr_xy
+		pop ax
+
+chk_update_20:
+		cmp byte [wants_update],0
+		jnz chk_update_50
+		test ah,02h		; left ALT key
+		jz chk_update_50
+		mov byte [wants_update],1
+		mov cx,183bh
+		mov si,upd_msg_0
+		push ax
+		call cwritestr_xy
+		pop ax
+
+chk_update_50:
+		cmp byte [video_mode],0
+		jz chk_update_90
+		test ah,01h		; left Ctrl key
+		jz chk_update_90
+		mov byte [video_mode],0
+		mov cx,1737h
+		mov si,upd_msg_2
+		call cwritestr_xy
+
+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 any key pressed
+;
+wait_for_key:
+		pusha
+		mov ah,2
+		int 16h
+		mov cl,al
+		mov ah,1
+		int 16h
+		mov dx,0
+		jz wait_for_key_10
+		mov dx,ax
+wait_for_key_10:
+		mov ah,2
+		int 16h
+		mov ch,al
+		mov ah,1
+		int 16h
+		jnz wait_for_key_50
+		xor ax,ax
+wait_for_key_50:
+		cmp ax,dx
+		jnz wait_for_key_90
+		cmp ch,cl
+		jz wait_for_key_10
+wait_for_key_90:
+		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
+
+		cmp word [fb_mode_1],byte 0
+		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:
+
+		cmp word [fb_mode_2],byte 0
+		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
+		cmp word [fb_mode_1],byte 0
+		jz process_fkeys_90
+process_fkeys_20:
+		cmp al,4
+		jnz process_fkeys_30
+		cmp word [fb_mode_2],byte 0
+		jz process_fkeys_90
+process_fkeys_30:
+
+		mov [video_mode],al
+		sub byte [video_mode],1
+		call show_vmode
+		clc
+process_fkeys_90:
+		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, 0x0020, 0x0200, 0x4000, 0x4000, 0x4000, 0, 0x0200
+		dw 0x4000, 0, 0, 0, 0, 0, 0, 0
+
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin