[comp.os.minix] Changes to compile Minix with MSC

ericr@ipmoea.UUCP (Eric Roskos) (08/09/87)

I've received a lot of requests, so I will post the changes I made to
Minix thus far, including those to make it compile with MSC, over the
next few days.

However, before you start putting these into your sources, please be sure
you want to do this.

There are a lot of changes here; about 40 files worth.  There are 3
different changes included here, because they were all changes I felt were
necessary before I could start using Minix on my machine.

The three changes are:

	1) A temporary "generic winchester" driver which can be used to
	   get Minix running until you write a driver for your disk
	   controller (or can afford to buy a new controller);

	2) A change that causes Minix to be loaded from floppy, as before,
	   but then lets you select whether the root filesystem should be
	   on RAM disk or a hard disk partition; and

	3) The changes to compile with MSC.

What this means depends on how you see Minix.  If you just want to use Minix
to run programs from the Usenet, etc., you probably should not put these
changes in.  I say this because if you make a lot of changes
to the OS, don't understand the changes, and would rather not be doing
programming in the OS internals anyway, this is likely to be too difficult.

You should also not put these changes in if you don't need them: if Minix
already runs fine on your machine, you already have what I had to build
to get where I am now, so you really don't need these changes.

In the first file (1 of 12), containing the Kernel changes, I've put in 
comments explaining why I made some of the more obscure ones; hopefully
this will make the reasons for the changes more clear.

I'll post the changes in the following 12 messages; I'll try to put a short
explanation in front of each.  There are two types of files: "diff" files
showing changes, and "shar" files containing DOS Makefiles, etc.  I'll
post the "diff" files first.

-- Eric Roskos

ericr@ipmoea.UUCP (Eric Roskos) (08/09/87)

This is the largest of the changes.  I've interspersed comments on the changes 
in the diff list, preceeded by ">>>>".  (Don't use "patch" -- see intro.)

After this, everything else will look trivial, so I posted it first to get
it out of the way.


Directory: /usr2/ericr/minix/minix/kernel

------------------------------------------------------------
*** const.h	Sat Aug  1 13:37:11 1987
--- ../../dos/kernel/const.h	Sat Aug  1 13:31:25 1987
***************
*** 49,51
  #define USER_Q             2	/* ready users are scheduled via queue 2 */
  
  #define printf        printk	/* the kernel really uses printk, not printf */

--- 49,52 -----
  #define USER_Q             2	/* ready users are scheduled via queue 2 */
  
  #define printf        printk	/* the kernel really uses printk, not printf */
+ #define interrupt     intr

------------------------------------------------------------
*** klib88.asm	Sat Aug  1 13:36:59 1987
--- ../../dos/kernel/klib88.asm	Sat Aug  1 13:31:10 1987
***************
*** 19,27
  ;   get_byte:	reads a	byte from a user program and returns it	as value
  
  ; The following	procedures are defined in this file and	called from outside it.
! PUBLIC phys_cop, cp_mess, port_out, port_in, lock, unlock, restore
! PUBLIC build_si, csv, cret, get_chro, vid_copy,	get_byte
! PUBLIC reboot, wreboot
  
  ; The following	external procedure is called in	this file.
  EXTRN panic:NEAR

--- 19,27 -----
  ;   get_byte:	reads a	byte from a user program and returns it	as value
  
  ; The following	procedures are defined in this file and	called from outside it.
! PUBLIC _phys_copy, _cp_mess, _port_out, _port_in, _lock, _unlock, _restore
! PUBLIC _build_sig, _get_chrome, _vid_copy,	_get_byte
! PUBLIC _reboot, _wreboot
  
  	ifdef GENERIC_FDISK
  PUBLIC _hdisk_params, _diskio, _win_init, _wn_low_safety, _wn_low_xor

>>>> Here, as a lot of places, an underscore had to be put in front because
>>>> that's what MSC does.  There is an option to turn the underscores
>>>> off, but it also then puts parameters on the stack in a non-C way.
>>>> This was a change local to the assembly files, which are always
>>>> machine-specific already anyway.  If you change the way the stack is
>>>> set up, some of the C code may have to be changed.

***************
*** 23,28
  PUBLIC build_si, csv, cret, get_chro, vid_copy,	get_byte
  PUBLIC reboot, wreboot
  
  ; The following	external procedure is called in	this file.
  EXTRN panic:NEAR
  

--- 23,32 -----
  PUBLIC _build_sig, _get_chrome, _vid_copy,	_get_byte
  PUBLIC _reboot, _wreboot
  
+ 	ifdef GENERIC_FDISK
+ PUBLIC _hdisk_params, _diskio, _win_init, _wn_low_safety, _wn_low_xor
+ 	endif
+ 
  ; The following	external procedure is called in	this file.
  EXTRN _panic:NEAR

>>>> These are the public symbols for the generic winchester driver.  If
>>>> you define GENERIC_FDISK when compiling Minix, you will get the generic
>>>> winchester code included.  I debated putting this in a separate file,
>>>> and decided that this code was general enough to go here for now.
  
***************
*** 24,30
  PUBLIC reboot, wreboot
  
  ; The following	external procedure is called in	this file.
! EXTRN panic:NEAR
  
  ; Variables and	data structures
  EXTRN color:WORD, cur_proc:WORD, proc_ptr:WORD,	splimit:WORD

--- 28,34 -----
  	endif
  
  ; The following	external procedure is called in	this file.
! EXTRN _panic:NEAR
  
  ; Variables and	data structures
  EXTRN _color:WORD, _cur_proc:WORD, _proc_ptr:WORD,	_splimit:WORD
***************
*** 27,34
  EXTRN panic:NEAR
  
  ; Variables and	data structures
! EXTRN color:WORD, cur_proc:WORD, proc_ptr:WORD,	splimit:WORD
! PUBLIC vec_tabl
  
  INCLUDE	..\lib\prologue.h
  

--- 31,39 -----
  EXTRN _panic:NEAR
  
  ; Variables and	data structures
! EXTRN _color:WORD, _cur_proc:WORD, _proc_ptr:WORD,	_splimit:WORD
! EXTRN _vid_mask:WORD
! PUBLIC _vec_table
  
  INCLUDE	..\lib\prologue.h

>>>> Apparently C86 required the names to be truncated, but MSC didn't,
>>>> so that was fixed here as well as putting underscores on.
  
***************
*** 32,37
  
  INCLUDE	..\lib\prologue.h
  
  
  @CODE	SEGMENT
  	assume	cs:@code,ds:dgroup

--- 37,55 -----
  
  INCLUDE	..\lib\prologue.h
  
+ ;
+ ; Macro to call the Hard Disk BIOS.  This is a macro because int 13 won't
+ ; work with Minix on my BIOS... don't know why... this lets you 
+ ; change it easily.
+ ;
+ hdcall	macro
+ 	ifdef	ERSATZ_GENERIC
+ 	pushf
+ 	call	dword ptr [disk_rom]
+ 	else
+ 	int	13H
+ 	endif
+ 	endm
  
  _TEXT	SEGMENT
  	assume	cs:_text,ds:dgroup

>>>> When I was debugging the hard disk BIOS, I had some trouble using int 13
>>>> at first, so for awhile I had a hardcoded, simulated interrupt in this
>>>> macro (which you get if you define ERSATZ_GENERIC).  But then I finally
>>>> got int 13 working.  I left this macro this way in case you find you have
>>>> some problem with your particular disk controller, but you'll have to
>>>> figure out the value for disk_rom, and fill it in, before it will work.

***************
*** 33,40
  INCLUDE	..\lib\prologue.h
  
  
! @CODE	SEGMENT
! 	assume	cs:@code,ds:dgroup
  
  ;===========================================================================
  ;				phys_copy

--- 51,58 -----
  	endif
  	endm
  
! _TEXT	SEGMENT
! 	assume	cs:_text,ds:dgroup

>>>> A different segment name is produced by MSC for the main code segment...
  
  ;===========================================================================
  ;				phys_copy
***************
*** 42,48
  ; This routine copies a	block of physical memory.  It is called	by:
  ;    phys_copy(	(long) source, (long) destination, (long) bytecount)
  
! phys_cop:
  	pushf			; save flags
  	cli			; disable interrupts
  	push bp			; save the registers

--- 60,66 -----
  ; This routine copies a	block of physical memory.  It is called	by:
  ;    phys_copy(	(long) source, (long) destination, (long) bytecount)
  
! _phys_copy:
  	pushf			; save flags
  	cli			; disable interrupts
  	push bp			; save the registers
***************
*** 143,149
  ; This routine destroys	ax.  It	preserves the other registers.
  
  Msize =	12			; size of a message in 16-bit words
! cp_mess:
  	push bp			; save bp
  	push es			; save es
  	push ds			; save ds

--- 161,167 -----
  ; This routine destroys	ax.  It	preserves the other registers.
  
  Msize =	12			; size of a message in 16-bit words
! _cp_mess:
  	push bp			; save bp
  	push es			; save es
  	push ds			; save ds
***************
*** 180,186
  ;===========================================================================
  ; port_out(port, value)	writes 'value' on the I/O port 'port'.
  
! port_out:
  	push bx			; save bx
  	mov bx,sp		; index	off bx
  	push ax			; save ax

--- 198,204 -----
  ;===========================================================================
  ; port_out(port, value)	writes 'value' on the I/O port 'port'.
  
! _port_out:
  	push bx			; save bx
  	mov bx,sp		; index	off bx
  	push ax			; save ax
***************
*** 198,204
  ;				port_in
  ;===========================================================================
  ; port_in(port,	&value)	reads from port	'port' and puts	the result in 'value'.
! port_in:
  	push bx			; save bx
  	mov bx,sp		; index	off bx
  	push ax			; save ax

--- 216,222 -----
  ;				port_in
  ;===========================================================================
  ; port_in(port,	&value)	reads from port	'port' and puts	the result in 'value'.
! _port_in:
  	push bx			; save bx
  	mov bx,sp		; index	off bx
  	push ax			; save ax
***************
*** 218,224
  ;				lock
  ;===========================================================================
  ; Disable CPU interrupts.
! lock:
  	pushf			; save flags on	stack
  	cli			; disable interrupts
  	pop lockvar		; save flags for possible restoration later

--- 236,242 -----
  ;				lock
  ;===========================================================================
  ; Disable CPU interrupts.
! _lock:
  	pushf			; save flags on	stack
  	cli			; disable interrupts
  	pop dgroup:lockvar		; save flags for possible restoration later
***************
*** 221,227
  lock:
  	pushf			; save flags on	stack
  	cli			; disable interrupts
! 	pop lockvar		; save flags for possible restoration later
  	ret			; return to caller
  
  

--- 239,245 -----
  _lock:
  	pushf			; save flags on	stack
  	cli			; disable interrupts
! 	pop dgroup:lockvar		; save flags for possible restoration later
  	ret			; return to caller
  
  
***************
*** 229,235
  ;				unlock
  ;===========================================================================
  ; Enable CPU interrupts.
! unlock:
  	sti			; enable interrupts
  	ret			; return to caller
  

--- 247,253 -----
  ;				unlock
  ;===========================================================================
  ; Enable CPU interrupts.
! _unlock:
  	sti			; enable interrupts
  	ret			; return to caller
  
***************
*** 238,245
  ;				restore
  ;===========================================================================
  ; Restore enable/disable bit to	the value it had before	last lock.
! restore:
! 	push lockvar		; push flags as	they were before previous lock
  	popf			; restore flags
  	ret			; return to caller
  

--- 256,263 -----
  ;				restore
  ;===========================================================================
  ; Restore enable/disable bit to	the value it had before	last lock.
! _restore:
! 	push dgroup:lockvar		; push flags as	they were before previous lock
  	popf			; restore flags
  	ret			; return to caller
  
***************
*** 263,269
  csreg =	18
  PSW   =	28
  
! build_si:
  	push bp			; save bp
  	mov bp,sp		; set bp to sp for accessing params
  	push bx			; save bx

--- 281,287 -----
  csreg =	18
  PSW   =	28
  
! _build_sig:
  	push bp			; save bp
  	mov bp,sp		; set bp to sp for accessing params
  	push bx			; save bx
***************
*** 284,289
  	ret			; return to caller
  
  
  ;===========================================================================
  ;		csv & cret  (compiler generated	symbols)
  ;===========================================================================

--- 302,309 -----
  	ret			; return to caller
  
  
+ 	ifdef	NEEDCSV
+ 	public csv, cret
  ;===========================================================================
  ;		csv & cret  (compiler generated	symbols)
  ;===========================================================================
***************
*** 289,295
  ;===========================================================================
  ; This version of csv replaces the standard one.  It checks for	stack overflow
  ; within the kernel in a simpler way than is usually done. cret	is standard.
! csv:
  	pop bx			; bx = return address
  	push bp			; stack	old frame pointer
  	mov bp,sp		; set new frame	pointer	to sp

--- 309,315 -----
  ;===========================================================================
  ; This version of csv replaces the standard one.  It checks for	stack overflow
  ; within the kernel in a simpler way than is usually done. cret	is standard.
! csv	proc	near
  	pop bx			; bx = return address
  	push bp			; stack	old frame pointer
  	mov bp,sp		; set new frame	pointer	to sp

>>>> MSC doesn't use a csv/cret, as far as I know, and didn't need this one;
>>>> I didn't use it in any assembly code I added, so I ifdef'ed it out.

***************
*** 296,302
  	push di			; save di
  	push si			; save si
  	sub sp,ax		; ax =	bytes of local variables
! 	cmp sp,dgroup:splimit	; has kernel stack grown too large
  	jbe csv1		; if sp	is too low, panic
  	jmp [bx]		; normal return: copy bx to program counter
  

--- 316,322 -----
  	push di			; save di
  	push si			; save si
  	sub sp,ax		; ax =	bytes of local variables
! 	cmp sp,dgroup:_splimit	; has kernel stack grown too large
  	jbe csv1		; if sp	is too low, panic
  	jmp [bx]		; normal return: copy bx to program counter
  
***************
*** 301,308
  	jmp [bx]		; normal return: copy bx to program counter
  
  csv1:
! 	mov dgroup:splimit,0		; prevent call to panic	from aborting in csv
! 	mov bx,dgroup:proc_ptr		; update rp->p_splimit
  	mov WORD PTR 50[bx],0		; rp->sp_limit = 0
  	push dgroup:cur_proc		; task number
  	mov ax,offset dgroup:stkoverrun	; stack	overran	the kernel stack area

--- 321,328 -----
  	jmp [bx]		; normal return: copy bx to program counter
  
  csv1:
! 	mov dgroup:_splimit,0		; prevent call to panic	from aborting in csv
! 	mov bx,dgroup:_proc_ptr		; update rp->p_splimit
  	mov WORD PTR 50[bx],0		; rp->sp_limit = 0
  	push dgroup:_cur_proc		; task number
  	mov ax,offset dgroup:stkoverrun; stack	overran	the kernel stack area
***************
*** 304,311
  	mov dgroup:splimit,0		; prevent call to panic	from aborting in csv
  	mov bx,dgroup:proc_ptr		; update rp->p_splimit
  	mov WORD PTR 50[bx],0		; rp->sp_limit = 0
! 	push dgroup:cur_proc		; task number
! 	mov ax,offset dgroup:stkoverrun	; stack	overran	the kernel stack area
  	push ax				; push first parameter
  	call panic		; call is: panic(stkoverrun, cur_proc)
  	jmp csv1		; this should not be necessary

--- 324,331 -----
  	mov dgroup:_splimit,0		; prevent call to panic	from aborting in csv
  	mov bx,dgroup:_proc_ptr		; update rp->p_splimit
  	mov WORD PTR 50[bx],0		; rp->sp_limit = 0
! 	push dgroup:_cur_proc		; task number
! 	mov ax,offset dgroup:stkoverrun; stack	overran	the kernel stack area
  	push ax				; push first parameter
  	call _panic		; call is: panic(stkoverrun, cur_proc)
  	jmp csv1		; this should not be necessary
***************
*** 307,313
  	push dgroup:cur_proc		; task number
  	mov ax,offset dgroup:stkoverrun	; stack	overran	the kernel stack area
  	push ax				; push first parameter
! 	call panic		; call is: panic(stkoverrun, cur_proc)
  	jmp csv1		; this should not be necessary
  
  

--- 327,333 -----
  	push dgroup:_cur_proc		; task number
  	mov ax,offset dgroup:stkoverrun; stack	overran	the kernel stack area
  	push ax				; push first parameter
! 	call _panic		; call is: panic(stkoverrun, cur_proc)
  	jmp csv1		; this should not be necessary
  
  csv	endp
***************
*** 310,315
  	call panic		; call is: panic(stkoverrun, cur_proc)
  	jmp csv1		; this should not be necessary
  
  
  cret:
  	lea	sp,-4[bp]	; set sp to point to saved si

--- 330,336 -----
  	call _panic		; call is: panic(stkoverrun, cur_proc)
  	jmp csv1		; this should not be necessary
  
+ csv	endp
  
  
  cret	proc	near
***************
*** 311,317
  	jmp csv1		; this should not be necessary
  
  
! cret:
  	lea	sp,-4[bp]	; set sp to point to saved si
  	pop	si		; restore saved	si
  	pop	di		; restore saved	di

--- 332,340 -----
  
  csv	endp
  
! 
! cret	proc	near
! 
  	lea	sp,-4[bp]	; set sp to point to saved si
  	pop	si		; restore saved	si
  	pop	di		; restore saved	di

>>>> Well, I guess I did use cret for awhile... I changed it to a "proc"
>>>> as a matter of coding style back when I was using it...

***************
*** 318,323
  	pop	bp		; restore bp
  	ret			; end of procedure
  
  ;===========================================================================
  ;				get_chrome
  ;===========================================================================

--- 341,350 -----
  	pop	bp		; restore bp
  	ret			; end of procedure
  
+ cret	endp
+ 
+ 	endif	; needcsv
+ 
  ;===========================================================================
  ;				get_chrome
  ;===========================================================================
***************
*** 324,330
  ; This routine calls the BIOS to find out if the display is monochrome or
  ; color.  The drivers are different, as	are the	video ram addresses, so	we
  ; need to know.
! get_chro:
  	int 11h			; call the BIOS	to get equipment type
  	and al,30h		; isolate color/mono field
  	cmp al,30h		; 0x30 is monochrome

--- 351,357 -----
  ; This routine calls the BIOS to find out if the display is monochrome or
  ; color.  The drivers are different, as	are the	video ram addresses, so	we
  ; need to know.
! _get_chrome:
  	int 11h			; call the BIOS	to get equipment type
  	and al,30h		; isolate color/mono field
  	cmp al,30h		; 0x30 is monochrome
***************
*** 352,358
  
  BLANK =	0700h
  
! vid_copy:
  	push bp			; we need bp to	access the parameters
  	mov bp,sp		; set bp to sp for indexing
  	push si			; save the registers

--- 379,385 -----
  
  BLANK =	0700h
  
! _vid_copy:
  	push bp			; we need bp to	access the parameters
  	mov bp,sp		; set bp to sp for indexing
  	push si			; save the registers
***************
*** 363,369
  	push es			; save es
  vid0:	mov si,4[bp]		; si = pointer to data to be copied
  	mov di,8[bp]		; di = offset within video ram
! 	and di,dgroup:vid_mask	; only 4K or 16K counts
  	mov cx,10[bp]		; cx = word count for copy loop
  	mov dx,03DAh		; prepare to see if color display is retracing
  

--- 390,396 -----
  	push es			; save es
  vid0:	mov si,4[bp]		; si = pointer to data to be copied
  	mov di,8[bp]		; di = offset within video ram
! 	and di,dgroup:_vid_mask	; only 4K or 16K counts
  	mov cx,10[bp]		; cx = word count for copy loop
  	mov dx,03DAh		; prepare to see if color display is retracing
  
***************
*** 370,376
  	mov bx,di		; see if copy will run off end of video ram
  	add bx,cx		; compute where copy ends
  	add bx,cx		; bx = last character copied + 1
! 	sub bx,dgroup:vid_mask	; bx = # characters beyond end of video ram
  	sub bx,1		; note: dec bx doesn't set flags properly
  	jle vid.1		; jump if no overrun
  	sar bx,1		; bx = # words that don't fit in video ram

--- 397,403 -----
  	mov bx,di		; see if copy will run off end of video ram
  	add bx,cx		; compute where copy ends
  	add bx,cx		; bx = last character copied + 1
! 	sub bx,dgroup:_vid_mask	; bx = # characters beyond end of video ram
  	sub bx,1		; note: dec bx doesn't set flags properly
  	jle vid1		; jump if no overrun
  	sar bx,1		; bx = # words that don't fit in video ram
***************
*** 372,378
  	add bx,cx		; bx = last character copied + 1
  	sub bx,dgroup:vid_mask	; bx = # characters beyond end of video ram
  	sub bx,1		; note: dec bx doesn't set flags properly
! 	jle vid.1		; jump if no overrun
  	sar bx,1		; bx = # words that don't fit in video ram
  	sub cx,bx		; reduce count by overrun
  	mov tmp,cx		; save actual count used for later

--- 399,405 -----
  	add bx,cx		; bx = last character copied + 1
  	sub bx,dgroup:_vid_mask	; bx = # characters beyond end of video ram
  	sub bx,1		; note: dec bx doesn't set flags properly
! 	jle vid1		; jump if no overrun
  	sar bx,1		; bx = # words that don't fit in video ram
  	sub cx,bx		; reduce count by overrun
  	mov dgroup:tmp,cx		; save actual count used for later

>>>> I'm not entirely sure how this assembled in the original source?

***************
*** 375,381
  	jle vid.1		; jump if no overrun
  	sar bx,1		; bx = # words that don't fit in video ram
  	sub cx,bx		; reduce count by overrun
! 	mov tmp,cx		; save actual count used for later
  
  vid1:	test dgroup:color,1	; skip vertical	retrace	test if	display	is mono
  	jz vid4			; if monochrome	then go	to vid.2

--- 402,408 -----
  	jle vid1		; jump if no overrun
  	sar bx,1		; bx = # words that don't fit in video ram
  	sub cx,bx		; reduce count by overrun
! 	mov dgroup:tmp,cx		; save actual count used for later
  
  vid1:	test dgroup:_color,1	; skip vertical	retrace	test if	display	is mono
  	jz vid4			; if monochrome	then go	to vid.2
***************
*** 377,383
  	sub cx,bx		; reduce count by overrun
  	mov tmp,cx		; save actual count used for later
  
! vid1:	test dgroup:color,1	; skip vertical	retrace	test if	display	is mono
  	jz vid4			; if monochrome	then go	to vid.2
  
  ;  vid2:in			; with a color display,	you can	only copy to

--- 404,410 -----
  	sub cx,bx		; reduce count by overrun
  	mov dgroup:tmp,cx		; save actual count used for later
  
! vid1:	test dgroup:_color,1	; skip vertical	retrace	test if	display	is mono
  	jz vid4			; if monochrome	then go	to vid.2
  
  ;  vid2:in			; with a color display,	you can	only copy to
***************
*** 401,408
  	cmp bx,0		; if bx < 0, then no overrun and we are done
  	jle vid6		; jump if everything fit
  	mov 10[bp],bx		; set up residual count
! 	mov 8[bp],0		; start copying at base of video ram
! 	cmp 4[bp],0		; NIL_PTR means store blanks
  	je vid0			; go do it
  	mov si,tmp		; si = count of words copied
  	add si,si		; si = count of bytes copied

--- 428,435 -----
  	cmp bx,0		; if bx < 0, then no overrun and we are done
  	jle vid6		; jump if everything fit
  	mov 10[bp],bx		; set up residual count
! 	mov word ptr 8[bp],0		; JER added size: start copying at base of video ram
! 	cmp word ptr 4[bp],0		; JER added size: NIL_PTR means store blanks
  	je vid0			; go do it
  	mov si,dgroup:tmp		; si = count of words copied
  	add si,si		; si = count of bytes copied

>>>> Here and in a number of places, it seems MASM 4.0 is more strict
>>>> than the assembler used to assemble the original sources:  the dgroup:
>>>> prefixes I added were required by MASM 4.0.

***************
*** 404,410
  	mov 8[bp],0		; start copying at base of video ram
  	cmp 4[bp],0		; NIL_PTR means store blanks
  	je vid0			; go do it
! 	mov si,tmp		; si = count of words copied
  	add si,si		; si = count of bytes copied
  	add 4[bp],si		; increment buffer pointer
  	jmp vid0		; go copy some more

--- 431,437 -----
  	mov word ptr 8[bp],0		; JER added size: start copying at base of video ram
  	cmp word ptr 4[bp],0		; JER added size: NIL_PTR means store blanks
  	je vid0			; go do it
! 	mov si,dgroup:tmp		; si = count of words copied
  	add si,si		; si = count of bytes copied
  	add 4[bp],si		; increment buffer pointer
  	jmp vid0		; go copy some more
***************
*** 409,414
  	add 4[bp],si		; increment buffer pointer
  	jmp vid0		; go copy some more
  
  	pop es			; restore registers
  	pop dx			; restore dx
  	pop cx			; restore cx

--- 436,442 -----
  	add 4[bp],si		; increment buffer pointer
  	jmp vid0		; go copy some more
  
+ vid6:				; JER - not in original source (vid6 label)
  	pop es			; restore registers
  	pop dx			; restore dx
  	pop cx			; restore cx
***************
*** 431,437
  ; where
  ;     'seg' is the value to put	in es
  ;     'off' is the offset from the es value
! get_byte:
  	push bp			; save bp
  	mov bp,sp		; we need to access parameters
  	push es			; save es

--- 459,465 -----
  ; where
  ;     'seg' is the value to put	in es
  ;     'off' is the offset from the es value
! _get_byte:
  	push bp			; save bp
  	mov bp,sp		; we need to access parameters
  	push es			; save es
***************
*** 449,454
  ;===========================================================================
  ; This code reboots the	PC
  
  
  reboot:
  	cli			; disable interrupts

--- 477,484 -----
  ;===========================================================================
  ; This code reboots the	PC
  
+ rb_vect		dw	00000H	; hardware restart address
+ 		dw	0FFFFH
  
  ; The following zeros out BIOS RAM (ROS on an IBM :-)) to clear any
  ; warmstart flags that may be present in a given BIOS.

>>>> This one's highly debatable... on my machine, when you did a ctrl-alt-del
>>>> with Minix running, you had to do it once to get DOS booted, then again
>>>> to get things reset: because Minix didn't reset the video controller,
>>>> and didn't reset the clock, the way DOS expected.  I thought a good while
>>>> and decided that DOS assumes when it is first loaded that it is starting
>>>> on a newly-initialized machine, probably, so the best thing to do for
>>>> compatibility with the maximum number of clones was to zero out low
>>>> memory so it resembled a freshly-started machine.  But on an IBM PC,
>>>> this will cause the long-running memory test to occur.  You can change
>>>> this if you find it works better a different way on your machine, but
>>>> it may not work on as many clones; you could try filling low memory with>>>> 1234H and see if that helps...
>>>>
>>>> wp(boot_dos_on_clone, machine_runs_ok) = low_memory_indeterminate :-)
>>>> 
>>>> (I used zeros because I figured most programmers would say, "the
>>>> machine is more likely to have zeros in ram, so that's not a good
>>>> number to choose", so there is something less than the 1/65536 probability
>>>> of failure if RAM contains zero, under my hypothesis...)

***************
*** 450,456
  ; This code reboots the	PC
  
  
! reboot:
  	cli			; disable interrupts
  	mov al,20h
  	out 20h,al		; re-enable interrupt controller

--- 480,514 -----
  rb_vect		dw	00000H	; hardware restart address
  		dw	0FFFFH
  
! ; The following zeros out BIOS RAM (ROS on an IBM :-)) to clear any
! ; warmstart flags that may be present in a given BIOS.
! 
! zros	proc	near
! 
! 	mov	cx,0100H	; 200H bytes / sizeof(word)
! 	mov	ax,0		; segment 0 & value to store
! 	mov	es,ax		; set es to low memory
! 	mov	di,0400H	; clear addresses 400H-5FFH
! 	cld			; autoincrement
! 	rep stosw		; zero out memory
! 	ret
! 
! zros	endp
! 
! ; Restore the interrupt	vectors	in low core.
! _resvec	proc	near
! 
! 	cld
! 	mov cx,2*65
! 	mov si,offset dgroup:_vec_table
! 	xor di,di
! 	mov es,di
!     rep	movsw
! 	ret
! 
! _resvec	endp
! 
! _reboot:
  	cli			; disable interrupts
  	mov al,20h
  	out 20h,al		; re-enable interrupt controller
***************
*** 454,461
  	cli			; disable interrupts
  	mov al,20h
  	out 20h,al		; re-enable interrupt controller
! 	call resvec		; restore the vectors in low core
! 	int 19h			; reboot the PC
  
  wreboot:
  	cli			; disable interrupts

--- 512,521 -----
  	cli			; disable interrupts
  	mov al,20h
  	out 20h,al		; re-enable interrupt controller
! ;;;;;	call _resvec		; restore the vectors in low core
! ;;;;;	int 19h			; reboot the PC
! 	call zros		; zero out low memory to force cold restart
! 	jmp dword ptr rb_vect
  
  _wreboot:
  	cli			; disable interrupts
***************
*** 457,463
  	call resvec		; restore the vectors in low core
  	int 19h			; reboot the PC
  
! wreboot:
  	cli			; disable interrupts
  	mov al,20h		; re-enable interrupt controller
  	out 20h,al

--- 517,523 -----
  	call zros		; zero out low memory to force cold restart
  	jmp dword ptr rb_vect
  
! _wreboot:
  	cli			; disable interrupts
  	mov al,20h		; re-enable interrupt controller
  	out 20h,al
***************
*** 461,467
  	cli			; disable interrupts
  	mov al,20h		; re-enable interrupt controller
  	out 20h,al
