ericr@ipmoea.UUCP (Eric Roskos) (08/09/87)
I've received a lot of requests, so I will post the changes I made to Minix thus far, including those to make it compile with MSC, over the next few days. However, before you start putting these into your sources, please be sure you want to do this. There are a lot of changes here; about 40 files worth. There are 3 different changes included here, because they were all changes I felt were necessary before I could start using Minix on my machine. The three changes are: 1) A temporary "generic winchester" driver which can be used to get Minix running until you write a driver for your disk controller (or can afford to buy a new controller); 2) A change that causes Minix to be loaded from floppy, as before, but then lets you select whether the root filesystem should be on RAM disk or a hard disk partition; and 3) The changes to compile with MSC. What this means depends on how you see Minix. If you just want to use Minix to run programs from the Usenet, etc., you probably should not put these changes in. I say this because if you make a lot of changes to the OS, don't understand the changes, and would rather not be doing programming in the OS internals anyway, this is likely to be too difficult. You should also not put these changes in if you don't need them: if Minix already runs fine on your machine, you already have what I had to build to get where I am now, so you really don't need these changes. In the first file (1 of 12), containing the Kernel changes, I've put in comments explaining why I made some of the more obscure ones; hopefully this will make the reasons for the changes more clear. I'll post the changes in the following 12 messages; I'll try to put a short explanation in front of each. There are two types of files: "diff" files showing changes, and "shar" files containing DOS Makefiles, etc. I'll post the "diff" files first. -- Eric Roskos
ericr@ipmoea.UUCP (Eric Roskos) (08/09/87)
This is the largest of the changes. I've interspersed comments on the changes in the diff list, preceeded by ">>>>". (Don't use "patch" -- see intro.) After this, everything else will look trivial, so I posted it first to get it out of the way. Directory: /usr2/ericr/minix/minix/kernel ------------------------------------------------------------ *** const.h Sat Aug 1 13:37:11 1987 --- ../../dos/kernel/const.h Sat Aug 1 13:31:25 1987 *************** *** 49,51 #define USER_Q 2 /* ready users are scheduled via queue 2 */ #define printf printk /* the kernel really uses printk, not printf */ --- 49,52 ----- #define USER_Q 2 /* ready users are scheduled via queue 2 */ #define printf printk /* the kernel really uses printk, not printf */ + #define interrupt intr ------------------------------------------------------------ *** klib88.asm Sat Aug 1 13:36:59 1987 --- ../../dos/kernel/klib88.asm Sat Aug 1 13:31:10 1987 *************** *** 19,27 ; get_byte: reads a byte from a user program and returns it as value ; The following procedures are defined in this file and called from outside it. ! PUBLIC phys_cop, cp_mess, port_out, port_in, lock, unlock, restore ! PUBLIC build_si, csv, cret, get_chro, vid_copy, get_byte ! PUBLIC reboot, wreboot ; The following external procedure is called in this file. EXTRN panic:NEAR --- 19,27 ----- ; get_byte: reads a byte from a user program and returns it as value ; The following procedures are defined in this file and called from outside it. ! PUBLIC _phys_copy, _cp_mess, _port_out, _port_in, _lock, _unlock, _restore ! PUBLIC _build_sig, _get_chrome, _vid_copy, _get_byte ! PUBLIC _reboot, _wreboot ifdef GENERIC_FDISK PUBLIC _hdisk_params, _diskio, _win_init, _wn_low_safety, _wn_low_xor >>>> Here, as a lot of places, an underscore had to be put in front because >>>> that's what MSC does. There is an option to turn the underscores >>>> off, but it also then puts parameters on the stack in a non-C way. >>>> This was a change local to the assembly files, which are always >>>> machine-specific already anyway. If you change the way the stack is >>>> set up, some of the C code may have to be changed. *************** *** 23,28 PUBLIC build_si, csv, cret, get_chro, vid_copy, get_byte PUBLIC reboot, wreboot ; The following external procedure is called in this file. EXTRN panic:NEAR --- 23,32 ----- PUBLIC _build_sig, _get_chrome, _vid_copy, _get_byte PUBLIC _reboot, _wreboot + ifdef GENERIC_FDISK + PUBLIC _hdisk_params, _diskio, _win_init, _wn_low_safety, _wn_low_xor + endif + ; The following external procedure is called in this file. EXTRN _panic:NEAR >>>> These are the public symbols for the generic winchester driver. If >>>> you define GENERIC_FDISK when compiling Minix, you will get the generic >>>> winchester code included. I debated putting this in a separate file, >>>> and decided that this code was general enough to go here for now. *************** *** 24,30 PUBLIC reboot, wreboot ; The following external procedure is called in this file. ! EXTRN panic:NEAR ; Variables and data structures EXTRN color:WORD, cur_proc:WORD, proc_ptr:WORD, splimit:WORD --- 28,34 ----- endif ; The following external procedure is called in this file. ! EXTRN _panic:NEAR ; Variables and data structures EXTRN _color:WORD, _cur_proc:WORD, _proc_ptr:WORD, _splimit:WORD *************** *** 27,34 EXTRN panic:NEAR ; Variables and data structures ! EXTRN color:WORD, cur_proc:WORD, proc_ptr:WORD, splimit:WORD ! PUBLIC vec_tabl INCLUDE ..\lib\prologue.h --- 31,39 ----- EXTRN _panic:NEAR ; Variables and data structures ! EXTRN _color:WORD, _cur_proc:WORD, _proc_ptr:WORD, _splimit:WORD ! EXTRN _vid_mask:WORD ! PUBLIC _vec_table INCLUDE ..\lib\prologue.h >>>> Apparently C86 required the names to be truncated, but MSC didn't, >>>> so that was fixed here as well as putting underscores on. *************** *** 32,37 INCLUDE ..\lib\prologue.h @CODE SEGMENT assume cs:@code,ds:dgroup --- 37,55 ----- INCLUDE ..\lib\prologue.h + ; + ; Macro to call the Hard Disk BIOS. This is a macro because int 13 won't + ; work with Minix on my BIOS... don't know why... this lets you + ; change it easily. + ; + hdcall macro + ifdef ERSATZ_GENERIC + pushf + call dword ptr [disk_rom] + else + int 13H + endif + endm _TEXT SEGMENT assume cs:_text,ds:dgroup >>>> When I was debugging the hard disk BIOS, I had some trouble using int 13 >>>> at first, so for awhile I had a hardcoded, simulated interrupt in this >>>> macro (which you get if you define ERSATZ_GENERIC). But then I finally >>>> got int 13 working. I left this macro this way in case you find you have >>>> some problem with your particular disk controller, but you'll have to >>>> figure out the value for disk_rom, and fill it in, before it will work. *************** *** 33,40 INCLUDE ..\lib\prologue.h ! @CODE SEGMENT ! assume cs:@code,ds:dgroup ;=========================================================================== ; phys_copy --- 51,58 ----- endif endm ! _TEXT SEGMENT ! assume cs:_text,ds:dgroup >>>> A different segment name is produced by MSC for the main code segment... ;=========================================================================== ; phys_copy *************** *** 42,48 ; This routine copies a block of physical memory. It is called by: ; phys_copy( (long) source, (long) destination, (long) bytecount) ! phys_cop: pushf ; save flags cli ; disable interrupts push bp ; save the registers --- 60,66 ----- ; This routine copies a block of physical memory. It is called by: ; phys_copy( (long) source, (long) destination, (long) bytecount) ! _phys_copy: pushf ; save flags cli ; disable interrupts push bp ; save the registers *************** *** 143,149 ; This routine destroys ax. It preserves the other registers. Msize = 12 ; size of a message in 16-bit words ! cp_mess: push bp ; save bp push es ; save es push ds ; save ds --- 161,167 ----- ; This routine destroys ax. It preserves the other registers. Msize = 12 ; size of a message in 16-bit words ! _cp_mess: push bp ; save bp push es ; save es push ds ; save ds *************** *** 180,186 ;=========================================================================== ; port_out(port, value) writes 'value' on the I/O port 'port'. ! port_out: push bx ; save bx mov bx,sp ; index off bx push ax ; save ax --- 198,204 ----- ;=========================================================================== ; port_out(port, value) writes 'value' on the I/O port 'port'. ! _port_out: push bx ; save bx mov bx,sp ; index off bx push ax ; save ax *************** *** 198,204 ; port_in ;=========================================================================== ; port_in(port, &value) reads from port 'port' and puts the result in 'value'. ! port_in: push bx ; save bx mov bx,sp ; index off bx push ax ; save ax --- 216,222 ----- ; port_in ;=========================================================================== ; port_in(port, &value) reads from port 'port' and puts the result in 'value'. ! _port_in: push bx ; save bx mov bx,sp ; index off bx push ax ; save ax *************** *** 218,224 ; lock ;=========================================================================== ; Disable CPU interrupts. ! lock: pushf ; save flags on stack cli ; disable interrupts pop lockvar ; save flags for possible restoration later --- 236,242 ----- ; lock ;=========================================================================== ; Disable CPU interrupts. ! _lock: pushf ; save flags on stack cli ; disable interrupts pop dgroup:lockvar ; save flags for possible restoration later *************** *** 221,227 lock: pushf ; save flags on stack cli ; disable interrupts ! pop lockvar ; save flags for possible restoration later ret ; return to caller --- 239,245 ----- _lock: pushf ; save flags on stack cli ; disable interrupts ! pop dgroup:lockvar ; save flags for possible restoration later ret ; return to caller *************** *** 229,235 ; unlock ;=========================================================================== ; Enable CPU interrupts. ! unlock: sti ; enable interrupts ret ; return to caller --- 247,253 ----- ; unlock ;=========================================================================== ; Enable CPU interrupts. ! _unlock: sti ; enable interrupts ret ; return to caller *************** *** 238,245 ; restore ;=========================================================================== ; Restore enable/disable bit to the value it had before last lock. ! restore: ! push lockvar ; push flags as they were before previous lock popf ; restore flags ret ; return to caller --- 256,263 ----- ; restore ;=========================================================================== ; Restore enable/disable bit to the value it had before last lock. ! _restore: ! push dgroup:lockvar ; push flags as they were before previous lock popf ; restore flags ret ; return to caller *************** *** 263,269 csreg = 18 PSW = 28 ! build_si: push bp ; save bp mov bp,sp ; set bp to sp for accessing params push bx ; save bx --- 281,287 ----- csreg = 18 PSW = 28 ! _build_sig: push bp ; save bp mov bp,sp ; set bp to sp for accessing params push bx ; save bx *************** *** 284,289 ret ; return to caller ;=========================================================================== ; csv & cret (compiler generated symbols) ;=========================================================================== --- 302,309 ----- ret ; return to caller + ifdef NEEDCSV + public csv, cret ;=========================================================================== ; csv & cret (compiler generated symbols) ;=========================================================================== *************** *** 289,295 ;=========================================================================== ; This version of csv replaces the standard one. It checks for stack overflow ; within the kernel in a simpler way than is usually done. cret is standard. ! csv: pop bx ; bx = return address push bp ; stack old frame pointer mov bp,sp ; set new frame pointer to sp --- 309,315 ----- ;=========================================================================== ; This version of csv replaces the standard one. It checks for stack overflow ; within the kernel in a simpler way than is usually done. cret is standard. ! csv proc near pop bx ; bx = return address push bp ; stack old frame pointer mov bp,sp ; set new frame pointer to sp >>>> MSC doesn't use a csv/cret, as far as I know, and didn't need this one; >>>> I didn't use it in any assembly code I added, so I ifdef'ed it out. *************** *** 296,302 push di ; save di push si ; save si sub sp,ax ; ax = bytes of local variables ! cmp sp,dgroup:splimit ; has kernel stack grown too large jbe csv1 ; if sp is too low, panic jmp [bx] ; normal return: copy bx to program counter --- 316,322 ----- push di ; save di push si ; save si sub sp,ax ; ax = bytes of local variables ! cmp sp,dgroup:_splimit ; has kernel stack grown too large jbe csv1 ; if sp is too low, panic jmp [bx] ; normal return: copy bx to program counter *************** *** 301,308 jmp [bx] ; normal return: copy bx to program counter csv1: ! mov dgroup:splimit,0 ; prevent call to panic from aborting in csv ! mov bx,dgroup:proc_ptr ; update rp->p_splimit mov WORD PTR 50[bx],0 ; rp->sp_limit = 0 push dgroup:cur_proc ; task number mov ax,offset dgroup:stkoverrun ; stack overran the kernel stack area --- 321,328 ----- jmp [bx] ; normal return: copy bx to program counter csv1: ! mov dgroup:_splimit,0 ; prevent call to panic from aborting in csv ! mov bx,dgroup:_proc_ptr ; update rp->p_splimit mov WORD PTR 50[bx],0 ; rp->sp_limit = 0 push dgroup:_cur_proc ; task number mov ax,offset dgroup:stkoverrun; stack overran the kernel stack area *************** *** 304,311 mov dgroup:splimit,0 ; prevent call to panic from aborting in csv mov bx,dgroup:proc_ptr ; update rp->p_splimit mov WORD PTR 50[bx],0 ; rp->sp_limit = 0 ! push dgroup:cur_proc ; task number ! mov ax,offset dgroup:stkoverrun ; stack overran the kernel stack area push ax ; push first parameter call panic ; call is: panic(stkoverrun, cur_proc) jmp csv1 ; this should not be necessary --- 324,331 ----- mov dgroup:_splimit,0 ; prevent call to panic from aborting in csv mov bx,dgroup:_proc_ptr ; update rp->p_splimit mov WORD PTR 50[bx],0 ; rp->sp_limit = 0 ! push dgroup:_cur_proc ; task number ! mov ax,offset dgroup:stkoverrun; stack overran the kernel stack area push ax ; push first parameter call _panic ; call is: panic(stkoverrun, cur_proc) jmp csv1 ; this should not be necessary *************** *** 307,313 push dgroup:cur_proc ; task number mov ax,offset dgroup:stkoverrun ; stack overran the kernel stack area push ax ; push first parameter ! call panic ; call is: panic(stkoverrun, cur_proc) jmp csv1 ; this should not be necessary --- 327,333 ----- push dgroup:_cur_proc ; task number mov ax,offset dgroup:stkoverrun; stack overran the kernel stack area push ax ; push first parameter ! call _panic ; call is: panic(stkoverrun, cur_proc) jmp csv1 ; this should not be necessary csv endp *************** *** 310,315 call panic ; call is: panic(stkoverrun, cur_proc) jmp csv1 ; this should not be necessary cret: lea sp,-4[bp] ; set sp to point to saved si --- 330,336 ----- call _panic ; call is: panic(stkoverrun, cur_proc) jmp csv1 ; this should not be necessary + csv endp cret proc near *************** *** 311,317 jmp csv1 ; this should not be necessary ! cret: lea sp,-4[bp] ; set sp to point to saved si pop si ; restore saved si pop di ; restore saved di --- 332,340 ----- csv endp ! ! cret proc near ! lea sp,-4[bp] ; set sp to point to saved si pop si ; restore saved si pop di ; restore saved di >>>> Well, I guess I did use cret for awhile... I changed it to a "proc" >>>> as a matter of coding style back when I was using it... *************** *** 318,323 pop bp ; restore bp ret ; end of procedure ;=========================================================================== ; get_chrome ;=========================================================================== --- 341,350 ----- pop bp ; restore bp ret ; end of procedure + cret endp + + endif ; needcsv + ;=========================================================================== ; get_chrome ;=========================================================================== *************** *** 324,330 ; This routine calls the BIOS to find out if the display is monochrome or ; color. The drivers are different, as are the video ram addresses, so we ; need to know. ! get_chro: int 11h ; call the BIOS to get equipment type and al,30h ; isolate color/mono field cmp al,30h ; 0x30 is monochrome --- 351,357 ----- ; This routine calls the BIOS to find out if the display is monochrome or ; color. The drivers are different, as are the video ram addresses, so we ; need to know. ! _get_chrome: int 11h ; call the BIOS to get equipment type and al,30h ; isolate color/mono field cmp al,30h ; 0x30 is monochrome *************** *** 352,358 BLANK = 0700h ! vid_copy: push bp ; we need bp to access the parameters mov bp,sp ; set bp to sp for indexing push si ; save the registers --- 379,385 ----- BLANK = 0700h ! _vid_copy: push bp ; we need bp to access the parameters mov bp,sp ; set bp to sp for indexing push si ; save the registers *************** *** 363,369 push es ; save es vid0: mov si,4[bp] ; si = pointer to data to be copied mov di,8[bp] ; di = offset within video ram ! and di,dgroup:vid_mask ; only 4K or 16K counts mov cx,10[bp] ; cx = word count for copy loop mov dx,03DAh ; prepare to see if color display is retracing --- 390,396 ----- push es ; save es vid0: mov si,4[bp] ; si = pointer to data to be copied mov di,8[bp] ; di = offset within video ram ! and di,dgroup:_vid_mask ; only 4K or 16K counts mov cx,10[bp] ; cx = word count for copy loop mov dx,03DAh ; prepare to see if color display is retracing *************** *** 370,376 mov bx,di ; see if copy will run off end of video ram add bx,cx ; compute where copy ends add bx,cx ; bx = last character copied + 1 ! sub bx,dgroup:vid_mask ; bx = # characters beyond end of video ram sub bx,1 ; note: dec bx doesn't set flags properly jle vid.1 ; jump if no overrun sar bx,1 ; bx = # words that don't fit in video ram --- 397,403 ----- mov bx,di ; see if copy will run off end of video ram add bx,cx ; compute where copy ends add bx,cx ; bx = last character copied + 1 ! sub bx,dgroup:_vid_mask ; bx = # characters beyond end of video ram sub bx,1 ; note: dec bx doesn't set flags properly jle vid1 ; jump if no overrun sar bx,1 ; bx = # words that don't fit in video ram *************** *** 372,378 add bx,cx ; bx = last character copied + 1 sub bx,dgroup:vid_mask ; bx = # characters beyond end of video ram sub bx,1 ; note: dec bx doesn't set flags properly ! jle vid.1 ; jump if no overrun sar bx,1 ; bx = # words that don't fit in video ram sub cx,bx ; reduce count by overrun mov tmp,cx ; save actual count used for later --- 399,405 ----- add bx,cx ; bx = last character copied + 1 sub bx,dgroup:_vid_mask ; bx = # characters beyond end of video ram sub bx,1 ; note: dec bx doesn't set flags properly ! jle vid1 ; jump if no overrun sar bx,1 ; bx = # words that don't fit in video ram sub cx,bx ; reduce count by overrun mov dgroup:tmp,cx ; save actual count used for later >>>> I'm not entirely sure how this assembled in the original source? *************** *** 375,381 jle vid.1 ; jump if no overrun sar bx,1 ; bx = # words that don't fit in video ram sub cx,bx ; reduce count by overrun ! mov tmp,cx ; save actual count used for later vid1: test dgroup:color,1 ; skip vertical retrace test if display is mono jz vid4 ; if monochrome then go to vid.2 --- 402,408 ----- jle vid1 ; jump if no overrun sar bx,1 ; bx = # words that don't fit in video ram sub cx,bx ; reduce count by overrun ! mov dgroup:tmp,cx ; save actual count used for later vid1: test dgroup:_color,1 ; skip vertical retrace test if display is mono jz vid4 ; if monochrome then go to vid.2 *************** *** 377,383 sub cx,bx ; reduce count by overrun mov tmp,cx ; save actual count used for later ! vid1: test dgroup:color,1 ; skip vertical retrace test if display is mono jz vid4 ; if monochrome then go to vid.2 ; vid2:in ; with a color display, you can only copy to --- 404,410 ----- sub cx,bx ; reduce count by overrun mov dgroup:tmp,cx ; save actual count used for later ! vid1: test dgroup:_color,1 ; skip vertical retrace test if display is mono jz vid4 ; if monochrome then go to vid.2 ; vid2:in ; with a color display, you can only copy to *************** *** 401,408 cmp bx,0 ; if bx < 0, then no overrun and we are done jle vid6 ; jump if everything fit mov 10[bp],bx ; set up residual count ! mov 8[bp],0 ; start copying at base of video ram ! cmp 4[bp],0 ; NIL_PTR means store blanks je vid0 ; go do it mov si,tmp ; si = count of words copied add si,si ; si = count of bytes copied --- 428,435 ----- cmp bx,0 ; if bx < 0, then no overrun and we are done jle vid6 ; jump if everything fit mov 10[bp],bx ; set up residual count ! mov word ptr 8[bp],0 ; JER added size: start copying at base of video ram ! cmp word ptr 4[bp],0 ; JER added size: NIL_PTR means store blanks je vid0 ; go do it mov si,dgroup:tmp ; si = count of words copied add si,si ; si = count of bytes copied >>>> Here and in a number of places, it seems MASM 4.0 is more strict >>>> than the assembler used to assemble the original sources: the dgroup: >>>> prefixes I added were required by MASM 4.0. *************** *** 404,410 mov 8[bp],0 ; start copying at base of video ram cmp 4[bp],0 ; NIL_PTR means store blanks je vid0 ; go do it ! mov si,tmp ; si = count of words copied add si,si ; si = count of bytes copied add 4[bp],si ; increment buffer pointer jmp vid0 ; go copy some more --- 431,437 ----- mov word ptr 8[bp],0 ; JER added size: start copying at base of video ram cmp word ptr 4[bp],0 ; JER added size: NIL_PTR means store blanks je vid0 ; go do it ! mov si,dgroup:tmp ; si = count of words copied add si,si ; si = count of bytes copied add 4[bp],si ; increment buffer pointer jmp vid0 ; go copy some more *************** *** 409,414 add 4[bp],si ; increment buffer pointer jmp vid0 ; go copy some more pop es ; restore registers pop dx ; restore dx pop cx ; restore cx --- 436,442 ----- add 4[bp],si ; increment buffer pointer jmp vid0 ; go copy some more + vid6: ; JER - not in original source (vid6 label) pop es ; restore registers pop dx ; restore dx pop cx ; restore cx *************** *** 431,437 ; where ; 'seg' is the value to put in es ; 'off' is the offset from the es value ! get_byte: push bp ; save bp mov bp,sp ; we need to access parameters push es ; save es --- 459,465 ----- ; where ; 'seg' is the value to put in es ; 'off' is the offset from the es value ! _get_byte: push bp ; save bp mov bp,sp ; we need to access parameters push es ; save es *************** *** 449,454 ;=========================================================================== ; This code reboots the PC reboot: cli ; disable interrupts --- 477,484 ----- ;=========================================================================== ; This code reboots the PC + rb_vect dw 00000H ; hardware restart address + dw 0FFFFH ; The following zeros out BIOS RAM (ROS on an IBM :-)) to clear any ; warmstart flags that may be present in a given BIOS. >>>> This one's highly debatable... on my machine, when you did a ctrl-alt-del >>>> with Minix running, you had to do it once to get DOS booted, then again >>>> to get things reset: because Minix didn't reset the video controller, >>>> and didn't reset the clock, the way DOS expected. I thought a good while >>>> and decided that DOS assumes when it is first loaded that it is starting >>>> on a newly-initialized machine, probably, so the best thing to do for >>>> compatibility with the maximum number of clones was to zero out low >>>> memory so it resembled a freshly-started machine. But on an IBM PC, >>>> this will cause the long-running memory test to occur. You can change >>>> this if you find it works better a different way on your machine, but >>>> it may not work on as many clones; you could try filling low memory with>>>> 1234H and see if that helps... >>>> >>>> wp(boot_dos_on_clone, machine_runs_ok) = low_memory_indeterminate :-) >>>> >>>> (I used zeros because I figured most programmers would say, "the >>>> machine is more likely to have zeros in ram, so that's not a good >>>> number to choose", so there is something less than the 1/65536 probability >>>> of failure if RAM contains zero, under my hypothesis...) *************** *** 450,456 ; This code reboots the PC ! reboot: cli ; disable interrupts mov al,20h out 20h,al ; re-enable interrupt controller --- 480,514 ----- rb_vect dw 00000H ; hardware restart address dw 0FFFFH ! ; The following zeros out BIOS RAM (ROS on an IBM :-)) to clear any ! ; warmstart flags that may be present in a given BIOS. ! ! zros proc near ! ! mov cx,0100H ; 200H bytes / sizeof(word) ! mov ax,0 ; segment 0 & value to store ! mov es,ax ; set es to low memory ! mov di,0400H ; clear addresses 400H-5FFH ! cld ; autoincrement ! rep stosw ; zero out memory ! ret ! ! zros endp ! ! ; Restore the interrupt vectors in low core. ! _resvec proc near ! ! cld ! mov cx,2*65 ! mov si,offset dgroup:_vec_table ! xor di,di ! mov es,di ! rep movsw ! ret ! ! _resvec endp ! ! _reboot: cli ; disable interrupts mov al,20h out 20h,al ; re-enable interrupt controller *************** *** 454,461 cli ; disable interrupts mov al,20h out 20h,al ; re-enable interrupt controller ! call resvec ; restore the vectors in low core ! int 19h ; reboot the PC wreboot: cli ; disable interrupts --- 512,521 ----- cli ; disable interrupts mov al,20h out 20h,al ; re-enable interrupt controller ! ;;;;; call _resvec ; restore the vectors in low core ! ;;;;; int 19h ; reboot the PC ! call zros ; zero out low memory to force cold restart ! jmp dword ptr rb_vect _wreboot: cli ; disable interrupts *************** *** 457,463 call resvec ; restore the vectors in low core int 19h ; reboot the PC ! wreboot: cli ; disable interrupts mov al,20h ; re-enable interrupt controller out 20h,al --- 517,523 ----- call zros ; zero out low memory to force cold restart jmp dword ptr rb_vect ! _wreboot: cli ; disable interrupts mov al,20h ; re-enable interrupt controller out 20h,al *************** *** 461,467 cli ; disable interrupts mov al,20h ; re-enable interrupt controller out 20h,al ! call resvec ; restore the vectors in low core xor ax,ax ; wait for character before continuing int 16h ; get char int 19h ; reboot the PC --- 521,527 ----- cli ; disable interrupts mov al,20h ; re-enable interrupt controller out 20h,al ! call _resvec ; restore the vectors in low core to call BIOS xor ax,ax ; wait for character before continuing int 16h ; get char call zros ; zero out low memory to force cold restart *************** *** 464,470 call resvec ; restore the vectors in low core xor ax,ax ; wait for character before continuing int 16h ; get char ! int 19h ; reboot the PC ; Restore the interrupt vectors in low core. resvec: --- 524,532 ----- call _resvec ; restore the vectors in low core to call BIOS xor ax,ax ; wait for character before continuing int 16h ; get char ! call zros ; zero out low memory to force cold restart ! ;;;;; int 19h ; reboot the PC ! jmp dword ptr rb_vect ifdef GENERIC_FDISK *************** *** 466,479 int 16h ; get char int 19h ; reboot the PC ! ; Restore the interrupt vectors in low core. ! resvec: ! cld ! mov cx,2*65 ! mov si,offset dgroup:vec_tabl ! xor di,di ! mov es,di ! rep movsw ret @CODE ENDS --- 528,594 ----- ;;;;; int 19h ; reboot the PC jmp dword ptr rb_vect >>>> Below are the C interfaces to the BIOS that are used in the generic >>>> disk driver... ! ifdef GENERIC_FDISK ! ! ! ;=========================================================================== ! ; diskio - JER (copied from fsck1) ! ;=========================================================================== ! ! ; diskio(RW, cyl, sector, head, #sectors, drv, sb, ib, trksiz) ! ; 4 6 8 10 12 14 16 18 20 ! ; Do not issue a BIOS call that crosses a track boundary ! _diskio: ! push bp ! mov bp,sp ! push si ! push di ! mov tmp1,0 ; tmp1 = # sectors actually transferred ! mov di,12[bp] ; di = # sectors to transfer ! mov tmp2,di ; di = # sectors to transfer ! d0: ! mov ax,6[bp] ; cylinder ! mov cl,ah ; cl = hi-order bits of cylinder ! ror cl,1 ; BIOS expects hi bits in a funny place ! ror cl,1 ; ! mov ch,al ; cx = sector # in BIOS format ! mov dh,10[bp] ; dh = head ! and cl,0C0H ; mask off any garbage bits ! or cl,8[bp] ; cl = sector # in low 6 bits ! inc cl ; BIOS counts sectors starting at 1 ! mov dl,14[bp] ; dl = drive code (0-3 or 0x80 - 0x81) ! or dl,80H ; force "hard disk" bit on ! push es ; set es with sb of buffer ! mov bx,16[bp] ! mov es,bx ! mov bx,18[bp] ; bx = ib of buffer ! mov ah,4[bp] ; ah = READING or WRITING ! add ah,2 ; BIOS codes are 2 and 3, not 0 and 1 ! mov al,12[bp] ; al = # sectors to transfer ! mov tmp,ax ; save, al is # sectors to read/write ! hdcall ; call the hard disk BIOS ! pop es ; restore es saved when setting sb above ! ; cmp ah,0 ; ah!=0 means BIOS detected error (no, cy does) ! ; jne d2 ; exit with error ! jc d2fail ; if carry set, error occurred ! mov ax,tmp ; fetch count of sectors transferred ! xor ah,ah ; count is in ax ! add tmp1,ax ; tmp1 accumulates sectors transferred ! mov si,tmp1 ; are we done yet? ! cmp si,tmp2 ! je d2ok ; jump if done ! inc word ptr 8[bp] ; next time around, start 1 sector higher ! add 18[bp],200h ; move up in buffer by 512 bytes (ib 4 bits) ! jmp d0 ! d2ok: ! xor ah,ah ; indicate "read OK" to driver ! d2fail: ! xor al,al ; move 1-byte BIOS error code into integer ! xchg ah,al ; return value for C caller ! pop di ! pop si ! pop bp ret ;=========================================================================== >>>> The above is not actually a copy of the fsck1 code the way the comment >>>> says, but it's close. *************** *** 476,482 rep movsw ret ! @CODE ENDS --- 591,626 ----- pop bp ret ! ;=========================================================================== ! ; hdisk_params - JER - get hard disk params more legally ! ;=========================================================================== ! ; hdisk_params(drive, pparams) ! _hdisk_params proc near ! push bp ! mov bp,sp ! mov dl,4[bp] ; drive number ! or dl,80H ; indicate fixed disk ! mov ah,08H ; request parameters ! push es ! hdcall ; call the hard disk BIOS ! pop es ! mov bx,6[bp] ; near pointer to parameter block ! mov 2[bx],dh ; maximum head number ! mov byte ptr 3[bx],0 ; 256 head disk? ! inc word ptr 2[bx] ; convert to number of heads ! mov 6[bx],cl ; number of sectors ! and byte ptr 6[bx],3fH ; mask off cyl # bits ! mov byte ptr 7[bx],0 ! rol cl,1 ; get cyl # high order bits ! rol cl,1 ! and cl,03H ! xchg cl,ch ; put in proper order ! mov 0[bx],cx ; store in parameter block ! xor dh,dh ! mov 4[bx],dx ; number of drives ! pop bp ; done ! ret ! _hdisk_params endp _win_init proc near push bp >>>> The original driver didn't make a BIOS call to do this... it looked >>>> around in the controller's option switches, the hard disk parameter >>>> table (pointed to by a vector in low memory), etc. That's because >>>> the BIOS vectors are patched out at startup; but I reenabled them >>>> if this option (GENERIC_FDISK) is defined, so the BIOS call is >>>> available here. *************** *** 478,483 @CODE ENDS @DATAI SEGMENT --- 622,646 ----- ret _hdisk_params endp + _win_init proc near + push bp + mov bp,sp + mov ah,00H ; BIOS reset + mov dl,80H + push es + hdcall ; call the hard disk BIOS + pop es + jc wi0 ; return error if carry set + mov ah,11H ; drive recalibrate + mov dl,80H + push es + hdcall ; call hard disk BIOS + pop es + jc wi0 ; return error if carry set + xor ax,ax ; return "OK" + wi0: pop bp + ret + _win_init endp endif ; GENERIC_FDISK *************** *** 480,486 ! @DATAI SEGMENT lockvar DW 0 ; place to store flags for lock()/restore() tmp DW 0 ; count of bytes already copied vec_tabl DW 130 dup(0) ; storage for interrupt vectors --- 643,656 ----- _win_init endp ! endif ; GENERIC_FDISK ! ! ! _TEXT ENDS ! ! ! ! _DATA SEGMENT lockvar DW 0 ; place to store flags for lock()/restore() tmp DW 0 ; count of bytes already copied tmp1 DW 0 *************** *** 483,489 @DATAI SEGMENT lockvar DW 0 ; place to store flags for lock()/restore() tmp DW 0 ; count of bytes already copied ! vec_tabl DW 130 dup(0) ; storage for interrupt vectors stkoverrun DB "Kernel stack overrun, task = ",0 @DATAI ENDS --- 653,687 ----- _DATA SEGMENT lockvar DW 0 ; place to store flags for lock()/restore() tmp DW 0 ; count of bytes already copied ! tmp1 DW 0 ! tmp2 DW 0 >>>> These temporaries are used by the _diskio routine... this is not >>>> really so good, since it makes the routine non-reentrant. They should >>>> really be on the stack, but presently I don't think _diskio is >>>> executed by more than one process at once. Still, it's this sort of >>>> thing that will cause you trouble a few years down the road, so this >>>> is one of the things I don't feel good about. I'll probably change it >>>> within a few months, so you may want to do this too...? ! ! ifdef ERSATZ_GENERIC ! ; ! ; The following vector is used to invoke the hard disk BIOS on the hard ! ; disk controller. It should be possible to do this via an int 13, but ! ; for awhile I couldn't get it to work, so I used this. ! ; ! disk_rom DW 00897H ! DW 0C800H ! endif ! ! ; ! ; The following are used by gn_wini to do an integrity check on the ! ; partition offsets -- they're here so that an errant program which ! ; destroys the "wini" table is less likely to destroy these too, although ! ; there's also a check on the integrity of these constants themselves ! ; against a constant in the instruction space of the winchester task. ! ; ! _wn_low_safety dd 0H ! _wn_low_xor dd 0H ! ! ; ! ; Here is where the original interrupt vectors get stored ! ; ! _vec_table DW 130 dup(0) ; storage for interrupt vectors stkoverrun DB "Kernel stack overrun, task = ",0 _DATA ENDS *************** *** 485,491 tmp DW 0 ; count of bytes already copied vec_tabl DW 130 dup(0) ; storage for interrupt vectors stkoverrun DB "Kernel stack overrun, task = ",0 ! @DATAI ENDS END ; end of assembly --- 683,689 ----- ; _vec_table DW 130 dup(0) ; storage for interrupt vectors stkoverrun DB "Kernel stack overrun, task = ",0 ! _DATA ENDS END ; end of assembly ------------------------------------------------------------ *** main.c Sat Aug 1 13:36:50 1987 --- ../../dos/kernel/main.c Sat Aug 1 13:31:02 1987 *************** *** 40,45 vir_clicks size; phys_clicks base_click, mm_base, previous_base; phys_bytes phys_b; extern unsigned sizes[8]; /* table filled in by build */ extern int color, vec_table[], get_chrome(), (*task[])(); extern int s_call(), disk_int(), tty_int(), clock_int(), disk_int(); --- 40,47 ----- vir_clicks size; phys_clicks base_click, mm_base, previous_base; phys_bytes phys_b; + phys_bytes pridx, pfs0; >>>> Means "pointer to root index" and "pointer to fs's word 0" >>>> these are *physical* addresses (at least in the context of Minix). + int root_idx; >>>> The index into an imaginary table telling where the root filesystem >>>> should go. I did *not* use the "scan code" here, eventhough this >>>> abstract integer root_idx is a function of the "scan code", because >>>> the "scan code" is peculiar to IBM PC's, and thus does not in any >>>> sense belong in this routine. I isolated this mapping to a single >>>> function, right below here, that does that for a particular machine. >>>> That's so you can pull it out later into a "machine specific" file >>>> if you want to, or can improve it in some other way, without a lot >>>> of trouble. extern unsigned sizes[8]; /* table filled in by build */ extern int color, vec_table[], get_chrome(), (*task[])(); extern int s_call(), disk_int(), tty_int(), clock_int(), disk_int(); *************** *** 117,124 phys_copy(0L, phys_b, (long) VECTOR_BYTES); /* save all the vectors */ /* Set up the new interrupt vectors. */ ! for (t = 0; t < 16; t++) set_vec(t, surprise, base_click); ! for (t = 16; t < 256; t++) set_vec(t, trp, base_click); set_vec(DIVIDE_VECTOR, divide, base_click); set_vec(SYS_VECTOR, s_call, base_click); set_vec(CLOCK_VECTOR, clock_int, base_click); --- 119,150 ----- phys_copy(0L, phys_b, (long) VECTOR_BYTES); /* save all the vectors */ /* Set up the new interrupt vectors. */ ! for (t = 0; t < 16; t++) ! { ! #ifdef GENERIC_FDISK ! /* JER - don't patch out hard disk vector */ ! if (pc_at) ! { ! if (t==AT_WINI_VECTOR) continue; ! } ! else ! { ! if (t==XT_WINI_VECTOR) continue; ! } ! #endif ! ! set_vec(t, surprise, base_click); ! } ! ! for (t = 16; t < 256; t++) ! { ! #ifdef GENERIC_FDISK ! /* JER - don't patch out BIOS vectors */ ! if (t==0x13 || (t>=0x40 && t<=0x5f)) continue; ! #endif ! ! set_vec(t, trp, base_click); ! } set_vec(DIVIDE_VECTOR, divide, base_click); set_vec(SYS_VECTOR, s_call, base_click); set_vec(CLOCK_VECTOR, clock_int, base_click); >>>> This change bothers me a lot, but I decided it's because here in >>>> the kernel initialization is some code that is setting "vectors". >>>> This idea of "vectors" seems strange because I'm not sure yet what >>>> "vectors" are in the context of Minix, at this point in time. >>>> Intuitively I feel this is not quite right, but I may misunderstand >>>> something that will become really obvious later, so I didn't do >>>> anything radical I might later regret. *************** *** 125,130 set_vec(KEYBOARD_VECTOR, tty_int, base_click); set_vec(FLOPPY_VECTOR, disk_int, base_click); set_vec(PRINTER_VECTOR, lpr_int, base_click); if (pc_at) set_vec(AT_WINI_VECTOR, wini_int, base_click); else --- 151,157 ----- set_vec(KEYBOARD_VECTOR, tty_int, base_click); set_vec(FLOPPY_VECTOR, disk_int, base_click); set_vec(PRINTER_VECTOR, lpr_int, base_click); + #ifndef GENERIC_FDISK if (pc_at) set_vec(AT_WINI_VECTOR, wini_int, base_click); else *************** *** 129,134 set_vec(AT_WINI_VECTOR, wini_int, base_click); else set_vec(XT_WINI_VECTOR, wini_int, base_click); /* Put a ptr to proc table in a known place so it can be found in /dev/mem */ set_vec( (BASE - 4)/4, proc, (phys_clicks) 0); --- 156,162 ----- set_vec(AT_WINI_VECTOR, wini_int, base_click); else set_vec(XT_WINI_VECTOR, wini_int, base_click); + #endif /* Put a ptr to proc table in a known place so it can be found in /dev/mem */ set_vec( (BASE - 4)/4, proc, (phys_clicks) 0); >>>> 4 *************** *** 133,138 /* Put a ptr to proc table in a known place so it can be found in /dev/mem */ set_vec( (BASE - 4)/4, proc, (phys_clicks) 0); bill_ptr = proc_addr(HARDWARE); /* it has to point somewhere */ pick_proc(); --- 161,179 ----- /* Put a ptr to proc table in a known place so it can be found in /dev/mem */ set_vec( (BASE - 4)/4, proc, (phys_clicks) 0); + /* + * Get index of device to use as root, and put it where fs can find it. + * We put it into the 0th word of data_org in FS, at present, which + * contained the magic number for "build," but is unused at boot time. + * If necessary, it can be moved somewhere else in data_org by expanding + * the size of the (used) array. JER 7/29/87 + */ + root_idx = get_ridx(); + pridx = umap(proc_addr(HARDWARE), D, (vir_bytes) &root_idx, sizeof(int)); + pfs0 = umap(proc_addr(FS_PROC_NR), D, (vir_bytes)0, sizeof(int)); + phys_copy(pridx, pfs0, (phys_bytes)sizeof(int)); + + bill_ptr = proc_addr(HARDWARE); /* it has to point somewhere */ pick_proc(); >>>> I'm not sure this is the best way to do this, but calling a low >>>> level routine called "stick_root_index_into_low_word_of_fs" isn't >>>> it either, so I apologise if I used some really roundabout way to >>>> do something simple... someone more familiar with Minix may suggest >>>> a better alternative. } /*===========================================================================* * unexpected_int * --- 183,191 ----- restart(); } + /*===========================================================================* + * get root device index - JER * + *===========================================================================*/ int get_ridx() { *************** *** 143,148 } /*===========================================================================* * unexpected_int * *===========================================================================*/ --- 187,220 ----- * get root device index - JER * *===========================================================================*/ + int get_ridx() + { + int ridx; + + #ifdef i8088 + extern int scan_code; /* scan code of key user typed to start us */ + + switch (scan_code) + { + case 12: /* user typed an '=' */ + case 13: + ridx = 0; /* root will be ram disk */ + break; + + default: /* user typed a digit */ + ridx = scan_code - 1; /* root will be winchester disk */ + break; + } + + #else + + ridx = 0; /* non-8088: use ram disk */ + + #endif + + return(ridx); + } >>>> This is the function that maps scan codes, front panel switch positions, >>>> or whatever input you can give to your boot code, into an identifier >>>> of where to boot from (which again is free to be assigned to a particular >>>> model of machine, which is why it's not a device number or drive ID here.) >>>> This is not as clean as it could be; get_ridx gets "something" machine >>>> specific that is used by some mapping function in fs that is also machine >>>> specific to map the former into a device number. It leaves things open >>>> in two places for now. This is a compromise, deferring deciding where >>>> the single mapping (eliminating the abstract index), if any, >>>> should go for the future. That's because dmap is in fs, whereas >>>> it's the kernel that gets the first call on boot, and in general contains >>>> the parts of Minix that are closest to the hardware. So I passed this >>>> abstract number between them, where neither really knows what it means >>>> to the other. If you think about this at length, it may become obvious >>>> why it's so, but it's kind of hard to explain here in a way that wouldn't >>>> sound as confusing as the above. This would be a good topic >>>> for comp.arch. + /*===========================================================================* * backtrace - JER * *===========================================================================*/ *************** *** 144,149 /*===========================================================================* * unexpected_int * *===========================================================================*/ PUBLIC unexpected_int() --- 216,253 ----- } /*===========================================================================* + * backtrace - JER * + *===========================================================================*/ + + PRIVATE backtrace(w) + int w; + { + int i; + int *p; + + #ifdef i8088 + /* produce a stack backtrace showing the call chain */ + + p = &w; /* first parameter */ + p--; /* return address */ + p--; /* next bp */ + + printf("Stack backtrace: "); + for (i=0; i<6; i++) + { + printf("%04x ",p[1]); + p = (int *) *p; + } + + printf("...\n"); + + /* really should only do this for kernel traps? */ + printf("\nType space to reboot\n"); + wreboot(); + #endif + } >>>> I put this backtrace code in back when Minix would not boot, only crash, >>>> as soon as it was loaded from disk (this was while I was trying to get >>>> it compiled with MSC). I am not sure it works any more, so you may >>>> want to just delete it; I left it in in case any more spurious crashes >>>> occurred, so I could get some information. + + /*===========================================================================* * unexpected_int * *===========================================================================*/ PUBLIC unexpected_int() *************** *** 153,158 printf("Unexpected trap: vector < 16\n"); printf("pc = 0x%x text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc, proc_ptr->p_map[D].mem_len<<4); } --- 257,263 ----- printf("Unexpected trap: vector < 16\n"); printf("pc = 0x%x text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc, proc_ptr->p_map[D].mem_len<<4); + backtrace(); } *************** *** 168,173 printf("a non-MINIX library routine that is trying to make a system call.\n"); printf("pc = 0x%x text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc, proc_ptr->p_map[D].mem_len<<4); } --- 273,279 ----- printf("a non-MINIX library routine that is trying to make a system call.\n"); printf("pc = 0x%x text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc, proc_ptr->p_map[D].mem_len<<4); + backtrace(); } *************** *** 181,186 printf("Trap to vector 0: divide overflow. "); printf("pc = 0x%x text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc, proc_ptr->p_map[D].mem_len<<4); } --- 287,293 ----- printf("Trap to vector 0: divide overflow. "); printf("pc = 0x%x text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc, proc_ptr->p_map[D].mem_len<<4); + backtrace(); } *************** *** 202,207 if (n != NO_NUM) printf(" %d", n); printf("\n"); } printf("\nType space to reboot\n"); wreboot(); --- 309,315 ----- if (n != NO_NUM) printf(" %d", n); printf("\n"); } + backtrace(); printf("\nType space to reboot\n"); wreboot(); ------------------------------------------------------------ *** mpx88.asm Sat Aug 1 13:37:11 1987 --- ../../dos/kernel/mpx88.asm Sat Aug 1 13:31:24 1987 *************** *** 32,37 CLOCK EQU -3 CLOCK_TICK EQU 2 FLOPPY EQU -5 ; The following procedures are defined in this file and called from outside it. --- 32,38 ----- CLOCK EQU -3 CLOCK_TICK EQU 2 FLOPPY EQU -5 + WINI EQU -6 ; The following keeps MSC's refs to this symbol from pulling in crtso.obj PUBLIC __acrtused *************** *** 33,38 CLOCK_TICK EQU 2 FLOPPY EQU -5 ; The following procedures are defined in this file and called from outside it. PUBLIC $main, tty_int, lpr_int, clock_in, disk_int --- 34,42 ----- FLOPPY EQU -5 WINI EQU -6 + ; The following keeps MSC's refs to this symbol from pulling in crtso.obj + PUBLIC __acrtused + __acrtused EQU 9876H ; The following procedures are defined in this file and called from outside it. PUBLIC $main, _tty_int, _lpr_int, _clock_int, _disk_int, _wini_int *************** *** 35,42 ; The following procedures are defined in this file and called from outside it. ! PUBLIC $main, tty_int, lpr_int, clock_in, disk_int ! PUBLIC s_call, surprise, trp, divide, restart ; The following external procedures are called in this file. --- 39,46 ----- __acrtused EQU 9876H ; The following procedures are defined in this file and called from outside it. ! PUBLIC $main, _tty_int, _lpr_int, _clock_int, _disk_int, _wini_int ! PUBLIC _s_call, _surprise, _trp, _divide, _restart ; The following external procedures are called in this file. *************** *** 40,47 ; The following external procedures are called in this file. ! EXTRN main:NEAR, sys_call:NEAR, interrup:NEAR, keyboard:NEAR ! EXTRN panic:NEAR, unexpect:NEAR, trap:NEAR, div_trap:NEAR, pr_char:NEAR ; Variables and data structures. --- 44,52 ----- ; The following external procedures are called in this file. ! EXTRN _main:NEAR, _sys_call:NEAR, _intr:NEAR, _keyboard:NEAR ! EXTRN _panic:NEAR, _unexpected_int:NEAR, _trap:NEAR, _div_trap:NEAR, ! EXTRN _pr_char:NEAR ; Variables and data structures. PUBLIC _sizes, _brksize, _splimit, _end *************** *** 43,49 EXTRN main:NEAR, sys_call:NEAR, interrup:NEAR, keyboard:NEAR EXTRN panic:NEAR, unexpect:NEAR, trap:NEAR, div_trap:NEAR, pr_char:NEAR - ; Variables and data structures. PUBLIC sizes, brksize, splimit, @end EXTRN cur_proc:WORD, proc_ptr:WORD, int_mess:WORD --- 48,53 ----- EXTRN _panic:NEAR, _unexpected_int:NEAR, _trap:NEAR, _div_trap:NEAR, EXTRN _pr_char:NEAR ; Variables and data structures. PUBLIC _sizes, _brksize, _splimit, _end EXTRN _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD *************** *** 45,53 ; Variables and data structures. ! PUBLIC sizes, brksize, splimit, @end ! EXTRN cur_proc:WORD, proc_ptr:WORD, int_mess:WORD ! EXTRN scan_cod:WORD, k_stack:WORD ; The following constants are offsets into the proc table. --- 49,57 ----- EXTRN _pr_char:NEAR ; Variables and data structures. ! PUBLIC _sizes, _brksize, _splimit, _end ! EXTRN _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD ! EXTRN _scan_code:WORD, _k_stack:WORD ; The following constants are offsets into the proc table. esreg = 14 *************** *** 49,55 EXTRN cur_proc:WORD, proc_ptr:WORD, int_mess:WORD EXTRN scan_cod:WORD, k_stack:WORD - ; The following constants are offsets into the proc table. esreg = 14 dsreg = 16 --- 53,58 ----- EXTRN _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD EXTRN _scan_code:WORD, _k_stack:WORD ; The following constants are offsets into the proc table. esreg = 14 dsreg = 16 *************** *** 65,70 INCLUDE ..\lib\prologue.h @CODE SEGMENT assume cs:@code,ds:dgroup --- 68,76 ----- INCLUDE ..\lib\prologue.h + ;=========================================================================== + ; data - JER moved here from before stack + ;=========================================================================== _DATAB SEGMENT ; datab ensures it is the beginning of all data >>>> I moved datab here to eliminate forward references to it, because back >>>> before Minix would even crash, it would just hang, and it looked like >>>> there was a bad pointer, and my guess was that MSC was having trouble >>>> with the forward references, because I know some 8086 assemblers have >>>> trouble with that. That wasn't it, but I still feel better when >>>> forward references are minimized. I don't know if it matters here. >>>> (At that time, all I had was a routine that would dump the ax onto the >>>> screen directly, so it was all intuitive guessing at that point: the >>>> display hadn't even been initialized by Minix yet. Hence the seemingly >>>> illogical change.) *************** *** 66,73 INCLUDE ..\lib\prologue.h ! @CODE SEGMENT ! assume cs:@code,ds:dgroup ;=========================================================================== ; Minix --- 72,78 ----- ; data - JER moved here from before stack ;=========================================================================== ! _DATAB SEGMENT ; datab ensures it is the beginning of all data _sizes DW 526Fh ; this must be the first data entry (magic nr) DW 7 dup(0) ; space for build table - total 16b *************** *** 69,74 @CODE SEGMENT assume cs:@code,ds:dgroup ;=========================================================================== ; Minix ;=========================================================================== --- 74,98 ----- _DATAB SEGMENT ; datab ensures it is the beginning of all data + _sizes DW 526Fh ; this must be the first data entry (magic nr) + DW 7 dup(0) ; space for build table - total 16b + _splimit DW 0 ; stack limit for current task (kernel only) + _bx_save DW 0 ; storage for bx + _ds_save DW 0 ; storage for ds + _ret_save DW 0 ; storage for return address + _lds_low DW 0,0 ; storage used for restoring ds:bx + _brksize DW offset dgroup:_END+2 ; first free memory in kernel + _ttyomess DB "RS232 interrupt",0 + _DATAB ENDS + + + _DATAV SEGMENT ; DATAV holds nothing. + _end label byte ; the segment just tells us where + _DATAV ENDS ; the data+bss ends. + + + _TEXT SEGMENT + ;=========================================================================== ; Minix ;=========================================================================== *************** *** 78,84 ORG 4 ; build writes the ds value at text address 4 ker_ds DW dgroup ; this word will contain kernel's ds value ; and it forces relocation for dos2out ! M0:cli ; disable interrupts mov ax,cs ; set up segment registers mov ds,ax ; set up ds mov ax,cs:ker_ds ; build has loaded this word with ds value --- 102,109 ----- ORG 4 ; build writes the ds value at text address 4 ker_ds DW dgroup ; this word will contain kernel's ds value ; and it forces relocation for dos2out ! M0: ! cli ; disable interrupts mov ax,cs ; set up segment registers mov ds,ax ; set up ds mov ax,ker_ds ; build has loaded this word with ds value *************** *** 81,87 M0:cli ; disable interrupts mov ax,cs ; set up segment registers mov ds,ax ; set up ds ! mov ax,cs:ker_ds ; build has loaded this word with ds value mov ds,ax ; ds now contains proper value mov ss,ax ; ss now contains proper value mov dgroup:scan_cod,bx ; save scan code for '=' key from bootstrap --- 106,112 ----- cli ; disable interrupts mov ax,cs ; set up segment registers mov ds,ax ; set up ds ! mov ax,ker_ds ; build has loaded this word with ds value mov ds,ax ; ds now contains proper value mov ss,ax ; ss now contains proper value mov es,ax ; JER - set es too >>>> I didn't see why the cs: override was on here, since ds=cs at this >>>> point, so I took it out during the early debugging. *************** *** 84,91 mov ax,cs:ker_ds ; build has loaded this word with ds value mov ds,ax ; ds now contains proper value mov ss,ax ; ss now contains proper value ! mov dgroup:scan_cod,bx ; save scan code for '=' key from bootstrap ! mov sp,offset dgroup:k_stack ; set sp to point to the top of the add sp,K_STACK_BYTES ; kernel stack call main ; start the main program of Minix --- 109,122 ----- mov ax,ker_ds ; build has loaded this word with ds value mov ds,ax ; ds now contains proper value mov ss,ax ; ss now contains proper value ! mov es,ax ; JER - set es too ! ! ifdef debug ! call prtax ! endif ! ! mov dgroup:_scan_code,bx ; save scan code for '=' key from bootstrap ! mov sp,offset dgroup:_k_stack ; set sp to point to the top of the add sp,K_STACK_BYTES ; kernel stack wto 'Kernel EP: stack now set up' call _main ; start the main program of Minix >>>> This was another guess that turned out invalid, I *think*.... I don't >>>> think MSC uses the es, but it looked like a possibility... you can >>>> see some vestigal debug code up there; wto is a macro in prologue.h >>>> that doesn't generate anything. *************** *** 87,93 mov dgroup:scan_cod,bx ; save scan code for '=' key from bootstrap mov sp,offset dgroup:k_stack ; set sp to point to the top of the add sp,K_STACK_BYTES ; kernel stack ! call main ; start the main program of Minix M1:jmp M1 ; this should never be executed --- 118,126 ----- mov dgroup:_scan_code,bx ; save scan code for '=' key from bootstrap mov sp,offset dgroup:_k_stack ; set sp to point to the top of the add sp,K_STACK_BYTES ; kernel stack ! wto 'Kernel EP: stack now set up' ! call _main ; start the main program of Minix ! wto 'Fatal: kernel _main returned' M1:jmp M1 ; this should never be executed >>>> wto is a macro in prologue.h which is currently defined to do nothing. >>>> for awhile it wrote strings to the display. *************** *** 95,103 ;=========================================================================== ; s_call ;=========================================================================== ! s_call: ; System calls are vectored here. ! call save ; save the machine state ! mov bp,dgroup:proc_ptr ; use bp to access sys call parameters push 2[bp] ; push(pointer to user message) (was bx) push [bp] ; push(src/dest) (was ax) push dgroup:cur_proc ; push caller --- 128,136 ----- ;=========================================================================== ; s_call ;=========================================================================== ! _s_call: ; System calls are vectored here. ! call _save ; save the machine state ! mov bp,dgroup:_proc_ptr ; use bp to access sys call parameters push 2[bp] ; push(pointer to user message) (was bx) push [bp] ; push(src/dest) (was ax) push dgroup:_cur_proc ; push caller *************** *** 100,106 mov bp,dgroup:proc_ptr ; use bp to access sys call parameters push 2[bp] ; push(pointer to user message) (was bx) push [bp] ; push(src/dest) (was ax) ! push dgroup:cur_proc ; push caller push 4[bp] ; push(SEND/RECEIVE/BOTH) (was cx) call sys_call ; sys_call(function, caller, src_dest, m_ptr) jmp restart ; jump to code to restart proc/task running --- 133,139 ----- mov bp,dgroup:_proc_ptr ; use bp to access sys call parameters push 2[bp] ; push(pointer to user message) (was bx) push [bp] ; push(src/dest) (was ax) ! push dgroup:_cur_proc ; push caller push 4[bp] ; push(SEND/RECEIVE/BOTH) (was cx) call _sys_call ; sys_call(function, caller, src_dest, m_ptr) jmp _restart ; jump to code to restart proc/task running *************** *** 102,109 push [bp] ; push(src/dest) (was ax) push dgroup:cur_proc ; push caller push 4[bp] ; push(SEND/RECEIVE/BOTH) (was cx) ! call sys_call ; sys_call(function, caller, src_dest, m_ptr) ! jmp restart ; jump to code to restart proc/task running ;=========================================================================== --- 135,142 ----- push [bp] ; push(src/dest) (was ax) push dgroup:_cur_proc ; push caller push 4[bp] ; push(SEND/RECEIVE/BOTH) (was cx) ! call _sys_call ; sys_call(function, caller, src_dest, m_ptr) ! jmp _restart ; jump to code to restart proc/task running ;=========================================================================== *************** *** 109,118 ;=========================================================================== ; tty_int ;=========================================================================== ! tty_int: ; Interrupt routine for terminal input. ! call save ; save the machine state ! call keyboard ; process a keyboard interrupt ! jmp restart ; continue execution ;=========================================================================== --- 142,151 ----- ;=========================================================================== ; tty_int ;=========================================================================== ! _tty_int: ; Interrupt routine for terminal input. ! call _save ; save the machine state ! call _keyboard ; process a keyboard interrupt ! jmp _restart ; continue execution ;=========================================================================== *************** *** 118,127 ;=========================================================================== ; lpr_int ;=========================================================================== ! lpr_int: ; Interrupt routine for terminal input. ! call save ; save the machine state ! call pr_char ; process a line printer interrupt ! jmp restart ; continue execution ;=========================================================================== --- 151,160 ----- ;=========================================================================== ; lpr_int ;=========================================================================== ! _lpr_int: ; Interrupt routine for terminal input. ! call _save ; save the machine state ! call _pr_char ; process a line printer interrupt ! jmp _restart ; continue execution ;=========================================================================== *************** *** 127,136 ;=========================================================================== ; disk_int ;=========================================================================== ! disk_int: ; Interrupt routine for the floppy disk. ! call save ; save the machine state ! mov dgroup:int_mess+2,DISKINT ; build message for disk task ! mov ax,offset dgroup:int_mess ; prepare to call interrupt[FLOPPY, &intmess] push ax ; push second parameter mov ax,FLOPPY ; prepare to push first parameter push ax ; push first parameter --- 160,169 ----- ;=========================================================================== ; disk_int ;=========================================================================== ! _disk_int: ; Interrupt routine for the floppy disk. ! call _save ; save the machine state ! mov dgroup:_int_mess+2,DISKINT ; build message for disk task ! mov ax,offset dgroup:_int_mess ; prepare to call interrupt[FLOPPY, &intmess] push ax ; push second parameter mov ax,FLOPPY ; prepare to push first parameter push ax ; push first parameter *************** *** 134,141 push ax ; push second parameter mov ax,FLOPPY ; prepare to push first parameter push ax ; push first parameter ! call interrup ; this is the call ! jmp restart ; continue execution ;=========================================================================== --- 167,174 ----- push ax ; push second parameter mov ax,FLOPPY ; prepare to push first parameter push ax ; push first parameter ! call _intr ; this is the call ! jmp _restart ; continue execution ;*===========================================================================* *************** *** 138,143 jmp restart ; continue execution ;=========================================================================== ; clock_int ;=========================================================================== --- 171,190 ----- jmp _restart ; continue execution + ;*===========================================================================* + ;* wini_int * + ;*===========================================================================* + _wini_int: ; Interrupt routine for the winchester disk. + call _save ; save the machine state + mov dgroup:_int_mess+2,DISKINT; build message for winchester task + mov ax,offset dgroup:_int_mess ; prepare to call interrupt(WINI, &intmess) + push ax ; push second parameter + mov ax,WINI ; prepare to push first parameter + push ax ; push first parameter + call _intr ; this is the call + jmp _restart ; continue execution + + >>>> This is not used in the generic driver, so it has never been tested in >>>> this version of the code... it was missing from the C86 sources. ;=========================================================================== ; clock_int ;=========================================================================== *************** *** 141,150 ;=========================================================================== ; clock_int ;=========================================================================== ! clock_in: ; Interrupt routine for the clock. ! call save ; save the machine state ! mov dgroup:int_mess+2,CLOCK_TICK; build message for clock task ! mov ax,offset dgroup:int_mess ; prepare to call interrupt(CLOCK,&intmess) push ax ; push second parameter mov ax,CLOCK ; prepare to push first parameter push ax ; push first parameter --- 188,197 ----- ;=========================================================================== ; clock_int ;=========================================================================== ! _clock_int: ; Interrupt routine for the clock. ! call _save ; save the machine state ! mov dgroup:_int_mess+2,CLOCK_TICK; build message for clock task ! mov ax,offset dgroup:_int_mess ; prepare to call interrupt(CLOCK,&intmess) push ax ; push second parameter mov ax,CLOCK ; prepare to push first parameter push ax ; push first parameter *************** *** 148,155 push ax ; push second parameter mov ax,CLOCK ; prepare to push first parameter push ax ; push first parameter ! call interrup ; this is the call ! jmp restart ; continue execution ;=========================================================================== --- 195,202 ----- push ax ; push second parameter mov ax,CLOCK ; prepare to push first parameter push ax ; push first parameter ! call _intr ; this is the call ! jmp _restart ; continue execution ;=========================================================================== *************** *** 155,164 ;=========================================================================== ; surprise ;=========================================================================== ! surprise: ; This is where unexpected interrupts come. ! call save ; save the machine state ! call unexpect ; go panic ! jmp restart ; never executed ;=========================================================================== --- 202,211 ----- ;=========================================================================== ; surprise ;=========================================================================== ! _surprise: ; This is where unexpected interrupts come. ! call _save ; save the machine state ! call _unexpected_int ; go panic ! jmp _restart ; never executed ;=========================================================================== *************** *** 164,173 ;=========================================================================== ; trp ;=========================================================================== ! trp: ; This is where unexpected traps come. ! call save ; save the machine state ! call trap ; print a message ! jmp restart ; this error is not fatal ;=========================================================================== --- 211,220 ----- ;=========================================================================== ; trp ;=========================================================================== ! _trp: ; This is where unexpected traps come. ! call _save ; save the machine state ! call _trap ; print a message ! jmp _restart ; this error is not fatal ;=========================================================================== *************** *** 173,182 ;=========================================================================== ; divide ;=========================================================================== ! divide: ; This is where divide overflow traps come. ! call save ; save the machine state ! call div_trap ; print a message ! jmp restart ; this error is not fatal ;=========================================================================== --- 220,229 ----- ;=========================================================================== ; divide ;=========================================================================== ! _divide: ; This is where divide overflow traps come. ! call _save ; save the machine state ! call _div_trap ; print a message ! jmp _restart ; this error is not fatal ;=========================================================================== *************** *** 182,188 ;=========================================================================== ; save ;=========================================================================== ! save: ; save the machine state in the proc table. push ds ; stack: psw/cs/pc/ret addr/ds push cs ; prepare to restore ds pop ds ; ds has now been set to cs --- 229,235 ----- ;=========================================================================== ; save ;=========================================================================== ! _save: ; save the machine state in the proc table. push ds ; stack: psw/cs/pc/ret addr/ds push cs ; prepare to restore ds pop ds ; ds has now been set to cs *************** *** 187,196 push cs ; prepare to restore ds pop ds ; ds has now been set to cs mov ds,ker_ds ; word 4 in kernel text space contains ds value ! pop ds_save ; stack: psw/cs/pc/ret addr ! pop ret_save ; stack: psw/cs/pc ! mov bx_save,bx ; save bx for later ; we need a free register ! mov bx,dgroup:proc_ptr ; start save set up; make bx point to save area add bx,OFF ; bx points to place to store cs pop PC-OFF[bx] ; store pc in proc table pop csreg-OFF[bx] ; store cs in proc table --- 234,243 ----- push cs ; prepare to restore ds pop ds ; ds has now been set to cs mov ds,ker_ds ; word 4 in kernel text space contains ds value ! pop dgroup:_ds_save ; stack: psw/cs/pc/ret addr ! pop dgroup:_ret_save ; stack: psw/cs/pc ! mov dgroup:_bx_save,bx ; save bx for later ; we need a free register ! mov bx,dgroup:_proc_ptr ; start save set up; make bx point to save area add bx,OFF ; bx points to place to store cs pop PC-OFF[bx] ; store pc in proc table pop csreg-OFF[bx] ; store cs in proc table *************** *** 200,206 mov sp,bx ; now use sp to point into proc table/task save mov bx,ds ; about to set ss mov ss,bx ; set ss ! push ds_save ; start saving all the registers, sp first push es ; save es between sp and bp mov es,bx ; es now references kernel memory too push bp ; save bp --- 247,253 ----- mov sp,bx ; now use sp to point into proc table/task save mov bx,ds ; about to set ss mov ss,bx ; set ss ! push dgroup:_ds_save ; start saving all the registers, sp first push es ; save es between sp and bp mov es,bx ; es now references kernel memory too push bp ; save bp *************** *** 208,214 push si ; save si push dx ; save dx push cx ; save cx ! push bx_save ; save original bx push ax ; all registers now saved mov sp,offset dgroup:k_stack ; temporary stack for interrupts add sp,K_STACK_BYTES ; set sp to top of temporary stack --- 255,261 ----- push si ; save si push dx ; save dx push cx ; save cx ! push dgroup:_bx_save ; save original bx push ax ; all registers now saved mov sp,offset dgroup:_k_stack ; temporary stack for interrupts add sp,K_STACK_BYTES ; set sp to top of temporary stack *************** *** 210,216 push cx ; save cx push bx_save ; save original bx push ax ; all registers now saved ! mov sp,offset dgroup:k_stack ; temporary stack for interrupts add sp,K_STACK_BYTES ; set sp to top of temporary stack mov splimit,offset dgroup:k_stack ; limit for temporary stack add splimit,8 ; splimit checks for stack overflow --- 257,263 ----- push cx ; save cx push dgroup:_bx_save ; save original bx push ax ; all registers now saved ! mov sp,offset dgroup:_k_stack ; temporary stack for interrupts add sp,K_STACK_BYTES ; set sp to top of temporary stack mov dgroup:_splimit,offset dgroup:_k_stack ; limit for temporary stack add dgroup:_splimit,8 ; splimit checks for stack overflow *************** *** 212,220 push ax ; all registers now saved mov sp,offset dgroup:k_stack ; temporary stack for interrupts add sp,K_STACK_BYTES ; set sp to top of temporary stack ! mov splimit,offset dgroup:k_stack ; limit for temporary stack ! add splimit,8 ; splimit checks for stack overflow ! mov ax,ret_save ; ax = address to return to jmp ax ; return to caller; Note: sp points to saved ax --- 259,267 ----- push ax ; all registers now saved mov sp,offset dgroup:_k_stack ; temporary stack for interrupts add sp,K_STACK_BYTES ; set sp to top of temporary stack ! mov dgroup:_splimit,offset dgroup:_k_stack ; limit for temporary stack ! add dgroup:_splimit,8 ; splimit checks for stack overflow ! mov ax,dgroup:_ret_save ; ax = address to return to jmp ax ; return to caller; Note: sp points to saved ax *************** *** 221,228 ;=========================================================================== ; restart ;=========================================================================== ! restart: ; This routine sets up and runs a proc or task. ! cmp dgroup:cur_proc,IDLE; restart user; if cur_proc = IDLE, go idle je _idle ; no user is runnable, jump to idle routine cli ; disable interrupts mov sp,dgroup:proc_ptr ; return to user, fetch regs from proc table --- 268,275 ----- ;=========================================================================== ; restart ;=========================================================================== ! _restart: ; This routine sets up and runs a proc or task. ! cmp dgroup:_cur_proc,IDLE; restart user; if cur_proc = IDLE, go idle je _idle ; no user is runnable, jump to idle routine cli ; disable interrupts mov sp,dgroup:_proc_ptr ; return to user, fetch regs from proc table *************** *** 225,231 cmp dgroup:cur_proc,IDLE; restart user; if cur_proc = IDLE, go idle je _idle ; no user is runnable, jump to idle routine cli ; disable interrupts ! mov sp,dgroup:proc_ptr ; return to user, fetch regs from proc table pop ax ; start restoring registers pop bx ; restore bx pop cx ; restore cx --- 272,278 ----- cmp dgroup:_cur_proc,IDLE; restart user; if cur_proc = IDLE, go idle je _idle ; no user is runnable, jump to idle routine cli ; disable interrupts ! mov sp,dgroup:_proc_ptr ; return to user, fetch regs from proc table pop ax ; start restoring registers pop bx ; restore bx pop cx ; restore cx *************** *** 232,238 pop dx ; restore dx pop si ; restore si pop di ; restore di ! mov lds_low,bx ; lds_low contains bx mov bx,sp ; bx points to saved bp register mov bp,SPLIM-ROFF[bx] ; splimit = p_splimit mov splimit,bp ; ditto --- 279,285 ----- pop dx ; restore dx pop si ; restore si pop di ; restore di ! mov dgroup:_lds_low,bx ; lds_low contains bx mov bx,sp ; bx points to saved bp register mov bp,SPLIM-ROFF[bx] ; splimit = p_splimit mov dgroup:_splimit,bp ; ditto *************** *** 235,241 mov lds_low,bx ; lds_low contains bx mov bx,sp ; bx points to saved bp register mov bp,SPLIM-ROFF[bx] ; splimit = p_splimit ! mov splimit,bp ; ditto mov bp,dsreg-ROFF[bx] ; bp = ds mov lds_low+2,bp ; lds_low+2 contains ds pop bp ; restore bp --- 282,288 ----- mov dgroup:_lds_low,bx ; lds_low contains bx mov bx,sp ; bx points to saved bp register mov bp,SPLIM-ROFF[bx] ; splimit = p_splimit ! mov dgroup:_splimit,bp ; ditto mov bp,dsreg-ROFF[bx] ; bp = ds mov dgroup:_lds_low+2,bp ; lds_low+2 contains ds pop bp ; restore bp *************** *** 237,243 mov bp,SPLIM-ROFF[bx] ; splimit = p_splimit mov splimit,bp ; ditto mov bp,dsreg-ROFF[bx] ; bp = ds ! mov lds_low+2,bp ; lds_low+2 contains ds pop bp ; restore bp pop es ; restore es mov sp,spreg-ROFF[bx] ; restore sp --- 284,290 ----- mov bp,SPLIM-ROFF[bx] ; splimit = p_splimit mov dgroup:_splimit,bp ; ditto mov bp,dsreg-ROFF[bx] ; bp = ds ! mov dgroup:_lds_low+2,bp ; lds_low+2 contains ds pop bp ; restore bp pop es ; restore es mov sp,spreg-ROFF[bx] ; restore sp *************** *** 245,251 push PSW-ROFF[bx] ; push psw (flags) push csreg-ROFF[bx] ; push cs push PC-ROFF[bx] ; push pc ! lds bx,DWORD PTR lds_low ; restore ds and bx in one fell swoop iret ; return to user or task ;=========================================================================== --- 292,298 ----- push PSW-ROFF[bx] ; push psw (flags) push csreg-ROFF[bx] ; push cs push PC-ROFF[bx] ; push pc ! lds bx,DWORD PTR dgroup:_lds_low ; restore ds and bx in one fell swoop iret ; return to user or task ;=========================================================================== *************** *** 256,261 L3: wait ; just idle while waiting for interrupt jmp L3 ; loop until interrupt @CODE ENDS --- 303,311 ----- L3: wait ; just idle while waiting for interrupt jmp L3 ; loop until interrupt + ;=========================================================================== + ; print - JER - print a debug message + ;=========================================================================== ifdef debug *************** *** 257,263 jmp L3 ; loop until interrupt ! @CODE ENDS ;=========================================================================== --- 307,313 ----- ; print - JER - print a debug message ;=========================================================================== ! ifdef debug print proc ; print string (bx), ax destroyed mov al,[bx] ; al contains char to be printed *************** *** 259,264 @CODE ENDS ;=========================================================================== ; data --- 309,328 ----- ifdef debug + print proc ; print string (bx), ax destroyed + mov al,[bx] ; al contains char to be printed + test al,al ; null char? + jne prt1 ; no + ret ; else return + prt1: mov ah,14 ; 14 = print char + inc bx ; increment string pointer + push bx ; save bx + mov bl,1 ; foreground color + xor bh,bh ; page 0 + int 10h ; call BIOS VIDEO_IO + pop bx ; restore bx + jmp print ; next character + print endp >>>> the above may not work any more, it was for back when Minix hadn't >>>> been initialized yet. It's ifdef'ed out, now; I just left it in >>>> in case I needed it in the future. You can leave it out. ; ; prtnum - print low-order 4 bits of al register in hex *************** *** 260,268 @CODE ENDS ! ;=========================================================================== ! ; data ! ;=========================================================================== @DATAB SEGMENT ; datab ensures it is the beginning of all data sizes DW 526Fh ; this must be the first data entry (magic nr) --- 324,332 ----- jmp print ; next character print endp ! ; ! ; prtnum - print low-order 4 bits of al register in hex ! ; prtnum proc near push ds *************** *** 264,280 ; data ;=========================================================================== ! @DATAB SEGMENT ; datab ensures it is the beginning of all data ! sizes DW 526Fh ; this must be the first data entry (magic nr) ! DW 7 dup(0) ; space for build table - total 16b ! splimit DW 0 ; stack limit for current task (kernel only) ! bx_save DW 0 ; storage for bx ! ds_save DW 0 ; storage for ds ! ret_save DW 0 ; storage for return address ! lds_low DW 0,0 ; storage used for restoring ds:bx ! brksize DW offset dgroup:@END+2 ; first free memory in kernel ! ttyomess DB "RS232 interrupt",0 ! @DATAB ENDS @DATAV SEGMENT ; DATAV holds nothing. The label in --- 328,346 ----- ; prtnum - print low-order 4 bits of al register in hex ; ! prtnum proc near ! push ds ! push cs ! pop ds ! push bx ! mov bx,offset xltab ! xlatb ! mov ah,14 ! mov bh,10 ! int 10H ! pop bx ! pop ds ! ret xltab db '0123456789ABCDEF ' prtnum endp *************** *** 276,281 ttyomess DB "RS232 interrupt",0 @DATAB ENDS @DATAV SEGMENT ; DATAV holds nothing. The label in @end label byte ; the segment just tells us where --- 342,349 ----- pop ds ret + xltab db '0123456789ABCDEF ' + prtnum endp ; ; prtax - print ax register's contents in hex *************** *** 277,285 @DATAB ENDS ! @DATAV SEGMENT ; DATAV holds nothing. The label in ! @end label byte ; the segment just tells us where ! @DATAV ENDS ; the data+bss ends. @STACK SEGMENT BYTE STACK 'STACK' ; Satisfy DOS-linker (dummy stack) @STACK ENDS --- 345,353 ----- xltab db '0123456789ABCDEF ' prtnum endp ! ; ! ; prtax - print ax register's contents in hex ! ; prtax proc near push cx *************** *** 281,287 @end label byte ; the segment just tells us where @DATAV ENDS ; the data+bss ends. ! @STACK SEGMENT BYTE STACK 'STACK' ; Satisfy DOS-linker (dummy stack) @STACK ENDS END ; end of assembly-file --- 349,390 ----- ; prtax - print ax register's contents in hex ; ! prtax proc near ! push cx ! push ax ! mov al,ah ! mov cl,4 ! shr al,cl ! call prtnum ! pop ax ! push ax ! mov al,ah ! and al,0fH ! call prtnum ! pop ax ! push ax ! mov cl,4 ! shr al,cl ! call prtnum ! pop ax ! push ax ! and al,0fH ! call prtnum ! mov al,10H ; special value to print a space ! call prtnum ! pop ax ! pop cx ! ret ! ! prtax endp ! ! endif ! ! ! ! _TEXT ENDS ! ! @STACK SEGMENT PARA STACK 'STACK' ; Satisfy DOS-linker (dummy stack) @STACK ENDS END ; end of assembly-file ------------------------------------------------------------ *** printer.c Sat Aug 1 13:37:15 1987 --- ../../dos/kernel/printer.c Sat Aug 1 13:31:32 1987 ------------------------------------------------------------ *** tty.c Sat Aug 1 13:37:08 1987 --- ../../dos/kernel/tty.c Sat Aug 1 13:31:21 1987 *************** *** 766,772 #define COLOR_BASE 0xB800 /* video ram paragraph for color display */ #define MONO_BASE 0xB000 /* video ram address for mono display */ #define C_VID_MASK 0x3FFF /* mask for 16K video RAM */ ! #define M_VID_MASK 0x0FFF /* mask for 4K video RAM */ #define C_RETRACE 0x0300 /* how many characters to display at once */ #define M_RETRACE 0x7000 /* how many characters to display at once */ #define WORD_MASK 0xFFFF /* mask for 16 bits */ --- 766,772 ----- #define COLOR_BASE 0xB800 /* video ram paragraph for color display */ #define MONO_BASE 0xB000 /* video ram address for mono display */ #define C_VID_MASK 0x3FFF /* mask for 16K video RAM */ ! #define M_VID_MASK 0x1FFF /* mask for 8K video RAM */ #define C_RETRACE 0x0300 /* how many characters to display at once */ #define M_RETRACE 0x7000 /* how many characters to display at once */ #define WORD_MASK 0xFFFF /* mask for 16 bits */ ------------------------------------------------------------ *** wini.c Sat Aug 1 13:37:18 1987 --- ../../dos/kernel/wini.c Sat Aug 1 13:31:36 1987 *************** *** 114,120 int r, caller, proc_nr; /* First initialize the controller */ ! init_param(); /* Here is the main loop of the disk task. It waits for a message, carries * it out, and sends a reply. --- 114,120 ----- int r, caller, proc_nr; /* First initialize the controller */ ! init_params(); /* Here is the main loop of the disk task. It waits for a message, carries * it out, and sends a reply. *************** *** 585,592 phys_copy(address, umap(proc_addr(WINCHESTER), D, buf, 64), 64L); /* Copy the parameters to the structures */ ! copy_param((&buf[type_0 * 16]), ¶m0); ! copy_param((&buf[type_1 * 16]), ¶m1); /* Get the nummer of drives from the bios */ phys_copy(0x475L, umap(proc_addr(WINCHESTER), D, buf, 1), 1L); --- 585,592 ----- phys_copy(address, umap(proc_addr(WINCHESTER), D, buf, 64), 64L); /* Copy the parameters to the structures */ ! copy_params((&buf[type_0 * 16]), ¶m0); ! copy_params((&buf[type_1 * 16]), ¶m1); /* Get the nummer of drives from the bios */ phys_copy(0x475L, umap(proc_addr(WINCHESTER), D, buf, 1), 1L);
ericr@ipmoea.UUCP (Eric Roskos) (08/09/87)
Directory: /usr2/ericr/minix/minix/fs ------------------------------------------------------------ *** glo.h Sat Aug 1 13:38:24 1987 --- ../../dos/fs/glo.h Sat Aug 1 13:33:16 1987 *************** *** 6,11 EXTERN int reviving; /* number of pipe processes to be revived */ EXTERN file_pos rdahedpos; /* position to read ahead */ EXTERN struct inode *rdahed_inode; /* pointer to inode to read ahead */ /* The parameters of the call are kept here. */ EXTERN message m; /* the input message itself */ --- 6,12 ----- EXTERN int reviving; /* number of pipe processes to be revived */ EXTERN file_pos rdahedpos; /* position to read ahead */ EXTERN struct inode *rdahed_inode; /* pointer to inode to read ahead */ + EXTERN dev_nr root_dev; /* the root device number (major/minor) */ /* The parameters of the call are kept here. */ EXTERN message m; /* the input message itself */ ------------------------------------------------------------ *** main.c Sat Aug 1 13:38:22 1987 --- ../../dos/fs/main.c Sat Aug 1 13:33:13 1987 *************** *** 24,29 #define M64K 0xFFFF0000L /* 16 bit mask for DMA check */ #define INFO 2 /* where in data_org is info from build */ #define MAX_RAM 512 /* maxium RAM disk size in blocks */ /*===========================================================================* --- 24,30 ----- #define M64K 0xFFFF0000L /* 16 bit mask for DMA check */ #define INFO 2 /* where in data_org is info from build */ + #define ROOT_IDX 0 /* where in data_org kernel put boot-dev idx */ #define MAX_RAM 512 /* maxium RAM disk size in blocks */ /*===========================================================================* *************** *** 223,228 struct super_block *sp; block_nr i; phys_clicks ram_clicks, init_org, init_text_clicks, init_data_clicks; extern phys_clicks data_org[INFO + 2]; extern struct buf *get_block(); --- 224,231 ----- struct super_block *sp; block_nr i; phys_clicks ram_clicks, init_org, init_text_clicks, init_data_clicks; + int fLoadRam; + int ir; extern phys_clicks data_org[INFO + 2]; extern struct buf *get_block(); *************** *** 231,246 init_text_clicks = data_org[INFO + 1]; init_data_clicks = data_org[INFO + 2]; ! /* Get size of RAM disk by reading root file system's super block */ ! bp = get_block(BOOT_DEV, SUPER_BLOCK, NORMAL); /* get RAM super block */ ! copy(super_block, bp->b_data, sizeof(struct super_block)); ! sp = &super_block[0]; ! if (sp->s_magic != SUPER_MAGIC) ! panic("Diskette in drive 0 is not root file system", NO_NUM); ! count = sp->s_nzones << sp->s_log_zone_size; /* # blocks on root dev */ ! if (count > MAX_RAM) panic("RAM disk is too big. # blocks = ", count); ! ram_clicks = count * (BLOCK_SIZE/CLICK_SIZE); ! put_block(bp, FULL_DATA_BLOCK); /* Tell MM the origin and size of INIT, and the amount of memory used for the * system plus RAM disk combined, so it can remove all of it from the map. --- 234,242 ----- init_text_clicks = data_org[INFO + 1]; init_data_clicks = data_org[INFO + 2]; ! /* select root device based on user input to fsck - JER 7/29/87 */ ! /* get root-device index stored by kernel at end of main() init */ ! ir = data_org[ROOT_IDX]; if (ir == 0) root_dev = DEV_RAM; *************** *** 242,247 ram_clicks = count * (BLOCK_SIZE/CLICK_SIZE); put_block(bp, FULL_DATA_BLOCK); /* Tell MM the origin and size of INIT, and the amount of memory used for the * system plus RAM disk combined, so it can remove all of it from the map. */ --- 238,269 ----- /* get root-device index stored by kernel at end of main() init */ ir = data_org[ROOT_IDX]; + if (ir == 0) + root_dev = DEV_RAM; + else + root_dev = DEV_WINI + ir; + + /* if root device is ram disk, have to load ram from boot floppy */ + fLoadRam = (root_dev&0xff00)==DEV_RAM; + + if (fLoadRam) + { + /* Get size of RAM disk by reading root file system's super block */ + bp = get_block(BOOT_DEV, SUPER_BLOCK, NORMAL); /* get RAM super block */ + copy(super_block, bp->b_data, sizeof(struct super_block)); + sp = &super_block[0]; + if (sp->s_magic != SUPER_MAGIC) + panic("Diskette in drive 0 is not root file system", NO_NUM); + count = sp->s_nzones << sp->s_log_zone_size; /* # blocks on root dev */ + if (count > MAX_RAM) panic("RAM disk is too big. # blocks = ", count); + ram_clicks = count * (BLOCK_SIZE/CLICK_SIZE); + put_block(bp, FULL_DATA_BLOCK); + } + else + { + ram_clicks = RAM_MIN * (BLOCK_SIZE/CLICK_SIZE); + } + /* Tell MM the origin and size of INIT, and the amount of memory used for the * system plus RAM disk combined, so it can remove all of it from the map. */ *************** *** 260,277 m1.COUNT = count; if (sendrec(MEM, &m1) != OK) panic("Can't report size to MEM", NO_NUM); ! /* Copy the blocks one at a time from the root diskette to the RAM */ ! printf("Loading RAM disk from root diskette. Loaded: 0K "); ! for (i = 0; i < count; i++) { ! bp = get_block(BOOT_DEV, (block_nr) i, NORMAL); ! bp1 = get_block(ROOT_DEV, i, NO_READ); ! copy(bp1->b_data, bp->b_data, BLOCK_SIZE); ! bp1->b_dirt = DIRTY; ! put_block(bp, I_MAP_BLOCK); ! put_block(bp1, I_MAP_BLOCK); ! k_loaded = ( (long) i * BLOCK_SIZE)/1024L; /* K loaded so far */ ! if (k_loaded % 5 == 0) printf("\b\b\b\b\b%3DK %c", k_loaded, 0); ! } printf("\rRAM disk loaded. Please remove root diskette. \n\n"); } --- 282,301 ----- m1.COUNT = count; if (sendrec(MEM, &m1) != OK) panic("Can't report size to MEM", NO_NUM); ! if (fLoadRam) ! { ! /* Copy the blocks one at a time from the root diskette to the RAM */ ! printf("Loading RAM disk from root diskette. Loaded: 0K "); ! for (i = 0; i < count; i++) { ! bp = get_block(BOOT_DEV, (block_nr) i, NORMAL); ! bp1 = get_block(ROOT_DEV, i, NO_READ); ! copy(bp1->b_data, bp->b_data, BLOCK_SIZE); ! bp1->b_dirt = DIRTY; ! put_block(bp, I_MAP_BLOCK); ! put_block(bp1, I_MAP_BLOCK); ! k_loaded = ( (long) i * BLOCK_SIZE)/1024L; /* K loaded so far */ ! if (k_loaded % 5 == 0) printf("\b\b\b\b\b%3DK %c", k_loaded, 0); ! } printf("\rRAM disk loaded. Please remove root diskette. \n\n"); } *************** *** 273,279 if (k_loaded % 5 == 0) printf("\b\b\b\b\b%3DK %c", k_loaded, 0); } ! printf("\rRAM disk loaded. Please remove root diskette. \n\n"); } --- 297,304 ----- if (k_loaded % 5 == 0) printf("\b\b\b\b\b%3DK %c", k_loaded, 0); } ! printf("\rRAM disk loaded. Please remove root diskette. \n\n"); ! } } ------------------------------------------------------------ *** super.c Sat Aug 1 13:38:24 1987 --- ../../dos/fs/super.c Sat Aug 1 13:33:15 1987 *************** *** 22,27 #include "buf.h" #include "inode.h" #include "super.h" #define INT_BITS (sizeof(int)<<3) #define BIT_MAP_SHIFT 13 /* (log2 of BLOCK_SIZE) + 3; 13 for 1k blocks */ --- 22,28 ----- #include "buf.h" #include "inode.h" #include "super.h" + #include "glo.h" #define INT_BITS (sizeof(int)<<3) #define BIT_MAP_SHIFT 13 /* (log2 of BLOCK_SIZE) + 3; 13 for 1k blocks */
ericr@ipmoea.UUCP (Eric Roskos) (08/09/87)
Directory: /usr2/ericr/minix/minix/h ------------------------------------------------------------ *** const.h Sat Aug 1 13:34:29 1987 --- ../../dos/h/const.h Sat Aug 1 13:28:34 1987 *************** *** 58,66 #define SIG_PUSH_BYTES 8 /* how many bytes pushed by signal */ #define MAX_ISTACK_BYTES 1024 /* maximum initial stack size for EXEC */ ! /* Device numbers of root (RAM) and boot (fd0) devices. */ ! #define ROOT_DEV (dev_nr) 256 /* major-minor device number of root dev */ ! #define BOOT_DEV (dev_nr) 512 /* major-minor device number of boot diskette */ /* Flag bits for i_mode in the inode. */ #define I_TYPE 0170000 /* this field gives inode type */ --- 58,78 ----- #define SIG_PUSH_BYTES 8 /* how many bytes pushed by signal */ #define MAX_ISTACK_BYTES 1024 /* maximum initial stack size for EXEC */ ! /* ! * Device numbers for minor dev 0 of winchester, floppy, and RAM disk. ! * These are used to determine where to find the root filesystem; ! * see load_ram in kernel/main.c for algorithm. - JER 7/29/87 ! */ ! #define DEV_RAM ((dev_nr) 0x0100) ! #define DEV_FLOPPY ((dev_nr) 0x0200) ! #define DEV_WINI ((dev_nr) 0x0300) ! ! /* Device numbers of root and boot devices. */ ! #define ROOT_DEV (dev_nr) root_dev /* major-minor device number of root dev */ ! #define BOOT_DEV (dev_nr) DEV_FLOPPY /* major-minor device number of boot diskette */ ! ! /* Minimum number of blocks for RAM disk (size if root != RAM) */ ! #define RAM_MIN 1 /* Flag bits for i_mode in the inode. */ #define I_TYPE 0170000 /* this field gives inode type */
ericr@ipmoea.UUCP (Eric Roskos) (08/10/87)
Directory: /usr2/ericr/minix/minix/lib ------------------------------------------------------------ *** catchsig.asm Sat Aug 1 13:36:05 1987 --- ../../dos/lib/catchsig.asm Sat Aug 1 13:30:07 1987 *************** *** 3,10 INCLUDE ..\lib\prologue.h ! PUBLIC begsig ! EXTRN vectab:WORD, M:WORD @CODE SEGMENT --- 3,10 ----- INCLUDE ..\lib\prologue.h ! PUBLIC _begsig ! EXTRN _vectab:WORD, _M:WORD _TEXT SEGMENT *************** *** 7,14 EXTRN vectab:WORD, M:WORD ! @CODE SEGMENT ! ASSUME CS:@CODE,DS:DGROUP MTYPE = 2 ; M+mtype = &M.m_type begsig: --- 7,14 ----- EXTRN _vectab:WORD, _M:WORD ! _TEXT SEGMENT ! ASSUME CS:_TEXT,DS:DGROUP MTYPE = 2 ; M+mtype = &M.m_type _begsig: *************** *** 11,17 ASSUME CS:@CODE,DS:DGROUP MTYPE = 2 ; M+mtype = &M.m_type ! begsig: push ax ; after interrupt, save all regs push bx push cx --- 11,17 ----- ASSUME CS:_TEXT,DS:DGROUP MTYPE = 2 ; M+mtype = &M.m_type ! _begsig: push ax ; after interrupt, save all regs push bx push cx *************** *** 25,32 mov bx,18[bp] ; bx = signal number dec bx ; vectab[0] is for sig 1 add bx,bx ; pointers are two bytes on 8088 ! mov bx,vectab[bx] ; bx = address of routine to call ! push M+mtype ; push status of last system call push ax ; func called with signal number as arg call bx back: --- 25,32 ----- mov bx,18[bp] ; bx = signal number dec bx ; vectab[0] is for sig 1 add bx,bx ; pointers are two bytes on 8088 ! mov bx,_vectab[bx] ; bx = address of routine to call ! push _M+mtype ; push status of last system call push ax ; func called with signal number as arg call bx back: *************** *** 31,37 call bx back: pop ax ; get signal number off stack ! pop M+mtype ; restore status of previous system call pop es ; signal handling finished pop ds pop bp --- 31,37 ----- call bx back: pop ax ; get signal number off stack ! pop _M+mtype ; restore status of previous system call pop es ; signal handling finished pop ds pop bp *************** *** 43,49 pop ax pop dummy ; remove signal number from stack iret ! @CODE ENDS @DATAI SEGMENT dummy DW 0 --- 43,49 ----- pop ax pop dummy ; remove signal number from stack iret ! _TEXT ENDS _DATA SEGMENT dummy DW 0 *************** *** 45,51 iret @CODE ENDS ! @DATAI SEGMENT dummy DW 0 @DATAI ENDS --- 45,51 ----- iret _TEXT ENDS ! _DATA SEGMENT dummy DW 0 _DATA ENDS *************** *** 47,52 @DATAI SEGMENT dummy DW 0 ! @DATAI ENDS END ; end of assembly-file --- 47,52 ----- _DATA SEGMENT dummy DW 0 ! _DATA ENDS END ; end of assembly-file ------------------------------------------------------------ *** crtso.asm Sat Aug 1 13:36:11 1987 --- ../../dos/lib/crtso.asm Sat Aug 1 13:30:18 1987 *************** *** 3,10 ! PUBLIC @end, brksize, edata, $main, environ, kamikaze ! EXTRN main:NEAR, exit:NEAR INCLUDE ..\lib\prologue.h --- 3,10 ----- ! PUBLIC _end, _brksize, _edata, $main, _environ, _kamikaze ! EXTRN _main:NEAR, _exit:NEAR INCLUDE ..\lib\prologue.h *************** *** 10,15 STACKSIZE EQU 2560 ; default stack is 5 Kb (2K words) @CODE SEGMENT --- 10,17 ----- STACKSIZE EQU 2560 ; default stack is 5 Kb (2K words) + PUBLIC __acrtused + __acrtused EQU 9876H ; used by MSC to pull in startup routine *************** *** 12,19 - @CODE SEGMENT - ASSUME CS:@CODE,DS:DGROUP ; This is the C run-time start-off routine. It's job is to take the ; arguments as put on the stack by EXEC, and to parse them and set them up the --- 14,19 ----- __acrtused EQU 9876H ; used by MSC to pull in startup routine _TEXT SEGMENT ASSUME CS:_TEXT,DS:DGROUP *************** *** 15,20 @CODE SEGMENT ASSUME CS:@CODE,DS:DGROUP ; This is the C run-time start-off routine. It's job is to take the ; arguments as put on the stack by EXEC, and to parse them and set them up the ; way main expects them. --- 15,23 ----- + _TEXT SEGMENT + ASSUME CS:_TEXT,DS:DGROUP + ; This is the C run-time start-off routine. It's job is to take the ; arguments as put on the stack by EXEC, and to parse them and set them up the ; way main expects them. *************** *** 29,35 inc ax ; calculate envp shl ax,1 add ax,bx ! mov environ,ax ; save envp push ax ; stack envp push bx ; stack argv push cx ; stack argc --- 32,38 ----- inc ax ; calculate envp shl ax,1 add ax,bx ! mov _environ,ax ; save envp push ax ; stack envp push bx ; stack argv push cx ; stack argc *************** *** 34,40 push bx ; stack argv push cx ; stack argc ! call main ; call main (arc,argv,envp) add sp,6 push ax ; stack program-termination status --- 37,43 ----- push bx ; stack argv push cx ; stack argc ! call _main ; call main (arc,argv,envp) add sp,6 push ax ; stack program-termination status *************** *** 38,44 add sp,6 push ax ; stack program-termination status ! call exit ; this will never return ; DEBUG from here on --- 41,47 ----- add sp,6 push ax ; stack program-termination status ! call _exit ; this will never return ; DEBUG from here on *************** *** 42,48 ; DEBUG from here on ! kamikaze: int 3 ret @CODE ENDS --- 45,51 ----- ; DEBUG from here on ! _kamikaze: int 3 ret _TEXT ENDS *************** *** 45,51 kamikaze: int 3 ret ! @CODE ENDS @DATAC SEGMENT --- 48,54 ----- _kamikaze: int 3 ret ! _TEXT ENDS _DATA SEGMENT *************** *** 48,57 @CODE ENDS ! @DATAC SEGMENT ! brksize DW offset dgroup:@END+2 ; dynamic changeable end of bss ! environ DW 0 ; save environment pointer here ! @DATAC ENDS @DATAT SEGMENT ; DATAT holds nothing. The label just edata label byte ; tells us where the initialized data --- 51,60 ----- _TEXT ENDS ! _DATA SEGMENT ! _brksize DW offset dgroup:_END+2 ; dynamic changeable end of bss ! _environ DW 0 ; save environment pointer here ! _DATA ENDS _DATAT SEGMENT ; DATAT holds nothing. The label just _edata label byte ; tells us where the initialized data *************** *** 53,61 environ DW 0 ; save environment pointer here @DATAC ENDS ! @DATAT SEGMENT ; DATAT holds nothing. The label just ! edata label byte ; tells us where the initialized data ! @DATAT ENDS ; (.data) ends. @DATAV SEGMENT ; DATAV holds nothing. The label in @end label byte ; the segment just tells us where --- 56,64 ----- _environ DW 0 ; save environment pointer here _DATA ENDS ! _DATAT SEGMENT ; DATAT holds nothing. The label just ! _edata label byte ; tells us where the initialized data ! _DATAT ENDS ; (.data) ends. _DATAV SEGMENT ; DATAV holds nothing. The label in _end label byte ; the segment just tells us where *************** *** 57,65 edata label byte ; tells us where the initialized data @DATAT ENDS ; (.data) ends. ! @DATAV SEGMENT ; DATAV holds nothing. The label in ! @end label byte ; the segment just tells us where ! @DATAV ENDS ; the data+bss ends. @STACK SEGMENT BYTE STACK 'STACK' DW STACKSIZE dup(?) ; add stack segment to bss --- 60,68 ----- _edata label byte ; tells us where the initialized data _DATAT ENDS ; (.data) ends. ! _DATAV SEGMENT ; DATAV holds nothing. The label in ! _end label byte ; the segment just tells us where ! _DATAV ENDS ; the data+bss ends. _STACK SEGMENT BYTE STACK 'STACK' DW STACKSIZE dup(?) ; add stack segment to bss *************** *** 61,67 @end label byte ; the segment just tells us where @DATAV ENDS ; the data+bss ends. ! @STACK SEGMENT BYTE STACK 'STACK' DW STACKSIZE dup(?) ; add stack segment to bss @STACK ENDS --- 64,70 ----- _end label byte ; the segment just tells us where _DATAV ENDS ; the data+bss ends. ! _STACK SEGMENT BYTE STACK 'STACK' DW STACKSIZE dup(?) ; add stack segment to bss _STACK ENDS *************** *** 63,69 @STACK SEGMENT BYTE STACK 'STACK' DW STACKSIZE dup(?) ; add stack segment to bss ! @STACK ENDS END $main ; program entry-point (could be anywhere) --- 66,72 ----- _STACK SEGMENT BYTE STACK 'STACK' DW STACKSIZE dup(?) ; add stack segment to bss ! _STACK ENDS END $main ; program entry-point (could be anywhere) ------------------------------------------------------------ *** getutil.asm Sat Aug 1 13:35:51 1987 --- ../../dos/lib/getutil.asm Sat Aug 1 13:29:47 1987 *************** *** 4,11 INCLUDE ..\lib\prologue.h ! PUBLIC get_base, get_size, get_tot_ ! EXTRN brksize:WORD, @end:byte @CODE SEGMENT --- 4,11 ----- INCLUDE ..\lib\prologue.h ! PUBLIC _get_base, _get_size, _get_tot_mem ! EXTRN _brksize:WORD, _end:byte _TEXT SEGMENT *************** *** 8,15 EXTRN brksize:WORD, @end:byte ! @CODE SEGMENT ! ASSUME CS:@CODE,DS:DGROUP ;======================================================================== ; utilities --- 8,15 ----- EXTRN _brksize:WORD, _end:byte ! _TEXT SEGMENT ! ASSUME CS:_TEXT,DS:DGROUP ;======================================================================== ; utilities *************** *** 15,21 ; utilities ;======================================================================== ! get_base: ; return click at which prog starts mov ax,ds ret --- 15,21 ----- ; utilities ;======================================================================== ! _get_base: ; return click at which prog starts mov ax,ds ret *************** *** 19,26 mov ax,ds ret ! get_size: ; return prog size in bytes [text+data+bss] ! mov ax,offset dgroup:@end ; end is label at end of bss ret ; Find out how much memory the machine has, including vectors, kernel MM, etc. --- 19,26 ----- mov ax,ds ret ! _get_size: ; return prog size in bytes [text+data+bss] ! mov ax,offset dgroup:_end ; end is label at end of bss ret ; Find out how much memory the machine has, including vectors, kernel MM, etc. *************** *** 24,30 ret ; Find out how much memory the machine has, including vectors, kernel MM, etc. ! get_tot_: cli push es push di --- 24,30 ----- ret ; Find out how much memory the machine has, including vectors, kernel MM, etc. ! _get_tot_mem: cli push es push di *************** *** 44,49 sti ret ! @CODE ENDS END ; end of assembly-file --- 44,49 ----- sti ret ! _TEXT ENDS END ; end of assembly-file ------------------------------------------------------------ *** head.asm Sat Aug 1 13:36:11 1987 --- ../../dos/lib/head.asm Sat Aug 1 13:30:14 1987 *************** *** 1,4 ! title Head - Start-off for initt, mm and fs (C86-compiler) page ,132 EXTRN main:NEAR --- 1,4 ----- ! title Head - Start-off for init, mm and fs (C86-compiler) page ,132 PUBLIC __acrtused ; magic symbol for MSC (indicates startup present) *************** *** 1,9 title Head - Start-off for initt, mm and fs (C86-compiler) page ,132 ! EXTRN main:NEAR ! PUBLIC $main, data_org, brksize, sp_limit, @end ! EXTRN stackpt:word INCLUDE ..\lib\prologue.h --- 1,8 ----- title Head - Start-off for init, mm and fs (C86-compiler) page ,132 ! PUBLIC __acrtused ; magic symbol for MSC (indicates startup present) ! __acrtused EQU 9876H EXTRN _main:NEAR PUBLIC $main, _data_org, _brksize, _sp_limit, _end *************** *** 5,10 PUBLIC $main, data_org, brksize, sp_limit, @end EXTRN stackpt:word INCLUDE ..\lib\prologue.h --- 4,13 ----- PUBLIC __acrtused ; magic symbol for MSC (indicates startup present) __acrtused EQU 9876H + EXTRN _main:NEAR + PUBLIC $main, _data_org, _brksize, _sp_limit, _end + EXTRN _stackpt:word, + INCLUDE ..\lib\prologue.h *************** *** 8,15 INCLUDE ..\lib\prologue.h ! @CODE SEGMENT ! assume cs:@code,ds:dgroup $main: jmp short L0 ORG 10h ; kernel uses this area as stack for inital IRET --- 11,18 ----- INCLUDE ..\lib\prologue.h ! _TEXT SEGMENT ! assume cs:_TEXT,ds:dgroup $main: jmp short L0 ORG 10h ; kernel uses this area as stack for inital IRET *************** *** 13,20 $main: jmp short L0 ORG 10h ; kernel uses this area as stack for inital IRET ! L0:mov sp,dgroup:stackpt ! call main L1:jmp L1 ; this will never be executed mov ax,DGROUP ; force relocation for dos2out (never executed) --- 16,23 ----- $main: jmp short L0 ORG 10h ; kernel uses this area as stack for inital IRET ! L0:mov sp,dgroup:_stackpt ! call _main L1:jmp L1 ; this will never be executed mov ax,DGROUP ; force relocation for dos2out (never executed) *************** *** 18,24 L1:jmp L1 ; this will never be executed mov ax,DGROUP ; force relocation for dos2out (never executed) ! @CODE ENDS @DATAB SEGMENT ; fs needs to know where build stuffed table --- 21,27 ----- L1:jmp L1 ; this will never be executed mov ax,DGROUP ; force relocation for dos2out (never executed) ! _TEXT ENDS _DATAB SEGMENT ; fs needs to know where build stuffed table *************** *** 21,28 @CODE ENDS ! @DATAB SEGMENT ; fs needs to know where build stuffed table ! data_org DW 0DADAh ; 0xDADA is magic number for build DW 7 dup(0) ; first 8 words of MM, FS, INIT are for stack brksize DW offset dgroup:@END ; first free memory sp_limit DW 0 --- 24,31 ----- _TEXT ENDS ! _DATAB SEGMENT ; fs needs to know where build stuffed table ! _data_org DW 0DADAh ; 0xDADA is magic number for build DW 7 dup(0) ; first 8 words of MM, FS, INIT are for stack _brksize DW offset dgroup:_END ; first free memory _sp_limit DW 0 *************** *** 24,32 @DATAB SEGMENT ; fs needs to know where build stuffed table data_org DW 0DADAh ; 0xDADA is magic number for build DW 7 dup(0) ; first 8 words of MM, FS, INIT are for stack ! brksize DW offset dgroup:@END ; first free memory ! sp_limit DW 0 ! @DATAB ENDS @DATAV SEGMENT ; DATAV holds nothing. The label in @END label byte ; the segment just tells us where --- 27,35 ----- _DATAB SEGMENT ; fs needs to know where build stuffed table _data_org DW 0DADAh ; 0xDADA is magic number for build DW 7 dup(0) ; first 8 words of MM, FS, INIT are for stack ! _brksize DW offset dgroup:_END ; first free memory ! _sp_limit DW 0 ! _DATAB ENDS _DATAV SEGMENT ; DATAV holds nothing. The label in _END label byte ; the segment just tells us where *************** *** 28,36 sp_limit DW 0 @DATAB ENDS ! @DATAV SEGMENT ; DATAV holds nothing. The label in ! @END label byte ; the segment just tells us where ! @DATAV ENDS ; the data+bss ends. @STACK SEGMENT BYTE STACK 'STACK' @STACK ENDS ; Add stack to satisfy DOS-linker --- 31,39 ----- _sp_limit DW 0 _DATAB ENDS ! _DATAV SEGMENT ; DATAV holds nothing. The label in ! _END label byte ; the segment just tells us where ! _DATAV ENDS ; the data+bss ends. @STACK SEGMENT BYTE STACK 'STACK' @STACK ENDS ; Add stack to satisfy DOS-linker ------------------------------------------------------------ *** message.c Sat Aug 1 13:36:05 1987 --- ../../dos/lib/message.c Sat Aug 1 13:30:10 1987 *************** *** 1,4 #include "../h/const.h" #include "../h/type.h" ! message M; --- 1,4 ----- #include "../h/const.h" #include "../h/type.h" ! message M = {0}; /* dummy init so linker will recognize this symbol */ ------------------------------------------------------------ *** prologue.h Sat Aug 1 13:35:57 1987 --- ../../dos/lib/prologue.h Sat Aug 1 13:29:52 1987 *************** *** 1,6 ; prologue.h ! ; standard prologue for c86 assembly code ; This file defines the correct ordering of segments @CODE SEGMENT BYTE PUBLIC 'CODE' ; text segment --- 1,6 ----- ; prologue.h ! ; standard prologue for MSC assembly code ; This file defines the correct ordering of segments ifdef debug *************** *** 3,22 ; standard prologue for c86 assembly code ; This file defines the correct ordering of segments ! @CODE SEGMENT BYTE PUBLIC 'CODE' ; text segment ! @CODE ENDS ! @DATAB SEGMENT PARA PUBLIC 'DATAB' ; data segment ! @DATAB ENDS ! @DATAC SEGMENT BYTE PUBLIC 'DATAC' ; data segment ! @DATAC ENDS ! @DATAI SEGMENT BYTE PUBLIC 'DATAI' ; data segment ! @DATAI ENDS ! @DATAT SEGMENT BYTE PUBLIC 'DATAT' ; bss segment ! @DATAT ENDS ! @DATAU SEGMENT BYTE PUBLIC 'DATAU' ; bss segment ! @DATAU ENDS ! @DATAV SEGMENT BYTE PUBLIC 'DATAV' ; bss segment ! @DATAV ENDS DGROUP GROUP @DATAB,@DATAC,@DATAI,@DATAT,@DATAU,@DATAV --- 3,13 ----- ; standard prologue for MSC assembly code ; This file defines the correct ordering of segments ! ifdef debug ! if1 ! %out Debug messages enabled ! endif ! endif _TEXT SEGMENT BYTE PUBLIC 'CODE' _TEXT ENDS *************** *** 18,22 @DATAV SEGMENT BYTE PUBLIC 'DATAV' ; bss segment @DATAV ENDS DGROUP GROUP @DATAB,@DATAC,@DATAI,@DATAT,@DATAU,@DATAV --- 9,32 ----- endif endif + _TEXT SEGMENT BYTE PUBLIC 'CODE' + _TEXT ENDS + _DATAB SEGMENT PARA PUBLIC 'DATA' + _DATAB ENDS + _DATA SEGMENT BYTE PUBLIC 'DATA' + _DATA ENDS + CONST SEGMENT BYTE PUBLIC 'CONST' + CONST ENDS + _DATAT SEGMENT BYTE PUBLIC 'CONST' + _DATAT ENDS + _BSS SEGMENT BYTE PUBLIC 'BSS' + _BSS ENDS + C_COMMON SEGMENT BYTE PUBLIC 'BSS' + C_COMMON ENDS + _DATAU SEGMENT BYTE PUBLIC 'BSS' + _DATAU ENDS + _DATAV SEGMENT BYTE PUBLIC 'BSS' + _DATAV ENDS DGROUP GROUP _DATAB, _DATA, CONST, _DATAT, _BSS, C_COMMON, _DATAV *************** *** 19,22 @DATAV ENDS ! DGROUP GROUP @DATAB,@DATAC,@DATAI,@DATAT,@DATAU,@DATAV --- 28,60 ----- _DATAV SEGMENT BYTE PUBLIC 'BSS' _DATAV ENDS ! DGROUP GROUP _DATAB, _DATA, CONST, _DATAT, _BSS, C_COMMON, _DATAV ! ! ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP ! ! ; ! ; Debugging message macro - JER ! ; ! ! wto macro mesg ! local msgstr ! ! ifdef debug ! ! public msgstr ; DEBUG so we can find it in the linker map ! _data segment ! msgstr db mesg ! db 0dH,0aH,00H ! _data ends ! ! push ax ! push bx ! mov bx,offset msgstr ! mov ax,bx ;DEBUG ! call prtax ;DEBUG ! call near ptr print ! pop bx ! pop ax ! ! endif ! endm ------------------------------------------------------------ *** sendrec.asm Sat Aug 1 13:36:00 1987 --- ../../dos/lib/sendrec.asm Sat Aug 1 13:30:04 1987 *************** *** 3,9 INCLUDE ..\lib\prologue.h ! PUBLIC send, receive, send_rec, sendrec ; The following definitions are from ../h/com.h --- 3,9 ----- INCLUDE ..\lib\prologue.h ! PUBLIC _send, _receive, _send_rec, _sendrec ; The following definitions are from ../h/com.h *************** *** 8,17 ; The following definitions are from ../h/com.h ! _SEND = 1 ! _RECEIVE= 2 ! _BOTH = 3 ! _SYSVEC = 32 @CODE SEGMENT --- 8,17 ----- ; The following definitions are from ../h/com.h ! SEND = 1 ! RECEIVE= 2 ! BOTH = 3 ! SYSVEC = 32 _TEXT SEGMENT *************** *** 14,21 _SYSVEC = 32 ! @CODE SEGMENT ! ASSUME CS:@CODE,DS:DGROUP ;======================================================================== ; send and receive --- 14,21 ----- SYSVEC = 32 ! _TEXT SEGMENT ! ASSUME CS:_TEXT,DS:DGROUP ;======================================================================== ; send and receive *************** *** 22,28 ;======================================================================== ; send(), receive(), send_rec() all save bp, but destroy ax, bx, and cx. ! send: mov cx,_SEND ; send(dest, ptr) jmp L0 receive: --- 22,28 ----- ;======================================================================== ; send(), receive(), send_rec() all save bp, but destroy ax, bx, and cx. ! _send: mov cx,SEND ; send(dest, ptr) jmp L0 _receive: *************** *** 25,32 send: mov cx,_SEND ; send(dest, ptr) jmp L0 ! receive: ! mov cx,_RECEIVE ; receive(src, ptr) jmp L0 sendrec: --- 25,32 ----- _send: mov cx,SEND ; send(dest, ptr) jmp L0 ! _receive: ! mov cx,RECEIVE ; receive(src, ptr) jmp L0 _sendrec: *************** *** 29,37 mov cx,_RECEIVE ; receive(src, ptr) jmp L0 ! sendrec: ! send_rec: ! mov cx,_BOTH ; send_rec(srcdest, ptr) jmp L0 L0: push bp ; save bp --- 29,37 ----- mov cx,RECEIVE ; receive(src, ptr) jmp L0 ! _sendrec: ! _send_rec: ! mov cx,BOTH ; send_rec(srcdest, ptr) jmp L0 L0: push bp ; save bp *************** *** 38,44 mov bp,sp ; can't index off sp mov ax,4[bp] ; ax = dest-src mov bx,6[bp] ; bx = message pointer ! int _SYSVEC ; trap to the kernel pop bp ; restore bp ret ; return --- 38,44 ----- mov bp,sp ; can't index off sp mov ax,4[bp] ; ax = dest-src mov bx,6[bp] ; bx = message pointer ! int SYSVEC ; trap to the kernel pop bp ; restore bp ret ; return *************** *** 42,47 pop bp ; restore bp ret ; return ! @CODE ENDS END ; end of assembly-file --- 42,47 ----- pop bp ; restore bp ret ; return ! _TEXT ENDS END ; end of assembly-file
ericr@ipmoea.UUCP (Eric Roskos) (08/21/87)
Directory: /usr2/ericr/minix/minix/tools ------------------------------------------------------------ *** ar.c Sat Aug 1 13:37:47 1987 --- ../../dos/tools/ar.c Sat Aug 1 13:32:37 1987 *************** *** 11,17 * p: print named files */ ! #include "stat.h" #include "signal.h" #define MAGIC_NUMBER 0177545 --- 11,19 ----- * p: print named files */ ! #include "sys/types.h" ! #include "sys/stat.h" ! #include "fcntl.h" #include "signal.h" #define MAGIC_NUMBER 0177545 *************** *** 52,58 #define NIL_MEM ((MEMBER *) 0) #define NIL_LONG ((long *) 0) ! #define IO_SIZE (10 * 1024) #define BLOCK_SIZE 1024 #define flush() print(NIL_PTR) --- 54,60 ----- #define NIL_MEM ((MEMBER *) 0) #define NIL_LONG ((long *) 0) ! #define IO_SIZE (4 * 1024) #define BLOCK_SIZE 1024 #define flush() print(NIL_PTR) *************** *** 84,89 BOOL quit; char *str1, *str2; { write(2, str1, strlen(str1)); if (str2 != NIL_PTR) write(2, str2, strlen(str2)); --- 86,92 ----- BOOL quit; char *str1, *str2; { + perror("ar"); write(2, str1, strlen(str1)); if (str2 != NIL_PTR) write(2, str2, strlen(str2)); *************** *** 129,135 return fd; } ! if ((fd = open(name, mode)) < 0) { if (mode == APPEND) { (void) close(open_archive(name, CREATE)); error(FALSE, "ar: creating ", name); --- 132,138 ----- return fd; } ! if ((fd = open(name, mode|O_BINARY)) < 0) { if (mode == APPEND) { (void) close(open_archive(name, CREATE|O_BINARY)); error(FALSE, "ar: creating ", name); *************** *** 131,137 if ((fd = open(name, mode)) < 0) { if (mode == APPEND) { ! (void) close(open_archive(name, CREATE)); error(FALSE, "ar: creating ", name); return open_archive(name, APPEND); } --- 134,140 ----- if ((fd = open(name, mode|O_BINARY)) < 0) { if (mode == APPEND) { ! (void) close(open_archive(name, CREATE|O_BINARY)); error(FALSE, "ar: creating ", name); return open_archive(name, APPEND|O_BINARY); } *************** *** 133,139 if (mode == APPEND) { (void) close(open_archive(name, CREATE)); error(FALSE, "ar: creating ", name); ! return open_archive(name, APPEND); } error(TRUE, "Cannot open ", name); } --- 136,142 ----- if (mode == APPEND) { (void) close(open_archive(name, CREATE|O_BINARY)); error(FALSE, "ar: creating ", name); ! return open_archive(name, APPEND|O_BINARY); } error(TRUE, "Cannot open ", name); } *************** *** 437,446 mode_buf[i * 3 + 2] = (tmp & S_IEXEC) ? 'x' : '-'; tmp <<= 3; } - if (mode & S_ISUID) - mode_buf[2] = 's'; - if (mode & S_ISGID) - mode_buf[5] = 's'; print(mode_buf); } --- 440,445 ----- mode_buf[i * 3 + 2] = (tmp & S_IEXEC) ? 'x' : '-'; tmp <<= 3; } print(mode_buf); } ------------------------------------------------------------ *** build.c Sat Aug 1 13:37:43 1987 --- ../../dos/tools/build.c Sat Aug 1 13:32:32 1987 *************** *** 1,3 /* This program takes the previously compiled and linked pieces of the * operating system, and puts them together to build a boot diskette. * The files are read and put on the boot diskette in this order: --- 1,5 ----- + #define C_DISKIO /* use JER's diskio for MSC */ + /* This program takes the previously compiled and linked pieces of the * operating system, and puts them together to build a boot diskette. * The files are read and put on the boot diskette in this order: *************** *** 41,46 * to get the resulting image onto the file "image". */ #define PROGRAMS 5 /* kernel + mm + fs + init + fsck = 5 */ #define PROG_ORG 1536 /* where does kernel begin in abs mem */ --- 43,53 ----- * to get the resulting image onto the file "image". */ + #ifdef MSDOS + #include <stdio.h> + #include <fcntl.h> + #include <dos.h> + #endif #define PROGRAMS 5 /* kernel + mm + fs + init + fsck = 5 */ #define PROG_ORG 1536 /* where does kernel begin in abs mem */ *************** *** 67,73 #define SEP_ID_BIT 0x20 /* bit that tells if file is separate I & D */ #ifdef MSDOS ! # define BREAD 4 /* value 0 means ASCII read */ #else # define BREAD 0 #endif --- 74,80 ----- #define SEP_ID_BIT 0x20 /* bit that tells if file is separate I & D */ #ifdef MSDOS ! # define BREAD (O_RDONLY|O_BINARY) /* value 0 means ASCII read */ #else error - not tested for non-dos with this version # define BREAD 0 *************** *** 69,74 #ifdef MSDOS # define BREAD 4 /* value 0 means ASCII read */ #else # define BREAD 0 #endif --- 76,82 ----- #ifdef MSDOS # define BREAD (O_RDONLY|O_BINARY) /* value 0 means ASCII read */ #else + error - not tested for non-dos with this version # define BREAD 0 #endif *************** *** 114,121 printf("Operating system size %29ld %5lx\n", cum_size, cum_size); printf("\nTotal size including fsck is %ld.\n", all_size); #else ! printf("Operating system size %29D %5X\n", cum_size, cum_size); ! printf("\nTotal size including fsck is %D.\n", all_size); #endif /* Make the three patches to the output file or diskette. */ --- 122,129 ----- printf("Operating system size %29ld %5lx\n", cum_size, cum_size); printf("\nTotal size including fsck is %ld.\n", all_size); #else ! printf("Operating system size %29ld %5lx\n", cum_size, cum_size); ! printf("\nTotal size including fsck is %ld.\n", all_size); #endif /* Make the three patches to the output file or diskette. */ *************** *** 166,172 unsigned text_bytes, data_bytes, bss_bytes, tot_bytes, rest, filler; unsigned left_to_read; char inbuf[READ_UNIT]; ! if ( (fd = open(file_name, BREAD)) < 0) pexit("can't open ", file_name); /* Read the header to see how big the segments are. */ --- 174,180 ----- unsigned text_bytes, data_bytes, bss_bytes, tot_bytes, rest, filler; unsigned left_to_read; char inbuf[READ_UNIT]; ! if ( (fd = open(file_name, BREAD)) < 0) pexit("can't open ", file_name); /* Read the header to see how big the segments are. */ *************** *** 192,198 sizes[num].sep_id = sepid; /* Print a message giving the program name and size, except for fsck. */ ! if (num < FSCK) { printf("%s text=%5u data=%5u bss=%5u tot=%5u hex=%4x %s\n", name[num], text_bytes, data_bytes, bss_bytes, tot_bytes, tot_bytes, (sizes[num].sep_id ? "Separate I & D" : "")); --- 200,207 ----- sizes[num].sep_id = sepid; /* Print a message giving the program name and size, except for fsck. */ ! if (num < FSCK) ! { printf("%s text=%5u data=%5u bss=%5u tot=%5u hex=%4x %s\n", name[num], text_bytes, data_bytes, bss_bytes, tot_bytes, tot_bytes, (sizes[num].sep_id ? "Separate I & D" : "")); *************** *** 374,379 data_offset = 512L + (long)sizes[KERN].text_size; /* start of kernel data */ i = (get_byte(data_offset+1L) << 8) + get_byte(data_offset); if (i != KERNEL_D_MAGIC) { pexit("kernel data space: no magic #",""); } --- 383,389 ----- data_offset = 512L + (long)sizes[KERN].text_size; /* start of kernel data */ i = (get_byte(data_offset+1L) << 8) + get_byte(data_offset); if (i != KERNEL_D_MAGIC) { + printf("Magic number in kernel is %x: should be %x\n",i,KERNEL_D_MAGIC); pexit("kernel data space: no magic #",""); } *************** *** 399,404 ds = PROG_ORG >> CLICK_SHIFT; /* combined I & D space */ else ds = (PROG_ORG + sizes[KERN].text_size) >> CLICK_SHIFT; /* separate */ put_byte(512L + DS_OFFSET, ds & 0377); put_byte(512L + DS_OFFSET + 1L, (ds>>8) & 0377); } --- 409,415 ----- ds = PROG_ORG >> CLICK_SHIFT; /* combined I & D space */ else ds = (PROG_ORG + sizes[KERN].text_size) >> CLICK_SHIFT; /* separate */ + printf("Kernel DS = %x\n", ds); put_byte(512L + DS_OFFSET, ds & 0377); put_byte(512L + DS_OFFSET + 1L, (ds>>8) & 0377); } *************** *** 546,551 buff = buff1; } read_block (blocknr,user) int blocknr; --- 557,563 ----- buff = buff1; } + #ifdef C_DISKIO int DMAoverrun(buff1) char *buff1; *************** *** 547,552 } read_block (blocknr,user) int blocknr; char user[SECTOR_SIZE]; --- 559,626 ----- #ifdef C_DISKIO + int DMAoverrun(buff1) + char *buff1; + { + int i; + + i = (int)buff1; + return(i > i + SECTOR_SIZE); + } + + int + absio(fn, drive, blocknr, buff) + int fn; + int drive; + int blocknr; + char *buff; + { + union REGS iregs; + union REGS oregs; + int track; + + iregs.h.ah = fn; + iregs.h.dl = drive; + track = blocknr / 9; + iregs.h.dh = track & 1; + iregs.h.ch = track >> 1; + iregs.h.cl = (blocknr % 9) + 1; + iregs.h.al = 1; + iregs.x.bx = (int)buff; + + int86(0x13, &iregs, &oregs); + + if (oregs.x.cflag) + { + fprintf(stderr, "absio: error %sing drv %c block %d address %x: bios code %x\n", + fn==2? "read" : "writ", 'A'+drive, blocknr, buff, oregs.h.ah&0xff); + return(oregs.x.ax); + } + else + { + return(0); + } + } + + int + absread(drive, blocknr, buff) + int drive; + int blocknr; + char *buff; + { + return(absio(2, drive, blocknr, buff)); + } + + int + abswrite(drive, blocknr, buff) + int drive; + int blocknr; + char *buff; + { + return(absio(3, drive, blocknr, buff)); + } + #endif + read_block (blocknr,user) int blocknr; char user[SECTOR_SIZE]; *************** *** 609,615 drive = (s[0] & ~32) - 'A'; if (drive<0 || drive>32) pexit ("no such drive: ",s); printf("Put a blank, formatted diskette in drive %s\nHit return when ready",s); ! gets (kbstr,10); puts(""); } --- 683,689 ----- drive = (s[0] & ~32) - 'A'; if (drive<0 || drive>32) pexit ("no such drive: ",s); printf("Put a blank, formatted diskette in drive %s\nHit return when ready",s); ! gets(kbstr); puts(""); } ------------------------------------------------------------ *** dos2out.c Sat Aug 1 13:37:45 1987 --- ../../dos/tools/dos2out.c Sat Aug 1 13:32:34 1987 *************** *** 97,103 #define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */ ! #include "/lib/C86/stdio.h" #define PH_SECTSIZE 512 /* size of a disk-block */ --- 97,104 ----- #define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */ ! #include <stdio.h> ! #include <fcntl.h> #define PH_SECTSIZE 512 /* size of a disk-block */ *************** *** 109,116 unsigned char inbuf2[PH_SECTSIZE]; unsigned char outbuf[PH_SECTSIZE]; ! struct a_out_hdr *a_ptr= outbuf; ! struct d_fmt_hdr *d_ptr= inbuf; main (argc,argv) --- 110,117 ----- unsigned char inbuf2[PH_SECTSIZE]; unsigned char outbuf[PH_SECTSIZE]; ! struct a_out_hdr *a_ptr= (struct a_out_hdr *)outbuf; ! struct d_fmt_hdr *d_ptr= (struct d_fmt_hdr *)inbuf; main (argc,argv) *************** *** 177,183 } /* end switch */ /* open & create files */ ! if ((inf=open(in_name,BREAD)) <0) { printf ("input file %s not found\n",in_name); exit(2); } --- 178,184 ----- } /* end switch */ /* open & create files */ ! if ((inf=open(in_name,O_RDONLY|O_BINARY)) <0) { printf ("input file %s not found\n",in_name); exit(2); } *************** *** 207,213 /* input file is ok, open output (possibly destroy existing file) */ ! if ((outf=creat(out_name,BWRITE)) <0) { printf ("cannot open output %s\n",out_name); exit(2); } --- 208,214 ----- /* input file is ok, open output (possibly destroy existing file) */ ! if ((outf=open(out_name,O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0666)) <0) { printf ("cannot open output %s\n",out_name); exit(2); } *************** *** 237,243 /* reposition file */ close (inf); ! inf=open(in_name,BREAD); in_cnt=read(inf,inbuf2,PH_SECTSIZE); /* make a.out header */ --- 238,244 ----- /* reposition file */ close (inf); ! inf=open(in_name,O_RDONLY|O_BINARY); in_cnt=read(inf,inbuf2,PH_SECTSIZE); /* make a.out header */ *************** *** 301,306 close (inf); if (delete) unlink (in_name); printf(" -done-\n"); } --- 302,308 ----- close (inf); if (delete) unlink (in_name); printf(" -done-\n"); + exit(0); } ------------------------------------------------------------ *** fsck.c Sat Aug 1 13:38:01 1987 --- ../../dos/tools/fsck.c Sat Aug 1 13:32:45 1987 *************** *** 87,92 #define isupper(c) between(c, 'A', 'Z') #define toupper(c) ( (c) + 'A' - 'a' ) #define quote(x) x #define nextarg(t) (*argp.quote(u_)t++) --- 87,93 ----- #define isupper(c) between(c, 'A', 'Z') #define toupper(c) ( (c) + 'A' - 'a' ) + #ifndef MSDOS /* actually, if not ANSI C */ #define quote(x) x #define nextarg(t) (*argp.quote(u_)t++) #else *************** *** 89,94 #define quote(x) x #define nextarg(t) (*argp.quote(u_)t++) #define prn(t,b,s) { printnum((long)nextarg(t),b,s,width,pad); width = 0; } #define prc(c) { width -= printchar(c, mode); } --- 90,98 ----- #ifndef MSDOS /* actually, if not ANSI C */ #define quote(x) x #define nextarg(t) (*argp.quote(u_)t++) + #else + #define nextarg(t) (*argp.u_##t++) + #endif #define prn(t,b,s) { printnum((long)nextarg(t),b,s,width,pad); width = 0; } #define prc(c) { width -= printchar(c, mode); } *************** *** 180,186 #ifdef STANDALONE extern end; /* last variable */ ! int *brk; /* the ``break'' (end of data space) */ #else int dev; /* file descriptor of the device */ #endif --- 184,190 ----- #ifdef STANDALONE extern end; /* last variable */ ! int *brksa; /* the ``break'' (end of data space) */ #else int dev; /* file descriptor of the device */ #endif *************** *** 361,367 register level; #ifdef STANDALONE ! brk = &end; #endif nregular = ndirectory = nblkspec = ncharspec = nbadinode = 0; for (level = 0; level < NLEVEL; level++) --- 365,371 ----- register level; #ifdef STANDALONE ! brksa = &end; #endif nregular = ndirectory = nblkspec = ncharspec = nbadinode = 0; for (level = 0; level < NLEVEL; level++) *************** *** 478,486 #ifdef STANDALONE register *r; ! p = (char *) brk; ! brk += nelem * ((elsize + sizeof(int) - 1) / sizeof(int)); ! for (r = (int *) p; r < brk; r++) *r = 0; return(p); #else --- 482,490 ----- #ifdef STANDALONE register *r; ! p = (char *) brksa; ! brksa += nelem * ((elsize + sizeof(int) - 1) / sizeof(int)); ! for (r = (int *) p; r < brksa; r++) *r = 0; return(p); #else *************** *** 1832,1838 printf("\n\n\n\n"); for (;;) { printf("\nHit key as follows:\n\n"); ! printf(" = start MINIX (root file system in drive 0)\n"); printf(" f check the file system (first insert any file system diskette)\n"); printf(" l check and list file system (first insert any file system diskette)\n"); printf(" m make an (empty) file system (first insert blank, formatted diskette)\n"); --- 1836,1843 ----- printf("\n\n\n\n"); for (;;) { printf("\nHit key as follows:\n\n"); ! printf(" = start MINIX (root file system in floppy drive 0)\n"); ! printf("[1-9] start MINIX (root file system on /dev/hd[1-9]\n"); printf(" f check the file system (first insert any file system diskette)\n"); printf(" l check and list file system (first insert any file system diskette)\n"); printf(" m make an (empty) file system (first insert blank, formatted diskette)\n"); *************** *** 1881,1887 } break; ! case '=': return((c >> 8) & 0xFF); default: printf("Illegal command\n"); continue; --- 1886,1902 ----- } break; ! case '=': /* boot from floppy 0 */ ! case '1': /* boot from a hard disk partition */ ! case '2': /* partitions 0 and 5 are raw and thus */ ! case '3': /* are not included in this list. */ ! case '4': /* Added 7/29/87 Eric Roskos (JER) */ ! case '6': ! case '7': ! case '8': ! case '9': ! return((c >> 8) & 0xFF); ! default: printf("Illegal command\n"); continue; ------------------------------------------------------------ *** fsck1.asm Sat Aug 1 13:38:03 1987 --- ../../dos/tools/fsck1.asm Sat Aug 1 13:32:50 1987 *************** *** 1,7 title fsck1 - additional stuff for fsck page,132 - INCLUDE ..\lib\prologue.h --- 1,6 ----- title fsck1 - additional stuff for fsck page,132 INCLUDE ..\lib\prologue.h *************** *** 10,18 XTSECTORS EQU 17 XTCYLS EQU 68 IFDEF STANDALONE ! PUBLIC $main, @end, edata, exit, kerstack,_prt ! EXTRN main:near ! ;EXTRN cinit:near, debug:near ENDIF PUBLIC reset_di, diskio, getc, putc, dmaoverr EXTRN cylsiz:word, tracksiz:word, drive:byte --- 9,17 ----- XTSECTORS EQU 17 XTCYLS EQU 68 IFDEF STANDALONE ! PUBLIC $main, _end, _edata, _exit, _kerstack, _prt ! EXTRN _main:near ! ;EXTRN _cinit:near, _debug:near ENDIF PUBLIC _reset_diskette, _diskio, _getc, _putc, _dmaoverrun EXTRN _cylsiz:word, _tracksiz:word, _drive:byte *************** *** 14,21 EXTRN main:near ;EXTRN cinit:near, debug:near ENDIF ! PUBLIC reset_di, diskio, getc, putc, dmaoverr ! EXTRN cylsiz:word, tracksiz:word, drive:byte ;---------------------------------------+ --- 13,20 ----- EXTRN _main:near ;EXTRN _cinit:near, _debug:near ENDIF ! PUBLIC _reset_diskette, _diskio, _getc, _putc, _dmaoverrun ! EXTRN _cylsiz:word, _tracksiz:word, _drive:byte PUBLIC __acrtused __acrtused EQU 9876H *************** *** 17,22 PUBLIC reset_di, diskio, getc, putc, dmaoverr EXTRN cylsiz:word, tracksiz:word, drive:byte ;---------------------------------------+ ; Code | --- 16,23 ----- PUBLIC _reset_diskette, _diskio, _getc, _putc, _dmaoverrun EXTRN _cylsiz:word, _tracksiz:word, _drive:byte + PUBLIC __acrtused + __acrtused EQU 9876H ;-------------------------------------------+ ; DATA - JER - moved here from before stack | *************** *** 18,23 EXTRN cylsiz:word, tracksiz:word, drive:byte ;---------------------------------------+ ; Code | ;---------------------------------------+ --- 19,38 ----- PUBLIC __acrtused __acrtused EQU 9876H + ;-------------------------------------------+ + ; DATA - JER - moved here from before stack | + ;-------------------------------------------+ + + _DATA SEGMENT + magic DW 0ABCDH + tmp DW 0 + tmp1 DW 0 + tmp2 DW 0 + fsckmsg DB "arrived at fsck1",0 + _DATA ENDS + + + IFDEF STANDALONE ;---------------------------------------+ ; Set up memory lay-out for standalone | ;---------------------------------------+ *************** *** 19,25 ;---------------------------------------+ ! ; Code | ;---------------------------------------+ ; @CODE SEGMENT --- 34,70 ----- IFDEF STANDALONE ;---------------------------------------+ ! ; Set up memory lay-out for standalone | ! ;---------------------------------------+ ! ; ! STACKSIZE EQU 8192 ! ! _DATA SEGMENT ! _brksa DW ? ! _DATA ENDS ! ! LOWCORE SEGMENT AT 0 ; tell where BIOS-data etc is ! ORG 120 ! dskbase label word ! LOWCORE ENDS ! ! MINIX SEGMENT AT 60h ; This is where Minix is loaded ! _kernel label byte ; absolute address 0000:1536d = 0060:0000h ! MINIX ENDS ! ! _DATAT SEGMENT ; DATAT holds nothing. The label tells us ! _edata label byte ; where .data ends. ! _DATAT ENDS ! ! _DATAU SEGMENT ; allocate the stack in .bss ! _kerstack DB STACKSIZE dup(?) ! _DATAU ENDS ! ! _DATAV SEGMENT ; DATAV holds nothing. The label tells us ! _end label byte ; where .data+.bss ends (first free memory) ! _DATAV ENDS ! ! ;---------------------------------------+ ; Code | ;---------------------------------------+ *************** *** 21,26 ;---------------------------------------+ ; Code | ;---------------------------------------+ ; @CODE SEGMENT assume cs:@code,ds:dgroup --- 66,73 ----- ;---------------------------------------+ + ; Code | + ;---------------------------------------+ ; _TEXT SEGMENT assume cs:_text,ds:dgroup *************** *** 22,29 ; Code | ;---------------------------------------+ ; ! @CODE SEGMENT ! assume cs:@code,ds:dgroup IFDEF STANDALONE $main: --- 69,76 ----- ; Code | ;---------------------------------------+ ; ! _TEXT SEGMENT ! assume cs:_text,ds:dgroup IFDEF STANDALONE $main: *************** *** 29,36 $main: mov dx,bx ; bootblok puts # sectors/track in bx xor ax,ax ! mov bx,offset dgroup:edata ; prepare to clear bss ! mov cx,offset dgroup:@end sub cx,bx sar cx,1 st1:mov [bx],ax ; clear bss --- 76,83 ----- $main: mov dx,bx ; bootblok puts # sectors/track in bx xor ax,ax ! mov bx,offset dgroup:_edata ; prepare to clear bss ! mov cx,offset dgroup:_end sub cx,bx sar cx,1 st1: mov [bx],ax ; clear bss *************** *** 33,39 mov cx,offset dgroup:@end sub cx,bx sar cx,1 ! st1:mov [bx],ax ; clear bss add bx,2 loop st1 --- 80,86 ----- mov cx,offset dgroup:_end sub cx,bx sar cx,1 ! st1: mov [bx],ax ; clear bss add bx,2 loop st1 *************** *** 37,43 add bx,2 loop st1 ! mov dgroup:tracksiz,dx ; dx (was bx) is # sectors/track add dx,dx mov dgroup:cylsiz,dx ; # sectors/cylinder mov sp,offset dgroup:kerstack+STACKSIZE --- 84,90 ----- add bx,2 loop st1 ! mov dgroup:_tracksiz,dx ; dx (was bx) is # sectors/track add dx,dx mov dgroup:_cylsiz,dx ; # sectors/cylinder mov sp,offset dgroup:_kerstack+STACKSIZE *************** *** 39,46 mov dgroup:tracksiz,dx ; dx (was bx) is # sectors/track add dx,dx ! mov dgroup:cylsiz,dx ; # sectors/cylinder ! mov sp,offset dgroup:kerstack+STACKSIZE ; call cinit ; mov ax,offset fsckmsg --- 86,93 ----- mov dgroup:_tracksiz,dx ; dx (was bx) is # sectors/track add dx,dx ! mov dgroup:_cylsiz,dx ; # sectors/cylinder ! mov sp,offset dgroup:_kerstack+STACKSIZE ; call cinit *************** *** 42,47 mov dgroup:cylsiz,dx ; # sectors/cylinder mov sp,offset dgroup:kerstack+STACKSIZE ; call cinit ; mov ax,offset fsckmsg ; push ax --- 89,95 ----- mov dgroup:_cylsiz,dx ; # sectors/cylinder mov sp,offset dgroup:_kerstack+STACKSIZE + ; call cinit ; mov ax,offset fsckmsg ; push ax *************** *** 47,54 ; push ax ; call debug ; pop ax ! ! call main mov bx,ax ; put scan code for '=' in bx cli mov dx,60h --- 95,103 ----- ; push ax ; call debug ; pop ax ! ! call _main ! mov bx,ax ; put scan code for '=' in bx ifdef debug *************** *** 50,55 call main mov bx,ax ; put scan code for '=' in bx cli mov dx,60h mov ds,dx --- 99,113 ----- call _main mov bx,ax ; put scan code for '=' in bx + + ifdef debug + mov ax,60H + mov es,ax + mov ax,word ptr es:4 + call prtax + wto '= DS word at kernel entry point' + endif + cli mov dx,60h mov ds,dx *************** *** 55,61 mov ds,dx mov es,dx mov ss,dx ! jmp far ptr kernel ; direct jmp to kernel & start Minix mov ax,DGROUP ; Force DOS-relocation (sep I&D) exit: mov bx,dgroup:tracksiz --- 113,121 ----- mov ds,dx mov es,dx mov ss,dx ! ! ! jmp far ptr _kernel ; direct jmp to kernel & start Minix mov ax,DGROUP ; Force DOS-relocation (sep I&D) _exit: mov bx,dgroup:_tracksiz *************** *** 58,64 jmp far ptr kernel ; direct jmp to kernel & start Minix mov ax,DGROUP ; Force DOS-relocation (sep I&D) ! exit: mov bx,dgroup:tracksiz jmp $main --- 118,124 ----- jmp far ptr _kernel ; direct jmp to kernel & start Minix mov ax,DGROUP ; Force DOS-relocation (sep I&D) ! _exit: mov bx,dgroup:_tracksiz jmp $main *************** *** 85,90 int 10h ; call BIOS VIDEO_IO pop bx ; restore bx jmp print ; next character ENDIF ; /* STANDALONE */ --- 145,210 ----- int 10h ; call BIOS VIDEO_IO pop bx ; restore bx jmp print ; next character + + ; + ; code for debug messages + ; + ifdef debug + ; + ; prtnum - print low-order 4 bits of al register in hex + ; + + prtnum proc near + push ds + push cs + pop ds + push bx + mov bx,offset xltab + xlatb + mov ah,14 + mov bh,10 + int 10H + pop bx + pop ds + ret + + xltab db '0123456789ABCDEF ' + prtnum endp + + ; + ; prtax - print ax register's contents in hex + ; + + prtax proc near + push cx + push ax + mov al,ah + mov cl,4 + shr al,cl + call prtnum + pop ax + push ax + mov al,ah + and al,0fH + call prtnum + pop ax + push ax + mov cl,4 + shr al,cl + call prtnum + pop ax + push ax + and al,0fH + call prtnum + mov al,10H ; special value to print a space + call prtnum + pop ax + pop cx + ret + + prtax endp + + endif ENDIF ; /* STANDALONE */ *************** *** 89,95 ENDIF ; /* STANDALONE */ ! putc: xor ax,ax call csv mov al,4[bp] ; al contains char to be printed --- 209,215 ----- ENDIF ; /* STANDALONE */ ! _putc: xor ax,ax call csv mov al,4[bp] ; al contains char to be printed *************** *** 100,106 pop bp jmp cret ! getc: xor ah,ah int 16h ret --- 220,226 ----- pop bp jmp cret ! _getc: xor ah,ah int 16h ret *************** *** 105,111 int 16h ret ! reset_di: ; reset_diskette xor ax,ax call csv push es ; not preserved --- 225,231 ----- int 16h ret ! _reset_diskette: ; reset_diskette xor ax,ax call csv push es ; not preserved *************** *** 115,121 ; handle diskio(RW, sector_number, buffer, sector_count) call ; Do not issue a BIOS call that crosses a track boundary ! diskio: xor ax,ax call csv mov tmp1,0 ; tmp1 = # sectors actually transferred --- 235,241 ----- ; handle diskio(RW, sector_number, buffer, sector_count) call ; Do not issue a BIOS call that crosses a track boundary ! _diskio: xor ax,ax call csv mov tmp1,0 ; tmp1 = # sectors actually transferred *************** *** 123,129 mov tmp2,di ; di = # sectors to transfer d0: mov ax,6[bp] ; ax = sector number to start at xor dx,dx ; dx:ax is dividend ! div dgroup:cylsiz ; ax = cylinder, dx = sector within cylinder mov cl,ah ; cl = hi-order bits of cylinder ror cl,1 ; BIOS expects hi bits in a funny place ror cl,1 ; ditto --- 243,249 ----- mov tmp2,di ; di = # sectors to transfer d0: mov ax,6[bp] ; ax = sector number to start at xor dx,dx ; dx:ax is dividend ! div dgroup:_cylsiz ; ax = cylinder, dx = sector within cylinder mov cl,ah ; cl = hi-order bits of cylinder ror cl,1 ; BIOS expects hi bits in a funny place ror cl,1 ; ditto *************** *** 130,136 mov ch,al ; cx = sector # in BIOS format mov ax,dx ; ax = sector offset within cylinder xor dx,dx ; dx:ax is dividend ! div dgroup:tracksiz ; ax = head, dx = sector mov dh,al ; dh = head or cl,dl ; cl = 2 high-order cyl bits || sector inc cl ; BIOS counts sectors starting at 1 --- 250,256 ----- mov ch,al ; cx = sector # in BIOS format mov ax,dx ; ax = sector offset within cylinder xor dx,dx ; dx:ax is dividend ! div dgroup:_tracksiz ; ax = head, dx = sector mov dh,al ; dh = head or cl,dl ; cl = 2 high-order cyl bits || sector inc cl ; BIOS counts sectors starting at 1 *************** *** 134,140 mov dh,al ; dh = head or cl,dl ; cl = 2 high-order cyl bits || sector inc cl ; BIOS counts sectors starting at 1 ! mov dl,dgroup:drive ; dl = drive code (0-3 or 0x80 - 0x81) mov bx,8[bp] ; bx = address of buffer mov al,cl ; al = sector # add al,10[bp] ; compute last sector --- 254,260 ----- mov dh,al ; dh = head or cl,dl ; cl = 2 high-order cyl bits || sector inc cl ; BIOS counts sectors starting at 1 ! mov dl,dgroup:_drive ; dl = drive code (0-3 or 0x80 - 0x81) mov bx,8[bp] ; bx = address of buffer mov al,cl ; al = sector # add al,10[bp] ; compute last sector *************** *** 139,145 mov al,cl ; al = sector # add al,10[bp] ; compute last sector dec al ; al = last sector to transfer ! cmp al,byte ptr dgroup:tracksiz ; see if last sector is on next track jle d1 ; jump if last sector is on this track mov word ptr 10[bp],1 ; transfer 1 sector at a time d1: mov ah,4[bp] ; ah = READING or WRITING --- 259,265 ----- mov al,cl ; al = sector # add al,10[bp] ; compute last sector dec al ; al = last sector to transfer ! cmp al,byte ptr dgroup:_tracksiz ; see if last sector is on next track jle d1 ; jump if last sector is on this track mov word ptr 10[bp],1 ; transfer 1 sector at a time d1: mov ah,4[bp] ; ah = READING or WRITING *************** *** 163,169 d2: jmp cret ! dmaoverr: ; test if &buffer causes a DMA overrun push bp mov bp,sp push bx --- 283,289 ----- d2: jmp cret ! _dmaoverrun: ; test if &buffer causes a DMA overrun push bp mov bp,sp push bx *************** *** 200,244 pop bp ret ! ! @CODE ENDS ! ! ! @DATAI SEGMENT ! tmp DW 0 ! tmp1 DW 0 ! tmp2 DW 0 ! fsckmsg DB "arrived at fsck1",0 ! @DATAI ENDS ! ! ! IFDEF STANDALONE ! ;---------------------------------------+ ! ; Set up memory lay-out for standalone | ! ;---------------------------------------+ ! ; ! STACKSIZE EQU 8192 ! ! LOWCORE SEGMENT AT 0 ; tell where BIOS-data etc is ! ORG 120 ! dskbase label word ! LOWCORE ENDS ! ! MINIX SEGMENT AT 60h ; This is where Minix is loaded ! kernel label byte ; absolute address 0000:1536d = 0060:0000h ! MINIX ENDS ! ! @DATAT SEGMENT ; DATAT holds nothing. The label tells us ! edata label byte ; where .data ends. ! @DATAT ENDS ! ! @DATAU SEGMENT ; allocate the stack in .bss ! kerstack DB STACKSIZE dup(?) ! @DATAU ENDS ! ! @DATAV SEGMENT ; DATAV holds nothing. The label tells us ! @end label byte ; where .data+.bss ends (first free memory) ! @DATAV ENDS @STACK SEGMENT BYTE STACK 'STACK' ; Satisfy DOS-linker @STACK ENDS ; (dummy stack-segment) --- 320,326 ----- pop bp ret ! _TEXT ENDS @STACK SEGMENT BYTE STACK 'STACK' ; Satisfy DOS-linker @STACK ENDS ; (dummy stack-segment)
ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # fs/fs # fs/_link.bat # fs/linklist # This archive created: Sat Aug 1 14:01:11 1987 export PATH; PATH=/bin:$PATH echo shar: extracting "'fs'" '(791 characters)' if test -f 'fs' then echo shar: will not over-write existing file "'fs'" else cat << \SHAR_EOF > 'fs' # # Makefile for FS # By E. Roskos 1987 # OBJ = cache.obj device.obj filedes.obj inode.obj link.obj main.obj \ misc.obj mount.obj open.obj path.obj pipe.obj protect.obj putc.obj \ read.obj stadir.obj super.obj table.obj time.obj utility.obj write.obj .c.obj: cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c .asm.obj: masm $*,$*,$*; cache.obj: cache.c device.obj: device.c filedes.obj: filedes.c inode.obj: inode.c link.obj: link.c main.obj: main.c misc.obj: misc.c mount.obj: mount.c open.obj: open.c path.obj: path.c pipe.obj: pipe.c protect.obj: protect.c putc.obj: putc.c read.obj: read.c stadir.obj: stadir.c super.obj: super.c table.obj: table.c time.obj: time.c utility.obj: utility.c write.obj: write.c fs.out: $(OBJ) _link SHAR_EOF if test 791 -ne "`wc -c < 'fs'`" then echo shar: error transmitting "'fs'" '(should have been 791 characters)' fi fi # end of overwriting check echo shar: extracting "'_link.bat'" '(109 characters)' if test -f '_link.bat' then echo shar: will not over-write existing file "'_link.bat'" else cat << \SHAR_EOF > '_link.bat' echo/ echo Linking file system task link/m/nod ..\lib\head+ <linklist >fs.lst ..\dos2out -pd fs >>fs.lst SHAR_EOF if test 109 -ne "`wc -c < '_link.bat'`" then echo shar: error transmitting "'_link.bat'" '(should have been 109 characters)' fi fi # end of overwriting check echo shar: extracting "'linklist'" '(151 characters)' if test -f 'linklist' then echo shar: will not over-write existing file "'linklist'" else cat << \SHAR_EOF > 'linklist' main+open+read+write+pipe+device+path+ mount+link+super+inode+cache+filedes+stadir+ protect+time+misc+utility+table+putc fs fs ..\lib\minix \lib\libh SHAR_EOF if test 151 -ne "`wc -c < 'linklist'`" then echo shar: error transmitting "'linklist'" '(should have been 151 characters)' fi fi # end of overwriting check # End of shell archive exit 0
ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # kernel/gn_wini.c # kernel/kernel # kernel/linklist # kernel/_link.bat # This archive created: Sat Aug 1 14:02:09 1987 export PATH; PATH=/bin:$PATH echo shar: extracting "'gn_wini.c'" '(11852 characters)' if test -f 'gn_wini.c' then echo shar: will not over-write existing file "'gn_wini.c'" else cat << \SHAR_EOF > 'gn_wini.c' /* This file contains a driver for "Generic" winchester disks; it uses * the ROM BIOS winchester disk routines. * * It was written by Eric Roskos, based on Adri Koppes's XT_WINI driver. * * If you use this driver, you have to define GENERIC_FDISK and recompile * main.c and klib88.asm, since those files have ifdef's in them for this * driver: main.c is changed to not overwrite the BIOS reserved vectors * and int 13H, and klib88.asm has C call interfaces to the BIOS. * * The driver supports two operations: read a block and * write a block. It accepts two messages, one for reading and one for * writing, both using message format m2 and with the same parameters: * * m_type DEVICE PROC_NR COUNT POSITION ADRRESS * ---------------------------------------------------------------- * | DISK_READ | device | proc nr | bytes | offset | buf ptr | * |------------+---------+---------+---------+---------+---------| * | DISK_WRITE | device | proc nr | bytes | offset | buf ptr | * ---------------------------------------------------------------- * * The file contains one entry point: * * winchester_task: main entry when system is brought up * */ #include "../h/const.h" #include "../h/type.h" #include "../h/callnr.h" #include "../h/com.h" #include "../h/error.h" #include "const.h" #include "type.h" #include "proc.h" /* * define WN_SAFETY to cause the driver to panic if you try to access any * sectors below the start of partition 2 -- this is supposed to prevent an * errant program from causing the DOS partition to be overwritten. It * assumes your DOS partition is partition 1 (the first one). */ #define WN_SAFETY /* */ /* Parameters for the disk drive. */ #define SECTOR_SIZE 512 /* physical sector size in bytes */ #define NR_SECTORS 0x11 /* number of sectors per track */ /* Error codes */ #define ERR -1 /* general error */ /* Miscellaneous. */ #define MAX_ERRORS 4 /* how often to try rd/wt before quitting */ #define MAX_RESULTS 4 /* max number of bytes controller returns */ #define NR_DEVICES 10 /* maximum number of drives */ #define MAX_WIN_RETRY 10000 /* max # times to try to output to WIN */ #define PART_TABLE 0x1C6 /* IBM partition table starts here in sect 0 */ #define DEV_PER_DRIVE 5 /* hd0 + hd1 + hd2 + hd3 + hd4 = 5 */ #define SAFETY_CONST 0xAAAAAAAAL /* table integrity check */ /* Variables. */ PRIVATE struct wini { /* main drive struct, one entry per drive */ int wn_opcode; /* DISK_READ or DISK_WRITE */ int wn_procnr; /* which proc wanted this operation? */ int wn_drive; /* drive number addressed */ int wn_cylinder; /* cylinder number addressed */ int wn_sector; /* sector addressed */ int wn_head; /* head number addressed */ int wn_heads; /* maximum number of heads */ long wn_low; /* lowest cylinder of partition */ long wn_size; /* size of partition in blocks */ int wn_trksize; /* size of track on this drive */ int wn_count; /* byte count */ vir_bytes wn_address; /* user virtual address */ char wn_results[MAX_RESULTS]; /* the controller can give lots of output */ } wini[NR_DEVICES]; PRIVATE int w_need_reset = FALSE; /* set to 1 when controller must be reset */ PRIVATE int nr_drives; /* Number of drives */ PRIVATE message w_mess; /* message buffer for in and out */ /* this buffer is sort of a waste of space, I think? */ PRIVATE unsigned char buf[BLOCK_SIZE]; /* Buffer used by the startup routine */ PRIVATE struct param { int nr_cyl; /* Number of cylinders */ int nr_heads; /* Number of heads */ int nr_drives; /* Number of drives on this drive's ctroller */ int nr_sectors; /* number of sectors per track */ } param0, param1; /*===========================================================================* * winchester_task * *===========================================================================*/ PUBLIC winchester_task() { /* Main program of the winchester disk driver task. */ int r, caller, proc_nr; #ifdef DEBUG printf("Winchester task has started\n"); #endif /* First initialize the controller */ init_params(); /* Here is the main loop of the disk task. It waits for a message, carries * it out, and sends a reply. */ while (TRUE) { /* First wait for a request to read or write a disk block. */ receive(ANY, &w_mess); /* get a request to do some work */ if (w_mess.m_source < 0) { printf("winchester task got message from %d ", w_mess.m_source); continue; } caller = w_mess.m_source; proc_nr = w_mess.PROC_NR; /* Now carry out the work. */ switch(w_mess.m_type) { case DISK_READ: case DISK_WRITE: r = w_do_rdwt(&w_mess); break; default: r = EINVAL; break; } /* Finally, prepare and send the reply message. */ w_mess.m_type = TASK_REPLY; w_mess.REP_PROC_NR = proc_nr; w_mess.REP_STATUS = r; /* # of bytes transferred or error code */ send(caller, &w_mess); /* send reply to caller */ } } /*===========================================================================* * w_do_rdwt * *===========================================================================*/ PRIVATE int w_do_rdwt(m_ptr) message *m_ptr; /* pointer to read or write w_message */ { /* Carry out a read or write request from the disk. */ register struct wini *wn; int r, device, errors = 0; long sector; phys_bytes user_phys; int sb, ib; int fRW; int csectors; int nr_sectors; extern phys_bytes umap(); #ifdef WN_SAFETY extern long wn_low_safety, wn_low_xor; #endif /* Decode the w_message parameters. */ device = m_ptr->DEVICE; if (device < 0 || device >= NR_DEVICES) return(EIO); if (m_ptr->COUNT != BLOCK_SIZE) return(EINVAL); wn = &wini[device]; /* 'wn' points to entry for this drive */ wn->wn_drive = device/DEV_PER_DRIVE; /* save drive number */ if (wn->wn_drive >= nr_drives) return(EIO); wn->wn_opcode = m_ptr->m_type; /* DISK_READ or DISK_WRITE */ if (m_ptr->POSITION % BLOCK_SIZE != 0) return(EINVAL); sector = m_ptr->POSITION/SECTOR_SIZE; if ((sector+BLOCK_SIZE/SECTOR_SIZE) > wn->wn_size) return(EOF); sector += wn->wn_low; nr_sectors = wn->wn_trksize; #ifdef WN_SAFETY /* try to insure errant program can't destroy another partition */ if (wn->wn_opcode != DISK_READ) /* allow reads of DOS partition */ { if ((wn_low_safety^SAFETY_CONST) != wn_low_xor) { printf("safety: %X xor: %X computed xor: %X\n", wn_low_safety, wn_low_xor, wn_low_safety^SAFETY_CONST); printf("winchester: driver tables appear overwritten\n"); return(EIO); } if (sector < wn_low_safety) { printf("winchester: tried to write sector below safety boundary\n", sector); return(EIO); } } #endif wn->wn_cylinder = sector / (wn->wn_heads * nr_sectors); wn->wn_sector = (sector % nr_sectors); wn->wn_head = (sector % (wn->wn_heads * nr_sectors) )/nr_sectors; wn->wn_count = m_ptr->COUNT; wn->wn_address = (vir_bytes) m_ptr->ADDRESS; wn->wn_procnr = m_ptr->PROC_NR; /* here we compute the values we pass the BIOS */ user_phys = umap(proc_addr(wn->wn_procnr), D, wn->wn_address, (vir_bytes)wn->wn_count); sb = (user_phys >> 4) & 0xffff; ib = user_phys & 0xf; fRW = (wn->wn_opcode==DISK_READ)? 0 : 1; csectors = wn->wn_count / SECTOR_SIZE; /* This loop allows a failed operation to be repeated. */ while (errors <= MAX_ERRORS) { errors++; /* increment count once per loop cycle */ if (errors >= MAX_ERRORS) return(EIO); /* First check to see if a reset is needed. */ if (w_need_reset) w_reset(); /* Perform the transfer. */ #ifdef DEBUG printf("diskio(%d,%x,%x,%x,%x,%x,%x,%x,%x)\n", fRW, wn->wn_cylinder, wn->wn_sector, wn->wn_head, csectors, wn->wn_drive, sb, ib, wn->wn_trksize); #endif r = diskio(fRW, wn->wn_cylinder, wn->wn_sector, wn->wn_head, csectors, wn->wn_drive, sb, ib, wn->wn_trksize); if (r == OK) break; /* if successful, exit loop */ } if (r!=OK) { printf("\ngn_wini: hardware error, BIOS code %02x\n", r); w_need_reset = TRUE; } return(r == OK ? BLOCK_SIZE : EIO); } #ifdef DEBUG /* debug code */ diskdebug(ax,bx,cx,dx) int ax,bx,cx,dx; { printf("BIOS call would have: ax=%04x, bx=%04x, cx=%04x, dx=%04x\n", ax,bx,cx,dx); return(0); } #endif /*===========================================================================* * w_reset * *===========================================================================*/ PRIVATE w_reset() { /* Issue a reset to the controller. This is done after any catastrophe, * like the controller refusing to respond. */ return(win_init()); } /*============================================================================* * init_params * *============================================================================*/ PRIVATE init_params() { /* This routine is called at startup to initialize the partition table, * the number of drives and the controller */ unsigned int i, segment, offset; phys_bytes address; extern phys_bytes umap(); extern int vec_table[]; /* * Be sure BIOS is all set up before we ask for parameters. This * may not really be necessary; we do it again below. */ win_init(); /* Copy the parameters to the structures */ hdisk_params(0, ¶m0); hdisk_params(1, ¶m1); /* Get the number of drives */ nr_drives = param0.nr_drives; /* Set the parameters in the drive structure */ for (i=0; i<5; i++) { wini[i].wn_heads = param0.nr_heads; wini[i].wn_trksize = param0.nr_sectors; } wini[0].wn_low = wini[5].wn_low = 0L; wini[0].wn_size = (long)((long)param0.nr_cyl * (long)param0.nr_heads * (long)NR_SECTORS); for (i=5; i<10; i++) { wini[i].wn_heads = param1.nr_heads; wini[i].wn_trksize = param1.nr_sectors; } wini[5].wn_size = (long)((long)param1.nr_cyl * (long)param1.nr_heads * (long)NR_SECTORS); /* Initialize the controller */ if ((nr_drives > 0) && (win_init() != OK)) nr_drives = 0; /* Read the partition table for each drive and save them */ for (i = 0; i < nr_drives; i++) { w_mess.DEVICE = i * 5; w_mess.POSITION = 0L; w_mess.COUNT = BLOCK_SIZE; w_mess.ADDRESS = (char *) buf; w_mess.PROC_NR = WINCHESTER; w_mess.m_type = DISK_READ; if (w_do_rdwt(&w_mess) != BLOCK_SIZE) panic("Can't read partition table of winchester ", i); copy_prt(i * 5); } } /*============================================================================* * copy_prt * *============================================================================*/ PRIVATE copy_prt(drive) int drive; { /* This routine copies the partition table for the selected drive to * the variables wn_low and wn_size */ register int i, offset; struct wini *wn; long adjust; #ifdef WN_SAFETY extern long wn_low_safety, wn_low_xor; #endif for (i=0; i<4; i++) { adjust = 0; wn = &wini[i + drive + 1]; offset = PART_TABLE + i * 0x10; wn->wn_low = *(long *)&buf[offset]; if ((wn->wn_low % (BLOCK_SIZE/SECTOR_SIZE)) != 0) { adjust = wn->wn_low; wn->wn_low = (wn->wn_low/(BLOCK_SIZE/SECTOR_SIZE)+1)*(BLOCK_SIZE/SECTOR_SIZE); adjust = wn->wn_low - adjust; } wn->wn_size = *(long *)&buf[offset + sizeof(long)] - adjust; } sort(&wini[drive + 1]); #ifdef WN_SAFETY wn_low_safety = wini[2].wn_low; wn_low_xor = wn_low_safety ^ SAFETY_CONST; #endif } PRIVATE sort(wn) register struct wini *wn; { register int i,j; for (i=0; i<4; i++) for (j=0; j<3; j++) if ((wn[j].wn_low == 0) && (wn[j+1].wn_low != 0)) swap(&wn[j], &wn[j+1]); else if (wn[j].wn_low > wn[j+1].wn_low && wn[j+1].wn_low != 0) swap(&wn[j], &wn[j+1]); } PRIVATE swap(first, second) register struct wini *first, *second; { register struct wini tmp; tmp = *first; *first = *second; *second = tmp; } SHAR_EOF if test 11852 -ne "`wc -c < 'gn_wini.c'`" then echo shar: error transmitting "'gn_wini.c'" '(should have been 11852 characters)' fi fi # end of overwriting check echo shar: extracting "'kernel'" '(657 characters)' if test -f 'kernel' then echo shar: will not over-write existing file "'kernel'" else cat << \SHAR_EOF > 'kernel' OBJ = at_wini.obj clock.obj dmp.obj floppy.obj klib88.obj main.obj \ memory.obj mpx88.obj printer.obj proc.obj system.obj table.obj \ tty.obj wini.obj xt_wini.obj gn_wini.obj .c.obj: cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c .asm.obj: masm /DGENERIC_FDISK $*,$*,$*; at_wini.obj: at_wini.c clock.obj: clock.c dmp.obj: dmp.c floppy.obj: floppy.c gn_wini.obj: gn_wini.c main.obj: main.c memory.obj: memory.c printer.obj: printer.c proc.obj: proc.c system.obj: system.c table.obj: table.c tty.obj: tty.c wini.obj: wini.c xt_wini.obj: xt_wini.c klib88.obj: klib88.asm mpx88.obj: mpx88.asm kernel.exe: $(OBJ) _link SHAR_EOF if test 657 -ne "`wc -c < 'kernel'`" then echo shar: error transmitting "'kernel'" '(should have been 657 characters)' fi fi # end of overwriting check echo shar: extracting "'linklist'" '(112 characters)' if test -f 'linklist' then echo shar: will not over-write existing file "'linklist'" else cat << \SHAR_EOF > 'linklist' main+proc+system+clock+memory+floppy+ gn_wini+tty+printer+table+klib88+dmp kernel kernel ..\lib\minix \lib\libh SHAR_EOF if test 112 -ne "`wc -c < 'linklist'`" then echo shar: error transmitting "'linklist'" '(should have been 112 characters)' fi fi # end of overwriting check echo shar: extracting "'_link.bat'" '(105 characters)' if test -f '_link.bat' then echo shar: will not over-write existing file "'_link.bat'" else cat << \SHAR_EOF > '_link.bat' echo/ echo Linking kernel link/m/nod mpx88+ < linklist >kernel.lst ..\dos2out -p kernel >> kernel.lst SHAR_EOF if test 105 -ne "`wc -c < '_link.bat'`" then echo shar: error transmitting "'_link.bat'" '(should have been 105 characters)' fi fi # end of overwriting check # End of shell archive exit 0
ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # lib/lib # lib/liblist # This archive created: Sat Aug 1 14:03:26 1987 export PATH; PATH=/bin:$PATH echo shar: extracting "'lib'" '(3909 characters)' if test -f 'lib' then echo shar: will not over-write existing file "'lib'" else cat << \SHAR_EOF > 'lib' # # Makefile for Minix Library # Microsoft C 4.0 Compiler # 1987 Eric Roskos # OBJ1 = \ abort.obj abs.obj access.obj alarm.obj atoi.obj atol.obj bcopy.obj \ brk.obj brk2.obj brksize.obj call.obj catchsig.obj chdir.obj chmod.obj \ chown.obj chroot.obj cleanup.obj close.obj creat.obj crtso.obj crypt.obj \ csv.obj ctype.obj doprintf.obj dup.obj dup2.obj end.obj exec.obj OBJ2 = \ exit.obj fclose.obj fflush.obj fgets.obj fopen.obj fork.obj fprintf.obj \ fputs.obj fread.obj freopen.obj fseek.obj fstat.obj ftell.obj fwrite.obj \ getc.obj getegid.obj getenv.obj geteuid.obj getgid.obj getgrent.obj \ getpass.obj getpid.obj getpwent.obj gets.obj getuid.obj getutil.obj OBJ3 = \ index.obj ioctl.obj isatty.obj itoa.obj kill.obj \ link.obj lseek.obj malloc.obj message.obj mknod.obj \ mktemp.obj mount.obj open.obj pause.obj perror.obj pipe.obj printdat.obj \ printk.obj prints.obj putc.obj rand.obj read.obj OBJ4 = \ regexp.obj regsub.obj rindex.obj scanf.obj sendrec.obj setbuf.obj \ setgid.obj setjmp.obj setuid.obj signal.obj sleep.obj sprintf.obj \ stat.obj stb.obj stderr.obj stime.obj strcat.obj strcmp.obj \ strcpy.obj strlen.obj strncat.obj strncmp.obj strncpy.obj sync.obj OBJ5 = \ syslib.obj time.obj times.obj umask.obj umount.obj ungetc.obj \ unlink.obj utime.obj wait.obj write.obj # OBJ6 should be head.obj for building the OS, crtso.obj for building # Minix executables OBJ6 = head.obj .c.obj: cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c .asm.obj: masm $*; abort.obj: abort.c abs.obj: abs.c access.obj: access.c alarm.obj: alarm.c atoi.obj: atoi.c atol.obj: atol.c bcopy.obj: bcopy.c brk.obj: brk.c brk2.obj: brk2.c brksize.obj: brksize.asm call.obj: call.c catchsig.obj: catchsig.asm chdir.obj: chdir.c chmod.obj: chmod.c chown.obj: chown.c chroot.obj: chroot.c cleanup.obj: cleanup.c close.obj: close.c creat.obj: creat.c crtso.obj: crtso.asm crypt.obj: crypt.c csv.obj: csv.asm ctype.obj: ctype.c doprintf.obj: doprintf.c dup.obj: dup.c dup2.obj: dup2.c end.obj: end.asm exec.obj: exec.c exit.obj: exit.c fclose.obj: fclose.c fflush.obj: fflush.c fgets.obj: fgets.c fopen.obj: fopen.c fork.obj: fork.c fprintf.obj: fprintf.c fputs.obj: fputs.c fread.obj: fread.c freopen.obj: freopen.c fseek.obj: fseek.c fstat.obj: fstat.c ftell.obj: ftell.c fwrite.obj: fwrite.c getc.obj: getc.c getegid.obj: getegid.c getenv.obj: getenv.c geteuid.obj: geteuid.c getgid.obj: getgid.c getgrent.obj: getgrent.c getpass.obj: getpass.c getpid.obj: getpid.c getpwent.obj: getpwent.c gets.obj: gets.c getuid.obj: getuid.c getutil.obj: getutil.asm head.obj: head.asm index.obj: index.c ioctl.obj: ioctl.c isatty.obj: isatty.c itoa.obj: itoa.c kill.obj: kill.c link.obj: link.c lseek.obj: lseek.c malloc.obj: malloc.c message.obj: message.c mknod.obj: mknod.c mktemp.obj: mktemp.c mount.obj: mount.c open.obj: open.c pause.obj: pause.c perror.obj: perror.c pipe.obj: pipe.c printdat.obj: printdat.c printk.obj: printk.c prints.obj: prints.c putc.obj: putc.c rand.obj: rand.c read.obj: read.c regexp.obj: regexp.c regsub.obj: regsub.c rindex.obj: rindex.c scanf.obj: scanf.c sendrec.obj: sendrec.asm setbuf.obj: setbuf.c setgid.obj: setgid.c setjmp.obj: setjmp.asm setuid.obj: setuid.c signal.obj: signal.c sleep.obj: sleep.c sprintf.obj: sprintf.c stat.obj: stat.c stb.obj: stb.c stderr.obj: stderr.c stime.obj: stime.c strcat.obj: strcat.c strcmp.obj: strcmp.c strcpy.obj: strcpy.c strlen.obj: strlen.c strncat.obj: strncat.c strncmp.obj: strncmp.c strncpy.obj: strncpy.c sync.obj: sync.c syslib.obj: syslib.c time.obj: time.c times.obj: times.c umask.obj: umask.c umount.obj: umount.c ungetc.obj: ungetc.c unlink.obj: unlink.c utime.obj: utime.c wait.obj: wait.c write.obj: write.c minix.lib: $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5) $(OBJ6) del minix.lib lib @liblist SHAR_EOF if test 3909 -ne "`wc -c < 'lib'`" then echo shar: error transmitting "'lib'" '(should have been 3909 characters)' fi fi # end of overwriting check echo shar: extracting "'liblist'" '(1205 characters)' if test -f 'liblist' then echo shar: will not over-write existing file "'liblist'" else cat << \SHAR_EOF > 'liblist' minix.lib y +abort.obj+abs.obj+access.obj+alarm.obj+atoi.obj+atol.obj+bcopy.obj & +brk.obj+brk2.obj+brksize.obj+call.obj+catchsig.obj+chdir.obj+chmod.obj & +chown.obj+chroot.obj+cleanup.obj+close.obj+creat.obj+crypt.obj & +csv.obj+ctype.obj+doprintf.obj+dup.obj+dup2.obj+end.obj+exec.obj & +exit.obj+fclose.obj+fflush.obj+fgets.obj+fopen.obj+fork.obj+fprintf.obj & +fputs.obj+fread.obj+freopen.obj+fseek.obj+fstat.obj+ftell.obj+fwrite.obj & +getc.obj+getegid.obj+getenv.obj+geteuid.obj+getgid.obj+getgrent.obj & +getpass.obj+getpid.obj+getpwent.obj+gets.obj+getuid.obj+getutil.obj & +index.obj+ioctl.obj+isatty.obj+itoa.obj+kill.obj & +link.obj+lseek.obj+malloc.obj+mknod.obj & +mktemp.obj+mount.obj+open.obj+pause.obj+perror.obj+pipe.obj+printdat.obj & +printk.obj+prints.obj+putc.obj+rand.obj+read.obj & +regexp.obj+regsub.obj+rindex.obj+scanf.obj+sendrec.obj+setbuf.obj & +setgid.obj+setjmp.obj+setuid.obj+signal.obj+sleep.obj+sprintf.obj & +stat.obj+stb.obj+stderr.obj+stime.obj+strcat.obj+strcmp.obj & +strcpy.obj+strlen.obj+strncat.obj+strncmp.obj+strncpy.obj+sync.obj & +syslib.obj+time.obj+times.obj+umask.obj+umount.obj+ungetc.obj & +unlink.obj+utime.obj+wait.obj+write.obj+message.obj minix.lst SHAR_EOF if test 1205 -ne "`wc -c < 'liblist'`" then echo shar: error transmitting "'liblist'" '(should have been 1205 characters)' fi fi # end of overwriting check # End of shell archive exit 0
ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # mm/_link.bat # mm/linklist # mm/mm # This archive created: Sat Aug 1 14:04:05 1987 export PATH; PATH=/bin:$PATH echo shar: extracting "'_link.bat'" '(115 characters)' if test -f '_link.bat' then echo shar: will not over-write existing file "'_link.bat'" else cat << \SHAR_EOF > '_link.bat' echo Linking memory manager link/m/NOD ..\lib\head+ <linklist >link.lst ..\dos2out mm >dos2out.lst >dos2out.lst SHAR_EOF if test 115 -ne "`wc -c < '_link.bat'`" then echo shar: error transmitting "'_link.bat'" '(should have been 115 characters)' fi fi # end of overwriting check echo shar: extracting "'linklist'" '(89 characters)' if test -f 'linklist' then echo shar: will not over-write existing file "'linklist'" else cat << \SHAR_EOF > 'linklist' main+forkexit+break+exec+signal+ getset+alloc+utility+table+putc mm mm ..\lib\minix libh SHAR_EOF if test 89 -ne "`wc -c < 'linklist'`" then echo shar: error transmitting "'linklist'" '(should have been 89 characters)' fi fi # end of overwriting check echo shar: extracting "'mm'" '(496 characters)' if test -f 'mm' then echo shar: will not over-write existing file "'mm'" else cat << \SHAR_EOF > 'mm' # # Makefile for MM # By E. Roskos 1987 # OBJ = alloc.obj break.obj exec.obj forkexit.obj getset.obj main.obj \ putc.obj signal.obj table.obj utility.obj .c.obj: cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c .asm.obj: masm $*,$*,$*; alloc.obj: alloc.c break.obj: break.c exec.obj: exec.c forkexit.obj: forkexit.c getset.obj: getset.c main.obj: main.c putc.obj: putc.c signal.obj: signal.c table.obj: table.c utility.obj: utility.c mm.out: $(OBJ) _link SHAR_EOF if test 496 -ne "`wc -c < 'mm'`" then echo shar: error transmitting "'mm'" '(should have been 496 characters)' fi fi # end of overwriting check # End of shell archive exit 0
ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # tools/fsck # tools/init # tools/bootblok # This archive created: Sat Aug 1 14:04:34 1987 export PATH; PATH=/bin:$PATH echo shar: extracting "'fsck'" '(284 characters)' if test -f 'fsck' then echo shar: will not over-write existing file "'fsck'" else cat << \SHAR_EOF > 'fsck' OBJ = fsck.obj fsck1.obj .c.obj: cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c .asm.obj: masm $*,$*,$*; fsck.obj: fsck.c fsck1.obj: fsck1.asm fsck.exe: $(OBJ) link /NOD fsck1+fsck,fsck,,..\lib\minix \lib\libh; >fsck.lst fsck.out: fsck.exe ..\dos2out -d fsck SHAR_EOF if test 284 -ne "`wc -c < 'fsck'`" then echo shar: error transmitting "'fsck'" '(should have been 284 characters)' fi fi # end of overwriting check echo shar: extracting "'init'" '(285 characters)' if test -f 'init' then echo shar: will not over-write existing file "'init'" else cat << \SHAR_EOF > 'init' OBJ = init.obj .c.obj: cl -Di8088 -DGENERIC_FDISK -X -I..\include -Osal -Gs -c $*.c .asm.obj: masm $*,$*,$*; init.obj: init.c init.exe: $(OBJ) link /NOD ..\lib\head+init+..\lib\message,init,,..\lib\minix \lib\libh; >init.lst init.out: init.exe ..\dos2out -pd init >>init.lst SHAR_EOF if test 285 -ne "`wc -c < 'init'`" then echo shar: error transmitting "'init'" '(should have been 285 characters)' fi fi # end of overwriting check echo shar: extracting "'bootblok'" '(160 characters)' if test -f 'bootblok' then echo shar: will not over-write existing file "'bootblok'" else cat << \SHAR_EOF > 'bootblok' bootblok.obj: bootblok.asm masm bootblok,,bootblok; bootblok.exe: bootblok.obj link bootblok; bootblok.bin: bootblok.exe exe2bin bootblok.exe bootblok.bin SHAR_EOF if test 160 -ne "`wc -c < 'bootblok'`" then echo shar: error transmitting "'bootblok'" '(should have been 160 characters)' fi fi # end of overwriting check # End of shell archive exit 0
ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)
title klib88 page,132 ; This file contains a number of assembly code utility routines needed by the ; kernel. They are: ; ; phys_copy: copies data from anywhere to anywhere in memory ; cp_mess: copies messages from source to destination ; port_out: outputs data on an I/O port ; port_in: inputs data from an I/O port ; lock: disable interrupts ; unlock: enable interrupts ; restore: restore interrupts [enable/disabled] as they were before lock[] ; build_sig: build 4 word structure pushed onto stack for signals ; csv: procedure prolog to save the registers ; cret: procedure epilog to restore the registers ; get_chrome: returns 0 is display is monochrome, 1 if it is color ; vid_copy: copy data to video ram [on color display during retrace only] ; get_byte: reads a byte from a user program and returns it as value ; The following procedures are defined in this file and called from outside it. PUBLIC _phys_copy, _cp_mess, _port_out, _port_in, _lock, _unlock, _restore PUBLIC _build_sig, _get_chrome, _vid_copy, _get_byte PUBLIC _reboot, _wreboot ifdef GENERIC_FDISK PUBLIC _hdisk_params, _diskio, _win_init, _wn_low_safety, _wn_low_xor endif ; The following external procedure is called in this file. EXTRN _panic:NEAR ; Variables and data structures EXTRN _color:WORD, _cur_proc:WORD, _proc_ptr:WORD, _splimit:WORD EXTRN _vid_mask:WORD PUBLIC _vec_table INCLUDE ..\lib\prologue.h ; ; Macro to call the Hard Disk BIOS. This is a macro because int 13 won't ; work with Minix on my BIOS... don't know why... this lets you ; change it easily. ; hdcall macro ifdef ERSATZ_GENERIC pushf call dword ptr [disk_rom] else int 13H endif endm _TEXT SEGMENT assume cs:_text,ds:dgroup ;=========================================================================== ; phys_copy ;=========================================================================== ; This routine copies a block of physical memory. It is called by: ; phys_copy( (long) source, (long) destination, (long) bytecount) _phys_copy: pushf ; save flags cli ; disable interrupts push bp ; save the registers push ax ; save ax push bx ; save bx push cx ; save cx push dx ; save dx push si ; save si push di ; save di push ds ; save ds push es ; save es mov bp,sp ; set bp to point to saved es L0: mov ax,28[bp] ; ax = high-order word of 32-bit destination mov di,26[bp] ; di = low-order word of 32-bit destination mov cx,4 ; start extracting click number from dest L1: rcr ax,1 ; click number is destination address / 16 rcr di,1 ; it is used in segment register for copy loop L1 ; 4 bits of high-order word are used mov es,di ; es = destination click mov ax,24[bp] ; ax = high-order word of 32-bit source mov si,22[bp] ; si = low-order word of 32-bit source mov cx,4 ; start extracting click number from source L2: rcr ax,1 ; click number is source address / 16 rcr si,1 ; it is used in segment register for copy loop L2 ; 4 bits of high-order word are used mov ds,si ; ds = source click mov di,26[bp] ; di = low-order word of dest address and di,000Fh ; di = offset from paragraph in es mov si,22[bp] ; si = low-order word of source address and si,000Fh ; si = offset from paragraph in ds mov dx,32[bp] ; dx = high-order word of byte count mov cx,30[bp] ; cx = low-order word of byte count test cx,8000h ; if bytes >= 32768, only do 32768 jnz L3 ; per iteration test dx,0FFFFh ; check high-order 17 bits to see if bytes jnz L3 ; if bytes >= 32768 then go to L3 jmp short L4 ; if bytes < 32768 then go to L4 L3: mov cx,8000h ; 0x8000 is unsigned 32768 L4: mov ax,cx ; save actual count used in ax; needed later test cx,0001h ; should we copy a byte or a word at a time? jz L5 ; jump if even rep movsb ; copy 1 byte at a time jmp short L6 ; check for more bytes L5: shr cx,1 ; word copy rep movsw ; copy 1 word at a time L6: mov dx,32[bp] ; decr count, incr src & dst, iterate if needed mov cx,30[bp] ; dx || cx is 32-bit byte count xor bx,bx ; bx || ax is 32-bit actual count used sub cx,ax ; compute bytes - actual count sbb dx,bx ; dx ;; cx is bytes not yet processed or cx,cx ; see if it is 0 jnz L7 ; if more bytes then go to L7 or dx,dx ; keep testing jnz L7 ; if loop done, fall through pop es ; restore all the saved registers pop ds ; restore ds pop di ; restore di pop si ; restore si pop dx ; restore dx pop cx ; restore cx pop bx ; restore bx pop ax ; restore ax pop bp ; restore bp popf ; restore flags ret ; return to caller L7: mov 32[bp],dx ; store decremented byte count back in mem mov 30[bp],cx ; as a long add 26[bp],ax ; increment destination adc 28[bp],bx ; carry from low-order word add 22[bp],ax ; increment source adc 24[bp],bx ; carry from low-order word jmp L0 ; start next iteration ;=========================================================================== ; cp_mess ;=========================================================================== ; This routine is makes a fast copy of a message from anywhere in the address ; space to anywhere else. It also copies the source address provided as a ; parameter to the call into the first word of the destination message. ; It is called by: ; cp_mess[src, src_clicks, src_offset, dst_clicks, dst_offset] ; where all 5 parameters are shorts [16-bits]. ; ; Note that the message size, 'Msize' is in WORDS [not bytes] and must be set ; correctly. Changing the definition of message the type file and not changing ; it here will lead to total disaster. ; This routine destroys ax. It preserves the other registers. Msize = 12 ; size of a message in 16-bit words _cp_mess: push bp ; save bp push es ; save es push ds ; save ds mov bp,sp ; index off bp because machine can't use sp pushf ; save flags cli ; disable interrupts push cx ; save cx push si ; save si push di ; save di mov ax,8[bp] ; ax = process number of sender mov di,16[bp] ; di = offset of destination buffer mov es,14[bp] ; es = clicks of destination mov si,12[bp] ; si = offset of source message mov ds,10[bp] ; ds = clicks of source message mov es:[di],ax ; copy sender's process number to dest message add si,2 ; don't copy first word add di,2 ; don't copy first word mov cx,Msize-1 ; remember, first word doesn't count rep movsw ; iterate cx times to copy the message pop di ; restore di pop si ; restore si pop cx ; restore cs popf ; restore flags pop ds ; restore ds pop es ; restore es pop bp ; restore bp ret ; that's all folks! ;=========================================================================== ; port_out ;=========================================================================== ; port_out(port, value) writes 'value' on the I/O port 'port'. _port_out: push bx ; save bx mov bx,sp ; index off bx push ax ; save ax push dx ; save dx mov dx,4[bx] ; dx = port mov ax,6[bx] ; ax = value out dx,al ; output 1 byte pop dx ; restore dx pop ax ; restore ax pop bx ; restore bx ret ; return to caller ;=========================================================================== ; port_in ;=========================================================================== ; port_in(port, &value) reads from port 'port' and puts the result in 'value'. _port_in: push bx ; save bx mov bx,sp ; index off bx push ax ; save ax push dx ; save dx mov dx,4[bx] ; dx = port in al,dx ; input 1 byte xor ah,ah ; clear ah mov bx,6[bx] ; fetch address where byte is to go mov [bx],ax ; return byte to caller in param pop dx ; restore dx pop ax ; restore ax pop bx ; restore bx ret ; return to caller ;=========================================================================== ; lock ;=========================================================================== ; Disable CPU interrupts. _lock: pushf ; save flags on stack cli ; disable interrupts pop dgroup:lockvar ; save flags for possible restoration later ret ; return to caller ;=========================================================================== ; unlock ;=========================================================================== ; Enable CPU interrupts. _unlock: sti ; enable interrupts ret ; return to caller ;=========================================================================== ; restore ;=========================================================================== ; Restore enable/disable bit to the value it had before last lock. _restore: push dgroup:lockvar ; push flags as they were before previous lock popf ; restore flags ret ; return to caller ;=========================================================================== ; build_sig ;=========================================================================== ; Build a structure that is pushed onto the stack for signals. It contains ; pc, psw, etc., and is machine dependent. The format is the same as generated ; by hardware interrupts, except that after the "interrupt", the signal number ; is also pushed. The signal processing routine within the user space first ; pops the signal number, to see which function to call. Then it calls the ; function. Finally, when the function returns to the low-level signal ; handling routine, control is passed back to where it was prior to the signal ; by executing a return-from-interrupt instruction, hence the need for using ; the hardware generated interrupt format on the stack. The call is: ; build_sig(sig_stuff, rp, sig) ; Offsets within proc table PC = 24 csreg = 18 PSW = 28 _build_sig: push bp ; save bp mov bp,sp ; set bp to sp for accessing params push bx ; save bx push si ; save si mov bx,4[bp] ; bx points to sig_stuff mov si,6[bp] ; si points to proc table entry mov ax,8[bp] ; ax = signal number mov [bx],ax ; put signal number in sig_stuff mov ax,PC[si] ; ax = signalled process' PC mov 2[bx],ax ; put pc in sig_stuff mov ax,csreg[si] ; ax = signalled process' cs mov 4[bx],ax ; put cs in sig_stuff mov ax,PSW[si] ; ax = signalled process' PSW mov 6[bx],ax ; put psw in sig_stuff pop si ; restore si pop bx ; restore bx pop bp ; restore bp ret ; return to caller ifdef NEEDCSV public csv, cret ;=========================================================================== ; csv & cret (compiler generated symbols) ;=========================================================================== ; This version of csv replaces the standard one. It checks for stack overflow ; within the kernel in a simpler way than is usually done. cret is standard. csv proc near pop bx ; bx = return address push bp ; stack old frame pointer mov bp,sp ; set new frame pointer to sp push di ; save di push si ; save si sub sp,ax ; ax = bytes of local variables cmp sp,dgroup:_splimit ; has kernel stack grown too large jbe csv1 ; if sp is too low, panic jmp [bx] ; normal return: copy bx to program counter csv1: mov dgroup:_splimit,0 ; prevent call to panic from aborting in csv mov bx,dgroup:_proc_ptr ; update rp->p_splimit mov WORD PTR 50[bx],0 ; rp->sp_limit = 0 push dgroup:_cur_proc ; task number mov ax,offset dgroup:stkoverrun; stack overran the kernel stack area push ax ; push first parameter call _panic ; call is: panic(stkoverrun, cur_proc) jmp csv1 ; this should not be necessary csv endp cret proc near lea sp,-4[bp] ; set sp to point to saved si pop si ; restore saved si pop di ; restore saved di pop bp ; restore bp ret ; end of procedure cret endp endif ; needcsv ;=========================================================================== ; get_chrome ;=========================================================================== ; This routine calls the BIOS to find out if the display is monochrome or ; color. The drivers are different, as are the video ram addresses, so we ; need to know. _get_chrome: int 11h ; call the BIOS to get equipment type and al,30h ; isolate color/mono field cmp al,30h ; 0x30 is monochrome je getchr1 ; if monochrome then go to getchr1 mov ax,1 ; color = 1 ret ; color return getchr1:xor ax,ax ; mono = 0 ret ; monochrome return ;=========================================================================== ; vid_copy ;=========================================================================== ; This routine takes a string of [character, attribute] pairs and writes them ; onto the screen. For a color display, the writing only takes places during ; the vertical retrace interval, to avoid displaying garbage on the screen. ; The call is: ; vid_copy(buffer, videobase, offset, words) ; where ; 'buffer' is a pointer to the (character, attribute) pairs ; 'videobase' is 0xB800 for color and 0xB000 for monochrome displays ; 'offset' tells where within video ram to copy the data ; 'words' tells how many words to copy ; if buffer is zero, the fill character (BLANK) is used BLANK = 0700h _vid_copy: push bp ; we need bp to access the parameters mov bp,sp ; set bp to sp for indexing push si ; save the registers push di ; save di push bx ; save bx push cx ; save cx push dx ; save dx push es ; save es vid0: mov si,4[bp] ; si = pointer to data to be copied mov di,8[bp] ; di = offset within video ram and di,dgroup:_vid_mask ; only 4K or 16K counts mov cx,10[bp] ; cx = word count for copy loop mov dx,03DAh ; prepare to see if color display is retracing mov bx,di ; see if copy will run off end of video ram add bx,cx ; compute where copy ends add bx,cx ; bx = last character copied + 1 sub bx,dgroup:_vid_mask ; bx = # characters beyond end of video ram sub bx,1 ; note: dec bx doesn't set flags properly jle vid1 ; jump if no overrun sar bx,1 ; bx = # words that don't fit in video ram sub cx,bx ; reduce count by overrun mov dgroup:tmp,cx ; save actual count used for later vid1: test dgroup:_color,1 ; skip vertical retrace test if display is mono jz vid4 ; if monochrome then go to vid.2 ; vid2:in ; with a color display, you can only copy to ; test al,010q ; the video ram during vertical retrace, so ; jnz vid2 ; wait for start of retrace period. Bit 3 of vid3: in al,dx ; 0x3DA is set during retrace. First wait test al,010q ; until it is off (no retrace), then wait jz vid3 ; until it comes on (start of retrace) vid4: pushf ; copying may now start; save the flags cli ; interrupts just get in the way: disable them mov es,6[bp] ; load es now: int routines may ruin it cmp si,0 ; si = 0 means blank the screen je vid7 ; jmp for blanking lock nop ; this is a trick for the IBM PC-simulator only ; 'lock' indicates a video ram access rep movsw ; this is the copy loop vid5: popf ; restore flags cmp bx,0 ; if bx < 0, then no overrun and we are done jle vid6 ; jump if everything fit mov 10[bp],bx ; set up residual count mov word ptr 8[bp],0 ; JER added size: start copying at base of video ram cmp word ptr 4[bp],0 ; JER added size: NIL_PTR means store blanks je vid0 ; go do it mov si,dgroup:tmp ; si = count of words copied add si,si ; si = count of bytes copied add 4[bp],si ; increment buffer pointer jmp vid0 ; go copy some more vid6: ; JER - not in original source (vid6 label) - hope it's right pop es ; restore registers pop dx ; restore dx pop cx ; restore cx pop bx ; restore bx pop di ; restore di pop si ; restore si pop bp ; restore bp ret ; return to caller vid7: mov ax,BLANK ; ax = blanking character rep stosw ; blank the screen jmp vid5 ; done ;=========================================================================== ; get_byte ;=========================================================================== ; This routine is used to fetch a byte from anywhere in memory. ; The call is: ; c = get_byte(seg, off) ; where ; 'seg' is the value to put in es ; 'off' is the offset from the es value _get_byte: push bp ; save bp mov bp,sp ; we need to access parameters push es ; save es mov es,4[bp] ; load es with segment value mov bx,6[bp] ; load bx with offset from segment mov al,es:[bx] ; al = byte xor ah,ah ; ax = byte pop es ; restore es pop bp ; restore bp ret ; return to caller ;=========================================================================== ; reboot & dump ;=========================================================================== ; This code reboots the PC rb_vect dw 00000H ; hardware restart address dw 0FFFFH ; The following zeros out BIOS RAM (ROS on an IBM :-)) to clear any ; warmstart flags that may be present in a given BIOS. zros proc near mov cx,0100H ; 200H bytes / sizeof(word) mov ax,0 ; segment 0 & value to store mov es,ax ; set es to low memory mov di,0400H ; clear addresses 400H-5FFH cld ; autoincrement rep stosw ; zero out memory ret zros endp ; Restore the interrupt vectors in low core. _resvec proc near cld mov cx,2*65 mov si,offset dgroup:_vec_table xor di,di mov es,di rep movsw ret _resvec endp _reboot: cli ; disable interrupts mov al,20h out 20h,al ; re-enable interrupt controller ;;;;; call _resvec ; restore the vectors in low core ;;;;; int 19h ; reboot the PC call zros ; zero out low memory to force cold restart jmp dword ptr rb_vect _wreboot: cli ; disable interrupts mov al,20h ; re-enable interrupt controller out 20h,al call _resvec ; restore the vectors in low core to call BIOS xor ax,ax ; wait for character before continuing int 16h ; get char call zros ; zero out low memory to force cold restart ;;;;; int 19h ; reboot the PC jmp dword ptr rb_vect ifdef GENERIC_FDISK ;=========================================================================== ; diskio - JER (copied from fsck1) ;=========================================================================== ; diskio(RW, cyl, sector, head, #sectors, drv, sb, ib, trksiz) ; 4 6 8 10 12 14 16 18 20 ; Do not issue a BIOS call that crosses a track boundary _diskio: push bp mov bp,sp push si push di mov tmp1,0 ; tmp1 = # sectors actually transferred mov di,12[bp] ; di = # sectors to transfer mov tmp2,di ; di = # sectors to transfer d0: mov ax,6[bp] ; cylinder mov cl,ah ; cl = hi-order bits of cylinder ror cl,1 ; BIOS expects hi bits in a funny place ror cl,1 ; mov ch,al ; cx = sector # in BIOS format mov dh,10[bp] ; dh = head and cl,0C0H ; mask off any garbage bits or cl,8[bp] ; cl = sector # in low 6 bits inc cl ; BIOS counts sectors starting at 1 mov dl,14[bp] ; dl = drive code (0-3 or 0x80 - 0x81) or dl,80H ; force "hard disk" bit on push es ; set es with sb of buffer mov bx,16[bp] mov es,bx mov bx,18[bp] ; bx = ib of buffer mov ah,4[bp] ; ah = READING or WRITING add ah,2 ; BIOS codes are 2 and 3, not 0 and 1 mov al,12[bp] ; al = # sectors to transfer mov tmp,ax ; save, al is # sectors to read/write hdcall ; call the hard disk BIOS pop es ; restore es saved when setting sb above ; cmp ah,0 ; ah!=0 means BIOS detected error (no, cy does) ; jne d2 ; exit with error jc d2fail ; if carry set, error occurred mov ax,tmp ; fetch count of sectors transferred xor ah,ah ; count is in ax add tmp1,ax ; tmp1 accumulates sectors transferred mov si,tmp1 ; are we done yet? cmp si,tmp2 je d2ok ; jump if done inc word ptr 8[bp] ; next time around, start 1 sector higher add 18[bp],200h ; move up in buffer by 512 bytes (ib 4 bits) jmp d0 d2ok: xor ah,ah ; indicate "read OK" to driver d2fail: xor al,al ; move 1-byte BIOS error code into integer xchg ah,al ; return value for C caller pop di pop si pop bp ret ;=========================================================================== ; hdisk_params - JER - get hard disk params (semi) legally ;=========================================================================== ; hdisk_params(drive, pparams) _hdisk_params proc near push bp mov bp,sp mov dl,4[bp] ; drive number or dl,80H ; indicate fixed disk mov ah,08H ; request parameters push es hdcall ; call the hard disk BIOS pop es mov bx,6[bp] ; near pointer to parameter block mov 2[bx],dh ; maximum head number mov byte ptr 3[bx],0 ; 256 head disk? inc word ptr 2[bx] ; convert to number of heads mov 6[bx],cl ; number of sectors and byte ptr 6[bx],3fH ; mask off cyl # bits mov byte ptr 7[bx],0 rol cl,1 ; get cyl # high order bits rol cl,1 and cl,03H xchg cl,ch ; put in proper order mov 0[bx],cx ; store in parameter block xor dh,dh mov 4[bx],dx ; number of drives pop bp ; done ret _hdisk_params endp _win_init proc near push bp mov bp,sp mov ah,00H ; BIOS reset mov dl,80H push es hdcall ; call the hard disk BIOS pop es jc wi0 ; return error if carry set mov ah,11H ; drive recalibrate mov dl,80H push es hdcall ; call hard disk BIOS pop es jc wi0 ; return error if carry set xor ax,ax ; return "OK" wi0: pop bp ret _win_init endp endif ; GENERIC_FDISK _TEXT ENDS _DATA SEGMENT lockvar DW 0 ; place to store flags for lock()/restore() tmp DW 0 ; count of bytes already copied tmp1 DW 0 tmp2 DW 0 ifdef ERSATZ_GENERIC ; ; The following vector is used to invoke the hard disk BIOS on the hard ; disk controller. It should be possible to do this via an int 13, but ; so far I haven't gotten it to work... there's some code down in paragraph 70 ; of DOS that seems to be causing this strange problem... I have to figure ; this out in detail, it doesn't make sense yet. ...Now I think I have it... ; disk_rom DW 00897H DW 0C800H endif ; ; The following are used by gn_wini to do an integrity check on the ; partition offsets -- they're here so that an errant program which ; destroys the "wini" table is less likely to destroy these too, although ; there's also a check on the integrity of these constants themselves ; against a constant in the instruction space of the winchester task. ; _wn_low_safety dd 0H _wn_low_xor dd 0H ; ; Here is where the original interrupt vectors get stored ; _vec_table DW 130 dup(0) ; storage for interrupt vectors stkoverrun DB "Kernel stack overrun, task = ",0 _DATA ENDS END ; end of assembly
ericr@ipmoea.UUCP (Eric Roskos) (08/22/87)
Title mpx88 page,132 ; This file is part of the lowest layer of the Minix kernel. All process ; switching and message handling is done here and in file "proc.c". This file ; is entered on every transition to the kernel, both for sending/receiving ; messages and for all interrupts. In all cases, the trap or interrupt ; routine first calls save() to store the machine state in the proc table. ; Then the stack is switched to k_stack. Finally, the real trap or interrupt ; handler (in C) is called. When it returns, the interrupt routine jumps to ; restart, to run the process or task whose number is in 'cur_proc'. ; ; The external entry points into this file are: ; s_call: process or task wants to send or receive a message ; tty_int: interrupt routine for each key depression and release ; lpr_int: interrupt routine for each line printer interrupt ; disk_int: disk interrupt routine ; clock_int: clock interrupt routine [HZ times per second] ; surprise: all other interrupts < 16 are vectored here ; trp: all traps with vector >= 16 are vectored here ; divide: divide overflow traps are vectored here ; restart: start running a task or process ; include the following from const.h: K_STACK_BYTES EQU 256 IDLE EQU -999 ; include the following from ../h/com.h DISKINT EQU 1 CLOCK EQU -3 CLOCK_TICK EQU 2 FLOPPY EQU -5 WINI EQU -6 ; The following keeps MSC's refs to this symbol from pulling in crtso.obj PUBLIC __acrtused __acrtused EQU 9876H ; The following procedures are defined in this file and called from outside it. PUBLIC $main, _tty_int, _lpr_int, _clock_int, _disk_int, _wini_int PUBLIC _s_call, _surprise, _trp, _divide, _restart ; The following external procedures are called in this file. EXTRN _main:NEAR, _sys_call:NEAR, _intr:NEAR, _keyboard:NEAR EXTRN _panic:NEAR, _unexpected_int:NEAR, _trap:NEAR, _div_trap:NEAR, EXTRN _pr_char:NEAR ; Variables and data structures. PUBLIC _sizes, _brksize, _splimit, _end EXTRN _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD EXTRN _scan_code:WORD, _k_stack:WORD ; The following constants are offsets into the proc table. esreg = 14 dsreg = 16 csreg = 18 ssreg = 20 spreg = 22 PC = 24 PSW = 28 SPLIM = 50 OFF = 18 ROFF = 12 INCLUDE ..\lib\prologue.h ;=========================================================================== ; data - JER moved here from before stack ;=========================================================================== _DATAB SEGMENT ; datab ensures it is the beginning of all data _sizes DW 526Fh ; this must be the first data entry (magic nr) DW 7 dup(0) ; space for build table - total 16b _splimit DW 0 ; stack limit for current task (kernel only) _bx_save DW 0 ; storage for bx _ds_save DW 0 ; storage for ds _ret_save DW 0 ; storage for return address _lds_low DW 0,0 ; storage used for restoring ds:bx _brksize DW offset dgroup:_END+2 ; first free memory in kernel _ttyomess DB "RS232 interrupt",0 _DATAB ENDS _DATAV SEGMENT ; DATAV holds nothing. _end label byte ; the segment just tells us where _DATAV ENDS ; the data+bss ends. _TEXT SEGMENT ;=========================================================================== ; Minix ;=========================================================================== $main: Minix: ; this is the entry point for the Minix kernel. jmp short M0 ; skip over the next word(s) ORG 4 ; build writes the ds value at text address 4 ker_ds DW dgroup ; this word will contain kernel's ds value ; and it forces relocation for dos2out M0: cli ; disable interrupts mov ax,cs ; set up segment registers mov ds,ax ; set up ds mov ax,ker_ds ; build has loaded this word with ds value mov ds,ax ; ds now contains proper value mov ss,ax ; ss now contains proper value mov es,ax ; JER - set es too ifdef debug call prtax endif mov dgroup:_scan_code,bx ; save scan code for '=' key from bootstrap mov sp,offset dgroup:_k_stack ; set sp to point to the top of the add sp,K_STACK_BYTES ; kernel stack wto 'Kernel EP: stack now set up' call _main ; start the main program of Minix wto 'Fatal: kernel _main returned' M1:jmp M1 ; this should never be executed ;=========================================================================== ; s_call ;=========================================================================== _s_call: ; System calls are vectored here. call _save ; save the machine state mov bp,dgroup:_proc_ptr ; use bp to access sys call parameters push 2[bp] ; push(pointer to user message) (was bx) push [bp] ; push(src/dest) (was ax) push dgroup:_cur_proc ; push caller push 4[bp] ; push(SEND/RECEIVE/BOTH) (was cx) call _sys_call ; sys_call(function, caller, src_dest, m_ptr) jmp _restart ; jump to code to restart proc/task running ;=========================================================================== ; tty_int ;=========================================================================== _tty_int: ; Interrupt routine for terminal input. call _save ; save the machine state call _keyboard ; process a keyboard interrupt jmp _restart ; continue execution ;=========================================================================== ; lpr_int ;=========================================================================== _lpr_int: ; Interrupt routine for terminal input. call _save ; save the machine state call _pr_char ; process a line printer interrupt jmp _restart ; continue execution ;=========================================================================== ; disk_int ;=========================================================================== _disk_int: ; Interrupt routine for the floppy disk. call _save ; save the machine state mov dgroup:_int_mess+2,DISKINT ; build message for disk task mov ax,offset dgroup:_int_mess ; prepare to call interrupt[FLOPPY, &intmess] push ax ; push second parameter mov ax,FLOPPY ; prepare to push first parameter push ax ; push first parameter call _intr ; this is the call jmp _restart ; continue execution ;*===========================================================================* ;* wini_int * ;*===========================================================================* _wini_int: ; Interrupt routine for the winchester disk. call _save ; save the machine state mov dgroup:_int_mess+2,DISKINT; build message for winchester task mov ax,offset dgroup:_int_mess ; prepare to call interrupt(WINI, &intmess) push ax ; push second parameter mov ax,WINI ; prepare to push first parameter push ax ; push first parameter call _intr ; this is the call jmp _restart ; continue execution ;=========================================================================== ; clock_int ;=========================================================================== _clock_int: ; Interrupt routine for the clock. call _save ; save the machine state mov dgroup:_int_mess+2,CLOCK_TICK; build message for clock task mov ax,offset dgroup:_int_mess ; prepare to call interrupt(CLOCK,&intmess) push ax ; push second parameter mov ax,CLOCK ; prepare to push first parameter push ax ; push first parameter call _intr ; this is the call jmp _restart ; continue execution ;=========================================================================== ; surprise ;=========================================================================== _surprise: ; This is where unexpected interrupts come. call _save ; save the machine state call _unexpected_int ; go panic jmp _restart ; never executed ;=========================================================================== ; trp ;=========================================================================== _trp: ; This is where unexpected traps come. call _save ; save the machine state call _trap ; print a message jmp _restart ; this error is not fatal ;=========================================================================== ; divide ;=========================================================================== _divide: ; This is where divide overflow traps come. call _save ; save the machine state call _div_trap ; print a message jmp _restart ; this error is not fatal ;=========================================================================== ; save ;=========================================================================== _save: ; save the machine state in the proc table. push ds ; stack: psw/cs/pc/ret addr/ds push cs ; prepare to restore ds pop ds ; ds has now been set to cs mov ds,ker_ds ; word 4 in kernel text space contains ds value pop dgroup:_ds_save ; stack: psw/cs/pc/ret addr pop dgroup:_ret_save ; stack: psw/cs/pc mov dgroup:_bx_save,bx ; save bx for later ; we need a free register mov bx,dgroup:_proc_ptr ; start save set up; make bx point to save area add bx,OFF ; bx points to place to store cs pop PC-OFF[bx] ; store pc in proc table pop csreg-OFF[bx] ; store cs in proc table pop PSW-OFF[bx] ; store psw mov ssreg-OFF[bx],ss ; store ss mov spreg-OFF[bx],sp ; sp as it was prior to interrupt mov sp,bx ; now use sp to point into proc table/task save mov bx,ds ; about to set ss mov ss,bx ; set ss push dgroup:_ds_save ; start saving all the registers, sp first push es ; save es between sp and bp mov es,bx ; es now references kernel memory too push bp ; save bp push di ; save di push si ; save si push dx ; save dx push cx ; save cx push dgroup:_bx_save ; save original bx push ax ; all registers now saved mov sp,offset dgroup:_k_stack ; temporary stack for interrupts add sp,K_STACK_BYTES ; set sp to top of temporary stack mov dgroup:_splimit,offset dgroup:_k_stack ; limit for temporary stack add dgroup:_splimit,8 ; splimit checks for stack overflow mov ax,dgroup:_ret_save ; ax = address to return to jmp ax ; return to caller; Note: sp points to saved ax ;=========================================================================== ; restart ;=========================================================================== _restart: ; This routine sets up and runs a proc or task. cmp dgroup:_cur_proc,IDLE; restart user; if cur_proc = IDLE, go idle je _idle ; no user is runnable, jump to idle routine cli ; disable interrupts mov sp,dgroup:_proc_ptr ; return to user, fetch regs from proc table pop ax ; start restoring registers pop bx ; restore bx pop cx ; restore cx pop dx ; restore dx pop si ; restore si pop di ; restore di mov dgroup:_lds_low,bx ; lds_low contains bx mov bx,sp ; bx points to saved bp register mov bp,SPLIM-ROFF[bx] ; splimit = p_splimit mov dgroup:_splimit,bp ; ditto mov bp,dsreg-ROFF[bx] ; bp = ds mov dgroup:_lds_low+2,bp ; lds_low+2 contains ds pop bp ; restore bp pop es ; restore es mov sp,spreg-ROFF[bx] ; restore sp mov ss,ssreg-ROFF[bx] ; restore ss using the value of ds push PSW-ROFF[bx] ; push psw (flags) push csreg-ROFF[bx] ; push cs push PC-ROFF[bx] ; push pc lds bx,DWORD PTR dgroup:_lds_low ; restore ds and bx in one fell swoop iret ; return to user or task ;=========================================================================== ; idle ;=========================================================================== _idle: ; executed when there is no work sti ; enable interrupts L3: wait ; just idle while waiting for interrupt jmp L3 ; loop until interrupt ;=========================================================================== ; print - JER - print a debug message ;=========================================================================== ifdef debug print proc ; print string (bx), ax destroyed mov al,[bx] ; al contains char to be printed test al,al ; null char? jne prt1 ; no ret ; else return prt1: mov ah,14 ; 14 = print char inc bx ; increment string pointer push bx ; save bx mov bl,1 ; foreground color xor bh,bh ; page 0 int 10h ; call BIOS VIDEO_IO pop bx ; restore bx jmp print ; next character print endp ; ; prtnum - print low-order 4 bits of al register in hex ; prtnum proc near push ds push cs pop ds push bx mov bx,offset xltab xlatb mov ah,14 mov bh,10 int 10H pop bx pop ds ret xltab db '0123456789ABCDEF ' prtnum endp ; ; prtax - print ax register's contents in hex ; prtax proc near push cx push ax mov al,ah mov cl,4 shr al,cl call prtnum pop ax push ax mov al,ah and al,0fH call prtnum pop ax push ax mov cl,4 shr al,cl call prtnum pop ax push ax and al,0fH call prtnum mov al,10H ; special value to print a space call prtnum pop ax pop cx ret prtax endp endif _TEXT ENDS @STACK SEGMENT PARA STACK 'STACK' ; Satisfy DOS-linker (dummy stack) @STACK ENDS END ; end of assembly-file