home *** CD-ROM | disk | FTP | other *** search
- ;
- ; --- Version 2.2 90-10-12 10:38 ---
- ;
- ; CTask - EMS support
- ;
- ; Public Domain Software written by
- ; Thomas Wagner
- ; Ferrari electronic Gmbh
- ; Beusselstrasse 27
- ; D-1000 Berlin 21
- ; Germany
- ;
- ; This module contains the EMS interface. CTask version 2.1
- ; will save and restore the EMS page map (the LIM 3.2 compatible
- ; 64k standard frame only) on a task switch if EMS support is
- ; installed.
- ;
- ; If the EMS driver supports it, the LIM 4.0 save/restore
- ; partial page map function is used. If this function is not
- ; available, the LIM 3.2 full page map save/restore call is used,
- ; provided that the space in the TCB (EMS_SAVE_SIZE) can hold
- ; the page map information.
- ;
- name tskems
- ;
- include tsk.mac
- ;
- IF DOS AND EMS
- ;
- .tsk_model
- ;
- Pubfunc tsk_install_ems
- ;
- extrn tsk_glob_rec: byte
- ;
- ;
- .tsk_data
- ;
- emm_name db "EMMXXXX0"
- ;
- ems_map dw 4
- dw 4 dup(?)
- ;
- getfunc dw ?
- setfunc dw ?
- ;
- .tsk_edata
- .tsk_code
- ;
- ; tsk_install_ems installs EMS support if an EMS driver is
- ; present, and saving the page map is possible.
- ;
- ; Returns 1 is EMS installed, 0 if no driver, -1 if saving
- ; is impossible.
- ;
- Localfunc tsk_install_ems,<uses si di>
- ;
- IFDEF LOAD_DS
- push ds
- mov ax,@CTASK_DATA
- mov ds,ax
- ENDIF
- xor ax,ax
- mov es,ax
- mov es,word ptr es:[67h*4+2]
- mov di,0ah
- mov si,offset emm_name
- mov cx,8
- repe cmpsb
- je ems_there
- jmp no_ems
- ;
- ; EMS is installed, but the partial map functions failed.
- ; Try the full page map save/restore, which is present in
- ; LIM 3.2.
- ;
- try_32:
- mov ax,4e03h ; get size of full page map save array
- int 67h
- or ah,ah
- jnz bad_ems ; we can't save if this fails
- cmp al,EMS_SAVE_SIZE
- ja bad_ems ; we can't save if array too large
- mov getfunc,4e00h ; get full map
- mov setfunc,4e01h ; set full map
- jmp enter_ok
- ;
- bad_ems:
- mov ax,-1
- jmp inst_ems_end
- ;
- ; EMS is installed, check if we can save a partial page
- ; map in the reserved space, and if the save partial page map
- ; call is implemented at all.
- ;
- ems_there:
- mov ax,4f02h ; get size of partial page map save array
- mov bx,4 ; for the four standard pages
- int 67h
- or ah,ah
- jnz try_32 ; if this call fails, we might have LIM 3.2
- cmp al,EMS_SAVE_SIZE
- ja bad_ems ; we can't save if array too large
- ;
- ; The partial page map call is available, and the space allocated
- ; in the TCB is sufficient. Now we have to build the page table
- ; for the get partial map function.
- ;
- ; Get physical pages
- ;
- mov ax,5801h ; get number of entries
- int 67h
- or ah,ah
- jnz try_32 ; if this call fails, we might have LIM 3.2
- mov al,4
- mul cl ; space required
- sub sp,ax ; make room on stack
- mov di,sp
- push ax ; save size
- mov ax,ss
- mov es,ax
- mov ax,5800h ; get physical page array
- int 67h
- or ah,ah
- jz phys_ok ; if this call fails, we might have LIM 3.2
- pop ax
- add sp,ax
- jmp try_32
- ;
- ; Find the physical page address for the first four pages
- ; (the LIM 3.2 64k frame)
- ;
- phys_ok:
- mov ax,-1
- ;
- first_loop:
- cmp word ptr es:[di+2],ax ; compare logical page number
- ja first_next ; skip if above what we already found
- mov ax,word ptr es:[di+2] ; the new minimum page
- mov bx,di ; save the index
- mov dx,cx ; and the remaining entries
- or ax,ax
- jz first_found
- ;
- first_next:
- add di,4
- loop first_loop
- ;
- ; We found the first logical page. Now copy the physical
- ; page numbers for the first four pages to the array.
- ;
- first_found:
- mov di,offset ems_map
- mov word ptr [di],4 ; four entries
- add di,2
- mov cx,4
- ;
- enter_map:
- mov ax,es:[bx] ; physical page
- mov [di],ax ; store in map array
- add bx,4
- add di,2
- dec cx
- jz enter_rdy
- dec dx
- jnz enter_map
- mov bx,sp ; recycle to start of list
- add bx,2 ; SP+2 since we pushed AX
- jmp enter_map
- ;
- enter_rdy:
- pop ax
- add sp,ax
- mov getfunc,4f00h ; get partial map
- mov setfunc,4f01h ; set partial map
- ;
- ; Enter the functions into the global variable block
- ;
- enter_ok:
- mov word ptr tsk_glob_rec.ems_save,offset @ems_savefn
- mov word ptr tsk_glob_rec.ems_save+2,cs
- mov word ptr tsk_glob_rec.ems_rest,offset @ems_restfn
- mov word ptr tsk_glob_rec.ems_rest+2,cs
- mov word ptr tsk_glob_rec.ems_savetsk,offset @save_ems_tsk
- mov word ptr tsk_glob_rec.ems_savetsk+2,cs
- ;
- mov ax,1
- jmp short inst_ems_end
- ;
- no_ems:
- xor ax,ax
- ;
- inst_ems_end:
- IFDEF LOAD_DS
- pop ds
- ENDIF
- ret
- ;
- tsk_install_ems endp
- ;
- ;
- ; The save and restore routines are called by the scheduler,
- ; and are entered with
- ; DS = CTask data segment
- ; ES:DI = TCB
- ;
- ; ems_savefn - Save EMS context function
- ;
- @ems_savefn proc far
- ;
- push si
- push di
- lea di,t_ems_map[di] ; destination
- mov si,offset ems_map ; not used for full map
- mov ax,getfunc ; get (partial) page map
- int 67h
- pop di
- pop si
- ret
- ;
- @ems_savefn endp
- ;
- ; ems_restfn - Restore EMS context function
- ;
- @ems_restfn proc far
- ;
- mov ax,setfunc ; set (partial) page map
- push ds
- push si
- mov si,es
- mov ds,si
- lea si,t_ems_map[di] ; source
- int 67h
- pop si
- pop ds
- ret
- ;
- @ems_restfn endp
- ;
- ; save_ems_tsk Save current EMS context in the specified task's TCB
- ;
- @save_ems_tsk proc far uses di, task: far ptr
- ;
- IFDEF LOAD_DS
- push ds
- mov ax,@CTASK_DATA
- mov ds,ax
- ENDIF
- les di,task
- call @ems_savefn
- IFDEF LOAD_DS
- pop ds
- ENDIF
- ret
- ;
- @save_ems_tsk endp
- ;
- .tsk_ecode
- ;
- ENDIF
- ;
- end
-
-