! 	call resvec		; restore the vectors in low core
  	xor ax,ax		; wait for character before continuing
  	int 16h			; get char
  	int 19h			; reboot the PC

--- 521,527 -----
  	cli			; disable interrupts
  	mov al,20h		; re-enable interrupt controller
  	out 20h,al
! 	call _resvec		; restore the vectors in low core to call BIOS
  	xor ax,ax		; wait for character before continuing
  	int 16h			; get char
  	call zros		; zero out low memory to force cold restart
***************
*** 464,470
  	call resvec		; restore the vectors in low core
  	xor ax,ax		; wait for character before continuing
  	int 16h			; get char
! 	int 19h			; reboot the PC
  
  ; Restore the interrupt	vectors	in low core.
  resvec:

--- 524,532 -----
  	call _resvec		; restore the vectors in low core to call BIOS
  	xor ax,ax		; wait for character before continuing
  	int 16h			; get char
! 	call zros		; zero out low memory to force cold restart
! ;;;;;	int 19h			; reboot the PC
! 	jmp dword ptr rb_vect
  
  
  	ifdef	GENERIC_FDISK
***************
*** 466,479
  	int 16h			; get char
  	int 19h			; reboot the PC
  
! ; Restore the interrupt	vectors	in low core.
! resvec:
! 	cld
! 	mov cx,2*65
! 	mov si,offset dgroup:vec_tabl
! 	xor di,di
! 	mov es,di
!     rep	movsw
  	ret
  
  @CODE	ENDS

--- 528,594 -----
  ;;;;;	int 19h			; reboot the PC
  	jmp dword ptr rb_vect
  

>>>> Below are the C interfaces to the BIOS that are used in the generic
>>>> disk driver...

! 	ifdef	GENERIC_FDISK
! 
! 
! ;===========================================================================
! ;				diskio - JER (copied from fsck1)
! ;===========================================================================
! 
! ; diskio(RW, cyl, sector, head, #sectors, drv, sb, ib, trksiz)
! ;	   4    6     8      10      12     14   16  18    20
! ; Do not issue a BIOS call that crosses a track boundary
! _diskio:
! 	push	bp
! 	mov	bp,sp
! 	push	si
! 	push	di
! 	mov	tmp1,0		; tmp1 = # sectors actually transferred
! 	mov	di,12[bp]	; di = # sectors to transfer
! 	mov	tmp2,di		; di = # sectors to transfer
! d0:
! 	mov	ax,6[bp]	; cylinder
! 	mov	cl,ah		; cl = hi-order bits of cylinder
! 	ror	cl,1		; BIOS expects hi bits in a funny place
! 	ror	cl,1		; 
! 	mov	ch,al		; cx = sector # in BIOS format
! 	mov	dh,10[bp]	; dh = head
! 	and	cl,0C0H		; mask off any garbage bits
! 	or	cl,8[bp]	; cl = sector # in low 6 bits
! 	inc	cl		; BIOS counts sectors starting at 1
! 	mov	dl,14[bp]	; dl = drive code (0-3 or 0x80 - 0x81)
! 	or	dl,80H		; force "hard disk" bit on
! 	push	es		; set es with sb of buffer
! 	mov	bx,16[bp]
! 	mov	es,bx
! 	mov	bx,18[bp]	; bx = ib of buffer
! 	mov	ah,4[bp]	; ah = READING or WRITING
! 	add	ah,2		; BIOS codes are 2 and 3, not 0 and 1
! 	mov	al,12[bp]	; al = # sectors to transfer
! 	mov	tmp,ax		; save, al is # sectors to read/write
! 	hdcall			; call the hard disk BIOS
! 	pop	es		; restore es saved when setting sb above
! ;	cmp	ah,0		; ah!=0 means BIOS detected error (no, cy does)
! ;	jne	d2		; exit with error
! 	jc	d2fail		; if carry set, error occurred
! 	mov	ax,tmp		; fetch count of sectors transferred
! 	xor	ah,ah		; count is in ax
! 	add	tmp1,ax		; tmp1 accumulates sectors transferred
! 	mov	si,tmp1		; are we done yet?
! 	cmp	si,tmp2	
! 	je	d2ok		; jump if done
! 	inc	word ptr 8[bp]	; next time around, start 1 sector higher
! 	add	18[bp],200h	; move up in buffer by 512 bytes (ib 4 bits)
! 	jmp	d0
! d2ok:
! 	xor	ah,ah		; indicate "read OK" to driver
! d2fail:	
! 	xor	al,al		; move 1-byte BIOS error code into integer
! 	xchg	ah,al		;    return value for C caller
! 	pop	di
! 	pop	si
! 	pop	bp
  	ret
  
  ;===========================================================================

>>>> The above is not actually a copy of the fsck1 code the way the comment
>>>> says, but it's close.

***************
*** 476,482
      rep	movsw
  	ret
  
! @CODE	ENDS
  
  
  

--- 591,626 -----
  	pop	bp
  	ret
  
! ;===========================================================================
! ;	hdisk_params - JER - get hard disk params more legally
! ;===========================================================================
! ; hdisk_params(drive, pparams)
! _hdisk_params	proc	near
! 	push	bp
! 	mov	bp,sp
! 	mov	dl,4[bp]	; drive number
! 	or	dl,80H		; indicate fixed disk
! 	mov	ah,08H		; request parameters
! 	push	es
! 	hdcall			; call the hard disk BIOS
! 	pop	es
! 	mov	bx,6[bp]	; near pointer to parameter block
! 	mov	2[bx],dh	; maximum head number
! 	mov	byte ptr 3[bx],0 ; 256 head disk?
! 	inc	word ptr 2[bx] 	; convert to number of heads
! 	mov	6[bx],cl	; number of sectors
! 	and	byte ptr 6[bx],3fH ; mask off cyl # bits
! 	mov	byte ptr 7[bx],0
! 	rol	cl,1		; get cyl # high order bits
! 	rol	cl,1
! 	and	cl,03H
! 	xchg	cl,ch		; put in proper order
! 	mov	0[bx],cx	; store in parameter block
! 	xor	dh,dh
! 	mov	4[bx],dx	; number of drives
! 	pop	bp		; done
! 	ret
! _hdisk_params	endp
  
  _win_init	proc	near
  	push	bp

>>>> The original driver didn't make a BIOS call to do this... it looked
>>>> around in the controller's option switches, the hard disk parameter
>>>> table (pointed to by a vector in low memory), etc.  That's because
>>>> the BIOS vectors are patched out at startup; but I reenabled them
>>>> if this option (GENERIC_FDISK) is defined, so the BIOS call is
>>>> available here.

***************
*** 478,483
  
  @CODE	ENDS
  
  
  
  @DATAI	SEGMENT

--- 622,646 -----
  	ret
  _hdisk_params	endp
  
+ _win_init	proc	near
+ 	push	bp
+ 	mov	bp,sp
+ 	mov	ah,00H		; BIOS reset
+ 	mov	dl,80H
+ 	push	es
+ 	hdcall			; call the hard disk BIOS
+ 	pop	es
+ 	jc	wi0		; return error if carry set
+ 	mov	ah,11H		; drive recalibrate
+ 	mov	dl,80H
+ 	push	es
+ 	hdcall			; call hard disk BIOS
+ 	pop	es
+ 	jc	wi0		; return error if carry set
+ 	xor	ax,ax		; return "OK"
+ wi0:	pop	bp
+ 	ret
+ _win_init	endp
  
  
  	endif	; GENERIC_FDISK
***************
*** 480,486
  
  
  
! @DATAI	SEGMENT
  lockvar	   DW	 0		; place	to store flags for lock()/restore()
  tmp        DW    0		; count of bytes already copied
  vec_tabl   DW	 130 dup(0)	; storage for interrupt	vectors

--- 643,656 -----
  _win_init	endp
  
  
! 	endif	; GENERIC_FDISK
! 
! 
! _TEXT	ENDS
! 
! 
! 
! _DATA	SEGMENT
  lockvar	   DW	 0		; place	to store flags for lock()/restore()
  tmp        DW    0		; count of bytes already copied
  tmp1	   DW	 0
***************
*** 483,489
  @DATAI	SEGMENT
  lockvar	   DW	 0		; place	to store flags for lock()/restore()
  tmp        DW    0		; count of bytes already copied
! vec_tabl   DW	 130 dup(0)	; storage for interrupt	vectors
  stkoverrun DB	 "Kernel stack overrun,	task = ",0
  @DATAI	ENDS
  

--- 653,687 -----
  _DATA	SEGMENT
  lockvar	   DW	 0		; place	to store flags for lock()/restore()
  tmp        DW    0		; count of bytes already copied
! tmp1	   DW	 0
! tmp2	   DW	 0

>>>> These temporaries are used by the _diskio routine... this is not
>>>> really so good, since it makes the routine non-reentrant.  They should
>>>> really be on the stack, but presently I don't think _diskio is
>>>> executed by more than one process at once.  Still, it's this sort of
>>>> thing that will cause you trouble a few years down the road, so this
>>>> is one of the things I don't feel good about.  I'll probably change it
>>>> within a few months, so you may want to do this too...?

! 
! 	ifdef ERSATZ_GENERIC
! ;
! ; The following vector is used to invoke the hard disk BIOS on the hard
! ; disk controller.  It should be possible to do this via an int 13, but
! ; for awhile I couldn't get it to work, so I used this.
! ;
! disk_rom   DW	 00897H
! 	   DW	 0C800H
! 	endif
! 
! ;
! ; The following are used by gn_wini to do an integrity check on the
! ; partition offsets -- they're here so that an errant program which
! ; destroys the "wini" table is less likely to destroy these too, although
! ; there's also a check on the integrity of these constants themselves
! ; against a constant in the instruction space of the winchester task.
! ;
! _wn_low_safety	dd	0H
! _wn_low_xor	dd	0H
! 
! ;
! ; Here is where the original interrupt vectors get stored
! ;
! _vec_table   DW	 130 dup(0)	; storage for interrupt	vectors
  stkoverrun DB	 "Kernel stack overrun,	task = ",0
  _DATA	ENDS
  
***************
*** 485,491
  tmp        DW    0		; count of bytes already copied
  vec_tabl   DW	 130 dup(0)	; storage for interrupt	vectors
  stkoverrun DB	 "Kernel stack overrun,	task = ",0
! @DATAI	ENDS
  
  	END	; end of assembly
  

--- 683,689 -----
  ;
  _vec_table   DW	 130 dup(0)	; storage for interrupt	vectors
  stkoverrun DB	 "Kernel stack overrun,	task = ",0
! _DATA	ENDS
  
  	END	; end of assembly
  
------------------------------------------------------------
*** main.c	Sat Aug  1 13:36:50 1987
--- ../../dos/kernel/main.c	Sat Aug  1 13:31:02 1987
***************
*** 40,45
    vir_clicks size;
    phys_clicks base_click, mm_base, previous_base;
    phys_bytes phys_b;
    extern unsigned sizes[8];	/* table filled in by build */
    extern int color, vec_table[], get_chrome(), (*task[])();
    extern int s_call(), disk_int(), tty_int(), clock_int(), disk_int();

--- 40,47 -----
    vir_clicks size;
    phys_clicks base_click, mm_base, previous_base;
    phys_bytes phys_b;
+   phys_bytes pridx, pfs0;
>>>> Means "pointer to root index" and "pointer to fs's word 0"
>>>> these are *physical* addresses (at least in the context of Minix).
+   int root_idx;
>>>> The index into an imaginary table telling where the root filesystem
>>>> should go.  I did *not* use the "scan code" here, eventhough this
>>>> abstract integer root_idx is a function of the "scan code", because
>>>> the "scan code" is peculiar to IBM PC's, and thus does not in any
>>>> sense belong in this routine.  I isolated this mapping to a single
>>>> function, right below here, that does that for a particular machine.
>>>> That's so you can pull it out later into a "machine specific" file
>>>> if you want to, or can improve it in some other way, without a lot
>>>> of trouble.
    extern unsigned sizes[8];	/* table filled in by build */
    extern int color, vec_table[], get_chrome(), (*task[])();
    extern int s_call(), disk_int(), tty_int(), clock_int(), disk_int();
***************
*** 117,124
    phys_copy(0L, phys_b, (long) VECTOR_BYTES);	/* save all the vectors */
  
    /* Set up the new interrupt vectors. */
!   for (t = 0; t < 16; t++) set_vec(t, surprise, base_click);
!   for (t = 16; t < 256; t++) set_vec(t, trp, base_click);
    set_vec(DIVIDE_VECTOR, divide, base_click);
    set_vec(SYS_VECTOR, s_call, base_click);
    set_vec(CLOCK_VECTOR, clock_int, base_click);

--- 119,150 -----
    phys_copy(0L, phys_b, (long) VECTOR_BYTES);	/* save all the vectors */
  
    /* Set up the new interrupt vectors. */
!   for (t = 0; t < 16; t++) 
!   {
! #ifdef GENERIC_FDISK
! 	/* JER - don't patch out hard disk vector */
! 	if (pc_at)
! 	{
! 		if (t==AT_WINI_VECTOR) continue;
! 	}
! 	else
! 	{
! 		if (t==XT_WINI_VECTOR) continue;
! 	}
! #endif
! 
! 	set_vec(t, surprise, base_click);
!   }
! 
!   for (t = 16; t < 256; t++) 
!   {
! #ifdef GENERIC_FDISK
! 	/* JER - don't patch out BIOS vectors */
! 	if (t==0x13 || (t>=0x40 && t<=0x5f)) continue;
! #endif
! 
! 	set_vec(t, trp, base_click);
!   }
    set_vec(DIVIDE_VECTOR, divide, base_click);
    set_vec(SYS_VECTOR, s_call, base_click);
    set_vec(CLOCK_VECTOR, clock_int, base_click);

>>>> This change bothers me a lot, but I decided it's because here in
>>>> the kernel initialization is some code that is setting "vectors".
>>>> This idea of "vectors" seems strange because I'm not sure yet what
>>>> "vectors" are in the context of Minix, at this point in time.
>>>> Intuitively I feel this is not quite right, but I may misunderstand
>>>> something that will become really obvious later, so I didn't do
>>>> anything radical I might later regret.

***************
*** 125,130
    set_vec(KEYBOARD_VECTOR, tty_int, base_click);
    set_vec(FLOPPY_VECTOR, disk_int, base_click);
    set_vec(PRINTER_VECTOR, lpr_int, base_click);
    if (pc_at)
  	  set_vec(AT_WINI_VECTOR, wini_int, base_click);
    else

--- 151,157 -----
    set_vec(KEYBOARD_VECTOR, tty_int, base_click);
    set_vec(FLOPPY_VECTOR, disk_int, base_click);
    set_vec(PRINTER_VECTOR, lpr_int, base_click);
+ #ifndef GENERIC_FDISK
    if (pc_at)
  	  set_vec(AT_WINI_VECTOR, wini_int, base_click);
    else
***************
*** 129,134
  	  set_vec(AT_WINI_VECTOR, wini_int, base_click);
    else
  	  set_vec(XT_WINI_VECTOR, wini_int, base_click);
  
    /* Put a ptr to proc table in a known place so it can be found in /dev/mem */
    set_vec( (BASE - 4)/4, proc, (phys_clicks) 0);

--- 156,162 -----
  	  set_vec(AT_WINI_VECTOR, wini_int, base_click);
    else
  	  set_vec(XT_WINI_VECTOR, wini_int, base_click);
+ #endif
  
    /* Put a ptr to proc table in a known place so it can be found in /dev/mem */
    set_vec( (BASE - 4)/4, proc, (phys_clicks) 0);

>>>> 4

***************
*** 133,138
    /* Put a ptr to proc table in a known place so it can be found in /dev/mem */
    set_vec( (BASE - 4)/4, proc, (phys_clicks) 0);
  
    bill_ptr = proc_addr(HARDWARE);	/* it has to point somewhere */
    pick_proc();
  

--- 161,179 -----
    /* Put a ptr to proc table in a known place so it can be found in /dev/mem */
    set_vec( (BASE - 4)/4, proc, (phys_clicks) 0);
  
+   /* 
+    * Get index of device to use as root, and put it where fs can find it.
+    * We put it into the 0th word of data_org in FS, at present, which
+    * contained the magic number for "build," but is unused at boot time.
+    * If necessary, it can be moved somewhere else in data_org by expanding
+    * the size of the (used) array. JER 7/29/87
+    */
+   root_idx = get_ridx();
+   pridx = umap(proc_addr(HARDWARE), D, (vir_bytes) &root_idx, sizeof(int));
+   pfs0 = umap(proc_addr(FS_PROC_NR), D, (vir_bytes)0, sizeof(int));
+   phys_copy(pridx, pfs0, (phys_bytes)sizeof(int));
+ 
+ 
    bill_ptr = proc_addr(HARDWARE);	/* it has to point somewhere */
    pick_proc();

>>>> I'm not sure this is the best way to do this, but calling a low
>>>> level routine called "stick_root_index_into_low_word_of_fs" isn't
>>>> it either, so I apologise if I used some really roundabout way to
>>>> do something simple... someone more familiar with Minix may suggest
>>>> a better alternative.
  }
  
  
  /*===========================================================================*
   *                                   unexpected_int                          * 

--- 183,191 -----
    restart();
  }
  
+ /*===========================================================================*
+  *                           get root device index - JER                     * 
+  *===========================================================================*/
  
  int get_ridx()
  {
***************
*** 143,148
  }
  
  
  /*===========================================================================*
   *                                   unexpected_int                          * 
   *===========================================================================*/

--- 187,220 -----
   *                           get root device index - JER                     * 
   *===========================================================================*/
  
+ int get_ridx()
+ {
+   int ridx;
+
+ #ifdef i8088
+   extern int scan_code; /* scan code of key user typed to start us */
+ 
+   switch (scan_code)
+   {
+   case 12:	/* user typed an '=' */
+   case 13:
+ 	ridx = 0;	/* root will be ram disk */
+ 	break;
+ 
+   default:	/* user typed a digit */
+ 	ridx = scan_code - 1;  /* root will be winchester disk */
+ 	break;
+   }
+ 
+ #else
+ 
+   ridx = 0;	/* non-8088: use ram disk */
+ 
+ #endif
+ 
+   return(ridx);
+ }

>>>> This is the function that maps scan codes, front panel switch positions,
>>>> or whatever input you can give to your boot code, into an identifier
>>>> of where to boot from (which again is free to be assigned to a particular
>>>> model of machine, which is why it's not a device number or drive ID here.)
>>>> This is not as clean as it could be; get_ridx gets "something" machine
>>>> specific that is used by some mapping function in fs that is also machine
>>>> specific to map the former into a device number.  It leaves things open
>>>> in two places for now.  This is a compromise, deferring deciding where
>>>> the single mapping (eliminating the abstract index), if any,
>>>> should go for the future.  That's because dmap is in fs, whereas
>>>> it's the kernel that gets the first call on boot, and in general contains
>>>> the parts of Minix that are closest to the hardware.  So I passed this
>>>> abstract number between them, where neither really knows what it means
>>>> to the other.  If you think about this at length, it may become obvious
>>>> why it's so, but it's kind of hard to explain here in a way that wouldn't
>>>> sound as confusing as the above.  This would be a good topic 
>>>> for comp.arch.

+ 
  /*===========================================================================*
   *                                   backtrace - JER                         * 
   *===========================================================================*/
***************
*** 144,149
  
  
  /*===========================================================================*
   *                                   unexpected_int                          * 
   *===========================================================================*/
  PUBLIC unexpected_int()

--- 216,253 -----
  }
  
  /*===========================================================================*
+  *                                   backtrace - JER                         * 
+  *===========================================================================*/
+ 
+ PRIVATE backtrace(w)
+ int w;
+ {
+ int i;
+ int *p;
+ 
+ #ifdef i8088
+   /* produce a stack backtrace showing the call chain */
+ 
+   p = &w;	/* first parameter */
+   p--;		/* return address  */
+   p--;		/* next bp	   */
+ 
+   printf("Stack backtrace: ");
+   for (i=0; i<6; i++)
+   {
+ 	printf("%04x ",p[1]);
+ 	p = (int *) *p;
+   }
+ 
+   printf("...\n");
+ 
+   /* really should only do this for kernel traps? */
+   printf("\nType space to reboot\n");
+   wreboot();
+ #endif
+ }

>>>> I put this backtrace code in back when Minix would not boot, only crash,
>>>> as soon as it was loaded from disk (this was while I was trying to get
>>>> it compiled with MSC).  I am not sure it works any more, so you may
>>>> want to just delete it; I left it in in case any more spurious crashes
>>>> occurred, so I could get some information.
+ 
+ /*===========================================================================*
   *                                   unexpected_int                          * 
   *===========================================================================*/
  PUBLIC unexpected_int()
***************
*** 153,158
    printf("Unexpected trap: vector < 16\n");
    printf("pc = 0x%x    text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc,
  					proc_ptr->p_map[D].mem_len<<4);
  }
  
  

--- 257,263 -----
    printf("Unexpected trap: vector < 16\n");
    printf("pc = 0x%x    text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc,
  					proc_ptr->p_map[D].mem_len<<4);
+   backtrace();
  }
  
  
***************
*** 168,173
    printf("a non-MINIX library routine that is trying to make a system call.\n");
    printf("pc = 0x%x    text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc,
  					proc_ptr->p_map[D].mem_len<<4);
  }
  
  

--- 273,279 -----
    printf("a non-MINIX library routine that is trying to make a system call.\n");
    printf("pc = 0x%x    text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc,
  					proc_ptr->p_map[D].mem_len<<4);
+   backtrace();
  }
  
  
***************
*** 181,186
    printf("Trap to vector 0: divide overflow.  ");
    printf("pc = 0x%x    text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc,
  					proc_ptr->p_map[D].mem_len<<4);
  }
  
  

--- 287,293 -----
    printf("Trap to vector 0: divide overflow.  ");
    printf("pc = 0x%x    text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc,
  					proc_ptr->p_map[D].mem_len<<4);
+   backtrace();
  }
  
  
***************
*** 202,207
  	if (n != NO_NUM) printf(" %d", n);
  	printf("\n");
    }
    printf("\nType space to reboot\n");
    wreboot();
  

--- 309,315 -----
  	if (n != NO_NUM) printf(" %d", n);
  	printf("\n");
    }
+   backtrace();
    printf("\nType space to reboot\n");
    wreboot();
  
------------------------------------------------------------
*** mpx88.asm	Sat Aug  1 13:37:11 1987
--- ../../dos/kernel/mpx88.asm	Sat Aug  1 13:31:24 1987
***************
*** 32,37
  CLOCK		EQU -3
  CLOCK_TICK	EQU  2
  FLOPPY		EQU -5
  
  
  ; The following	procedures are defined in this file and	called from outside it.

--- 32,38 -----
  CLOCK		EQU -3
  CLOCK_TICK	EQU  2
  FLOPPY		EQU -5
+ WINI		EQU	-6
  
  ; The following keeps MSC's refs to this symbol from pulling in crtso.obj
  PUBLIC		__acrtused
***************
*** 33,38
  CLOCK_TICK	EQU  2
  FLOPPY		EQU -5
  
  
  ; The following	procedures are defined in this file and	called from outside it.
  PUBLIC $main, tty_int, lpr_int,	clock_in, disk_int

--- 34,42 -----
  FLOPPY		EQU -5
  WINI		EQU	-6
  
+ ; The following keeps MSC's refs to this symbol from pulling in crtso.obj
+ PUBLIC		__acrtused
+ __acrtused	EQU	9876H
  
  ; The following	procedures are defined in this file and	called from outside it.
  PUBLIC $main, _tty_int, _lpr_int,	_clock_int, _disk_int, _wini_int
***************
*** 35,42
  
  
  ; The following	procedures are defined in this file and	called from outside it.
! PUBLIC $main, tty_int, lpr_int,	clock_in, disk_int
! PUBLIC s_call, surprise, trp, divide, restart
  
  
  ; The following	external procedures are	called in this file.

--- 39,46 -----
  __acrtused	EQU	9876H
  
  ; The following	procedures are defined in this file and	called from outside it.
! PUBLIC $main, _tty_int, _lpr_int,	_clock_int, _disk_int, _wini_int
! PUBLIC _s_call, _surprise, _trp, _divide, _restart
  
  
  ; The following	external procedures are	called in this file.
***************
*** 40,47
  
  
  ; The following	external procedures are	called in this file.
! EXTRN main:NEAR,  sys_call:NEAR, interrup:NEAR,	keyboard:NEAR
! EXTRN panic:NEAR, unexpect:NEAR, trap:NEAR, div_trap:NEAR, pr_char:NEAR
  
  
  ; Variables and	data structures.

--- 44,52 -----
  
  
  ; The following	external procedures are	called in this file.
! EXTRN _main:NEAR,  _sys_call:NEAR, _intr:NEAR,	_keyboard:NEAR
! EXTRN _panic:NEAR, _unexpected_int:NEAR, _trap:NEAR, _div_trap:NEAR, 
! EXTRN _pr_char:NEAR
  
  ; Variables and	data structures.
  PUBLIC _sizes, _brksize, _splimit, _end
***************
*** 43,49
  EXTRN main:NEAR,  sys_call:NEAR, interrup:NEAR,	keyboard:NEAR
  EXTRN panic:NEAR, unexpect:NEAR, trap:NEAR, div_trap:NEAR, pr_char:NEAR
  
- 
  ; Variables and	data structures.
  PUBLIC sizes, brksize, splimit,	@end
  EXTRN  cur_proc:WORD, proc_ptr:WORD, int_mess:WORD

--- 48,53 -----
  EXTRN _panic:NEAR, _unexpected_int:NEAR, _trap:NEAR, _div_trap:NEAR, 
  EXTRN _pr_char:NEAR
  
  ; Variables and	data structures.
  PUBLIC _sizes, _brksize, _splimit, _end
  EXTRN  _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD
***************
*** 45,53
  
  
  ; Variables and	data structures.
! PUBLIC sizes, brksize, splimit,	@end
! EXTRN  cur_proc:WORD, proc_ptr:WORD, int_mess:WORD
! EXTRN  scan_cod:WORD, k_stack:WORD
  
  
  ; The following	constants are offsets into the proc table.

--- 49,57 -----
  EXTRN _pr_char:NEAR
  
  ; Variables and	data structures.
! PUBLIC _sizes, _brksize, _splimit, _end
! EXTRN  _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD
! EXTRN  _scan_code:WORD, _k_stack:WORD
  
  ; The following	constants are offsets into the proc table.
  esreg =	14
***************
*** 49,55
  EXTRN  cur_proc:WORD, proc_ptr:WORD, int_mess:WORD
  EXTRN  scan_cod:WORD, k_stack:WORD
  
- 
  ; The following	constants are offsets into the proc table.
  esreg =	14
  dsreg =	16

--- 53,58 -----
  EXTRN  _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD
  EXTRN  _scan_code:WORD, _k_stack:WORD
  
  ; The following	constants are offsets into the proc table.
  esreg =	14
  dsreg =	16
***************
*** 65,70
  
  INCLUDE	..\lib\prologue.h
  
  
  @CODE	SEGMENT
  	assume	cs:@code,ds:dgroup

--- 68,76 -----
  
  INCLUDE	..\lib\prologue.h
  
+ ;===========================================================================
+ ;				data - JER moved here from before stack
+ ;===========================================================================
  
  _DATAB	SEGMENT			; datab	ensures	it is the beginning of all data

>>>> I moved datab here to eliminate forward references to it, because back
>>>> before Minix would even crash, it would just hang, and it looked like
>>>> there was a bad pointer, and my guess was that MSC was having trouble
>>>> with the forward references, because I know some 8086 assemblers have
>>>> trouble with that.  That wasn't it, but I still feel better when
>>>> forward references are minimized.  I don't know if it matters here.
>>>> (At that time, all I had was a routine that would dump the ax onto the
>>>> screen directly, so it was all intuitive guessing at that point: the
>>>> display hadn't even been initialized by Minix yet.  Hence the seemingly
>>>> illogical change.)
  
***************
*** 66,73
  INCLUDE	..\lib\prologue.h
  
  
! @CODE	SEGMENT
! 	assume	cs:@code,ds:dgroup
  
  ;===========================================================================
  ;				Minix

--- 72,78 -----
  ;				data - JER moved here from before stack
  ;===========================================================================
  
! _DATAB	SEGMENT			; datab	ensures	it is the beginning of all data
  
  _sizes	 DW	526Fh		; this must be the first data entry (magic nr)
  	 DW	7 dup(0)	; space	for build table	- total	16b
***************
*** 69,74
  @CODE	SEGMENT
  	assume	cs:@code,ds:dgroup
  
  ;===========================================================================
  ;				Minix
  ;===========================================================================

--- 74,98 -----
  
  _DATAB	SEGMENT			; datab	ensures	it is the beginning of all data
  
+ _sizes	 DW	526Fh		; this must be the first data entry (magic nr)
+ 	 DW	7 dup(0)	; space	for build table	- total	16b
+ _splimit	 DW	0		; stack	limit for current task (kernel only)
+ _bx_save	 DW	0		; storage for bx
+ _ds_save	 DW	0		; storage for ds
+ _ret_save DW	0		; storage for return address
+ _lds_low	 DW	0,0		; storage used for restoring ds:bx
+ _brksize	 DW	offset dgroup:_END+2	; first	free memory in kernel
+ _ttyomess DB	"RS232 interrupt",0
+ _DATAB	ENDS
+ 
+ 
+ _DATAV	SEGMENT			; DATAV	holds nothing.
+ _end	label	byte	; the segment just tells us where
+ _DATAV	ENDS			; the data+bss ends.
+ 
+ 
+ _TEXT	SEGMENT
+ 
  ;===========================================================================
  ;				Minix
  ;===========================================================================
***************
*** 78,84
  	ORG 4			; build	writes the ds value at text address 4
  ker_ds	DW  dgroup		; this word will contain kernel's ds value
  				; and it forces	relocation for dos2out
