1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  linux_logo in i386 assembly language
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#    based on the code from ll_asm-0.36
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  By Vince Weaver <vince _at_ deater.net>
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Modified to remove non-deterministic system calls
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# And to avoid reading from /proc
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.include "../logo.include"
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# offsets into the results returned by the uname syscall
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_SYSNAME,0
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_NODENAME,65
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_RELEASE,65*2
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_VERSION,(65*3)
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_MACHINE,(65*4)
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_DOMAINNAME,65*5
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# offset into the results returned by the sysinfo syscall
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ S_TOTALRAM,16
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Sycscalls
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ SYSCALL_EXIT,     1
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ SYSCALL_WRITE,    4
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ STDIN,0
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ STDOUT,1
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ STDERR,2
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.globl _start
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown_start:
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========================
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# PRINT LOGO
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========================
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# LZSS decompression algorithm implementation
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# by Stephan Walter 2002, based on LZSS.C by Haruhiko Okumura 1989
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# optimized some more by Vince Weaver
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# we used to fill the buffer with FREQUENT_CHAR
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# but, that only gains us one byte of space in the lzss image.
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# the lzss algorithm does automatic RLE... pretty clever
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# so we compress with NUL as FREQUENT_CHAR and it is pre-done for us
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov     $(N-F), %bp   	     	# R
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov  	$logo, %esi		# %esi points to logo (for lodsb)
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$out_buffer, %edi	# point to out_buffer
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%edi	     		# save this value for later
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndecompression_loop:
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb			# load in a byte
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov 	$0xff, %bh	# re-load top as a hackish 8-bit counter
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov 	%al, %bl	# move in the flags
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntest_flags:
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$logo_end, %esi # have we reached the end?
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done_logo  	# if so, exit
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	shr 	$1, %ebx	# shift bottom bit into carry flag
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jc	discrete_char	# if set, we jump to discrete char
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownoffset_length:
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsw                   # get match_length and match_position
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov %eax,%edx		# copy to edx
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    			# no need to mask dx, as we do it
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				# by default in output_loop
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	shr $(P_BITS),%eax
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	add $(THRESHOLD+1),%al
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov %al,%cl             # cl = (ax >> P_BITS) + THRESHOLD + 1
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				#                       (=match_length)
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownoutput_loop:
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	and 	$POSITION_MASK,%dh  	# mask it
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov 	text_buf(%edx), %al	# load byte from text_buf[]
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc 	%edx	    		# advance pointer in text_buf
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstore_byte:
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb				# store it
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov     %al, text_buf(%ebp)	# store also to text_buf[r]
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc 	%ebp 			# r++
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	and 	$(N-1), %bp		# mask r
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	loop 	output_loop		# repeat until k>j
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	or	%bh,%bh			# if 0 we shifted through 8 and must
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jnz	test_flags		# re-load flags
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jmp 	decompression_loop
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndiscrete_char:
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb				# load a byte
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%ecx			# we set ecx to one so byte
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# will be output once
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# (how do we know ecx is zero?)
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jmp     store_byte              # and cleverly store it
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# end of LZSS code
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndone_logo:
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop 	%ebp			# get out_buffer and keep in bp
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%ecx		# move out_buffer to ecx
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	write_stdout		# print the logo
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#  Setup
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsetup:
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$strcat,%edx		# use edx as call pointer
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#==========================
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# PRINT VERSION
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#==========================
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push 	$SYSCALL_UNAME		# uname syscall
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%eax			# in 3 bytes
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$uname_info,%ebx	# uname struct
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	int	$0x80			# do syscall
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%edi		# point %edi to out_buffer
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(uname_info+U_SYSNAME),%esi	# os-name from uname "Linux"
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%edx			# call strcat
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$ver_string,%esi		# source is " Version "
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%edx			        # call strcat
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%esi  				# save our .txt pointer
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(uname_info+U_RELEASE),%esi    # version from uname "2.4.1"
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%edx				# call strcat
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%esi  			# restore .txt pointer
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# source is ", Compiled "
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%edx			# call strcat
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%esi  			# store for later
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(uname_info+U_VERSION),%esi	# compiled date
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%edx			# call strcat
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%ecx		# move out_buffer to ecx
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0xa,%ax		# store linefeed on end
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosw				# and zero
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%edx			# call strcat
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	center_and_print	# center and print
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#===============================
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Middle-Line
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#===============================
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Load /proc/cpuinfo into buffer
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%edx			# save call pointer
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push	$SYSCALL_OPEN		# load 5 [ open() ]
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%eax			# in 3 bytes
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$cpuinfo,%ebx		# '/proc/cpuinfo'
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	xor	%ecx,%ecx		# 0 = O_RDONLY <bits/fcntl.h>
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	cdq				# clear edx in clever way
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	int	$0x80			# syscall.  fd in eax.
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# we should check that eax>=0
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	%eax,%ebx		# save our fd
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push	$SYSCALL_READ		# load 3 = read()
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%eax			# in 3 bytes
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$disk_buffer,%ecx
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$16,%dh		 	# 4096 is maximum size of proc file #)
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# we load sneakily by knowing
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# 16<<8 = 4096. be sure edx clear
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	int	$0x80
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push	$SYSCALL_CLOSE		# close (to be correct)
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%eax
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	int	$0x80
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=============
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Number of CPUs
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=============
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownnumber_of_cpus:
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	xor	%ebx,%ebx		# chip count
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# $disk_buffer still in ecx
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbogo_loop:
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	(%ecx), %eax		# load 4 bytes into eax
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%ecx			# increment pointer
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0,%al			# check for end of file
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done_bogo
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Grrr, due to a bug in binutils 2.18.50.0.9
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   (which unfortunately shipped with Fedora 10)
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   http://sourceware.org/bugzilla/show_bug.cgi?id=6878
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   We can't use the apostrophe character
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	cmp	$('o'<<24+'g'<<16+'o'<<8+'b'),%eax
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$(0x6f<<24+0x67<<16+0x6f<<8+0x62),%eax
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				        # "bogo" in little-endian
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	bogo_loop		# if not equal, keep going
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%ebx			# otherwise, we have a bogo
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%ebx			# times two for future magic
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jmp	bogo_loop
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndone_bogo:
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lea	one-6(%ebx,%ebx,2), %esi
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				    	# Load into esi
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# [one]+(num_cpus*6)
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					#
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# the above multiplies by three
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# esi = (ebx+(ebx*2))
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 				# and we double-incremented ebx
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# earlier
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%edi		# move output buffer to edi
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%edx			# restore call pointer
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%edx			# copy it (call strcat)
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$' ',%al		# print a space
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0x20,%al		# print a space
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push %ebx			# store cpu count
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push %edx			# store strcat pointer
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# MHz
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint_mhz:
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$('z'<<24+'H'<<16+'M'<<8+' '),%ebx
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(0x7a<<24+0x48<<16+0x4d<<8+0x20),%ebx
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			   		# find ' MHz' and grab up to .
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	                                # we are little endian
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$'.',%ah
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0x2e,%ah
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# below is same as "sub $(strcat-find_string),%edx
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# gas won't let us force the one-byte constant
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte 0x83,0xEA,strcat-find_string
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%edx			# call find string
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebx,%eax  		# clever way to get MHz in, sadly
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ror	$8,%eax			# not any smaller than a mov
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosl
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Chip Name
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchip_name:
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# because of ugly newer cpuinfos from intel I had to hack this
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# now we grab the first two words in the name field and use that
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# it works on all recent Intel and AMD chips.  Older things
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# might choke
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$('e'<<24+'m'<<16+'a'<<8+'n'),%ebx
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(0x65<<24+0x6d<<16+0x61<<8+0x6e),%ebx
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# find 'name\t: ' and grab up to \n
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# we are little endian
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$' ',%ah
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0x20,%ah
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%edx	   		# print first word
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb				# store a space
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	skip_spaces		# print next word
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%edx
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%ebx			# restore chip count
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%esi
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%edx			# ' Processor'
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmpb	$2,%bl
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	print_s
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%esi   			# if singular, skip the s
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint_s:
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%edx			# 's, '
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%esi			# restore the values
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push 	%edx
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#========
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# RAM
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#========
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push    $SYSCALL_SYSINFO	# sysinfo() syscall
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%eax
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$sysinfo_buff,%ebx
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	int	$0x80
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	(sysinfo_buff+S_TOTALRAM),%eax	# size in bytes of RAM
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	shr	$20,%eax		# divide by 1024*1024 to get M
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adc	$0, %eax		# round
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call num_to_ascii
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop  %edx	 		# restore strcat pointer
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %esi	 		# print 'M RAM, '
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%edx			# call strcat
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%esi
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#========
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Bogomips
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#========
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$('s'<<24+'p'<<16+'i'<<8+'m'),%ebx
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(0x73<<24+0x70<<16+0x69<<8+0x6d),%ebx
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# find 'mips\t: ' and grab up to \n
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0xa,%ah
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	find_string
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%esi	   		# bogo total follows RAM
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%edx			# call strcat
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%esi
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%ecx		# point ecx to out_buffer
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	center_and_print	# center and print
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=================================
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Print Host Name
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=================================
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov     %ebp,%edi		  # point to output_buffer
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(uname_info+U_NODENAME),%esi	# host name from uname()
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call    *%edx			  # call strcat
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      			# ecx is unchanged
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	center_and_print	# center and print
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%ecx			# (.txt) pointer to default_colors
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	write_stdout
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Exit
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownexit:
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	xor     %ebx,%ebx
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	xor	%eax,%eax
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%eax	 		# put exit syscall number (1) in eax
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int     $0x80             	# and exit
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=================================
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# FIND_STRING
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=================================
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   ah is char to end at
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   ebx is 4-char ascii string to look for
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   edi points at output buffer
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfind_string:
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$disk_buffer-1,%esi	# look in cpuinfo buffer
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfind_loop:
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%esi
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmpb	$0, (%esi)		# are we at EOF?
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done			# if so, done
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	(%esi), %ebx		# do the strings match?
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	find_loop		# if not, loop
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# ! if we get this far, we matched
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfind_colon:
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb				# repeat till we find colon
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0,%al			# this is actually smaller code
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done			#   than an or ecx/repnz scasb
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	cmp	$':',%al
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0x3a,%al
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	find_colon
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownskip_spaces:
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        lodsb                           # skip spaces
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp     $0x20,%al               # Loser new intel chips have lots??
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        je      skip_spaces
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstore_loop:
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0,%al
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	%ah,%al			# is it end string?
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je 	almost_done		# if so, finish
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	cmp	$'\n',%al		# also end if linefeed
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0xa,%al		# also end if linefeed
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	almost_done
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb				# if not store and continue
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb				# load value
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jmp	store_loop
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownalmost_done:
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	movb	 $0, (%edi)	        # replace last value with NUL
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndone:
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# strcat
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstrcat:
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb				# load a byte from [ds:esi]
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb				# store a byte to [es:edi]
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0,%al			# is it zero?
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	strcat			# if not loop
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dec	%edi			# point to one less than null
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret				# return
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#==============================
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# center_and_print
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#==============================
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# string to center in ecx
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncenter_and_print:
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push    %edx
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%ecx			# save the string pointer
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%edi			# move to a clear buffer
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%edi			# save for later
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$('['<<8+27),%ax	# we want to output ^[[
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(0x5b<<8+27),%ax	# we want to output ^[[
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosw
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cdq	      			# clear dx
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstr_loop2:				# find end of string
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%edx
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmpb	$0,(%ecx,%edx)		# repeat till we find zero
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	str_loop2
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	$81	 		# one added to cheat, we don't
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# count the trailing '\n'
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%eax
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	%eax,%edx		# see if we are >=80
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jl	not_too_big		# if so, don't center
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	$80
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%edx
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownnot_too_big:
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	sub	%edx,%eax		# subtract size from 80
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	shr	%eax			# then divide by 2
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	num_to_ascii		# print number of spaces
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$'C',%al		# tack a 'C' on the end
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0x43,%al		# tack a 'C' on the end
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# ah is zero from num_to_ascii
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosw				# store C and a NULL
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop  %ecx			# pop the pointer to ^[[xC
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call write_stdout		# write to the screen
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndone_center:
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop  %ecx			# restore string pointer
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     				# and trickily print the real string
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop %edx
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# WRITE_STDOUT
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# ecx has string
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# eax,ebx,ecx,edx trashed
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownwrite_stdout:
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push    %edx
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	$SYSCALL_WRITE		# put 4 in eax (write syscall)
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %eax     		# in 3 bytes of code
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cdq   	      			# clear edx
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	xor	%ebx,%ebx		# put 1 in ebx (stdout)
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%ebx			# in 3 bytes of code
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			# another way of doing this:    lea 1(%edx), %ebx
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstr_loop1:
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%edx
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmpb	$0,(%ecx,%edx)		# repeat till zero
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	str_loop1
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int	$0x80  			# run the syscall
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%edx
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	##############################
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# num_to_ascii
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	##############################
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# ax = value to print
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# edi points to where we want it
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownnum_to_ascii:
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push    $10
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %ebx
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	xor     %ecx,%ecx       # clear ecx
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndiv_by_10:
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cdq                     # clear edx
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	div     %ebx            # divide
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push    %edx            # save for later
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc     %ecx            # add to length counter
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	or      %eax,%eax       # was Q zero?
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jnz     div_by_10       # if not divide again
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownwrite_out:
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %eax            # restore in reverse order
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	add     $0x30, %al      # convert to ASCII
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb                   # save digit
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	loop    write_out       # loop till done
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#===========================================================================
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	section .data
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#===========================================================================
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.data
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownver_string:	.ascii	" Version \0"
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncompiled_string:	.ascii	", Compiled \0"
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprocessor:		.ascii " Processor\0"
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browns_comma:		.ascii "s, \0"
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownram_comma:	.ascii	"M RAM, \0"
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbogo_total:	.ascii	" Bogomips Total\n\0"
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndefault_colors:	.ascii "\033[0m\n\n\0"
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncpuinfo:	.ascii	"/proc/cpuinfo\0"
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownone:	.ascii	"One\0\0\0"
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntwo:	.ascii	"Two\0\0\0"
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownthree:	.ascii	"Three\0"
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfour:	.ascii	"Four\0"
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.include	"../logo.lzss_new"
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndisk_buffer:
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "processor	: 0\n"
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "vendor_id	: AuthenticAMD\n"
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpu family	: 6\n"
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "model		: 6\n"
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "model name	: AMD Athlon(tm) XP 2000+\n"
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "stepping	: 2\n"
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpu MHz		: 1665.267\n"
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cache size	: 256 KB\n"
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "fdiv_bug	: no\n"
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "hlt_bug		: no\n"
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "f00f_bug	: no\n"
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "coma_bug	: no\n"
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "fpu		: yes\n"
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "fpu_exception	: yes\n"
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpuid level	: 1\n"
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "wp		: yes\n"
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 mmx fxsr sse syscall mmxext 3dnowext 3dnow up\n"
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "bogomips	: 3330.53\n"
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "clflush size	: 32\n"
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "power management: ts\n\0"
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuname_info:
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "Linux\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "tobler\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "2.6.29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "#1 SMP Mon May 4 09:51:54 EDT 2009\0\0"
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsysinfo_buff:
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.long 0,0,0,0,512*1024*1024,0,0,0,0
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.long 0,0,0,0,0,0,0,0,0
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#============================================================================
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	section .bss
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#============================================================================
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.bss
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.lcomm  text_buf, (N+F-1)
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.lcomm	out_buffer,16384
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
626