jaime@killer (James da Silva @ The Unix Connection BBS, Dallas, Texas) (06/28/87)
After more than a couple nights of poking around and endless
iterations of re-compiling the kernel, I have gotten Minix to
boot on a 16Mhz Intel-Motherboard 80386 AT.
The basic incompatibility arises in the vid_copy function, used
to copy text into screen memory. AST uses the 'lock' prefix to
indicate to the PC-Simulator that video memory has changed. The
specific instruction used is 'lock nop'.
The designers of the 80386 decided to restrict the use of the
lock prefix to certain instructions that read a value from
memory, modify it in some way, then store it back in the same
memory location. In particular, the lock prefix is permitted only
with the following instructions and addressing modes:
BT, BTS, BTR, BTC mem, reg/immediate
ADD, OR, ADC, SBB, AND, SUB, XOR mem, reg/immediate
XCHG reg, mem
XCHG mem, reg
NOT, NEG, INC, DEC mem
The 'lock nop' instruction was causing an undefined opcode trap
to occur. Not Pretty. And not easy to find. With the lock nop
instruction commented out, Minix came up without a hitch.
If you want to maintain compatibility with the PC Simulator (as I
expect AST will with any release), vid_copy must be modified to
lock one of the instructions mentioned above. I added a dummy
byte in the data segment named 'vidlck', then incremented it with
the lock prefix. This works on my 386, and it should work under
the PC Simulator, too.
For the compatibility records, my machine is an Intel iSBC 386AT
motherboard. I think this is the same motherboard used in the
Wyse 386 and others. My guess is that, with this fix installed,
Minix should boot on any AT-compatible 80386 box, including the
Compaq 386.
I'd love to hear from any other people running (or trying to run)
Minix on a 386. Protected mode Minix, anyone?
Here's the modified vid_copy function:
|*===========================================================================*
|* 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 char (BLANK) is used
|
| June 28, 1987 - modified by James da Silva to work on 80386 machines and
| still remain compatible with AST's PC-Simulator.
BLANK = 0x0700 | controls color of cursor on blank screen
.data
vidlck: .byte 0 | a dummy data byte used in lock
.text
_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
vid.0: mov si,4(bp) | si = pointer to data to be copied
mov di,8(bp) | di = offset within video ram
and di,_vid_mask | only 4K or 16K counts
mov cx,10(bp) | cx = word count for copy loop
mov dx,#0x3DA | 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,_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
vid.1: test _color,*1 | skip vertical retrace test if display is mono
jz vid.4 | if monochrome then go to vid.2
|vid.2: in | with a color display, you can only copy to
| test al,*010 | the video ram during vertical retrace, so
| jnz vid.2 | wait for start of retrace period. Bit 3 of
vid.3: in | 0x3DA is set during retrace. First wait
testb al,*010 | until it is off (no retrace), then wait
jz vid.3 | until it comes on (start of retrace)
vid.4: pushf | copying may now start; save 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 vid.7 | jump for blanking
lock | this is a trick for the IBM PC simulator only
incb vidlck | 'lock' indicates a video ram access
rep | this is the copy loop
movw | ditto
vid.5: popf | restore flags
cmp bx,#0 | if bx < 0, then no overrun and we are done
jle vid.6 | 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 vid.0 | 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 vid.0 | go copy some more
vid.6: 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
vid.7: mov ax,#BLANK | ax = blanking character
rep | copy loop
stow | blank screen
jmp vid.5 | done
----------------------------------------------------------------
James da Silva 14102 Bramble Ct. #203
Path: ..!ihnp4!killer!jaime Laurel, Maryland 20807