Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!mit-eddie!uw-beaver!tikal!amc!ipmoea!ericr From: ericr@ipmoea.UUCP (Eric Roskos) Newsgroups: comp.os.minix Subject: Changes to compile Minix with MSC (Kernel changes: 1 of 12) Message-ID: <21@ipmoea.UUCP> Date: Sat, 8-Aug-87 20:00:00 EDT Article-I.D.: ipmoea.21 Posted: Sat Aug 8 20:00:00 1987 Date-Received: Tue, 11-Aug-87 05:23:30 EDT Reply-To: ericr@ipmoea.UUCP (Eric Roskos) Organization: Redmond, WA Lines: 2671 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);