!      M0:cli			; disable interrupts
  	mov ax,cs		; set up segment registers
  	mov ds,ax		; set up ds
  	mov ax,cs:ker_ds	; build	has loaded this	word with ds value

--- 102,109 -----
  	ORG 4			; build	writes the ds value at text address 4
  ker_ds	DW  dgroup		; this word will contain kernel's ds value
  				; and it forces	relocation for dos2out
! M0:
!  	cli			; disable interrupts
  	mov ax,cs		; set up segment registers
  	mov ds,ax		; set up ds
  	mov ax,ker_ds	; build	has loaded this	word with ds value
***************
*** 81,87
       M0:cli			; disable interrupts
  	mov ax,cs		; set up segment registers
  	mov ds,ax		; set up ds
! 	mov ax,cs:ker_ds	; build	has loaded this	word with ds value
  	mov ds,ax		; ds now contains proper value
  	mov ss,ax		; ss now contains proper value
  	mov dgroup:scan_cod,bx		; save scan code for '=' key from bootstrap

--- 106,112 -----
   	cli			; disable interrupts
  	mov ax,cs		; set up segment registers
  	mov ds,ax		; set up ds
! 	mov ax,ker_ds	; build	has loaded this	word with ds value
  	mov ds,ax		; ds now contains proper value
  	mov ss,ax		; ss now contains proper value
  	mov	es,ax		; JER - set es too

>>>> I didn't see why the cs: override was on here, since ds=cs at this
>>>> point, so I took it out during the early debugging.

***************
*** 84,91
  	mov ax,cs:ker_ds	; build	has loaded this	word with ds value
  	mov ds,ax		; ds now contains proper value
  	mov ss,ax		; ss now contains proper value
! 	mov dgroup:scan_cod,bx		; save scan code for '=' key from bootstrap
! 	mov sp,offset dgroup:k_stack	; set sp to point to the top of	the
  	add sp,K_STACK_BYTES		; kernel stack
  	call main		; start	the main program of Minix
  

--- 109,122 -----
  	mov ax,ker_ds	; build	has loaded this	word with ds value
  	mov ds,ax		; ds now contains proper value
  	mov ss,ax		; ss now contains proper value
! 	mov	es,ax		; JER - set es too
! 
! 	ifdef	debug
! 	call	prtax
! 	endif
! 
! 	mov dgroup:_scan_code,bx		; save scan code for '=' key from bootstrap
! 	mov sp,offset dgroup:_k_stack	; set sp to point to the top of	the
  	add sp,K_STACK_BYTES		; kernel stack
  	wto	'Kernel EP: stack now set up'
  	call _main		; start	the main program of Minix

>>>> This was another guess that turned out invalid, I *think*.... I don't
>>>> think MSC uses the es, but it looked like a possibility... you can
>>>> see some vestigal debug code up there; wto is a macro in prologue.h
>>>> that doesn't generate anything.

***************
*** 87,93
  	mov dgroup:scan_cod,bx		; save scan code for '=' key from bootstrap
  	mov sp,offset dgroup:k_stack	; set sp to point to the top of	the
  	add sp,K_STACK_BYTES		; kernel stack
! 	call main		; start	the main program of Minix
  
       M1:jmp M1			; this should never be executed
  

--- 118,126 -----
  	mov dgroup:_scan_code,bx		; save scan code for '=' key from bootstrap
  	mov sp,offset dgroup:_k_stack	; set sp to point to the top of	the
  	add sp,K_STACK_BYTES		; kernel stack
! 	wto	'Kernel EP: stack now set up'
! 	call _main		; start	the main program of Minix
! 	wto	'Fatal: kernel _main returned'
  
       M1:jmp M1			; this should never be executed

>>>> wto is a macro in prologue.h which is currently defined to do nothing.
>>>> for awhile it wrote strings to the display.
  
***************
*** 95,103
  ;===========================================================================
  ;				s_call
  ;===========================================================================
! s_call:				; System calls are vectored here.
! 	call save		; save the machine state
! 	mov bp,dgroup:proc_ptr	; use bp to access sys call parameters
  	push 2[bp]		; push(pointer to user message)	(was bx)
  	push [bp]		; push(src/dest) (was ax)
  	push dgroup:cur_proc	; push caller

--- 128,136 -----
  ;===========================================================================
  ;				s_call
  ;===========================================================================
! _s_call:				; System calls are vectored here.
! 	call _save		; save the machine state
! 	mov bp,dgroup:_proc_ptr	; use bp to access sys call parameters
  	push 2[bp]		; push(pointer to user message)	(was bx)
  	push [bp]		; push(src/dest) (was ax)
  	push dgroup:_cur_proc	; push caller
***************
*** 100,106
  	mov bp,dgroup:proc_ptr	; use bp to access sys call parameters
  	push 2[bp]		; push(pointer to user message)	(was bx)
  	push [bp]		; push(src/dest) (was ax)
! 	push dgroup:cur_proc	; push caller
  	push 4[bp]		; push(SEND/RECEIVE/BOTH) (was cx)
  	call sys_call		; sys_call(function, caller, src_dest, m_ptr)
  	jmp restart		; jump to code to restart proc/task running

--- 133,139 -----
  	mov bp,dgroup:_proc_ptr	; use bp to access sys call parameters
  	push 2[bp]		; push(pointer to user message)	(was bx)
  	push [bp]		; push(src/dest) (was ax)
! 	push dgroup:_cur_proc	; push caller
  	push 4[bp]		; push(SEND/RECEIVE/BOTH) (was cx)
  	call _sys_call		; sys_call(function, caller, src_dest, m_ptr)
  	jmp _restart		; jump to code to restart proc/task running
***************
*** 102,109
  	push [bp]		; push(src/dest) (was ax)
  	push dgroup:cur_proc	; push caller
  	push 4[bp]		; push(SEND/RECEIVE/BOTH) (was cx)
! 	call sys_call		; sys_call(function, caller, src_dest, m_ptr)
! 	jmp restart		; jump to code to restart proc/task running
  
  
  ;===========================================================================

--- 135,142 -----
  	push [bp]		; push(src/dest) (was ax)
  	push dgroup:_cur_proc	; push caller
  	push 4[bp]		; push(SEND/RECEIVE/BOTH) (was cx)
! 	call _sys_call		; sys_call(function, caller, src_dest, m_ptr)
! 	jmp _restart		; jump to code to restart proc/task running
  
  
  ;===========================================================================
***************
*** 109,118
  ;===========================================================================
  ;				tty_int
  ;===========================================================================
! tty_int:			; Interrupt routine for	terminal input.
! 	call save		; save the machine state
! 	call keyboard		; process a keyboard interrupt
! 	jmp  restart		; continue execution
  
  
  ;===========================================================================

--- 142,151 -----
  ;===========================================================================
  ;				tty_int
  ;===========================================================================
! _tty_int:			; Interrupt routine for	terminal input.
! 	call _save		; save the machine state
! 	call _keyboard		; process a keyboard interrupt
! 	jmp  _restart		; continue execution
  
  
  ;===========================================================================
***************
*** 118,127
  ;===========================================================================
  ;				lpr_int
  ;===========================================================================
! lpr_int:			; Interrupt routine for	terminal input.
! 	call save		; save the machine state
! 	call pr_char		; process a line printer interrupt
! 	jmp  restart		; continue execution
  
  
  ;===========================================================================

--- 151,160 -----
  ;===========================================================================
  ;				lpr_int
  ;===========================================================================
! _lpr_int:			; Interrupt routine for	terminal input.
! 	call _save		; save the machine state
! 	call _pr_char		; process a line printer interrupt
! 	jmp  _restart		; continue execution
  
  
  ;===========================================================================
***************
*** 127,136
  ;===========================================================================
  ;				disk_int
  ;===========================================================================
! disk_int:			; Interrupt routine for	the floppy disk.
! 	call save			; save the machine state
! 	mov  dgroup:int_mess+2,DISKINT	; build	message	for disk task
! 	mov  ax,offset dgroup:int_mess	; prepare to call interrupt[FLOPPY, &intmess]
  	push ax				; push second parameter
  	mov  ax,FLOPPY		; prepare to push first	parameter
  	push ax			; push first parameter

--- 160,169 -----
  ;===========================================================================
  ;				disk_int
  ;===========================================================================
! _disk_int:			; Interrupt routine for	the floppy disk.
! 	call _save			; save the machine state
! 	mov  dgroup:_int_mess+2,DISKINT	; build	message	for disk task
! 	mov  ax,offset dgroup:_int_mess	; prepare to call interrupt[FLOPPY, &intmess]
  	push ax				; push second parameter
  	mov  ax,FLOPPY		; prepare to push first	parameter
  	push ax			; push first parameter
***************
*** 134,141
  	push ax				; push second parameter
  	mov  ax,FLOPPY		; prepare to push first	parameter
  	push ax			; push first parameter
! 	call interrup		; this is the call
! 	jmp  restart		; continue execution
  
  
  ;===========================================================================

--- 167,174 -----
  	push ax				; push second parameter
  	mov  ax,FLOPPY		; prepare to push first	parameter
  	push ax			; push first parameter
! 	call _intr		; this is the call
! 	jmp  _restart		; continue execution
  
  
  ;*===========================================================================*
***************
*** 138,143
  	jmp  restart		; continue execution
  
  
  ;===========================================================================
  ;				clock_int
  ;===========================================================================

--- 171,190 -----
  	jmp  _restart		; continue execution
  
  
+ ;*===========================================================================*
+ ;*				wini_int				     *
+ ;*===========================================================================*
+ _wini_int:			; Interrupt routine for the winchester disk.
+ 	call _save		; save the machine state
+ 	mov dgroup:_int_mess+2,DISKINT; build message for winchester task
+ 	mov ax,offset dgroup:_int_mess	; prepare to call interrupt(WINI, &intmess)
+ 	push ax			; push second parameter
+ 	mov ax,WINI		; prepare to push first parameter
+ 	push ax			; push first parameter
+ 	call _intr		; this is the call
+ 	jmp _restart		; continue execution
+ 
+ 

>>>> This is not used in the generic driver, so it has never been tested in
>>>> this version of the code... it was missing from the C86 sources.

  ;===========================================================================
  ;				clock_int
  ;===========================================================================
***************
*** 141,150
  ;===========================================================================
  ;				clock_int
  ;===========================================================================
! clock_in:			; Interrupt routine for	the clock.
! 	call save			; save the machine state
! 	mov dgroup:int_mess+2,CLOCK_TICK; build	message	for clock task
! 	mov ax,offset dgroup:int_mess	; prepare to call interrupt(CLOCK,&intmess)
  	push ax				; push second parameter
  	mov  ax,CLOCK		; prepare to push first	parameter
  	push ax			; push first parameter

--- 188,197 -----
  ;===========================================================================
  ;				clock_int
  ;===========================================================================
! _clock_int:			; Interrupt routine for	the clock.
! 	call _save			; save the machine state
! 	mov dgroup:_int_mess+2,CLOCK_TICK; build	message	for clock task
! 	mov ax,offset dgroup:_int_mess	; prepare to call interrupt(CLOCK,&intmess)
  	push ax				; push second parameter
  	mov  ax,CLOCK		; prepare to push first	parameter
  	push ax			; push first parameter
***************
*** 148,155
  	push ax				; push second parameter
  	mov  ax,CLOCK		; prepare to push first	parameter
  	push ax			; push first parameter
! 	call interrup		; this is the call
! 	jmp  restart		; continue execution
  
  
  ;===========================================================================

--- 195,202 -----
  	push ax				; push second parameter
  	mov  ax,CLOCK		; prepare to push first	parameter
  	push ax			; push first parameter
! 	call _intr		; this is the call
! 	jmp  _restart		; continue execution
  
  
  ;===========================================================================
***************
*** 155,164
  ;===========================================================================
  ;				surprise
  ;===========================================================================
! surprise:			; This is where	unexpected interrupts come.
! 	call save		; save the machine state
! 	call unexpect		; go panic
! 	jmp  restart		; never	executed
  
  
  ;===========================================================================

--- 202,211 -----
  ;===========================================================================
  ;				surprise
  ;===========================================================================
! _surprise:			; This is where	unexpected interrupts come.
! 	call _save		; save the machine state
! 	call _unexpected_int		; go panic
! 	jmp  _restart		; never	executed
  
  
  ;===========================================================================
***************
*** 164,173
  ;===========================================================================
  ;				trp
  ;===========================================================================
! trp:				; This is where	unexpected traps come.
! 	call save		; save the machine state
! 	call trap		; print	a message
! 	jmp restart		; this error is	not fatal
  
  
  ;===========================================================================

--- 211,220 -----
  ;===========================================================================
  ;				trp
  ;===========================================================================
! _trp:				; This is where	unexpected traps come.
! 	call _save		; save the machine state
! 	call _trap		; print	a message
! 	jmp _restart		; this error is	not fatal
  
  
  ;===========================================================================
***************
*** 173,182
  ;===========================================================================
  ;				divide					     
  ;===========================================================================
! divide:				; This is where divide overflow traps come.
! 	call save		; save the machine state
! 	call div_trap		; print a message
! 	jmp restart		; this error is not fatal
  
  
  ;===========================================================================

--- 220,229 -----
  ;===========================================================================
  ;				divide					     
  ;===========================================================================
! _divide:				; This is where divide overflow traps come.
! 	call _save		; save the machine state
! 	call _div_trap		; print a message
! 	jmp _restart		; this error is not fatal
  
  
  ;===========================================================================
***************
*** 182,188
  ;===========================================================================
  ;				save
  ;===========================================================================
! save:				; save the machine state in the	proc table.
  	push ds			; stack: psw/cs/pc/ret addr/ds
  	push cs			; prepare to restore ds
  	pop ds			; ds has now been set to cs

--- 229,235 -----
  ;===========================================================================
  ;				save
  ;===========================================================================
! _save:				; save the machine state in the	proc table.
  	push ds			; stack: psw/cs/pc/ret addr/ds
  	push cs			; prepare to restore ds
  	pop ds			; ds has now been set to cs
***************
*** 187,196
  	push cs			; prepare to restore ds
  	pop ds			; ds has now been set to cs
  	mov ds,ker_ds		; word 4 in kernel text	space contains ds value
! 	pop ds_save		; stack: psw/cs/pc/ret addr
! 	pop ret_save		; stack: psw/cs/pc
! 	mov bx_save,bx		; save bx for later ; we need a	free register
! 	mov bx,dgroup:proc_ptr	; start	save set up; make bx point to save area
  	add bx,OFF		; bx points to place to	store cs
  	pop PC-OFF[bx]		; store	pc in proc table
  	pop csreg-OFF[bx]	; store	cs in proc table

--- 234,243 -----
  	push cs			; prepare to restore ds
  	pop ds			; ds has now been set to cs
  	mov ds,ker_ds		; word 4 in kernel text	space contains ds value
! 	pop dgroup:_ds_save		; stack: psw/cs/pc/ret addr
! 	pop dgroup:_ret_save		; stack: psw/cs/pc
! 	mov dgroup:_bx_save,bx		; save bx for later ; we need a	free register
! 	mov bx,dgroup:_proc_ptr	; start	save set up; make bx point to save area
  	add bx,OFF		; bx points to place to	store cs
  	pop PC-OFF[bx]		; store	pc in proc table
  	pop csreg-OFF[bx]	; store	cs in proc table
***************
*** 200,206
  	mov sp,bx		; now use sp to	point into proc	table/task save
  	mov bx,ds		; about	to set ss
  	mov ss,bx		; set ss
! 	push ds_save		; start	saving all the registers, sp first
  	push es			; save es between sp and bp
  	mov es,bx		; es now references kernel memory too
  	push bp			; save bp

--- 247,253 -----
  	mov sp,bx		; now use sp to	point into proc	table/task save
  	mov bx,ds		; about	to set ss
  	mov ss,bx		; set ss
! 	push dgroup:_ds_save		; start	saving all the registers, sp first
  	push es			; save es between sp and bp
  	mov es,bx		; es now references kernel memory too
  	push bp			; save bp
***************
*** 208,214
  	push si			; save si
  	push dx			; save dx
  	push cx			; save cx
! 	push bx_save		; save original	bx
  	push ax				    ; all registers now	saved
  	mov sp,offset dgroup:k_stack	    ; temporary	stack for interrupts
  	add sp,K_STACK_BYTES		    ; set sp to	top of temporary stack

--- 255,261 -----
  	push si			; save si
  	push dx			; save dx
  	push cx			; save cx
! 	push dgroup:_bx_save		; save original	bx
  	push ax				    ; all registers now	saved
  	mov sp,offset dgroup:_k_stack	    ; temporary	stack for interrupts
  	add sp,K_STACK_BYTES		    ; set sp to	top of temporary stack
***************
*** 210,216
  	push cx			; save cx
  	push bx_save		; save original	bx
  	push ax				    ; all registers now	saved
! 	mov sp,offset dgroup:k_stack	    ; temporary	stack for interrupts
  	add sp,K_STACK_BYTES		    ; set sp to	top of temporary stack
  	mov splimit,offset dgroup:k_stack   ; limit for	temporary stack
  	add splimit,8			    ; splimit checks for stack overflow

--- 257,263 -----
  	push cx			; save cx
  	push dgroup:_bx_save		; save original	bx
  	push ax				    ; all registers now	saved
! 	mov sp,offset dgroup:_k_stack	    ; temporary	stack for interrupts
  	add sp,K_STACK_BYTES		    ; set sp to	top of temporary stack
  	mov dgroup:_splimit,offset dgroup:_k_stack   ; limit for	temporary stack
  	add dgroup:_splimit,8			    ; splimit checks for stack overflow
***************
*** 212,220
  	push ax				    ; all registers now	saved
  	mov sp,offset dgroup:k_stack	    ; temporary	stack for interrupts
  	add sp,K_STACK_BYTES		    ; set sp to	top of temporary stack
! 	mov splimit,offset dgroup:k_stack   ; limit for	temporary stack
! 	add splimit,8			    ; splimit checks for stack overflow
! 	mov ax,ret_save		; ax = address to return to
  	jmp ax			; return to caller; Note: sp points to saved ax
  
  

--- 259,267 -----
  	push ax				    ; all registers now	saved
  	mov sp,offset dgroup:_k_stack	    ; temporary	stack for interrupts
  	add sp,K_STACK_BYTES		    ; set sp to	top of temporary stack
! 	mov dgroup:_splimit,offset dgroup:_k_stack   ; limit for	temporary stack
! 	add dgroup:_splimit,8			    ; splimit checks for stack overflow
! 	mov ax,dgroup:_ret_save		; ax = address to return to
  	jmp ax			; return to caller; Note: sp points to saved ax
  
  
***************
*** 221,228
  ;===========================================================================
  ;				restart
  ;===========================================================================
! restart:			; This routine sets up and runs	a proc or task.
! 	cmp dgroup:cur_proc,IDLE; restart user; if cur_proc = IDLE, go	idle
  	je _idle		; no user is runnable, jump to idle routine
  	cli			; disable interrupts
  	mov sp,dgroup:proc_ptr	; return to user, fetch	regs from proc table

--- 268,275 -----
  ;===========================================================================
  ;				restart
  ;===========================================================================
! _restart:			; This routine sets up and runs	a proc or task.
! 	cmp dgroup:_cur_proc,IDLE; restart user; if cur_proc = IDLE, go	idle
  	je _idle		; no user is runnable, jump to idle routine
  	cli			; disable interrupts
  	mov sp,dgroup:_proc_ptr	; return to user, fetch	regs from proc table
***************
*** 225,231
  	cmp dgroup:cur_proc,IDLE; restart user; if cur_proc = IDLE, go	idle
  	je _idle		; no user is runnable, jump to idle routine
  	cli			; disable interrupts
! 	mov sp,dgroup:proc_ptr	; return to user, fetch	regs from proc table
  	pop ax			; start	restoring registers
  	pop bx			; restore bx
  	pop cx			; restore cx

--- 272,278 -----
  	cmp dgroup:_cur_proc,IDLE; restart user; if cur_proc = IDLE, go	idle
  	je _idle		; no user is runnable, jump to idle routine
  	cli			; disable interrupts
! 	mov sp,dgroup:_proc_ptr	; return to user, fetch	regs from proc table
  	pop ax			; start	restoring registers
  	pop bx			; restore bx
  	pop cx			; restore cx
***************
*** 232,238
  	pop dx			; restore dx
  	pop si			; restore si
  	pop di			; restore di
! 	mov lds_low,bx		; lds_low contains bx
  	mov bx,sp		; bx points to saved bp	register
  	mov bp,SPLIM-ROFF[bx]	; splimit = p_splimit
  	mov splimit,bp		; ditto

--- 279,285 -----
  	pop dx			; restore dx
  	pop si			; restore si
  	pop di			; restore di
! 	mov dgroup:_lds_low,bx		; lds_low contains bx
  	mov bx,sp		; bx points to saved bp	register
  	mov bp,SPLIM-ROFF[bx]	; splimit = p_splimit
  	mov dgroup:_splimit,bp		; ditto
***************
*** 235,241
  	mov lds_low,bx		; lds_low contains bx
  	mov bx,sp		; bx points to saved bp	register
  	mov bp,SPLIM-ROFF[bx]	; splimit = p_splimit
! 	mov splimit,bp		; ditto
  	mov bp,dsreg-ROFF[bx]	; bp = ds
  	mov lds_low+2,bp	; lds_low+2 contains ds
  	pop bp			; restore bp

--- 282,288 -----
  	mov dgroup:_lds_low,bx		; lds_low contains bx
  	mov bx,sp		; bx points to saved bp	register
  	mov bp,SPLIM-ROFF[bx]	; splimit = p_splimit
! 	mov dgroup:_splimit,bp		; ditto
  	mov bp,dsreg-ROFF[bx]	; bp = ds
  	mov dgroup:_lds_low+2,bp	; lds_low+2 contains ds
  	pop bp			; restore bp
***************
*** 237,243
  	mov bp,SPLIM-ROFF[bx]	; splimit = p_splimit
  	mov splimit,bp		; ditto
  	mov bp,dsreg-ROFF[bx]	; bp = ds
! 	mov lds_low+2,bp	; lds_low+2 contains ds
  	pop bp			; restore bp
  	pop es			; restore es
  	mov sp,spreg-ROFF[bx]	; restore sp

--- 284,290 -----
  	mov bp,SPLIM-ROFF[bx]	; splimit = p_splimit
  	mov dgroup:_splimit,bp		; ditto
  	mov bp,dsreg-ROFF[bx]	; bp = ds
! 	mov dgroup:_lds_low+2,bp	; lds_low+2 contains ds
  	pop bp			; restore bp
  	pop es			; restore es
  	mov sp,spreg-ROFF[bx]	; restore sp
***************
*** 245,251
  	push PSW-ROFF[bx]	; push psw (flags)
  	push csreg-ROFF[bx]	; push cs
  	push PC-ROFF[bx]	; push pc
! 	lds  bx,DWORD PTR lds_low   ; restore ds and bx	in one fell swoop
  	iret			; return to user or task
  
  ;===========================================================================

--- 292,298 -----
  	push PSW-ROFF[bx]	; push psw (flags)
  	push csreg-ROFF[bx]	; push cs
  	push PC-ROFF[bx]	; push pc
! 	lds  bx,DWORD PTR dgroup:_lds_low   ; restore ds and bx	in one fell swoop
  	iret			; return to user or task
  
  ;===========================================================================
***************
*** 256,261
  L3:	wait			; just idle while waiting for interrupt
  	jmp L3			; loop until interrupt
  
  
  @CODE	ENDS
  

--- 303,311 -----
  L3:	wait			; just idle while waiting for interrupt
  	jmp L3			; loop until interrupt
  
+ ;===========================================================================
+ ;				print - JER - print a debug message
+ ;===========================================================================
  
  	ifdef debug
  
***************
*** 257,263
  	jmp L3			; loop until interrupt
  
  
! @CODE	ENDS
  
  
  ;===========================================================================

--- 307,313 -----
  ;				print - JER - print a debug message
  ;===========================================================================
  
! 	ifdef debug
  
  print	proc                    ; print string (bx), ax destroyed
          mov     al,[bx]         ; al contains char to be printed
***************
*** 259,264
  
  @CODE	ENDS
  
  
  ;===========================================================================
  ;				data

--- 309,328 -----
  
  	ifdef debug
  
+ print	proc                    ; print string (bx), ax destroyed
+         mov     al,[bx]         ; al contains char to be printed
+         test    al,al           ; null char?
+         jne     prt1            ; no
+         ret                     ; else return
+ prt1:   mov     ah,14           ; 14 = print char
+         inc     bx              ; increment string pointer
+         push    bx              ; save bx
+         mov     bl,1            ; foreground color
+ 	xor	bh,bh		; page 0
+         int     10h             ; call BIOS VIDEO_IO
+         pop     bx              ; restore bx
+         jmp     print           ; next character
+ print	endp

>>>> the above may not work any more, it was for back when Minix hadn't
>>>> been initialized yet.  It's ifdef'ed out, now; I just left it in
>>>> in case I needed it in the future.  You can leave it out.
  
  ;
  ; prtnum - print low-order 4 bits of al register in hex
***************
*** 260,268
  @CODE	ENDS
  
  
! ;===========================================================================
! ;				data
! ;===========================================================================
  
  @DATAB	SEGMENT			; datab	ensures	it is the beginning of all data
  sizes	 DW	526Fh		; this must be the first data entry (magic nr)

--- 324,332 -----
          jmp     print           ; next character
  print	endp
  
! ;
! ; prtnum - print low-order 4 bits of al register in hex
! ;
  
  prtnum	proc	near
  	push	ds
***************
*** 264,280
  ;				data
  ;===========================================================================
  
! @DATAB	SEGMENT			; datab	ensures	it is the beginning of all data
! sizes	 DW	526Fh		; this must be the first data entry (magic nr)
! 	 DW	7 dup(0)	; space	for build table	- total	16b
! splimit	 DW	0		; stack	limit for current task (kernel only)
! bx_save	 DW	0		; storage for bx
! ds_save	 DW	0		; storage for ds
! ret_save DW	0		; storage for return address
! lds_low	 DW	0,0		; storage used for restoring ds:bx
! brksize	 DW	offset dgroup:@END+2	; first	free memory in kernel
! ttyomess DB	"RS232 interrupt",0
! @DATAB	ENDS
  
  
  @DATAV	SEGMENT			; DATAV	holds nothing. The label in

--- 328,346 -----
  ; prtnum - print low-order 4 bits of al register in hex
  ;
  
! prtnum	proc	near
! 	push	ds
! 	push	cs
! 	pop	ds
! 	push	bx
! 	mov	bx,offset xltab
! 	xlatb
! 	mov	ah,14
! 	mov	bh,10
! 	int	10H
! 	pop	bx
! 	pop	ds
! 	ret
  
  xltab	db	'0123456789ABCDEF '
  prtnum	endp
***************
*** 276,281
  ttyomess DB	"RS232 interrupt",0
  @DATAB	ENDS
  
  
  @DATAV	SEGMENT			; DATAV	holds nothing. The label in
  @end	label	byte		; the segment just tells us where

--- 342,349 -----
  	pop	ds
  	ret
  
+ xltab	db	'0123456789ABCDEF '
+ prtnum	endp
  
  ;
  ; prtax - print ax register's contents in hex
***************
*** 277,285
  @DATAB	ENDS
  
  
! @DATAV	SEGMENT			; DATAV	holds nothing. The label in
! @end	label	byte		; the segment just tells us where
! @DATAV	ENDS			; the data+bss ends.
  
  @STACK	SEGMENT	BYTE STACK 'STACK'	; Satisfy DOS-linker (dummy stack)
  @STACK	ENDS

--- 345,353 -----
  xltab	db	'0123456789ABCDEF '
  prtnum	endp
  
! ;
! ; prtax - print ax register's contents in hex
! ;
  
  prtax	proc	near
  	push	cx
***************
*** 281,287
  @end	label	byte		; the segment just tells us where
  @DATAV	ENDS			; the data+bss ends.
  
! @STACK	SEGMENT	BYTE STACK 'STACK'	; Satisfy DOS-linker (dummy stack)
  @STACK	ENDS
  
  	END	; end of assembly-file

--- 349,390 -----
  ; prtax - print ax register's contents in hex
  ;
  
! prtax	proc	near
! 	push	cx
! 	push	ax
! 	mov	al,ah
! 	mov	cl,4
! 	shr	al,cl
! 	call	prtnum
! 	pop	ax
! 	push	ax
! 	mov	al,ah
! 	and	al,0fH
! 	call	prtnum
! 	pop	ax
! 	push	ax
! 	mov	cl,4
! 	shr	al,cl
! 	call	prtnum
! 	pop	ax
! 	push	ax
! 	and	al,0fH
! 	call	prtnum
! 	mov	al,10H		; special value to print a space
! 	call	prtnum
! 	pop	ax
! 	pop	cx
! 	ret
! 
! prtax	endp
! 
! 	endif
!     
! 
! 
! _TEXT	ENDS
! 
! @STACK	SEGMENT	PARA STACK 'STACK'	; Satisfy DOS-linker (dummy stack)
  @STACK	ENDS
  
  	END	; end of assembly-file
------------------------------------------------------------
*** printer.c	Sat Aug  1 13:37:15 1987
--- ../../dos/kernel/printer.c	Sat Aug  1 13:31:32 1987
------------------------------------------------------------
*** tty.c	Sat Aug  1 13:37:08 1987
--- ../../dos/kernel/tty.c	Sat Aug  1 13:31:21 1987
***************
*** 766,772
  #define COLOR_BASE    0xB800	/* video ram paragraph for color display */
  #define MONO_BASE     0xB000	/* video ram address for mono display */
  #define C_VID_MASK    0x3FFF	/* mask for 16K video RAM */
