evas@euraiv1.UUCP (10/02/87)
Here is part 2 of 9: Eelco van Asperen.
echo Extracting kernel/mpx88.dif
sed 's/^X//' > kernel/mpx88.dif << '+ END-OF-FILE 'kernel/mpx88.dif
X12c12
X< ; restart, to run the process or task whose number is in 'cur_proc'.
X---
X> ; _restart, to run the process or task whose number is in 'cur_proc'.
X23c23
X< ; restart: start running a task or process
X---
X> ; _restart: start running a task or process
X34a35
X> WINCHESTER EQU -6
X38,39c39,41
X< PUBLIC $main, tty_int, lpr_int, clock_in, disk_int
X< PUBLIC s_call, surprise, trp, divide, restart
X---
X> PUBLIC $main, _tty_int, _lpr_int, _clock_int, _disk_int
X> public _wini_int
X> PUBLIC _s_call, _surprise, _trp, _divide, _restart
X43,44c45,46
X< EXTRN main:NEAR, sys_call:NEAR, interrup:NEAR, keyboard:NEAR
X< EXTRN panic:NEAR, unexpect:NEAR, trap:NEAR, div_trap:NEAR, pr_char:NEAR
X---
X> EXTRN _main:NEAR, _sys_call:NEAR, _interrupt:NEAR, _keyboard:NEAR
X> EXTRN _panic:NEAR, _unexpected_int:NEAR, _trap:NEAR, _div_trap:NEAR, _pr_char:NEAR
X48,50c50,52
X< PUBLIC sizes, brksize, splimit, @end
X< EXTRN cur_proc:WORD, proc_ptr:WORD, int_mess:WORD
X< EXTRN scan_cod:WORD, k_stack:WORD
X---
X> PUBLIC _sizes, _brksize, _splimit, __end
X> EXTRN _cur_proc:WORD, _proc_ptr:WORD, _int_mess:WORD
X> EXTRN _scan_code:WORD, _k_stack:WORD
X69,70c71,72
X< @CODE SEGMENT
X< assume cs:@code,ds:dgroup
X---
X> _TEXT SEGMENT
X> assume cs:_TEXT,ds:dgroup
X87,90c89,92
X< mov dgroup:scan_cod,bx ; save scan code for '=' key from bootstrap
X< mov sp,offset dgroup:k_stack ; set sp to point to the top of the
X< add sp,K_STACK_BYTES ; kernel stack
X< call main ; start the main program of Minix
X---
X> mov dgroup:_scan_code,bx ; save scan code for '=' key from bootstrap
X> mov sp,offset dgroup:_k_stack ; set sp to point to the top of the
X> add sp,K_STACK_BYTES ; kernel stack
X> call _main ; start the main program of Minix
X98,106c100,108
X< s_call: ; System calls are vectored here.
X< call save ; save the machine state
X< mov bp,dgroup:proc_ptr ; use bp to access sys call parameters
X< push 2[bp] ; push(pointer to user message) (was bx)
X< push [bp] ; push(src/dest) (was ax)
X< push dgroup:cur_proc ; push caller
X< push 4[bp] ; push(SEND/RECEIVE/BOTH) (was cx)
X< call sys_call ; sys_call(function, caller, src_dest, m_ptr)
X< jmp restart ; jump to code to restart proc/task running
X---
X> _s_call: ; System calls are vectored here.
X> call save ; save the machine state
X> mov bp,dgroup:_proc_ptr ; use bp to access sys call parameters
X> push 2[bp] ; push(pointer to user message) (was bx)
X> push [bp] ; push(src/dest) (was ax)
X> push dgroup:_cur_proc ; push caller
X> push 4[bp] ; push(SEND/RECEIVE/BOTH) (was cx)
X> call _sys_call ; sys_call(function, caller, src_dest, m_ptr)
X> jmp _restart ; jump to code to _restart proc/task running
X112,115c114,117
X< tty_int: ; Interrupt routine for terminal input.
X< call save ; save the machine state
X< call keyboard ; process a keyboard interrupt
X< jmp restart ; continue execution
X---
X> _tty_int: ; Interrupt routine for terminal input.
X> call save ; save the machine state
X> call _keyboard ; process a keyboard interrupt
X> jmp _restart ; continue execution
X121,124c123,126
X< lpr_int: ; Interrupt routine for terminal input.
X< call save ; save the machine state
X< call pr_char ; process a line printer interrupt
X< jmp restart ; continue execution
X---
X> _lpr_int: ; Interrupt routine for terminal input.
X> call save ; save the machine state
X> call _pr_char ; process a line printer interrupt
X> jmp _restart ; continue execution
X128,133c130,148
X< ; disk_int
X< ;===========================================================================
X< disk_int: ; Interrupt routine for the floppy disk.
X< call save ; save the machine state
X< mov dgroup:int_mess+2,DISKINT ; build message for disk task
X< mov ax,offset dgroup:int_mess ; prepare to call interrupt[FLOPPY, &intmess]
X---
X> ; _wini_int
X> ;===========================================================================
X> _wini_int: ; Interrupt routine for the floppy disk.
X> call save ; save the machine state
X> mov dgroup:_int_mess+2,DISKINT ; build message for disk task
X> mov ax,offset dgroup:_int_mess ; prepare to call interrupt[FLOPPY, &intmess]
X> push ax ; push second parameter
X> mov ax,WINCHESTER ; prepare to push first parameter
X> push ax ; push first parameter
X> call _interrupt ; this is the call
X> jmp _restart ; continue execution
X>
X> ;===========================================================================
X> ; disk_int
X> ;===========================================================================
X> _disk_int: ; Interrupt routine for the floppy disk.
X> call save ; save the machine state
X> mov dgroup:_int_mess+2,DISKINT ; build message for disk task
X> mov ax,offset dgroup:_int_mess ; prepare to call interrupt[FLOPPY, &intmess]
X137,138c152,153
X< call interrup ; this is the call
X< jmp restart ; continue execution
X---
X> call _interrupt ; this is the call
X> jmp _restart ; continue execution
X144,147c159,162
X< clock_in: ; Interrupt routine for the clock.
X< call save ; save the machine state
X< mov dgroup:int_mess+2,CLOCK_TICK; build message for clock task
X< mov ax,offset dgroup:int_mess ; prepare to call interrupt(CLOCK,&intmess)
X---
X> _clock_int: ; Interrupt routine for the clock.
X> call save ; save the machine state
X> mov dgroup:_int_mess+2,CLOCK_TICK; build message for clock task
X> mov ax,offset dgroup:_int_mess ; prepare to call interrupt(CLOCK,&intmess)
X151,152c166,167
X< call interrup ; this is the call
X< jmp restart ; continue execution
X---
X> call _interrupt ; this is the call
X> jmp _restart ; continue execution
X158,161c173,176
X< surprise: ; This is where unexpected interrupts come.
X< call save ; save the machine state
X< call unexpect ; go panic
X< jmp restart ; never executed
X---
X> _surprise: ; This is where unexpected interrupts come.
X> call save ; save the machine state
X> call _unexpected_int ; go panic
X> jmp _restart ; never executed
X167,170c182,185
X< trp: ; This is where unexpected traps come.
X< call save ; save the machine state
X< call trap ; print a message
X< jmp restart ; this error is not fatal
X---
X> _trp: ; This is where unexpected traps come.
X> call save ; save the machine state
X> call _trap ; print a message
X> jmp _restart ; this error is not fatal
X176,179c191,194
X< divide: ; This is where divide overflow traps come.
X< call save ; save the machine state
X< call div_trap ; print a message
X< jmp restart ; this error is not fatal
X---
X> _divide: ; This is where divide overflow traps come.
X> call save ; save the machine state
X> call _div_trap ; print a message
X> jmp _restart ; this error is not fatal
X193c208
X< mov bx,dgroup:proc_ptr ; start save set up; make bx point to save area
X---
X> mov bx,dgroup:_proc_ptr ; start save set up; make bx point to save area
X213,216c228,231
X< mov sp,offset dgroup:k_stack ; temporary stack for interrupts
X< add sp,K_STACK_BYTES ; set sp to top of temporary stack
X< mov splimit,offset dgroup:k_stack ; limit for temporary stack
X< add splimit,8 ; splimit checks for stack overflow
X---
X> mov sp,offset dgroup:_k_stack ; temporary stack for interrupts
X> add sp,K_STACK_BYTES ; set sp to top of temporary stack
X> mov _splimit,offset dgroup:_k_stack ; limit for temporary stack
X> add _splimit,8 ; splimit checks for stack overflow
X222,228c237,243
X< ; restart
X< ;===========================================================================
X< restart: ; This routine sets up and runs a proc or task.
X< cmp dgroup:cur_proc,IDLE; restart user; if cur_proc = IDLE, go idle
X< je _idle ; no user is runnable, jump to idle routine
X< cli ; disable interrupts
X< mov sp,dgroup:proc_ptr ; return to user, fetch regs from proc table
X---
X> ; _restart
X> ;===========================================================================
X> _restart: ; This routine sets up and runs a proc or task.
X> cmp dgroup:_cur_proc,IDLE; _restart user; if cur_proc = IDLE, go idle
X> je _idle ; no user is runnable, jump to idle routine
X> cli ; disable interrupts
X> mov sp,dgroup:_proc_ptr ; return to user, fetch regs from proc table
X238c253
X< mov splimit,bp ; ditto
X---
X> mov _splimit,bp ; ditto
X260c275
X< @CODE ENDS
X---
X> _TEXT ENDS
X267,270c282,285
X< @DATAB SEGMENT ; datab ensures it is the beginning of all data
X< sizes DW 526Fh ; this must be the first data entry (magic nr)
X< DW 7 dup(0) ; space for build table - total 16b
X< splimit DW 0 ; stack limit for current task (kernel only)
X---
X> _DATABEG SEGMENT ; DATABEG ensures it is the beginning of all data
X> _sizes DW 526Fh ; this must be the first data entry (magic nr)
X> DW 7 dup(0) ; space for build table - total 16b
X> _splimit DW 0 ; stack limit for current task (kernel only)
X275,288c290,302
X< brksize DW offset dgroup:@END+2 ; first free memory in kernel
X< ttyomess DB "RS232 interrupt",0
X< @DATAB ENDS
X<
X<
X< @DATAV SEGMENT ; DATAV holds nothing. The label in
X< @end label byte ; the segment just tells us where
X< @DATAV ENDS ; the data+bss ends.
X<
X< @STACK SEGMENT BYTE STACK 'STACK' ; Satisfy DOS-linker (dummy stack)
X< @STACK ENDS
X<
X< END ; end of assembly-file
X<
X---
X> _brksize DW offset dgroup:__end+2 ; first free memory in kernel
X> ttyomess DB "RS232 interrupt",0
X> _DATABEG ENDS
X>
X>
X> _DATAEND SEGMENT ; DATAEND holds nothing. The label in
X> __end label byte ; the segment just tells us where
X> _DATAEND ENDS ; the data+bss ends.
X>
X> _STACK SEGMENT BYTE STACK 'STACK' ; Satisfy DOS-linker (dummy stack)
X> _STACK ENDS
X>
X> END ; end of assembly-file
+ END-OF-FILE kernel/mpx88.dif
chmod u=rw,g=r,o=r kernel/mpx88.dif
set `sum kernel/mpx88.dif`
sum=$1
case $sum in
50985) :;;
*) echo 'Bad sum in 'kernel/mpx88.dif >&2
esac
echo Extracting kernel/printer.dif
sed 's/^X//' > kernel/printer.dif << '+ END-OF-FILE 'kernel/printer.dif
X33,34c33,34
X< #define NORMAL_STATUS 0xDF /* printer gives this status when idle */
X< #define BUSY_STATUS 0x5F /* printer gives this status when busy */
X---
X> #define NORMAL_STATUS 0x90 /* printer gives this status when idle */
X> #define BUSY_STATUS 0x10 /* printer gives this status when busy */
X48a49
X> #define STATUS_MASK 0xB0 /* mask to filter out status bits */
X121c122
X< if (value == NORMAL_STATUS) {
X---
X> if ((value&STATUS_MASK) == NORMAL_STATUS) {
X127c128
X< if (value == BUSY_STATUS) {
X---
X> if ((value&STATUS_MASK) == BUSY_STATUS) {
X139c140
X< if (value == BUSY_STATUS) r = EAGAIN;
X---
X> if ((value&STATUS_MASK) == BUSY_STATUS) r = EAGAIN;
X253c254
X< if (value == NORMAL_STATUS) {
X---
X> if ((value&STATUS_MASK) == NORMAL_STATUS) {
X264c265
X< } else if (value == BUSY_STATUS) {
X---
X> } else if ((value&STATUS_MASK) == BUSY_STATUS) {
X275a277,278
X>
X>
+ END-OF-FILE kernel/printer.dif
chmod u=rw,g=r,o=r kernel/printer.dif
set `sum kernel/printer.dif`
sum=$1
case $sum in
63911) :;;
*) echo 'Bad sum in 'kernel/printer.dif >&2
esac
echo Extracting kernel/proc.dif
sed 's/^X//' > kernel/proc.dif << '+ END-OF-FILE 'kernel/proc.dif
X40c40,42
X< if (pc_at) port_out(INT2_CTL, ENABLE); /* re-enable second 8259A */
X---
X> if (pc_at && task == WINCHESTER)
X> /* this re-enables the second controller chip */
X> port_out(INT2_CTL, ENABLE);
+ END-OF-FILE kernel/proc.dif
chmod u=rw,g=r,o=r kernel/proc.dif
set `sum kernel/proc.dif`
sum=$1
case $sum in
15207) :;;
*) echo 'Bad sum in 'kernel/proc.dif >&2
esac
echo Extracting kernel/system.dif
sed 's/^X//' > kernel/system.dif << '+ END-OF-FILE 'kernel/system.dif
X154,204c154
X< );
X< cursor(6,7,0); LowVideo;
X< with t[n] do
X< if (dir[1] = '!')
X< then begin
X< ViaCommand:=False; Pause:=False; Finito:=True;
X< if (dir[2] = '/')
X< then begin
X< i:=pos(' ',dir);
X< cmd:=copy(dir,i+1,length(dir)-i);
X< options:=copy(dir,2,i-2);
X< InOpt:=False;
X< for i:=1 to length(options) do
X< if (options[i] = '/')
X< then InOpt:=True
X< else if InOpt
X< then begin
X< case UpCase(options[i]) of
X< 'C': ViaCommand:=True;
X< 'P': Pause:=True;
X< 'R': Finito:=False;
X< end;
X< InOpt:=False;
X< end;
X< end
X< else cmd:=copy(dir,2,length(dir)-1);
X<
X< if ViaCommand
X< then error:=SubProcessViaCOMMAND(cmd)
X< else error:=SubProcess(cmd);
X< LowVideo;
X< if (error <> ok)
X< then writeln(^m^j'Error: ',DosErrorStr(error));
X< if Pause
X< then begin
X< write(^m^j'Hit any key to continue: ');
X< if ReadKey > 0 then {please Pascal God's};
X< writeln;
X< end;
X< end
X< else begin
X< {$I-}
X< ChDir(dir); error:=IOresult;
X< if (error <> ok) then writeln('Error: sub-directory not found');
X< Finito:=True;
X< {$I+}
X< end;
X< until Finito or (error <> ok);
X< Halt(error);
X< end.
X< register struct proc *rp, *rsrc;
X---
X> register struct proc *rp, *rsrc;
X506c456,508
X< /* MM is waiting for new input. Find a process with ---
X> /* MM is waiting for new input. Find a process with pending signals. */
X> for (rp = proc_addr(0); rp < proc_addr(NR_PROCS); rp++)
X> if (rp->p_pending != 0) {
X> m.m_type = KSIG;
X> m.PROC1 = rp - proc - NR_TASKS;
X> m.SIG_MAP = rp->p_pending;
X> sig_procs--;
X> if (mini_send(HARDWARE, proc_nr, &m) != OK)
X> panic("can't inform MM", NO_NUM);
X> rp->p_pending = 0; /* the ball is now in MM's court */
X> return;
X> }
X> }
X>
X>
X> /*===========================================================================*
X> * umap *
X> *===========================================================================*/
X> PUBLIC phys_bytes umap(rp, seg, vir_addr, bytes)
X> register struct proc *rp; /* pointer to proc table entry for process */
X> int seg; /* T, D, or S segment */
X> vir_bytes vir_addr; /* virtual address in bytes within the seg */
X> vir_bytes bytes; /* # of bytes to be copied */
X> {
X> /* Calculate the physical memory address for a given virtual address. */
X> vir_clicks vc; /* the virtual address in clicks */
X> phys_bytes seg_base, pa; /* intermediate variables as phys_bytes */
X>
X> /* If 'seg' is D it could really be S and vice versa. T really means T.
X> * If the virtual address falls in the gap, it causes a problem. On the
X> * 8088 it is probably a legal stack reference, since "stackfaults" are
X> * not detected by the hardware. On 8088s, the gap is called S and
X> * accepted, but on other machines it is called D and rejected.
X> */
X> if (bytes <= 0) return( (phys_bytes) 0);
X> vc = (vir_addr + bytes - 1) >> CLICK_SHIFT; /* last click of data */
X>
X> #ifdef i8088
X> if (seg != T)
X> seg = (vc < rp->p_map[D].mem_vir + rp->p_map[D].mem_len ? D : S);
X> #else
X> if (seg != T)
X> seg = (vc < rp->p_map[S].mem_vir ? D : S);
X> #endif
X>
X> if((vir_addr>>CLICK_SHIFT) >= rp->p_map[seg].mem_vir + rp->p_map[seg].mem_len)
X> return( (phys_bytes) 0 );
X> seg_base = (phys_bytes) rp->p_map[seg].mem_phys;
X> seg_base = seg_base << CLICK_SHIFT; /* segment orgin in bytes */
X> pa = (phys_bytes) vir_addr;
X> pa -= rp->p_map[seg].mem_vir << CLICK_SHIFT;
X> return(seg_base + pa);
X> }
+ END-OF-FILE kernel/system.dif
chmod u=rw,g=r,o=r kernel/system.dif
set `sum kernel/system.dif`
sum=$1
case $sum in
22746) :;;
*) echo 'Bad sum in 'kernel/system.dif >&2
esac
echo Extracting kernel/tty.dif
sed 's/^X//' > kernel/tty.dif << '+ END-OF-FILE 'kernel/tty.dif
X153c153
X< PUBLIC scan_code; /* scan code for '=' saved by bootstrap */
X---
X> PUBLIC int scan_code; /* scan code for '=' saved by bootstrap */
+ END-OF-FILE kernel/tty.dif
chmod u=rw,g=r,o=r kernel/tty.dif
set `sum kernel/tty.dif`
sum=$1
case $sum in
11016) :;;
*) echo 'Bad sum in 'kernel/tty.dif >&2
esac
echo Extracting kernel/xt_wini.dif
sed 's/^X//' > kernel/xt_wini.dif << '+ END-OF-FILE 'kernel/xt_wini.dif
X29a30,32
X> #define DEBUG FALSE /* TRUE: enable debug messages */
X> #define MONITOR TRUE /* TRUE: monitor performance of busy loops */
X>
X32a36,40
X> #define WST_REQ 0x001 /* Request bit */
X> #define WST_INPUT 0x002 /* Set if controller is writing to cpu */
X> #define WST_BUS 0x004 /* Command/status bit */
X> #define WST_BUSY 0x008 /* Busy */
X> #define WST_INTERRUPT 0x020 /* Interrupt generated ?? */
X53d60
X< #define CTRL_BYTE 5 /* Control byte for controller */
X70c77
X< #define MAX_WIN_RETRY 10000 /* max # times to try to output to WIN */
X---
X> #define MAX_WIN_RETRY 32000 /* max # times to try to output to WIN */
X78c85
X< int wn_drive; /* drive number addressed */
X---
X> int wn_drive; /* drive number addressed (<< 5) */
X82a90
X> int wn_ctrl_byte; /* Control byte for COMMANDS (10-Apr-87 GO) */
X105,106c113,118
X< } param0, param1;
X<
X---
X> int ctrl_byte; /* Copied control-byte from bios tables */
X> } param0, param1;
X>
X> #if DEBUG
X> #define port_out(port, val) xport_out(port, val)
X> #endif /* DEBUG */
X117c129
X< init_param();
X---
X> init_params();
X151c163
X< * w_do_rdwt *
X---
X> * w_do_rdwt *
X168,170c180
X< wn->wn_drive = device/DEV_PER_DRIVE; /* save drive number */
X< if (wn->wn_drive >= nr_drives)
X< return(EIO);
X---
X>
X267c277
X< command[1] = (wn->wn_head | (wn->wn_drive << 5));
X---
X> command[1] = wn->wn_head | wn->wn_drive;
X271c281,282
X< command[5] = CTRL_BYTE;
X---
X> command[5] = wn->wn_ctrl_byte;
X>
X277c288
X< receive(HARDWARE, &w_mess);
X---
X> w_wait_int();
X303,306c314,317
X< if (!(status & 2))
X< return(OK);
X< command[0] = WIN_SENSE;
X< command[1] = (wn->wn_drive << 5);
X---
X> if (!(status & 2)) /* Test "error" bit */
X> return(OK);
X> command[0] = WIN_SENSE;
X> command[1] = wn->wn_drive;
X312c323
X< if (hd_wait(1) != OK)
X---
X> if (hd_wait(WST_REQ) != OK)
X317,319c328,338
X< if (wn->wn_results[0] & 63)
X< return(ERR);
X< else
X---
X> if(hd_wait(WST_REQ) != OK) /* Missing from */
X> return (ERR); /* Original. 11-Apr-87 G.O. */
X>
X> port_in(WIN_DATA, &status); /* Read "error" flag */
X>
X> if(((status & 2) != 0) || (wn->wn_results[0] & 0x3F)) {
X> #if DEBUG
X> printf("\nwin_results: results[0] = %x", wn->wn_results[0]);
X> #endif /* DEBUG */
X> return(ERR);
X> } else
X334,336c353,360
X<
X< if (w_need_reset) return; /* if controller is not listening, return */
X< if (hd_wait(1) == OK)
X---
X> int r;
X>
X> if (w_need_reset) return; /* if controller is not listening, return */
X>
X> do {
X> port_in(WIN_STATUS, &r);
X> } while((r & (WST_REQ | WST_BUSY)) == WST_BUSY);
X>
X349,358c373,393
X< int r = 1, i;
X<
X< /* Strobe reset bit low. */
X< port_out(WIN_STATUS, r);
X< for (i = 0; i < 10000; i++) {
X< port_in(WIN_STATUS, &r);
X< if ( (r&01) == 0)break;
X< }
X< if (r & 2) {
X< printf("Hard disk won't reset\n");
X---
X> int r = 0, i;
X>
X> /* Strobe reset bit low. */
X> port_out(WIN_STATUS, 0);
X>
X> for(i = MAX_WIN_RETRY/10; i; --i)
X> ; /* Spin loop for a while */
X>
X> port_out(WIN_SELECT, 0); /* Issue select pulse */
X> for (i = 0; i < MAX_WIN_RETRY; i++) {
X> port_in(WIN_STATUS, &r);
X> if(r & 0x30) /* What is 10? 20 = INTERRUPT */
X> return (ERR);
X>
X> if((r & (WST_BUSY | WST_BUS | WST_REQ)) ==
X> (WST_BUSY | WST_BUS | WST_REQ))
X> break;
X> }
X>
X> if (i == MAX_WIN_RETRY) {
X> printf("Hard disk won't reset, status = %x\n", r);
X365,414c400,479
X< return(win_init());
X< }
X<
X< /*===========================================================================*
X< * win_init *
X< *===========================================================================*/
X< PRIVATE win_init()
X< {
X< /* Routine to initialize the drive parameters after boot or reset */
X<
X< register int i;
X<
X< command[0] = WIN_SPECIFY; /* Specify some parameters */
X< command[1] = 0; /* Drive 0 */
X< if (com_out(NO_DMA_INT) != OK) /* Output command block */
X< return(ERR);
X< lock();
X<
X< /* No. of cylinders (high byte) */
X< win_out(param0.nr_cyl >> 8);
X<
X< /* No. of cylinders (low byte) */
X< win_out(param0.nr_cyl & 0xFF);
X<
X< /* No. of heads */
X< win_out(param0.nr_heads);
X<
X< /* Start reduced write (high byte) */
X< win_out(param0.reduced_wr >> 8);
X<
X< /* Start reduced write (low byte) */
X< win_out(param0.reduced_wr & 0xFF);
X<
X< /* Start write precompensation (high byte) */
X< win_out(param0.wr_precomp >> 8);
X<
X< /* Start write precompensation (low byte) */
X< win_out(param0.wr_precomp & 0xFF);
X<
X< /* Ecc burst length */
X< win_out(param0.max_ecc);
X< unlock();
X<
X< if (check_init() != OK) { /* See if controller accepted parameters */
X< w_need_reset = TRUE;
X< return(ERR);
X< }
X<
X< if (nr_drives > 1) {
X< command[1] = (1 << 5); /* Drive 1 */
X---
X> if(win_specify(0, ¶m0) != OK)
X> return (ERR);
X>
X> #if DEBUG
X> printf("\nw_reset: drive 0 specified");
X> #endif /* DEBUG */
X>
X> if ((nr_drives > 1) && (win_specify(1, ¶m1) != OK))
X> return(ERR);
X>
X> #if DEBUG
X> printf("\nw_reset: drive 1 specified");
X> #endif /* DEBUG */
X>
X> for (i=0; i<nr_drives; i++) {
X> command[0] = WIN_RECALIBRATE;
X> command[1] = i << 5;
X> command[5] = wini[i * DEV_PER_DRIVE].wn_ctrl_byte;
X>
X> #if DEBUG
X> printf("\nw_reset: recal %d, ctrl_byte = %x", i, command[5]);
X> #endif /* DEBUG */
X>
X> if (com_out(INT) != OK)
X> return(ERR);
X>
X> w_wait_int();
X>
X> if (win_results(&wini[i * DEV_PER_DRIVE]) != OK) {
X> w_need_reset = TRUE;
X> #if DEBUG
X> printf("\nw_reset: Recal error");
X> #endif /* DEBUG */
X> return(ERR);
X> }
X> }
X> return(OK);
X> }
X>
X>
X> /*===========================================================================*
X> * w_wait_int *
X> *===========================================================================*/
X> PRIVATE w_wait_int()
X> {
X> /*DEBUG: loop looking for 0x20 in status (I don't know what that is!!) */
X> /* 10-Apr-87. G. Oliver */
X> int r, i; /* Some local storage */
X>
X> receive(HARDWARE, &w_mess);
X>
X> port_out(DMA_INIT, 0x07); /* Disable int from DMA */
X>
X> for(i=0; i<MAX_WIN_RETRY; ++i) {
X> port_in(WIN_STATUS, &r);
X> if(r & WST_INTERRUPT)
X> break; /* Exit if end of int */
X> }
X>
X> #if MONITOR
X> if(i > 10) { /* Some arbitrary limit below which we don't really care */
X> if(i == MAX_WIN_RETRY)
X> printf("wini: timeout waiting for INTERRUPT status\n");
X> else
X> printf("wini: %d loops waiting for INTERRUPT status\n", i);
X> }
X> #endif /* MONITOR */
X> }
X>
X>
X> /*============================================================================*
X> * win_specify *
X> *============================================================================*/
X> PRIVATE win_specify(drive, paramp)
X> int drive;
X> struct param *paramp;
X> {
X> command[0] = WIN_SPECIFY; /* Specify some parameters */
X> command[1] = drive << 5; /* Drive number */
X>
X420,442c485,508
X< win_out(param1.nr_cyl >> 8);
X<
X< /* No. of cylinders (low byte) */
X< win_out(param1.nr_cyl & 0xFF);
X<
X< /* No. of heads */
X< win_out(param1.nr_heads);
X<
X< /* Start reduced write (high byte) */
X< win_out(param1.reduced_wr >> 8);
X<
X< /* Start reduced write (low byte) */
X< win_out(param1.reduced_wr & 0xFF);
X<
X< /* Start write precompensation (high byte) */
X< win_out(param1.wr_precomp >> 8);
X<
X< /* Start write precompensation (low byte) */
X< win_out(param1.wr_precomp & 0xFF);
X<
X< /* Ecc burst length */
X< win_out(param1.max_ecc);
X< unlock();
X---
X> win_out(paramp->nr_cyl >> 8);
X>
X> /* No. of cylinders (low byte) */
X> win_out(paramp->nr_cyl);
X>
X> /* No. of heads */
X> win_out(paramp->nr_heads);
X>
X> /* Start reduced write (high byte) */
X> win_out(paramp->reduced_wr >> 8);
X>
X> /* Start reduced write (low byte) */
X> win_out(paramp->reduced_wr);
X>
X> /* Start write precompensation (high byte) */
X> win_out(paramp->wr_precomp >> 8);
X>
X> /* Start write precompensation (low byte) */
X> win_out(paramp->wr_precomp);
X>
X> /* Ecc burst length */
X> win_out(paramp->max_ecc);
X> unlock();
X>
X447,459c513
X< }
X< for (i=0; i<nr_drives; i++) {
X< command[0] = WIN_RECALIBRATE;
X< command[1] = i << 5;
X< command[5] = CTRL_BYTE;
X< if (com_out(INT) != OK)
X< return(ERR);
X< receive(HARDWARE, &w_mess);
X< if (win_results() != OK) {
X< w_need_reset = TRUE;
X< return(ERR);
X< }
X< }
X---
X> else
X469,476c523,546
X< int r;
X<
X< if (hd_wait(2) == OK) {
X< port_in(WIN_DATA, &r);
X< if (r & 2)
X< return(ERR);
X< else
X< return(OK);
X---
X> int r, s;
X>
X> if (hd_wait(WST_REQ | WST_INPUT) == OK) {
X> port_in(WIN_DATA, &r);
X>
X> do {
X> port_in(WIN_STATUS, &s);
X> } while(s & WST_BUSY); /* Loop while still busy */
X>
X> if (r & 2) /* Test error bit */
X> {
X> #if DEBUG
X> printf("\ncheck_init: error bit set in %x", r);
X> #endif /* DEBUG */
X> return(ERR);
X> }
X> else
X> return(OK);
X> } else
X> {
X> #if DEBUG
X> printf("\ncheck_init: INPUT not active");
X> #endif /* DEBUG */
X> return (ERR); /* Missing from original: 11-Apr-87 G.O. */
X490,492c560,562
X< if (com_out(NO_DMA_INT) == OK && hd_wait(1) == OK) {
X< port_in(WIN_DATA, &r);
X< if (hd_wait(1) == OK) {
X---
X> if (com_out(NO_DMA_INT) == OK && hd_wait(WST_REQ) == OK) {
X> port_in(WIN_DATA, &r);
X> if (hd_wait(WST_REQ) == OK) {
X504,505c574,575
X< PRIVATE hd_wait(bit)
X< register int bit;
X---
X> PRIVATE hd_wait(bits)
X> register int bits;
X514,515c584,585
X< r &= bit;
X< } while ((i++ < MAX_WIN_RETRY) && !r);
X---
X> r &= bits;
X> } while ((i++ < MAX_WIN_RETRY) && r != bits); /* Wait for ALL bits */
X518a589,591
X> #if DEBUG
X> printf("\nhd_wait: timeout waiting for %x (%x)", bits, r);
X> #endif /* DEBUG */
X532,554c605,648
X< register int i = 0;
X< int r;
X<
X< port_out(WIN_SELECT, mode);
X< port_out(WIN_DMA, mode);
X< for (i=0; i<MAX_WIN_RETRY; i++) {
X< port_in(WIN_STATUS, &r);
X< if ((r & 0x0F) == 0x0D)
X< break;
X< }
X< if (i == MAX_WIN_RETRY) {
X< w_need_reset = TRUE;
X< return(ERR);
X< }
X< lock();
X< for (i=0; i<6; i++)
X< port_out(WIN_DATA, command[i]);
X< unlock();
X< port_in(WIN_STATUS, &r);
X< if (r & 1) {
X< w_need_reset = TRUE;
X< return(ERR);
X< } else
X---
X> register int i;
X> int r;
X>
X> port_out(WIN_DMA, mode);
X> port_out(WIN_SELECT, mode);
X> for (i=0; i<MAX_WIN_RETRY; i++) {
X> port_in(WIN_STATUS, &r);
X> if (r & WST_BUSY)
X> break;
X> }
X>
X> if (i == MAX_WIN_RETRY) {
X> w_need_reset = TRUE;
X> #if DEBUG
X> printf("\ncom_out: retry exceeded, status = %x", r);
X> #endif /* DEBUG */
X> return(ERR);
X> }
X>
X>
X> lock();
X>
X> for (i=0; i<6; i++) {
X> if(hd_wait(WST_REQ) != OK)
X> break; /* No data request pending */
X>
X> port_in(WIN_STATUS, &r);
X>
X> if((r & (WST_BUSY | WST_BUS | WST_INPUT)) !=
X> (WST_BUSY | WST_BUS))
X> break;
X>
X> port_out(WIN_DATA, command[i]);
X> }
X>
X> unlock();
X>
X> if(i != 6) {
X> #if DEBUG
X> printf("\ncom_out: packet write aborted, status=%x", r);
X> #endif /* DEBUG */
X> return(ERR);
X> }
X> else
X576,577c670,671
X< type_0 = (i >> 2) & 3;
X< type_1 = i & 3;
X---
X> type_0 = i & 3;
X> type_1 = (i >> 2) & 3;
X584c678
X< address = ((long)segment << 4) + offset;
X---
X> address = ((phys_bytes)segment << 4) + offset;
X588,591c682,685
X< copy_param((&buf[type_0 * 16]), ¶m0);
X< copy_param((&buf[type_1 * 16]), ¶m1);
X<
X< /* Get the nummer of drives from the bios */
X---
X> copy_params(&buf[type_0 * 16], ¶m0);
X> copy_params(&buf[type_1 * 16], ¶m1);
X>
X> /* Get the number of drives from the bios */
X596,602c690,705
X< for (i=0; i<5; i++)
X< wini[i].wn_heads = param0.nr_heads;
X< wini[0].wn_low = wini[5].wn_low = 0L;
X< wini[0].wn_size = (long)((long)param0.nr_cyl * (long)param0.nr_heads * (long)NR_SECTORS);
X< for (i=5; i<10; i++)
X< wini[i].wn_heads = param1.nr_heads;
X< wini[5].wn_size = (long)((long)param1.nr_cyl * (long)param1.nr_heads * (long)NR_SECTORS);
X---
X> for (i = 0; i < DEV_PER_DRIVE; i++) {
X> wini[i].wn_heads = param0.nr_heads;
X> wini[i].wn_ctrl_byte = param0.ctrl_byte;
X> wini[i].wn_drive = 0 << 5; /* Set drive number */
X> }
X>
X> wini[0].wn_low = wini[DEV_PER_DRIVE].wn_low = 0L;
X> wini[0].wn_size = (long)((long)param0.nr_cyl * (long)param0.nr_heads * (long)NR_SECTORS);
X>
X> for (i = DEV_PER_DRIVE; i < (2*DEV_PER_DRIVE); i++) {
X> wini[i].wn_heads = param1.nr_heads;
X> wini[i].wn_ctrl_byte = param1.ctrl_byte;
X> wini[i].wn_drive = 1 << 5; /* Set drive number */
X> }
X> wini[DEV_PER_DRIVE].wn_size =
X> (long)((long)param1.nr_cyl * (long)param1.nr_heads * (long)NR_SECTORS);
X606c709
X< if ((nr_drives > 0) && (win_init() != OK))
X---
X> if ((nr_drives > 0) && (w_reset() != OK))
X611c714
X< w_mess.DEVICE = i * 5;
X---
X> w_mess.DEVICE = i * DEV_PER_DRIVE;
X619c722,725
X< copy_prt(i * 5);
X---
X> copy_prt(i * DEV_PER_DRIVE);
X> #if DEBUG
X> printf("\ninit_params: drive %d processed", i);
X> #endif /* DEBUG */
X631c737
X< * and sets the parameters for partition 0 and 5
X---
X> * and sets the parameters for partition 0 and DEV_PER_DRIVE
X638a745
X> dest->ctrl_byte = (int)src[8];
X691a799,816
X>
X> #if DEBUG
X> #undef port_out
X> /* Write values written to ports with debugging version of port_out */
X> xport_out(port, val)
X> int port, val;
X> {
X> static int __ctr = 0;
X>
X> printf(" (%x)=%x", port, val);
X> if(++__ctr > 4)
X> {
X> printf("\n");
X> __ctr = 0;
X> }
X> port_out(port, val);
X> }
X> #endif /* DEBUG */
+ END-OF-FILE kernel/xt_wini.dif
chmod u=rw,g=r,o=r kernel/xt_wini.dif
set `sum kernel/xt_wini.dif`
sum=$1
case $sum in
40760) :;;
*) echo 'Bad sum in 'kernel/xt_wini.dif >&2
esac
exit 0