home *** CD-ROM | disk | FTP | other *** search
- ; **************
- ; * SLICER.asm *
- ; *******************************************
- ; * Copyright TimeSlice, Inc. 1985, 86, 87. *
- ; *******************************************
- ;
- .8087 ;enable fpc code
- ;
- include ts.inc
- ;
- start_data
- ;
- _fsw dw 0FFFFh ;used to check if fpc is there
-
- extern_data _tsfpc,word ;FPC presence flag
- extern_data _tckrst,word ;timer tick reset counter
- extern_data _tckcnt,word ;timer tick counter
- extern_data _ts_trace,word ;trace Slicer
-
- extern_ptr _idleproc,d ;pointer to TSIDLE, runs when all other task are blocked
- extern_ptr _DosFlag,d ;Is DOS interrupted
- extern_data _idle,word ;current level of critstar/critend nesting
- extern_data _i13Flag,word ;FileIO interrupted
- ;
- end_data
- ;
- extern_code ts_main ;to force ts_main to be present, or give error.
- extern_code prout ;to trace curproc
- extern_code critstart ;to handle critical task
- extern_code critend ;to handle critical task
- ;
- start_code
- ;
- ;*******
- ;* INITFPC( PTR )
- ;* Initialize the area pointed by PTR with current 87 regs.
- ;*******
- ;
- start_struct
- mbr inFPCbp d_int
- mbr inFPCret d_ret
- mbr inFPCptr d_ptr
- ;
- routine initfpc
- push bp
- mov bp,sp
- push_sdi
- ldptr es,di,[bp].inFPCptr
- fnsave es:[di]
- pop_sdi
- pop bp
- return initfpc
- ;
- ;*******
- ;* SLICER()
- ;* Slicer() is responsible for the context switching which occurs whenever
- ;* the current process has expired its time slice. (A time slice is defined
- ;* as the number of time quantum units assigned to that process.)
- ;* It saves the current proc's registers (except for the SS and SP) using
- ;* a PUSHA instruction. The SS and SP are then copied in the process's PCB.
- ;* The next ready-to-run process's state is then restored by first
- ;* activating that process' SS and SP and then executing a POPA instruction
- ;* which then restores all other registers.
- ;* A jump to the original timer service routine is done so that nothing is
- ;* disturbed.
- ;*******
- public slicer
- public __gus
- public __jaddr
- ;
- slicer proc far
- __gus proc far
- pusha ;push all registers
- mov ax,dgroup ;activate local data segment
- mov ds,ax
- mov ah,_volguc ;voluntary give up control???
- test ah,ah
- jnz cntxsw ;yes, always context switch
- mov ax,_sslev ;slicer asleep???
- test ax,ax
- jz s2
- jmp slxit ;yes, skip context switching
- s2: dec _timcnt ;check if switch context needed
- jz cntxsw
- jmp slxit ;No context swich needed
-
- cntxsw: ldptr es,di,curproc,d ;set ES:DI to *curproc
- mov ax,es:[di].status
-
- mov _idle,di ;mark offset of the interrupted task
-
- test ax,DOSCRIT ;was this a Critical Task
- jz FPCtst
-
- ldptr es,di,_DosFlag,d ;Interrupt TASK in DOS ??
- mov bx, es:[di] ;
- or bx, _i13Flag ;or in Disk service ??
- cmp bl, 0 ;
- jz noDOS ;No, do context switch freely
-
- test ax, INDOS ;DOS already critical
- jnz iDOS
-
- sub ax, ax ;DOS is interrupted,
- push ax ;so do a late critstart for DOS
- call critstart
- pop ax
-
- iDOS: ldptr es,di,curproc,d ;set ES:DI to *curproc
- mov ax,es:[di].status ;hold this special case in status
- or ax, INDOS ;say we are in DOS
- mov es:[di].status, ax
- jmp FPCtst
-
- noDOS: ldptr es,di,curproc,d ;set ES:DI to *curproc
- mov ax,es:[di].status
- test ax, INDOS ;Last slice left in DOS ?
- jz FPCtst
- xor ax, INDOS ;clear the in DOS status
- mov es:[di].status, ax
-
- xor ax,ax
- push ax
- call critend
- pop ax
-
- ldptr es,di,curproc,d ;set ES:DI to *curproc
- mov ax,es:[di].status
-
- FPCtst: test ax,SAVEFPC ;save fpc context???
- jz noFPCsv
- fnsave es:[di].regsFPC ;save iAPXFPC registers
- noFPCsv:mov ax,ss ;save current process stack seg
- mov es:[di].pss,ax
- mov ax,sp ;" " " stack pointer
- mov es:[di].psp,ax
- s3: mov ax,es:[di].nxt.off ;load curproc with curproc->nxt
- if ldata
- mov bx,es:[di].nxt.sgt
- mov curproc.sgt,bx
- mov es,bx
- endif
- ifndef stkset
- mov bx,ax ;bx will compute stk_base
- add bx,process
- endif
- mov curproc.off,ax
- mov di,ax ;set ES:DI to *curproc
- mov ax,es:[di].status ;process blocked??
-
- test ax,BLOCKED
- jz rstFPC ;Not blocked, restore FPC
-
- mov ax,[_idle]
- cmp ax,di ;Process is blocked
- jnz s3 ;if this is the process last running
- ; then we have some idle time
- ldptr es,di,_idleproc,d ;
- if ldata
- mov bx,es
- mov curproc.sgt,bx
- endif
- ifndef stkset
- mov bx,di ;bx will compute stk_base
- add bx,process
- endif
- mov curproc.off,di
- mov ax,es:[di].status ;process status
-
- rstFPC: test ax,SAVEFPC ;now test process->status for 87 processing
- jz noFPCrs
- frstor es:[di].regsFPC ;yes, restore fpc registers
- ifndef stkset
- add bx,94 ;add 94 byte for FPC save area to stack base
- endif
- noFPCrs:
- ifndef stkset
- mov stk_base, bx ;update stack overflow marker
- endif
- mov ax,es:[di].pss ;no,load ss & sp w/new curproc values
- mov ss,ax
- mov ax,es:[di].psp
- mov sp,ax
-
- mov ax, _ts_trace ;Trace slicer ?
- cmp ax, 0
- je notrac
-
- push es
- push di
-
- mov ax,es:[di].pname.sgt ;
- push ax
- mov ax,es:[di].pname.off ;
- push ax
- mov ax, 7
- push ax
- sub ax, ax
- push ax ;prout(0,0,NORMVID, curproc->pname)
- push ax
- call prout
- add sp, 10
-
- pop di
- pop es
-
- notrac: mov ax,es:[di].tunits ;reload _timcnt
- mov bh,_volguc ;load voluntary give-up-control flag
- test bh,bh ;last process did guc() ???
- je s4 ;no
- inc ax ;yes, add one time unit to curproc
- xor bh,bh ;reset _volguc
- mov _volguc,bh ;clear volguc...
- mov _timcnt,ax
-
- popa ;restore all registers...
- iret ;exec nxt process
- ;
- s4: mov _timcnt,ax ;set number of time units for curproc
- ;
- ; Take care of timer ticks counter, and exiting from the slicer
- ; when a regular timer interrupt occurred
- ;
- slxit: dec _tckcnt ;regular timer tick???
- jnz s5 ;no: special accelerated tick
- mov ax,_tckrst ;yes: reset tick counter to reset value
- mov _tckcnt,ax
- popa ;restore all registers
- ;
- db JMPFAR ;jump to original timer interrupt routine
- __jaddr:dw 0
- dw 0
- ;
- ; Take care of special accelerated timer tick
- ;
- s5: mov al,20h ;issue EOI
- out 20h,al
- popa ;restore all registers...
- iret ;exec nxt process
- __gus endp
- slicer endp
- ;
- ;
- ;
- ;*******
- ;* _TS_BOOT()
- ;* 1) Installs the initial PCB at _base, initializes it, and reset _base.
- ;* 2) Copies the 4 byte interupt vector from location 0:_SLINT to CS:JADDR
- ;* prior to installing the slicer.
- ;*******
- start_struct
- mbr bootbp d_int
- mbr bootret d_ret
- mbr bootpp d_ptr
- ;
- routine _ts_boot
- push bp
- mov bp,sp
- push_sdi
- mov ax,ds ;init _datseg
- mov _datseg,ax
- mov ax,ss ;init _stkseg
- mov _stkseg,ax
- mov ax,cs ;init _codseg (small code only)
- mov _codseg,ax
- ;
- ; Check for presence of fpc
- ;
- fninit ;initialize fpc
- fnstsw _fsw ;get its status word
- mov cx,100h ;delay while 87 works on its own
- delay: loop delay
- mov ax,_fsw
- and ax,0B8BFh ;if fpc, these are reset
- jnz noFPC
- inc byte ptr _tsfpc ;mark that fpc is here
- noFPC:
- ;
- ; set initial PCB at STK_BASE
- ;
- ldptr es,ax,[bp].bootpp,d ;base of regular stack
- mov di,ax ;init boot process to itself
- mov es:[di].nxt.off,ax ;point to itself (only proc at start)
- mov ax,es
- mov es:[di].nxt.sgt,ax
- xor ax,ax
- stptrr es:[di].crnxt,ax,ax ;not on critical list
- ldint es:[di].tunits,1
- ldint es:[di].status,READY
- mov curproc.off,di
- if ldata
- mov bx,es
- mov curproc.sgt,bx
- endif
- ;
- ; attach slicer to interrupt # _slint
- ;
- cli ;set timer interrupt to slicer
- mov ax,_slint ;ax <-- interrupt of slicer
- mov cl,2
- shl ax,cl ;ax <-- offset of slicer's IntVector
- mov si,ax ;si <-- slicer's Int Vector
- push ds ;save local data segment
- xor ax,ax ;so that we can address the interrupt
- mov ds,ax ;table located at 0:0
- mov ax,[si] ;ax <-- slicer's Intrpt original offset
- mov bx,offset __jaddr
- mov cx,seg __jaddr
- mov es,cx
- mov es:[bx],ax ;save original routine's offset...
- mov ax,[si+2] ;ax <-- slicer's Intrpt original segment
- add bx,2
- mov es:[bx],ax ;and code segment so that we can jmp to it
- ;
- ;
- mov ax,offset slicer ;install slicer in interrupt table
- mov [si],ax
- mov ax,seg slicer
- mov [si+2],ax
- pop ds ;restore local data segment
- mov ax,ds
- mov es,ax
- sti
- pop_sdi
- pop bp
- return _ts_boot
- ;
- ;
- public _inDos_ptr
- _inDos_ptr proc far
- mov ah, 34h
- int 21h
- mov ax, bx
- mov dx, es
- ret
- _inDos_ptr endp
-
- end_code
-