! #define M_VID_MASK    0x0FFF	/* mask for  4K video RAM */
  #define C_RETRACE     0x0300	/* how many characters to display at once */
  #define M_RETRACE     0x7000	/* how many characters to display at once */
  #define WORD_MASK     0xFFFF	/* mask for 16 bits */

--- 766,772 -----
  #define COLOR_BASE    0xB800	/* video ram paragraph for color display */
  #define MONO_BASE     0xB000	/* video ram address for mono display */
  #define C_VID_MASK    0x3FFF	/* mask for 16K video RAM */
! #define M_VID_MASK    0x1FFF	/* mask for  8K video RAM */
  #define C_RETRACE     0x0300	/* how many characters to display at once */
  #define M_RETRACE     0x7000	/* how many characters to display at once */
  #define WORD_MASK     0xFFFF	/* mask for 16 bits */
------------------------------------------------------------
*** wini.c	Sat Aug  1 13:37:18 1987
--- ../../dos/kernel/wini.c	Sat Aug  1 13:31:36 1987
***************
*** 114,120
    int r, caller, proc_nr;
  
    /* First initialize the controller */
!   init_param();
  
    /* Here is the main loop of the disk task.  It waits for a message, carries
     * it out, and sends a reply.

--- 114,120 -----
    int r, caller, proc_nr;
  
    /* First initialize the controller */
!   init_params();
  
    /* Here is the main loop of the disk task.  It waits for a message, carries
     * it out, and sends a reply.
***************
*** 585,592
    phys_copy(address, umap(proc_addr(WINCHESTER), D, buf, 64), 64L);
  
    /* Copy the parameters to the structures */
!   copy_param((&buf[type_0 * 16]), &param0);
!   copy_param((&buf[type_1 * 16]), &param1);
  
    /* Get the nummer of drives from the bios */
    phys_copy(0x475L, umap(proc_addr(WINCHESTER), D, buf, 1), 1L);

--- 585,592 -----
    phys_copy(address, umap(proc_addr(WINCHESTER), D, buf, 64), 64L);
  
    /* Copy the parameters to the structures */
!   copy_params((&buf[type_0 * 16]), &param0);
!   copy_params((&buf[type_1 * 16]), &param1);
  
    /* Get the nummer of drives from the bios */
    phys_copy(0x475L, umap(proc_addr(WINCHESTER), D, buf, 1), 1L);

ericr@ipmoea.UUCP (Eric Roskos) (08/09/87)

Directory: /usr2/ericr/minix/minix/fs

------------------------------------------------------------
*** glo.h	Sat Aug  1 13:38:24 1987
--- ../../dos/fs/glo.h	Sat Aug  1 13:33:16 1987
***************
*** 6,11
  EXTERN int reviving;		/* number of pipe processes to be revived */
  EXTERN file_pos rdahedpos;	/* position to read ahead */
  EXTERN struct inode *rdahed_inode;	/* pointer to inode to read ahead */
  
  /* The parameters of the call are kept here. */
  EXTERN message m;		/* the input message itself */

--- 6,12 -----
  EXTERN int reviving;		/* number of pipe processes to be revived */
  EXTERN file_pos rdahedpos;	/* position to read ahead */
  EXTERN struct inode *rdahed_inode;	/* pointer to inode to read ahead */
+ EXTERN dev_nr root_dev;		/* the root device number (major/minor) */
  
  /* The parameters of the call are kept here. */
  EXTERN message m;		/* the input message itself */
------------------------------------------------------------
*** main.c	Sat Aug  1 13:38:22 1987
--- ../../dos/fs/main.c	Sat Aug  1 13:33:13 1987
***************
*** 24,29
  
  #define M64K     0xFFFF0000L	/* 16 bit mask for DMA check */
  #define INFO               2	/* where in data_org is info from build */
  #define MAX_RAM          512	/* maxium RAM disk size in blocks */
  
  /*===========================================================================*

--- 24,30 -----
  
  #define M64K     0xFFFF0000L	/* 16 bit mask for DMA check */
  #define INFO               2	/* where in data_org is info from build */
+ #define ROOT_IDX	   0	/* where in data_org kernel put boot-dev idx */
  #define MAX_RAM          512	/* maxium RAM disk size in blocks */
  
  /*===========================================================================*
***************
*** 223,228
    struct super_block *sp;
    block_nr i;
    phys_clicks ram_clicks, init_org, init_text_clicks, init_data_clicks;
    extern phys_clicks data_org[INFO + 2];
    extern struct buf *get_block();
  

--- 224,231 -----
    struct super_block *sp;
    block_nr i;
    phys_clicks ram_clicks, init_org, init_text_clicks, init_data_clicks;
+   int fLoadRam;
+   int ir;
    extern phys_clicks data_org[INFO + 2];
    extern struct buf *get_block();
  
***************
*** 231,246
    init_text_clicks = data_org[INFO + 1];
    init_data_clicks = data_org[INFO + 2];
  
!   /* Get size of RAM disk by reading root file system's super block */
!   bp = get_block(BOOT_DEV, SUPER_BLOCK, NORMAL);  /* get RAM super block */
!   copy(super_block, bp->b_data, sizeof(struct super_block));
!   sp = &super_block[0];
!   if (sp->s_magic != SUPER_MAGIC)
! 	panic("Diskette in drive 0 is not root file system", NO_NUM);
!   count = sp->s_nzones << sp->s_log_zone_size;	/* # blocks on root dev */
!   if (count > MAX_RAM) panic("RAM disk is too big. # blocks = ", count);
!   ram_clicks = count * (BLOCK_SIZE/CLICK_SIZE);
!   put_block(bp, FULL_DATA_BLOCK);
  
    /* Tell MM the origin and size of INIT, and the amount of memory used for the
     * system plus RAM disk combined, so it can remove all of it from the map.

--- 234,242 -----
    init_text_clicks = data_org[INFO + 1];
    init_data_clicks = data_org[INFO + 2];
  
!   /* select root device based on user input to fsck - JER 7/29/87 */
!   /* get root-device index stored by kernel at end of main() init */
!   ir = data_org[ROOT_IDX];
  
    if (ir == 0)
  	root_dev = DEV_RAM;
***************
*** 242,247
    ram_clicks = count * (BLOCK_SIZE/CLICK_SIZE);
    put_block(bp, FULL_DATA_BLOCK);
  
    /* Tell MM the origin and size of INIT, and the amount of memory used for the
     * system plus RAM disk combined, so it can remove all of it from the map.
     */

--- 238,269 -----
    /* get root-device index stored by kernel at end of main() init */
    ir = data_org[ROOT_IDX];
  
+   if (ir == 0)
+ 	root_dev = DEV_RAM;
+   else
+ 	root_dev = DEV_WINI + ir;
+ 
+   /* if root device is ram disk, have to load ram from boot floppy */
+   fLoadRam = (root_dev&0xff00)==DEV_RAM;
+ 
+   if (fLoadRam)
+   {
+ 	  /* Get size of RAM disk by reading root file system's super block */
+ 	  bp = get_block(BOOT_DEV, SUPER_BLOCK, NORMAL);  /* get RAM super block */
+ 	  copy(super_block, bp->b_data, sizeof(struct super_block));
+ 	  sp = &super_block[0];
+ 	  if (sp->s_magic != SUPER_MAGIC)
+ 		panic("Diskette in drive 0 is not root file system", NO_NUM);
+ 	  count = sp->s_nzones << sp->s_log_zone_size;	/* # blocks on root dev */
+ 	  if (count > MAX_RAM) panic("RAM disk is too big. # blocks = ", count);
+ 	  ram_clicks = count * (BLOCK_SIZE/CLICK_SIZE);
+ 	  put_block(bp, FULL_DATA_BLOCK);
+   }
+   else
+   {
+ 	  ram_clicks = RAM_MIN * (BLOCK_SIZE/CLICK_SIZE);
+   }
+ 
    /* Tell MM the origin and size of INIT, and the amount of memory used for the
     * system plus RAM disk combined, so it can remove all of it from the map.
     */
***************
*** 260,277
    m1.COUNT = count;
    if (sendrec(MEM, &m1) != OK) panic("Can't report size to MEM", NO_NUM);
  
!   /* Copy the blocks one at a time from the root diskette to the RAM */
!   printf("Loading RAM disk from root diskette.      Loaded:   0K ");
!   for (i = 0; i < count; i++) {
! 	bp = get_block(BOOT_DEV, (block_nr) i, NORMAL);
! 	bp1 = get_block(ROOT_DEV, i, NO_READ);
! 	copy(bp1->b_data, bp->b_data, BLOCK_SIZE);
! 	bp1->b_dirt = DIRTY;
! 	put_block(bp, I_MAP_BLOCK);
! 	put_block(bp1, I_MAP_BLOCK);
! 	k_loaded = ( (long) i * BLOCK_SIZE)/1024L;	/* K loaded so far */
! 	if (k_loaded % 5 == 0) printf("\b\b\b\b\b%3DK %c", k_loaded, 0);
!   }
  
    printf("\rRAM disk loaded.  Please remove root diskette.           \n\n");
  }

--- 282,301 -----
    m1.COUNT = count;
    if (sendrec(MEM, &m1) != OK) panic("Can't report size to MEM", NO_NUM);
  
!   if (fLoadRam)
!   {
! 	  /* Copy the blocks one at a time from the root diskette to the RAM */
! 	  printf("Loading RAM disk from root diskette.      Loaded:   0K ");
! 	  for (i = 0; i < count; i++) {
! 		bp = get_block(BOOT_DEV, (block_nr) i, NORMAL);
! 		bp1 = get_block(ROOT_DEV, i, NO_READ);
! 		copy(bp1->b_data, bp->b_data, BLOCK_SIZE);
! 		bp1->b_dirt = DIRTY;
! 		put_block(bp, I_MAP_BLOCK);
! 		put_block(bp1, I_MAP_BLOCK);
! 		k_loaded = ( (long) i * BLOCK_SIZE)/1024L;	/* K loaded so far */
! 		if (k_loaded % 5 == 0) printf("\b\b\b\b\b%3DK %c", k_loaded, 0);
! 	  }
  
  	  printf("\rRAM disk loaded.  Please remove root diskette.           \n\n");
    }
***************
*** 273,279
  	if (k_loaded % 5 == 0) printf("\b\b\b\b\b%3DK %c", k_loaded, 0);
    }
  
!   printf("\rRAM disk loaded.  Please remove root diskette.           \n\n");
  }
  
  

--- 297,304 -----
  		if (k_loaded % 5 == 0) printf("\b\b\b\b\b%3DK %c", k_loaded, 0);
  	  }
  
! 	  printf("\rRAM disk loaded.  Please remove root diskette.           \n\n");
!   }
  }
  
  
------------------------------------------------------------
*** super.c	Sat Aug  1 13:38:24 1987
--- ../../dos/fs/super.c	Sat Aug  1 13:33:15 1987
***************
*** 22,27
  #include "buf.h"
  #include "inode.h"
  #include "super.h"
  
  #define INT_BITS (sizeof(int)<<3)
  #define BIT_MAP_SHIFT     13	/* (log2 of BLOCK_SIZE) + 3; 13 for 1k blocks */

--- 22,28 -----
  #include "buf.h"
  #include "inode.h"
  #include "super.h"
+ #include "glo.h"
  
  #define INT_BITS (sizeof(int)<<3)
  #define BIT_MAP_SHIFT     13	/* (log2 of BLOCK_SIZE) + 3; 13 for 1k blocks */

ericr@ipmoea.UUCP (Eric Roskos) (08/09/87)

Directory: /usr2/ericr/minix/minix/h

------------------------------------------------------------
*** const.h	Sat Aug  1 13:34:29 1987
--- ../../dos/h/const.h	Sat Aug  1 13:28:34 1987
***************
*** 58,66
  #define SIG_PUSH_BYTES	      8	/* how many bytes pushed by signal */
  #define MAX_ISTACK_BYTES   1024	/* maximum initial stack size for EXEC */
  
! /* Device numbers of root (RAM) and boot (fd0) devices. */
! #define ROOT_DEV (dev_nr)   256	/* major-minor device number of root dev */
! #define BOOT_DEV (dev_nr)   512	/* major-minor device number of boot diskette */
  
  /* Flag bits for i_mode in the inode. */
  #define I_TYPE          0170000	/* this field gives inode type */

--- 58,78 -----
  #define SIG_PUSH_BYTES	      8	/* how many bytes pushed by signal */
  #define MAX_ISTACK_BYTES   1024	/* maximum initial stack size for EXEC */
  
! /* 
!  * Device numbers for minor dev 0 of winchester, floppy, and RAM disk.
!  * These are used to determine where to find the root filesystem;
!  * see load_ram in kernel/main.c for algorithm. - JER 7/29/87
!  */
! #define DEV_RAM		((dev_nr) 0x0100)
! #define DEV_FLOPPY	((dev_nr) 0x0200)
! #define DEV_WINI 	((dev_nr) 0x0300)
! 
! /* Device numbers of root and boot devices. */
! #define ROOT_DEV (dev_nr)   root_dev	/* major-minor device number of root dev */
! #define BOOT_DEV (dev_nr)   DEV_FLOPPY	/* major-minor device number of boot diskette */
! 
! /* Minimum number of blocks for RAM disk (size if root != RAM) */
! #define RAM_MIN		1
  
  /* Flag bits for i_mode in the inode. */
  #define I_TYPE          0170000	/* this field gives inode type */

ericr@ipmoea.UUCP (Eric Roskos) (08/10/87)

Directory: /usr2/ericr/minix/minix/lib

------------------------------------------------------------
*** catchsig.asm	Sat Aug  1 13:36:05 1987
--- ../../dos/lib/catchsig.asm	Sat Aug  1 13:30:07 1987
***************
*** 3,10
  
  	INCLUDE ..\lib\prologue.h
  
! 	PUBLIC begsig
! 	EXTRN  vectab:WORD, M:WORD
  
  
  @CODE	SEGMENT

--- 3,10 -----
  
  	INCLUDE ..\lib\prologue.h
  
! 	PUBLIC _begsig
! 	EXTRN  _vectab:WORD, _M:WORD
  
  
  _TEXT	SEGMENT
***************
*** 7,14
  	EXTRN  vectab:WORD, M:WORD
  
  
! @CODE	SEGMENT
! 	ASSUME	CS:@CODE,DS:DGROUP
  
  MTYPE = 2			; M+mtype =  &M.m_type
  begsig:

--- 7,14 -----
  	EXTRN  _vectab:WORD, _M:WORD
  
  
! _TEXT	SEGMENT
! 	ASSUME	CS:_TEXT,DS:DGROUP
  
  MTYPE = 2			; M+mtype =  &M.m_type
  _begsig:
***************
*** 11,17
  	ASSUME	CS:@CODE,DS:DGROUP
  
  MTYPE = 2			; M+mtype =  &M.m_type
! begsig:
  	push ax			; after interrupt, save all regs
  	push bx
  	push cx

--- 11,17 -----
  	ASSUME	CS:_TEXT,DS:DGROUP
  
  MTYPE = 2			; M+mtype =  &M.m_type
! _begsig:
  	push ax			; after interrupt, save all regs
  	push bx
  	push cx
***************
*** 25,32
  	mov bx,18[bp]		; bx = signal number
  	dec bx			; vectab[0] is for sig 1
  	add bx,bx		; pointers are two bytes on 8088
! 	mov bx,vectab[bx]	; bx = address of routine to call
! 	push M+mtype		; push status of last system call
  	push ax			; func called with signal number as arg
  	call bx
  back:

--- 25,32 -----
  	mov bx,18[bp]		; bx = signal number
  	dec bx			; vectab[0] is for sig 1
  	add bx,bx		; pointers are two bytes on 8088
! 	mov bx,_vectab[bx]	; bx = address of routine to call
! 	push _M+mtype		; push status of last system call
  	push ax			; func called with signal number as arg
  	call bx
  back:
***************
*** 31,37
  	call bx
  back:
  	pop ax			; get signal number off stack
! 	pop M+mtype		; restore status of previous system call
  	pop es			; signal handling finished
  	pop ds
  	pop bp

--- 31,37 -----
  	call bx
  back:
  	pop ax			; get signal number off stack
! 	pop _M+mtype		; restore status of previous system call
  	pop es			; signal handling finished
  	pop ds
  	pop bp
***************
*** 43,49
  	pop ax
  	pop dummy		; remove signal number from stack
  	iret
! @CODE	ENDS
  
  @DATAI SEGMENT
  dummy	 DW	 0

--- 43,49 -----
  	pop ax
  	pop dummy		; remove signal number from stack
  	iret
! _TEXT	ENDS
  
  _DATA	SEGMENT
  dummy	 DW	 0
***************
*** 45,51
  	iret
  @CODE	ENDS
  
! @DATAI SEGMENT
  dummy	 DW	 0
  @DATAI	ENDS
  

--- 45,51 -----
  	iret
  _TEXT	ENDS
  
! _DATA	SEGMENT
  dummy	 DW	 0
  _DATA	ENDS
  
***************
*** 47,52
  
  @DATAI SEGMENT
  dummy	 DW	 0
! @DATAI	ENDS
  
  	END	; end of assembly-file

--- 47,52 -----
  
  _DATA	SEGMENT
  dummy	 DW	 0
! _DATA	ENDS
  
  	END	; end of assembly-file
------------------------------------------------------------
*** crtso.asm	Sat Aug  1 13:36:11 1987
--- ../../dos/lib/crtso.asm	Sat Aug  1 13:30:18 1987
***************
*** 3,10
  
  
  
! PUBLIC	@end, brksize, edata, $main, environ, kamikaze
! EXTRN   main:NEAR, exit:NEAR
  
  INCLUDE ..\lib\prologue.h
  

--- 3,10 -----
  
  
  
! PUBLIC	_end, _brksize, _edata, $main, _environ, _kamikaze
! EXTRN   _main:NEAR, _exit:NEAR
  
  INCLUDE ..\lib\prologue.h
  
***************
*** 10,15
  
  STACKSIZE EQU 2560	; default stack is 5 Kb (2K words)
  
  
  
  @CODE	SEGMENT

--- 10,17 -----
  
  STACKSIZE EQU 2560	; default stack is 5 Kb (2K words)
  
+ PUBLIC	__acrtused
+ __acrtused	EQU	9876H	; used by MSC to pull in startup routine
  
  
  
***************
*** 12,19
  
  
  
- @CODE	SEGMENT
- 	ASSUME	CS:@CODE,DS:DGROUP
  
  ; This is the C run-time start-off routine.  It's job is to take the
  ; arguments as put on the stack by EXEC, and to parse them and set them up the

--- 14,19 -----
  __acrtused	EQU	9876H	; used by MSC to pull in startup routine
  
  
  
  _TEXT	SEGMENT
  	ASSUME	CS:_TEXT,DS:DGROUP
***************
*** 15,20
  @CODE	SEGMENT
  	ASSUME	CS:@CODE,DS:DGROUP
  
  ; This is the C run-time start-off routine.  It's job is to take the
  ; arguments as put on the stack by EXEC, and to parse them and set them up the
  ; way main expects them.

--- 15,23 -----
  
  
  
+ _TEXT	SEGMENT
+ 	ASSUME	CS:_TEXT,DS:DGROUP
+ 
  ; This is the C run-time start-off routine.  It's job is to take the
  ; arguments as put on the stack by EXEC, and to parse them and set them up the
  ; way main expects them.
***************
*** 29,35
  	inc	ax		; calculate envp
  	shl	ax,1
  	add	ax,bx
! 	mov	environ,ax	; save envp
  	push	ax		; stack envp
  	push	bx		; stack argv
  	push	cx		; stack argc

--- 32,38 -----
  	inc	ax		; calculate envp
  	shl	ax,1
  	add	ax,bx
! 	mov	_environ,ax	; save envp
  	push	ax		; stack envp
  	push	bx		; stack argv
  	push	cx		; stack argc
***************
*** 34,40
  	push	bx		; stack argv
  	push	cx		; stack argc
  
! 	call	main		; call main (arc,argv,envp)
  
  	add	sp,6
  	push	ax		; stack program-termination status

--- 37,43 -----
  	push	bx		; stack argv
  	push	cx		; stack argc
  
! 	call	_main		; call main (arc,argv,envp)
  
  	add	sp,6
  	push	ax		; stack program-termination status
***************
*** 38,44
  
  	add	sp,6
  	push	ax		; stack program-termination status
! 	call	exit		; this will never return
  
  	; DEBUG from here on
  

--- 41,47 -----
  
  	add	sp,6
  	push	ax		; stack program-termination status
! 	call	_exit		; this will never return
  
  	; DEBUG from here on
  
***************
*** 42,48
  
  	; DEBUG from here on
  
! kamikaze: 	int 3
  		ret
  
  @CODE	ENDS

--- 45,51 -----
  
  	; DEBUG from here on
  
! _kamikaze: 	int 3
  		ret
  
  _TEXT	ENDS
***************
*** 45,51
  kamikaze: 	int 3
  		ret
  
! @CODE	ENDS
  
  
  @DATAC	SEGMENT

--- 48,54 -----
  _kamikaze: 	int 3
  		ret
  
! _TEXT	ENDS
  
  
  _DATA	SEGMENT
***************
*** 48,57
  @CODE	ENDS
  
  
! @DATAC	SEGMENT
! brksize	DW	offset dgroup:@END+2  	; dynamic changeable end of bss
! environ	DW	0			; save environment pointer here
! @DATAC	ENDS
  
  @DATAT	SEGMENT				; DATAT holds nothing. The label just
  edata	label byte			; tells us where the initialized data

--- 51,60 -----
  _TEXT	ENDS
  
  
! _DATA	SEGMENT
! _brksize	DW	offset dgroup:_END+2  	; dynamic changeable end of bss
! _environ	DW	0			; save environment pointer here
! _DATA 	ENDS
  
  _DATAT	SEGMENT				; DATAT holds nothing. The label just
  _edata	label byte			; tells us where the initialized data
***************
*** 53,61
  environ	DW	0			; save environment pointer here
  @DATAC	ENDS
  
! @DATAT	SEGMENT				; DATAT holds nothing. The label just
! edata	label byte			; tells us where the initialized data
! @DATAT	ENDS				; (.data) ends.
  
  @DATAV	SEGMENT				; DATAV holds nothing. The label in
  @end	label byte			; the segment just tells us where

--- 56,64 -----
  _environ	DW	0			; save environment pointer here
  _DATA 	ENDS
  
! _DATAT	SEGMENT				; DATAT holds nothing. The label just
! _edata	label byte			; tells us where the initialized data
! _DATAT	ENDS				; (.data) ends.
  
  _DATAV	SEGMENT				; DATAV holds nothing. The label in
  _end	label byte			; the segment just tells us where
***************
*** 57,65
  edata	label byte			; tells us where the initialized data
  @DATAT	ENDS				; (.data) ends.
  
! @DATAV	SEGMENT				; DATAV holds nothing. The label in
! @end	label byte			; the segment just tells us where
! @DATAV	ENDS				; the data+bss ends.
  
  @STACK	SEGMENT	BYTE STACK 'STACK'
  	DW	STACKSIZE dup(?)	; add stack segment to bss

--- 60,68 -----
  _edata	label byte			; tells us where the initialized data
  _DATAT	ENDS				; (.data) ends.
  
! _DATAV	SEGMENT				; DATAV holds nothing. The label in
! _end	label byte			; the segment just tells us where
! _DATAV	ENDS				; the data+bss ends.
  
  _STACK	SEGMENT	BYTE STACK 'STACK'
  	DW	STACKSIZE dup(?)	; add stack segment to bss
***************
*** 61,67
  @end	label byte			; the segment just tells us where
  @DATAV	ENDS				; the data+bss ends.
  
! @STACK	SEGMENT	BYTE STACK 'STACK'
  	DW	STACKSIZE dup(?)	; add stack segment to bss
  @STACK	ENDS
  

--- 64,70 -----
  _end	label byte			; the segment just tells us where
  _DATAV	ENDS				; the data+bss ends.
  
! _STACK	SEGMENT	BYTE STACK 'STACK'
  	DW	STACKSIZE dup(?)	; add stack segment to bss
  _STACK	ENDS
  
***************
*** 63,69
  
  @STACK	SEGMENT	BYTE STACK 'STACK'
  	DW	STACKSIZE dup(?)	; add stack segment to bss
! @STACK	ENDS
  
  
  	END	$main	; program entry-point (could be anywhere)

--- 66,72 -----
  
  _STACK	SEGMENT	BYTE STACK 'STACK'
  	DW	STACKSIZE dup(?)	; add stack segment to bss
! _STACK	ENDS
  
  
  	END	$main	; program entry-point (could be anywhere)
------------------------------------------------------------
*** getutil.asm	Sat Aug  1 13:35:51 1987
--- ../../dos/lib/getutil.asm	Sat Aug  1 13:29:47 1987
***************
*** 4,11
  
  	INCLUDE ..\lib\prologue.h
  
! 	PUBLIC get_base, get_size, get_tot_
! 	EXTRN  brksize:WORD, @end:byte
  
  
  @CODE	SEGMENT

--- 4,11 -----
  
  	INCLUDE ..\lib\prologue.h
  
! 	PUBLIC _get_base, _get_size, _get_tot_mem
! 	EXTRN  _brksize:WORD, _end:byte
  
  
  _TEXT	SEGMENT
***************
*** 8,15
  	EXTRN  brksize:WORD, @end:byte
  
  
! @CODE	SEGMENT
! 	ASSUME	CS:@CODE,DS:DGROUP
  
  ;========================================================================
  ;                           utilities                                     

--- 8,15 -----
  	EXTRN  _brksize:WORD, _end:byte
  
  
! _TEXT	SEGMENT
! 	ASSUME	CS:_TEXT,DS:DGROUP
  
  ;========================================================================
  ;                           utilities                                     
***************
*** 15,21
  ;                           utilities                                     
  ;========================================================================
  
! get_base:			; return click at which prog starts
  	mov ax,ds
  	ret
  

--- 15,21 -----
  ;                           utilities                                     
  ;========================================================================
  
! _get_base:			; return click at which prog starts
  	mov ax,ds
  	ret
  
***************
*** 19,26
  	mov ax,ds
  	ret
  
! get_size:			   ; return prog size in bytes [text+data+bss]
! 	mov ax,offset dgroup:@end  ; end is label at end of bss
  	ret
  
  ; Find out how much memory the machine has, including vectors, kernel MM, etc.

--- 19,26 -----
  	mov ax,ds
  	ret
  
! _get_size:			   ; return prog size in bytes [text+data+bss]
! 	mov ax,offset dgroup:_end  ; end is label at end of bss
  	ret
  
  ; Find out how much memory the machine has, including vectors, kernel MM, etc.
***************
*** 24,30
  	ret
  
  ; Find out how much memory the machine has, including vectors, kernel MM, etc.
! get_tot_:
  	cli
  	push es
  	push di

--- 24,30 -----
  	ret
  
  ; Find out how much memory the machine has, including vectors, kernel MM, etc.
! _get_tot_mem:
  	cli
  	push es
  	push di
***************
*** 44,49
  	sti
  	ret
  
! @CODE	ENDS
  
  	END	; end of assembly-file

--- 44,49 -----
  	sti
  	ret
  
! _TEXT	ENDS
  
  	END	; end of assembly-file
------------------------------------------------------------
*** head.asm	Sat Aug  1 13:36:11 1987
--- ../../dos/lib/head.asm	Sat Aug  1 13:30:14 1987
***************
*** 1,4
! title Head  -  Start-off for initt, mm and fs (C86-compiler)
  page ,132
  
  EXTRN main:NEAR

--- 1,4 -----
! title Head  -  Start-off for init, mm and fs (C86-compiler)
  page ,132
  
  PUBLIC 		__acrtused 		; magic symbol for MSC (indicates startup present)
***************
*** 1,9
  title Head  -  Start-off for initt, mm and fs (C86-compiler)
  page ,132
  
! EXTRN main:NEAR
! PUBLIC $main, data_org,	brksize, sp_limit, @end
! EXTRN  stackpt:word
  
  INCLUDE	..\lib\prologue.h
  

--- 1,8 -----
  title Head  -  Start-off for init, mm and fs (C86-compiler)
  page ,132
  
! PUBLIC 		__acrtused 		; magic symbol for MSC (indicates startup present)
! __acrtused	EQU	9876H
  
  EXTRN _main:NEAR
  PUBLIC $main, _data_org, _brksize, _sp_limit, _end
***************
*** 5,10
  PUBLIC $main, data_org,	brksize, sp_limit, @end
  EXTRN  stackpt:word
  
  INCLUDE	..\lib\prologue.h
  
  

--- 4,13 -----
  PUBLIC 		__acrtused 		; magic symbol for MSC (indicates startup present)
  __acrtused	EQU	9876H
  
+ EXTRN _main:NEAR
+ PUBLIC $main, _data_org, _brksize, _sp_limit, _end
+ EXTRN  _stackpt:word,
+ 
  INCLUDE	..\lib\prologue.h
  
  
***************
*** 8,15
  INCLUDE	..\lib\prologue.h
  
  
! @CODE	SEGMENT
! 	assume	cs:@code,ds:dgroup
  
  $main:	jmp	short L0
  	ORG 10h			; kernel uses this area	as stack for inital IRET

--- 11,18 -----
  INCLUDE	..\lib\prologue.h
  
  
! _TEXT	SEGMENT
! 	assume	cs:_TEXT,ds:dgroup
  
  $main:	jmp	short L0
  	ORG 10h			; kernel uses this area	as stack for inital IRET
***************
*** 13,20
  
  $main:	jmp	short L0
  	ORG 10h			; kernel uses this area	as stack for inital IRET
!      L0:mov	sp,dgroup:stackpt
! 	call	main
       L1:jmp L1			; this will never be executed
  	mov	ax,DGROUP	; force	relocation for dos2out (never executed)
  

--- 16,23 -----
  
  $main:	jmp	short L0
  	ORG 10h			; kernel uses this area	as stack for inital IRET
