summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/XMA2EMS/GENIOCTL.INC
blob: 1580fce626ad095b5f2be6a0aa6034a6b7c96a80 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
GENERIC_IOCTL_P PROC
;����������������������������������������������������������������������������͸
;� This routine handles the Generic IOCTL call.  The EMS device driver        �
;� provides an interface through the Generic IOCTL call to allocate pages     �
;� for the Workstation Program.  Since WSP needs memory off the 'bottom' of   �
;� the XMA card in order to bank switch memory, an IOCTL call is needed to    �
;� mark these pages as allocated in the Page Allocation Table.                �
;�                                                                            �
;�    The pages for EMS are taken from the linked Page Allocation List.       �
;� The PAL is initialized from top down, meaning pages that correspond to     �
;� the highest physical addresses on the card are at the beginning of the     �
;� free list.  Therefore, WSP needs to get the pages from the end of the      �
;� free list.                                                                 �
;�                                                                            �
;�    Programs may load before WSP and allocate and deallocate pages.         �
;� This will work fine for WSP, since these pages will come from the 'top'    �
;� using the standard function 43 allocate call.  It will even work if        �
;� an application allocates these bottom pages and then deallocates to        �
;� the EMS pool, since the deallocated pages are returned to the top of       �
;� the free list and linked in reverse order.  The allocates and deallocates  �
;� must, however, occur in a stack (LIFO) order or problems will arise.       �
;� For example, suppose the system has 30 EMS pages.  Handle A allocs         �
;� 20 pages that come from the 'top' of the memory card.  Handle B then       �
;� allocs the bottom 10.  Handle A goes counter to LIFO order and deallocs    �
;� its 20.  WSP then issues this generic IOCTL call asking for 20 pages.      �
;� The pages are available, but they are not from the bottom physical         �
;� blocks on the card.  For this we return error code '91'x (see below).      �
;�                                                                            �
;� The call from WSP's loader will be function 0.  No other functions are     �
;� supported at this time.  If an error is encountered, the return code       �
;� is set in the request packet, but not the device driver header.  The       �
;� header error is set by previous versions of the EMS driver that didn't     �
;� handle the IOCTL.                                                          �
;�                                                                            �
;����������������������������������������������������������������������������Ĵ
;� On entry: ES:BX -> Device driver request header                            �
;�                                                                            �
;� The IOCTL code will set standard EMS return codes in the packet's function �
;� field on exit.  These include:                                             �
;�      '00'x - Good - Requested pages reserved for WSP                       �
;�      '80'x - Software malfunction in EMS software                          �
;�      '84'x - Function code passed is not defined                           �
;�      '87'x - Insufficient total pages to satisfy request                   �
;�      '88'x - Insufficient free pages to satisfy request                    �
;�      '89'x - 0 pages requested                                             �
;�      '90'x - Parameter list has an invalid length (Not an EMS return code) �
;�      '91'x - Allocated pages do not correspond to                          �
;�               the 'bottom' blocks of XMA memory   (Not an EMS return code) �
;�                                                                            �
;����������������������������������������������������������������������������;

GIP     EQU     ES:[DI]               ;Pointer to the Generic IOCTL packet @RH6

GEN_IOCTL_PARM  STRUC                 ;                                    @RH6
GIO_PLEN   DW      ?                  ; Length of the parameter list       @RH6
GIO_FCNRC  DW      ?                  ; Function code on call, ret code on ret
GIO_WSPP   DW      ?                  ; Number of pages to reserve for WSP @RH6
GEN_IOCTL_PARM  ENDS                  ;

GENERIC_IOCTL:                        ;                                    @RH6
        PUSH    ES                    ;Save pointer to the request header
        PUSH    BX
        LES     DI,RH.RH19_RQPK       ;Point ES:DI to the Generic IOCTL    @RH6
                                      ; request packet                     @RH6
        PUSH    CS                    ;Set addressability to our data      @RH6
        POP     DS                    ;                                    @RH6
        XOR     AH,AH                 ;Init upper half of user's ret code  @RH6
                        ;����������������������������������������������������Ŀ
                        ;� First insure the parameter list is long enough     �
                        ;�  to input the number of pages needed by WSP        �
                        ;������������������������������������������������������
        CMP     GIP.GIO_PLEN,4          ;If the length is 4 bytes then OK  @RH6
        JE      GIO_FCN_CHK             ;Else give invalid len ret code    @RH6
        MOV     AL,90h                  ; and error exit                   @RH6
        JMP     GIP_EXIT                ;                                  @RH6
                        ;����������������������������������������������������Ŀ
                        ;� Check for function code 0 (only one available)     �
