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 0
MEYER%DEARN.BITNET@wiscvm.wisc.edu (Udo Meyer) (08/03/87)
The mail file limit of the DEARN LISTSERV machine is currently set to 2000 lines. This mail and some of the previous on MINIX-L have therefore not been distributed to the subscribers at DEARN. Happy EARNing...Udo Meyer, EARN Coordinator Germany