!      L0:mov	sp,dgroup:_stackpt
! 	call	_main
       L1:jmp L1			; this will never be executed
  	mov	ax,DGROUP	; force	relocation for dos2out (never executed)
  
***************
*** 18,24
       L1:jmp L1			; this will never be executed
  	mov	ax,DGROUP	; force	relocation for dos2out (never executed)
  
! @CODE	ENDS
  
  
  @DATAB	SEGMENT			; fs needs to know where build stuffed table

--- 21,27 -----
       L1:jmp L1			; this will never be executed
  	mov	ax,DGROUP	; force	relocation for dos2out (never executed)
  
! _TEXT	ENDS
  
  
  _DATAB	SEGMENT			; fs needs to know where build stuffed table
***************
*** 21,28
  @CODE	ENDS
  
  
! @DATAB	SEGMENT			; fs needs to know where build stuffed table
! data_org DW 0DADAh		; 0xDADA is magic number for build
  	 DW 7 dup(0)		; first 8 words of MM, FS, INIT are for stack
  brksize	 DW	offset dgroup:@END  ; first free memory
  sp_limit DW	0

--- 24,31 -----
  _TEXT	ENDS
  
  
! _DATAB	SEGMENT			; fs needs to know where build stuffed table
! _data_org DW 0DADAh		; 0xDADA is magic number for build
  	 DW 7 dup(0)		; first 8 words of MM, FS, INIT are for stack
  _brksize	 DW	offset dgroup:_END  ; first free memory
  _sp_limit DW	0
***************
*** 24,32
  @DATAB	SEGMENT			; fs needs to know where build stuffed table
  data_org DW 0DADAh		; 0xDADA is magic number for build
  	 DW 7 dup(0)		; first 8 words of MM, FS, INIT are for stack
! brksize	 DW	offset dgroup:@END  ; first free memory
! sp_limit DW	0
! @DATAB	ENDS
  
  @DATAV	SEGMENT				; DATAV	holds nothing. The label in
  	@END	label	byte		; the segment just tells us where

--- 27,35 -----
  _DATAB	SEGMENT			; fs needs to know where build stuffed table
  _data_org DW 0DADAh		; 0xDADA is magic number for build
  	 DW 7 dup(0)		; first 8 words of MM, FS, INIT are for stack
! _brksize	 DW	offset dgroup:_END  ; first free memory
! _sp_limit DW	0
! _DATAB	ENDS
  
  _DATAV	SEGMENT				; DATAV	holds nothing. The label in
  _END	label	byte		; the segment just tells us where
***************
*** 28,36
  sp_limit DW	0
  @DATAB	ENDS
  
! @DATAV	SEGMENT				; DATAV	holds nothing. The label in
! 	@END	label	byte		; the segment just tells us where
! @DATAV	ENDS				; the data+bss ends.
  
  @STACK	SEGMENT	BYTE STACK 'STACK'
  @STACK	ENDS				; Add stack to satisfy DOS-linker

--- 31,39 -----
  _sp_limit DW	0
  _DATAB	ENDS
  
! _DATAV	SEGMENT				; DATAV	holds nothing. The label in
! _END	label	byte		; the segment just tells us where
! _DATAV	ENDS				; the data+bss ends.
  
  @STACK	SEGMENT	BYTE STACK 'STACK'
  @STACK	ENDS				; Add stack to satisfy DOS-linker
------------------------------------------------------------
*** message.c	Sat Aug  1 13:36:05 1987
--- ../../dos/lib/message.c	Sat Aug  1 13:30:10 1987
***************
*** 1,4
  #include "../h/const.h"
  #include "../h/type.h"
  
! message M;

--- 1,4 -----
  #include "../h/const.h"
  #include "../h/type.h"
  
! message M = {0}; /* dummy init so linker will recognize this symbol */
------------------------------------------------------------
*** prologue.h	Sat Aug  1 13:35:57 1987
--- ../../dos/lib/prologue.h	Sat Aug  1 13:29:52 1987
***************
*** 1,6
  
  ;	prologue.h	
! ;	standard prologue for c86 assembly code
  ;	This file defines the correct ordering of segments
  
  @CODE	SEGMENT BYTE PUBLIC 'CODE'	; text segment

--- 1,6 -----
  
  ;	prologue.h	
! ;	standard prologue for MSC assembly code
  ;	This file defines the correct ordering of segments
  
  	ifdef	debug
***************
*** 3,22
  ;	standard prologue for c86 assembly code
  ;	This file defines the correct ordering of segments
  
! @CODE	SEGMENT BYTE PUBLIC 'CODE'	; text segment
! @CODE	ENDS
! @DATAB	SEGMENT PARA PUBLIC 'DATAB'	; data segment
! @DATAB	ENDS
! @DATAC	SEGMENT BYTE PUBLIC 'DATAC'	; data segment
! @DATAC	ENDS
! @DATAI	SEGMENT BYTE PUBLIC 'DATAI'	; data segment
! @DATAI	ENDS
! @DATAT	SEGMENT BYTE PUBLIC 'DATAT'	; bss segment
! @DATAT	ENDS
! @DATAU	SEGMENT BYTE PUBLIC 'DATAU'	; bss segment
! @DATAU	ENDS
! @DATAV	SEGMENT BYTE PUBLIC 'DATAV'	; bss segment
! @DATAV	ENDS
  
  
  DGROUP	GROUP	@DATAB,@DATAC,@DATAI,@DATAT,@DATAU,@DATAV

--- 3,13 -----
  ;	standard prologue for MSC assembly code
  ;	This file defines the correct ordering of segments
  
! 	ifdef	debug
! 	if1
! 	%out	Debug messages enabled
! 	endif
! 	endif
  
  _TEXT	SEGMENT  BYTE PUBLIC 'CODE'
  _TEXT	ENDS
***************
*** 18,22
  @DATAV	SEGMENT BYTE PUBLIC 'DATAV'	; bss segment
  @DATAV	ENDS
  
  
  DGROUP	GROUP	@DATAB,@DATAC,@DATAI,@DATAT,@DATAU,@DATAV

--- 9,32 -----
  	endif
  	endif
  
+ _TEXT	SEGMENT  BYTE PUBLIC 'CODE'
+ _TEXT	ENDS
+ _DATAB	SEGMENT  PARA PUBLIC 'DATA'
+ _DATAB	ENDS
+ _DATA	SEGMENT  BYTE PUBLIC 'DATA'
+ _DATA	ENDS
+ CONST	SEGMENT  BYTE PUBLIC 'CONST'
+ CONST	ENDS
+ _DATAT	SEGMENT  BYTE PUBLIC 'CONST'
+ _DATAT	ENDS
+ _BSS	SEGMENT  BYTE PUBLIC 'BSS'
+ _BSS	ENDS
+ C_COMMON SEGMENT BYTE PUBLIC 'BSS'
+ C_COMMON ENDS
+ _DATAU	SEGMENT  BYTE PUBLIC 'BSS'
+ _DATAU	ENDS
+ _DATAV	SEGMENT  BYTE PUBLIC 'BSS'
+ _DATAV	ENDS
  
  DGROUP	GROUP	_DATAB, _DATA, CONST, _DATAT, _BSS, C_COMMON, _DATAV
  
***************
*** 19,22
  @DATAV	ENDS
  
  
! DGROUP	GROUP	@DATAB,@DATAC,@DATAI,@DATAT,@DATAU,@DATAV

--- 28,60 -----
  _DATAV	SEGMENT  BYTE PUBLIC 'BSS'
  _DATAV	ENDS
  
! DGROUP	GROUP	_DATAB, _DATA, CONST, _DATAT, _BSS, C_COMMON, _DATAV
! 
! 	ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
! 
! ;
! ; Debugging message macro - JER
! ;
! 
! wto	macro	mesg
! 	local	msgstr
! 
! 	ifdef	debug
! 
! 	public	msgstr		; DEBUG so we can find it in the linker map
! _data	segment
! msgstr db	mesg
! 	db	0dH,0aH,00H
! _data	ends
! 
! 	push	ax
! 	push	bx
! 	mov	bx,offset msgstr
! 	mov		ax,bx	;DEBUG
! 	call	prtax	;DEBUG
! 	call	near ptr print
! 	pop	bx
! 	pop	ax
! 
! 	endif
! 	endm
------------------------------------------------------------
*** sendrec.asm	Sat Aug  1 13:36:00 1987
--- ../../dos/lib/sendrec.asm	Sat Aug  1 13:30:04 1987
***************
*** 3,9
  
  	INCLUDE ..\lib\prologue.h
  
! 	PUBLIC send, receive, send_rec, sendrec
  
  
  ; The following definitions are from  ../h/com.h

--- 3,9 -----
  
  	INCLUDE ..\lib\prologue.h
  
! 	PUBLIC _send, _receive, _send_rec, _sendrec
  
  
  ; The following definitions are from  ../h/com.h
***************
*** 8,17
  
  ; The following definitions are from  ../h/com.h
  
! 	_SEND	= 1
! 	_RECEIVE= 2
! 	_BOTH	= 3
! 	_SYSVEC	= 32
  
  
  @CODE	SEGMENT

--- 8,17 -----
  
  ; The following definitions are from  ../h/com.h
  
! 	SEND	= 1
! 	RECEIVE= 2
! 	BOTH	= 3
! 	SYSVEC	= 32
  
  
  _TEXT	SEGMENT
***************
*** 14,21
  	_SYSVEC	= 32
  
  
! @CODE	SEGMENT
! 	ASSUME	CS:@CODE,DS:DGROUP
  
  ;========================================================================
  ;                           send and receive                              

--- 14,21 -----
  	SYSVEC	= 32
  
  
! _TEXT	SEGMENT
! 	ASSUME	CS:_TEXT,DS:DGROUP
  
  ;========================================================================
  ;                           send and receive                              
***************
*** 22,28
  ;========================================================================
  ; send(), receive(), send_rec() all save bp, but destroy ax, bx, and cx.
  
! send:	mov cx,_SEND		; send(dest, ptr)
  	jmp L0
  
  receive:

--- 22,28 -----
  ;========================================================================
  ; send(), receive(), send_rec() all save bp, but destroy ax, bx, and cx.
  
! _send:	mov cx,SEND		; send(dest, ptr)
  	jmp L0
  
  _receive:
***************
*** 25,32
  send:	mov cx,_SEND		; send(dest, ptr)
  	jmp L0
  
! receive:
! 	mov cx,_RECEIVE		; receive(src, ptr)
  	jmp L0
  
  sendrec:

--- 25,32 -----
  _send:	mov cx,SEND		; send(dest, ptr)
  	jmp L0
  
! _receive:
! 	mov cx,RECEIVE		; receive(src, ptr)
  	jmp L0
  
  _sendrec:
***************
*** 29,37
  	mov cx,_RECEIVE		; receive(src, ptr)
  	jmp L0
  
! sendrec:
! send_rec:
! 	mov cx,_BOTH		; send_rec(srcdest, ptr)
  	jmp L0
  
    L0:	push bp			; save bp

--- 29,37 -----
  	mov cx,RECEIVE		; receive(src, ptr)
  	jmp L0
  
! _sendrec:
! _send_rec:
! 	mov cx,BOTH		; send_rec(srcdest, ptr)
  	jmp L0
  
    L0:	push bp			; save bp
***************
*** 38,44
  	mov bp,sp		; can't index off sp
  	mov ax,4[bp]		; ax = dest-src
  	mov bx,6[bp]		; bx = message pointer
! 	int _SYSVEC		; trap to the kernel
  	pop bp			; restore bp
  	ret			; return
  

--- 38,44 -----
  	mov bp,sp		; can't index off sp
  	mov ax,4[bp]		; ax = dest-src
  	mov bx,6[bp]		; bx = message pointer
! 	int SYSVEC		; trap to the kernel
  	pop bp			; restore bp
  	ret			; return
  
***************
*** 42,47
  	pop bp			; restore bp
  	ret			; return
  
! @CODE	ENDS
  
  	END	; end of assembly-file

--- 42,47 -----
  	pop bp			; restore bp
  	ret			; return
  
! _TEXT	ENDS
  
  	END	; end of assembly-file

ericr@ipmoea.UUCP (Eric Roskos) (08/21/87)

Directory: /usr2/ericr/minix/minix/tools

------------------------------------------------------------
*** ar.c	Sat Aug  1 13:37:47 1987
--- ../../dos/tools/ar.c	Sat Aug  1 13:32:37 1987
***************
*** 11,17
   *	  p: print named files
   */
  
! #include "stat.h"
  #include "signal.h"
  
  #define MAGIC_NUMBER	0177545

--- 11,19 -----
   *	  p: print named files
   */
  
! #include "sys/types.h"
! #include "sys/stat.h"
! #include "fcntl.h"
  #include "signal.h"
  
  #define MAGIC_NUMBER	0177545
***************
*** 52,58
  #define NIL_MEM		((MEMBER *) 0)
  #define NIL_LONG	((long *) 0)
  
! #define IO_SIZE		(10 * 1024)
  #define BLOCK_SIZE	1024
  
  #define flush()		print(NIL_PTR)

--- 54,60 -----
  #define NIL_MEM		((MEMBER *) 0)
  #define NIL_LONG	((long *) 0)
  
! #define IO_SIZE		(4 * 1024)
  #define BLOCK_SIZE	1024
  
  #define flush()		print(NIL_PTR)
***************
*** 84,89
  BOOL quit;
  char *str1, *str2;
  {
    write(2, str1, strlen(str1));
    if (str2 != NIL_PTR)
  	write(2, str2, strlen(str2));

--- 86,92 -----
  BOOL quit;
  char *str1, *str2;
  {
+   perror("ar");
    write(2, str1, strlen(str1));
    if (str2 != NIL_PTR)
  	write(2, str2, strlen(str2));
***************
*** 129,135
  	return fd;
    }
  
!   if ((fd = open(name, mode)) < 0) {
  	if (mode == APPEND) {
  		(void) close(open_archive(name, CREATE));
  		error(FALSE, "ar: creating ", name);

--- 132,138 -----
  	return fd;
    }
  
!   if ((fd = open(name, mode|O_BINARY)) < 0) {
  	if (mode == APPEND) {
  		(void) close(open_archive(name, CREATE|O_BINARY));
  		error(FALSE, "ar: creating ", name);
***************
*** 131,137
  
    if ((fd = open(name, mode)) < 0) {
  	if (mode == APPEND) {
! 		(void) close(open_archive(name, CREATE));
  		error(FALSE, "ar: creating ", name);
  		return open_archive(name, APPEND);
  	}

--- 134,140 -----
  
    if ((fd = open(name, mode|O_BINARY)) < 0) {
  	if (mode == APPEND) {
! 		(void) close(open_archive(name, CREATE|O_BINARY));
  		error(FALSE, "ar: creating ", name);
  		return open_archive(name, APPEND|O_BINARY);
  	}
***************
*** 133,139
  	if (mode == APPEND) {
  		(void) close(open_archive(name, CREATE));
  		error(FALSE, "ar: creating ", name);
! 		return open_archive(name, APPEND);
  	}
  	error(TRUE, "Cannot open ", name);
    }

--- 136,142 -----
  	if (mode == APPEND) {
  		(void) close(open_archive(name, CREATE|O_BINARY));
  		error(FALSE, "ar: creating ", name);
! 		return open_archive(name, APPEND|O_BINARY);
  	}
  	error(TRUE, "Cannot open ", name);
    }
***************
*** 437,446
  	mode_buf[i * 3 + 2] = (tmp & S_IEXEC) ? 'x' : '-';
  	tmp <<= 3;
    }
-   if (mode & S_ISUID)
- 	mode_buf[2] = 's';
-   if (mode & S_ISGID)
- 	mode_buf[5] = 's';
    print(mode_buf);
  }
  

--- 440,445 -----
  	mode_buf[i * 3 + 2] = (tmp & S_IEXEC) ? 'x' : '-';
  	tmp <<= 3;
    }
    print(mode_buf);
  }
  
------------------------------------------------------------
*** build.c	Sat Aug  1 13:37:43 1987
--- ../../dos/tools/build.c	Sat Aug  1 13:32:32 1987
***************
*** 1,3
  /* This program takes the previously compiled and linked pieces of the
   * operating system, and puts them together to build a boot diskette.
   * The files are read and put on the boot diskette in this order:

--- 1,5 -----
+ #define C_DISKIO	/* use JER's diskio for MSC */
+ 
  /* This program takes the previously compiled and linked pieces of the
   * operating system, and puts them together to build a boot diskette.
   * The files are read and put on the boot diskette in this order:
***************
*** 41,46
   * to get the resulting image onto the file "image".
   */
  
  
  #define PROGRAMS 5              /* kernel + mm + fs + init + fsck = 5 */
  #define PROG_ORG 1536           /* where does kernel begin in abs mem */

--- 43,53 -----
   * to get the resulting image onto the file "image".
   */
  
+ #ifdef MSDOS
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <dos.h>
+ #endif
  
  #define PROGRAMS 5              /* kernel + mm + fs + init + fsck = 5 */
  #define PROG_ORG 1536           /* where does kernel begin in abs mem */
***************
*** 67,73
  #define SEP_ID_BIT 0x20         /* bit that tells if file is separate I & D */
  
  #ifdef MSDOS
! # define BREAD 4                /* value 0 means ASCII read */
  #else
  # define BREAD 0
  #endif

--- 74,80 -----
  #define SEP_ID_BIT 0x20         /* bit that tells if file is separate I & D */
  
  #ifdef MSDOS
! # define BREAD (O_RDONLY|O_BINARY)                /* value 0 means ASCII read */
  #else
  error - not tested for non-dos with this version
  # define BREAD 0
***************
*** 69,74
  #ifdef MSDOS
  # define BREAD 4                /* value 0 means ASCII read */
  #else
  # define BREAD 0
  #endif
  

--- 76,82 -----
  #ifdef MSDOS
  # define BREAD (O_RDONLY|O_BINARY)                /* value 0 means ASCII read */
  #else
+ error - not tested for non-dos with this version
  # define BREAD 0
  #endif
  
***************
*** 114,121
    printf("Operating system size  %29ld     %5lx\n", cum_size, cum_size);
    printf("\nTotal size including fsck is %ld.\n", all_size);
  #else
!   printf("Operating system size  %29D     %5X\n", cum_size, cum_size);
!   printf("\nTotal size including fsck is %D.\n", all_size);
  #endif
  
    /* Make the three patches to the output file or diskette. */

--- 122,129 -----
    printf("Operating system size  %29ld     %5lx\n", cum_size, cum_size);
    printf("\nTotal size including fsck is %ld.\n", all_size);
  #else
!   printf("Operating system size  %29ld     %5lx\n", cum_size, cum_size);
!   printf("\nTotal size including fsck is %ld.\n", all_size);
  #endif
  
    /* Make the three patches to the output file or diskette. */
***************
*** 166,172
    unsigned text_bytes, data_bytes, bss_bytes, tot_bytes, rest, filler;
    unsigned left_to_read;
    char inbuf[READ_UNIT];
!   
    if ( (fd = open(file_name, BREAD)) < 0) pexit("can't open ", file_name);
  
    /* Read the header to see how big the segments are. */

--- 174,180 -----
    unsigned text_bytes, data_bytes, bss_bytes, tot_bytes, rest, filler;
    unsigned left_to_read;
    char inbuf[READ_UNIT];
! 
    if ( (fd = open(file_name, BREAD)) < 0) pexit("can't open ", file_name);
  
    /* Read the header to see how big the segments are. */
***************
*** 192,198
    sizes[num].sep_id    = sepid;
  
    /* Print a message giving the program name and size, except for fsck. */
!   if (num < FSCK) { 
          printf("%s  text=%5u  data=%5u  bss=%5u  tot=%5u  hex=%4x  %s\n",
                  name[num], text_bytes, data_bytes, bss_bytes, tot_bytes,
                  tot_bytes, (sizes[num].sep_id ? "Separate I & D" : ""));

--- 200,207 -----
    sizes[num].sep_id    = sepid;
  
    /* Print a message giving the program name and size, except for fsck. */
!   if (num < FSCK) 
!   { 
          printf("%s  text=%5u  data=%5u  bss=%5u  tot=%5u  hex=%4x  %s\n",
                  name[num], text_bytes, data_bytes, bss_bytes, tot_bytes,
                  tot_bytes, (sizes[num].sep_id ? "Separate I & D" : ""));
***************
*** 374,379
    data_offset = 512L + (long)sizes[KERN].text_size;    /* start of kernel data */
    i = (get_byte(data_offset+1L) << 8) + get_byte(data_offset);
    if (i != KERNEL_D_MAGIC)  {
  	pexit("kernel data space: no magic #","");
    }
    

--- 383,389 -----
    data_offset = 512L + (long)sizes[KERN].text_size;    /* start of kernel data */
    i = (get_byte(data_offset+1L) << 8) + get_byte(data_offset);
    if (i != KERNEL_D_MAGIC)  {
+ 	printf("Magic number in kernel is %x: should be %x\n",i,KERNEL_D_MAGIC);
  	pexit("kernel data space: no magic #","");
    }
    
***************
*** 399,404
          ds = PROG_ORG >> CLICK_SHIFT;   /* combined I & D space */
    else
          ds = (PROG_ORG + sizes[KERN].text_size) >> CLICK_SHIFT; /* separate */
    put_byte(512L + DS_OFFSET, ds & 0377);
    put_byte(512L + DS_OFFSET + 1L, (ds>>8) & 0377);
  }

--- 409,415 -----
          ds = PROG_ORG >> CLICK_SHIFT;   /* combined I & D space */
    else
          ds = (PROG_ORG + sizes[KERN].text_size) >> CLICK_SHIFT; /* separate */
+   printf("Kernel DS = %x\n", ds);
    put_byte(512L + DS_OFFSET, ds & 0377);
    put_byte(512L + DS_OFFSET + 1L, (ds>>8) & 0377);
  }
***************
*** 546,551
       buff = buff1;
  }
  
  
  read_block (blocknr,user)
  int blocknr;

--- 557,563 -----
       buff = buff1;
  }
  
+ #ifdef C_DISKIO
  
  int DMAoverrun(buff1)
  char *buff1;
***************
*** 547,552
  }
  
  
  read_block (blocknr,user)
  int blocknr;
  char user[SECTOR_SIZE];

--- 559,626 -----
  
  #ifdef C_DISKIO
  
+ int DMAoverrun(buff1)
+ char *buff1;
+ {
+ int i;
+ 
+ 	i = (int)buff1;
+ 	return(i > i + SECTOR_SIZE);
+ }
+ 
+ int
+ absio(fn, drive, blocknr, buff)
+ int fn;
+ int drive;
+ int blocknr;
+ char *buff;
+ {
+ union REGS iregs;
+ union REGS oregs;
+ int track;
+ 
+ 	iregs.h.ah = fn;
+ 	iregs.h.dl = drive;
+ 	track = blocknr / 9;
+ 	iregs.h.dh = track & 1;
+ 	iregs.h.ch = track >> 1;
+ 	iregs.h.cl = (blocknr % 9) + 1;
+ 	iregs.h.al = 1;
+ 	iregs.x.bx = (int)buff;
+ 
+ 	int86(0x13, &iregs, &oregs);
+ 
+ 	if (oregs.x.cflag)
+ 	{
+ 		fprintf(stderr, "absio: error %sing drv %c block %d address %x: bios code %x\n",
+ 			fn==2? "read" : "writ", 'A'+drive, blocknr, buff, oregs.h.ah&0xff);
+ 		return(oregs.x.ax);
+ 	}
+ 	else
+ 	{
+ 		return(0);
+ 	}
+ }
+ 
+ int
+ absread(drive, blocknr, buff)
+ int drive;
+ int blocknr;
+ char *buff;
+ {
+ 	return(absio(2, drive, blocknr, buff));
+ }
+ 
+ int
+ abswrite(drive, blocknr, buff)
+ int drive;
+ int blocknr;
+ char *buff;
+ {
+ 	return(absio(3, drive, blocknr, buff));
+ }
+ #endif
+ 
  read_block (blocknr,user)
  int blocknr;
  char user[SECTOR_SIZE];
***************
*** 609,615
    drive = (s[0] & ~32) - 'A';
    if (drive<0 || drive>32) pexit ("no such drive: ",s);
    printf("Put a blank, formatted diskette in drive %s\nHit return when ready",s);
!   gets (kbstr,10);
    puts("");
  }
  

--- 683,689 -----
    drive = (s[0] & ~32) - 'A';
    if (drive<0 || drive>32) pexit ("no such drive: ",s);
    printf("Put a blank, formatted diskette in drive %s\nHit return when ready",s);
!   gets(kbstr);
    puts("");
  }
  
------------------------------------------------------------
*** dos2out.c	Sat Aug  1 13:37:45 1987
--- ../../dos/tools/dos2out.c	Sat Aug  1 13:32:34 1987
***************
*** 97,103
  #define A_WLR(cputype)	((cputype&0x02)!=0)  /* TRUE if words left-to-right */
  
  
! #include "/lib/C86/stdio.h"
  
  
  #define PH_SECTSIZE	512		/* size of a disk-block */

--- 97,104 -----
  #define A_WLR(cputype)	((cputype&0x02)!=0)  /* TRUE if words left-to-right */
  
  
! #include <stdio.h>
! #include <fcntl.h>
  
  
  #define PH_SECTSIZE	512		/* size of a disk-block */
***************
*** 109,116
  unsigned char inbuf2[PH_SECTSIZE];
  unsigned char outbuf[PH_SECTSIZE];
  
! struct a_out_hdr *a_ptr= outbuf;
! struct d_fmt_hdr *d_ptr= inbuf;
  
  
  main (argc,argv)

--- 110,117 -----
  unsigned char inbuf2[PH_SECTSIZE];
  unsigned char outbuf[PH_SECTSIZE];
  
! struct a_out_hdr *a_ptr= (struct a_out_hdr *)outbuf;
! struct d_fmt_hdr *d_ptr= (struct d_fmt_hdr *)inbuf;
  
  
  main (argc,argv)
***************
*** 177,183
      } /* end switch */
  
      /* open & create files */
!     if ((inf=open(in_name,BREAD)) <0) {
         printf ("input file %s not found\n",in_name);
         exit(2);
      }

--- 178,184 -----
      } /* end switch */
  
      /* open & create files */
!     if ((inf=open(in_name,O_RDONLY|O_BINARY)) <0) {
         printf ("input file %s not found\n",in_name);
         exit(2);
      }
***************
*** 207,213
  
  
      /* input file is ok, open output (possibly destroy existing file) */
!     if ((outf=creat(out_name,BWRITE)) <0) {
  	printf ("cannot open output %s\n",out_name);
  	exit(2);
      }

--- 208,214 -----
  
  
      /* input file is ok, open output (possibly destroy existing file) */
!     if ((outf=open(out_name,O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0666)) <0) {
  	printf ("cannot open output %s\n",out_name);
  	exit(2);
      }
***************
*** 237,243
  
      /* reposition file */
      close (inf);
!     inf=open(in_name,BREAD);
      in_cnt=read(inf,inbuf2,PH_SECTSIZE);
  
      /* make a.out header */

--- 238,244 -----
  
      /* reposition file */
      close (inf);
!     inf=open(in_name,O_RDONLY|O_BINARY);
      in_cnt=read(inf,inbuf2,PH_SECTSIZE);
  
      /* make a.out header */
***************
*** 301,306
      close (inf);
      if (delete) unlink (in_name);
      printf("   -done-\n");
  }
  
  

--- 302,308 -----
      close (inf);
      if (delete) unlink (in_name);
      printf("   -done-\n");
+ 	exit(0);
  }
  
  
------------------------------------------------------------
*** fsck.c	Sat Aug  1 13:38:01 1987
--- ../../dos/tools/fsck.c	Sat Aug  1 13:32:45 1987
***************
*** 87,92
  #define isupper(c)	between(c, 'A', 'Z')
  #define toupper(c)	( (c) + 'A' - 'a' )
  
  #define quote(x)	x
  #define nextarg(t)	(*argp.quote(u_)t++)
  

--- 87,93 -----
  #define isupper(c)	between(c, 'A', 'Z')
  #define toupper(c)	( (c) + 'A' - 'a' )
  
+ #ifndef MSDOS	/* actually, if not ANSI C */
  #define quote(x)	x
  #define nextarg(t)	(*argp.quote(u_)t++)
  #else
***************
*** 89,94
  
  #define quote(x)	x
  #define nextarg(t)	(*argp.quote(u_)t++)
  
  #define prn(t,b,s)	{ printnum((long)nextarg(t),b,s,width,pad); width = 0; }
  #define prc(c)		{ width -= printchar(c, mode); }

--- 90,98 -----
  #ifndef MSDOS	/* actually, if not ANSI C */
  #define quote(x)	x
  #define nextarg(t)	(*argp.quote(u_)t++)
+ #else
+ #define nextarg(t)	(*argp.u_##t++)
+ #endif
  
  #define prn(t,b,s)	{ printnum((long)nextarg(t),b,s,width,pad); width = 0; }
  #define prc(c)		{ width -= printchar(c, mode); }
***************
*** 180,186
  
  #ifdef STANDALONE
  extern end;			/* last variable */
! int *brk;			/* the ``break'' (end of data space) */
  #else
  int dev;			/* file descriptor of the device */
  #endif

--- 184,190 -----
  
  #ifdef STANDALONE
  extern end;			/* last variable */
! int *brksa;			/* the ``break'' (end of data space) */
  #else
  int dev;			/* file descriptor of the device */
  #endif
***************
*** 361,367
  	register level;
  
  #ifdef STANDALONE
! 	  brk = &end;
  #endif
  	nregular = ndirectory = nblkspec = ncharspec = nbadinode = 0;
  	for (level = 0; level < NLEVEL; level++)

--- 365,371 -----
  	register level;
  
  #ifdef STANDALONE
