diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DEV/XMA2EMS/GENIOCTL.INC | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/DEV/XMA2EMS/GENIOCTL.INC')
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/GENIOCTL.INC | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/v4.0/src/DEV/XMA2EMS/GENIOCTL.INC b/v4.0/src/DEV/XMA2EMS/GENIOCTL.INC new file mode 100644 index 0000000..1580fce --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/GENIOCTL.INC | |||
| @@ -0,0 +1,167 @@ | |||
| 1 | |||
| 2 | GENERIC_IOCTL_P PROC | ||
| 3 | ;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ | ||
| 4 | ;³ This routine handles the Generic IOCTL call. The EMS device driver ³ | ||
| 5 | ;³ provides an interface through the Generic IOCTL call to allocate pages ³ | ||
| 6 | ;³ for the Workstation Program. Since WSP needs memory off the 'bottom' of ³ | ||
| 7 | ;³ the XMA card in order to bank switch memory, an IOCTL call is needed to ³ | ||
| 8 | ;³ mark these pages as allocated in the Page Allocation Table. ³ | ||
| 9 | ;³ ³ | ||
| 10 | ;³ The pages for EMS are taken from the linked Page Allocation List. ³ | ||
| 11 | ;³ The PAL is initialized from top down, meaning pages that correspond to ³ | ||
| 12 | ;³ the highest physical addresses on the card are at the beginning of the ³ | ||
| 13 | ;³ free list. Therefore, WSP needs to get the pages from the end of the ³ | ||
| 14 | ;³ free list. ³ | ||
| 15 | ;³ ³ | ||
| 16 | ;³ Programs may load before WSP and allocate and deallocate pages. ³ | ||
| 17 | ;³ This will work fine for WSP, since these pages will come from the 'top' ³ | ||
| 18 | ;³ using the standard function 43 allocate call. It will even work if ³ | ||
| 19 | ;³ an application allocates these bottom pages and then deallocates to ³ | ||
| 20 | ;³ the EMS pool, since the deallocated pages are returned to the top of ³ | ||
| 21 | ;³ the free list and linked in reverse order. The allocates and deallocates ³ | ||
| 22 | ;³ must, however, occur in a stack (LIFO) order or problems will arise. ³ | ||
| 23 | ;³ For example, suppose the system has 30 EMS pages. Handle A allocs ³ | ||
| 24 | ;³ 20 pages that come from the 'top' of the memory card. Handle B then ³ | ||
| 25 | ;³ allocs the bottom 10. Handle A goes counter to LIFO order and deallocs ³ | ||
| 26 | ;³ its 20. WSP then issues this generic IOCTL call asking for 20 pages. ³ | ||
| 27 | ;³ The pages are available, but they are not from the bottom physical ³ | ||
| 28 | ;³ blocks on the card. For this we return error code '91'x (see below). ³ | ||
| 29 | ;³ ³ | ||
| 30 | ;³ The call from WSP's loader will be function 0. No other functions are ³ | ||
| 31 | ;³ supported at this time. If an error is encountered, the return code ³ | ||
| 32 | ;³ is set in the request packet, but not the device driver header. The ³ | ||
| 33 | ;³ header error is set by previous versions of the EMS driver that didn't ³ | ||
| 34 | ;³ handle the IOCTL. ³ | ||
| 35 | ;³ ³ | ||
| 36 | ;ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ | ||
| 37 | ;³ On entry: ES:BX -> Device driver request header ³ | ||
| 38 | ;³ ³ | ||
| 39 | ;³ The IOCTL code will set standard EMS return codes in the packet's function ³ | ||
| 40 | ;³ field on exit. These include: ³ | ||
| 41 | ;³ '00'x - Good - Requested pages reserved for WSP ³ | ||
| 42 | ;³ '80'x - Software malfunction in EMS software ³ | ||
| 43 | ;³ '84'x - Function code passed is not defined ³ | ||
| 44 | ;³ '87'x - Insufficient total pages to satisfy request ³ | ||
| 45 | ;³ '88'x - Insufficient free pages to satisfy request ³ | ||
| 46 | ;³ '89'x - 0 pages requested ³ | ||
| 47 | ;³ '90'x - Parameter list has an invalid length (Not an EMS return code) ³ | ||
| 48 | ;³ '91'x - Allocated pages do not correspond to ³ | ||
| 49 | ;³ the 'bottom' blocks of XMA memory (Not an EMS return code) ³ | ||
| 50 | ;³ ³ | ||
| 51 | ;ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; | ||
| 52 | |||
| 53 | GIP EQU ES:[DI] ;Pointer to the Generic IOCTL packet @RH6 | ||
| 54 | |||
| 55 | GEN_IOCTL_PARM STRUC ; @RH6 | ||
| 56 | GIO_PLEN DW ? ; Length of the parameter list @RH6 | ||
| 57 | GIO_FCNRC DW ? ; Function code on call, ret code on ret | ||
| 58 | GIO_WSPP DW ? ; Number of pages to reserve for WSP @RH6 | ||
| 59 | GEN_IOCTL_PARM ENDS ; | ||
| 60 | |||
| 61 | GENERIC_IOCTL: ; @RH6 | ||
| 62 | PUSH ES ;Save pointer to the request header | ||
| 63 | PUSH BX | ||
| 64 | LES DI,RH.RH19_RQPK ;Point ES:DI to the Generic IOCTL @RH6 | ||
| 65 | ; request packet @RH6 | ||
| 66 | PUSH CS ;Set addressability to our data @RH6 | ||
| 67 | POP DS ; @RH6 | ||
| 68 | XOR AH,AH ;Init upper half of user's ret code @RH6 | ||
| 69 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 70 | ;³ First insure the parameter list is long enough ³ | ||
| 71 | ;³ to input the number of pages needed by WSP ³ | ||
| 72 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 73 | CMP GIP.GIO_PLEN,4 ;If the length is 4 bytes then OK @RH6 | ||
| 74 | JE GIO_FCN_CHK ;Else give invalid len ret code @RH6 | ||
| 75 | MOV AL,90h ; and error exit @RH6 | ||
| 76 | JMP GIP_EXIT ; @RH6 | ||
| 77 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 78 | ;³ Check for function code 0 (only one available) ³ | ||
| 79 | GIO_FCN_CHK: ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 80 | CMP GIP.GIO_FCNRC,0 ; @RH6 | ||
| 81 | JE GIO_REQNOT0_CHK ; @RH6 | ||
| 82 | MOV AL,EMS_CODE84 ; @RH6 | ||
| 83 | JMP GIP_EXIT ; @RH6 | ||
| 84 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 85 | ;³ Parm list is OK. Attempt to reserve WSP pages. ³ | ||
| 86 | GIO_REQNOT0_CHK: ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 87 | MOV BX,GIP.GIO_WSPP ;BX = requested WSP pages @RH6 | ||
| 88 | CMP BX,0 ;Check that request was not 0 @RH6 | ||
| 89 | JNE GIO_NOT0 ; @RH6 | ||
| 90 | MOV AL,EMS_CODE89 ; @RH6 | ||
| 91 | JMP GIP_EXIT ; @RH6 | ||
| 92 | |||
| 93 | GIO_NOT0: ; @RH6 | ||
| 94 | CMP BX,TOTAL_EMS_PAGES ;Check for enough total pages @RH6 | ||
| 95 | JNA GIO_OKTOTAL ; @RH6 | ||
| 96 | MOV AL,EMS_CODE87 ; @RH6 | ||
| 97 | JMP GIP_EXIT ; @RH6 | ||
| 98 | |||
| 99 | ;Note: section is not reentrant. It is possible RH8 | ||
| 100 | ; that between the time FREE_PAGES is loaded and RH8 | ||
| 101 | ; then changed, an EMS allocate or deallocate RH8 | ||
| 102 | ; could occur and hose this up. However, since RH8 | ||
| 103 | ; WSP is loading at this point, it is unlikely. RH8 | ||
| 104 | GIO_OKTOTAL: | ||
| 105 | CLI ;Don't allow other alloc or deall @RH8 | ||
| 106 | CMP BX,FREE_PAGES ;Check for enough free pages @RH6 | ||
| 107 | JNA GIO_REMOVE_FREE ; If not enough pages free then @RH6 | ||
| 108 | MOV AX,FREE_PAGES ; return number of free in parm @RH6 | ||
| 109 | STI ; list and set ret code @RH8 | ||
| 110 | MOV GIP.GIO_WSPP,AX ; @RH6 | ||
| 111 | MOV AL,EMS_CODE88 ; @RH6 | ||
| 112 | JMP GIP_EXIT ; @RH6 | ||
| 113 | |||
| 114 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 115 | ;³ Remove WSP pages from the end of the free list ³ | ||
| 116 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 117 | GIO_REMOVE_FREE: | ||
| 118 | SUB FREE_PAGES,BX | ||
| 119 | MOV CX,FREE_PAGES | ||
| 120 | MOV SI,PAL_FREE_PTR | ||
| 121 | STI | ||
| 122 | SHL SI,1 | ||
| 123 | |||
| 124 | CMP CX,0 ;WSP LEAVE NOTHING FREE? | ||
| 125 | JNE GIO_GET_LAST_FREE ;YES SET FREE PTR TO NULL | ||
| 126 | MOV PAL_FREE_PTR,PAL_NULL | ||
| 127 | JMP SHORT GIO_MARK_WSP | ||
| 128 | |||
| 129 | |||
| 130 | GIO_GET_LAST_FREE: | ||
| 131 | DEC CX | ||
| 132 | CMP CX,0 | ||
| 133 | JE GIO_GOT_LAST_FREE | ||
| 134 | GIO_LAST_FREE_LOOP: | ||
| 135 | MOV SI,PAGE_LIST_ENTRY ;BASED OFF SI | ||
| 136 | SHL SI,1 | ||
| 137 | LOOP GIO_LAST_FREE_LOOP | ||
| 138 | |||
| 139 | |||
| 140 | GIO_GOT_LAST_FREE: | ||
| 141 | MOV AX,PAGE_LIST_ENTRY ;STORE OFFSET FOR 1ST WSP | ||
| 142 | MOV PAGE_LIST_ENTRY,PAL_NULL ;THEN MAKE IT END OF FREE LIST | ||
| 143 | MOV SI,AX ;RESTORE 1ST WSP (TOP) | ||
| 144 | SHL SI,1 | ||
| 145 | |||
| 146 | GIO_MARK_WSP: | ||
| 147 | MOV CX,BX ;LOOPR FOR WSP PAGES | ||
| 148 | GIO_WSP_LOOP: | ||
| 149 | MOV AX,PAGE_LIST_ENTRY ;STORE INDEX OF NEXT | ||
| 150 | MOV PAGE_LIST_ENTRY,WSP_ALLOC ;MARK AS WSP | ||
| 151 | MOV SI,AX ;RESTOER INEX OF NEXT | ||
| 152 | SHL SI,1 | ||
| 153 | LOOP GIO_WSP_LOOP | ||
| 154 | |||
| 155 | XOR AX,AX ;Set good return code | ||
| 156 | |||
| 157 | GIP_EXIT: ;GGA | ||
| 158 | |||
| 159 | MOV GIP.GIO_FCNRC,AX ;Store ret code in user's req packet | ||
| 160 | POP BX ;Restore for ptr to request header @RH6 | ||
| 161 | POP ES ; @RH6 | ||
| 162 | MOV RH.RHC_STA,STAT_DONE ; Store done status and good return@RH6 | ||
| 163 | ; code into request header @RH6 | ||
| 164 | RET | ||
| 165 | GENERIC_IOCTL_P ENDP | ||
| 166 | |||
| 167 | \ No newline at end of file | ||