diff options
Diffstat (limited to 'v4.0/src/MEMM/MEMM/EMMINIT.ASM')
| -rw-r--r-- | v4.0/src/MEMM/MEMM/EMMINIT.ASM | 678 |
1 files changed, 678 insertions, 0 deletions
diff --git a/v4.0/src/MEMM/MEMM/EMMINIT.ASM b/v4.0/src/MEMM/MEMM/EMMINIT.ASM new file mode 100644 index 0000000..65527b9 --- /dev/null +++ b/v4.0/src/MEMM/MEMM/EMMINIT.ASM | |||
| @@ -0,0 +1,678 @@ | |||
| 1 | |||
| 2 | |||
| 3 | page 58,132 | ||
| 4 | ;****************************************************************************** | ||
| 5 | title EMMINIT - Expanded Memory Manager initialization | ||
| 6 | ;****************************************************************************** | ||
| 7 | ; | ||
| 8 | ; (C) Copyright MICROSOFT Corp. 1986 | ||
| 9 | ; | ||
| 10 | ; Title: MEMM.EXE - MICROSOFT Expanded Memory Manager 386 Driver | ||
| 11 | ; | ||
| 12 | ; Module: EMMINIT - Expanded Memory Manager initialization routine | ||
| 13 | ; | ||
| 14 | ; Version: 0.05 | ||
| 15 | ; | ||
| 16 | ; Date: May 24 ,1986 | ||
| 17 | ; | ||
| 18 | ; Author: | ||
| 19 | ; | ||
| 20 | ;****************************************************************************** | ||
| 21 | ; | ||
| 22 | ; Change Log: | ||
| 23 | ; | ||
| 24 | ; DATE REVISION Description | ||
| 25 | ; -------- -------- -------------------------------------------- | ||
| 26 | ; 04/16/86 Original Adapted from DOS clock driver. | ||
| 27 | ; 05/24/86 0.00 From EMML test driver. | ||
| 28 | ; 06/21/86 0.02 added cld to EMM_Init | ||
| 29 | ; 06/28/86 0.02 Name change from MEMM386 to MEMM | ||
| 30 | ; 06/29/86 0.02 INC AX (was INC AL) for emm_free init | ||
| 31 | ; 07/06/86 0.04 Size _emm_page,_emm_free, & _pft386 based | ||
| 32 | ; on # of pages in system | ||
| 33 | ; 07/06/86 0.04 Changed assume to DGROUP | ||
| 34 | ; 07/10/86 0.05 moved int 67h patch to INIT | ||
| 35 | ; 06/07/88 added FRS_array initialization (Paul Chan) | ||
| 36 | ; | ||
| 37 | ;****************************************************************************** | ||
| 38 | ; Functional Description: | ||
| 39 | ; This module initializes the data structures for the EMM | ||
| 40 | ; and sets the current emm data break address (_emm_brk). | ||
| 41 | ; | ||
| 42 | ;****************************************************************************** | ||
| 43 | .lfcond | ||
| 44 | .386p | ||
| 45 | page | ||
| 46 | ;****************************************************************************** | ||
| 47 | ; P U B L I C D E C L A R A T I O N S | ||
| 48 | ;****************************************************************************** | ||
| 49 | ; | ||
| 50 | public EMM_Init | ||
| 51 | page | ||
| 52 | ;****************************************************************************** | ||
| 53 | ; L O C A L C O N S T A N T S | ||
| 54 | ;****************************************************************************** | ||
| 55 | ; | ||
| 56 | include vdmseg.inc | ||
| 57 | include emmdef.inc | ||
| 58 | |||
| 59 | FALSE equ 0 | ||
| 60 | TRUE equ not FALSE | ||
| 61 | |||
| 62 | EMM_HW_ERROR equ 81h ; EMM h/w error status | ||
| 63 | |||
| 64 | ;****************************************************************************** | ||
| 65 | ; E X T E R N A L R E F E R E N C E S | ||
| 66 | ;****************************************************************************** | ||
| 67 | ; | ||
| 68 | _DATA segment | ||
| 69 | |||
| 70 | extrn pool_size:word ; size of EMM Pages Pool in kbytes | ||
| 71 | extrn xbase_addr_h:byte ; bit 16-24 of address of first byte of emm memory | ||
| 72 | extrn xbase_addr_l:word ; bit 0-15 of address of first byte of emm memory | ||
| 73 | extrn sys_size:word ; number of 16k pages taken away from conv. mem | ||
| 74 | extrn PageT_Seg:word ; segment of system page table | ||
| 75 | |||
| 76 | extrn _PF_Base:word ; segment addr of page frame base | ||
| 77 | extrn _page_frame_pages:word ; number of pages in 3.2 page frame | ||
| 78 | |||
| 79 | extrn _EMMstatus:word ; status of EMM | ||
| 80 | |||
| 81 | extrn _page_frame_base:word ; pointers into page tables for each window | ||
| 82 | extrn _mappable_pages:word ; mappable page array | ||
| 83 | extrn _EMM_MPindex:byte ; index into mappable page array | ||
| 84 | extrn _physical_page_count:word ; number of physical pages | ||
| 85 | extrn _mappable_page_count:word ; number of mappable pages | ||
| 86 | |||
| 87 | extrn _cntxt_pages:word ; pages in a context | ||
| 88 | extrn _cntxt_bytes:word ; bytes in a context | ||
| 89 | |||
| 90 | extrn _emm_page:word ; ptr to array of EMM pages | ||
| 91 | extrn _free_count:word ; # of free EMM pages | ||
| 92 | extrn _emmpt_start:word ; start of empty part of emm page | ||
| 93 | extrn _emm_free:word ; ptr to array of free EMM pages | ||
| 94 | extrn _free_top:word ; top of _emm_free | ||
| 95 | |||
| 96 | extrn _total_pages:word ; total # of EMM pages available | ||
| 97 | extrn _pft386:word ; ptr to array of page table entries | ||
| 98 | |||
| 99 | extrn _emm_brk:word ; offset for emm data break address | ||
| 100 | |||
| 101 | extrn FRS_array:word ; | ||
| 102 | extrn CurRegSetn:byte | ||
| 103 | extrn CurRegSet:word | ||
| 104 | extrn FRS_free:byte | ||
| 105 | |||
| 106 | extrn _handle_table:word | ||
| 107 | extrn _handle_count:word | ||
| 108 | |||
| 109 | _DATA ends | ||
| 110 | |||
| 111 | ifndef NOHIMEM | ||
| 112 | else | ||
| 113 | VDATA segment | ||
| 114 | extrn vdata_begin:byte | ||
| 115 | VDATA ends | ||
| 116 | endif | ||
| 117 | |||
| 118 | LAST segment | ||
| 119 | extrn mappable_segs:byte | ||
| 120 | LAST ends | ||
| 121 | |||
| 122 | _TEXT segment | ||
| 123 | extrn InitELIM:far | ||
| 124 | _TEXT ends | ||
| 125 | |||
| 126 | LAST segment | ||
| 127 | extrn InitEPage:near | ||
| 128 | LAST ends | ||
| 129 | |||
| 130 | |||
| 131 | page | ||
| 132 | ;****************************************************************************** | ||
| 133 | ; S E G M E N T D E F I N I T I O N | ||
| 134 | ;****************************************************************************** | ||
| 135 | ; | ||
| 136 | ;****************************************************************************** | ||
| 137 | ; | ||
| 138 | ; Code Segment | ||
| 139 | ; | ||
| 140 | ;****************************************************************************** | ||
| 141 | ;****************************************************************************** | ||
| 142 | ; MACROS used in the EMM initialisation code | ||
| 143 | ;****************************************************************************** | ||
| 144 | ;****************************************************************************** | ||
| 145 | ; | ||
| 146 | ; Get_FRS_window - get pointer to Fast Register Set window | ||
| 147 | ; | ||
| 148 | ; ENTRY: Reg - points to an FRS_struc | ||
| 149 | ; | ||
| 150 | ; EXIT: Reg - points to FRS_window entry in the structure | ||
| 151 | ; | ||
| 152 | ; USES: Reg | ||
| 153 | ; | ||
| 154 | ;****************************************************************************** | ||
| 155 | Get_FRS_window MACRO Reg | ||
| 156 | |||
| 157 | mov Reg, word ptr [CurRegSet] ; just offset (assume dgroup) | ||
| 158 | add Reg, FRS_window ; points to FRS window entries | ||
| 159 | ENDM | ||
| 160 | |||
| 161 | ;****************************************************************************** | ||
| 162 | ;**init_PAGE_FRAME_BASE: macro to fill in the page_frame_base array. this | ||
| 163 | ; array contains the selector:offset into page table. The selector is already | ||
| 164 | ; initialised. So the offset of each of the physical pages into the page | ||
| 165 | ; table needs to be filled in. | ||
| 166 | ; | ||
| 167 | ; ENTRY: SI = INDEX INTO _page_frame_base, also physical page # | ||
| 168 | ; BX = Segment of physical page | ||
| 169 | ; | ||
| 170 | ;****************************************************************************** | ||
| 171 | init_page_frame_base MACRO | ||
| 172 | ; | ||
| 173 | push si | ||
| 174 | push bx | ||
| 175 | ; | ||
| 176 | shl si,2 ; convert index into offset in dword array | ||
| 177 | ; | ||
| 178 | shr bx,6 ; convert segment into page table offset | ||
| 179 | ; since there is 1 dword entry for each 4k | ||
| 180 | ; | ||
| 181 | mov _page_frame_base[si],bx ; fill this in | ||
| 182 | ; | ||
| 183 | pop bx | ||
| 184 | pop si | ||
| 185 | ; | ||
| 186 | ENDM | ||
| 187 | |||
| 188 | ;****************************************************************************** | ||
| 189 | ;**init_MAPPABLE_PAGES: macro to fill the _mappable_pages array. this array | ||
| 190 | ; contains the segment and physical page number of all the mappable physical | ||
| 191 | ; pages. | ||
| 192 | ; | ||
| 193 | ; ENTRY: SI = INDEX INTO _page_frame_base, also physical page # | ||
| 194 | ; BX = Segment of physical page | ||
| 195 | ; DI = Index into _mappable_pages | ||
| 196 | ; | ||
| 197 | ;****************************************************************************** | ||
| 198 | init_mappable_pages MACRO | ||
| 199 | ; | ||
| 200 | push di | ||
| 201 | ; | ||
| 202 | shl di,2 ; convert index into offset in dword array | ||
| 203 | ; | ||
| 204 | mov _mappable_pages[di],bx ; fill in segment | ||
| 205 | mov _mappable_pages[di][2],si ; and physical page number | ||
| 206 | ; | ||
| 207 | pop di | ||
| 208 | ; | ||
| 209 | ENDM | ||
| 210 | |||
| 211 | ;****************************************************************************** | ||
| 212 | ;**init_MAPPABLE_INDEX: macro to fill in EMM_MPIndex array. This array | ||
| 213 | ; contains a cross reference for the memory from 4000h to 10000h into the | ||
| 214 | ; mappable_pages array. There is an entry for each 16k page. The pages in | ||
| 215 | ; this range which are not mappable are initialised to -1. The ones which | ||
| 216 | ; are mappable are initialised to the index into the mappable_pages array | ||
| 217 | ; for the entry which represents this page | ||
| 218 | ; | ||
| 219 | ; ENTRY: DI = Index into _mappable_pages | ||
| 220 | ; BX = Segment of physical page | ||
| 221 | ; | ||
| 222 | ;****************************************************************************** | ||
| 223 | init_mappable_index MACRO | ||
| 224 | ; | ||
| 225 | push ax | ||
| 226 | push bx | ||
| 227 | ; | ||
| 228 | shr bx,10 ; convert segment to 16k page # | ||
| 229 | sub bx,CONV_STRT_PG ; first page in EMM_MPIndex array is 16 | ||
| 230 | ; | ||
| 231 | mov ax,di ; to extract the lower byte | ||
| 232 | mov _EMM_MPIndex[bx],al ; fill in index | ||
| 233 | ; | ||
| 234 | pop bx | ||
| 235 | pop ax | ||
| 236 | ; | ||
| 237 | ENDM | ||
| 238 | |||
| 239 | ;****************************************************************************** | ||
| 240 | ; INVALIDATE_MAPPABLE_PAGE_ENTRY: macro to remove the page from the mappable | ||
| 241 | ; page temporary list we are using. this is to facilitate the recognition | ||
| 242 | ; of pages above A000 which are not page frame pages. When we recognise page | ||
| 243 | ; frame pages we invalidate them so that the subsequent pass for pages doesn't | ||
| 244 | ; include these. | ||
| 245 | ; | ||
| 246 | ; ENTRY: BX = Segment of physical page | ||
| 247 | ;****************************************************************************** | ||
| 248 | inv_mpbl MACRO | ||
| 249 | ; | ||
| 250 | push bx | ||
| 251 | ; | ||
| 252 | shr bx,10 ; convert segment to 16k page # | ||
| 253 | mov cs:mappable_segs[bx],PAGE_NOT_MAPPABLE | ||
| 254 | ; | ||
| 255 | pop bx | ||
| 256 | ; | ||
| 257 | |||
| 258 | ENDM | ||
| 259 | |||
| 260 | ; | ||
| 261 | LAST segment USE16 | ||
| 262 | assume cs:LAST, ds:DGROUP, es:DGROUP | ||
| 263 | |||
| 264 | ;****************************************************************************** | ||
| 265 | ; LOCAL VARIABLES | ||
| 266 | ;****************************************************************************** | ||
| 267 | first_sys_ppage dw 0ffffh ; physical page number of first system page | ||
| 268 | |||
| 269 | page | ||
| 270 | ;****************************************************************************** | ||
| 271 | ; | ||
| 272 | ; CODE FOR INITIALISATION | ||
| 273 | ; | ||
| 274 | ;****************************************************************************** | ||
| 275 | |||
| 276 | |||
| 277 | page | ||
| 278 | ;****************************************************************************** | ||
| 279 | ; EMM_Init - initialization routine for EMM. | ||
| 280 | ; Patches int 67h vector. | ||
| 281 | ; | ||
| 282 | ; ENTRY: none | ||
| 283 | ; | ||
| 284 | ; EXIT: EMM vector initialized. | ||
| 285 | ; EMM data structures initialized | ||
| 286 | ; NC => no errors | ||
| 287 | ; C => errors | ||
| 288 | ; | ||
| 289 | ; USED: none | ||
| 290 | ; | ||
| 291 | ;****************************************************************************** | ||
| 292 | EMM_Init proc near | ||
| 293 | ; | ||
| 294 | pusha | ||
| 295 | push ds | ||
| 296 | push es | ||
| 297 | ; | ||
| 298 | ; set DS,ES to DGROUP segment | ||
| 299 | ; | ||
| 300 | mov ax,seg DGROUP | ||
| 301 | mov ds,ax | ||
| 302 | mov es,ax | ||
| 303 | ; | ||
| 304 | cld ; strings foward | ||
| 305 | ; | ||
| 306 | ; init EMM status | ||
| 307 | ; | ||
| 308 | mov [_EMMstatus],0 | ||
| 309 | |||
| 310 | ; | ||
| 311 | ; set total # of EMM pages | ||
| 312 | ; | ||
| 313 | mov cx,[pool_size] ; CX = kbytes of expanded memory | ||
| 314 | shr cx,4 ; CX = # of EMM pages available | ||
| 315 | mov [_total_pages],cx ; pages total | ||
| 316 | ; | ||
| 317 | ; init ptrs for _emm_page, _emm_free and _pft386 | ||
| 318 | ; | ||
| 319 | shl cx,1 ; CX = bytes in total_pages words | ||
| 320 | |||
| 321 | ifndef NOHIMEM | ||
| 322 | else | ||
| 323 | mov ax,seg VDATA | ||
| 324 | sub ax,seg DGROUP | ||
| 325 | shl ax,4 ; convert into offset from dgroup | ||
| 326 | add ax,offset VDATA:vdata_begin | ||
| 327 | mov [_emm_page],ax | ||
| 328 | endif | ||
| 329 | |||
| 330 | |||
| 331 | mov ax,[_emm_page] ; AX = ptr to emm_page array | ||
| 332 | add ax,cx ; AX = ptr to word just past emm_page[] | ||
| 333 | mov [_emm_free],ax ; set ptr for emm_free[] | ||
| 334 | add ax,cx ; AX = ptr to word just past emm_free[] | ||
| 335 | mov [_pft386],ax ; set ptr for _pft386[] | ||
| 336 | shl cx,1 ; CX = bytes in total_pages dwords | ||
| 337 | add ax,cx ; AX = ptr to word just past _pft386[] | ||
| 338 | mov [_emm_brk],ax ; set break address for emm data | ||
| 339 | shr cx,2 ; CX = total_pages again | ||
| 340 | ; | ||
| 341 | ; init free pages array | ||
| 342 | ; | ||
| 343 | mov [_free_count],cx ; all pages free initially | ||
| 344 | mov [_free_top],0 ; top ptr pts to first free page | ||
| 345 | mov di,[_emm_free] ; ES:DI pts to _emm_free[0] | ||
| 346 | mov bx,[_free_top] ; BX = current top of free list | ||
| 347 | shl bx,1 | ||
| 348 | add di,bx ; ES:DI pts to begin of free page area | ||
| 349 | xor ax,ax ; start with EMM page#0 | ||
| 350 | EMMP_loop: ; copy free pages into _emm_free | ||
| 351 | stosw ; store EMM page# | ||
| 352 | inc ax ;(0.02) increment page# | ||
| 353 | loop EMMP_loop ;Q: all entries in _emm_free[] ? | ||
| 354 | ; N: do next page. | ||
| 355 | ; | ||
| 356 | ; fix _page_frame_pages to be a maximum of 4 (for the LIM 3.2 frame) | ||
| 357 | ; | ||
| 358 | cmp [_page_frame_pages],4 | ||
| 359 | jbe EMIN_1 | ||
| 360 | mov [_page_frame_pages],4 | ||
| 361 | EMIN_1: | ||
| 362 | ; | ||
| 363 | ; See validity of page frame | ||
| 364 | ; | ||
| 365 | test [_PF_base],3ffh ; if any of these bits are set it is | ||
| 366 | ; invalid | ||
| 367 | jne EMIN_2 ; | ||
| 368 | cmp [_PF_base],0E400h ; in the ROM area | ||
| 369 | jae EMIN_2 ; also invalid | ||
| 370 | cmp [_PF_base],0C000h ; or in the video area | ||
| 371 | jnb EMIN_3 ; | ||
| 372 | EMIN_2: | ||
| 373 | ; | ||
| 374 | ; Page Frame invalid, set it to FFFFh and _page_frame_pages to 0 | ||
| 375 | ; | ||
| 376 | mov [_PF_base],0FFFFh | ||
| 377 | mov [_page_frame_pages],0 | ||
| 378 | ; | ||
| 379 | EMIN_3: | ||
| 380 | ; | ||
| 381 | ; setting up _page_frame_base | ||
| 382 | ; _mappable_pages | ||
| 383 | ; _EMM_MPIndex | ||
| 384 | ; _physical_page_count | ||
| 385 | ; _mappable_page_count | ||
| 386 | ; | ||
| 387 | ; | ||
| 388 | ; | ||
| 389 | ; ----------------- ----------------- ----------------- | ||
| 390 | ; | for pages | | for pages | | |FC00h | ||
| 391 | ; | below | | below | |---------------| | ||
| 392 | ; | A000h | | A000h | | | | ||
| 393 | ; ----------------- ----------------- | | | ||
| 394 | ; | | | | | . | | ||
| 395 | ; | for pages | | for pages | | . | | ||
| 396 | ; | above | | above | | . | | ||
| 397 | ; | A000h | | A000h | <-- | | | ||
| 398 | ; | | | | | |---------------| | ||
| 399 | ; ----------------- ----------------- | | |4800h | ||
| 400 | ; | for page frame| | for page frame| | |---------------| | ||
| 401 | ; | pages even if | | pages only if | |------- |4400h | ||
| 402 | ; | they don't | | they exist | |---------------| | ||
| 403 | ; | exist | | | | |4000h | ||
| 404 | ; ----------------- ----------------- ----------------- | ||
| 405 | ; | ||
| 406 | ; _page_frame_base _mappable_pages EMM_MPIndex | ||
| 407 | ; | ||
| 408 | ; Each entry reps Each entry reps Each entry reps | ||
| 409 | ; a physical page. a mappable ph. page a system page | ||
| 410 | ; | ||
| 411 | ; DWORD. DWORD Byte | ||
| 412 | ; | ||
| 413 | ; 1st WORD: offset 1st WORD: segment Index into | ||
| 414 | ; into page table of ph. page _mappable_pages | ||
| 415 | ; which reps the page | ||
| 416 | ; 2nd WORD: sel. 2nd WORD: physical | ||
| 417 | ; of page table page # of ph. page | ||
| 418 | ; | ||
| 419 | ; | ||
| 420 | ; 1. Set up for the page frame pages. Note that they may or may not exist. | ||
| 421 | ; Even if they do not exist entries must be set up for them in the | ||
| 422 | ; _page_frame_base. | ||
| 423 | ; | ||
| 424 | ; | ||
| 425 | ; initialise indexes. | ||
| 426 | ; | ||
| 427 | xor si,si ; index into _page_frame_pages | ||
| 428 | ; thus also physical page number | ||
| 429 | xor di,di ; index into _mappable_pages | ||
| 430 | ; | ||
| 431 | ; set up for page frame pages | ||
| 432 | ; | ||
| 433 | mov cx,[_page_frame_pages] ; get number | ||
| 434 | jcxz EMIN_5 ; if none exist then skip next portion | ||
| 435 | ; | ||
| 436 | mov bx,[_PF_base] ; get page frame base | ||
| 437 | ; | ||
| 438 | ; the setup loop: | ||
| 439 | ; | ||
| 440 | EMIN_4: | ||
| 441 | init_page_frame_base | ||
| 442 | init_mappable_pages | ||
| 443 | init_mappable_index | ||
| 444 | inv_mpbl | ||
| 445 | ; | ||
| 446 | ; update counters for next entry | ||
| 447 | ; | ||
| 448 | inc si | ||
| 449 | inc di | ||
| 450 | add bx,0400h | ||
| 451 | ; | ||
| 452 | ; and loop back | ||
| 453 | ; | ||
| 454 | loop EMIN_4 | ||
| 455 | ; | ||
| 456 | EMIN_5: | ||
| 457 | ; | ||
| 458 | ; 2. If page frame pages were less than 4 then also we should set aside | ||
| 459 | ; four entries in the physical page array | ||
| 460 | ; | ||
| 461 | mov si,4 | ||
| 462 | ; | ||
| 463 | ; 3. Setup for the mappable pages above A000h. Search the mappable_segs | ||
| 464 | ; array for mappable pages above A000h and for each mappable page make | ||
| 465 | ; an entry in the arrays | ||
| 466 | ; | ||
| 467 | ; | ||
| 468 | ; setup the segment and the count of pages we have to look for. also | ||
| 469 | ; the index into the mappable_segs array | ||
| 470 | ; | ||
| 471 | mov bx,0A000h ; segment | ||
| 472 | mov dx,bx ; | ||
| 473 | shr dx,10 ; page # corresponding to segment | ||
| 474 | ; | ||
| 475 | mov cx,64 ; max page # | ||
| 476 | sub cx,dx ; | ||
| 477 | ; | ||
| 478 | ; setup loop | ||
| 479 | EMIN_6: | ||
| 480 | ; | ||
| 481 | ; see if page mappable | ||
| 482 | ; | ||
| 483 | xchg dx,bx | ||
| 484 | cmp cs:mappable_segs[bx],PAGE_MAPPABLE ; | ||
| 485 | xchg dx,bx | ||
| 486 | jnz EMIN_7 | ||
| 487 | ; | ||
| 488 | ; page mappable. set up entries for it | ||
| 489 | ; | ||
| 490 | init_page_frame_base ; set up the page_frame_base entry | ||
| 491 | init_mappable_pages ; set up the mappable_pages entry | ||
| 492 | init_mappable_index ; set up the EMM_MPIndex | ||
| 493 | ; | ||
| 494 | ; update counters for next entry | ||
| 495 | ; | ||
| 496 | inc si ; these two are only updated | ||
| 497 | inc di ; if an entry is found | ||
| 498 | EMIN_7: | ||
| 499 | inc dx ; and these two are updated in | ||
| 500 | add bx,0400h ; any case | ||
| 501 | ; | ||
| 502 | ; and loop back | ||
| 503 | ; | ||
| 504 | loop EMIN_6 | ||
| 505 | |||
| 506 | ; | ||
| 507 | ; 4. Finally set up for the system pages | ||
| 508 | ; | ||
| 509 | ; | ||
| 510 | ; store the physical page # of the 1st system page. | ||
| 511 | ; | ||
| 512 | mov cs:[first_sys_ppage],si | ||
| 513 | ; | ||
| 514 | ; setup the segment and the count of pages we have to look for. also | ||
| 515 | ; the index into the mappable_segs array | ||
| 516 | ; | ||
| 517 | mov bx,04000h ; segment | ||
| 518 | mov dx,bx ; | ||
| 519 | shr dx,10 ; page # corresponding to segment | ||
| 520 | ; | ||
| 521 | mov cx,40 ; max page # | ||
| 522 | sub cx,dx ; | ||
| 523 | ; number of pages to be examined | ||
| 524 | ; | ||
| 525 | ; setup loop | ||
| 526 | EMIN_8: | ||
| 527 | ; | ||
| 528 | ; see if page mappable. | ||
| 529 | ; | ||
| 530 | xchg dx,bx | ||
| 531 | cmp cs:mappable_segs[bx],PAGE_MAPPABLE ; | ||
| 532 | xchg dx,bx | ||
| 533 | jnz EMIN_9 | ||
| 534 | ; | ||
| 535 | ; page mappable. set up entries for it | ||
| 536 | ; | ||
| 537 | init_page_frame_base ; set up the page_frame_base entry | ||
| 538 | init_mappable_pages ; set up the mappable_pages entry | ||
| 539 | init_mappable_index ; set up the EMM_MPIndex | ||
| 540 | ; | ||
| 541 | ; update counters for next entry | ||
| 542 | ; | ||
| 543 | inc si ; these two are only updated | ||
| 544 | inc di ; if an entry is found | ||
| 545 | EMIN_9: | ||
| 546 | inc dx ; and these two are updated in | ||
| 547 | add bx,0400h ; any case | ||
| 548 | ; | ||
| 549 | ; and loop back | ||
| 550 | ; | ||
| 551 | loop EMIN_8 | ||
| 552 | ; | ||
| 553 | ; 5. finally use the indexes to fill up the counts of the number of entries in | ||
| 554 | ; each array. | ||
| 555 | ; | ||
| 556 | mov [_physical_page_count],si | ||
| 557 | mov [_mappable_page_count],di | ||
| 558 | ; | ||
| 559 | ; | ||
| 560 | ; 6. and the pages in a context and the number of bytes needed to save a | ||
| 561 | ; context. | ||
| 562 | ; | ||
| 563 | inc si ; cntxt_pages = (physical_page_count | ||
| 564 | ; + 1) & NOT 1 | ||
| 565 | and si, NOT 0001h ; to round up si to higher even # | ||
| 566 | mov [_cntxt_pages],si ; number of pages in a context | ||
| 567 | ; | ||
| 568 | shl si,1 | ||
| 569 | add si,2 ; cntxt_bytes = cntxt_pages*2 + 2 | ||
| 570 | mov [_cntxt_bytes],si ; | ||
| 571 | ; | ||
| 572 | |||
| 573 | ; | ||
| 574 | ; initialize FRS_array | ||
| 575 | ; | ||
| 576 | lea si,FRS_array ; DS:SI <-- FRS_array | ||
| 577 | mov [si.FRS_alloc], 1 ; mark FRS set 0 as allocated | ||
| 578 | mov [CurRegSetn], 0 ; use FRS set 0 | ||
| 579 | mov [FRS_free], FRS_COUNT-1 ; one less FRS set | ||
| 580 | mov word ptr [CurRegSet], SI; save current FRS pointer | ||
| 581 | |||
| 582 | ; | ||
| 583 | ; NOW for some Handle 0 initialisation. We have to reclaim the pages we | ||
| 584 | ; released to the emm page pool from the conventional memory. This is | ||
| 585 | ; easy. These happen to be the first k pages in the emm page pool. We | ||
| 586 | ; need to fix the following data structures to reclaim these. | ||
| 587 | ; | ||
| 588 | ; k pages need to be transferred to emm_page array from emm_free array | ||
| 589 | ; and emmpt_start, _free_top, _free_count and _handle_table and _handle_count | ||
| 590 | ; updated | ||
| 591 | ; | ||
| 592 | ; find out the number of pages to be reclaimed | ||
| 593 | ; | ||
| 594 | mov cx,[sys_size] ; in kb | ||
| 595 | shr cx, 4 ; convert to number of 16k pages | ||
| 596 | ; | ||
| 597 | ; transfer these many pages from the emm_free array to the emm_pages array | ||
| 598 | ; | ||
| 599 | push cx | ||
| 600 | ; | ||
| 601 | mov si,_emm_free ; | ||
| 602 | add si,_free_top ; | ||
| 603 | add si,_free_top ; get offset to free page | ||
| 604 | ; | ||
| 605 | mov di,_emm_page ; | ||
| 606 | add di,_emmpt_start ; | ||
| 607 | add di,_emmpt_start ; get offset to next available loc in | ||
| 608 | ; emm_page | ||
| 609 | ; | ||
| 610 | cld | ||
| 611 | rep movsw ; transfer the pages over | ||
| 612 | ; | ||
| 613 | pop cx | ||
| 614 | ; | ||
| 615 | ; fix entry for handle 0 in handle table | ||
| 616 | ; | ||
| 617 | mov dx, [_emmpt_start] | ||
| 618 | mov _handle_table[0],dx ; offset into emm_page array | ||
| 619 | mov _handle_table[2],cx ; number of pages | ||
| 620 | ; | ||
| 621 | ; handle_count needs to be incremented to indicate that handle 0 is | ||
| 622 | ; allocated | ||
| 623 | ; | ||
| 624 | inc [_handle_count] | ||
| 625 | ; | ||
| 626 | ; fix ptr in emm page tracking arrays | ||
| 627 | ; | ||
| 628 | add [_emmpt_start],cx | ||
| 629 | add [_free_top],cx | ||
| 630 | sub [_free_count],cx | ||
| 631 | ; | ||
| 632 | ; Initialise FRS initialisation | ||
| 633 | ; | ||
| 634 | ; di = pointer into FRS. bx = physical page number. si = pointer into emm_page | ||
| 635 | ; cx = number of pages mapped. | ||
| 636 | ; | ||
| 637 | mov si,_handle_table[0] ; get pointer into emm_page | ||
| 638 | shl si,1 ; emm_page is a word array | ||
| 639 | add si,[_emm_page] ; | ||
| 640 | ; | ||
| 641 | GET_FRS_WINDOW di ; get pointer to FRS area | ||
| 642 | |||
| 643 | mov bx,cs:[first_sys_ppage] | ||
| 644 | shl bx,1 | ||
| 645 | add di,bx ; | ||
| 646 | ; | ||
| 647 | cld | ||
| 648 | rep movsw | ||
| 649 | ; | ||
| 650 | ; | ||
| 651 | ; the way we have allocated the pages we don't need to update the Page table | ||
| 652 | ; the pages that have been mapped | ||
| 653 | ; | ||
| 654 | ; init ELIM h/w emulation (DMA PORTS) | ||
| 655 | ; | ||
| 656 | call InitELIM | ||
| 657 | |||
| 658 | ; | ||
| 659 | ; init EMM_PTE - ptrs to EMM pages | ||
| 660 | ; | ||
| 661 | call InitEPage | ||
| 662 | ; | ||
| 663 | ; leave - no errors | ||
| 664 | ; | ||
| 665 | pop es | ||
| 666 | pop ds | ||
| 667 | popa | ||
| 668 | ; | ||
| 669 | xor ax,ax | ||
| 670 | clc | ||
| 671 | ret | ||
| 672 | ; | ||
| 673 | EMM_Init endp | ||
| 674 | |||
| 675 | ; | ||
| 676 | LAST ends | ||
| 677 | |||
| 678 | end | ||