! 	  brksa = &end;
  #endif
  	nregular = ndirectory = nblkspec = ncharspec = nbadinode = 0;
  	for (level = 0; level < NLEVEL; level++)
***************
*** 478,486
  #ifdef STANDALONE
  	register *r;
  	
! 	p = (char *) brk;
! 	brk += nelem * ((elsize + sizeof(int) - 1) / sizeof(int));
! 	for (r = (int *) p; r < brk; r++)
  		*r = 0;
  	return(p);
  #else

--- 482,490 -----
  #ifdef STANDALONE
  	register *r;
  	
! 	p = (char *) brksa;
! 	brksa += nelem * ((elsize + sizeof(int) - 1) / sizeof(int));
! 	for (r = (int *) p; r < brksa; r++)
  		*r = 0;
  	return(p);
  #else
***************
*** 1832,1838
  	printf("\n\n\n\n");
  	for (;;) {
  		printf("\nHit key as follows:\n\n");
! 		printf("    =  start MINIX (root file system in drive 0)\n");
  		printf("    f  check the file system (first insert any file system diskette)\n");
  		printf("    l  check and list file system (first insert any file system diskette)\n");
  		printf("    m  make an (empty) file system (first insert blank, formatted diskette)\n");

--- 1836,1843 -----
  	printf("\n\n\n\n");
  	for (;;) {
  		printf("\nHit key as follows:\n\n");
! 		printf("    =  start MINIX (root file system in floppy drive 0)\n");
! 		printf("[1-9]  start MINIX (root file system on /dev/hd[1-9]\n");
  		printf("    f  check the file system (first insert any file system diskette)\n");
  		printf("    l  check and list file system (first insert any file system diskette)\n");
  		printf("    m  make an (empty) file system (first insert blank, formatted diskette)\n");
***************
*** 1881,1887
  			}
  			break;
  			
! 		case '=': return((c >> 8) & 0xFF);
  		default:
  			printf("Illegal command\n");
  			continue;

--- 1886,1902 -----
  			}
  			break;
  			
! 		case '=': 	/* boot from floppy 0 */
! 		case '1':	/* boot from a hard disk partition */
! 		case '2':	/* partitions 0 and 5 are raw and thus */
! 		case '3':	/* are not included in this list. */
! 		case '4':	/* Added 7/29/87 Eric Roskos (JER) */
! 		case '6':
! 		case '7':
! 		case '8':
! 		case '9':
! 			return((c >> 8) & 0xFF);
! 
  		default:
  			printf("Illegal command\n");
  			continue;
------------------------------------------------------------
*** fsck1.asm	Sat Aug  1 13:38:03 1987
--- ../../dos/tools/fsck1.asm	Sat Aug  1 13:32:50 1987
***************
*** 1,7
  title  fsck1  -  additional stuff for fsck
  page,132
  
- 
  INCLUDE ..\lib\prologue.h      
  
  

--- 1,6 -----
  title  fsck1  -  additional stuff for fsck
  page,132
  
  INCLUDE ..\lib\prologue.h      
  
  
***************
*** 10,18
  XTSECTORS  EQU  17
  XTCYLS     EQU  68
  IFDEF STANDALONE
!   PUBLIC $main, @end, edata, exit, kerstack,_prt
!   EXTRN  main:near
!  ;EXTRN  cinit:near, debug:near
  ENDIF
  PUBLIC reset_di, diskio, getc, putc, dmaoverr
  EXTRN cylsiz:word, tracksiz:word, drive:byte

--- 9,17 -----
  XTSECTORS  EQU  17
  XTCYLS     EQU  68
  IFDEF STANDALONE
!   PUBLIC $main, _end, _edata, _exit, _kerstack, _prt
!   EXTRN  _main:near
!  ;EXTRN  _cinit:near, _debug:near
  ENDIF
  PUBLIC _reset_diskette, _diskio, _getc, _putc, _dmaoverrun
  EXTRN _cylsiz:word, _tracksiz:word, _drive:byte
***************
*** 14,21
    EXTRN  main:near
   ;EXTRN  cinit:near, debug:near
  ENDIF
! PUBLIC reset_di, diskio, getc, putc, dmaoverr
! EXTRN cylsiz:word, tracksiz:word, drive:byte
  
  
  ;---------------------------------------+

--- 13,20 -----
    EXTRN  _main:near
   ;EXTRN  _cinit:near, _debug:near
  ENDIF
! PUBLIC _reset_diskette, _diskio, _getc, _putc, _dmaoverrun
! EXTRN _cylsiz:word, _tracksiz:word, _drive:byte
  
  PUBLIC __acrtused
  __acrtused	EQU	9876H
***************
*** 17,22
  PUBLIC reset_di, diskio, getc, putc, dmaoverr
  EXTRN cylsiz:word, tracksiz:word, drive:byte
  
  
  ;---------------------------------------+
  ;               Code                    |

--- 16,23 -----
  PUBLIC _reset_diskette, _diskio, _getc, _putc, _dmaoverrun
  EXTRN _cylsiz:word, _tracksiz:word, _drive:byte
  
+ PUBLIC __acrtused
+ __acrtused	EQU	9876H
  
  ;-------------------------------------------+
  ; DATA - JER - moved here from before stack |
***************
*** 18,23
  EXTRN cylsiz:word, tracksiz:word, drive:byte
  
  
  ;---------------------------------------+
  ;               Code                    |
  ;---------------------------------------+

--- 19,38 -----
  PUBLIC __acrtused
  __acrtused	EQU	9876H
  
+ ;-------------------------------------------+
+ ; DATA - JER - moved here from before stack |
+ ;-------------------------------------------+
+ 
+ _DATA	SEGMENT
+ magic	DW	0ABCDH
+ tmp	DW 0
+ tmp1	DW 0
+ tmp2	DW 0
+ fsckmsg DB "arrived at fsck1",0
+ _DATA	ENDS
+ 
+ 
+ IFDEF STANDALONE
  ;---------------------------------------+
  ;  Set up memory lay-out for standalone |
  ;---------------------------------------+
***************
*** 19,25
  
  
  ;---------------------------------------+
! ;               Code                    |
  ;---------------------------------------+
  ;
  @CODE   SEGMENT

--- 34,70 -----
  
  IFDEF STANDALONE
  ;---------------------------------------+
! ;  Set up memory lay-out for standalone |
! ;---------------------------------------+
! ;
! STACKSIZE EQU 8192
! 
! _DATA	SEGMENT
! _brksa	DW	?
! _DATA	ENDS
! 
! LOWCORE SEGMENT AT 0            ; tell where BIOS-data etc is
! 	ORG 120
! dskbase label word
! LOWCORE ENDS
! 
! MINIX	SEGMENT AT 60h          ; This is where Minix is loaded
! _kernel  label byte		; absolute address 0000:1536d = 0060:0000h
! MINIX	ENDS
! 
! _DATAT  SEGMENT			; DATAT holds nothing. The label tells us
! _edata   label byte              ; where .data ends.
! _DATAT  ENDS
! 
! _DATAU   SEGMENT		; allocate the stack in .bss
! _kerstack DB STACKSIZE dup(?)
! _DATAU   ENDS
! 
! _DATAV  SEGMENT			; DATAV holds nothing. The label tells us
! _end    label byte              ; where .data+.bss ends (first free memory)
! _DATAV  ENDS
! 
! 
  ;---------------------------------------+
  ;               Code                    |
  ;---------------------------------------+
***************
*** 21,26
  ;---------------------------------------+
  ;               Code                    |
  ;---------------------------------------+
  ;
  @CODE   SEGMENT
          assume  cs:@code,ds:dgroup

--- 66,73 -----
  
  
  ;---------------------------------------+
+ ;               Code                    |
+ ;---------------------------------------+
  ;
  _TEXT   SEGMENT
          assume  cs:_text,ds:dgroup
***************
*** 22,29
  ;               Code                    |
  ;---------------------------------------+
  ;
! @CODE   SEGMENT
!         assume  cs:@code,ds:dgroup
  
  IFDEF   STANDALONE
  $main:

--- 69,76 -----
  ;               Code                    |
  ;---------------------------------------+
  ;
! _TEXT   SEGMENT
!         assume  cs:_text,ds:dgroup
  
  IFDEF   STANDALONE
  $main:
***************
*** 29,36
  $main:
  	mov	dx,bx		; bootblok puts # sectors/track in bx
  	xor	ax,ax
!         mov     bx,offset dgroup:edata          ; prepare to clear bss
!         mov     cx,offset dgroup:@end
  	sub	cx,bx
  	sar	cx,1
      st1:mov	[bx],ax		; clear bss

--- 76,83 -----
  $main:
  	mov	dx,bx		; bootblok puts # sectors/track in bx
  	xor	ax,ax
!         mov     bx,offset dgroup:_edata          ; prepare to clear bss
!         mov     cx,offset dgroup:_end
  	sub	cx,bx
  	sar	cx,1
  st1: mov	[bx],ax		; clear bss
***************
*** 33,39
          mov     cx,offset dgroup:@end
  	sub	cx,bx
  	sar	cx,1
!     st1:mov	[bx],ax		; clear bss
  	add	bx,2
  	loop	st1
  

--- 80,86 -----
          mov     cx,offset dgroup:_end
  	sub	cx,bx
  	sar	cx,1
! st1: mov	[bx],ax		; clear bss
  	add	bx,2
  	loop	st1
  
***************
*** 37,43
  	add	bx,2
  	loop	st1
  
! 	mov	dgroup:tracksiz,dx	; dx (was bx) is # sectors/track
  	add	dx,dx
  	mov	dgroup:cylsiz,dx	; # sectors/cylinder
  	mov	sp,offset dgroup:kerstack+STACKSIZE

--- 84,90 -----
  	add	bx,2
  	loop	st1
  
! 	mov	dgroup:_tracksiz,dx	; dx (was bx) is # sectors/track
  	add	dx,dx
  	mov	dgroup:_cylsiz,dx	; # sectors/cylinder
  	mov	sp,offset dgroup:_kerstack+STACKSIZE
***************
*** 39,46
  
  	mov	dgroup:tracksiz,dx	; dx (was bx) is # sectors/track
  	add	dx,dx
! 	mov	dgroup:cylsiz,dx	; # sectors/cylinder
! 	mov	sp,offset dgroup:kerstack+STACKSIZE
  	
  ;	call	cinit
  ;	mov	ax,offset fsckmsg

--- 86,93 -----
  
  	mov	dgroup:_tracksiz,dx	; dx (was bx) is # sectors/track
  	add	dx,dx
! 	mov	dgroup:_cylsiz,dx	; # sectors/cylinder
! 	mov	sp,offset dgroup:_kerstack+STACKSIZE
  	
  
  ;	call	cinit
***************
*** 42,47
  	mov	dgroup:cylsiz,dx	; # sectors/cylinder
  	mov	sp,offset dgroup:kerstack+STACKSIZE
  	
  ;	call	cinit
  ;	mov	ax,offset fsckmsg
  ;	push	ax

--- 89,95 -----
  	mov	dgroup:_cylsiz,dx	; # sectors/cylinder
  	mov	sp,offset dgroup:_kerstack+STACKSIZE
  	
+ 
  ;	call	cinit
  ;	mov	ax,offset fsckmsg
  ;	push	ax
***************
*** 47,54
  ;	push	ax
  ;	call	debug
  ;	pop	ax
! 	
! 	call	main
  	mov	bx,ax		; put scan code for '=' in bx
  	cli
  	mov	dx,60h

--- 95,103 -----
  ;	push	ax
  ;	call	debug
  ;	pop	ax
! 
! 	call	_main
! 
  	mov	bx,ax		; put scan code for '=' in bx
  
  	ifdef	debug
***************
*** 50,55
  	
  	call	main
  	mov	bx,ax		; put scan code for '=' in bx
  	cli
  	mov	dx,60h
  	mov	ds,dx

--- 99,113 -----
  	call	_main
  
  	mov	bx,ax		; put scan code for '=' in bx
+ 
+ 	ifdef	debug
+ 	mov	ax,60H
+ 	mov	es,ax
+ 	mov	ax,word ptr es:4
+ 	call 	prtax
+ 	wto	'= DS word at kernel entry point'
+ 	endif
+ 
  	cli
  	mov	dx,60h
  	mov	ds,dx
***************
*** 55,61
  	mov	ds,dx
  	mov	es,dx
  	mov	ss,dx
!         jmp     far ptr kernel		; direct jmp to kernel & start Minix
          mov     ax,DGROUP               ; Force DOS-relocation (sep I&D)
  
  exit:	mov	bx,dgroup:tracksiz

--- 113,121 -----
  	mov	ds,dx
  	mov	es,dx
  	mov	ss,dx
! 
! 
!         jmp     far ptr _kernel		; direct jmp to kernel & start Minix
          mov     ax,DGROUP               ; Force DOS-relocation (sep I&D)
  
  _exit:	mov	bx,dgroup:_tracksiz
***************
*** 58,64
          jmp     far ptr kernel		; direct jmp to kernel & start Minix
          mov     ax,DGROUP               ; Force DOS-relocation (sep I&D)
  
! exit:	mov	bx,dgroup:tracksiz
  	jmp	$main
  
  

--- 118,124 -----
          jmp     far ptr _kernel		; direct jmp to kernel & start Minix
          mov     ax,DGROUP               ; Force DOS-relocation (sep I&D)
  
! _exit:	mov	bx,dgroup:_tracksiz
  	jmp	$main
  
  
***************
*** 85,90
          int     10h             ; call BIOS VIDEO_IO
          pop     bx              ; restore bx
          jmp     print           ; next character
      
  ENDIF   ; /* STANDALONE */
  

--- 145,210 -----
          int     10h             ; call BIOS VIDEO_IO
          pop     bx              ; restore bx
          jmp     print           ; next character
+ 
+ ;
+ ;	code for debug messages
+ ;
+ 	ifdef	debug
+ ;
+ ; prtnum - print low-order 4 bits of al register in hex
+ ;
+ 
+ prtnum	proc	near
+ 	push	ds
+ 	push	cs
+ 	pop	ds
+ 	push	bx
+ 	mov	bx,offset xltab
+ 	xlatb
+ 	mov	ah,14
+ 	mov	bh,10
+ 	int	10H
+ 	pop	bx
+ 	pop	ds
+ 	ret
+ 
+ xltab	db	'0123456789ABCDEF '
+ prtnum	endp
+ 
+ ;
+ ; prtax - print ax register's contents in hex
+ ;
+ 
+ prtax	proc	near
+ 	push	cx
+ 	push	ax
+ 	mov	al,ah
+ 	mov	cl,4
+ 	shr	al,cl
+ 	call	prtnum
+ 	pop	ax
+ 	push	ax
+ 	mov	al,ah
+ 	and	al,0fH
+ 	call	prtnum
+ 	pop	ax
+ 	push	ax
+ 	mov	cl,4
+ 	shr	al,cl
+ 	call	prtnum
+ 	pop	ax
+ 	push	ax
+ 	and	al,0fH
+ 	call	prtnum
+ 	mov	al,10H		; special value to print a space
+ 	call	prtnum
+ 	pop	ax
+ 	pop	cx
+ 	ret
+ 
+ prtax	endp
+ 
+ 	endif
      
  ENDIF   ; /* STANDALONE */
  
***************
*** 89,95
  ENDIF   ; /* STANDALONE */
  
  
! putc:
          xor     ax,ax
          call    csv
          mov     al,4[bp]        ; al contains char to be printed

--- 209,215 -----
  ENDIF   ; /* STANDALONE */
  
  
! _putc:
          xor     ax,ax
          call    csv
          mov     al,4[bp]        ; al contains char to be printed
***************
*** 100,106
          pop     bp
          jmp     cret
  
! getc:
          xor     ah,ah
          int     16h
          ret

--- 220,226 -----
          pop     bp
          jmp     cret
  
! _getc:
          xor     ah,ah
          int     16h
          ret
***************
*** 105,111
          int     16h
          ret
  
! reset_di:                       ; reset_diskette
          xor     ax,ax
          call    csv
          push    es              ; not preserved

--- 225,231 -----
          int     16h
          ret
  
! _reset_diskette:                       ; reset_diskette
          xor     ax,ax
          call    csv
          push    es              ; not preserved
***************
*** 115,121
  
  ; handle diskio(RW, sector_number, buffer, sector_count) call
  ; Do not issue a BIOS call that crosses a track boundary
! diskio:
  	xor	ax,ax
  	call	csv
  	mov	tmp1,0		; tmp1 = # sectors actually transferred

--- 235,241 -----
  
  ; handle diskio(RW, sector_number, buffer, sector_count) call
  ; Do not issue a BIOS call that crosses a track boundary
! _diskio:
  	xor	ax,ax
  	call	csv
  	mov	tmp1,0		; tmp1 = # sectors actually transferred
***************
*** 123,129
  	mov	tmp2,di		; di = # sectors to transfer
  d0:	mov	ax,6[bp]	; ax = sector number to start at
  	xor	dx,dx		; dx:ax is dividend
! 	div	dgroup:cylsiz	; ax = cylinder, dx = sector within cylinder
  	mov	cl,ah		; cl = hi-order bits of cylinder
  	ror	cl,1		; BIOS expects hi bits in a funny place
  	ror	cl,1		; ditto

--- 243,249 -----
  	mov	tmp2,di		; di = # sectors to transfer
  d0:	mov	ax,6[bp]	; ax = sector number to start at
  	xor	dx,dx		; dx:ax is dividend
! 	div	dgroup:_cylsiz	; ax = cylinder, dx = sector within cylinder
  	mov	cl,ah		; cl = hi-order bits of cylinder
  	ror	cl,1		; BIOS expects hi bits in a funny place
  	ror	cl,1		; ditto
***************
*** 130,136
  	mov	ch,al		; cx = sector # in BIOS format
  	mov	ax,dx		; ax = sector offset within cylinder
  	xor	dx,dx		; dx:ax is dividend
! 	div	dgroup:tracksiz	; ax = head, dx = sector
  	mov	dh,al		; dh = head
  	or	cl,dl		; cl = 2 high-order cyl bits || sector
  	inc	cl		; BIOS counts sectors starting at 1

--- 250,256 -----
  	mov	ch,al		; cx = sector # in BIOS format
  	mov	ax,dx		; ax = sector offset within cylinder
  	xor	dx,dx		; dx:ax is dividend
! 	div	dgroup:_tracksiz	; ax = head, dx = sector
  	mov	dh,al		; dh = head
  	or	cl,dl		; cl = 2 high-order cyl bits || sector
  	inc	cl		; BIOS counts sectors starting at 1
***************
*** 134,140
  	mov	dh,al		; dh = head
  	or	cl,dl		; cl = 2 high-order cyl bits || sector
  	inc	cl		; BIOS counts sectors starting at 1
! 	mov	dl,dgroup:drive	; dl = drive code (0-3 or 0x80 - 0x81)
  	mov	bx,8[bp]	; bx = address of buffer
  	mov	al,cl		; al = sector #
  	add	al,10[bp]	; compute last sector

--- 254,260 -----
  	mov	dh,al		; dh = head
  	or	cl,dl		; cl = 2 high-order cyl bits || sector
  	inc	cl		; BIOS counts sectors starting at 1
! 	mov	dl,dgroup:_drive	; dl = drive code (0-3 or 0x80 - 0x81)
  	mov	bx,8[bp]	; bx = address of buffer
  	mov	al,cl		; al = sector #
  	add	al,10[bp]	; compute last sector
***************
*** 139,145
  	mov	al,cl		; al = sector #
  	add	al,10[bp]	; compute last sector
  	dec	al		; al = last sector to transfer
! 	cmp	al,byte ptr dgroup:tracksiz ; see if last sector is on next track
  	jle	d1		; jump if last sector is on this track
  	mov	word ptr 10[bp],1    ; transfer 1 sector at a time
  d1:	mov	ah,4[bp]	; ah = READING or WRITING

--- 259,265 -----
  	mov	al,cl		; al = sector #
  	add	al,10[bp]	; compute last sector
  	dec	al		; al = last sector to transfer
! 	cmp	al,byte ptr dgroup:_tracksiz ; see if last sector is on next track
  	jle	d1		; jump if last sector is on this track
  	mov	word ptr 10[bp],1    ; transfer 1 sector at a time
  d1:	mov	ah,4[bp]	; ah = READING or WRITING
***************
*** 163,169
  d2:	jmp	cret
  
  
! dmaoverr:                       ; test if &buffer causes a DMA overrun
          push    bp
          mov     bp,sp
          push    bx

--- 283,289 -----
  d2:	jmp	cret
  
  
! _dmaoverrun:                       ; test if &buffer causes a DMA overrun
          push    bp
          mov     bp,sp
          push    bx
***************
*** 200,244
          pop     bp
          ret
  
! 
! @CODE   ENDS
! 
! 
! @DATAI	SEGMENT
! tmp	DW 0
! tmp1	DW 0
! tmp2	DW 0
! fsckmsg DB "arrived at fsck1",0
! @DATAI	ENDS
! 
! 
! IFDEF STANDALONE
! ;---------------------------------------+
! ;  Set up memory lay-out for standalone |
! ;---------------------------------------+
! ;
! STACKSIZE EQU 8192
! 
! LOWCORE SEGMENT AT 0            ; tell where BIOS-data etc is
! 	ORG 120
! dskbase label word
! LOWCORE ENDS
! 
! MINIX	SEGMENT AT 60h          ; This is where Minix is loaded
! kernel  label byte		; absolute address 0000:1536d = 0060:0000h
! MINIX	ENDS
! 
! @DATAT  SEGMENT			; DATAT holds nothing. The label tells us
! edata   label byte              ; where .data ends.
! @DATAT  ENDS
! 
! @DATAU   SEGMENT		; allocate the stack in .bss
! kerstack DB STACKSIZE dup(?)
! @DATAU   ENDS
! 
! @DATAV  SEGMENT			; DATAV holds nothing. The label tells us
! @end    label byte              ; where .data+.bss ends (first free memory)
! @DATAV  ENDS
  
  @STACK  SEGMENT BYTE STACK 'STACK' ; Satisfy DOS-linker
  @STACK  ENDS			   ; (dummy stack-segment)

--- 320,326 -----
          pop     bp
          ret
  
! _TEXT   ENDS
  
  @STACK  SEGMENT BYTE STACK 'STACK' ; Satisfy DOS-linker
  @STACK  ENDS			   ; (dummy stack-segment)

ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	fs/fs
#	fs/_link.bat
#	fs/linklist
# This archive created: Sat Aug  1 14:01:11 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'fs'" '(791 characters)'
if test -f 'fs'
then
	echo shar: will not over-write existing file "'fs'"
else
cat << \SHAR_EOF > 'fs'
#
# Makefile for FS
# By E. Roskos 1987
#

OBJ = cache.obj device.obj filedes.obj inode.obj link.obj main.obj \
misc.obj mount.obj open.obj path.obj pipe.obj protect.obj putc.obj \
read.obj stadir.obj super.obj table.obj time.obj utility.obj write.obj

.c.obj:
	cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c

.asm.obj:
	masm $*,$*,$*;

cache.obj: cache.c
 
device.obj: device.c
 
filedes.obj: filedes.c
 
inode.obj: inode.c
 
link.obj: link.c
 
main.obj: main.c
 
misc.obj: misc.c
 
mount.obj: mount.c
 
open.obj: open.c
 
path.obj: path.c
 
pipe.obj: pipe.c
 
protect.obj: protect.c
 
putc.obj: putc.c
 
read.obj: read.c
 
stadir.obj: stadir.c
 
super.obj: super.c
 
table.obj: table.c
 
time.obj: time.c
 
utility.obj: utility.c
 
write.obj: write.c
 
fs.out:	$(OBJ)
	_link
SHAR_EOF
if test 791 -ne "`wc -c < 'fs'`"
then
	echo shar: error transmitting "'fs'" '(should have been 791 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'_link.bat'" '(109 characters)'
if test -f '_link.bat'
then
	echo shar: will not over-write existing file "'_link.bat'"
else
cat << \SHAR_EOF > '_link.bat'
echo/
echo     Linking file system task
link/m/nod ..\lib\head+ <linklist >fs.lst
..\dos2out -pd fs >>fs.lst
SHAR_EOF
if test 109 -ne "`wc -c < '_link.bat'`"
then
	echo shar: error transmitting "'_link.bat'" '(should have been 109 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'linklist'" '(151 characters)'
if test -f 'linklist'
then
	echo shar: will not over-write existing file "'linklist'"
else
cat << \SHAR_EOF > 'linklist'
main+open+read+write+pipe+device+path+
mount+link+super+inode+cache+filedes+stadir+
protect+time+misc+utility+table+putc
fs
fs
..\lib\minix \lib\libh

SHAR_EOF
if test 151 -ne "`wc -c < 'linklist'`"
then
	echo shar: error transmitting "'linklist'" '(should have been 151 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	kernel/gn_wini.c
#	kernel/kernel
#	kernel/linklist
#	kernel/_link.bat
# This archive created: Sat Aug  1 14:02:09 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'gn_wini.c'" '(11852 characters)'
if test -f 'gn_wini.c'
then
	echo shar: will not over-write existing file "'gn_wini.c'"
else
cat << \SHAR_EOF > 'gn_wini.c'
/* This file contains a driver for "Generic" winchester disks; it uses
 * the ROM BIOS winchester disk routines.
 *
 * It was written by Eric Roskos, based on Adri Koppes's XT_WINI driver.
 *
 * If you use this driver, you have to define GENERIC_FDISK and recompile
 * main.c and klib88.asm, since those files have ifdef's in them for this
 * driver: main.c is changed to not overwrite the BIOS reserved vectors
 * and int 13H, and klib88.asm has C call interfaces to the BIOS.
 *
 * The driver supports two operations: read a block and
 * write a block.  It accepts two messages, one for reading and one for
 * writing, both using message format m2 and with the same parameters:
 *
 *    m_type      DEVICE    PROC_NR     COUNT    POSITION  ADRRESS
 * ----------------------------------------------------------------
 * |  DISK_READ | device  | proc nr |  bytes  |  offset | buf ptr |
 * |------------+---------+---------+---------+---------+---------|
 * | DISK_WRITE | device  | proc nr |  bytes  |  offset | buf ptr |
 * ----------------------------------------------------------------
 *
 * The file contains one entry point:
 *
 *   winchester_task:	main entry when system is brought up
 *
 */

#include "../h/const.h"
#include "../h/type.h"
#include "../h/callnr.h"
#include "../h/com.h"
#include "../h/error.h"
#include "const.h"
#include "type.h"
#include "proc.h"

/*
 * define WN_SAFETY to cause the driver to panic if you try to access any
 * sectors below the start of partition 2 -- this is supposed to prevent an
 * errant program from causing the DOS partition to be overwritten.  It
 * assumes your DOS partition is partition 1 (the first one).
 */
#define WN_SAFETY	/* */

/* Parameters for the disk drive. */
#define SECTOR_SIZE      512	/* physical sector size in bytes */
#define NR_SECTORS      0x11	/* number of sectors per track */

/* Error codes */
#define ERR		  -1	/* general error */

/* Miscellaneous. */
#define MAX_ERRORS         4	/* how often to try rd/wt before quitting */
#define MAX_RESULTS        4	/* max number of bytes controller returns */
#define NR_DEVICES        10	/* maximum number of drives */
#define MAX_WIN_RETRY  10000	/* max # times to try to output to WIN */
#define PART_TABLE     0x1C6	/* IBM partition table starts here in sect 0 */
#define DEV_PER_DRIVE      5	/* hd0 + hd1 + hd2 + hd3 + hd4 = 5 */
#define SAFETY_CONST 0xAAAAAAAAL /* table integrity check */

/* Variables. */
PRIVATE struct wini {		/* main drive struct, one entry per drive */
  int wn_opcode;		/* DISK_READ or DISK_WRITE */
  int wn_procnr;		/* which proc wanted this operation? */
  int wn_drive;			/* drive number addressed */
  int wn_cylinder;		/* cylinder number addressed */
  int wn_sector;		/* sector addressed */
  int wn_head;			/* head number addressed */
  int wn_heads;			/* maximum number of heads */
  long wn_low;			/* lowest cylinder of partition */
  long wn_size;			/* size of partition in blocks */
  int wn_trksize;		/* size of track on this drive */
  int wn_count;			/* byte count */
  vir_bytes wn_address;		/* user virtual address */
  char wn_results[MAX_RESULTS];	/* the controller can give lots of output */
} wini[NR_DEVICES];

PRIVATE int w_need_reset = FALSE;	 /* set to 1 when controller must be reset */
PRIVATE int nr_drives;		 /* Number of drives */

PRIVATE message w_mess;		/* message buffer for in and out */

/* this buffer is sort of a waste of space, I think? */
PRIVATE unsigned char buf[BLOCK_SIZE]; /* Buffer used by the startup routine */

PRIVATE struct param {
	int nr_cyl;		/* Number of cylinders */
	int nr_heads;		/* Number of heads */
	int nr_drives;		/* Number of drives on this drive's ctroller */
	int nr_sectors;		/* number of sectors per track */
} param0, param1;

/*===========================================================================*
 *				winchester_task				     * 
 *===========================================================================*/
PUBLIC winchester_task()
{
/* Main program of the winchester disk driver task. */

  int r, caller, proc_nr;

#ifdef DEBUG
  printf("Winchester task has started\n");
#endif

  /* First initialize the controller */
  init_params();

  /* Here is the main loop of the disk task.  It waits for a message, carries
   * it out, and sends a reply.
   */

  while (TRUE) {
	/* First wait for a request to read or write a disk block. */
	receive(ANY, &w_mess);	/* get a request to do some work */
	if (w_mess.m_source < 0) {
		printf("winchester task got message from %d ", w_mess.m_source);
		continue;
	}
	caller = w_mess.m_source;
	proc_nr = w_mess.PROC_NR;

	/* Now carry out the work. */
	switch(w_mess.m_type) {
	    case DISK_READ:
	    case DISK_WRITE:	r = w_do_rdwt(&w_mess);	break;
	    default:		r = EINVAL;		break;
	}

	/* Finally, prepare and send the reply message. */
	w_mess.m_type = TASK_REPLY;	
	w_mess.REP_PROC_NR = proc_nr;

	w_mess.REP_STATUS = r;	/* # of bytes transferred or error code */
	send(caller, &w_mess);	/* send reply to caller */
  }
}


