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