wok-tiny diff linux/stuff/bootloader.S @ rev 95

linux: add bootloader
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Oct 06 21:04:42 2015 +0200 (2015-10-06)
parents
children 2c3b4f47fbf5
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/linux/stuff/bootloader.S	Tue Oct 06 21:04:42 2015 +0200
     1.3 @@ -0,0 +1,824 @@
     1.4 +BOOTSEG		= 0x07C0		/* original address of boot-sector */
     1.5 +SYSSEG		= 0x1000		/* historical load address >> 4 */
     1.6 +INITSEG		= 0x9000		/* boot address >> 4 */
     1.7 +SETUPSEG	= 0x9020		/* setup address >> 4 */
     1.8 +ASK_VGA		= -3
     1.9 +
    1.10 +#ifndef SVGA_MODE
    1.11 +#define SVGA_MODE ASK_VGA
    1.12 +#endif
    1.13 +
    1.14 +#ifndef RAMDISK
    1.15 +#define RAMDISK 0
    1.16 +#endif
    1.17 +
    1.18 +#ifndef ROOT_RDONLY
    1.19 +#define ROOT_RDONLY 1
    1.20 +#endif
    1.21 +
    1.22 +/* Assume protocol 2.00+ (kernel >= 1.3.73) */
    1.23 +/* feature set */
    1.24 +#define EXE_SUPPORT		real mode dos .exe file support
    1.25 +// #define EXE_ONLY		remove floppy code
    1.26 +#define EXE_CMDLINE		kernel >= 2.4
    1.27 +// #define FLOPPY_CMDLINE	kernel >= 2.4
    1.28 +// #define OLDCMDLINE		kernel  < 2.4
    1.29 +#define MORETHAN16M		up to 4Gb RAM, not 16Mb
    1.30 +#define KEYBOARDLESS_SUPPORT	scan floppy swap each 5 seconds
    1.31 +// #define FAT12_SUPPORT	will format the floppy free space in FAT 12
    1.32 +// #define REALMODE_NOT_CHECKED	exe crash when started in vm86
    1.33 +// #define SINGLE_FLOPPY	Everytihng fit in a single floppy
    1.34 +// #define EDIT_CMDLINE
    1.35 +// #define MOVE_CMDLINE
    1.36 +#define INITRD_SUPPORT
    1.37 +// #define INITRD_AUTOADDR	Hole in 16Mb..32Mb
    1.38 +// #define MULTI_INITRD		Russian dolls
    1.39 +// #define README_SUPPORT
    1.40 +// #define COUNTER		Show floppy number
    1.41 +#define LABEL "SliTaz"
    1.42 +
    1.43 +	.code16
    1.44 +	.org	0
    1.45 +
    1.46 +bootsect_start:
    1.47 +
    1.48 +cur_initrd_size_ofs	= 494
    1.49 +ramdisk_image_ofs	= 0x218
    1.50 +ramdisk_image	=	bootsect_start+ramdisk_image_ofs
    1.51 +ramdisk_size_ofs	= 0x21C
    1.52 +ramdisk_size	=	bootsect_start+ramdisk_size_ofs
    1.53 +cmd_line_ptr_ofs	= 0x228
    1.54 +cmd_line_ptr	=	bootsect_start+cmd_line_ptr_ofs
    1.55 +setup_sects	=	bootsect_start+497
    1.56 +syssize		=	bootsect_start+500
    1.57 +boot_flag_ofs	= 510
    1.58 +boot_flag	=	bootsect_start+boot_flag_ofs
    1.59 +
    1.60 +
    1.61 +stacktop	= 0x9E00		# in 0x8000 .. 0xA000
    1.62 +zeroed		= 48+10			# gdt + zeroed registers
    1.63 +.macro	INIT_REGS
    1.64 +	movw	$stacktop-zeroed, %di	# stacktop is an arbitrary value >=
    1.65 +					# length of bootsect + length of
    1.66 +					# setup + room for stack;
    1.67 +					# 12 is disk parm size.
    1.68 +	pushw	$INITSEG
    1.69 +	popw	%ss			# %ss contain INITSEG
    1.70 +	movw	%di, %sp		# put stack at INITSEG:stacktop-...
    1.71 +	pushw	%ss
    1.72 +	popw	%es			# %es = %ss = INITSEG
    1.73 +	xorw	%ax, %ax		# %ax = 0
    1.74 +#if defined(EXE_CMDLINE)
    1.75 +	movw	$zeroed+1, %cx		# clear gdt + offset, %ds, limits, cmdline=""
    1.76 +	rep				# don't worry about cld
    1.77 +	stosb				# already done above
    1.78 +	decw	%di
    1.79 +#else
    1.80 +	movw	$zeroed/2, %cx		# clear gdt + offset, %ds, limits
    1.81 +	rep				# don't worry about cld
    1.82 +	stosw				# already done above
    1.83 +#endif
    1.84 +	popw	%bx			# offset = 0
    1.85 +.endm
    1.86 +
    1.87 +#ifdef FAT12_SUPPORT
    1.88 +	jmp	fdstart
    1.89 +	nop
    1.90 +	.ascii	"SLITAZ  "
    1.91 +	.word	512			// 0B: bytes per sector
    1.92 +	.byte	1			// 0D: sectors per cluster
    1.93 +	.word	2880			// 0E: reserved seectors
    1.94 +	.byte	2			// 10: FAT number
    1.95 +	.word	64			// 11: root entries 4x 16
    1.96 +	.word	2880			// 13: total sectors
    1.97 +	.byte	0xF0			// 15: media id (or F9)
    1.98 +#endif
    1.99 +
   1.100 +#ifdef EXE_SUPPORT
   1.101 +#define CODESZ		0x8000
   1.102 +#define EXEADRS(x)	x+0xE0
   1.103 +	decw	%bp			// Magic number: MZ
   1.104 +	popw	%dx
   1.105 +#ifdef EXE_ONLY
   1.106 +	.word	512			// Bytes on last page of file
   1.107 +#else
   1.108 +	jmp	fdstart			// Bytes on last page of file
   1.109 +#endif
   1.110 +	.word	(CODESZ+511)/512	// Pages in file
   1.111 +	.word	0			// Relocations
   1.112 +	.word	2			// Size of header in paragraphs
   1.113 +	.word	4096			// Minimum extra paragraphs needed
   1.114 +	.word	-1			// Maximum extra paragraphs needed
   1.115 +	.word	(CODESZ+15)/16		// Initial (relative) SS value
   1.116 +	.word	stacktop+4		// Initial SP value (+callf)
   1.117 +	.word	0			// Checksum
   1.118 +	.word	EXEADRS(comstart)	// Initial IP value
   1.119 +	.word	0xFFF0			// Initial (relative) CS value
   1.120 +#if defined(EXE_ONLY) || defined(SINGLE_FLOPPY) || defined(COUNTER)
   1.121 +//	.word	0x001C			// File address of relocation table
   1.122 +//	.word	0,0,0			// Overlay number
   1.123 +	.ascii	"(SliTaz)"
   1.124 +#else
   1.125 +swap_floppy:
   1.126 +	.ascii	"Next!"
   1.127 +	.byte	7,13,0			# swap detection needs 13, 0
   1.128 +#endif
   1.129 +#ifdef OLDCMDLINE
   1.130 +# ifdef FLOPPY_CMDLINE
   1.131 +	.word	0			# 0xA33F
   1.132 +	.word	0			# stacktop
   1.133 +# else
   1.134 +	.word	0xA33F
   1.135 +	.word	stacktop
   1.136 +# endif
   1.137 +#endif
   1.138 +#ifndef EXE_ONLY
   1.139 +fdstart:
   1.140 +	pushw	%dx
   1.141 +#endif
   1.142 +#endif
   1.143 + 
   1.144 +LOADSEG		= 0x8000		# 0x1000 multiple, up to 512K zImage
   1.145 +LOADSZ		= 0x10000
   1.146 +
   1.147 +#if defined(EXE_SUPPORT) || defined(EXE_ONLY)
   1.148 +A20BUFFER	= 0x68000		# a20 gate / himem.sys support
   1.149 +#define USEA20BUFFER
   1.150 +#endif
   1.151 + 
   1.152 +#ifndef EXE_ONLY
   1.153 +# bootsect_start:
   1.154 +#ifdef EXE_SUPPORT
   1.155 +	call	initregs
   1.156 +	cwd				# floppy = head = 0
   1.157 +#else
   1.158 +	INIT_REGS
   1.159 +#endif
   1.160 +	popw	%ds			# %ds = 0
   1.161 +	movb	setup_sects+0x7C00, %al	# read bootsector + setup
   1.162 +	incw	%ax			# %ax = setup_sects+bootsect
   1.163 +	popw	%fs			# %fs = 0
   1.164 +
   1.165 +# Many BIOS's default disk parameter tables will not recognize
   1.166 +# multi-sector reads beyond the maximum sector number specified
   1.167 +# in the default diskette parameter tables - this may mean 7
   1.168 +# sectors in some cases.
   1.169 +#
   1.170 +# Since single sector reads are slow and out of the question,
   1.171 +# we must take care of this by creating new parameter tables
   1.172 +# (for the first disk) in RAM.  We can set the maximum sector
   1.173 +# count to 36 - the most we will encounter on an ED 2.88.  
   1.174 +#
   1.175 +# High doesn't hurt.  Low does.  Let's use the max: 63
   1.176 +
   1.177 +	cli
   1.178 +	ldsw	0x78(%bx), %si		# %ds:%bx+0x78 is parameter table address
   1.179 +	popw	%di
   1.180 +	pushw	%es
   1.181 +	pushw	%di
   1.182 +#ifdef	FLOPPY_CMDLINE
   1.183 +	movw	$0, %bp			# patched by installer (7C22)
   1.184 +skipcmdline:
   1.185 +#define cmd_line_ptr	0x22
   1.186 +#endif
   1.187 +	movb	$6, %cl			# copy 12 bytes
   1.188 +	rep				# don't worry about cld
   1.189 +	  movsw				# already done above
   1.190 +	pushw	%ss
   1.191 +	popw	%ds			# now %ds = %es = %ss = INITSEG
   1.192 +	popl	%fs:0x78(%bx)		# update parameter table address
   1.193 +	movb	$63, 0x4-12(%di)	# patch sector count, %di = stacktop
   1.194 +
   1.195 +	xchg	%ax, %di		# sector count
   1.196 +	popw	%ax			# limits = 0
   1.197 +	incw	%cx			# cylinder 0, sector 1, clear Z
   1.198 +	call	read_first_sectors	# read setup
   1.199 +#ifdef	README_SUPPORT
   1.200 +	xorw	%si, %si
   1.201 +	orw	readme, %si
   1.202 +	jz	readmeend
   1.203 +readmeloop:
   1.204 +	call	puts
   1.205 +	jz	readmeend
   1.206 +	call	wait4key
   1.207 +	cmpb	$27, %al
   1.208 +	jne	readmeloop
   1.209 +readmeend:
   1.210 +#endif
   1.211 +#endif
   1.212 +loadsys:
   1.213 +	movw	$0x200,%si
   1.214 +type_of_loader	=	0x10
   1.215 +loadflags	=	0x11
   1.216 +heap_end_ptr	=	0x24
   1.217 +	orw	$0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader
   1.218 +	movb	$(stacktop-0x300)/256, heap_end_ptr+1(%si)
   1.219 +	call	puts_version		# show which kernel we are loading
   1.220 +
   1.221 +#ifdef	FLOPPY_CMDLINE
   1.222 +# The cmdline can be entered and modifed at boot time.
   1.223 +# Only characters before the cursor are passed to the kernel.
   1.224 +
   1.225 +	xorw	%si, %si
   1.226 +	orw	cmd_line_ptr-7(%bx), %si
   1.227 +	jz	nocmdline
   1.228 +#ifdef OLDCMDLINE
   1.229 +	movw	$0xA33F, cmd_line_ptr-2-7(%bx)
   1.230 +#endif
   1.231 +	call	puts
   1.232 +#ifdef	EDIT_CMDLINE
   1.233 +cmdlp:
   1.234 +	movb	$0x20, %al		# clear end of line
   1.235 +cmdlpz:
   1.236 +	call	putc			#  with Space
   1.237 +	subb	$0x18, %al		#   and BackSpace
   1.238 +	jnc	cmdlpz
   1.239 +	decw	%si
   1.240 +cmdget:
   1.241 +#ifdef KEYBOARDLESS_SUPPORT
   1.242 +	call	wait4key
   1.243 +#else
   1.244 +	int	$0x16
   1.245 +#endif
   1.246 +	cbw				# %ah = 0, get keyboard character
   1.247 +	cmpb	$8, %al			# BackSpace ?
   1.248 +	je	cmdbs
   1.249 +	movb	%al, (%si)		# store char
   1.250 +	lodsw				# %si += 2
   1.251 +cmdbs:
   1.252 +	cmpw	%si, cmd_line_ptr-7(%bx)
   1.253 +	je	cmdget
   1.254 +	call	putc
   1.255 +	cmpb	$10, %al		# Enter/linefeed ?
   1.256 +	jne	cmdlp
   1.257 +	movb	%bh,-2(%si)		# set end of string and remove CR
   1.258 +endcmdline:
   1.259 +#endif
   1.260 +#ifdef MOVE_CMDLINE
   1.261 +	pushw	%ss
   1.262 +	popw	%es
   1.263 +	movw	$0x8000, %di
   1.264 +	movw	%di, %si
   1.265 +	xchgw	%si, cmd_line_ptr-7(%bx)
   1.266 +	movb	$0x2, %ch
   1.267 +	rep
   1.268 +	  movsb
   1.269 +#endif
   1.270 +nocmdline:
   1.271 +#endif
   1.272 +
   1.273 +# This routine loads the system at address LOADSEG, making sure
   1.274 +# no 64kB boundaries are crossed. We try to load it as fast as
   1.275 +# possible, loading whole tracks whenever we can.
   1.276 +
   1.277 +.macro	autoaddr base
   1.278 +#ifdef INITRD_AUTOADDR
   1.279 +	movb	$0x88, %ah
   1.280 +	int	$0x15
   1.281 +	//jc	NeedMoreRAM			# error code 80 or 86
   1.282 +	cmpw	$0xB000, %ax			# more than 45M ?
   1.283 +	jb	NeedMoreRAM
   1.284 +	movb	%ch, bootsect_dst_base_hi(%si)	# initramfs @ 32M
   1.285 +	movb	%ch, ramdisk_image_ofs+3-\base
   1.286 +NeedMoreRAM:
   1.287 +#endif
   1.288 +.endm
   1.289 +
   1.290 +bootsect_src_limit	= 16
   1.291 +bootsect_dst_limit	= 24
   1.292 +bootsect_src_base	= 18
   1.293 +bootsect_dst_base	= 26		# bits  0..23
   1.294 +bootsect_dst_base_hi	= 31		# bits 24..31
   1.295 +	popw	%bx			# clear %bx
   1.296 +	movw	%sp, %si		# for bootsect_gdt
   1.297 +init_gdt:
   1.298 +	decw	bootsect_src_limit(%bx,%si)	# max 64Kb
   1.299 +	movw	$0x9300+(LOADSEG/0x1000), bootsect_src_base+2(%bx,%si)
   1.300 +	xorb	$bootsect_dst_limit-bootsect_src_limit, %bl
   1.301 +	jne	init_gdt
   1.302 +#ifdef INITRD_SUPPORT
   1.303 +	movw	$syssize, %bx
   1.304 +	movb	$5, %cl
   1.305 +code32_start	=	0x214
   1.306 +	movw	code32_start+1, %ax		# destination = 0x00100000 or 0x00010000
   1.307 +initrdlp:
   1.308 +	movl	(%bx), %ebx
   1.309 +	decl	%ebx
   1.310 +	shrl	%cl, %ebx
   1.311 +#else
   1.312 +code32_start	=	0x214
   1.313 +	movw	code32_start+1, %ax		# destination = 0x00100000 or 0x00010000
   1.314 +	movl	syssize, %ebx
   1.315 +	decl	%ebx
   1.316 +	shrl	$5, %ebx
   1.317 +#endif
   1.318 +#ifdef MORETHAN16M
   1.319 +	incl	%ebx
   1.320 +#else
   1.321 +	incw	%bx
   1.322 +#endif
   1.323 +#ifdef USEA20BUFFER
   1.324 +	movw	$0x00100000>>8, %di
   1.325 +#endif
   1.326 +syslp:
   1.327 +#ifdef USEA20BUFFER
   1.328 +	cmpw	%ax, %di
   1.329 +	jne	nota20
   1.330 +	xorw	$(0x00100000+A20BUFFER)>>8, %ax
   1.331 +nota20:
   1.332 +#endif
   1.333 +	movw	%ax, bootsect_dst_base+1(%si)
   1.334 +#ifdef MORETHAN16M
   1.335 +	movl	$LOADSZ/512, %edi	# size in sectors
   1.336 +	subl	%edi, %ebx
   1.337 +#else
   1.338 +	movw	$LOADSZ/512, %di	# size in sectors
   1.339 +	subw	%di, %bx
   1.340 +#endif
   1.341 +	pushf
   1.342 +	jnc	not_last
   1.343 +	addw	%bx, %di
   1.344 +not_last:
   1.345 +#ifdef MULTI_INITRD
   1.346 +	pushw	%di
   1.347 +#endif
   1.348 +	pushw	%ax
   1.349 +	pushw	%bx
   1.350 +	pushw	%si
   1.351 +	xorw	%bx,%bx
   1.352 +	pushw	$LOADSEG
   1.353 +	popw	%es
   1.354 +#ifdef EXE_ONLY
   1.355 +	call	read_sectors_dos
   1.356 +#else
   1.357 +patchcall:
   1.358 +	call	read_sectors		# update %bp
   1.359 +#endif
   1.360 +	popw	%si
   1.361 +	popw	%bx
   1.362 +	movw	%es, %cx		# word count = LOADSZ/2 (= LOADSEG)
   1.363 +	movb	$0x87, %ah
   1.364 +	pushw	%ss
   1.365 +	popw	%es			# restore es
   1.366 +	int	$0x15			# max 16M, maybe more...
   1.367 +	popw	%ax
   1.368 +#ifdef MULTI_INITRD
   1.369 +	popw	%di
   1.370 +	shlw	$1,%di			# sectors to pages
   1.371 +	addw	%di, %ax
   1.372 +#ifdef MORETHAN16M
   1.373 +	adcb	%cl, bootsect_dst_base_hi(%si)	# breaks 16M limit ?
   1.374 +#endif
   1.375 +#else
   1.376 +#ifdef MORETHAN16M
   1.377 +	addw	$0x100, %ax		# next dest (ax+=LOADSZ/256)
   1.378 +	adcb	%cl, bootsect_dst_base_hi(%si)	# breaks 16M limit ?
   1.379 +#else
   1.380 +	incb	%ah			# next dest (ax+=LOADSZ/256)
   1.381 +#endif
   1.382 +#endif
   1.383 +#ifdef USEA20BUFFER
   1.384 +	movw	$(LOADSZ+A20BUFFER)>>8, %di
   1.385 +#endif
   1.386 +	popf
   1.387 +	ja	syslp
   1.388 +#ifdef INITRD_SUPPORT
   1.389 +initrdlp2:
   1.390 +#ifdef INITRD_AUTOADDR
   1.391 +	movw	$0x209, %cx
   1.392 +#else
   1.393 +	movb	$9, %cl
   1.394 +#endif
   1.395 +#ifdef MULTI_INITRD
   1.396 +	movw	$cur_initrd_size_ofs, %di
   1.397 +	movw	(%di), %bx
   1.398 +	addw	$4, (%di)
   1.399 +	shrw	%cl, boot_flag_ofs-cur_initrd_size_ofs(%di)
   1.400 +	je	nextInitrd	
   1.401 +	orw	%bx, %bx
   1.402 +	je	bootit			# no initrd
   1.403 +	autoaddr	cur_initrd_size_ofs(%di)
   1.404 +	movw	ramdisk_image+1,%ax
   1.405 +	jmp	initrdlp
   1.406 +nextInitrd:
   1.407 +	pushw	%bx
   1.408 +	movl	-4(%bx), %ebx
   1.409 +	addl	%ebx, ramdisk_size_ofs-cur_initrd_size_ofs(%di)
   1.410 +	movb	$swap_floppy2-0x100, %cs:dpy_swap_floppy-2+0x7C00
   1.411 +	popw	%bx
   1.412 +	cmpb	2(%di), %bl
   1.413 +	jb	initrdlp
   1.414 +#else
   1.415 +	movw	$ramdisk_size, %bx
   1.416 +#ifdef MORETHAN16M
   1.417 +	cmpb	%cl, ramdisk_image+2-ramdisk_size(%bx)
   1.418 +	jb	bootit
   1.419 +	autoaddr	ramdisk_size_ofs(%bx)
   1.420 +	movw	ramdisk_image+1,%ax
   1.421 +	shrw	%cl, boot_flag-ramdisk_size(%bx)
   1.422 +	jne	initrdlp
   1.423 +#else
   1.424 +	movw	ramdisk_image+1,%ax
   1.425 +	cmpw	%ax, bootsect_dst_base+1(%si)
   1.426 +	jb	initrdlp
   1.427 +#endif
   1.428 +#endif
   1.429 +bootit:
   1.430 +#ifdef USEA20BUFFER
   1.431 +#ifdef MORETHAN16M
   1.432 +#ifdef INITRD_SUPPORT
   1.433 +	movb	%al, bootsect_dst_base_hi(%si)		// assume @initrd 64k aligned
   1.434 +	//movb	$0, bootsect_dst_base_hi(%si)
   1.435 +#else
   1.436 +	movb	%cl, bootsect_dst_base_hi(%si)
   1.437 +#endif
   1.438 +#endif
   1.439 +	movb	$0x10, bootsect_dst_base+2(%si)		// assume @initrd 64k aligned
   1.440 +	//movw	$0x1000, bootsect_dst_base+1(%si)		// assume @initrd page aligned
   1.441 +	movw	$A20BUFFER/0x100, bootsect_src_base+1(%si)
   1.442 +	movb	$0x87, %ah
   1.443 +	int	$0x15
   1.444 +#endif
   1.445 +#endif
   1.446 +#ifdef MULTI_INITRD
   1.447 +        jcxz	read_sectorslp
   1.448 +#endif
   1.449 +
   1.450 +# This procedure turns off the floppy drive motor, so
   1.451 +# that we enter the kernel in a known state, and
   1.452 +# don't have to worry about it later.
   1.453 +
   1.454 +kill_motor:
   1.455 +#ifdef USEA20BUFFER
   1.456 +	cwd
   1.457 +#else
   1.458 +	xchgw	%ax, %di		# reset FDC (%di < 128)
   1.459 +#endif
   1.460 +	int	$0x13
   1.461 +
   1.462 +# After that (everything loaded), we jump to the setup-routine
   1.463 +# loaded directly after the bootblock:
   1.464 +# Segments are as follows: %ds = %ss = INITSEG
   1.465 +
   1.466 +	ljmp	$SETUPSEG, $0
   1.467 +
   1.468 +# read_sectors reads %di sectors into %es:0 buffer.
   1.469 +# %es:0 is updated to the next memory location.
   1.470 +# First, sectors are read sector by sector until
   1.471 +# sector per track count is known. Then they are
   1.472 +# read track by track.
   1.473 +# Assume no error on first track.
   1.474 +
   1.475 +#ifndef EXE_ONLY
   1.476 +
   1.477 +#define FLOPPY_CYLINDERS	80	
   1.478 +#define FLOPPY_HEADS		2	
   1.479 +
   1.480 +.macro	putsmsg
   1.481 +#if !defined(SINGLE_FLOPPY) && defined(COUNTER)
   1.482 +	movw	$msgdigit+1-msg, %bx
   1.483 +nextdigit:
   1.484 +	andb	$0xF0, (%bx,%si)
   1.485 +	decw	%bx
   1.486 +	incb	(%bx,%si)
   1.487 +	cmpb	$'9', (%bx,%si)
   1.488 +	ja	nextdigit
   1.489 +#endif
   1.490 +	call	puts
   1.491 +.endm
   1.492 +
   1.493 +check_limits:
   1.494 +	popw	%dx
   1.495 +        cmpb    %al, %cl		# max sector known ?
   1.496 +        ja	next_head		#   no -> store it
   1.497 +	pushaw
   1.498 +        int     $0x13			# reset controler
   1.499 +	stc
   1.500 +	call	putcdot			# print '-'
   1.501 +read_sectorslp:
   1.502 +	popaw
   1.503 +bdendlp:
   1.504 +	pushw	%dx			# some bios break dx...
   1.505 +        pushw   %ax			# limits
   1.506 +	subb	%cl, %al		# sectors remaining in track
   1.507 +	ja	tolastsect
   1.508 +	movb	$1, %al			# 1 sector mini
   1.509 +tolastsect:
   1.510 +	cmpw	%di, %ax
   1.511 +	jb	more1trk
   1.512 +	movw	%di, %ax		# sectors to read
   1.513 +more1trk:
   1.514 +	pushw	%ax			# save context
   1.515 +	movb	$2, %ah			# cmd: read chs
   1.516 +        int     $0x13
   1.517 +	popw	%dx			# save %ax
   1.518 +        popw    %ax			# limits
   1.519 +	jc	check_limits
   1.520 +	xchgw	%ax, %bp
   1.521 +	addw	%dx,%cx			# next sector
   1.522 +	movw	%cx, %gs
   1.523 +	addb	%dl,%bh
   1.524 +	addb	%dl,%bh			# next location
   1.525 +	subw	%dx,%di			# update sector counter
   1.526 +	popw	%dx
   1.527 +	jz	putcdot
   1.528 +read_sectors:
   1.529 +	movw	%gs, %cx
   1.530 +#   al is last sector+1
   1.531 +#   ah is 0
   1.532 +	xchgw	%ax, %bp
   1.533 +        cmpb    %al,%cl			# reach sector limit ?
   1.534 +        jne     bdendlp
   1.535 +next_head:
   1.536 +        movb    %cl,%al
   1.537 +        movb    $1, %cl			# first sector
   1.538 +inc_head:
   1.539 +        xorb    %cl, %dh		# next head
   1.540 +        jne	bdendlp			# reach head limit ?
   1.541 +        incb    %ch			# next cylinder
   1.542 +read_first_sectors:
   1.543 +#ifdef SINGLE_FLOPPY
   1.544 +	jmp	bdendlp
   1.545 +#else
   1.546 +        cmpb    $FLOPPY_CYLINDERS,%ch	# reach cylinder limit ?
   1.547 +        jne	bdendlp
   1.548 +next_floppy:
   1.549 +	movb	$0,%ch			# first cylinder
   1.550 +	pushaw
   1.551 +	movw	$swap_floppy,%si
   1.552 +dpy_swap_floppy:
   1.553 +#ifdef KEYBOARDLESS_SUPPORT
   1.554 +	pushw	%bx
   1.555 +	putsmsg
   1.556 +	popw	%bx
   1.557 +	movw	%si, %bp
   1.558 +waitfloppy:
   1.559 +	call	wait
   1.560 +	jne	waitfloppydone
   1.561 +#ifdef MULTI_INITRD
   1.562 +	decb	(%si)			# max_timeouts	
   1.563 +gobootit:
   1.564 +	//movw	ramdisk_size+2-max_timeouts(%si), %cx
   1.565 +	.byte	0x8B, 0x4C, ramdisk_size+2-max_timeouts
   1.566 +	jz	bootit
   1.567 +#endif
   1.568 +	pushw	%dx			# some bios break dx...
   1.569 +	cbw
   1.570 +	int	$0x13			# reset FDC
   1.571 +	movw	$0x201,%ax
   1.572 +	int	$0x13			# read first sector
   1.573 +	popw	%dx
   1.574 +	rclb	$1,%ah			# floppy changed 06=>0D no error 00
   1.575 +	cmpb	-2(%bp), %ah		# 0D then 00
   1.576 +	jne	waitfloppy		# no => try again
   1.577 +	incw	%bp
   1.578 +	decw	%ax			# was 0001 ?
   1.579 +	jne	waitfloppy
   1.580 +waitfloppydone:
   1.581 +#else
   1.582 +	putsmsg
   1.583 +	cbw				# %ah = 0, get keyboard character
   1.584 +	int	$0x16
   1.585 +#endif
   1.586 +#ifdef MULTI_INITRD
   1.587 +	orb	$0x20, %al
   1.588 +	cmp	$'b', %al
   1.589 +        jz	gobootit
   1.590 +#endif
   1.591 +        jmp	read_sectorslp
   1.592 +#endif
   1.593 +#endif
   1.594 +
   1.595 +#ifdef EXE_SUPPORT
   1.596 +read_sectors_dos:
   1.597 +	xorw	%dx, %dx	// write to %ds:%dx, not %es:%bx
   1.598 +	call	read_sectors_dosz
   1.599 +read_sectors_dosz:
   1.600 +	pushw	%es
   1.601 +	popw	%ds
   1.602 +	movb	$0x3F, %ah	// read
   1.603 +	movw	%di, %cx
   1.604 +	shlw	$8, %cx		// byte count / 2
   1.605 +	movw	%bp, %bx
   1.606 +	int	$0x21
   1.607 +	xchgw	%ax, %dx
   1.608 +	pushw	%ss
   1.609 +	popw	%ds
   1.610 +#endif
   1.611 +
   1.612 +putcdot:
   1.613 +	movb	$'.'+3, %al	// . = success, - = failure
   1.614 +putclf:
   1.615 +	sbbb	$3, %al
   1.616 +putc:
   1.617 +	movb	$0xe, %ah
   1.618 +	movw	$7, %bx			#   one dot each 64k
   1.619 + 	int	$0x10
   1.620 +	cmp	$0xd, %al		# CR ?
   1.621 +	je	putclf
   1.622 +	ret
   1.623 +
   1.624 +#ifdef KEYBOARDLESS_SUPPORT
   1.625 +clock	= 0x46C
   1.626 +wait:
   1.627 +wait4key:
   1.628 +	movw	$clock, %di
   1.629 +#define DELAY 5
   1.630 +	movb	$257-(DELAY*182)/10, %fs:(%di)
   1.631 +waitkbd:
   1.632 +	movw	$0x10D, %ax		# test keyboard, timeout => CR
   1.633 +	cmpb	%fs:(%di),%ah
   1.634 +	je	waitdone
   1.635 +	int	$0x16
   1.636 +	jz	waitkbd
   1.637 +	cbw
   1.638 +	int	$0x16			# eat char
   1.639 +	movw	%di, %fs		# disable timeout
   1.640 +	incw	%di			# clear Z
   1.641 +waitdone:
   1.642 +	ret
   1.643 +#endif
   1.644 +
   1.645 +#ifdef EXE_SUPPORT
   1.646 +comstart:
   1.647 +#ifndef EXE_ONLY
   1.648 +	call	initregs
   1.649 +#else
   1.650 +	INIT_REGS
   1.651 +#endif
   1.652 +	movb	EXEADRS(setup_sects), %al	# read bootsector + setup
   1.653 +	incw	%ax
   1.654 +#ifdef EXE_CMDLINE
   1.655 +	movw	$0x80, %si
   1.656 +	movb	(%si), %cl
   1.657 +	incw	%si
   1.658 +# ifdef OLDCMDLINE
   1.659 +#  ifdef FLOPPY_CMDLINE
   1.660 +	jcxz	nocmdline
   1.661 +	movw	%di, EXEADRS(0x22)
   1.662 +	movw	$0xA33F, 0x7F(%si)
   1.663 +#  endif
   1.664 +# endif
   1.665 +	rep
   1.666 +	  movsb
   1.667 +nocmdline:
   1.668 +	xchgw	%ax, %di
   1.669 +# ifdef HELP
   1.670 +	cmpb	$'?', -1(%si)
   1.671 +	movw	$EXEADRS(0x200), %si
   1.672 +	je	puts_version
   1.673 +#  ifndef REALMODE_NOT_CHECKED
   1.674 +	smsww	%ax
   1.675 +	andb	$1, %al
   1.676 +	jne	puts_version			// real mode only...
   1.677 +#  endif
   1.678 +# endif
   1.679 +#else
   1.680 +	xchgw	%ax, %di
   1.681 +#endif
   1.682 +	movw	0x2C(%bx), %ds	// DOS 3.0+
   1.683 +loop1:
   1.684 +	incw	%bx
   1.685 +	cmpw	%cx, (%bx)
   1.686 +	jne	loop1
   1.687 +	leaw	4(%bx), %dx 	// %ds:%dx filename
   1.688 +#if !defined(REALMODE_NOT_CHECKED) && defined(EXE_CMDLINE) && defined(HELP)
   1.689 +	movb	$0x3D, %ah	// open, access = RO
   1.690 +#else
   1.691 +	movw	$0x3D00, %ax	// open, access = RO
   1.692 +#endif
   1.693 +	int	$0x21
   1.694 +	jc	dosexit
   1.695 +	xchgw	%ax, %bp	// fd
   1.696 +	call	read_sectors_dos	// update %ds
   1.697 +#ifndef EXE_ONLY
   1.698 +	addb	$read_sectors_dos-read_sectors, patchcall+1
   1.699 +#endif
   1.700 +#ifdef EXE_CMDLINE
   1.701 +# ifdef OLDCMDLINE
   1.702 +	movw	$0x202, %bx
   1.703 +	cmpw	%bx, 0x206-0x202(%bx)	# new cmdline for version >= 0x202
   1.704 +	jb	oldcmdline
   1.705 +	movw	$INITSEG/16+stacktop/256, cmd_line_ptr+1-0x202(%bx)
   1.706 +# else
   1.707 +	movw	$INITSEG/16+stacktop/256, cmd_line_ptr+1
   1.708 +# endif
   1.709 +oldcmdline:
   1.710 +#endif
   1.711 +//	ljmp	$INITSEG, $loadsys
   1.712 +	pushw	%ds
   1.713 +	.byte	0x6A, loadsys-bootsect_start
   1.714 +	lretw
   1.715 +#endif
   1.716 +#define kernel_version_offset	0xE
   1.717 +puts_version:
   1.718 +	addw	kernel_version_offset(%si),%si	# starting protocol 2.00, Kernel 1.3.73
   1.719 +puts:
   1.720 +	movb	$0xd, %al		# CR
   1.721 +putcs:
   1.722 +	call	putc
   1.723 +	lodsb
   1.724 +	cmpb	$0, %al			# end of string is any byte <= 0
   1.725 +	jg	putcs
   1.726 +dosexit:
   1.727 +	ret	
   1.728 +
   1.729 +#if !defined(FLOPPY_ONLY) && !defined(EXE_ONLY)
   1.730 +initregs:
   1.731 +	popw	%si
   1.732 +	INIT_REGS
   1.733 +	pushw	%si			# use new stack
   1.734 +	ret
   1.735 +#endif
   1.736 +
   1.737 +
   1.738 +#if !defined(SINGLE_FLOPPY) && !defined(EXE_SUPPORT)
   1.739 +#ifdef MULTI_INITRD
   1.740 +swap_floppy2:
   1.741 +	.ascii	"B or "
   1.742 +#endif
   1.743 +swap_floppy:
   1.744 +#ifdef COUNTER
   1.745 +msg:
   1.746 +	.ascii	"Put disk 00"
   1.747 +msgdigit:
   1.748 +	.ascii	"1, press Enter."
   1.749 +#else
   1.750 +	.ascii	"Next!"
   1.751 +#endif
   1.752 +	.byte	7,13,0			# swap detection needs 13, 0
   1.753 +#ifdef MULTI_INITRD
   1.754 +max_timeouts:
   1.755 +	.byte	20
   1.756 +table:
   1.757 +	.org	cur_initrd_size_ofs
   1.758 +cur_initrd_size:
   1.759 +	.word	table
   1.760 +	.byte	table+4-256
   1.761 +#endif
   1.762 +#endif
   1.763 +#ifdef	README_SUPPORT
   1.764 +	.org	0x1EF
   1.765 +readme:
   1.766 +	.word	0
   1.767 +#endif
   1.768 +#ifdef LABEL
   1.769 +	.ascii LABEL
   1.770 +#endif
   1.771 +	.org	0x1F1
   1.772 +
   1.773 +#ifdef MULTI_INITRD
   1.774 +	.org	0x400
   1.775 +	
   1.776 +	orw	$0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader
   1.777 +	pushal
   1.778 +	
   1.779 +	movw	$10+16, %cx
   1.780 +fillbuf:
   1.781 +	pushw	$0
   1.782 +	loop	fillbuf
   1.783 +	popal			// clear regiters
   1.784 +maploop:
   1.785 +	movw	%sp, %di	// %es = %ss
   1.786 +	movb	$20, %cl
   1.787 +	movw	$0xE820, %ax
   1.788 +	movl	$0x534d4150, %edx
   1.789 +	int	$0x15
   1.790 +	sbbl	%eax, %edx
   1.791 +	jne	mapdone
   1.792 +	decw	16(%di)	
   1.793 +	jne	notram
   1.794 +	addw	8+2(%di), %bp
   1.795 +notram:
   1.796 +	orw	%bx, %bx
   1.797 +	jnz	maploop
   1.798 +mapdone:
   1.799 +	addw	$20, %sp
   1.800 +	shrw	$20-16,%bp
   1.801 +	jnz	mapdone2
   1.802 +	movb	$0x88, %ah
   1.803 +	int	$0x15
   1.804 +	xchgw	%ax, %bp
   1.805 +	shrw	$10, %bp
   1.806 +mapdone2:
   1.807 +	incw	%bp
   1.808 +// %bp : nb Mb	
   1.809 +	call	here
   1.810 +here:
   1.811 +	popw	%di
   1.812 +	movw	$0x1EE, %si
   1.813 +	lodsw
   1.814 +sizeloop:
   1.815 +	scasw			// %di += 2
   1.816 +	addw	$4, %ax
   1.817 +	cmpb	%al, (%si)	
   1.818 +	jbe	sizedone
   1.819 +	cmpw	%bp, sizes-here(%di)
   1.820 +	jbe	sizeloop
   1.821 +	movb	%al, (%si)
   1.822 +sizedone:
   1.823 +	popal
   1.824 +	lret			// need %si
   1.825 +sizes:
   1.826 +
   1.827 +#endif