/*===========================================================================*
 *				w_do_rdwt				     * 
 *===========================================================================*/
PRIVATE int w_do_rdwt(m_ptr)
message *m_ptr;			/* pointer to read or write w_message */
{
/* Carry out a read or write request from the disk. */
  register struct wini *wn;
  int r, device, errors = 0;
  long sector;
  phys_bytes user_phys;
  int sb, ib;
  int fRW;
  int csectors;
  int nr_sectors;
  extern phys_bytes umap();
#ifdef WN_SAFETY
  extern long wn_low_safety, wn_low_xor;
#endif

  /* Decode the w_message parameters. */
  device = m_ptr->DEVICE;
  if (device < 0 || device >= NR_DEVICES)
	return(EIO);
  if (m_ptr->COUNT != BLOCK_SIZE)
	return(EINVAL);
  wn = &wini[device];		/* 'wn' points to entry for this drive */
  wn->wn_drive = device/DEV_PER_DRIVE;	/* save drive number */
  if (wn->wn_drive >= nr_drives)
	return(EIO);
  wn->wn_opcode = m_ptr->m_type;	/* DISK_READ or DISK_WRITE */
  if (m_ptr->POSITION % BLOCK_SIZE != 0)
	return(EINVAL);
  sector = m_ptr->POSITION/SECTOR_SIZE;
  if ((sector+BLOCK_SIZE/SECTOR_SIZE) > wn->wn_size)
	return(EOF);
  sector += wn->wn_low;
  nr_sectors = wn->wn_trksize;

#ifdef WN_SAFETY
  /* try to insure errant program can't destroy another partition */

  if (wn->wn_opcode != DISK_READ) /* allow reads of DOS partition */
  {
    if ((wn_low_safety^SAFETY_CONST) != wn_low_xor)
    {
      printf("safety: %X xor: %X computed xor: %X\n",
	wn_low_safety, wn_low_xor, wn_low_safety^SAFETY_CONST);
      printf("winchester: driver tables appear overwritten\n");
      return(EIO);
    }

    if (sector < wn_low_safety)
    {
      printf("winchester: tried to write sector below safety boundary\n",
		sector);
      return(EIO);
    }
  }
#endif

  wn->wn_cylinder = sector / (wn->wn_heads * nr_sectors);
  wn->wn_sector =  (sector % nr_sectors);
  wn->wn_head = (sector % (wn->wn_heads * nr_sectors) )/nr_sectors;
  wn->wn_count = m_ptr->COUNT;
  wn->wn_address = (vir_bytes) m_ptr->ADDRESS;
  wn->wn_procnr = m_ptr->PROC_NR;

  /* here we compute the values we pass the BIOS */
  user_phys = umap(proc_addr(wn->wn_procnr), D, wn->wn_address, 
		   (vir_bytes)wn->wn_count);
  sb = (user_phys >> 4) & 0xffff;
  ib = user_phys & 0xf;
  fRW = (wn->wn_opcode==DISK_READ)? 0 : 1;
  csectors = wn->wn_count / SECTOR_SIZE;

  /* This loop allows a failed operation to be repeated. */
  while (errors <= MAX_ERRORS) {
	errors++;		/* increment count once per loop cycle */
	if (errors >= MAX_ERRORS)
		return(EIO);

	/* First check to see if a reset is needed. */
	if (w_need_reset) w_reset();

	/* Perform the transfer. */
#ifdef DEBUG
	printf("diskio(%d,%x,%x,%x,%x,%x,%x,%x,%x)\n",
		fRW, wn->wn_cylinder, wn->wn_sector, wn->wn_head,
	  	csectors, wn->wn_drive, sb, ib, wn->wn_trksize);
#endif
	r = diskio(fRW, wn->wn_cylinder, wn->wn_sector, wn->wn_head,
		   csectors, wn->wn_drive, sb, ib, wn->wn_trksize);
	if (r == OK) break;	/* if successful, exit loop */

  }

  if (r!=OK)
  {
	printf("\ngn_wini: hardware error, BIOS code %02x\n", r);
	w_need_reset = TRUE;
  }

  return(r == OK ? BLOCK_SIZE : EIO);
}

#ifdef DEBUG

/* debug code */

diskdebug(ax,bx,cx,dx)
int ax,bx,cx,dx;
{
	printf("BIOS call would have: ax=%04x, bx=%04x, cx=%04x, dx=%04x\n",
		ax,bx,cx,dx);
	return(0);
}

#endif

/*===========================================================================*
 *				w_reset					     * 
 *===========================================================================*/
PRIVATE w_reset()
{
/* Issue a reset to the controller.  This is done after any catastrophe,
 * like the controller refusing to respond.
 */

  return(win_init());
}

/*============================================================================*
 *				init_params				      *
 *============================================================================*/
PRIVATE init_params()
{
/* This routine is called at startup to initialize the partition table,
 * the number of drives and the controller
*/
  unsigned int i, segment, offset;
  phys_bytes address;
  extern phys_bytes umap();
  extern int vec_table[];

  /*
   * Be sure BIOS is all set up before we ask for parameters.  This
   * may not really be necessary; we do it again below.
   */
  win_init();

  /* Copy the parameters to the structures */
  hdisk_params(0, &param0);
  hdisk_params(1, &param1);

  /* Get the number of drives */
  nr_drives = param0.nr_drives;

  /* Set the parameters in the drive structure */
  for (i=0; i<5; i++)
  {
	wini[i].wn_heads = param0.nr_heads;
	wini[i].wn_trksize = param0.nr_sectors;
  }
  wini[0].wn_low = wini[5].wn_low = 0L;
  wini[0].wn_size = (long)((long)param0.nr_cyl * (long)param0.nr_heads * (long)NR_SECTORS);
  for (i=5; i<10; i++)
  {
	wini[i].wn_heads = param1.nr_heads;
	wini[i].wn_trksize = param1.nr_sectors;
  }
  wini[5].wn_size = (long)((long)param1.nr_cyl * (long)param1.nr_heads * (long)NR_SECTORS);


  /* Initialize the controller */
  if ((nr_drives > 0) && (win_init() != OK))
		nr_drives = 0;

  /* Read the partition table for each drive and save them */
  for (i = 0; i < nr_drives; i++) {
	w_mess.DEVICE = i * 5;
	w_mess.POSITION = 0L;
	w_mess.COUNT = BLOCK_SIZE;
	w_mess.ADDRESS = (char *) buf;
	w_mess.PROC_NR = WINCHESTER;
	w_mess.m_type = DISK_READ;
	if (w_do_rdwt(&w_mess) != BLOCK_SIZE)
		panic("Can't read partition table of winchester ", i);
	copy_prt(i * 5);
  }
}

/*============================================================================*
 *				copy_prt				      *
 *============================================================================*/
PRIVATE copy_prt(drive)
int drive;
{
/* This routine copies the partition table for the selected drive to
 * the variables wn_low and wn_size
 */

  register int i, offset;
  struct wini *wn;
  long adjust;
#ifdef WN_SAFETY
  extern long wn_low_safety, wn_low_xor;
#endif

  for (i=0; i<4; i++) {
	adjust = 0;
	wn = &wini[i + drive + 1];
	offset = PART_TABLE + i * 0x10;
	wn->wn_low = *(long *)&buf[offset];
	if ((wn->wn_low % (BLOCK_SIZE/SECTOR_SIZE)) != 0) {
		adjust = wn->wn_low;
		wn->wn_low = (wn->wn_low/(BLOCK_SIZE/SECTOR_SIZE)+1)*(BLOCK_SIZE/SECTOR_SIZE);
		adjust = wn->wn_low - adjust;
	}
	wn->wn_size = *(long *)&buf[offset + sizeof(long)] - adjust;
  }
  sort(&wini[drive + 1]);

#ifdef WN_SAFETY
  wn_low_safety = wini[2].wn_low;
  wn_low_xor = wn_low_safety ^ SAFETY_CONST;
#endif
}

PRIVATE sort(wn)
register struct wini *wn;
{
  register int i,j;

  for (i=0; i<4; i++)
	for (j=0; j<3; j++)
		if ((wn[j].wn_low == 0) && (wn[j+1].wn_low != 0))
			swap(&wn[j], &wn[j+1]);
		else if (wn[j].wn_low > wn[j+1].wn_low && wn[j+1].wn_low != 0)
			swap(&wn[j], &wn[j+1]);
}

PRIVATE swap(first, second)
register struct wini *first, *second;
{
  register struct wini tmp;

  tmp = *first;
  *first = *second;
  *second = tmp;
}
SHAR_EOF
if test 11852 -ne "`wc -c < 'gn_wini.c'`"
then
	echo shar: error transmitting "'gn_wini.c'" '(should have been 11852 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'kernel'" '(657 characters)'
if test -f 'kernel'
then
	echo shar: will not over-write existing file "'kernel'"
else
cat << \SHAR_EOF > 'kernel'

OBJ = at_wini.obj clock.obj dmp.obj floppy.obj klib88.obj main.obj \
	  memory.obj mpx88.obj printer.obj proc.obj system.obj table.obj \
	  tty.obj wini.obj xt_wini.obj gn_wini.obj

.c.obj:
	cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c

.asm.obj:
	masm /DGENERIC_FDISK $*,$*,$*;

at_wini.obj: at_wini.c

clock.obj: clock.c

dmp.obj: dmp.c

floppy.obj: floppy.c

gn_wini.obj: gn_wini.c

main.obj: main.c

memory.obj: memory.c

printer.obj: printer.c

proc.obj: proc.c

system.obj: system.c

table.obj: table.c

tty.obj: tty.c

wini.obj: wini.c

xt_wini.obj: xt_wini.c

klib88.obj: klib88.asm

mpx88.obj: mpx88.asm

kernel.exe: $(OBJ)
	_link
SHAR_EOF
if test 657 -ne "`wc -c < 'kernel'`"
then
	echo shar: error transmitting "'kernel'" '(should have been 657 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'linklist'" '(112 characters)'
if test -f 'linklist'
then
	echo shar: will not over-write existing file "'linklist'"
else
cat << \SHAR_EOF > 'linklist'
main+proc+system+clock+memory+floppy+
gn_wini+tty+printer+table+klib88+dmp
kernel
kernel
..\lib\minix \lib\libh
SHAR_EOF
if test 112 -ne "`wc -c < 'linklist'`"
then
	echo shar: error transmitting "'linklist'" '(should have been 112 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'_link.bat'" '(105 characters)'
if test -f '_link.bat'
then
	echo shar: will not over-write existing file "'_link.bat'"
else
cat << \SHAR_EOF > '_link.bat'
echo/
echo    Linking kernel
link/m/nod mpx88+ < linklist >kernel.lst
..\dos2out -p kernel >> kernel.lst
SHAR_EOF
if test 105 -ne "`wc -c < '_link.bat'`"
then
	echo shar: error transmitting "'_link.bat'" '(should have been 105 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	lib/lib
#	lib/liblist
# This archive created: Sat Aug  1 14:03:26 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'lib'" '(3909 characters)'
if test -f 'lib'
then
	echo shar: will not over-write existing file "'lib'"
else
cat << \SHAR_EOF > 'lib'
#
# Makefile for Minix Library
# Microsoft C 4.0 Compiler
# 1987 Eric Roskos
#

OBJ1 = \
abort.obj abs.obj access.obj alarm.obj atoi.obj atol.obj bcopy.obj \
brk.obj brk2.obj brksize.obj call.obj catchsig.obj chdir.obj chmod.obj \
chown.obj chroot.obj cleanup.obj close.obj creat.obj crtso.obj crypt.obj \
csv.obj ctype.obj doprintf.obj dup.obj dup2.obj end.obj exec.obj 

OBJ2 = \
exit.obj fclose.obj fflush.obj fgets.obj fopen.obj fork.obj fprintf.obj \
fputs.obj fread.obj freopen.obj fseek.obj fstat.obj ftell.obj fwrite.obj \
getc.obj getegid.obj getenv.obj geteuid.obj getgid.obj getgrent.obj  \
getpass.obj getpid.obj getpwent.obj gets.obj getuid.obj getutil.obj 

OBJ3 = \
index.obj ioctl.obj isatty.obj itoa.obj kill.obj \
link.obj lseek.obj malloc.obj message.obj mknod.obj \
mktemp.obj mount.obj open.obj pause.obj perror.obj pipe.obj printdat.obj \
printk.obj prints.obj putc.obj rand.obj read.obj 

OBJ4 = \
regexp.obj regsub.obj rindex.obj scanf.obj sendrec.obj setbuf.obj \
setgid.obj setjmp.obj setuid.obj signal.obj sleep.obj sprintf.obj \
stat.obj stb.obj stderr.obj stime.obj strcat.obj strcmp.obj \
strcpy.obj strlen.obj strncat.obj strncmp.obj strncpy.obj sync.obj 

OBJ5 = \
syslib.obj time.obj times.obj umask.obj umount.obj ungetc.obj \
unlink.obj utime.obj wait.obj write.obj 

# OBJ6 should be head.obj for building the OS, crtso.obj for building
# Minix executables

OBJ6 = head.obj

.c.obj:
	cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c

.asm.obj:
	masm $*;

abort.obj: abort.c

abs.obj: abs.c

access.obj: access.c

alarm.obj: alarm.c

atoi.obj: atoi.c

atol.obj: atol.c

bcopy.obj: bcopy.c

brk.obj: brk.c

brk2.obj: brk2.c

brksize.obj: brksize.asm

call.obj: call.c

catchsig.obj: catchsig.asm

chdir.obj: chdir.c

chmod.obj: chmod.c

chown.obj: chown.c

chroot.obj: chroot.c

cleanup.obj: cleanup.c

close.obj: close.c

creat.obj: creat.c

crtso.obj: crtso.asm

crypt.obj: crypt.c

csv.obj: csv.asm

ctype.obj: ctype.c

doprintf.obj: doprintf.c

dup.obj: dup.c

dup2.obj: dup2.c

end.obj: end.asm

exec.obj: exec.c

exit.obj: exit.c

fclose.obj: fclose.c

fflush.obj: fflush.c

fgets.obj: fgets.c

fopen.obj: fopen.c

fork.obj: fork.c

fprintf.obj: fprintf.c

fputs.obj: fputs.c

fread.obj: fread.c

freopen.obj: freopen.c

fseek.obj: fseek.c

fstat.obj: fstat.c

ftell.obj: ftell.c

fwrite.obj: fwrite.c

getc.obj: getc.c

getegid.obj: getegid.c

getenv.obj: getenv.c

geteuid.obj: geteuid.c

getgid.obj: getgid.c

getgrent.obj: getgrent.c

getpass.obj: getpass.c

getpid.obj: getpid.c

getpwent.obj: getpwent.c

gets.obj: gets.c

getuid.obj: getuid.c

getutil.obj: getutil.asm

head.obj: head.asm

index.obj: index.c

ioctl.obj: ioctl.c

isatty.obj: isatty.c

itoa.obj: itoa.c

kill.obj: kill.c

link.obj: link.c

lseek.obj: lseek.c

malloc.obj: malloc.c

message.obj: message.c

mknod.obj: mknod.c

mktemp.obj: mktemp.c

mount.obj: mount.c

open.obj: open.c

pause.obj: pause.c

perror.obj: perror.c

pipe.obj: pipe.c

printdat.obj: printdat.c

printk.obj: printk.c

prints.obj: prints.c

putc.obj: putc.c

rand.obj: rand.c

read.obj: read.c

regexp.obj: regexp.c

regsub.obj: regsub.c

rindex.obj: rindex.c

scanf.obj: scanf.c

sendrec.obj: sendrec.asm

setbuf.obj: setbuf.c

setgid.obj: setgid.c

setjmp.obj: setjmp.asm

setuid.obj: setuid.c

signal.obj: signal.c

sleep.obj: sleep.c

sprintf.obj: sprintf.c

stat.obj: stat.c

stb.obj: stb.c

stderr.obj: stderr.c

stime.obj: stime.c

strcat.obj: strcat.c

strcmp.obj: strcmp.c

strcpy.obj: strcpy.c

strlen.obj: strlen.c

strncat.obj: strncat.c

strncmp.obj: strncmp.c

strncpy.obj: strncpy.c

sync.obj: sync.c

syslib.obj: syslib.c

time.obj: time.c

times.obj: times.c

umask.obj: umask.c

umount.obj: umount.c

ungetc.obj: ungetc.c

unlink.obj: unlink.c

utime.obj: utime.c

wait.obj: wait.c

write.obj: write.c

minix.lib: $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5) $(OBJ6)
	del minix.lib
	lib @liblist
SHAR_EOF
if test 3909 -ne "`wc -c < 'lib'`"
then
	echo shar: error transmitting "'lib'" '(should have been 3909 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'liblist'" '(1205 characters)'
if test -f 'liblist'
then
	echo shar: will not over-write existing file "'liblist'"
else
cat << \SHAR_EOF > 'liblist'
minix.lib
y
+abort.obj+abs.obj+access.obj+alarm.obj+atoi.obj+atol.obj+bcopy.obj &
+brk.obj+brk2.obj+brksize.obj+call.obj+catchsig.obj+chdir.obj+chmod.obj &
+chown.obj+chroot.obj+cleanup.obj+close.obj+creat.obj+crypt.obj &
+csv.obj+ctype.obj+doprintf.obj+dup.obj+dup2.obj+end.obj+exec.obj &
+exit.obj+fclose.obj+fflush.obj+fgets.obj+fopen.obj+fork.obj+fprintf.obj &
+fputs.obj+fread.obj+freopen.obj+fseek.obj+fstat.obj+ftell.obj+fwrite.obj &
+getc.obj+getegid.obj+getenv.obj+geteuid.obj+getgid.obj+getgrent.obj &
+getpass.obj+getpid.obj+getpwent.obj+gets.obj+getuid.obj+getutil.obj &
+index.obj+ioctl.obj+isatty.obj+itoa.obj+kill.obj &
+link.obj+lseek.obj+malloc.obj+mknod.obj &
+mktemp.obj+mount.obj+open.obj+pause.obj+perror.obj+pipe.obj+printdat.obj &
+printk.obj+prints.obj+putc.obj+rand.obj+read.obj &
+regexp.obj+regsub.obj+rindex.obj+scanf.obj+sendrec.obj+setbuf.obj &
+setgid.obj+setjmp.obj+setuid.obj+signal.obj+sleep.obj+sprintf.obj &
+stat.obj+stb.obj+stderr.obj+stime.obj+strcat.obj+strcmp.obj &
+strcpy.obj+strlen.obj+strncat.obj+strncmp.obj+strncpy.obj+sync.obj &
+syslib.obj+time.obj+times.obj+umask.obj+umount.obj+ungetc.obj &
+unlink.obj+utime.obj+wait.obj+write.obj+message.obj
minix.lst
SHAR_EOF
if test 1205 -ne "`wc -c < 'liblist'`"
then
	echo shar: error transmitting "'liblist'" '(should have been 1205 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	mm/_link.bat
#	mm/linklist
#	mm/mm
# This archive created: Sat Aug  1 14:04:05 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'_link.bat'" '(115 characters)'
if test -f '_link.bat'
then
	echo shar: will not over-write existing file "'_link.bat'"
else
cat << \SHAR_EOF > '_link.bat'
echo    Linking memory manager
link/m/NOD ..\lib\head+ <linklist >link.lst
..\dos2out mm >dos2out.lst >dos2out.lst
SHAR_EOF
if test 115 -ne "`wc -c < '_link.bat'`"
then
	echo shar: error transmitting "'_link.bat'" '(should have been 115 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'linklist'" '(89 characters)'
if test -f 'linklist'
then
	echo shar: will not over-write existing file "'linklist'"
else
cat << \SHAR_EOF > 'linklist'
main+forkexit+break+exec+signal+
getset+alloc+utility+table+putc
mm
mm
..\lib\minix libh
SHAR_EOF
if test 89 -ne "`wc -c < 'linklist'`"
then
	echo shar: error transmitting "'linklist'" '(should have been 89 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'mm'" '(496 characters)'
if test -f 'mm'
then
	echo shar: will not over-write existing file "'mm'"
else
cat << \SHAR_EOF > 'mm'
#
# Makefile for MM
# By E. Roskos 1987
#

OBJ = alloc.obj break.obj exec.obj forkexit.obj getset.obj main.obj \
	  putc.obj signal.obj table.obj utility.obj

.c.obj:
	cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c

.asm.obj:
	masm $*,$*,$*;

alloc.obj: alloc.c
 
break.obj: break.c
 
exec.obj: exec.c
 
forkexit.obj: forkexit.c
 
getset.obj: getset.c
 
main.obj: main.c
 
putc.obj: putc.c
 
signal.obj: signal.c
 
table.obj: table.c
 
utility.obj: utility.c

mm.out: $(OBJ)
	_link
SHAR_EOF
if test 496 -ne "`wc -c < 'mm'`"
then
	echo shar: error transmitting "'mm'" '(should have been 496 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	tools/fsck
#	tools/init
#	tools/bootblok
# This archive created: Sat Aug  1 14:04:34 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'fsck'" '(284 characters)'
if test -f 'fsck'
then
	echo shar: will not over-write existing file "'fsck'"
else
cat << \SHAR_EOF > 'fsck'

OBJ = fsck.obj fsck1.obj

.c.obj:
	cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c

.asm.obj:
	masm $*,$*,$*;

fsck.obj:	fsck.c

fsck1.obj:	fsck1.asm

fsck.exe: $(OBJ)
	link /NOD fsck1+fsck,fsck,,..\lib\minix \lib\libh; >fsck.lst

fsck.out: fsck.exe
	..\dos2out -d fsck
SHAR_EOF
if test 284 -ne "`wc -c < 'fsck'`"
then
	echo shar: error transmitting "'fsck'" '(should have been 284 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'init'" '(285 characters)'
if test -f 'init'
then
	echo shar: will not over-write existing file "'init'"
else
cat << \SHAR_EOF > 'init'

OBJ = init.obj

.c.obj:
	cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c

.asm.obj:
	masm $*,$*,$*;

init.obj: init.c

init.exe: $(OBJ)
	link /NOD ..\lib\head+init+..\lib\message,init,,..\lib\minix \lib\libh; >init.lst

init.out: init.exe
	..\dos2out -pd init >>init.lst
SHAR_EOF
if test 285 -ne "`wc -c < 'init'`"
then
	echo shar: error transmitting "'init'" '(should have been 285 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'bootblok'" '(160 characters)'
if test -f 'bootblok'
then
	echo shar: will not over-write existing file "'bootblok'"
else
cat << \SHAR_EOF > 'bootblok'
bootblok.obj:	bootblok.asm
	masm bootblok,,bootblok;

bootblok.exe:	bootblok.obj
	link bootblok;

bootblok.bin:	bootblok.exe
	exe2bin bootblok.exe bootblok.bin
SHAR_EOF
if test 160 -ne "`wc -c < 'bootblok'`"
then
	echo shar: error transmitting "'bootblok'" '(should have been 160 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)

title klib88
page,132

; This file contains a number of assembly code utility routines	needed by the
; kernel.  They	are:
;
;   phys_copy:	copies data from anywhere to anywhere in memory
;   cp_mess:	copies messages	from source to destination
;   port_out:	outputs	data on	an I/O port
;   port_in:	inputs data from an I/O	port
;   lock:	disable	interrupts
;   unlock:	enable interrupts
;   restore:	restore	interrupts [enable/disabled] as	they were before lock[]
;   build_sig:	build 4	word structure pushed onto stack for signals
;   csv:	procedure prolog to save the registers
;   cret:	procedure epilog to restore the	registers
;   get_chrome:	returns	0 is display is	monochrome, 1 if it is color
;   vid_copy:	copy data to video ram [on color display during	retrace	only]
;   get_byte:	reads a	byte from a user program and returns it	as value

; The following	procedures are defined in this file and	called from outside it.
PUBLIC _phys_copy, _cp_mess, _port_out, _port_in, _lock, _unlock, _restore
PUBLIC _build_sig, _get_chrome, _vid_copy,	_get_byte
PUBLIC _reboot, _wreboot

	ifdef GENERIC_FDISK
PUBLIC _hdisk_params, _diskio, _win_init, _wn_low_safety, _wn_low_xor
	endif

; The following	external procedure is called in	this file.
EXTRN _panic:NEAR

; Variables and	data structures
EXTRN _color:WORD, _cur_proc:WORD, _proc_ptr:WORD,	_splimit:WORD
EXTRN _vid_mask:WORD
PUBLIC _vec_table

INCLUDE	..\lib\prologue.h

;
; Macro to call the Hard Disk BIOS.  This is a macro because int 13 won't
; work with Minix on my BIOS... don't know why... this lets you 
; change it easily.
;
hdcall	macro
	ifdef	ERSATZ_GENERIC
	pushf
	call	dword ptr [disk_rom]
	else
	int	13H
	endif
	endm

_TEXT	SEGMENT
	assume	cs:_text,ds:dgroup

;===========================================================================
;				phys_copy
;===========================================================================
; This routine copies a	block of physical memory.  It is called	by:
;    phys_copy(	(long) source, (long) destination, (long) bytecount)

_phys_copy:
	pushf			; save flags
	cli			; disable interrupts
	push bp			; save the registers
	push ax			; save ax
	push bx			; save bx
	push cx			; save cx
	push dx			; save dx
	push si			; save si
	push di			; save di
	push ds			; save ds
	push es			; save es
	mov bp,sp		; set bp to point to saved es

  L0:	mov ax,28[bp]		; ax = high-order word of 32-bit destination
	mov di,26[bp]		; di = low-order word of 32-bit	destination
	mov cx,4		; start	extracting click number	from dest
  L1:	rcr ax,1		; click	number is destination address /	16
	rcr di,1		; it is	used in	segment	register for copy
	loop L1			; 4 bits of high-order word are	used
	mov es,di		; es = destination click

	mov ax,24[bp]		; ax = high-order word of 32-bit source
	mov si,22[bp]		; si = low-order word of 32-bit	source
	mov cx,4		; start	extracting click number	from source
  L2:	rcr ax,1		; click	number is source address / 16
	rcr si,1		; it is	used in	segment	register for copy
	loop L2			; 4 bits of high-order word are	used
	mov ds,si		; ds = source click

	mov di,26[bp]		; di = low-order word of dest address
	and di,000Fh		; di = offset from paragraph  in es
	mov si,22[bp]		; si = low-order word of source	address
	and si,000Fh		; si = offset from paragraph  in ds

	mov dx,32[bp]		; dx = high-order word of byte count
	mov cx,30[bp]		; cx = low-order word of byte count

	test cx,8000h		; if bytes >= 32768, only do 32768
	jnz L3			; per iteration
	test dx,0FFFFh		; check	high-order 17 bits to see if bytes
	jnz L3			; if bytes >= 32768 then go to L3
	jmp short L4		; if bytes < 32768 then	go to L4
  L3:	mov cx,8000h		; 0x8000 is unsigned 32768
  L4:	mov ax,cx		; save actual count used in ax;	needed later

	test cx,0001h		; should we copy a byte	or a word at a time?
	jz L5			; jump if even
	rep movsb		; copy 1 byte at a time
	jmp short L6		; check	for more bytes

  L5:	shr cx,1		; word copy
	rep movsw		; copy 1 word at a time

  L6:	mov dx,32[bp]		; decr count, incr src & dst, iterate if needed
	mov cx,30[bp]		; dx ||	cx is 32-bit byte count
	xor bx,bx		; bx ||	ax is 32-bit actual count used
	sub cx,ax		; compute bytes	- actual count
	sbb dx,bx		; dx ;;	cx is  bytes not yet processed
	or cx,cx		; see if it is 0
	jnz L7			; if more bytes	then go	to L7
	or dx,dx		; keep testing
	jnz L7			; if loop done,	fall through

	pop es			; restore all the saved	registers
	pop ds			; restore ds
	pop di			; restore di
	pop si			; restore si
	pop dx			; restore dx
	pop cx			; restore cx
	pop bx			; restore bx
	pop ax			; restore ax
	pop bp			; restore bp
	popf			; restore flags
	ret			; return to caller

L7:	mov 32[bp],dx		; store	decremented byte count back in mem
	mov 30[bp],cx		; as a long
	add 26[bp],ax		; increment destination
	adc 28[bp],bx		; carry	from low-order word
	add 22[bp],ax		; increment source
	adc 24[bp],bx		; carry	from low-order word
	jmp L0			; start	next iteration


;===========================================================================
;				cp_mess
;===========================================================================
; This routine is makes	a fast copy of a message from anywhere in the address
; space	to anywhere else.  It also copies the source address provided as a
; parameter to the call	into the first word of the destination message.
; It is	called by:
;    cp_mess[src, src_clicks, src_offset, dst_clicks, dst_offset]
; where	all 5 parameters are shorts [16-bits].
;
; Note that the	message	size, 'Msize' is in WORDS [not bytes] and must be set
; correctly.  Changing the definition of message the type file and not changing
; it here will lead to total disaster.
; This routine destroys	ax.  It	preserves the other registers.

