--- Makefile
+++ Makefile
@@ -330,15 +330,15 @@
 first.s:	first.S lilo.h version.h Makefile
 		$(CPP) $(PCONFIG) -DFIRST=0x199d1f05 -o first.s first.S
 
-second.s:	second.S read.S volume.S mapper.S biosdata.S shs3.S bdata.h lilo.h version.h \
+second.s:	second.S gfxlogo.S read.S volume.S mapper.S biosdata.S shs3.S bdata.h lilo.h version.h \
 			graph.S menu.S strlen.S bitmap.S crt.S display4.S Makefile
 		$(CPP) $(PCONFIG) -DTEXT=0x8bd7820b second.S -o second.s
 
-third.s:	second.S read.S volume.S mapper.S biosdata.S shs3.S bdata.h lilo.h version.h \
+third.s:	second.S gfxlogo.S read.S volume.S mapper.S biosdata.S shs3.S bdata.h lilo.h version.h \
 			graph.S menu.S strlen.S bitmap.S crt.S display4.S Makefile
 		$(CPP) $(PCONFIG) -DMENU=0x7920a7c2 second.S -o third.s
 
-bitmap.s:	second.S read.S volume.S mapper.S biosdata.S shs3.S bdata.h lilo.h version.h \
+bitmap.s:	second.S gfxlogo.S read.S volume.S mapper.S biosdata.S shs3.S bdata.h lilo.h version.h \
 			graph.S menu.S strlen.S bitmap.S crt.S display4.S Makefile
 		$(CPP) $(PCONFIG) -DBITMAP=0xf54f8b9d second.S -o bitmap.s
 
--- bsect.c
+++ bsect.c
@@ -774,6 +774,7 @@
 	if (st.st_size > i)
 	    die("%s is too big (> %d bytes)",message,i);
 	param2.msg_len = bitmap ? (st.st_size+15)/16 : st.st_size;
+	if(!bitmap) param2.msg_len = st.st_size > 0xffff ? 0xffff : st.st_size;
 	map_begin_section();
 #ifndef LCF_UNIFY
 	map_add(&geo,0,((st.st_size)+SECTOR_SIZE-1)/SECTOR_SIZE);
