wok diff memtest/stuff/bootloader.S @ rev 15280

cinepaint: remove a wrong error trigger (again)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Sep 26 13:12:43 2013 +0000 (2013-09-26)
parents
children d9dd83ccc85f
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/memtest/stuff/bootloader.S	Thu Sep 26 13:12:43 2013 +0000
     1.3 @@ -0,0 +1,389 @@
     1.4 +SYSSEG		= 0x1000
     1.5 +INITSEG		= 0x9000
     1.6 +SETUPSEG	= 0x9020
     1.7 +
     1.8 +setup_sects	= 497
     1.9 +syssize		= 500
    1.10 +
    1.11 +	.text
    1.12 +	.code16
    1.13 +	.org	0
    1.14 +	.globl	_start
    1.15 +_start:
    1.16 +
    1.17 +#define CODESZ 512
    1.18 +
    1.19 +/* some extra features */
    1.20 +#define EXE_SUPPORT		real mode dos .exe file support
    1.21 +#define CMDLINE	0x9E00
    1.22 +#define HELP			store help message for /? argument
    1.23 +#define CHECK_REALMODE		does not support vm86
    1.24 +
    1.25 +/* some contraints to reduce the size */
    1.26 +//#define FLOPPY_1440K_ONLY	1.44M floppies support only
    1.27 +#define NO_CURSOR_DEFINITION
    1.28 +
    1.29 +#ifdef EXE_SUPPORT
    1.30 +#define EXEADRS(x)	x+0xE0
    1.31 +stacktop	= 0x9E00		# in 0x8000 .. 0xA000
    1.32 +	decw	%bp			// Magic number: MZ
    1.33 +	popw	%dx
    1.34 +	jmp	start			// Bytes on last page of file
    1.35 +	.word	(CODESZ+511)/512	// Pages in file
    1.36 +	.word	0			// Relocations
    1.37 +	.word	(end_header-_start)/16	// Size of header in paragraphs
    1.38 +	.word	4096			// Minimum extra paragraphs needed
    1.39 +	.word	-1			// Maximum extra paragraphs needed
    1.40 +	.word	(CODESZ+15)/16		// Initial (relative) SS value
    1.41 +	.word	stacktop		// Initial SP value
    1.42 +	.word	0			// Checksum
    1.43 +	.word	EXEADRS(comstart)	// Initial IP value
    1.44 +	.word	0xFFF0			// Initial (relative) CS value
    1.45 +//	.word	0x001C			// File address of relocation table
    1.46 +//	.word	0,0,0			// Overlay number
    1.47 +	.ascii  "(SliTaz)"
    1.48 +end_header:
    1.49 +comstart:
    1.50 +#ifdef CMDLINE
    1.51 +	.word	0xA33A			// CMP     AH,[BP+DI+stacktop]
    1.52 +	.word	stacktop
    1.53 +#else
    1.54 +#undef HELP
    1.55 +#endif
    1.56 +	cld				# assume nothing
    1.57 +	pushw	$INITSEG
    1.58 +	popw	%es
    1.59 +#ifdef CMDLINE
    1.60 +	movw	%sp, %di
    1.61 +	movw	$0x80, %si
    1.62 +	lodsb
    1.63 +	cbw
    1.64 +	xchgw	%ax, %cx
    1.65 +	jcxz	nocmdline
    1.66 +	movb	$0x3F, 0x7F(%si)
    1.67 +skipspace:
    1.68 +	lodsb
    1.69 +	cmpb	$0x20, %al
    1.70 +	je	skipspace
    1.71 +	decw	%si
    1.72 +	rep
    1.73 +	  movsb
    1.74 +# ifdef HELP
    1.75 +# define PUTS
    1.76 +	movw	$EXEADRS(helpmsg), %si
    1.77 +	cmpb	$'/', %al
    1.78 +	je	puts
    1.79 +# endif
    1.80 +nocmdline:
    1.81 +#endif
    1.82 +#ifdef CHECK_REALMODE
    1.83 +#define PUTS
    1.84 +	movw	$EXEADRS(realmode_expected), %si
    1.85 +	pushfw			// save flags
    1.86 +		// bits  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
    1.87 +		// flags  0 NT  IOPL OF DF IF TF SF ZF  0 AF  0 PF  1 CF
    1.88 +	movb	$0x10, %ah	// DF = IF = TF = 0
    1.89 +	pushw	%ax
    1.90 +	popfw			// < 286 : flags[12..15] are forced 1
    1.91 +	pushfw			// = 286 : flags[12..15] are forced 0
    1.92 +	popw	%cx		// > 286 : only flags[15] is forced 0
    1.93 +	popfw			// restore flags
    1.94 +	addb	%ah, %ch	// test F0 and 00 cases
    1.95 +	cmpb	%ah, %ch
    1.96 +	jbe	puts		// C=8086/80186, Z=80286
    1.97 +	smsww	%ax
    1.98 +	andb	$1, %al
    1.99 +	jne	puts
   1.100 +#endif
   1.101 +	movw	$0x100, %si
   1.102 +	movw	$end_header, %di
   1.103 +	movb	EXEADRS(setup_sects), %ch
   1.104 +	movb	$(512-(end_header-_start))/2, %cl
   1.105 +	rep
   1.106 +	  movsw
   1.107 +	ljmp	$INITSEG, $movesys
   1.108 +start:
   1.109 +	pushw	%dx
   1.110 +	xorw	%dx, %dx
   1.111 +#else
   1.112 +#undef HELP
   1.113 +#undef CMDLINE
   1.114 +#undef CHECK_REALMODE
   1.115 +#endif
   1.116 +	cld				# assume nothing
   1.117 +stacktop	= 0x9E00		# in 0x8000 .. 0xA000
   1.118 +zeroed		= 12			# zeroed registers
   1.119 +	movw	$stacktop-12-zeroed, %di	# stacktop is an arbitrary value >=
   1.120 +					# length of bootsect + length of
   1.121 +					# setup + room for stack;
   1.122 +					# 12 is disk parm size.
   1.123 +	pushw	$INITSEG
   1.124 +	popw	%ss			# %ss contain INITSEG
   1.125 +	movw	%di, %sp		# put stack at INITSEG:stacktop-...
   1.126 +
   1.127 +# Many BIOS's default disk parameter tables will not recognize
   1.128 +# multi-sector reads beyond the maximum sector number specified
   1.129 +# in the default diskette parameter tables - this may mean 7
   1.130 +# sectors in some cases.
   1.131 +#
   1.132 +# Since single sector reads are slow and out of the question,
   1.133 +# we must take care of this by creating new parameter tables
   1.134 +# (for the first disk) in RAM.  We can set the maximum sector
   1.135 +# count to 36 - the most we will encounter on an ED 2.88.  
   1.136 +#
   1.137 +# High doesn't hurt.  Low does.  Let's use the max: 63
   1.138 +
   1.139 +	pushw	%ss
   1.140 +	popw	%es			# %es = %ss = INITSEG
   1.141 +	xorw	%ax, %ax		# %ax = 0
   1.142 +	movw	$zeroed/2, %cx		# clear gdt + offset, %ds, limits
   1.143 +	rep				# don't worry about cld
   1.144 +	stosw				# already done above
   1.145 +	popw	%bx			# offset = 0
   1.146 +	popw	%ds			# %ds = 0
   1.147 +	popw	%fs			# %fs = 0
   1.148 +
   1.149 +	movb	setup_sects+0x7C00, %al	# read bootsector + setup (%ds = 0)
   1.150 +	incw	%ax
   1.151 +
   1.152 +	ldsw	0x78(%bx), %si		# %ds:%bx+0x78 is parameter table address
   1.153 +	pushw	%es
   1.154 +	pushw	%di
   1.155 +	movb	$6, %cl			# copy 12 bytes
   1.156 +	rep				# don't worry about cld
   1.157 +	movsw				# already done above
   1.158 +	pushw	%ss
   1.159 +	popw	%ds			# now %ds = %es = %ss = INITSEG
   1.160 +	popl	%fs:0x78(%bx)		# update parameter table address
   1.161 +	movb	$63, 0x4-12(%di)	# patch sector count, %di = stacktop
   1.162 +	cli
   1.163 +
   1.164 +	xchg	%ax, %di		# sector count
   1.165 +	popw	%ax			# limits = 0
   1.166 +	incw	%cx			# cylinder 0, sector 1, clear Z
   1.167 +	call	read_first_sectors	# read setup
   1.168 +
   1.169 +# This routine loads the system at address LOADSEG, making sure
   1.170 +# no 64kB boundaries are crossed. We try to load it as fast as
   1.171 +# possible, loading whole tracks whenever we can.
   1.172 +
   1.173 +	popw	%bx			# clear %bx
   1.174 +	movw	syssize, %di
   1.175 +	addw	$(512/16)-1, %di
   1.176 +	shrw	$9-4, %di
   1.177 +	movw	$SYSSEG, %cx
   1.178 +	call	read_sectorsCX
   1.179 +
   1.180 +# This procedure turns off the floppy drive motor, so
   1.181 +# that we enter the kernel in a known state, and
   1.182 +# don't have to worry about it later.
   1.183 +
   1.184 +kill_motor:
   1.185 +	xchgw	%ax, %di		# reset FDC (%di < 128)
   1.186 +	int	$0x13
   1.187 +
   1.188 +# After that (everything loaded), we jump to the setup-routine
   1.189 +# loaded directly after the bootblock:
   1.190 +# Segments are as follows: %ds = %ss = INITSEG
   1.191 +
   1.192 +jmp_setup:
   1.193 +	ljmp	$SETUPSEG, $0
   1.194 +
   1.195 +#ifdef PUTS
   1.196 +#define PUTC
   1.197 +puts:
   1.198 +	lodsb
   1.199 +	orb	%al, %al
   1.200 +	je	exit
   1.201 +	call	putc
   1.202 +	jmp	puts
   1.203 +#endif
   1.204 +#ifdef EXE_SUPPORT
   1.205 +movesys:
   1.206 +	pushw	%es
   1.207 +	popw	%ss
   1.208 +	movw	EXEADRS(syssize), %bp	// %ds untouched
   1.209 +	movw	$SYSSEG, %ax
   1.210 +	movw	%ds, %bx
   1.211 +	cwd
   1.212 +	incw	%dx
   1.213 +	cmpw	%ax, %bx
   1.214 +	jnc	forward
   1.215 +	negw	%dx
   1.216 +	addw	%bp, %ax
   1.217 +	addw	%bp, %bx
   1.218 +forward:
   1.219 +	movw	%ax, %es
   1.220 +	movw	%bx, %ds
   1.221 +	xorw	%di, %di
   1.222 +	movb	$8, %cl
   1.223 +	rep
   1.224 +	  movsw
   1.225 +	subw	$16, %si
   1.226 +	addw	%dx, %ax
   1.227 +	addw	%dx, %bx
   1.228 +	decw	%bp
   1.229 +	jns	forward
   1.230 +#ifndef NO_CURSOR_DEFINITION
   1.231 +	movb	$1, %ah
   1.232 +	movb	$0, %bh
   1.233 +	movb	$0x20, %ch	// 0x2000
   1.234 +	int	$0x10
   1.235 +#endif
   1.236 +	pushw	%ss
   1.237 +	popw	%ds
   1.238 +	jmp	jmp_setup
   1.239 +#endif
   1.240 +putcdot:
   1.241 +#ifdef PUTC
   1.242 +	movb	$0x2E, %al
   1.243 +putc:
   1.244 +	movb	$0xE, %ah
   1.245 +	movw	$7, %bx
   1.246 +	int	$0x10
   1.247 +#endif
   1.248 +exit:
   1.249 +	ret
   1.250 +
   1.251 +
   1.252 +# read_sectors reads %di sectors into %es:0 buffer.
   1.253 +# %es:0 is updated to the next memory location.
   1.254 +# First, sectors are read sector by sector until
   1.255 +# sector per track count is known. Then they are
   1.256 +# read track by track.
   1.257 +# Assume no error on first track.
   1.258 +
   1.259 +#ifdef FLOPPY_1440K_ONLY
   1.260 +#define FLOPPY_HEADS		2	/* 2 heads */
   1.261 +#define FLOPPY_SECTORS		18	/* 18 sectors */
   1.262 +#else
   1.263 +#define FLOPPY_HEADS		2	/* 2 heads minimum */
   1.264 +#define FLOPPY_SECTORS		9	/* 9 sectors minimum */
   1.265 +#endif
   1.266 +
   1.267 +check_limits:
   1.268 +#ifndef FLOPPY_1440K_ONLY
   1.269 +	popw	%dx
   1.270 +#ifdef FLOPPY_SECTORS
   1.271 +	cmpb	$FLOPPY_SECTORS+1, %cl	# minimum sector count
   1.272 +	jb	check_head
   1.273 +#endif
   1.274 +        cmpb    %al, %cl		# max sector known ?
   1.275 +        ja	next_head		#   no -> store it
   1.276 +check_head:
   1.277 +#ifdef FLOPPY_HEADS
   1.278 +	cmpb	$FLOPPY_HEADS, %dh	# 2 heads minimum
   1.279 +	jb	check_cylinder
   1.280 +#endif
   1.281 +        cmpb    %ah, %dh		# max head known ?
   1.282 +        ja	next_cylinder		#   no -> store it
   1.283 +check_cylinder:
   1.284 +#endif
   1.285 +	pushaw
   1.286 +#ifndef FLOPPY_1440K_ONLY
   1.287 +	cbw				# %ah = 0
   1.288 +#endif
   1.289 +        int     $0x13			# reset controler
   1.290 +	popaw
   1.291 +	movb	$1, %al			# sector by sector...
   1.292 +read_sectorslp:
   1.293 +	pushw	%dx			# some bios break dx...
   1.294 +#ifndef FLOPPY_1440K_ONLY
   1.295 +        pushw   %ax			# limits
   1.296 +	subb	%cl, %al		# sectors remaining in track
   1.297 +	ja	tolastsect
   1.298 +	movb	$1, %al			# 1 sector mini
   1.299 +tolastsect:
   1.300 +#else
   1.301 +	mov	$FLOPPY_SECTORS+1, %al
   1.302 +	subb	%cl, %al		# sectors remaining in track
   1.303 +#endif
   1.304 +	cbw
   1.305 +	cmpw	%di, %ax
   1.306 +	jb	more1trk
   1.307 +	movw	%di, %ax		# sectors to read
   1.308 +more1trk:
   1.309 +	pushw	%ax			# save context
   1.310 +	movb	$2, %ah			# cmd: read chs
   1.311 +        int     $0x13
   1.312 +#ifndef FLOPPY_1440K_ONLY
   1.313 +	popw	%dx			# save %ax
   1.314 +        popw    %ax			# limits
   1.315 +#else
   1.316 +	popw	%ax			# restore context
   1.317 +	popw	%dx
   1.318 +#endif
   1.319 +	jc	check_limits
   1.320 +#ifndef FLOPPY_1440K_ONLY
   1.321 +	xchgw	%ax, %bp
   1.322 +	addw	%dx,%cx			# next sector
   1.323 +	movw	%cx, %gs
   1.324 +	movw	%es, %cx
   1.325 +	pushw	%dx
   1.326 +	shlw	$5, %dx
   1.327 +	addw	%dx, %cx
   1.328 +	popw	%dx
   1.329 +	subw	%dx,%di			# update sector counter
   1.330 +	popw	%dx
   1.331 +read_sectorsCX:
   1.332 +	movw	%cx, %es		# next location
   1.333 +	jz	putcdot
   1.334 +#else
   1.335 +	addw	%ax,%cx			# next sector
   1.336 +	movw	%cx, %gs
   1.337 +	movw	%es, %cx
   1.338 +	pushw	%ax
   1.339 +	shlw	$5, %ax
   1.340 +	addw	%ax, %cx
   1.341 +	popw	%ax
   1.342 +	subw	%ax,%di			# update sector counter
   1.343 +read_sectorsCX:
   1.344 +	movw	%cx, %es		# next location
   1.345 +	jz	putcdot
   1.346 +#endif
   1.347 +read_sectors:
   1.348 +	movw	%gs, %cx
   1.349 +#ifndef FLOPPY_1440K_ONLY
   1.350 +#   al is last sector+1
   1.351 +#   ah is last cylinder+1
   1.352 +	xchgw	%ax, %bp
   1.353 +#endif
   1.354 +#ifndef FLOPPY_1440K_ONLY
   1.355 +        cmpb    %al,%cl			# reach sector limit ?
   1.356 +        jne     bdendlp
   1.357 +next_head:
   1.358 +        movb    %cl,%al
   1.359 +#else
   1.360 +        cmpb    $FLOPPY_SECTORS+1,%cl	# reach sector limit ?
   1.361 +        jne     bdendlp
   1.362 +#endif
   1.363 +        incb    %dh			# next head
   1.364 +        movb    $1,%cl			# first sector
   1.365 +#ifndef FLOPPY_1440K_ONLY
   1.366 +        cmpb    %ah, %dh		# reach head limit ?
   1.367 +        jne     bdendlp
   1.368 +next_cylinder:
   1.369 +        movb    %dh,%ah
   1.370 +#else
   1.371 +        cmpb    %cl,%dh			# reach head limit ?
   1.372 +        je	bdendlp
   1.373 +#endif
   1.374 +# NOTE : support 256 cylinders max
   1.375 +        incb    %ch			# next cylinder
   1.376 +read_first_sectors:
   1.377 +        movb    $0,%dh			# first head
   1.378 +bdendlp:
   1.379 +        jmp	read_sectorslp
   1.380 +
   1.381 +#ifdef CHECK_REALMODE
   1.382 +realmode_expected:
   1.383 +	.ascii	"386 real mode only."
   1.384 +	.byte	13,10,0
   1.385 +#endif
   1.386 +#ifdef HELP
   1.387 +helpmsg:
   1.388 +	.ascii	"No help available."
   1.389 +	.byte	13,10
   1.390 +	.byte	0
   1.391 +#endif
   1.392 +	.org	497