Msize =	12			; size of a message in 16-bit words
_cp_mess:
	push bp			; save bp
	push es			; save es
	push ds			; save ds
	mov bp,sp		; index	off bp because machine can't use sp
	pushf			; save flags
	cli			; disable interrupts
	push cx			; save cx
	push si			; save si
	push di			; save di

	mov ax,8[bp]		; ax = process number of sender
	mov di,16[bp]		; di = offset of destination buffer
	mov es,14[bp]		; es = clicks of destination
	mov si,12[bp]		; si = offset of source	message
	mov ds,10[bp]		; ds = clicks of source	message
	mov es:[di],ax		; copy sender's	process	number to dest message
	add si,2		; don't	copy first word
	add di,2		; don't	copy first word
	mov cx,Msize-1		; remember, first word doesn't count
	rep movsw		; iterate cx times to copy the message

	pop di			; restore di
	pop si			; restore si
	pop cx			; restore cs
	popf			; restore flags
	pop ds			; restore ds
	pop es			; restore es
	pop bp			; restore bp
	ret			; that's all folks!


;===========================================================================
;				port_out
;===========================================================================
; port_out(port, value)	writes 'value' on the I/O port 'port'.

_port_out:
	push bx			; save bx
	mov bx,sp		; index	off bx
	push ax			; save ax
	push dx			; save dx
	mov dx,4[bx]		; dx = port
	mov ax,6[bx]		; ax = value
	out dx,al		; output 1 byte
	pop dx			; restore dx
	pop ax			; restore ax
	pop bx			; restore bx
	ret			; return to caller


;===========================================================================
;				port_in
;===========================================================================
; port_in(port,	&value)	reads from port	'port' and puts	the result in 'value'.
_port_in:
	push bx			; save bx
	mov bx,sp		; index	off bx
	push ax			; save ax
	push dx			; save dx
	mov dx,4[bx]		; dx = port
	in  al,dx		; input	1 byte
	xor ah,ah		; clear	ah
	mov bx,6[bx]		; fetch	address	where byte is to go
	mov [bx],ax		; return byte to caller	in param
	pop dx			; restore dx
	pop ax			; restore ax
	pop bx			; restore bx
	ret			; return to caller


;===========================================================================
;				lock
;===========================================================================
; Disable CPU interrupts.
_lock:
	pushf			; save flags on	stack
	cli			; disable interrupts
	pop dgroup:lockvar		; save flags for possible restoration later
	ret			; return to caller


;===========================================================================
;				unlock
;===========================================================================
; Enable CPU interrupts.
_unlock:
	sti			; enable interrupts
	ret			; return to caller


;===========================================================================
;				restore
;===========================================================================
; Restore enable/disable bit to	the value it had before	last lock.
_restore:
	push dgroup:lockvar		; push flags as	they were before previous lock
	popf			; restore flags
	ret			; return to caller


;===========================================================================
;				build_sig
;===========================================================================
; Build	a structure that is pushed onto	the stack for signals.	It contains
; pc, psw, etc., and is	machine	dependent. The format is the same as generated
; by hardware interrupts, except that after the	"interrupt", the signal	number
; is also pushed.  The signal processing routine within	the user space first
; pops the signal number, to see which function	to call.  Then it calls	the
; function.  Finally, when the function	returns	to the low-level signal
; handling routine, control is passed back to where it was prior to the	signal
; by executing a return-from-interrupt instruction, hence the need for using
; the hardware generated interrupt format on the stack.	 The call is:
;     build_sig(sig_stuff, rp, sig)

; Offsets within proc table
PC    =	24
csreg =	18
PSW   =	28

_build_sig:
	push bp			; save bp
	mov bp,sp		; set bp to sp for accessing params
	push bx			; save bx
	push si			; save si
	mov bx,4[bp]		; bx points to sig_stuff
	mov si,6[bp]		; si points to proc table entry
	mov ax,8[bp]		; ax = signal number
	mov [bx],ax		; put signal number in sig_stuff
	mov ax,PC[si]		; ax = signalled process' PC
	mov 2[bx],ax		; put pc in sig_stuff
	mov ax,csreg[si]	; ax = signalled process' cs
	mov 4[bx],ax		; put cs in sig_stuff
	mov ax,PSW[si]		; ax = signalled process' PSW
	mov 6[bx],ax		; put psw in sig_stuff
	pop si			; restore si
	pop bx			; restore bx
	pop bp			; restore bp
	ret			; return to caller


	ifdef	NEEDCSV
	public csv, cret
;===========================================================================
;		csv & cret  (compiler generated	symbols)
;===========================================================================
; This version of csv replaces the standard one.  It checks for	stack overflow
; within the kernel in a simpler way than is usually done. cret	is standard.
csv	proc	near
	pop bx			; bx = return address
	push bp			; stack	old frame pointer
	mov bp,sp		; set new frame	pointer	to sp
	push di			; save di
	push si			; save si
	sub sp,ax		; ax =	bytes of local variables
	cmp sp,dgroup:_splimit	; has kernel stack grown too large
	jbe csv1		; if sp	is too low, panic
	jmp [bx]		; normal return: copy bx to program counter

csv1:
	mov dgroup:_splimit,0		; prevent call to panic	from aborting in csv
	mov bx,dgroup:_proc_ptr		; update rp->p_splimit
	mov WORD PTR 50[bx],0		; rp->sp_limit = 0
	push dgroup:_cur_proc		; task number
	mov ax,offset dgroup:stkoverrun; stack	overran	the kernel stack area
	push ax				; push first parameter
	call _panic		; call is: panic(stkoverrun, cur_proc)
	jmp csv1		; this should not be necessary

csv	endp


cret	proc	near

	lea	sp,-4[bp]	; set sp to point to saved si
	pop	si		; restore saved	si
	pop	di		; restore saved	di
	pop	bp		; restore bp
	ret			; end of procedure

cret	endp

	endif	; needcsv

;===========================================================================
;				get_chrome
;===========================================================================
; This routine calls the BIOS to find out if the display is monochrome or
; color.  The drivers are different, as	are the	video ram addresses, so	we
; need to know.
_get_chrome:
	int 11h			; call the BIOS	to get equipment type
	and al,30h		; isolate color/mono field
	cmp al,30h		; 0x30 is monochrome
	je getchr1		; if monochrome	then go	to getchr1
	mov ax,1		; color	= 1
	ret			; color	return
getchr1:xor ax,ax		; mono = 0
	ret			; monochrome return


;===========================================================================
;				vid_copy
;===========================================================================
; This routine takes a string of [character, attribute]	pairs and writes them
; onto the screen.  For	a color	display, the writing only takes	places during
; the vertical retrace interval, to avoid displaying garbage on	the screen.
; The call is:
;     vid_copy(buffer, videobase, offset, words)
; where
;     'buffer'	  is a pointer to the (character, attribute) pairs
;     'videobase' is 0xB800 for	color and 0xB000 for monochrome	displays
;     'offset'	  tells	where within video ram to copy the data
;     'words'	  tells	how many words to copy
; if buffer is zero, the fill character	(BLANK)	is used

BLANK =	0700h

_vid_copy:
	push bp			; we need bp to	access the parameters
	mov bp,sp		; set bp to sp for indexing
	push si			; save the registers
	push di			; save di
	push bx			; save bx
	push cx			; save cx
	push dx			; save dx
	push es			; save es
vid0:	mov si,4[bp]		; si = pointer to data to be copied
	mov di,8[bp]		; di = offset within video ram
	and di,dgroup:_vid_mask	; only 4K or 16K counts
	mov cx,10[bp]		; cx = word count for copy loop
	mov dx,03DAh		; prepare to see if color display is retracing

	mov bx,di		; see if copy will run off end of video ram
	add bx,cx		; compute where copy ends
	add bx,cx		; bx = last character copied + 1
	sub bx,dgroup:_vid_mask	; bx = # characters beyond end of video ram
	sub bx,1		; note: dec bx doesn't set flags properly
	jle vid1		; jump if no overrun
	sar bx,1		; bx = # words that don't fit in video ram
	sub cx,bx		; reduce count by overrun
	mov dgroup:tmp,cx		; save actual count used for later

vid1:	test dgroup:_color,1	; skip vertical	retrace	test if	display	is mono
	jz vid4			; if monochrome	then go	to vid.2

;  vid2:in			; with a color display,	you can	only copy to
;	test al,010q		; the video ram	during vertical	retrace, so
;	jnz vid2		; wait for start of retrace period.  Bit 3 of
vid3:   in al,dx		; 0x3DA	is set during retrace.	First wait
	test al,010q		; until	it is off (no retrace),	then wait
	jz vid3			; until	it comes on (start of retrace)

vid4:   pushf			; copying may now start; save the flags
	cli			; interrupts just get in the way: disable them
	mov es,6[bp]		; load es now: int routines may	ruin it

	cmp si,0		; si = 0 means blank the screen
	je vid7			; jmp for blanking
	lock nop		; this is a trick for the IBM PC-simulator only
				; 'lock' indicates a video ram access
	rep movsw		; this is the copy loop

vid5:   popf			; restore flags
	cmp bx,0		; if bx < 0, then no overrun and we are done
	jle vid6		; jump if everything fit
	mov 10[bp],bx		; set up residual count
	mov word ptr 8[bp],0		; JER added size: start copying at base of video ram
	cmp word ptr 4[bp],0		; JER added size: NIL_PTR means store blanks
	je vid0			; go do it
	mov si,dgroup:tmp		; si = count of words copied
	add si,si		; si = count of bytes copied
	add 4[bp],si		; increment buffer pointer
	jmp vid0		; go copy some more

vid6:				; JER - not in original source (vid6 label) - hope it's right
	pop es			; restore registers
	pop dx			; restore dx
	pop cx			; restore cx
	pop bx			; restore bx
	pop di			; restore di
	pop si			; restore si
	pop bp			; restore bp
	ret			; return to caller

vid7:   mov ax,BLANK		; ax = blanking	character
	rep stosw		; blank	the screen
	jmp vid5		; done

;===========================================================================
;				get_byte
;===========================================================================
; This routine is used to fetch	a byte from anywhere in	memory.
; The call is:
;     c	= get_byte(seg,	off)
; where
;     'seg' is the value to put	in es
;     'off' is the offset from the es value
_get_byte:
	push bp			; save bp
	mov bp,sp		; we need to access parameters
	push es			; save es
	mov es,4[bp]		; load es with segment value
	mov bx,6[bp]		; load bx with offset from segment
	mov al,es:[bx]		; al = byte
	xor ah,ah		; ax = byte
	pop es			; restore es
	pop bp			; restore bp
	ret			; return to caller


;===========================================================================
;				reboot & dump
;===========================================================================
; This code reboots the	PC

rb_vect		dw	00000H	; hardware restart address
		dw	0FFFFH

; The following zeros out BIOS RAM (ROS on an IBM :-)) to clear any
; warmstart flags that may be present in a given BIOS.

zros	proc	near

	mov	cx,0100H	; 200H bytes / sizeof(word)
	mov	ax,0		; segment 0 & value to store
	mov	es,ax		; set es to low memory
	mov	di,0400H	; clear addresses 400H-5FFH
	cld			; autoincrement
	rep stosw		; zero out memory
	ret

zros	endp

; Restore the interrupt	vectors	in low core.
_resvec	proc	near

	cld
	mov cx,2*65
	mov si,offset dgroup:_vec_table
	xor di,di
	mov es,di
    rep	movsw
	ret

_resvec	endp

_reboot:
	cli			; disable interrupts
	mov al,20h
	out 20h,al		; re-enable interrupt controller
;;;;;	call _resvec		; restore the vectors in low core
;;;;;	int 19h			; reboot the PC
	call zros		; zero out low memory to force cold restart
	jmp dword ptr rb_vect

_wreboot:
	cli			; disable interrupts
	mov al,20h		; re-enable interrupt controller
	out 20h,al
	call _resvec		; restore the vectors in low core to call BIOS
	xor ax,ax		; wait for character before continuing
	int 16h			; get char
	call zros		; zero out low memory to force cold restart
;;;;;	int 19h			; reboot the PC
	jmp dword ptr rb_vect


	ifdef	GENERIC_FDISK


;===========================================================================
;				diskio - JER (copied from fsck1)
;===========================================================================

; diskio(RW, cyl, sector, head, #sectors, drv, sb, ib, trksiz)
;	 4    6     8      10      12     14   16  18    20
; Do not issue a BIOS call that crosses a track boundary
_diskio:
	push	bp
	mov	bp,sp
	push	si
	push	di
	mov	tmp1,0		; tmp1 = # sectors actually transferred
	mov	di,12[bp]	; di = # sectors to transfer
	mov	tmp2,di		; di = # sectors to transfer
d0:
	mov	ax,6[bp]	; cylinder
	mov	cl,ah		; cl = hi-order bits of cylinder
	ror	cl,1		; BIOS expects hi bits in a funny place
	ror	cl,1		; 
	mov	ch,al		; cx = sector # in BIOS format
	mov	dh,10[bp]	; dh = head
	and	cl,0C0H		; mask off any garbage bits
	or	cl,8[bp]	; cl = sector # in low 6 bits
	inc	cl		; BIOS counts sectors starting at 1
	mov	dl,14[bp]	; dl = drive code (0-3 or 0x80 - 0x81)
	or	dl,80H		; force "hard disk" bit on
	push	es		; set es with sb of buffer
	mov	bx,16[bp]
	mov	es,bx
	mov	bx,18[bp]	; bx = ib of buffer
	mov	ah,4[bp]	; ah = READING or WRITING
	add	ah,2		; BIOS codes are 2 and 3, not 0 and 1
	mov	al,12[bp]	; al = # sectors to transfer
	mov	tmp,ax		; save, al is # sectors to read/write
	hdcall			; call the hard disk BIOS
	pop	es		; restore es saved when setting sb above
;	cmp	ah,0		; ah!=0 means BIOS detected error (no, cy does)
;	jne	d2		; exit with error
	jc	d2fail		; if carry set, error occurred
	mov	ax,tmp		; fetch count of sectors transferred
	xor	ah,ah		; count is in ax
	add	tmp1,ax		; tmp1 accumulates sectors transferred
	mov	si,tmp1		; are we done yet?
	cmp	si,tmp2	
	je	d2ok		; jump if done
	inc	word ptr 8[bp]	; next time around, start 1 sector higher
	add	18[bp],200h	; move up in buffer by 512 bytes (ib 4 bits)
	jmp	d0
d2ok:
	xor	ah,ah		; indicate "read OK" to driver
d2fail:	
	xor	al,al		; move 1-byte BIOS error code into integer
	xchg	ah,al		;    return value for C caller
	pop	di
	pop	si
	pop	bp
	ret

;===========================================================================
;	hdisk_params - JER - get hard disk params (semi) legally
;===========================================================================
; hdisk_params(drive, pparams)
_hdisk_params	proc	near
	push	bp
	mov	bp,sp
	mov	dl,4[bp]	; drive number
	or	dl,80H		; indicate fixed disk
	mov	ah,08H		; request parameters
	push	es
	hdcall			; call the hard disk BIOS
	pop	es
	mov	bx,6[bp]	; near pointer to parameter block
	mov	2[bx],dh	; maximum head number
	mov	byte ptr 3[bx],0 ; 256 head disk?
	inc	word ptr 2[bx] 	; convert to number of heads
	mov	6[bx],cl	; number of sectors
	and	byte ptr 6[bx],3fH ; mask off cyl # bits
	mov	byte ptr 7[bx],0
	rol	cl,1		; get cyl # high order bits
	rol	cl,1
	and	cl,03H
	xchg	cl,ch		; put in proper order
	mov	0[bx],cx	; store in parameter block
	xor	dh,dh
	mov	4[bx],dx	; number of drives
	pop	bp		; done
	ret
_hdisk_params	endp

_win_init	proc	near
	push	bp
	mov	bp,sp
	mov	ah,00H		; BIOS reset
	mov	dl,80H
	push	es
	hdcall			; call the hard disk BIOS
	pop	es
	jc	wi0		; return error if carry set
	mov	ah,11H		; drive recalibrate
	mov	dl,80H
	push	es
	hdcall			; call hard disk BIOS
	pop	es
	jc	wi0		; return error if carry set
	xor	ax,ax		; return "OK"
wi0:	pop	bp
	ret
_win_init	endp


	endif	; GENERIC_FDISK


_TEXT	ENDS



_DATA	SEGMENT
lockvar	   DW	 0		; place	to store flags for lock()/restore()
tmp        DW    0		; count of bytes already copied
tmp1	   DW	 0
tmp2	   DW	 0

	ifdef ERSATZ_GENERIC
;
; The following vector is used to invoke the hard disk BIOS on the hard
; disk controller.  It should be possible to do this via an int 13, but
; so far I haven't gotten it to work... there's some code down in paragraph 70
; of DOS that seems to be causing this strange problem... I have to figure
; this out in detail, it doesn't make sense yet.  ...Now I think I have it...
;
disk_rom   DW	 00897H
	   DW	 0C800H
	endif

;
; The following are used by gn_wini to do an integrity check on the
; partition offsets -- they're here so that an errant program which
; destroys the "wini" table is less likely to destroy these too, although
; there's also a check on the integrity of these constants themselves
; against a constant in the instruction space of the winchester task.
;
_wn_low_safety	dd	0H
_wn_low_xor	dd	0H

;
; Here is where the original interrupt vectors get stored
;
_vec_table   DW	 130 dup(0)	; storage for interrupt	vectors
stkoverrun DB	 "Kernel stack overrun,	task = ",0
_DATA	ENDS

	END	; end of assembly

ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)

Title mpx88
page,132


; This file is part of the lowest layer	of the Minix kernel.  All process
; switching and	message	handling is done here and in file "proc.c".  This file
; is entered on	every transition to the	kernel,	both for sending/receiving
; messages and for all interrupts.  In all cases, the trap or interrupt
; routine first	calls save() to	store the machine state	in the proc table.
; Then the stack is switched to	k_stack.  Finally, the real trap or interrupt
; handler (in C) is called.  When it returns, the interrupt routine jumps to
; restart, to run the process or task whose number is in 'cur_proc'.
;
; The external entry points into this file are:
;   s_call:	process	or task	wants to send or receive a message
;   tty_int:	interrupt routine for each key depression and release
;   lpr_int:	interrupt routine for each line	printer	interrupt
;   disk_int:	disk interrupt routine
;   clock_int:	clock interrupt	routine	[HZ times per second]
;   surprise:	all other interrupts < 16 are vectored here
;   trp:	all traps with vector >= 16 are	vectored here
;   divide:	divide overflow traps are vectored here
;   restart:	start running a	task or	process


; include the following	from const.h:
K_STACK_BYTES	EQU  256
IDLE		EQU -999

; include the following	from ../h/com.h
DISKINT		EQU  1
CLOCK		EQU -3
CLOCK_TICK	EQU  2
FLOPPY		EQU -5
WINI		EQU	-6

; The following keeps MSC's refs to this symbol from pulling in crtso.obj
PUBLIC		__acrtused
__acrtused	EQU	9876H

; The following	procedures are defined in this file and	called from outside it.
PUBLIC $main, _tty_int, _lpr_int,	_clock_int, _disk_int, _wini_int
PUBLIC _s_call, _surprise, _trp, _divide, _restart


; The following	external procedures are	called in this file.
EXTRN _main:NEAR,  _sys_call:NEAR, _intr:NEAR,	_keyboard:NEAR
EXTRN _panic:NEAR, _unexpected_int:NEAR, _trap:NEAR, _div_trap:NEAR, 
EXTRN _pr_char:NEAR

; Variables and	data structures.
PUBLIC _sizes, _brksize, _splimit, _end
EXTRN  _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD
EXTRN  _scan_code:WORD, _k_stack:WORD

; The following	constants are offsets into the proc table.
esreg =	14
dsreg =	16
csreg =	18
ssreg =	20
spreg =	22
PC    =	24
PSW   =	28
SPLIM =	50
OFF   =	18
ROFF  =	12


INCLUDE	..\lib\prologue.h

;===========================================================================
;				data - JER moved here from before stack
;===========================================================================

_DATAB	SEGMENT			; datab	ensures	it is the beginning of all data

_sizes	 DW	526Fh		; this must be the first data entry (magic nr)
	 DW	7 dup(0)	; space	for build table	- total	16b
_splimit	 DW	0		; stack	limit for current task (kernel only)
_bx_save	 DW	0		; storage for bx
_ds_save	 DW	0		; storage for ds
_ret_save DW	0		; storage for return address
_lds_low	 DW	0,0		; storage used for restoring ds:bx
_brksize	 DW	offset dgroup:_END+2	; first	free memory in kernel
_ttyomess DB	"RS232 interrupt",0
_DATAB	ENDS


_DATAV	SEGMENT			; DATAV	holds nothing.
_end	label	byte	; the segment just tells us where
_DATAV	ENDS			; the data+bss ends.


_TEXT	SEGMENT

;===========================================================================
;				Minix
;===========================================================================
$main:
Minix:				; this is the entry point for the Minix	kernel.
	jmp short M0		; skip over the	next word(s)
	ORG 4			; build	writes the ds value at text address 4
ker_ds	DW  dgroup		; this word will contain kernel's ds value
				; and it forces	relocation for dos2out
M0:
 	cli			; disable interrupts
	mov ax,cs		; set up segment registers
	mov ds,ax		; set up ds
	mov ax,ker_ds	; build	has loaded this	word with ds value
	mov ds,ax		; ds now contains proper value
	mov ss,ax		; ss now contains proper value
	mov	es,ax		; JER - set es too

	ifdef	debug
	call	prtax
	endif

	mov dgroup:_scan_code,bx		; save scan code for '=' key from bootstrap
	mov sp,offset dgroup:_k_stack	; set sp to point to the top of	the
	add sp,K_STACK_BYTES		; kernel stack
	wto	'Kernel EP: stack now set up'
	call _main		; start	the main program of Minix
	wto	'Fatal: kernel _main returned'

     M1:jmp M1			; this should never be executed


;===========================================================================
;				s_call
;===========================================================================
_s_call:				; System calls are vectored here.
	call _save		; save the machine state
	mov bp,dgroup:_proc_ptr	; use bp to access sys call parameters
	push 2[bp]		; push(pointer to user message)	(was bx)
	push [bp]		; push(src/dest) (was ax)
	push dgroup:_cur_proc	; push caller
	push 4[bp]		; push(SEND/RECEIVE/BOTH) (was cx)
	call _sys_call		; sys_call(function, caller, src_dest, m_ptr)
	jmp _restart		; jump to code to restart proc/task running


;===========================================================================
;				tty_int
;===========================================================================
_tty_int:			; Interrupt routine for	terminal input.
	call _save		; save the machine state
	call _keyboard		; process a keyboard interrupt
	jmp  _restart		; continue execution


;===========================================================================
;				lpr_int
;===========================================================================
_lpr_int:			; Interrupt routine for	terminal input.
	call _save		; save the machine state
	call _pr_char		; process a line printer interrupt
	jmp  _restart		; continue execution


;===========================================================================
;				disk_int
;===========================================================================
_disk_int:			; Interrupt routine for	the floppy disk.
	call _save			; save the machine state
	mov  dgroup:_int_mess+2,DISKINT	; build	message	for disk task
	mov  ax,offset dgroup:_int_mess	; prepare to call interrupt[FLOPPY, &intmess]
	push ax				; push second parameter
	mov  ax,FLOPPY		; prepare to push first	parameter
	push ax			; push first parameter
	call _intr		; this is the call
	jmp  _restart		; continue execution


;*===========================================================================*
;*				wini_int				     *
;*===========================================================================*
_wini_int:			; Interrupt routine for the winchester disk.
	call _save		; save the machine state
	mov dgroup:_int_mess+2,DISKINT; build message for winchester task
	mov ax,offset dgroup:_int_mess	; prepare to call interrupt(WINI, &intmess)
	push ax			; push second parameter
	mov ax,WINI		; prepare to push first parameter
	push ax			; push first parameter
	call _intr		; this is the call
	jmp _restart		; continue execution


;===========================================================================
;				clock_int
;===========================================================================
_clock_int:			; Interrupt routine for	the clock.
	call _save			; save the machine state
	mov dgroup:_int_mess+2,CLOCK_TICK; build	message	for clock task
	mov ax,offset dgroup:_int_mess	; prepare to call interrupt(CLOCK,&intmess)
	push ax				; push second parameter
	mov  ax,CLOCK		; prepare to push first	parameter
	push ax			; push first parameter
	call _intr		; this is the call
	jmp  _restart		; continue execution


;===========================================================================
;				surprise
;===========================================================================
_surprise:			; This is where	unexpected interrupts come.
	call _save		; save the machine state
	call _unexpected_int		; go panic
	jmp  _restart		; never	executed


;===========================================================================
;				trp
;===========================================================================
_trp:				; This is where	unexpected traps come.
	call _save		; save the machine state
	call _trap		; print	a message
	jmp _restart		; this error is	not fatal


;===========================================================================
;				divide					     
;===========================================================================
_divide:				; This is where divide overflow traps come.
	call _save		; save the machine state
	call _div_trap		; print a message
	jmp _restart		; this error is not fatal


;===========================================================================
;				save
;===========================================================================
_save:				; save the machine state in the	proc table.
	push ds			; stack: psw/cs/pc/ret addr/ds
	push cs			; prepare to restore ds
	pop ds			; ds has now been set to cs
	mov ds,ker_ds		; word 4 in kernel text	space contains ds value
	pop dgroup:_ds_save		; stack: psw/cs/pc/ret addr
	pop dgroup:_ret_save		; stack: psw/cs/pc
	mov dgroup:_bx_save,bx		; save bx for later ; we need a	free register
	mov bx,dgroup:_proc_ptr	; start	save set up; make bx point to save area
	add bx,OFF		; bx points to place to	store cs
	pop PC-OFF[bx]		; store	pc in proc table
	pop csreg-OFF[bx]	; store	cs in proc table
	pop PSW-OFF[bx]		; store	psw
	mov ssreg-OFF[bx],ss	; store	ss
	mov spreg-OFF[bx],sp	; sp as	it was prior to	interrupt
	mov sp,bx		; now use sp to	point into proc	table/task save
	mov bx,ds		; about	to set ss
	mov ss,bx		; set ss
	push dgroup:_ds_save		; start	saving all the registers, sp first
	push es			; save es between sp and bp
	mov es,bx		; es now references kernel memory too
	push bp			; save bp
	push di			; save di
	push si			; save si
	push dx			; save dx
	push cx			; save cx
	push dgroup:_bx_save		; save original	bx
	push ax				    ; all registers now	saved
	mov sp,offset dgroup:_k_stack	    ; temporary	stack for interrupts
	add sp,K_STACK_BYTES		    ; set sp to	top of temporary stack
	mov dgroup:_splimit,offset dgroup:_k_stack   ; limit for	temporary stack
	add dgroup:_splimit,8			    ; splimit checks for stack overflow
	mov ax,dgroup:_ret_save		; ax = address to return to
	jmp ax			; return to caller; Note: sp points to saved ax


;===========================================================================
;				restart
;===========================================================================
_restart:			; This routine sets up and runs	a proc or task.
	cmp dgroup:_cur_proc,IDLE; restart user; if cur_proc = IDLE, go	idle
	je _idle		; no user is runnable, jump to idle routine
	cli			; disable interrupts
	mov sp,dgroup:_proc_ptr	; return to user, fetch	regs from proc table
	pop ax			; start	restoring registers
	pop bx			; restore bx
	pop cx			; restore cx
	pop dx			; restore dx
	pop si			; restore si
	pop di			; restore di
	mov dgroup:_lds_low,bx		; lds_low contains bx
	mov bx,sp		; bx points to saved bp	register
	mov bp,SPLIM-ROFF[bx]	; splimit = p_splimit
	mov dgroup:_splimit,bp		; ditto
	mov bp,dsreg-ROFF[bx]	; bp = ds
	mov dgroup:_lds_low+2,bp	; lds_low+2 contains ds
	pop bp			; restore bp
	pop es			; restore es
	mov sp,spreg-ROFF[bx]	; restore sp
	mov ss,ssreg-ROFF[bx]	; restore ss using the value of	ds
	push PSW-ROFF[bx]	; push psw (flags)
	push csreg-ROFF[bx]	; push cs
	push PC-ROFF[bx]	; push pc
	lds  bx,DWORD PTR dgroup:_lds_low   ; restore ds and bx	in one fell swoop
	iret			; return to user or task

;===========================================================================
;				idle
;===========================================================================
_idle:				; executed when	there is no work
	sti			; enable interrupts
L3:	wait			; just idle while waiting for interrupt
	jmp L3			; loop until interrupt

;===========================================================================
;				print - JER - print a debug message
;===========================================================================

	ifdef debug

print	proc                    ; print string (bx), ax destroyed
        mov     al,[bx]         ; al contains char to be printed
        test    al,al           ; null char?
        jne     prt1            ; no
        ret                     ; else return
prt1:   mov     ah,14           ; 14 = print char
        inc     bx              ; increment string pointer
        push    bx              ; save bx
        mov     bl,1            ; foreground color
	xor	bh,bh		; page 0
        int     10h             ; call BIOS VIDEO_IO
        pop     bx              ; restore bx
        jmp     print           ; next character
print	endp

;
; prtnum - print low-order 4 bits of al register in hex
;

prtnum	proc	near
	push	ds
	push	cs
	pop	ds
	push	bx
	mov	bx,offset xltab
	xlatb
	mov	ah,14
	mov	bh,10
	int	10H
	pop	bx
	pop	ds
	ret

xltab	db	'0123456789ABCDEF '
prtnum	endp

;
; prtax - print ax register's contents in hex
;

prtax	proc	near
	push	cx
	push	ax
	mov	al,ah
	mov	cl,4
	shr	al,cl
	call	prtnum
	pop	ax
	push	ax
	mov	al,ah
	and	al,0fH
	call	prtnum
	pop	ax
	push	ax
	mov	cl,4
	shr	al,cl
	call	prtnum
	pop	ax
	push	ax
	and	al,0fH
	call	prtnum
	mov	al,10H		; special value to print a space
	call	prtnum
	pop	ax
	pop	cx
	ret

prtax	endp

	endif
    


_TEXT	ENDS

@STACK	SEGMENT	PARA STACK 'STACK'	; Satisfy DOS-linker (dummy stack)
@STACK	ENDS

	END	; end of assembly-file