--- gfxlogo.S
+++ gfxlogo.S
@@ -0,0 +1,764 @@
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; gfx stuff
+;
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+; != 0 -> everything is fine
+gfx_ok:			.byte 0
+
+; we need it at some point
+gfx_tmp:		.word 0
+
+; the memory area we are working with
+gfx_mem:		.long 0		; linear address
+
+; interface to loadable gfx extension (seg:ofs values)
+gfx_bc_jt:		.long 0
+
+gfx_bc_init:		.long 0
+gfx_bc_done:		.long 0
+gfx_bc_input:		.long 0
+gfx_bc_menu_init:	.long 0
+gfx_bc_infobox_init:	.long 0
+gfx_bc_infobox_done:	.long 0
+gfx_bc_progress_init:	.long 0
+gfx_bc_progress_done:	.long 0
+gfx_bc_progress_update:	.long 0
+gfx_bc_progress_limit:	.long 0
+gfx_bc_password_init:	.long 0
+gfx_bc_password_done:	.long 0
+
+; system config data (52 bytes)
+gfx_sysconfig:
+gfx_bootloader:		.byte 0
+gfx_sector_shift:	.byte 0
+gfx_media_type:		.byte 0
+gfx_failsafe:		.byte 0
+gfx_sysconfig_size:	.byte gfx_sysconfig_end-gfx_sysconfig
+gfx_boot_drive:		.byte 0
+gfx_callback:		.word 0
+gfx_bootloader_seg:	.word 0
+gfx_reserved_1:		.word 0
+gfx_user_info_0:	.long 0
+gfx_user_info_1:	.long 0
+gfx_bios_mem_size:	.long 0
+gfx_xmem_0:		.word 0x21	; extended mem area 0 (start:size in MB; 12:4 bits)
+gfx_xmem_1:		.word 0x41
+gfx_xmem_2:		.word 0
+gfx_xmem_3:		.word 0
+gfx_file:		.long 0
+gfx_archive_start:	.long 0
+gfx_archive_end:	.long 0
+gfx_mem0_start:		.long 0
+gfx_mem0_end:		.long 0
+gfx_sysconfig_end:
+
+; 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:		.blkb sizeof_menu_desc
+
+; 64 dummy entries (all "")
+gfx_args_entry:		.blkb 64
+
+gfx_password_buf:	.blkb 32
+gfx_msg_wrong_image:	.ascii "Could not find kernel image: "
+			.byte 0
+gfx_msg_wrong_password:	.ascii "Sorry, incorrect password."
+			.byte 0
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; I really have no idea how to get as86 to do this properly
+
+		macro farcall
+		.byte 0xff
+		.byte 0x1e
+		.word ?1
+		mend
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_get_sysconfig:
+		xor ax,ax
+		ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_set_sysconfig:
+		ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Initialize graphics code. Load and display graphics data.
+;
+;  edi		file length
+;
+;  return:	[gfx_ok] = 0/1
+;
+gfx_init:
+		push es
+
+		cld
+
+		mov byte gfx_ok,#0
+
+		; no gfx if we use a serial line
+		cmp byte par2_port,#0
+		jnz near gfx_init_90
+
+		mov gfx_bootloader_seg,cs
+		mov gfx_archive_end,edi
+
+		; define our memory area
+		; gfx_mem _must_ be 16-byte aligned
+		mov dword gfx_mem,#0x10000
+		add edi,gfx_mem
+		add edi,#15		; add space for alignment
+		mov gfx_mem0_start,edi
+		mov dword gfx_mem0_end,#0x80000
+
+		sub edi,gfx_mem0_end
+		neg edi
+		cmp edi,#0x1000		; we need some minimum space
+		jc near gfx_init_80
+
+		; align 4
+		mov eax,gfx_mem0_start
+		add eax,#3
+		and eax,#~3
+		mov gfx_mem0_start,eax
+
+		call find_file
+		or eax,eax
+		jz near gfx_init_80
+
+		push edi
+		push eax
+		add eax,edi
+		call align_it
+		pop eax
+		pop edi
+
+		sub edi,gfx_mem
+		mov ecx,gfx_archive_start
+		add edi,ecx
+		mov gfx_file,edi
+		add gfx_archive_end,ecx
+		add eax,edi
+		shr eax,4
+		mov gfx_bc_jt+2,ax
+
+		; setup jump table
+		les bx,gfx_bc_jt
+
+		seg es
+		mov ax,(bx)
+		mov gfx_bc_init,ax
+		mov gfx_bc_init+2,es
+
+		seg es
+		mov ax,(bx+2)
+		mov gfx_bc_done,ax
+		mov gfx_bc_done+2,es
+
+		seg es
+		mov ax,(bx+4)
+		mov gfx_bc_input,ax
+		mov gfx_bc_input+2,es
+
+		seg es
+		mov ax,(bx+6)
+		mov gfx_bc_menu_init,ax
+		mov gfx_bc_menu_init+2,es
+
+		seg es
+		mov ax,(bx+8)
+		mov gfx_bc_infobox_init,ax
+		mov gfx_bc_infobox_init+2,es
+
+		seg es
+		mov ax,(bx+10)
+		mov gfx_bc_infobox_done,ax
+		mov gfx_bc_infobox_done+2,es
+
+		seg es
+		mov ax,(bx+12)
+		mov gfx_bc_progress_init,ax
+		mov gfx_bc_progress_init+2,es
+
+		seg es
+		mov ax,(bx+14)
+		mov gfx_bc_progress_done,ax
+		mov gfx_bc_progress_done+2,es
+
+		seg es
+		mov ax,(bx+16)
+		mov gfx_bc_progress_update,ax
+		mov gfx_bc_progress_update+2,es
+
+		seg es
+		mov ax,(bx+18)
+		mov gfx_bc_progress_limit,ax
+		mov gfx_bc_progress_limit+2,es
+
+		seg es
+		mov ax,(bx+20)
+		mov gfx_bc_password_init,ax
+		mov gfx_bc_password_init+2,es
+
+		seg es
+		mov ax,(bx+22)
+		mov gfx_bc_password_done,ax
+		mov gfx_bc_password_done+2,es
+
+		; esi sysconfig data
+		.byte 0x66
+		mov si,ds		; mov esi,ds
+		shl esi,4
+		add esi,#gfx_sysconfig
+
+		farcall(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
+		farcall(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
+
+		mov ax,#0xffff
+		xchg ax,par2_timeout
+
+		; map 0xffff -> 0
+		add ax,#1
+		cmc
+		sbb ax,#0
+
+gfx_input_20:
+		.byte 0x66
+		mov di,ds		; mov edi,ds
+		shl edi,4
+		add edi,#cmdline
+		mov ecx,#CL_LENGTH
+		movzx eax,ax
+
+		; edi	buffer  (0: no buffer)
+		; ecx	buffer size
+		; eax	timeout value (0: no timeout)
+
+		farcall(gfx_bc_input)
+
+		pushf
+		call gfx_set_sysconfig
+		popf
+		jnc gfx_input_50
+		mov ax,#1
+gfx_input_50:
+		cmp ax,#1
+		jz gfx_input_80
+
+		call find_boot_image
+		jnc gfx_input_90
+
+		.byte 0x66
+		mov cx,ds		; mov ecx,ds
+		shl ecx,4
+		lea esi,(ecx+gfx_msg_wrong_image)
+		lea edi,(ecx+cmdline)
+
+		mov al,#0
+		call gfx_infobox 
+
+		xor ax,ax
+		jmp gfx_input_20
+gfx_input_80:
+		push ax
+		call gfx_done
+		pop ax
+gfx_input_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_setup_menu:
+		cmp byte gfx_ok,#0
+		jz gfx_setup_menu_90
+
+		mov si,#DESCR0
+		mov di,si
+		xor ax,ax
+		mov cx,#IMAGES
+gfx_setup_menu_20:
+		cmp byte (si),#0
+		jz gfx_setup_menu_30
+		inc ax
+		add si,#id_size
+		loop gfx_setup_menu_20
+gfx_setup_menu_30:
+		mov esi,#menu_desc
+
+		xor ah,ah
+		mov (si+menu_entries),ax
+
+		mov (si+menu_default),di
+		mov (si+menu_default+2),ds
+
+		mov (si+menu_ent_list),di
+		mov (si+menu_ent_list+2),ds
+		mov word (si+menu_ent_size),#id_size
+
+		mov word (si+menu_arg_list),#gfx_args_entry
+		mov (si+menu_arg_list+2),ds
+		mov word (si+menu_arg_size),#1
+
+		.byte 0x66
+		mov ax,ds		; mov eax,ds
+		shl eax,4
+		add esi,eax
+
+		farcall(gfx_bc_menu_init)
+gfx_setup_menu_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_infobox:
+		pushad
+		cmp byte gfx_ok,#0
+		jz gfx_infobox_90
+		farcall(gfx_bc_infobox_init)
+		xor edi,edi
+		xor eax,eax
+		farcall(gfx_bc_input)
+		farcall(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
+		farcall(gfx_bc_progress_init)
+gfx_progress_init_90:
+		popad
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_progress_done:
+		pushad
+		cmp byte gfx_ok,#0
+		jz gfx_progress_done_90
+		farcall(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
+		farcall(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
+		farcall(gfx_bc_progress_limit)
+gfx_progress_limit_90:
+		popad
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; ds:di image descr
+;
+gfx_password:
+		push es
+		pushad
+		cmp byte gfx_ok,#0
+		stc
+		jz gfx_password_90
+		push di
+		.byte 0x66
+		mov cx,ds			; mov ecx,ds
+		shl ecx,4
+		lea esi,(ecx+gfx_password_buf)	; not used
+		movzx edi,di
+		add edi,ecx
+		farcall(gfx_bc_password_init)
+		.byte 0x66
+		mov di,ds			; mov edi,ds
+		shl edi,4
+		add edi,#gfx_password_buf
+		mov ecx,#32
+		xor eax,eax
+		farcall(gfx_bc_input)
+		.byte 0x66
+		mov si,ds			; mov esi,ds
+		shl esi,4
+		add esi,#gfx_password_buf
+		farcall(gfx_bc_password_done)
+		pop di
+		call check_password
+		jnc gfx_password_90
+		.byte 0x66
+		mov si,ds			; mov esi,ds
+		shl esi,4
+		add esi,#gfx_msg_wrong_password
+		xor edi,edi
+		mov al,#0
+		farcall(gfx_bc_infobox_init)
+		xor edi,edi
+		xor eax,eax
+		farcall(gfx_bc_input)
+		farcall(gfx_bc_infobox_done)
+		stc
+gfx_password_90:
+		popad
+		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),#0xf
+		pop eax
+		ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; locate the boot image
+;
+; return:
+;   bx		boot image index
+;   CF		error (image not found)
+;
+find_boot_image:
+		mov dx,#DESCR0
+		mov cx,#IMAGES
+
+		xor bx,bx
+
+find_boot_image_10:
+		mov si,dx
+		mov di,#cmdline
+find_boot_image_20:
+		mov al,(si)
+		or al,al
+		jz find_boot_image_60
+		cmp al,(di)
+		jnz find_boot_image_30
+		inc si
+		inc di
+		jmp find_boot_image_20
+find_boot_image_30:
+		inc bx
+		add dx,#id_size
+		cmp bx,cx
+		jb find_boot_image_10
+		; not found, strip options for fancy error message
+
+		mov si,#cmdline
+		mov cx,#MAX_IMAGE_NAME+1
+find_boot_image_40:
+		cmp byte (si),#0x20+1
+		inc si
+		jb find_boot_image_50
+		loop find_boot_image_40
+find_boot_image_50:
+		mov byte (si-1),#0
+		jmp find_boot_image_80
+find_boot_image_60:
+		mov al,(di)
+		cmp al,#0x20
+		ja find_boot_image_30
+		imul bx,bx,#id_size
+		add bx,#DESCR0
+		jmp find_boot_image_90
+find_boot_image_80:
+		stc
+find_boot_image_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; ds:di image descr
+;
+; CF = 0: password valid
+;
+check_password:
+#if defined(SHS_PASSWORDS)
+		mov bp,di
+		mov di,#gfx_password_buf
+		mov si,di
+		push ds
+		pop es
+		mov cx,#32 - 1
+		xor al,al
+		repne
+		scasb
+		sub cx,#32 - 1
+		not cx
+		mov bx,cx
+
+		push ss
+		pop es
+		mov cx,#32
+		sub sp,cx
+		mov di,sp
+		rep
+		movsb
+		mov si,sp
+
+		push bp
+
+		push bx		; length
+		push si		; ss:si password
+		call _shsInit
+		call _shsUpdate
+		call _shsFinal
+		pop si
+		pop bx
+
+		pop di
+
+		add di,#id_password_crc
+		mov si,#shs_digest
+		mov cx,#MAX_PW_CRC*4
+		push ds
+		pop es
+		repe
+		cmpsb
+		je check_pw_50
+		inc cx
+check_pw_50:
+		add sp,#32
+		pushad		; clear password buffer
+		mov di,#gfx_password_buf
+		mov cx,#32
+		xor al,al
+		rep
+		stosb
+		popad
+		cmp cx,#1
+		cmc
+#endif
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; locate graphics file
+;
+; return:	eax: code offset (0 -> no file found)
+; 		edi: gfx file start
+;
+find_file:
+		mov edi,gfx_mem
+		push edi
+		call gfx_l2so
+		pop bx
+		pop es
+		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_mem0_start
+		sub ecx,#26 + 12		; min cpio header + gfx header
+		cmp edi,ecx
+		jae find_file_90
+
+		push edi
+		call gfx_l2so
+		pop bx
+		pop es
+		seg es
+		cmp word (bx),#0x71c7
+		jnz find_file_90		; no cpio record
+
+		seg es
+		movzx esi,word (bx+20)		; file name size
+
+		inc si
+		and si,#~1			; align
+
+		seg es
+		mov ecx,(bx+22)			; data size
+		rol ecx,#16			; get word order right
+
+		inc ecx
+		and ecx,#~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
+		seg es
+		cmp dword (bx),#0x0b2d97f00	; header.magic_id
+		jnz magic_ok_90
+		; version 8
+		seg es
+		cmp byte (bx+4),#8		; header.version
+		jb magic_ok_90
+		seg es
+		cmp byte (bx+4),#8		; header.version
+		ja magic_ok_90
+		seg es
+		mov eax,(bx+8)
+magic_ok_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+;  eax		address to be aligned
+;
+align_it:
+		push dword gfx_mem
+		pop dword gfx_archive_start
+		neg al
+		and eax,#0x0f
+		jz align_it_90
+		add gfx_archive_start,eax
+		mov esi,gfx_mem
+		mov ebx,gfx_mem0_start
+		sub ebx,esi
+		sub ebx,#0x0f
+		add esi,ebx
+		dec esi
+
+		std
+
+align_it_30:
+		or ebx,ebx
+		jz align_it_60
+		mov ecx,ebx
+		cmp ebx,#0x8000
+		jb align_it_40
+		mov ecx,#0x8000
+align_it_40:
+		push esi
+		sub ebx,ecx
+		sub (esp),ecx
+		push esi
+		call gfx_l2so
+		pop si
+		add si,#0x8000
+		sub word (esp),#0x8000 >> 4
+		pop es
+		mov di,si
+		add di,ax
+		seg es
+		rep
+		movsb
+		pop esi
+		jmp align_it_30
+align_it_60:
+
+		cld
+
+align_it_90:
+		ret
+
+
--- lilo.h
+++ lilo.h
@@ -331,7 +331,7 @@
 #define DC_MAGIC	0xf4f2	/* magic number of default cmd. line sector */
 #define DC_MGOFF	0x6b6d	/* magic number for disabled line */
 
-#define MAX_MESSAGE	65535	/* maximum message length */
+#define MAX_MESSAGE	8*64*1024-1	/* maximum message length (512k) */
 #define MAX_MENU_TITLE	37	/* maximum MENU title length */
 
 #define NEW_HDR_SIG	"HdrS"	/* setup header signature */
--- second.S
+++ second.S
@@ -618,7 +618,8 @@
 	seg	es
 	cmp	byte ptr (si),#0 ! empty ?
 	je	iloop		! yes -> enter interactive mode
-	jmp	niloop		! enter non-interactive mode
+niloop0:
+	br	niloop		! enter non-interactive mode
 
 ! No external parameters after timeout -> boot first image
 
@@ -626,7 +627,7 @@
 	pop	es
 	mov	si,#DFLCMD+2	! default command line ?
 	cmp	byte ptr (si),#0
-	jne	niloop		! yes -> use it
+	jne	niloop0		! yes -> use it
 	mov	ax,nodfl	! no idea how to tell as86 to do jmp (addr) :-(
 	jmp	ax		! fall through
 
@@ -634,16 +635,23 @@
 ! Command input processor
 
 iloop:
-#if defined(MENU) || defined(BITMAP)
+#ifdef BITMAP
 	call	menu_setup
 #endif
 
 #ifndef BITMAP
+	cmp	byte gfx_ok,#0
+	jnz	iloop_gfx
+
+	; load message before doing anything else
+	; the graphics/text stuff is mixed in a rather messy way...
+
 ;;	BEG_FS
 ;;	SEG_FS		! message disabled ?
 	cmp	word ptr par2_msg_len,#0		;MSG_OFF+SSDIFF,#0
 ;;	END_FS
-	je	nomsg		! yes -> skip this
+	; _must_ be 'jz'!
+	jz	iloop_20	! yes -> skip this
 	call	crlf
 ;BEG_FS
 ;SEG_FS		! load the message file
@@ -657,13 +665,96 @@
 	call	sread
 	call	loadfile
 
+	; es:bx points to file end
+	movzx	ebx,bx
+	xor	edi,edi
+	mov	di,es
+	shl	edi,4
+	add	edi,ebx
+	sub	edi,#SYSSEG * 16
+
+	; edi -> message file size
+
 	xor	bx,bx		! set the terminating NUL and disable further
 				! messages
 	xchg	bx,par2_msg_len		;MSG_OFF+SSDIFF
 
 	push	#SYSSEG
 	pop	ds
-	mov	byte ptr (bx),#0
+
+	cmp     word ptr 0,#0x71c7                      ; cpio header
+	jz iloop_cpio
+
+	cmp     dword ptr 0,#0x0b2d97f00                ; magic header
+	; _must_ be 'jnz'!
+	jnz     iloop_10
+
+iloop_cpio:
+
+	push    cs
+	pop     ds
+
+	; graphical message
+
+	call    gfx_init
+	push    cs
+	pop     es
+	cmp     byte gfx_ok,#0
+	jz      iloop
+	call    gfx_setup_menu
+iloop_gfx:
+	push    cs
+	pop     es
+	call    gfx_input
+	cmp     ax,#1
+	jz      iloop           ; text mode
+	mov     gfx_tmp,bx
+	jmp     near scan_cmdline
+
+	; normal text message
+iloop_10:
+	; keep the zero flag!
+	mov     byte ptr (bx),#0
+	push    cs
+	pop     ds
+
+iloop_20:
+#ifdef MENU
+	pushf
+	call    menu_setup
+	popf
+#endif
+	jnz     totxt
+
+	mov     ax,showit
+	mov     dx,showit+2
+	mov     bx,ax
+	or      bx,dx
+	jz      iloop_40
+	push    ds
+	shl     dx,12
+	mov     bx,ax
+	and     bx,#0xf
+	shr     ax,4
+	add     ax,dx
+	add     ax,#SYSSEG
+	mov     ds,ax
+	call    say
+	pop     ds
+	xor     ax,ax
+	mov     showit,ax
+	mov     showit+2,ax
+iloop_40:
+
+	jmp nomsg
+
+showit:
+	.long   0
+
+totxt:
+	push    #SYSSEG
+	pop     ds
+
 	xor	bx,bx		! display the message
 	call	say
 
@@ -699,12 +790,6 @@
 	mov	al,(si)
 	inc	si
 	jmp	gotinp		! go on
-	
-tolist:
-#ifdef BITMAP
-	call	menu_exit
-#endif
-	br	list		! ...
 
 kbinp:	
 	mov	cx,#brto	! get a key
@@ -733,7 +818,7 @@
 	cmp	al,#8		! BS ?
 	je	todelch		! yes -> erase one character
 	cmp	al,#13		! CR ?
-	je	cr		! yes -> go on
+	je	near cr		! yes -> go on
 	cmp	al,#127		! DEL ?
 	je	todelch		! yes -> erase one character
 	ja	input		! non-printable -> ignore it
@@ -783,6 +868,11 @@
 
 todelch:br	delch		! ...
 todell:	br	delline		! ...
+tolist:
+#ifdef BITMAP
+	call	menu_exit
+#endif
+	br	list		! ...
 
 ! End of input, process the command line
 
@@ -825,6 +915,8 @@
 	or	al,al		! at end ?
 	jnz	cpsav		! no -> go on
 
+
+scan_cmdline:
 	cmp	bx,#cmdline	! empty line ?
 	je	notrspc		! yes -> boot first image
 	cmp	byte ptr (bx-1),#32 ! trailing space ?
@@ -882,6 +974,11 @@
 	je	chkvga		! yes -> look for options again
 	or	al,al		! at end ?
 	jnz	vsknb		! no -> go on
+
+	mov	bx,gfx_tmp
+	cmp	byte gfx_ok,#0
+	jnz	near boot
+
 	call	crlf		! write CR/LF
 	cmp	di,#cmdline+1	! empty line ?
 emptyl:	je	bfirst		! yes -> boot first image
@@ -1073,6 +1170,16 @@
 ;;	SEG_FS
 	mov	word ptr par2_timeout,#0xffff	; cancel timeout
 ;;	END_FS
+
+	cmp     byte gfx_ok,#0
+	jz      dopw_nogfx
+	mov     di,bx
+	call    gfx_password
+	pop     bx
+	jnc     toboot
+	jmp     near iloop
+dopw_nogfx:
+
 	mov	bx,#msg_pw	! display a prompt
 	call	say
 
@@ -1450,7 +1557,9 @@
 
 ! Boot the image BX points to
 
-doboot:	mov	byte ptr prechr,#61 ! switch to equal sign
+doboot:
+	call	gfx_done
+	mov	byte ptr prechr,#61 ! switch to equal sign
 	push	bx		! save image descr
 	mov	bx,#msg_l	! say hi
 	call	say
@@ -3274,6 +3383,8 @@
 
 
 
+#include	"gfxlogo.S"
+
 #ifdef SHS_PASSWORDS
 #include "shs3.S"
 #endif
@@ -3421,6 +3532,8 @@
 	jmp	vgaput1
 #else
 	xor	cx,cx
+	mov	bh,ch
+	mov	bl,#10		; bx: base (_not_ bl!)
 	mov	ah,cl
 	test	byte ptr (si),#0xff ! no value ?
 	jz	vgaerr		! yes -> error
@@ -3429,17 +3542,47 @@
 	jz	vgaput		! yes -> done
 	cmp	al,#32
 	je	vgaput
-	cmp	al,#48		! is it a digit ?  (0x30=48="0")
-	jb	vgaerr		! no -> error
-	cmp	al,#57		! 57=0x39="9"
-	ja	vgaerr
-	sub	al,#48		! cx = cx*10+al-'0'
-	imul	cx,#10
+	cmp	al,#0x61
+ 	jb	vgadig_10
+	sub	al,#0x20	; upper case
+vgadig_10:
+	or	cx,cx
+	jnz vgadig_20
+	cmp	al,#0x58
+	jnz vgadig_20
+	mov	bl,#16		; hex
+	jmp	vgadig
+vgadig_20:
+	cmp	al,#0x3a
+	jb	vgadig_30
+	sub	al,#7
+vgadig_30:
+	sub	al,#0x30
+	jb	vgaerr		; not a digit
+	cmp	al,bl
+	jae	vgaerr		; larger than current base
+	imul	cx,bx
 	add	cx,ax
 	jnc	vgadig		! next one
 #endif
 
-vgaerr:	mov	bx,#msg_v	! display an error message
+vgaerr:
+	mov	bx,#msg_v	! display an error message
+	cmp	byte gfx_ok,#0
+	jz	vgaerr_txt
+	lea	esi,(bx+1)	; skip initial NL
+	.byte	0x66
+	mov	di,ds		; mov edi,ds
+	shl	edi,4
+	add	esi,edi
+	xor	edi,edi
+	mov	al,#0
+	mov	msg_v1,al	; drop final NL
+	call	gfx_infobox
+	mov	byte msg_v1,#10	; put it back
+	stc	
+	ret
+vgaerr_txt:
 	call	say
 /* ifdef HIGHMEM_MAX */
 	xor	eax,eax
@@ -3583,8 +3726,10 @@
 	xor     dx,dx
 	mov     cx,#10          ! default radix is decimal
 	cmp	byte ptr (si),#0x39
-	ja	s2lbad		! error if > '9'
+	/* Those were changed to jna and previously */
+	ja	s2lbad		! error if > '9'	
 	cmp     byte ptr (si),#0x30        ! == '0'?
+	/* Likewise */
 	jb	s2lbad		! error if < '0'
 	jne     s2lnext
 	inc     si
@@ -3890,8 +4035,8 @@
 
 msg_v:	.byte	10
 	.ascii	"Valid vga values are ASK, NORMAL, EXTENDED or a "
-	.ascii	"decimal number."
-	.byte	10,0
+	.ascii	"number."
+msg_v1:	.byte	10,0
 
 msg_pks:.byte	10
 	.ascii	"Invalid hexadecimal number. - Ignoring remaining items."