GIO_FCN_CHK:            ;������������������������������������������������������
        CMP     GIP.GIO_FCNRC,0         ;                                  @RH6
        JE      GIO_REQNOT0_CHK         ;                                  @RH6
        MOV     AL,EMS_CODE84           ;                                  @RH6
        JMP     GIP_EXIT                ;                                  @RH6
                        ;����������������������������������������������������Ŀ
                        ;� Parm list is OK.  Attempt to reserve WSP pages.    �
GIO_REQNOT0_CHK:        ;������������������������������������������������������
        MOV     BX,GIP.GIO_WSPP         ;BX = requested WSP pages          @RH6
        CMP     BX,0                    ;Check that request was not 0      @RH6
        JNE     GIO_NOT0                ;                                  @RH6
        MOV     AL,EMS_CODE89           ;                                  @RH6
        JMP     GIP_EXIT                ;                                  @RH6

GIO_NOT0:                               ;                                  @RH6
        CMP     BX,TOTAL_EMS_PAGES      ;Check for enough total pages      @RH6
        JNA     GIO_OKTOTAL             ;                                  @RH6
        MOV     AL,EMS_CODE87           ;                                  @RH6
        JMP     GIP_EXIT                ;                                  @RH6

                        ;Note: section is not reentrant.  It is possible    RH8
                        ; that between the time FREE_PAGES is loaded and    RH8
                        ; then changed, an EMS allocate or deallocate       RH8
                        ; could occur and hose this up.  However, since     RH8
                        ; WSP is loading at this point, it is unlikely.     RH8
GIO_OKTOTAL:
        CLI                             ;Don't allow other alloc or deall  @RH8
        CMP     BX,FREE_PAGES           ;Check for enough free pages       @RH6
        JNA     GIO_REMOVE_FREE         ; If not enough pages free then    @RH6
        MOV     AX,FREE_PAGES           ;  return number of free in parm   @RH6
        STI                             ;  list and set ret code           @RH8
        MOV     GIP.GIO_WSPP,AX         ;                                  @RH6
        MOV     AL,EMS_CODE88           ;                                  @RH6
        JMP     GIP_EXIT                ;                                  @RH6

                        ;����������������������������������������������������Ŀ
                        ;� Remove WSP pages from the end of the free list     �
                        ;������������������������������������������������������
GIO_REMOVE_FREE:
        SUB     FREE_PAGES,BX
        MOV     CX,FREE_PAGES
        MOV     SI,PAL_FREE_PTR
        STI
        SHL     SI,1

        CMP     CX,0                    ;WSP LEAVE NOTHING FREE?
        JNE     GIO_GET_LAST_FREE       ;YES SET FREE PTR TO NULL
        MOV     PAL_FREE_PTR,PAL_NULL
        JMP     SHORT GIO_MARK_WSP


GIO_GET_LAST_FREE:
        DEC     CX
        CMP     CX,0
        JE      GIO_GOT_LAST_FREE
GIO_LAST_FREE_LOOP:
        MOV     SI,PAGE_LIST_ENTRY      ;BASED OFF SI
        SHL     SI,1
        LOOP    GIO_LAST_FREE_LOOP


GIO_GOT_LAST_FREE:
        MOV     AX,PAGE_LIST_ENTRY      ;STORE OFFSET FOR 1ST WSP
        MOV     PAGE_LIST_ENTRY,PAL_NULL ;THEN MAKE IT END OF FREE LIST
        MOV     SI,AX                   ;RESTORE 1ST WSP (TOP)
        SHL     SI,1

GIO_MARK_WSP:
        MOV     CX,BX                   ;LOOPR FOR WSP PAGES
GIO_WSP_LOOP:
        MOV     AX,PAGE_LIST_ENTRY      ;STORE INDEX OF NEXT
        MOV     PAGE_LIST_ENTRY,WSP_ALLOC ;MARK AS WSP
        MOV     SI,AX                   ;RESTOER INEX OF NEXT
        SHL     SI,1
        LOOP    GIO_WSP_LOOP

        XOR     AX,AX                   ;Set good return code

GIP_EXIT:                                                                                 ;GGA

        MOV     GIP.GIO_FCNRC,AX        ;Store ret code in user's req packet
        POP     BX                      ;Restore for ptr to request header @RH6
        POP     ES                      ;                                  @RH6
        MOV     RH.RHC_STA,STAT_DONE    ; Store done status and good return@RH6
                                        ;   code into request header       @RH6
        RET
GENERIC_IOCTL_P ENDP