[comp.os.minix] Minix diff's for Turbo C Part 2 of 2

aiv@euraiv1.UUCP (Eelco van Asperen) (07/31/87)

	[this is the second (and last) part of my posting;
	 unshar it in the same directory as the first one and 
	 start reading the readme-file.
									Eelco]

# This is a shar archive.  Extract with sh, not csh.
# This archive ends with exit, so do not worry about trailing junk.
# --------------------------- cut here --------------------------
PATH=/bin:/usr/bin
echo Extracting kernel/Makefile
sed 's/^X//' > kernel/Makefile << '+ END-OF-FILE 'kernel/Makefile
XOBJS=	CLOCK.OBJ DMP.OBJ FLOPPY.OBJ MAIN.OBJ MEMORY.OBJ \
X	PRINTER.OBJ PROC.OBJ SYSTEM.OBJ TABLE.OBJ TTY.OBJ XT_WINI.OBJ
X
X
Xkernel:	$(OBJS) mpx88.obj klib88.obj
X	link @linklist
X	dos2out -d kernel
X
X.c.obj:
X	tcc -A -mt -I..\include -Di8088 -DTURBO -c $<
X
X.asm.obj:	
X	masm /mx $<,,nul,nul
X
Xmpx88.obj:	mpx88.asm
Xklib88.obj:	klib88.asm
+ END-OF-FILE kernel/Makefile
chmod 'u=rw,g=r,o=r' kernel/Makefile
set `sum kernel/Makefile`
sum=$1
case $sum in
23861)	:;;
*)	echo 'Bad sum in 'kernel/Makefile >&2
esac
echo Extracting kernel/klib88.asm
sed 's/^X//' > kernel/klib88.asm << '+ END-OF-FILE 'kernel/klib88.asm
Xtitle klib88
Xpage,132
X
X; This file contains a number of assembly code utility routines	needed by the
X; kernel.  They	are:
X;
X;   phys_copy:	copies data from anywhere to anywhere in memory
X;   cp_mess:	copies messages	from source to destination
X;   port_out:	outputs	data on	an I/O port
X;   port_in:	inputs data from an I/O	port
X;   lock:	disable	interrupts
X;   unlock:	enable interrupts
X;   restore:	restore	interrupts [enable/disabled] as	they were before lock[]
X;   build_sig:	build 4	word structure pushed onto stack for signals
X;   csv:	procedure prolog to save the registers
X;   cret:	procedure epilog to restore the	registers
X;   get_chrome:	returns	0 is display is	monochrome, 1 if it is color
X;   vid_copy:	copy data to video ram [on color display during	retrace	only]
X;   get_byte:	reads a	byte from a user program and returns it	as value
X
X
XTURBO equ 1
X
X; The following	procedures are defined in this file and	called from outside it.
XPUBLIC _phys_copy, _cp_mess, _port_out, _port_in, _lock, _unlock, _restore
XPUBLIC _build_sig, _get_chrome, _vid_copy, _get_byte
X
Xifndef TURBO
XPUBLIC_csv, _cret 
Xendif
X
XPUBLIC _reboot, _wreboot
X
X; The following	external procedure is called in	this file.
XEXTRN _panic:NEAR
X
X; Variables and	data structures
XEXTRN _color:WORD, _cur_proc:WORD, _proc_ptr:WORD, _splimit:WORD
XEXTRN _vid_mask:WORD		; declared in tty.c
XPUBLIC _vec_table
X
XINCLUDE	..\lib\prologue.h
X
X
X_TEXT	SEGMENT
X	assume	cs:_TEXT,ds:dgroup
X
X;===========================================================================
X;				phys_copy
X;===========================================================================
X; This routine copies a	block of physical memory.  It is called	by:
X;    phys_copy(	(long) source, (long) destination, (long) bytecount)
X
X_phys_copy:
X	pushf			; save flags
X	cli			; disable interrupts
X	push bp			; save the registers
X	push ax			; save ax
X	push bx			; save bx
X	push cx			; save cx
X	push dx			; save dx
X	push si			; save si
X	push di			; save di
X	push ds			; save ds
X	push es			; save es
X	mov bp,sp		; set bp to point to saved es
X
X  L0:	mov ax,28[bp]		; ax = high-order word of 32-bit destination
X	mov di,26[bp]		; di = low-order word of 32-bit	destination
X	mov cx,4		; start	extracting click number	from dest
X  L1:	rcr ax,1		; click	number is destination address /	16
X	rcr di,1		; it is	used in	segment	register for copy
X	loop L1			; 4 bits of high-order word are	used
X	mov es,di		; es = destination click
X
X	mov ax,24[bp]		; ax = high-order word of 32-bit source
X	mov si,22[bp]		; si = low-order word of 32-bit	source
X	mov cx,4		; start	extracting click number	from source
X  L2:	rcr ax,1		; click	number is source address / 16
X	rcr si,1		; it is	used in	segment	register for copy
X	loop L2			; 4 bits of high-order word are	used
X	mov ds,si		; ds = source click
X
X	mov di,26[bp]		; di = low-order word of dest address
X	and di,000Fh		; di = offset from paragraph  in es
X	mov si,22[bp]		; si = low-order word of source	address
X	and si,000Fh		; si = offset from paragraph  in ds
X
X	mov dx,32[bp]		; dx = high-order word of byte count
X	mov cx,30[bp]		; cx = low-order word of byte count
X
X	test cx,8000h		; if bytes >= 32768, only do 32768
X	jnz L3			; per iteration
X	test dx,0FFFFh		; check	high-order 17 bits to see if bytes
X	jnz L3			; if bytes >= 32768 then go to L3
X	jmp short L4		; if bytes < 32768 then	go to L4
X  L3:	mov cx,8000h		; 0x8000 is unsigned 32768
X  L4:	mov ax,cx		; save actual count used in ax;	needed later
X
X	test cx,0001h		; should we copy a byte	or a word at a time?
X	jz L5			; jump if even
X	rep movsb		; copy 1 byte at a time
X	jmp short L6		; check	for more bytes
X
X  L5:	shr cx,1		; word copy
X	rep movsw		; copy 1 word at a time
X
X  L6:	mov dx,32[bp]		; decr count, incr src & dst, iterate if needed
X	mov cx,30[bp]		; dx ||	cx is 32-bit byte count
X	xor bx,bx		; bx ||	ax is 32-bit actual count used
X	sub cx,ax		; compute bytes	- actual count
X	sbb dx,bx		; dx ;;	cx is  bytes not yet processed
X	or cx,cx		; see if it is 0
X	jnz L7			; if more bytes	then go	to L7
X	or dx,dx		; keep testing
X	jnz L7			; if loop done,	fall through
X
X	pop es			; restore all the saved	registers
X	pop ds			; restore ds
X	pop di			; restore di
X	pop si			; restore si
X	pop dx			; restore dx
X	pop cx			; restore cx
X	pop bx			; restore bx
X	pop ax			; restore ax
X	pop bp			; restore bp
X	popf			; restore flags
X	ret			; return to caller
X
XL7:	mov 32[bp],dx		; store	decremented byte count back in mem
X	mov 30[bp],cx		; as a long
X	add 26[bp],ax		; increment destination
X	adc 28[bp],bx		; carry	from low-order word
X	add 22[bp],ax		; increment source
X	adc 24[bp],bx		; carry	from low-order word
X	jmp L0			; start	next iteration
X
X
X;===========================================================================
X;				cp_mess
X;===========================================================================
X; This routine is makes	a fast copy of a message from anywhere in the address
X; space	to anywhere else.  It also copies the source address provided as a
X; parameter to the call	into the first word of the destination message.
X; It is	called by:
X;    cp_mess[src, src_clicks, src_offset, dst_clicks, dst_offset]
X; where	all 5 parameters are shorts [16-bits].
X;
X; Note that the	message	size, 'Msize' is in WORDS [not bytes] and must be set
X; correctly.  Changing the definition of message the type file and not changing
X; it here will lead to total disaster.
X; This routine destroys	ax.  It	preserves the other registers.
X
XMsize =	12			; size of a message in 16-bit words
X_cp_mess:
X	push bp			; save bp
X	push es			; save es
X	push ds			; save ds
X	mov bp,sp		; index	off bp because machine can't use sp
X	pushf			; save flags
X	cli			; disable interrupts
X	push cx			; save cx
X	push si			; save si
X	push di			; save di
X
X	mov ax,8[bp]		; ax = process number of sender
X	mov di,16[bp]		; di = offset of destination buffer
X	mov es,14[bp]		; es = clicks of destination
X	mov si,12[bp]		; si = offset of source	message
X	mov ds,10[bp]		; ds = clicks of source	message
X	mov es:[di],ax		; copy sender's	process	number to dest message
X	add si,2		; don't	copy first word
X	add di,2		; don't	copy first word
X	mov cx,Msize-1		; remember, first word doesn't count
X	rep movsw		; iterate cx times to copy the message
X
X	pop di			; restore di
X	pop si			; restore si
X	pop cx			; restore cs
X	popf			; restore flags
X	pop ds			; restore ds
X	pop es			; restore es
X	pop bp			; restore bp
X	ret			; that's all folks!
X
X
X;===========================================================================
X;				port_out
X;===========================================================================
X; port_out(port, value)	writes 'value' on the I/O port 'port'.
X
X_port_out:
X	push bx			; save bx
X	mov bx,sp		; index	off bx
X	push ax			; save ax
X	push dx			; save dx
X	mov dx,4[bx]		; dx = port
X	mov ax,6[bx]		; ax = value
X	out dx,al		; output 1 byte
X	pop dx			; restore dx
X	pop ax			; restore ax
X	pop bx			; restore bx
X	ret			; return to caller
X
X
X;===========================================================================
X;				port_in
X;===========================================================================
X; port_in(port,	&value)	reads from port	'port' and puts	the result in 'value'.
X_port_in:
X	push bx			; save bx
X	mov bx,sp		; index	off bx
X	push ax			; save ax
X	push dx			; save dx
X	mov dx,4[bx]		; dx = port
X	in  al,dx		; input	1 byte
X	xor ah,ah		; clear	ah
X	mov bx,6[bx]		; fetch	address	where byte is to go
X	mov [bx],ax		; return byte to caller	in param
X	pop dx			; restore dx
X	pop ax			; restore ax
X	pop bx			; restore bx
X	ret			; return to caller
X
X
X;===========================================================================
X;				lock
X;===========================================================================
X; Disable CPU interrupts.
X_lock:
X	pushf			; save flags on	stack
X	cli			; disable interrupts
X	pop lockvar		; save flags for possible restoration later
X	ret			; return to caller
X
X
X;===========================================================================
X;				unlock
X;===========================================================================
X; Enable CPU interrupts.
X_unlock:
X	sti			; enable interrupts
X	ret			; return to caller
X
X
X;===========================================================================
X;				restore
X;===========================================================================
X; Restore enable/disable bit to	the value it had before	last lock.
X_restore:
X	push lockvar		; push flags as	they were before previous lock
X	popf			; restore flags
X	ret			; return to caller
X
X
X;===========================================================================
X;				build_sig
X;===========================================================================
X; Build	a structure that is pushed onto	the stack for signals.	It contains
X; pc, psw, etc., and is	machine	dependent. The format is the same as generated
X; by hardware interrupts, except that after the	"interrupt", the signal	number
X; is also pushed.  The signal processing routine within	the user space first
X; pops the signal number, to see which function	to call.  Then it calls	the
X; function.  Finally, when the function	returns	to the low-level signal
X; handling routine, control is passed back to where it was prior to the	signal
X; by executing a return-from-interrupt instruction, hence the need for using
X; the hardware generated interrupt format on the stack.	 The call is:
X;     build_sig(sig_stuff, rp, sig)
X
X; Offsets within proc table
XPC    =	24
Xcsreg =	18
XPSW   =	28
X
X_build_sig:
X	push bp			; save bp
X	mov bp,sp		; set bp to sp for accessing params
X	push bx			; save bx
X	push si			; save si
X	mov bx,4[bp]		; bx points to sig_stuff
X	mov si,6[bp]		; si points to proc table entry
X	mov ax,8[bp]		; ax = signal number
X	mov [bx],ax		; put signal number in sig_stuff
X	mov ax,PC[si]		; ax = signalled process' PC
X	mov 2[bx],ax		; put pc in sig_stuff
X	mov ax,csreg[si]	; ax = signalled process' cs
X	mov 4[bx],ax		; put cs in sig_stuff
X	mov ax,PSW[si]		; ax = signalled process' PSW
X	mov 6[bx],ax		; put psw in sig_stuff
X	pop si			; restore si
X	pop bx			; restore bx
X	pop bp			; restore bp
X	ret			; return to caller
X
Xifndef TURBO
X
X;===========================================================================
X;		csv & cret  (compiler generated	symbols)
X;===========================================================================
X; This version of csv replaces the standard one.  It checks for	stack overflow
X; within the kernel in a simpler way than is usually done. cret	is standard.
X_csv:
X	pop bx			; bx = return address
X	push bp			; stack	old frame pointer
X	mov bp,sp		; set new frame	pointer	to sp
X	push di			; save di
X	push si			; save si
X	sub sp,ax		; ax =	bytes of local variables
X	cmp sp,dgroup:_splimit	; has kernel stack grown too large
X	jbe csv1		; if sp	is too low, panic
X	jmp [bx]		; normal return: copy bx to program counter
X
Xcsv1:
X	mov dgroup:_splimit,0		; prevent call to panic	from aborting in csv
X	mov bx,dgroup:_proc_ptr		; update rp->p_splimit
X	mov WORD PTR 50[bx],0		; rp->sp_limit = 0
X	push dgroup:_cur_proc		; task number
X	mov ax,offset dgroup:stkoverrun ; stack overran the kernel stack area
X	push ax				; push first parameter
X	call _panic		; call is: panic(stkoverrun, cur_proc)
X	jmp csv1		; this should not be necessary
X
X
X_cret:
X	lea	sp,-4[bp]	; set sp to point to saved si
X	pop	si		; restore saved	si
X	pop	di		; restore saved	di
X	pop	bp		; restore bp
X	ret			; end of procedure
X
Xendif
X
X;===========================================================================
X;				get_chrome
X;===========================================================================
X; This routine calls the BIOS to find out if the display is monochrome or
X; color.  The drivers are different, as	are the	video ram addresses, so	we
X; need to know.
X_get_chrome:
X	int 11h			; call the BIOS	to get equipment type
X	and al,30h		; isolate color/mono field
X	cmp al,30h		; 0x30 is monochrome
X	je getchr1		; if monochrome	then go	to getchr1
X	mov ax,1		; color	= 1
X	ret			; color	return
Xgetchr1:xor ax,ax		; mono = 0
X	ret			; monochrome return
X
X
X;===========================================================================
X;				vid_copy
X;===========================================================================
X; This routine takes a string of [character, attribute]	pairs and writes them
X; onto the screen.  For	a color	display, the writing only takes	places during
X; the vertical retrace interval, to avoid displaying garbage on	the screen.
X; The call is:
X;     vid_copy(buffer, videobase, offset, words)
X; where
X;     'buffer'	  is a pointer to the (character, attribute) pairs
X;     'videobase' is 0xB800 for	color and 0xB000 for monochrome	displays
X;     'offset'	  tells	where within video ram to copy the data
X;     'words'	  tells	how many words to copy
X; if buffer is zero, the fill character	(BLANK)	is used
X
XBLANK =	0700h
X
X_vid_copy:
X	push bp			; we need bp to	access the parameters
X	mov bp,sp		; set bp to sp for indexing
X	push si			; save the registers
X	push di			; save di
X	push bx			; save bx
X	push cx			; save cx
X	push dx			; save dx
X	push es			; save es
Xvid0:	mov si,4[bp]		; si = pointer to data to be copied
X	mov di,8[bp]		; di = offset within video ram
X	and di,dgroup:_vid_mask	; only 4K or 16K counts
X	mov cx,10[bp]		; cx = word count for copy loop
X	mov dx,03DAh		; prepare to see if color display is retracing
X
X	mov bx,di		; see if copy will run off end of video ram
X	add bx,cx		; compute where copy ends
X	add bx,cx		; bx = last character copied + 1
X	sub bx,dgroup:_vid_mask	; bx = # characters beyond end of video ram
X	sub bx,1		; note: dec bx doesn't set flags properly
X	jle vid1		; jump if no overrun
X	sar bx,1		; bx = # words that don't fit in video ram
X	sub cx,bx		; reduce count by overrun
X	mov tmp,cx		; save actual count used for later
X
Xvid1:	test dgroup:_color,1	; skip vertical	retrace	test if	display	is mono
X	jz vid4			; if monochrome	then go	to vid.2
X
X;  vid2:in			; with a color display,	you can	only copy to
X;	test al,010q		; the video ram	during vertical	retrace, so
X;	jnz vid2		; wait for start of retrace period.  Bit 3 of
Xvid3:   in al,dx		; 0x3DA	is set during retrace.	First wait
X	test al,010q		; until	it is off (no retrace),	then wait
X	jz vid3			; until	it comes on (start of retrace)
X
Xvid4:   pushf			; copying may now start; save the flags
X	cli			; interrupts just get in the way: disable them
X	mov es,6[bp]		; load es now: int routines may	ruin it
X
X	cmp si,0		; si = 0 means blank the screen
X	je vid7			; jmp for blanking
X	lock nop		; this is a trick for the IBM PC-simulator only
X				; 'lock' indicates a video ram access
X	rep movsw		; this is the copy loop
X
Xvid5:   popf			; restore flags
X	cmp bx,0		; if bx < 0, then no overrun and we are done
X	jle vid6		; jump if everything fit
X	mov 10[bp],bx		; set up residual count
X	mov word ptr 8[bp],0	; start copying at base of video ram
X	cmp word ptr 4[bp],0	; NIL_PTR means store blanks
X	je vid0			; go do it
X	mov si,tmp		; si = count of words copied
X	add si,si		; si = count of bytes copied
X	add 4[bp],si		; increment buffer pointer
X	jmp vid0		; go copy some more
X
X; the vid6-label was missing !! [EVAS]
X;
Xvid6:	pop es			; restore registers
X	pop dx			; restore dx
X	pop cx			; restore cx
X	pop bx			; restore bx
X	pop di			; restore di
X	pop si			; restore si
X	pop bp			; restore bp
X	ret			; return to caller
X
Xvid7:   mov ax,BLANK		; ax = blanking	character
X	rep stosw		; blank	the screen
X	jmp vid5		; done
X
X;===========================================================================
X;				get_byte
X;===========================================================================
X; This routine is used to fetch	a byte from anywhere in	memory.
X; The call is:
X;     c	= get_byte(seg,	off)
X; where
X;     'seg' is the value to put	in es
X;     'off' is the offset from the es value
X_get_byte:
X	push bp			; save bp
X	mov bp,sp		; we need to access parameters
X	push es			; save es
X	mov es,4[bp]		; load es with segment value
X	mov bx,6[bp]		; load bx with offset from segment
X	mov al,es:[bx]		; al = byte
X	xor ah,ah		; ax = byte
X	pop es			; restore es
X	pop bp			; restore bp
X	ret			; return to caller
X
X
X;===========================================================================
X;				reboot & dump
X;===========================================================================
X; This code reboots the	PC
X
X
X_reboot:
X	cli			; disable interrupts
X	mov al,20h
X	out 20h,al		; re-enable interrupt controller
X	call resvec		; restore the vectors in low core
X	int 19h			; reboot the PC
X
X_wreboot:
X	cli			; disable interrupts
X	mov al,20h		; re-enable interrupt controller
X	out 20h,al
X	call resvec		; restore the vectors in low core
X	xor ax,ax		; wait for character before continuing
X	int 16h			; get char
X	int 19h			; reboot the PC
X
X; Restore the interrupt	vectors	in low core.
Xresvec:
X	cld
X	mov cx,2*65
X	mov si,offset dgroup:_vec_table
X	xor di,di
X	mov es,di
X    rep	movsw
X	ret
X
X_TEXT	ENDS
X
X
X
X_BSS	SEGMENT
Xlockvar	   DW	 0		; place	to store flags for lock()/restore()
Xtmp        DW    0		; count of bytes already copied
X_vec_table   DW	 130 dup(0)	; storage for interrupt	vectors
Xstkoverrun DB	 "Kernel stack overrun,	task = ",0
X_BSS	ENDS
X
X	END	; end of assembly
+ END-OF-FILE kernel/klib88.asm
chmod 'u=rw,g=r,o=r' kernel/klib88.asm
set `sum kernel/klib88.asm`
sum=$1
case $sum in
49310)	:;;
*)	echo 'Bad sum in 'kernel/klib88.asm >&2
esac
echo Extracting kernel/linklist
sed 's/^X//' > kernel/linklist << '+ END-OF-FILE 'kernel/linklist
Xmpx88+main+proc+system+clock+memory+floppy+
Xwini+tty+printer+table+klib88+dmp
Xkernel
Xkernel
X..\mlib\minix
+ END-OF-FILE kernel/linklist
chmod 'u=rw,g=r,o=r' kernel/linklist
set `sum kernel/linklist`
sum=$1
case $sum in
9870)	:;;
*)	echo 'Bad sum in 'kernel/linklist >&2
esac
echo Extracting kernel/mpx88.asm
sed 's/^X//' > kernel/mpx88.asm << '+ END-OF-FILE 'kernel/mpx88.asm
XTitle mpx88
Xpage,132
X
X
X; This file is part of the lowest layer	of the Minix kernel.  All process
X; switching and	message	handling is done here and in file "proc.c".  This file
X; is entered on	every transition to the	kernel,	both for sending/receiving
X; messages and for all interrupts.  In all cases, the trap or interrupt
X; routine first	calls save() to	store the machine state	in the proc table.
X; Then the stack is switched to	k_stack.  Finally, the real trap or interrupt
X; handler (in C) is called.  When it returns, the interrupt routine jumps to
X; _restart, to run the process or task whose number is in 'cur_proc'.
X;
X; The external entry points into this file are:
X;   s_call:	process	or task	wants to send or receive a message
X;   tty_int:	interrupt routine for each key depression and release
X;   lpr_int:	interrupt routine for each line	printer	interrupt
X;   disk_int:	disk interrupt routine
X;   clock_int:	clock interrupt	routine	[HZ times per second]
X;   surprise:	all other interrupts < 16 are vectored here
X;   trp:	all traps with vector >= 16 are	vectored here
X;   divide:	divide overflow traps are vectored here
X;   _restart:	start running a	task or	process
X
X
X; include the following	from const.h:
XK_STACK_BYTES	EQU  256
XIDLE		EQU -999
X
X; include the following	from ../h/com.h
XDISKINT		EQU  1
XCLOCK		EQU -3
XCLOCK_TICK	EQU  2
XFLOPPY		EQU -5
XWINCHESTER	EQU -6
X
X
X; The following	procedures are defined in this file and	called from outside it.
XPUBLIC $main, _tty_int, _lpr_int,	_clock_int, _disk_int
Xpublic _wini_int
XPUBLIC _s_call, _surprise, _trp, _divide, _restart
X
X
X; The following	external procedures are	called in this file.
XEXTRN _main:NEAR,  _sys_call:NEAR, _interrupt:NEAR,	_keyboard:NEAR
XEXTRN _panic:NEAR, _unexpected_int:NEAR, _trap:NEAR, _div_trap:NEAR, _pr_char:NEAR
X
X
X; Variables and	data structures.
XPUBLIC _sizes, _brksize, _splimit,	__end
XEXTRN  _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD
XEXTRN  _scan_code:WORD, _k_stack:WORD
X
X
X; The following	constants are offsets into the proc table.
Xesreg =	14
Xdsreg =	16
Xcsreg =	18
Xssreg =	20
Xspreg =	22
XPC    =	24
XPSW   =	28
XSPLIM =	50
XOFF   =	18
XROFF  =	12
X
X
XINCLUDE	..\lib\prologue.h
X
X
X_TEXT	SEGMENT
X	assume	cs:_TEXT,ds:dgroup
X
X;===========================================================================
X;				Minix
X;===========================================================================
X$main:
XMinix:				; this is the entry point for the Minix	kernel.
X	jmp short M0		; skip over the	next word(s)
X	ORG 4			; build	writes the ds value at text address 4
Xker_ds	DW  dgroup		; this word will contain kernel's ds value
X				; and it forces	relocation for dos2out
X     M0:cli			; disable interrupts
X	mov ax,cs		; set up segment registers
X	mov ds,ax		; set up ds
X	mov ax,cs:ker_ds	; build	has loaded this	word with ds value
X	mov ds,ax		; ds now contains proper value
X	mov ss,ax		; ss now contains proper value
X	mov dgroup:_scan_code,bx		; save scan code for '=' key from bootstrap
X	mov sp,offset dgroup:_k_stack	; set sp to point to the top of	the
X	add sp,K_STACK_BYTES		; kernel stack
X	call _main		; start	the main program of Minix
X
X     M1:jmp M1			; this should never be executed
X
X
X;===========================================================================
X;				s_call
X;===========================================================================
X_s_call:				; System calls are vectored here.
X	call save		; save the machine state
X	mov bp,dgroup:_proc_ptr	; use bp to access sys call parameters
X	push 2[bp]		; push(pointer to user message)	(was bx)
X	push [bp]		; push(src/dest) (was ax)
X	push dgroup:_cur_proc	; push caller
X	push 4[bp]		; push(SEND/RECEIVE/BOTH) (was cx)
X	call _sys_call		; sys_call(function, caller, src_dest, m_ptr)
X	jmp _restart		; jump to code to _restart proc/task running
X
X
X;===========================================================================
X;				tty_int
X;===========================================================================
X_tty_int:			; Interrupt routine for	terminal input.
X	call save		; save the machine state
X	call _keyboard		; process a keyboard interrupt
X	jmp  _restart		; continue execution
X
X
X;===========================================================================
X;				lpr_int
X;===========================================================================
X_lpr_int:			; Interrupt routine for	terminal input.
X	call save		; save the machine state
X	call _pr_char		; process a line printer interrupt
X	jmp  _restart		; continue execution
X
X
X;===========================================================================
X;				_wini_int
X;===========================================================================
X_wini_int:			; Interrupt routine for	the floppy disk.
X	call save			; save the machine state
X	mov  dgroup:_int_mess+2,DISKINT	; build	message	for disk task
X	mov  ax,offset dgroup:_int_mess	; prepare to call interrupt[FLOPPY, &intmess]
X	push ax				; push second parameter
X	mov  ax,WINCHESTER		; prepare to push first	parameter
X	push ax			; push first parameter
X	call _interrupt		; this is the call
X	jmp  _restart		; continue execution
X
X;===========================================================================
X;				disk_int
X;===========================================================================
X_disk_int:			; Interrupt routine for	the floppy disk.
X	call save			; save the machine state
X	mov  dgroup:_int_mess+2,DISKINT	; build	message	for disk task
X	mov  ax,offset dgroup:_int_mess	; prepare to call interrupt[FLOPPY, &intmess]
X	push ax				; push second parameter
X	mov  ax,FLOPPY		; prepare to push first	parameter
X	push ax			; push first parameter
X	call _interrupt		; this is the call
X	jmp  _restart		; continue execution
X
X
X;===========================================================================
X;				clock_int
X;===========================================================================
X_clock_int:			; Interrupt routine for	the clock.
X	call save			; save the machine state
X	mov dgroup:_int_mess+2,CLOCK_TICK; build	message	for clock task
X	mov ax,offset dgroup:_int_mess	; prepare to call interrupt(CLOCK,&intmess)
X	push ax				; push second parameter
X	mov  ax,CLOCK		; prepare to push first	parameter
X	push ax			; push first parameter
X	call _interrupt		; this is the call
X	jmp  _restart		; continue execution
X
X
X;===========================================================================
X;				surprise
X;===========================================================================
X_surprise:			; This is where	unexpected interrupts come.
X	call save		; save the machine state
X	call _unexpected_int		; go panic
X	jmp  _restart		; never	executed
X
X
X;===========================================================================
X;				trp
X;===========================================================================
X_trp:				; This is where	unexpected traps come.
X	call save		; save the machine state
X	call _trap		; print	a message
X	jmp _restart		; this error is	not fatal
X
X
X;===========================================================================
X;				divide					     
X;===========================================================================
X_divide:			; This is where divide overflow traps come.
X	call save		; save the machine state
X	call _div_trap		; print a message
X	jmp _restart		; this error is not fatal
X
X
X;===========================================================================
X;				save
X;===========================================================================
Xsave:				; save the machine state in the	proc table.
X	push ds			; stack: psw/cs/pc/ret addr/ds
X	push cs			; prepare to restore ds
X	pop ds			; ds has now been set to cs
X	mov ds,ker_ds		; word 4 in kernel text	space contains ds value
X	pop ds_save		; stack: psw/cs/pc/ret addr
X	pop ret_save		; stack: psw/cs/pc
X	mov bx_save,bx		; save bx for later ; we need a	free register
X	mov bx,dgroup:_proc_ptr	; start	save set up; make bx point to save area
X	add bx,OFF		; bx points to place to	store cs
X	pop PC-OFF[bx]		; store	pc in proc table
X	pop csreg-OFF[bx]	; store	cs in proc table
X	pop PSW-OFF[bx]		; store	psw
X	mov ssreg-OFF[bx],ss	; store	ss
X	mov spreg-OFF[bx],sp	; sp as	it was prior to	interrupt
X	mov sp,bx		; now use sp to	point into proc	table/task save
X	mov bx,ds		; about	to set ss
X	mov ss,bx		; set ss
X	push ds_save		; start	saving all the registers, sp first
X	push es			; save es between sp and bp
X	mov es,bx		; es now references kernel memory too
X	push bp			; save bp
X	push di			; save di
X	push si			; save si
X	push dx			; save dx
X	push cx			; save cx
X	push bx_save		; save original	bx
X	push ax				    ; all registers now	saved
X	mov sp,offset dgroup:_k_stack	    ; temporary	stack for interrupts
X	add sp,K_STACK_BYTES		    ; set sp to	top of temporary stack
X	mov _splimit,offset dgroup:_k_stack   ; limit for	temporary stack
X	add _splimit,8			    ; splimit checks for stack overflow
X	mov ax,ret_save		; ax = address to return to
X	jmp ax			; return to caller; Note: sp points to saved ax
X
X
X;===========================================================================
X;				_restart
X;===========================================================================
X_restart:			; This routine sets up and runs	a proc or task.
X	cmp dgroup:_cur_proc,IDLE; _restart user; if cur_proc = IDLE, go	idle
X	je _idle		; no user is runnable, jump to idle routine
X	cli			; disable interrupts
X	mov sp,dgroup:_proc_ptr	; return to user, fetch	regs from proc table
X	pop ax			; start	restoring registers
X	pop bx			; restore bx
X	pop cx			; restore cx
X	pop dx			; restore dx
X	pop si			; restore si
X	pop di			; restore di
X	mov lds_low,bx		; lds_low contains bx
X	mov bx,sp		; bx points to saved bp	register
X	mov bp,SPLIM-ROFF[bx]	; splimit = p_splimit
X	mov _splimit,bp		; ditto
X	mov bp,dsreg-ROFF[bx]	; bp = ds
X	mov lds_low+2,bp	; lds_low+2 contains ds
X	pop bp			; restore bp
X	pop es			; restore es
X	mov sp,spreg-ROFF[bx]	; restore sp
X	mov ss,ssreg-ROFF[bx]	; restore ss using the value of	ds
X	push PSW-ROFF[bx]	; push psw (flags)
X	push csreg-ROFF[bx]	; push cs
X	push PC-ROFF[bx]	; push pc
X	lds  bx,DWORD PTR lds_low   ; restore ds and bx	in one fell swoop
X	iret			; return to user or task
X
X;===========================================================================
X;				idle
X;===========================================================================
X_idle:				; executed when	there is no work
X	sti			; enable interrupts
XL3:	wait			; just idle while waiting for interrupt
X	jmp L3			; loop until interrupt
X
X
X_TEXT	ENDS
X
X
X;===========================================================================
X;				data
X;===========================================================================
X
X_DATABEG SEGMENT		; DATABEG	ensures	it is the beginning of all data
X_sizes	 DW	526Fh		; this must be the first data entry (magic nr)
X	 DW	7 dup(0)	; space	for build table	- total	16b
X_splimit DW	0		; stack	limit for current task (kernel only)
Xbx_save	 DW	0		; storage for bx
Xds_save	 DW	0		; storage for ds
Xret_save DW	0		; storage for return address
Xlds_low	 DW	0,0		; storage used for restoring ds:bx
X_brksize DW	offset dgroup:__end+2	; first	free memory in kernel
Xttyomess DB	"RS232 interrupt",0
X_DATABEG	ENDS
X
X
X_DATAEND	SEGMENT			; DATAEND	holds nothing. The label in
X__end	label	byte		; the segment just tells us where
X_DATAEND	ENDS			; the data+bss ends.
X
X_STACK	SEGMENT	BYTE STACK 'STACK'	; Satisfy DOS-linker (dummy stack)
X_STACK	ENDS
X
X	END	; end of assembly-file
+ END-OF-FILE kernel/mpx88.asm
chmod 'u=rw,g=r,o=r' kernel/mpx88.asm
set `sum kernel/mpx88.asm`
sum=$1
case $sum in
48355)	:;;
*)	echo 'Bad sum in 'kernel/mpx88.asm >&2
esac
echo Extracting kernel/xt_wini.dif
sed 's/^X//' > kernel/xt_wini.dif << '+ END-OF-FILE 'kernel/xt_wini.dif
X163c163
X<  *				w_do_rdwt				     * 
X---
X>  *				w_do_rdwt					     * 
X682,683c682,683
X<   copy_params(&buf[type_0 * 16], &param0);
X<   copy_params(&buf[type_1 * 16], &param1);
X---
X>   copy_param(&buf[type_0 * 16], &param0);
X>   copy_param(&buf[type_1 * 16], &param1);
+ END-OF-FILE kernel/xt_wini.dif
chmod 'u=rw,g=r,o=r' kernel/xt_wini.dif
set `sum kernel/xt_wini.dif`
sum=$1
case $sum in
18317)	:;;
*)	echo 'Bad sum in 'kernel/xt_wini.dif >&2
esac
echo Extracting tools/build.dif
sed 's/^X//' > tools/build.dif << '+ END-OF-FILE 'tools/build.dif
X43a44,52
X> #ifdef DOS
X> # define MSDOS
X> # ifdef TURBO
X> #   include <dos.h>
X> #   include <fcntl.h>
X> #   include <sys\stat.h>
X> #   include <stdio.h>
X> # endif
X> #endif
X70c79,83
X< # define BREAD 4                /* value 0 means ASCII read */
X---
X> #  ifdef TURBO
X> #    define BREAD	(O_RDONLY|O_BINARY)
X> #  else
X> #    define BREAD 4                /* value 0 means ASCII read */
X> #  endif
X117,118c130,131
X<   printf("Operating system size  %29D     %5X\n", cum_size, cum_size);
X<   printf("\nTotal size including fsck is %D.\n", all_size);
X---
X>   printf("Operating system size  %29ld     %5lX\n", cum_size, cum_size);
X>   printf("\nTotal size including fsck is %ld.\n", all_size);
X169c182
X<   
X---
X> 
X177c190
X<         pexit("separate I & D but text size not multiple of 16 bytes.  File: ", 
X---
X>         pexit("separate I & D but text size not multiple of 16 bytes.  File: ",
X227c240
X< /* Read the header and check the magic number.  The standard Monix header 
X---
X> /* Read the header and check the magic number.  The standard Monix header
X248,250c261,265
X<   if ((n = read(fd, hd, 8)) != 8) pexit("file header too short: ", file_name);
X<   header_len = hd[HDR_LEN];
X<   if (header_len != HEADER1 && header_len != HEADER2) 
X---
X>   if ((n = read(fd, hd, 8)) != 8)
X>   	pexit("file header too short: ", file_name);
X> 
X>   header_len = hd[HDR_LEN];
X>   if (header_len != HEADER1 && header_len != HEADER2)
X257,258c272,275
X<   if ((n = read(fd, head, header_len - 8)) != header_len - 8)
X<         pexit("header too short: ", file_name);
X---
X>   if ((n = read(fd, head, header_len - 8)) != header_len - 8) {
X>   	printf("expected %d, got %d\n",header_len - 8,n);
X>         pexit("header too short: ", file_name);
X>   }
X350a368,369
X> 
X>   printf("fsck starts at %4.4X:%4.4X\n",cs,ip);
X379c398
X<   
X---
X> 
X501a521
X> 
X529a550
X> 
X543c564,569
X<   if (DMAoverrun(buff1))
X---
X>   if (/*
X>   	DMAoverrun(buff1)
X>   	in the 1.1 distribution, this was a dummy routine in
X>   	diskio.asm; always returned 0.
X>   	*/
X>   	0)
X558,560c584,593
X<   retries = MAX_RETRIES;
X<   do
X<       err = absread (drive, blocknr, buff);
X---
X>   if (drive == -1) {
X> 	lseek(image, (long)SECTOR_SIZE * (long) blocknr, 0);
X> 	if (read(image, user, SECTOR_SIZE) != SECTOR_SIZE)
X>   		pexit("block read error", "");
X>   	return;
X>   }
X> 
X>   retries = MAX_RETRIES;
X>   do
X>       err = absread (drive, 1, blocknr, buff);
X579a613,619
X>   if (drive == -1) {
X> 	lseek(image, (long)SECTOR_SIZE * (long) blocknr, 0);
X> 	if (write(image, user, SECTOR_SIZE) != SECTOR_SIZE)
X> 		pexit("block write error", "");
X> 	return;
X>   }
X> 
X585c625
X<       err = abswrite (drive, blocknr, buff);
X---
X>       err = abswrite (drive, 1, blocknr, buff);
X597c637,639
X< { extern char *derrtab[];
X---
X> {
X>   extern char *derrtab[];
X> 
X608,613c650,663
X<   if (s[1] != ':') pexit ("wrong drive name (dos): ",s);
X<   drive = (s[0] & ~32) - 'A';
X<   if (drive<0 || drive>32) pexit ("no such drive: ",s);
X<   printf("Put a blank, formatted diskette in drive %s\nHit return when ready",s);
X<   gets (kbstr,10);
X<   puts("");
X---
X> 
X>   if (s[1] != ':') /*pexit("wrong drive name (dos): ",s);*/ {
X>   	drive = -1;
X> 	image = open(s,O_RDWR|O_BINARY|O_CREAT,S_IREAD|S_IWRITE);
X> 	if (image == -1)
X> 		pexit("error opening image-file: ",s);
X>   }
X>   else {  	
X> 	drive = (s[0] & ~32) - 'A';
X> 	if (drive<0 || drive>32) pexit ("no such drive: ",s);
X> 	printf("Put a blank, formatted diskette in drive %s\nHit return when ready",s);
X> 	fgets (kbstr,10,stdin);
X> 	puts("");
X>   }
+ END-OF-FILE tools/build.dif
chmod 'u=rw,g=r,o=r' tools/build.dif
set `sum tools/build.dif`
sum=$1
case $sum in
58229)	:;;
*)	echo 'Bad sum in 'tools/build.dif >&2
esac
echo Extracting tools/dos2out.dif
sed 's/^X//' > tools/dos2out.dif << '+ END-OF-FILE 'tools/dos2out.dif
X100c100,102
X< #include "/lib/C86/stdio.h"
X---
X> #include <stdio.h>
X> #include <fcntl.h>
X> #include <sys\stat.h>
X180c182
X<     if ((inf=open(in_name,BREAD)) <0) {
X---
X>     if ((inf=open(in_name,O_RDONLY|O_BINARY)) <0) {
X210c212
X<     if ((outf=creat(out_name,BWRITE)) <0) {
X---
X>     if ((outf=open(out_name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,S_IREAD|S_IWRITE)) <0) {
X240c242
X<     inf=open(in_name,BREAD);
X---
X>     inf=open(in_name,O_RDONLY|O_BINARY);
X303a306
X>     exit(0);
+ END-OF-FILE tools/dos2out.dif
chmod 'u=rw,g=r,o=r' tools/dos2out.dif
set `sum tools/dos2out.dif`
sum=$1
case $sum in
34456)	:;;
*)	echo 'Bad sum in 'tools/dos2out.dif >&2
esac
echo Extracting tools/fsck.dif
sed 's/^X//' > tools/fsck.dif << '+ END-OF-FILE 'tools/fsck.dif
X6,9c6,10
X< #include "../fs/type.h"
X< 
X< /* #define DOS			/* compile to run under MS-DOS */
X< #define STANDALONE		/* compile for the boot-diskette */
X---
X> 
X> #undef printf /* ../fs/const.h redefines printf as printk !! */
X> 
X> #include "../fs/type.h"
X> 
X90a92,93
X> 
X> #ifndef TURBO
X94a98
X> #endif
X176c180,182
X< #define atol(s) atoi(s)		/* kludge for C86 (no atol(s) in library) */
X---
X> # ifdef C86
X> #  define atol(s) atoi(s)	/* kludge for C86 (no atol(s) in library) */
X> # endif
X199a206,207
X> #ifndef TURBO
X> 
X208,210c216,240
X< #ifndef STANDALONE
X< # ifdef DOS
X< #  include "/lib/c86/stdio.h"
X---
X> #endif
X> 
X> #ifndef STANDALONE
X> # ifdef DOS
X> #  ifdef TURBO
X> 
X>      /* Print the given character. */
X>      putchar(c){
X>      	if (c == '\n')
X>      		putc('\r');
X>      	putc(c);
X>      }
X> 
X>      /* Get a character from the user and echo it. */
X>      getchar(){
X>      	register c;
X> 
X>      	if ((c = getc() & 0xFF) == '\r')
X>      		c = '\n';
X>      	putchar(c);
X>      	return(c);
X>      }
X> #  else
X> #   include <stdio.h>
X> #  endif
X214,215c244,248
X< /* Print the given character. */
X< putchar(c){
X---
X> extern void putc(char);
X> extern int getc(void);
X> 
X> /* Print the given character. */
X> putchar(int c){
X222,223c255,256
X< getchar(){
X< 	register c;
X---
X> int getchar(void){
X> 	register int c;
X235,238c268
X< printnum(n, base, sign, width, pad)
X< long n;
X< int base, sign;
X< int width, pad;
X---
X> printnum(long n, int base, int sign, int width, int pad)
X276c306,307
X< printchar(c, mode){
X---
X> printchar(int c, int mode)
X> {
X297a329,330
X> #ifndef TURBO
X> 
X357,372c390,452
X< 
X< /* Initialize the variables used by this program.
X<  */
X< initvars(){
X< 	register level;
X< 
X< #ifdef STANDALONE
X< 	  brk = &end;
X< #endif
X< 	nregular = ndirectory = nblkspec = ncharspec = nbadinode = 0;
X< 	for (level = 0; level < NLEVEL; level++)
X< 		ztype[level] = 0;
X< 	changed = 0;
X< 	firstlist = 1;
X< 	firstcnterr = 1;
X< 	thisblk = NO_BLOCK;
X---
X> #else /*TURBO*/
X> 
X> /* we have to use an explicit path since we use Turbo C to
X> * do Minix development and normally only want to use the Minix
X> * header files;
X> */
X> #include "\tc\include\stdarg.h"
X> 
X> #define prn(t,b,s)	{ printnum((long)va_arg(argptr,t),b,s,width,pad); width = 0; }
X> #define prc(c)		{ width -= printchar(c, mode); }
X> 
X> 
X> /* Print the arguments according to format.
X>  */
X> printf(char *format, ...)
X> {
X> 	register char *fmt, *s;
X> 	register short width, pad, mode;
X> 	va_list argptr;
X> 
X> 	va_start(argptr,format);
X> 
X> 	for (fmt = format; *fmt != 0; fmt++)
X> 		switch(*fmt) {
X> 		case '\n': putchar('\r');
X> 		default:   putchar(*fmt);
X> 			   break;
X> 		case '%':
X> 			if (*++fmt == '-')
X> 				fmt++;
X> 			pad = *fmt == '0' ? '0' : ' ';
X> 			width = 0;
X> 			while (isdigit(*fmt)) {
X> 				width *= 10;
X> 				width += *fmt++ - '0';
X> 			}
X> 			if (*fmt == 'l' && islower(*++fmt))
X> 				*fmt = toupper(*fmt);
X> 			mode = isupper(*fmt);
X> 			switch (*fmt) {
X> 			case 'c':
X> 			case 'C':  prc(va_arg(argptr,char));	break;
X> 			case 'b':  prn(unsigned,  2, 0);	break;
X> 			case 'B':  prn(long,      2, 0);	break;
X> 			case 'o':  prn(unsigned,  8, 0);	break;
X> 			case 'O':  prn(long,      8, 0);	break;
X> 			case 'd':  prn(int,      10, 1);	break;
X> 			case 'D':  prn(long,     10, 1);	break;
X> 			case 'u':  prn(unsigned, 10, 0);	break;
X> 			case 'U':  prn(long,     10, 0);	break;
X> 			case 'x':  prn(unsigned, 16, 0);	break;
X> 			case 'X':  prn(long,     16, 0);	break;
X> 			case 's':
X> 			case 'S':  s = va_arg(argptr,char *);
X> 				   while (*s) prc(*s++);	break;
X> 			case '\0': break;
X> 			default:   putchar(*fmt);
X> 			}
X> 			while (width-- > 0)
X> 				putchar(pad);
X> 		}
X> 
X> 	va_end(argptr);
X376,385c456,473
X< 
X< /* Copy n bytes.
X<  */
X< copy(p, q, n)
X< register char *p, *q;
X< register int n;
X< {
X< 	do
X< 		*q++ = *p++;
X< 	while (--n);
X---
X> #endif
X> 
X> /* Initialize the variables used by this program.
X>  */
X> initvars(void)
X> {
X> 	register level;
X> 
X> #ifdef STANDALONE
X> 	  brk = &end;
X> #endif
X> 	nregular = ndirectory = nblkspec = ncharspec = nbadinode = 0;
X> 	for (level = 0; level < NLEVEL; level++)
X> 		ztype[level] = 0;
X> 	changed = 0;
X> 	firstlist = 1;
X> 	firstcnterr = 1;
X> 	thisblk = NO_BLOCK;
X389,396c477,484
X< /* Print the string `s' and exit.
X<  */
X< fatal(s)
X< char *s;
X< {
X< 	printf("%s\n", s);
X< 	printf("fatal\n");
X< 	exit(-1);
X---
X> 
X> /* Copy n bytes.
X>  */
X> copy(register char *p, register char *q, register int n)
X> {
X> 	do
X> 		*q++ = *p++;
X> 	while (--n);
X400,404c488,494
X< /* Test for end of line.
X<  */
X< eoln(c)
X< {
X< 	return(c < 0 || c == '\n' || c == '\r');
X---
X> /* Print the string `s' and exit.
X>  */
X> fatal(char *s)
X> {
X> 	printf("%s\n", s);
X> 	printf("fatal\n");
X> 	exit(-1);
X407a498,505
X> /* Test for end of line.
X>  */
X> eoln(c)
X> {
X> 	return(c < 0 || c == '\n' || c == '\r');
X> }
X> 
X> 
X411,412c509
X< yes(question)
X< char *question;
X---
X> yes(char *question)
X434,435c531
X< atoo(s)
X< char *s;
X---
X> atoo(char *s)
X448,449c544
X< input(buf, size)
X< char *buf;
X---
X> input(char *buf, int size)
X474,475c569
X< char *alloc(nelem, elsize)
X< unsigned nelem, elsize;
X---
X> char *alloc(unsigned int nelem, unsigned int elsize)
X479c573
X< 	register *r;
X---
X> 	register int *r;
X509,510c603
X< printname(s)
X< char *s;
X---
X> printname(char *s)
X525,526c618
X< printrec(sp)
X< struct stack *sp;
X---
X> printrec(struct stack *sp)
X537c629,630
X< printpath(mode, nlcr){
X---
X> printpath(int mode, int nlcr)
X> {
X584,585c677,679
X< #ifdef STANDALONE
X< disktype()
X---
X> 
X> #ifdef STANDALONE
X> disktype(void)
X621,622c715
X< devio(bno, dir)
X< block_nr bno;
X---
X> devio(block_nr bno, int dir)
X684,686c777
X< devread(offset, buf, size)
X< long offset;
X< char *buf;
X---
X> devread(long offset, char *buf, int size)
X695,697c786
X< devwrite(offset, buf, size)
X< long offset;
X< char *buf;
X---
X> devwrite(long offset, char *buf, int size)
X710,711c799
X< pr(fmt, cnt, s, p)
X< char *fmt, *s, *p;
X---
X> pr(char *fmt, int cnt, char *s, char *p)
X761c849,850
X< lsuper(){
X---
X> lsuper(void)
X> {
X798c887,888
X< makedev(){
X---
X> makedev(void)
X> {
X827c917,918
X< mkfs(){
X---
X> mkfs(void)
X> {
X866c957,958
X< getsuper(){
X---
X> getsuper(void)
X> {
X894c986,987
X< chksuper(){
X---
X> chksuper(void)
X> {
X941,942c1034
X< lsi(clist)
X< char **clist;
X---
X> lsi(char **clist)
X980c1072,1073
X< unsigned *allocbitmap(nblk){
X---
X> unsigned *allocbitmap(int nblk)
X> {
X991,993c1084
X< loadbitmap(bitmap, bno, nblk)
X< unsigned *bitmap;
X< block_nr bno;
X---
X> loadbitmap(unsigned int *bitmap, block_nr bno, int nblk)
X1007,1009c1098
X< dumpbitmap(bitmap, bno, nblk)
X< unsigned *bitmap;
X< block_nr bno;
X---
X> dumpbitmap(unsigned *bitmap, block_nr bno, int nblk)
X1021,1023c1110
X< initbitmap(bitmap, bit, nblk)
X< unsigned *bitmap;
X< bit_nr bit;
X---
X> initbitmap(unsigned *bitmap, bit_nr bit, int nblk)
X1077c1164,1165
X< getbitmaps(){
X---
X> getbitmaps(void)
X> {
X1082c1170
X< 	dirmap = allocbitmap(N_IMAP);
X---
X> 	dirmap = allocbitmap(N_IMAP); 
X1100,1104c1188,1189
X< chkword(w1, w2, bit, type, n, report)
X< unsigned w1, w2;
X< char *type;
X< bit_nr bit;
X< int *n, *report;
X---
X> chkword(unsigned int w1, unsigned int w2, bit_nr bit, 
X> 	char *type, int *n, int *report)
X1121,1125c1206,1207
X< chkmap(cmap, dmap, bit, blkno, nblk, nbit, type)
X< unsigned *cmap, *dmap;
X< bit_nr bit, nbit;
X< block_nr blkno;
X< char *type;
X---
X> chkmap(unsigned int *cmap, unsigned int *dmap, bit_nr bit, block_nr blkno, 
X> 	int nblk, bit_nr nbit, char *type)
X1153c1235,1236
X< chkilist(){
X---
X> chkilist(void)
X> {
X1177c1260,1261
X< getcount(){
X---
X> getcount(void)
X> {
X1184,1185c1268
X< counterror(ino)
X< inode_nr ino;
X---
X> counterror(inode_nr ino)
X1215c1298,1299
X< chkcount(){
X---
X> chkcount(void)
X> {
X1238,1239c1322
X< printperm(mode, shift, special, overlay)
X< mask_bits mode;
X---
X> printperm(mask_bits mode, int shift, int special, int overlay)
X1251,1253c1334
X< list(ino, ip)
X< inode_nr ino;
X< d_inode *ip;
X---
X> list(inode_nr ino, d_inode *ip)
X1286,1287c1367
X< remove(dp)
X< dir_struct *dp;
X---
X> remove(dir_struct *dp)
X1306,1309c1386
X< chkdots(ino, pos, dp, exp)
X< inode_nr ino, exp;
X< file_pos pos;
X< dir_struct *dp;
X---
X> chkdots(inode_nr ino, file_pos pos, dir_struct *dp, inode_nr exp)
X1339,1341c1416
X< chkname(ino, dp)
X< inode_nr ino;
X< dir_struct *dp;
X---
X> chkname(inode_nr ino, dir_struct *dp)
X1371,1374c1446
X< chkentry(ino, pos, dp)
X< inode_nr ino;
X< file_pos pos;
X< dir_struct *dp;
X---
X> chkentry(inode_nr ino, file_pos pos, dir_struct *dp)
X1429,1433c1501
X< chkdirzone(ino, ip, pos, zno)
X< inode_nr ino;
X< d_inode *ip;
X< file_pos pos;
X< zone_nr zno;
X---
X> chkdirzone(inode_nr ino, d_inode *ip, file_pos pos, zone_nr zno)
X1469,1472c1537
X< errzone(mess, zno, level, pos)
X< char *mess;
X< zone_nr zno;
X< file_pos pos;
X---
X> errzone(char *mess, zone_nr zno, int level, file_pos pos)
X1489,1492c1554
X< markzone(ino, zno, level, pos)
X< inode_nr ino;
X< zone_nr zno;
X< file_pos pos;
X---
X> markzone(inode_nr ino, zone_nr zno, int level, file_pos pos)
X1508c1570,1571
X< 		errzone("found", ino, zno, level, pos, bit);
X---
X> 		errzone("found", /*ino,*/ zno, level, pos /*, bit*/);
X> 		/* the ino and bit-parameters should not be there I think */
X1516,1520c1579
X< chkindzone(ino, ip, pos, zno, level)
X< inode_nr ino;
X< d_inode *ip;
X< file_pos *pos;
X< zone_nr zno;
X---
X> chkindzone(inode_nr ino, d_inode *ip, file_pos *pos, zone_nr zno, int level)
X1538c1597,1598
X< file_pos jump(level){
X---
X> file_pos jump(int level)
X> {
X1551,1555c1611
X< zonechk(ino, ip, pos, zno, level)
X< inode_nr ino;
X< d_inode *ip;
X< file_pos *pos;
X< zone_nr zno;
X---
X> zonechk(inode_nr ino, d_inode *ip, file_pos *pos, zone_nr zno, int level)
X1570,1574c1626,1627
X< chkzones(ino, ip, pos, zlist, len, level)
X< inode_nr ino;
X< d_inode *ip;
X< file_pos *pos;
X< zone_nr *zlist;
X---
X> chkzones(inode_nr ino, d_inode *ip, file_pos *pos, zone_nr *zlist, 
X> 	int len, int level)
X1592,1594c1645
X< chkfile(ino, ip)
X< inode_nr ino;
X< d_inode *ip;
X---
X> chkfile(inode_nr ino, d_inode *ip)
X1608,1610c1659
X< chkdirectory(ino, ip)
X< inode_nr ino;
X< d_inode *ip;
X---
X> chkdirectory(inode_nr ino, d_inode *ip)
X1636,1638c1685
X< chkmode(ino, ip)
X< inode_nr ino;
X< d_inode *ip;
X---
X> chkmode(inode_nr ino, d_inode *ip)
X1665,1667c1712
X< chkinode(ino, ip)
X< inode_nr ino;
X< d_inode *ip;
X---
X> chkinode(inode_nr ino, d_inode *ip)
X1695,1696c1740
X< descendtree(dp)
X< dir_struct *dp;
X---
X> descendtree(dir_struct *dp)
X1738c1782,1783
X< chktree(){
X---
X> chktree(void)
X> {
X1753c1798,1799
X< printtotal(){
X---
X> printtotal(void)
X> {
X1777,1778c1823
X< chkdev(f, clist, ilist, zlist)
X< char *f, **clist, **ilist, **zlist;
X---
X> chkdev(char *f, char **clist, char **ilist, char **zlist)
X1819,1820c1864,1869
X< main(argc, argv)
X< char **argv;
X---
X> #ifdef STANDALONE
X> main()
X> #else
X> main(argc, argv)
X> char **argv;
X> #endif
X1900c1949
X< 	disktype()	/* init tracksiz & cylsize for disk in A: */
X---
X> 	disktype();	/* init tracksiz & cylsize for disk in A: */
X1933c1982
X< get_partition()
X---
X> get_partition(void)
X1957,1959c2006,2009
X< /* This define tells where to find things in partition table. */
X< #define P1 0x1C6
X< int read_partition()
X---
X> 
X> /* This define tells where to find things in partition table. */
X> #define P1 0x1C6
X> int read_partition(void)
X1978,2007c2028,2068
X<   fo6d5
X< < #include "../fs/type.h"
X< 8,9c7
X< < /* #define DOS			/* compile to run under MS-DOS */
X< < #define STANDALONE		/* compile for the boot-diskette */
X< ---
X< > #undef printf /* ../fs/const.h redefines printf as printk !! */
X< 10a9
X< > #include "../fs/type.h"
X< 11a11,12
X< > 
X< > 
X< 91d91
X< < #define nextarg(t)	(*argp.quote(u_)t++)
X< 93,94c93,94
X< < #define prn(t,b,s)	{ printnum((long)nextarg(t),b,s,width,pad); width = 0; }
X< < #define prc(c)		{ width -= printchar(c, mode); }
X< ---
X< > #ifndef TURBO
X< > #define nextarg(t)	(*argp.quote(u_)t++)
X< 96,98c96,98
X< < #define setbit(w, b)	(w[(b) >> BITSHIFT] |= 1 << ((b) & BITMASK))
X< < #define clrbit(w, b)	(w[(b) >> BITSHIFT] &= ~(1 << ((b) & BITMASK)))
X< < #define bitset(w, b)	(w[(b) >> BITSHIFT] & (1 << ((b) & BITMASK)))
X< ---
X< > #define prn(t,b,s)	{ printnum((long)nextarg(t),b,s,width,pad); width = 0; }
X< > #define prc(c)		{ width -= printchar(c, mode); }
X< > #endif
X< 99a100,103
X< > #define setbit(w, b)	(w[(b) >> BITSHIFT] |= 1 << ((b) & B---
X>   for (p=0; p<4; p++) {
X> 	b0 = rwbuf[P1+16*p+0] & 0xFF;
X> 	b1 = rwbuf[P1+16*p+1] & 0xFF;
X> 	b2 = rwbuf[P1+16*p+2] & 0xFF;
X> 	b3 = rwbuf[P1+16*p+3] & 0xFF;
X> 	val[p] = (b3<<24) | (b2<<16) | (b1<<8) | b0;
X> 	if (val[p] > 65535) {
X> 		printf("Fsck can't handle partitions above sector 65535\n");
X> 		exit(1);
X> 	}
X>   }
X>   p = (partition >= PARB ? partition - PARB + 1 : partition);
X>   sort(val);
X>   part_offset = (unsigned) val[p-1];
X>   if ((part_offset % (BLOCK_SIZE/SECTOR_SIZE)) != 0)
X>     part_offset = (part_offset/(BLOCK_SIZE/SECTOR_SIZE)+1)*(BLOCK_SIZE/SECTOR_SIZE);
X>   return(0);
X> }
X> 
X> sort(val)
X> register long *val;
X> {
X>   register int i,j;
X> 
X>   for (i=0; i<4; i++)
X> 	for (j=0; j<3; j++)
X> 		if ((val[j] == 0) && (val[j+1] != 0))
X> 			swap(&val[j], &val[j+1]);
X> 		else if (val[j] > val[j+1] && val[j+1] != 0)
X> 			swap(&val[j], &val[j+1]);
X> }
X> 
X> swap(register long *first, register long *second)
X> {
X>   register long tmp;
X> 
X> first, *second;
X>   tmp = *first;
X>   *first = *second;
X>   *second = tmp;
X> }
+ END-OF-FILE tools/fsck.dif
chmod 'u=rw,g=r,o=r' tools/fsck.dif
set `sum tools/fsck.dif`
sum=$1
case $sum in
63034)	:;;
*)	echo 'Bad sum in 'tools/fsck.dif >&2
esac
echo Extracting tools/fsck1.dif
sed 's/^X//' > tools/fsck1.dif << '+ END-OF-FILE 'tools/fsck1.dif
X4,5c4,7
X< 
X< INCLUDE ..\lib\prologue.h      
X---
X> TURBO equ 1
X> XDEBUG equ 0
X> 
X> INCLUDE ..\lib\prologue.h
X13,18c15,20
X<   PUBLIC $main, @end, edata, exit, kerstack,_prt
X<   EXTRN  main:near
X<  ;EXTRN  cinit:near, debug:near
X< ENDIF
X< PUBLIC reset_di, diskio, getc, putc, dmaoverr
X< EXTRN cylsiz:word, tracksiz:word, drive:byte
X---
X>   PUBLIC $main, _end, _exit ;NOTUSED??: , edata, kerstack, _prt
X>   EXTRN  _main:near
X>  ;EXTRN  cinit:near, debug:near
X> ENDIF
X> PUBLIC _reset_diskette, _diskio, _getc, _putc, _dmaoverrun
X> EXTRN _cylsiz:word, _tracksiz:word, _drive:word
X25,26c27,28
X< @CODE   SEGMENT
X<         assume  cs:@code,ds:dgroup
X---
X> _TEXT   SEGMENT
X>         assume  cs:_TEXT,ds:dgroup
X33c35
X<         mov     cx,offset dgroup:@end
X---
X>         mov     cx,offset dgroup:_end
X40,51c42,46
X< 	mov	dgroup:tracksiz,dx	; dx (was bx) is # sectors/track
X< 	add	dx,dx
X< 	mov	dgroup:cylsiz,dx	; # sectors/cylinder
X< 	mov	sp,offset dgroup:kerstack+STACKSIZE
X< 	
X< ;	call	cinit
X< ;	mov	ax,offset fsckmsg
X< ;	push	ax
X< ;	call	debug
X< ;	pop	ax
X< 	
X< 	call	main
X---
X> 	mov	dgroup:_tracksiz,dx	; dx (was bx) is # sectors/track
X> 	add	dx,dx
X> 	mov	dgroup:_cylsiz,dx	; # sectors/cylinder
X> 	mov	sp,offset dgroup:kerstack+STACKSIZE
X> 	call	_main
X61c56
X< exit:	mov	bx,dgroup:tracksiz
X---
X> _exit:	mov	bx,dgroup:_tracksiz
X92,95c87,97
X< putc:
X<         xor     ax,ax
X<         call    csv
X<         mov     al,4[bp]        ; al contains char to be printed
X---
X> _putc:
X> ifdef TURBO
X>         push    bp
X>         mov     bp,sp
X>         xor     ax,ax
X> else
X>         xor     ax,ax
X>         call    csv
X> endif
X> 
X>         mov     ax,4[bp]        ; al contains char to be printed
X101,103c103,110
X<         jmp     cret
X< 
X< getc:
X---
X> ifdef TURBO
X>         pop     bp
X>         ret
X> else
X>         jmp     cret
X> endif
X> 
X> _getc:
X108,110c115,119
X< reset_di:                       ; reset_diskette
X<         xor     ax,ax
X<         call    csv
X---
X> _reset_diskette:                       ; reset_diskette
X>         xor     ax,ax
X> ifndef TURBO
X>         call    csv
X> endif
X114c123,127
X<         jmp     cret
X---
X> ifdef TURBO
X>         ret
X> else
X>         jmp     cret
X> endif
X118,120c131,140
X< diskio:
X< 	xor	ax,ax
X< 	call	csv
X---
X> _diskio:
X> 	xor	ax,ax
X> ifdef TURBO
X> 	push	bp
X> 	mov	bp,sp
X> 	push	si
X> 	push	di
X> else
X> 	call	csv
X> endif
X126c146
X< 	div	dgroup:cylsiz	; ax = cylinder, dx = sector within cylinder
X---
X> 	div	dgroup:_cylsiz	; ax = cylinder, dx = sector within cylinder
X133c153
X< 	div	dgroup:tracksiz	; ax = head, dx = sector
X---
X> 	div	dgroup:_tracksiz	; ax = head, dx = sector
X137c157,163
X< 	mov	dl,dgroup:drive	; dl = drive code (0-3 or 0x80 - 0x81)
X---
X> 
X> ; _drive used to be declared as a byte here but as an int in fsck.c
X> ; so now we have to use the int-declaration from fsck.c:
X> ;
X> ;	mov	dl,dgroup:_drive	
X> 
X> 	mov	dl,byte ptr dgroup:_drive	; dl = drive code (0-3 or 0x80 - 0x81)
X142c168
X< 	cmp	al,byte ptr dgroup:tracksiz ; see if last sector is on next track
X---
X> 	cmp	al,byte ptr dgroup:_tracksiz ; see if last sector is on next track
X163,166c189,200
X< d2:	jmp	cret
X< 
X< 
X< dmaoverr:                       ; test if &buffer causes a DMA overrun
X---
X> d2:	
X> ifdef TURBO
X> 	pop	di
X> 	pop	si
X> 	pop	bp
X> 	ret
X> else
X> 	jmp	cret
X> endif
X> 
X> 
X> _dmaoverrun:                       ; test if &buffer causes a DMA overrun
X186a221
X> ifndef TURBO
X202,207c237,242
X< 
X< 
X< @CODE   ENDS
X< 
X< 
X< @DATAI	SEGMENT
X---
X> endif
X> 
X> _TEXT	ENDS
X> 
X> 
X> _DATA	SEGMENT
X211,212c246
X< fsckmsg DB "arrived at fsck1",0
X< @DATAI	ENDS
X---
X> _DATA	ENDS
X231,241c265,275
X< @DATAT  SEGMENT			; DATAT holds nothing. The label tells us
X< edata   label byte              ; where .data ends.
X< @DATAT  ENDS
X< 
X< @DATAU   SEGMENT		; allocate the stack in .bss
X< kerstack DB STACKSIZE dup(?)
X< @DATAU   ENDS
X< 
X< @DATAV  SEGMENT			; DATAV holds nothing. The label tells us
X< @end    label byte              ; where .data+.bss ends (first free memory)
X< @DATAV  ENDS
X---
X> _DATAEND	SEGMENT		; DATAEND holds nothing. The label tells us
X> edata   label byte              ; where .data ends.
X> _DATAEND  ENDS
X> 
X> _BSS	SEGMENT		; allocate the stack in .bss
X> kerstack DB STACKSIZE dup(?)
X> _BSS	ENDS
X> 
X> _BSSEND  SEGMENT			; DATAV holds nothing. The label tells us
X> _end    label byte              ; where .data+.bss ends (first free memory)
X> _BSSEND	ENDS
X248,249c282,283
X<         END     ; end of assembly-file
X< 
X---
X>         END $main     ; end of assembly-file
X> 
+ END-OF-FILE tools/fsck1.dif
chmod 'u=rw,g=r,o=r' tools/fsck1.dif
set `sum tools/fsck1.dif`
sum=$1
case $sum in
60374)	:;;
*)	echo 'Bad sum in 'tools/fsck1.dif >&2
esac
echo Extracting tools/makefile
sed 's/^X//' > tools/makefile << '+ END-OF-FILE 'tools/makefile
XDOS=0
X!if $(DOS)
XINCLUDE=\tc\include
X!else
XINCLUDE=..\include
X!endif
XCC=tcc
XCCOPTS=-Di8088 -DSTANDALONE -DTURBO -UDOS
XTCLIB=\tc\lib
XLN=tlink /n/s/c/d
XFORMATTER=c:\etc\format
X
X.c.obj:
X	$(CC) -A -mt -I$(INCLUDE) $(OPTS) -c $<
X
X.asm.obj:
X	masm /mx $<,,nul,nul
X
X.obj.exe:
X	$(LN) ..\mlib\head $<,$*,$*,..\mlib\minix
X
X.exe.out:
X	dos2out -d $*
X
Xbootblok.bin:	bootblok.asm
X	masm /mx bootblok,,nul,nul
X	link bootblok,,nul,nul
X	exe2bin bootblok.exe bootblok.bin
X	del bootblok.exe
X	del bootblok.obj
X
Xminix:	bootblok.bin ..\kernel\kernel.out ..\mm\mm.out ..\fs\fs.out init.out fsck.out
X	build bootblok.bin ..\kernel\kernel.out ..\mm\mm.out ..\fs\fs.out init.out fsck.out a:
X
X# the @*#*&!!?@#$!% DOS-formatter doesn't return a proper error-code !!
X
Ximage:	bootblok.bin ..\kernel\kernel.out ..\mm\mm.out ..\fs\fs.out init.out fsck.out
X	- $(FORMATTER) a:
X	build bootblok.bin ..\kernel\kernel.out ..\mm\mm.out ..\fs\fs.out init.out fsck.out a:
X
Xfsck.out:	fsck.exe
X
Xfsck.exe:	fsck1.obj fsck.obj
X	$(LN) fsck1 fsck,fsck,fsck,..\mlib\minix
X
Xfsck1.obj:	fsck1.asm
X
Xfsck.obj:	fsck.c
X
Xinit.out:	init.exe
X
Xinit.exe:	init.obj
X	$(LN) ..\mlib\head init,init,init,..\mlib\minix
X
Xinit.obj:	init.c
X
Xbuild.exe:	build.obj
X	$(LN) $(TCLIB)\c0s build,build,build,$(TCLIB)\cs
X
Xbuild.obj:	build.c
+ END-OF-FILE tools/makefile
chmod 'u=rw,g=r,o=r' tools/makefile
set `sum tools/makefile`
sum=$1
case $sum in
37582)	:;;
*)	echo 'Bad sum in 'tools/makefile >&2
esac
exit 0

MEYER%DEARN.BITNET@wiscvm.wisc.edu (Udo Meyer) (08/03/87)

The mail file limit of the DEARN LISTSERV machine is currently set to
2000 lines. This mail and some of the previous on MINIX-L have therefore
not been distributed to the subscribers at DEARN.

Happy EARNing...Udo Meyer, EARN Coordinator Germany