168 lines
4 KiB
NASM
168 lines
4 KiB
NASM
;
|
|
; spcemm.asm,
|
|
;
|
|
; 10-Dec-1992 Jonle , adapted from em_drvr.asm from Insignia solutions
|
|
;
|
|
; This code serves as a stub device driver for emm memory manager.
|
|
; Its sole purpose is for apps to be able to identify that an emm driver is
|
|
; loaded and that LIM services are available. This code is linked into the
|
|
; device driver chain contains a strategy, interrupt and device header
|
|
;
|
|
; The driver should only be loaded if emm memory is available
|
|
; from NTVDM.
|
|
;
|
|
|
|
BOP MACRO callid
|
|
db 0c4h, 0c4h, callid
|
|
endm
|
|
|
|
|
|
;
|
|
; Request Header, for initialization
|
|
;
|
|
REQHEAD STRUC
|
|
ReqLen DB ? ; Length in bytes of request block
|
|
ReqUnit DB ? ; Block Device unit number
|
|
ReqFunc DB ? ; Type of request
|
|
ReqStat DW ? ; Status Word
|
|
REQHEAD ENDS
|
|
|
|
;
|
|
; Segment definitions for ntio.sys,
|
|
;
|
|
include biosseg.inc
|
|
include vint.inc
|
|
|
|
SpcEmmSeg segment
|
|
|
|
assume cs:SpcEmmSeg,ds:nothing,es:nothing
|
|
|
|
;
|
|
; SpcEmmBeg - SpcEmmEnd
|
|
;
|
|
; Marks the resident code, anything outside of these markers
|
|
; is discarded after intialization
|
|
; 11-Dec-1992 Jonle
|
|
;
|
|
|
|
public SpcEmmBeg
|
|
|
|
SpcEmmBeg label byte
|
|
|
|
|
|
;
|
|
; character device Header
|
|
; must be first in the .sys file
|
|
;
|
|
dd -1 ;pointer to next device driver
|
|
dw 8000H ;attribute (plain character device)
|
|
dw offset STRATEGY ;pointer to device "strategy" routine
|
|
dw offset Interrupt ;pointer to device "interrupt" routine
|
|
db 'EMMXXXX0' ;8 byte name DO NOT CHANGE THE NAME
|
|
|
|
;
|
|
; Request Header address, saved here by strategy routine
|
|
;
|
|
pReqHdr dd ?
|
|
|
|
|
|
;
|
|
; Device "strategy" entry point, save request header address
|
|
;
|
|
Strategy proc far
|
|
mov word ptr cs:pReqHdr, bx
|
|
mov word ptr cs:pReqHdr+2, es
|
|
ret
|
|
Strategy endp
|
|
|
|
|
|
; EmmIsr - int 67h isr
|
|
;
|
|
EmmIsr: ; LIM Isr
|
|
bop 67h
|
|
emmiret:
|
|
FIRET
|
|
|
|
; ret trap for em function 'alter page map & call'
|
|
EmmRet:
|
|
bop 68h
|
|
jmp emmiret
|
|
|
|
|
|
|
|
;----------------------------------------------------------------------
|
|
; Device "interrupt" entry point
|
|
;----------------------------------------------------------------------
|
|
Interrupt PROC FAR
|
|
|
|
push es
|
|
push di
|
|
|
|
les di, cs:pReqHdr ; check for valid commands
|
|
cmp es:[di.ReqFunc], 0ah
|
|
je validcmd
|
|
cmp es:[di.ReqFunc], 0
|
|
je validcmd
|
|
|
|
mov ax, 8003h ; we don't handle anything else
|
|
jmp short irptexit
|
|
|
|
validcmd:
|
|
xor ax,ax
|
|
|
|
irptexit:
|
|
or ax, 0100h ;tell em we finished
|
|
mov es:[di.ReqStat],AX ;store status in request header
|
|
|
|
pop di
|
|
pop es
|
|
ret
|
|
|
|
Interrupt ENDP
|
|
|
|
public SpcEmmEnd
|
|
SpcEmmEnd label byte
|
|
|
|
public InitSpcEmm
|
|
;
|
|
; InitSpcEmm Initializes Spc 32 bit memory manager
|
|
; returns ax=0 for success
|
|
;
|
|
; Inputs: ds is expected seg for drv code, cs is temporary sysinitseg
|
|
; Outputs: ax zero for success
|
|
;
|
|
InitSpcEmm proc near
|
|
|
|
; BOP 66 - initialize LIM memory
|
|
; pass the address of bop 68 to the em manager
|
|
; in ds:dx and to return the number of em pages in BX
|
|
;
|
|
; NOTE: All EMM options come from pif file
|
|
; There are NO command line options
|
|
xor bx, bx
|
|
mov dx, offset EmmRet
|
|
bop 66h
|
|
cmp bx, 0ffffh ;ffff means incorrect config (eg no 64K gap)
|
|
je fail
|
|
cmp bx, 0 ;check expanded memory is available
|
|
je fail
|
|
|
|
; set up IVT for INT 67h
|
|
FCLI
|
|
xor ax, ax
|
|
mov es, ax
|
|
mov bx, offset EmmIsr
|
|
mov word ptr es:[67h*4], bx
|
|
mov word ptr es:[(67h*4)+2], ds
|
|
FSTI
|
|
|
|
ret
|
|
fail:
|
|
mov ax, 0ffffh
|
|
ret
|
|
|
|
InitSpcEmm endp
|
|
|
|
SpcEmmSeg ends
|
|
end
|