diff options
Diffstat (limited to 'v4.0/src/DEV/XMA2EMS')
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/DIAGS.ASM | 1909 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/EMSINIT.INC | 886 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/EMS_US.MSG | 110 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/GENIOCTL.INC | 167 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/I13HOOK.INC | 449 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/LIM40.INC | 1792 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/LIM40B.INC | 3468 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/MAKEFILE | 24 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/PARMPARS.INC | 530 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/PS2_5060.INC | 735 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/ROMSCAN.INC | 420 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/XMA1DIAG.INC | 1870 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM | 2591 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/XMA2EMS.LC | 11 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/XMA2EMS.SKL | 39 | ||||
| -rw-r--r-- | v4.0/src/DEV/XMA2EMS/XMA2EMSP.INC | 243 |
16 files changed, 15244 insertions, 0 deletions
diff --git a/v4.0/src/DEV/XMA2EMS/DIAGS.ASM b/v4.0/src/DEV/XMA2EMS/DIAGS.ASM new file mode 100644 index 0000000..6c52a1c --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/DIAGS.ASM | |||
| @@ -0,0 +1,1909 @@ | |||
| 1 | ;-----------------------------------------------------------------------; | ||
| 2 | ; DATA THAT IS UNIQUE TO THE DIAGNOSTICS PORTION OF ; | ||
| 3 | ; THE DEVICE DRIVER. THIS AREA WILL NOT REMAIN PRESENT ; | ||
| 4 | ; AFTER INITIALIZATION. ; | ||
| 5 | ;-----------------------------------------------------------------------; | ||
| 6 | INCLUDE EMS_US.MSG | ||
| 7 | |||
| 8 | MEM_INST DB '1' | ||
| 9 | ADDR_MODEL_BYTE DD 0F000FFFEH ;ADDRESS IN BIOS OF MODEL BYTE | ||
| 10 | MODEL DB ? ;SAVE AREA FOR MODEL | ||
| 11 | TEST_ID DB ? ;SAVE AREA FOR CURRENT TEST ID | ||
| 12 | CTRLPARM DW ? ;SAVE AREA FOR CONTROL PARM | ||
| 13 | PAGE_UNDER_TEST DW 0 ;SAVE AREA FOR PAGE UNDER TEST | ||
| 14 | CUR_SAVE DW ? ;SAVE AREA FOR NEXT AVAILABLE LINE | ||
| 15 | ;FOR MESSAGES | ||
| 16 | ACTIVE_PAGE DB ? ;ACTIVE DISPLAY PAGE | ||
| 17 | TESTABLE_SEGMENTS DW ? | ||
| 18 | |||
| 19 | |||
| 20 | PAGE | ||
| 21 | ;-----------------------------------------------------------------------; | ||
| 22 | ; EQUATES THAT ARE UNIQUE TO THE DIAGNOSTICS PORTION OF ; | ||
| 23 | ; THE DEVICE DRIVER. ; | ||
| 24 | ;-----------------------------------------------------------------------; | ||
| 25 | BASE_REG EQU 31A0H | ||
| 26 | DMACAPT EQU 31A8H ;I/O ADDRESS OF DMA CAPTURE REG | ||
| 27 | BLK_ON EQU 11110111B ;MASK FOR ENABLING A BLOCK | ||
| 28 | BLK_OFF EQU 00001000B ;MASK FOR INHIBITING A BLOCK | ||
| 29 | VIRT_MODE EQU 00000010B ;MASK FOR VIRTUAL MODE | ||
| 30 | REAL_MODE EQU 11111101B ;MASK FOR REAL MODE | ||
| 31 | MAX_TASK_ID EQU 15 ;MAXIMIM TASK ID | ||
| 32 | ENABLE EQU 01H ;INDICATES THAT BLOCK SHOULD BE ENABLED | ||
| 33 | TABLEN EQU 1000H ;NUMBER OF ENTRIES IN XLAT TABLE | ||
| 34 | DMAREQ1 EQU 0009H ;I/O ADDRESS OF DMA CTRL 1 REQ REG | ||
| 35 | DMAREQ2 EQU 00D2H ;I/O ADDRESS OF DMA CTRL 2 REQ REG | ||
| 36 | DMAMODE1 EQU 000BH ;I/O ADDRESS OF DMA CTRL 1 MODE REG | ||
| 37 | DMAMODE2 EQU 00D6H ;I/O ADDRESS OF DMA CTRL 2 MODE REG | ||
| 38 | PC1 EQU 0FFH ;RESERVED BYTE FOR PC1 | ||
| 39 | PC_XT EQU 0FEH ;RESERVED BYTE FOR XT | ||
| 40 | XT_AQUARIUS EQU 0FBH ;RESERVED BYTE FOR XT-AQUARIUS | ||
| 41 | AT_NMI_REG EQU 70H ;AT NMI REG | ||
| 42 | AT_NMI_OFF EQU 80H ;AT NMI OFF MASK | ||
| 43 | AT_NMI_ON EQU 00H ;AT NMI ON MASK | ||
| 44 | AT_CHCHK_EN_REG EQU 61H ;AT CH CHK ENABLE REG | ||
| 45 | AT_CHCHK_REG EQU 61H ;AT CH CHK REG | ||
| 46 | AT_CHCHK_EN EQU 0F7H ;AT CH CHK ENABLE MASK | ||
| 47 | AT_CHCHK_DIS EQU 08H ;AT CH CHK DISABLE MASK | ||
| 48 | AT_CHCHK EQU 40H ;AT CH CHK MASK | ||
| 49 | XT_NMI_REG EQU 0A0H ;XT NMI REG | ||
| 50 | XT_NMI_OFF EQU 00H ;XT NMI OFF MASK | ||
| 51 | XT_NMI_ON EQU 80H ;XT NMI ON MASK | ||
| 52 | XT_CHCHK_EN_REG EQU 61H ;XT CH CHK ENABLE REG | ||
| 53 | XT_CHCHK_REG EQU 62H ;XT CH CHK REG | ||
| 54 | XT_CHCHK_EN EQU 0DFH ;XT CH CHK ENABLE MASK | ||
| 55 | XT_CHCHK_DIS EQU 20H ;XT CH CHK DISABLE MASK | ||
| 56 | XT_CHCHK EQU 40H ;XT CH CHK MASK | ||
| 57 | ONE_MEG EQU 16 ;CONSTANT FOR ONE MEG MEMORY CARD | ||
| 58 | TWO_MEG EQU 32 ;CONSTANT FOR TWO MEG MEMORY CARD | ||
| 59 | CR EQU 0DH ;CARRIAGE RETURN | ||
| 60 | LF EQU 0AH ;LINE FEED | ||
| 61 | PRES_TEST EQU 01 ;PRESENCE TEST ID | ||
| 62 | REG_TEST EQU 02 ;REG TEST ID | ||
| 63 | AUTO_INC EQU 03 ;AUTO INC TEST ID | ||
| 64 | XLAT_TABLE_TEST EQU 04 ;TT TEST ID | ||
| 65 | LOMEM_TEST EQU 05 ;ABOVE 640K TEST ID | ||
| 66 | DMA_CAPTURE EQU 06 ;DMA CAPTURE TEST ID | ||
| 67 | PAGE_TEST EQU 07 ;PAGE TEST ID | ||
| 68 | MEM_TEST EQU 10 ;MEMORY TEST ID | ||
| 69 | |||
| 70 | |||
| 71 | ;------------------------------------------------------------------------; | ||
| 72 | ; Diagnostics...on exit if ZF=0 then error ; | ||
| 73 | ;------------------------------------------------------------------------; | ||
| 74 | DIAGS PROC | ||
| 75 | |||
| 76 | MOV CS:TEST_ID,00H ;CLEAR TEST ID BYTE | ||
| 77 | MOV CS:CTRLPARM,0100H ;SAVE CONTROL PARM | ||
| 78 | CALL GETMOD ;FIND OUT WHICH PC THIS IS | ||
| 79 | CALL CUR_POS ;GET CURSOR READY FOR MESSAGES | ||
| 80 | CALL REGTST ;TEST XMA REGISTERS | ||
| 81 | JNE FOUND_ERROR ;JUMP IF ERROR | ||
| 82 | CALL INCTST | ||
| 83 | JNE FOUND_ERROR | ||
| 84 | CALL XLATST | ||
| 85 | JNE FOUND_ERROR | ||
| 86 | CALL LOMEMTST ;TEST FOR BELOW 640K | ||
| 87 | JNE FOUND_ERROR ;JUMP IF ERROR | ||
| 88 | CALL MEMARRAY ;TEST MEMORY ABOVE 640K | ||
| 89 | JNE FOUND_ERROR ;JUMP IF ERROR | ||
| 90 | CALL PAGETST | ||
| 91 | JNE FOUND_ERROR | ||
| 92 | CALL CAPTST ;TEST DMA CAPTURE | ||
| 93 | JNE FOUND_ERROR ;JUMP IF ERROR | ||
| 94 | FOUND_ERROR: | ||
| 95 | RET | ||
| 96 | DIAGS ENDP | ||
| 97 | |||
| 98 | |||
| 99 | |||
| 100 | |||
| 101 | PAGE | ||
| 102 | ;------------------------------------------------------------------------- | ||
| 103 | ;------------------------------------------------------------------------- | ||
| 104 | ; | ||
| 105 | ; PRESENCE TEST | ||
| 106 | ; | ||
| 107 | ; DESCRIPTION : This routine will determine if the XMA is in the system. | ||
| 108 | ; It will also determine the amount of memory installed | ||
| 109 | ; on the card in 1Meg increments (up to 4Meg). | ||
| 110 | ; | ||
| 111 | ; FUNCTION/ : See description | ||
| 112 | ; PURPOSE | ||
| 113 | ; | ||
| 114 | ; ENTRY POINT : PRESTST | ||
| 115 | ; | ||
| 116 | ; ENTRY : The assumption is that at least 1MB of memory is installed. | ||
| 117 | ; CONDITIONS If the 2nd, 3rd or 4th MB of memory is installed then the | ||
| 118 | ; TOTAL_XMA_PAGES, TOTAL_PAGES, FREE_PAGES and | ||
| 119 | ; MEM_INST words are Revised accordingly. | ||
| 120 | ; | ||
| 121 | ; | ||
| 122 | ; | ||
| 123 | ; EXIT : (zero flag) = 0 indicates that the XMA is not installed. | ||
| 124 | ; if (zero flag) <> 0 then | ||
| 125 | ; TOTAL_XMA_PAGES, TOTAL_PAGES, FREE_PAGES and | ||
| 126 | ; MEM_INST words are Revised accordingly. | ||
| 127 | ; | ||
| 128 | ; AX,BX,CX,DX ARE DESTROYED | ||
| 129 | ;------------------------------------------------------------------------- | ||
| 130 | ; | ||
| 131 | PRESTST PROC | ||
| 132 | ; | ||
| 133 | MOV AL,PRES_TEST | ||
| 134 | MOV CS:TEST_ID,AL | ||
| 135 | |||
| 136 | ;SAVE CONTENTS OF MODE REG | ||
| 137 | MOV DX,MODE_REG | ||
| 138 | IN AL,DX | ||
| 139 | PUSH AX | ||
| 140 | |||
| 141 | ; TRANSLATE TABLE ADDRESS AND DATA REGISTERS | ||
| 142 | ; | ||
| 143 | MOV AX,0AA55H ;DATA PATTERN (IN REAL MODE) | ||
| 144 | ;BE CERTAIN MODE REG GETS | ||
| 145 | ;REAL MODE | ||
| 146 | MOV DX,MODE_REG ;I/O TO MODE REG | ||
| 147 | OUT DX,AL ;WRITE PATTERN | ||
| 148 | MOV DX,TTPOINTER + 1 ;I/O TO TT POINTER (ODD ADDR) | ||
| 149 | XCHG AL,AH ;CHRG BUS WITH INVERSE PATTERN | ||
| 150 | OUT DX,AL ;WRITE IT | ||
| 151 | MOV DX,MODE_REG | ||
| 152 | IN AL,DX ;READ BACK MODE REG | ||
| 153 | XOR AL,AH | ||
| 154 | AND AL,0FH ;MASK OFF UNUSED BITS | ||
| 155 | ;ZERO FLAG = 0 IF ERROR | ||
| 156 | END_PRES: | ||
| 157 | POP AX | ||
| 158 | PUSHF ;SAVE FLAGS | ||
| 159 | MOV DX,MODE_REG | ||
| 160 | OUT DX,AL ;RESTORE MODE REG TO INITIAL STATE | ||
| 161 | POPF ;RESTORE FLAGS | ||
| 162 | RET ;BACK TO CALLER | ||
| 163 | ; | ||
| 164 | PRESTST ENDP | ||
| 165 | |||
| 166 | |||
| 167 | |||
| 168 | |||
| 169 | PAGE | ||
| 170 | ;------------------------------------------------------------------------- | ||
| 171 | ;------------------------------------------------------------------------- | ||
| 172 | ; | ||
| 173 | ; SAVES CURSOR POSITION | ||
| 174 | ; | ||
| 175 | ; DESCRIPTION : This routine simply saves the cursor location | ||
| 176 | ; in CS:CUR_SAVE. This cursor position | ||
| 177 | ; should be used by the KB_OK routine to insure proper | ||
| 178 | ; format of the screen. | ||
| 179 | ; | ||
| 180 | ; FUNCTION/ : See description | ||
| 181 | ; PURPOSE | ||
| 182 | ; | ||
| 183 | ; | ||
| 184 | ; ENTRY POINT : CUR_POS | ||
| 185 | ; | ||
| 186 | ; ENTRY : | ||
| 187 | ; CONDITIONS | ||
| 188 | ; | ||
| 189 | ; | ||
| 190 | ; EXIT : new cursor position is saved in CS:CUR_SAVE | ||
| 191 | ; | ||
| 192 | ; All registers are preserved | ||
| 193 | ; | ||
| 194 | ;------------------------------------------------------------------------- | ||
| 195 | ; | ||
| 196 | CUR_POS PROC | ||
| 197 | ; | ||
| 198 | PUSH AX | ||
| 199 | PUSH BX | ||
| 200 | PUSH CX | ||
| 201 | PUSH DX | ||
| 202 | PUSH SI | ||
| 203 | PUSH DI | ||
| 204 | PUSH DS ;SAVE REGISTERS | ||
| 205 | ; | ||
| 206 | PUSH CS | ||
| 207 | POP DS ;GET DS TO THIS CODE SEGMENT | ||
| 208 | ;MOVE CURSOR TO NEXT AVAILABLE LINE | ||
| 209 | ;IF DOS | ||
| 210 | ; MOV AH,9 ;DOS PRINT STRING | ||
| 211 | ; MOV DX,OFFSET NEXT_LINE + 1 ;OFFSET OF NEXT LINE MSG | ||
| 212 | ; INT 21H ;DISPLAY MESSAGE | ||
| 213 | ;ELSE | ||
| 214 | ; MOV BX,OFFSET NEXT_LINE ;GET OFFSET OF NEXT LINE MSG | ||
| 215 | ; MOV AH,0 ;TELL DCP TO DISPLAY | ||
| 216 | ; INT 82H ;DISPLAY MESSAGE | ||
| 217 | ;ENDIF | ||
| 218 | ; rsh001 fix scroll problem | ||
| 219 | ; and remove IF DOS crap | ||
| 220 | ;READ CURRENT VIDEO PAGE ; rsh001 | ||
| 221 | MOV AH,15 ;READ CURRENT Video Page | ||
| 222 | INT 10H ;VIDEO CALL | ||
| 223 | MOV ACTIVE_PAGE,BH ;SAVE ACTIVE PAGE | ||
| 224 | |||
| 225 | ;READ CURRENT CURSOR POSITION | ||
| 226 | MOV AH,3 ;READ CURRENT CURSOR POS | ||
| 227 | INT 10H ;VIDEO CALL | ||
| 228 | MOV CUR_SAVE,DX ;SAVE CURSOR POSITION | ||
| 229 | |||
| 230 | ;RESTORE ALL REGISTERS | ||
| 231 | POP DS | ||
| 232 | POP DI | ||
| 233 | POP SI | ||
| 234 | POP DX | ||
| 235 | POP CX | ||
| 236 | POP BX | ||
| 237 | POP AX ;RESTORE ALL REGISTERS | ||
| 238 | |||
| 239 | RET ;RETURN TO CALLER | ||
| 240 | |||
| 241 | CUR_POS ENDP | ||
| 242 | |||
| 243 | |||
| 244 | |||
| 245 | |||
| 246 | |||
| 247 | PAGE | ||
| 248 | ;------------------------------------------------------------------------- | ||
| 249 | ;------------------------------------------------------------------------- | ||
| 250 | ; | ||
| 251 | ; TEST FOR PRESENCE OF MORE THAN 1 MEGABYTE OF MEMORY | ||
| 252 | ; | ||
| 253 | ; DESCRIPTION : This routine will determine if the 2nd, 3rd or 4th MB is | ||
| 254 | ; installed. Since there are no switches or other indicators | ||
| 255 | ; to be tested, this test will make a "best guess" as to | ||
| 256 | ; the presence of this memory. This test will roll a 0 | ||
| 257 | ; and a 1 through the 1st word of the next Meg and if | ||
| 258 | ; at least 1 bit is consistently good then it is assumed | ||
| 259 | ; that the optional memory is installed. If successful | ||
| 260 | ; then try next Meg. | ||
| 261 | ; | ||
| 262 | ; FUNCTION/ : See description | ||
| 263 | ; PURPOSE | ||
| 264 | ; | ||
| 265 | ; ENTRY POINT : TRY4MEG | ||
| 266 | ; | ||
| 267 | ; ENTRY : none | ||
| 268 | ; CONDITIONS | ||
| 269 | ; | ||
| 270 | ; EXIT : | ||
| 271 | ; | ||
| 272 | ; AX,BX,CX,DX ARE DESTROYED | ||
| 273 | ;------------------------------------------------------------------------- | ||
| 274 | ; | ||
| 275 | TRY4MEG PROC | ||
| 276 | |||
| 277 | ;MEMORY TEST MUST RUN IN PAGE MODE | ||
| 278 | ;BEFORE CARD IS PUT INTO PAGE MODE...MUST SET UP XLAT TABLE TO PASSOVER | ||
| 279 | ;RESERVED MEMORY SPACES (IE.,BIOS, DISPLAY, DISTRIBUTED ROS, ETC) | ||
| 280 | ; | ||
| 281 | CALL VIRT2REAL | ||
| 282 | |||
| 283 | MOV DX,IDREG ;I/O TO ID REGISTER | ||
| 284 | MOV AL,0 ;ID = 0 | ||
| 285 | OUT DX,AL ;SWITCH TO ID = 0 | ||
| 286 | ; | ||
| 287 | ;DISABLE NMI AND ENABLE I/O CHANNEL CHECK | ||
| 288 | MOV AL,CS:MODEL ;GET SAVED MODEL BYTE | ||
| 289 | CMP AL,PC1 ;IS IT A PC1? | ||
| 290 | JE TR2M1 ;IF NO THEN TRY FOR PC_XT | ||
| 291 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 292 | JE TR2M1 ;IF NO THEN TRY FOR AQUARIUS | ||
| 293 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 294 | JE TR2M1 ;IF NO THEN USE AT NMI REGS | ||
| 295 | ;USE PC-AT NMI REGISTER | ||
| 296 | MOV DX,AT_NMI_REG ;AT's NMI REGISTER | ||
| 297 | MOV AL,AT_NMI_OFF ;MASK OFF NMI | ||
| 298 | OUT DX,AL ;OUTPUT IT | ||
| 299 | MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG | ||
| 300 | IN AL,DX ;READ IT | ||
| 301 | OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 302 | OUT DX,AL ;WRITE IT | ||
| 303 | AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 304 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 305 | ;ENABLED | ||
| 306 | ;USE PC1, XT, AQUARIUS REGISTERS | ||
| 307 | TR2M1: | ||
| 308 | MOV DX,XT_NMI_REG ;XT's NMI REGISTER | ||
| 309 | MOV AL,XT_NMI_OFF ;MASK OFF NMI | ||
| 310 | OUT DX,AL ;OUTPUT IT | ||
| 311 | MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG | ||
| 312 | IN AL,DX ;READ IT | ||
| 313 | OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 314 | OUT DX,AL ;WRITE IT | ||
| 315 | AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 316 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 317 | ;ENABLED | ||
| 318 | ; | ||
| 319 | ;MAP FIRST 64K OF 2ND MEG INTO PC SPACE BEGINNING AT 512K | ||
| 320 | ;***jnw MOV CX,3 ;LOOK FOR PRESENCE OF NEXT 3 MB IN 1MB STEPS | ||
| 321 | MOV CX,99*1024/16 ;***jnw ;LOOK FOR PRESENCE OF NEXT n MB IN 1MB STEPS | ||
| 322 | MOV AX,CS:PAGE_FRAME_STA ;SEGMENT AT PAGE FRAME | ||
| 323 | ;***jnw MOV DX,256 ;BEGINNING AT 2ND MEG OF XMA | ||
| 324 | MOV DX,256+3 ;***jnw ;AT end of 16k | ||
| 325 | MOV BH,0 ;ASSIGNED TO TASK ID 0 | ||
| 326 | MOV BL,01H ;ENABLE THIS MEMORY | ||
| 327 | TR2M1A: | ||
| 328 | PUSH AX | ||
| 329 | PUSH BX | ||
| 330 | PUSH CX | ||
| 331 | PUSH DX | ||
| 332 | ;***jnw MOV CX,16 ;16 * 4K = 64K BLOCK | ||
| 333 | MOV CX,1 ;***jnw ;1 * 4K = 4K BLOCK | ||
| 334 | CALL SETXLAT ;SET TRANSLATE TABLE | ||
| 335 | ; | ||
| 336 | MOV AX,CS:PAGE_FRAME_STA | ||
| 337 | MOV DS,AX ;SET SEGMENT AND | ||
| 338 | MOV SI,0 ;OFFSET TO TEST | ||
| 339 | MOV BX,0000000000000001B ;ROLL 1 THROUGH WORD | ||
| 340 | MOV DX,1111111111111110B ;ROLL 0 THROUGH WORD | ||
| 341 | MOV CX,16 ;16 BITS TO TEST | ||
| 342 | TR2M2: | ||
| 343 | MOV [SI],BX ;WRITE ROLLING 1 PATTERN | ||
| 344 | LOCK MOV [SI+2],DX ;CHARGE BUS INVERSE PATTERN | ||
| 345 | LOCK MOV AX,[SI] ;READ BACK INITIAL PATTERN | ||
| 346 | AND AX,BX ;ISOLATE BIT UNDER TEST | ||
| 347 | ;***jnw JZ TR2M3 ;IF ZERO TRY ANOTHER BIT | ||
| 348 | JZ quit ;IF ZERO quit ***jnw | ||
| 349 | MOV [SI],DX ;WRITE ROLLING 0 PATTERN | ||
| 350 | LOCK MOV [SI+2],BX ;CHARGE BUS INVERSE PATTERN | ||
| 351 | LOCK MOV AX,[SI] ;READ BACK INITIAL PATTERN | ||
| 352 | AND AX,BX ;ISOLATE BIT UNDER TEST | ||
| 353 | AND AX,BX ;ISOLATE BIT UNDER TEST | ||
| 354 | ;***jnw JZ TR2M4 ;IF ZERO THEN FOUND GOOD BIT | ||
| 355 | Jnz quit ;IF nonzero then quit ***jnw | ||
| 356 | TR2M3: | ||
| 357 | ROL BX,1 ;ROLL 1 TO NEXT POSITION | ||
| 358 | ROL DX,1 ;ROLL 0 TO NEXT POSITION | ||
| 359 | LOOP TR2M2 ;REPEAT FOR 16 BITS | ||
| 360 | jmp tr2m4 ;all 16 bits passed test ***jnw | ||
| 361 | quit: ;***jnw | ||
| 362 | ;AT THIS POINT THERE ARE NO GOOD BITS SO END SEARCH FOR NEXT MB | ||
| 363 | POP DX ;RECOVER THESES REGISTERS | ||
| 364 | POP CX | ||
| 365 | POP BX | ||
| 366 | POP AX | ||
| 367 | JMP TR2M5 ;EXIT | ||
| 368 | ;AT THIS POINT WE KNOW THERE IS MEMORY IN THIS MEG THAT WAS JUST TESTED | ||
| 369 | TR2M4: | ||
| 370 | ;***jnw ADD CS:MEM_INST,1 ;ADD 1 MB TO THIS FLAG | ||
| 371 | ;***jnw ADD CS:TOTAL_XMA_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG | ||
| 372 | ;***jnw ADD CS:TOTAL_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG | ||
| 373 | ;***jnw ADD CS:FREE_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG | ||
| 374 | ADD CS:TOTAL_XMA_PAGES,1 ;Add 16k ***jnw | ||
| 375 | ADD CS:TOTAL_PAGES,1 ;Add 16k ***jnw | ||
| 376 | ADD CS:FREE_PAGES,1 ;Add 16k ***jnw | ||
| 377 | POP DX ;RECOVER THESE REGISTERS | ||
| 378 | POP CX | ||
| 379 | POP BX | ||
| 380 | POP AX | ||
| 381 | ;***jnw ADD DX,256 ;TRY NEXT MB | ||
| 382 | ADD DX,4 ;TRY NEXT 16k ***jnw | ||
| 383 | LOOP TR2M1A ;REPEAT LOOP | ||
| 384 | TR2M5: | ||
| 385 | ;BEFORE NMI IS ENABLED, CLEAR PARITY CHECK LATCH ON XMA | ||
| 386 | MOV SI,0 | ||
| 387 | MOV AX,[SI] ;READ 1ST WORD OF THIS SEG | ||
| 388 | MOV [SI],AX ;WRITE BACK SAME WORD | ||
| 389 | ;THE WRITE WILL CLEAR PCHK LTCH | ||
| 390 | ;PUT THE XMA CARD BACK INTO REAL MODE | ||
| 391 | MOV DX,MODE_REG ;READY FOR I/O TO MODE REG | ||
| 392 | IN AL,DX ;READ IT | ||
| 393 | AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT | ||
| 394 | OUT DX,AL ;WRITE IT TO MODE REG | ||
| 395 | ;CLEAR I/O CHANNEL CHECK LATCHES AND ENABLE NMI | ||
| 396 | MOV AL,CS:MODEL ;GET SAVED MODEL BYTE | ||
| 397 | CMP AL,PC1 ;IS IT A PC1? | ||
| 398 | JE TR2M6 ;USE XT REGISTERS | ||
| 399 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 400 | JE TR2M6 ;USE XT REGISTERS | ||
| 401 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 402 | JE TR2M6 ;USE XT REGISTERS | ||
| 403 | ;IF NONE OF THE ABOVE THEN... | ||
| 404 | ;USE AT NMI REGISTER | ||
| 405 | MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG | ||
| 406 | IN AL,DX ;READ IT | ||
| 407 | OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 408 | OUT DX,AL ;WRITE IT | ||
| 409 | AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 410 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 411 | ;ENABLED | ||
| 412 | MOV DX,AT_NMI_REG ;AT's NMI REGISTER | ||
| 413 | MOV AL,AT_NMI_ON ;MASK ON NMI | ||
| 414 | OUT DX,AL ;OUTPUT IT | ||
| 415 | ;USE XT/AQUARIUS NMI REGISTER | ||
| 416 | TR2M6: | ||
| 417 | MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG | ||
| 418 | IN AL,DX ;READ IT | ||
| 419 | OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 420 | OUT DX,AL ;WRITE IT | ||
| 421 | AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 422 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 423 | ;ENABLED | ||
| 424 | MOV DX,XT_NMI_REG ;XT's NMI REGISTER | ||
| 425 | MOV AL,XT_NMI_ON ;MASK ON NMI | ||
| 426 | OUT DX,AL ;OUTPUT IT | ||
| 427 | ; | ||
| 428 | RET ;RETURN TO CALLER | ||
| 429 | |||
| 430 | TRY4MEG ENDP | ||
| 431 | |||
| 432 | |||
| 433 | PAGE | ||
| 434 | ;------------------------------------------------------------------------- | ||
| 435 | ;------------------------------------------------------------------------- | ||
| 436 | ; | ||
| 437 | ; REGISTER TESTS | ||
| 438 | ; | ||
| 439 | ; DESCRIPTION : This routine will test the following subset | ||
| 440 | ; of XMA registers: | ||
| 441 | ; 31A0...8 bits | ||
| 442 | ; 31A1...4 bits | ||
| 443 | ; 31A6...4 bits | ||
| 444 | ; 31A7...4 bits (BIT 1 IS HELD LOW TO DISABLE | ||
| 445 | ; THE VIRTUAL MODE) | ||
| 446 | ; | ||
| 447 | ; The test is performed by writing and reading | ||
| 448 | ; AA, 55, FF, 00 from each of the above locations. | ||
| 449 | ; | ||
| 450 | ; NOTE: Regs 31A6 and 31A7 should always return 0 in | ||
| 451 | ; the high nibble. | ||
| 452 | ; | ||
| 453 | ; The remainding registers will be tested in | ||
| 454 | ; subsequent routines. | ||
| 455 | ; | ||
| 456 | ; | ||
| 457 | ; FUNCTION/ : To ensure integrity of XMA registers that will be used | ||
| 458 | ; PURPOSE in subsequent routines. | ||
| 459 | ; | ||
| 460 | ; ENTRY POINT : REGTST | ||
| 461 | ; | ||
| 462 | ; ENTRY : none | ||
| 463 | ; CONDITIONS | ||
| 464 | ; | ||
| 465 | ; EXIT : XMA registers are set to zero | ||
| 466 | ; | ||
| 467 | ; (zero flag) = 0 indicates an error | ||
| 468 | ; (DX) failing register | ||
| 469 | ; (AL) expected data XOR'ed with actual data | ||
| 470 | ; | ||
| 471 | ;------------------------------------------------------------------------- | ||
| 472 | ; | ||
| 473 | REGTST PROC | ||
| 474 | ; | ||
| 475 | MOV AL,REG_TEST | ||
| 476 | MOV CS:TEST_ID,AL | ||
| 477 | |||
| 478 | ;SAVE CONTENTS OF MODE REG | ||
| 479 | MOV DX,MODE_REG | ||
| 480 | IN AL,DX | ||
| 481 | PUSH AX | ||
| 482 | |||
| 483 | ; TRANSLATE TABLE ADDRESS AND DATA REGISTERS | ||
| 484 | ; | ||
| 485 | MOV BX,0AA55H ;SET UP INITIAL DATA PATTERN | ||
| 486 | MOV AX,BX | ||
| 487 | MOV CX,BX | ||
| 488 | |||
| 489 | R1: | ||
| 490 | MOV DX,BASE_REG ;FIRST REGISTER PAIR TO WRITE | ||
| 491 | |||
| 492 | OUT DX,AX ;WRITE PATTERN TO REGS | ||
| 493 | ADD DX,6 ;POINT TO NEXT REG PAIR | ||
| 494 | XCHG AL,AH ;SETUP INVERSE PATTERN | ||
| 495 | AND AH,11111101B ;MASK OFF BIT 1 | ||
| 496 | OUT DX,AX ;BECAUSE AH -> 21B7 | ||
| 497 | R2: | ||
| 498 | SUB DX,6 ;POINT TO FIRST REGISTER PAIR | ||
| 499 | IN AX,DX ;READ REGISTER (21B1 -> AH) | ||
| 500 | XOR AX,BX ;DATA READ AS EXPECTED ? | ||
| 501 | AND AX,0FFFH ;MASK OFF UPPER NIBBLE OF 21B1 | ||
| 502 | JNE R_ERROR ;MISMATCH - GO TO ERROR ROUTINE | ||
| 503 | XCHG BH,BL ;NEXT PATTERN TO TEST | ||
| 504 | AND BX,0F0FH ;REGS RETURN 0 IN HI NIBBLE | ||
| 505 | ADD DX,6 ;POINT TO NEXT REGISTER PAIR | ||
| 506 | IN AX,DX ;READ IT (21B7 -> AH) | ||
| 507 | XOR AX,BX ;DATA READ AS EXPECTED ? | ||
| 508 | AND AX,0DFFH ;MASK OFF BIT 1 IN REG 21B7 | ||
| 509 | JNE R_ERROR ;MISMATCH - GO TO ERROR ROUTINE | ||
| 510 | ; | ||
| 511 | CMP CH,CL ;LAST PASS ? | ||
| 512 | JE R_EXIT ;YES - THEN EXIT REG TEST | ||
| 513 | ; | ||
| 514 | CMP CX,055AAH ;END OF AA55,55AA PATTERNS? | ||
| 515 | JNE R3 ; | ||
| 516 | MOV CX,000FFH ;SET UP NEXT VALUE TO WRITE | ||
| 517 | JMP R4 | ||
| 518 | R3: | ||
| 519 | CMP CX,00FFH ;END OF FF00,00FF PATTERNS? | ||
| 520 | JNE R4 ; | ||
| 521 | MOV CX,0 ;YES, THEN SET UP FOR LAST PASS | ||
| 522 | R4: | ||
| 523 | XCHG CL,CH ;SET UP INVERSE PATTERN | ||
| 524 | MOV AX,CX ;SAVE IT | ||
| 525 | MOV BX,CX ;SAVE IT | ||
| 526 | R5: | ||
| 527 | JMP R1 ;CONTINUE TILL ZERO PATTERN | ||
| 528 | |||
| 529 | R_ERROR: | ||
| 530 | R_EXIT: | ||
| 531 | POP AX | ||
| 532 | MOV DX,MODE_REG | ||
| 533 | OUT DX,AL ;restore mode reg | ||
| 534 | RET | ||
| 535 | ; | ||
| 536 | REGTST ENDP | ||
| 537 | |||
| 538 | |||
| 539 | |||
| 540 | |||
| 541 | PAGE | ||
| 542 | ;------------------------------------------------------------------------- | ||
| 543 | ;------------------------------------------------------------------------- | ||
| 544 | ; | ||
| 545 | ; MEMORY ARRAY TEST | ||
| 546 | ; | ||
| 547 | ; DESCRIPTION : This routine test all 1Meg (or 2Meg) of XMA memory | ||
| 548 | ; through a 64K window in PC space beginning at PF:0 | ||
| 549 | ; (where PF is the Page Frame Segment) | ||
| 550 | ; This module looks at TOTAL_XMA_PAGES | ||
| 551 | ; to determine the memory size to be tested. | ||
| 552 | ; | ||
| 553 | ; (i) write the Translate Table for the 1st 64K block | ||
| 554 | ; of XMA memory to be mapped into PF:0 in PC space | ||
| 555 | ; (ii) test PF:0 to PF:FFFF | ||
| 556 | ; (iii) if good...write Translate Table to map next 64K block | ||
| 557 | ; into PF:0 | ||
| 558 | ; (iv) repeat 'till all XMA memory is tested | ||
| 559 | ; | ||
| 560 | ; FUNCTION/ : See description | ||
| 561 | ; PURPOSE | ||
| 562 | ; | ||
| 563 | ; | ||
| 564 | ; ENTRY POINT : MEMARRAY | ||
| 565 | ; | ||
| 566 | ; ENTRY : | ||
| 567 | ; CONDITIONS | ||
| 568 | ; | ||
| 569 | ; EXIT : All SMAS memory is set to zero. | ||
| 570 | ; | ||
| 571 | ; (zero flag) = 0 if storage error | ||
| 572 | ; (AX) expected data XOR'ed with actual data | ||
| 573 | ; if AX = 0 and ZF = 0 then parity error | ||
| 574 | ; DS:SI point to failing location | ||
| 575 | ; CS:PAGE_UNDER_TEST point failing 64k block | ||
| 576 | ; | ||
| 577 | ; AX,BX,CX,DX,DS,ES,SI,DI ARE DESTROYED | ||
| 578 | ; | ||
| 579 | ;------------------------------------------------------------------------- | ||
| 580 | |||
| 581 | MEMARRAY PROC | ||
| 582 | |||
| 583 | MOV AL,MEM_TEST | ||
| 584 | MOV CS:TEST_ID,AL | ||
| 585 | |||
| 586 | ;MEMORY TEST MUST RUN IN PAGE MODE | ||
| 587 | |||
| 588 | CALL VIRT2REAL | ||
| 589 | |||
| 590 | ;INDICATE 0 KB OK | ||
| 591 | MOV DX,(640-64)/4 ;CODE FOR 640 KB OK | ||
| 592 | CALL KB_OK | ||
| 593 | ;SETUP FOR TEST OF SMAS MEMORY ARRAY | ||
| 594 | MOV AX,CS:PAGE_FRAME_STA ;PAGE MEMORY FROM THIS SEGMENT | ||
| 595 | MOV ES,AX ;SET UP DEST SEG | ||
| 596 | MOV DS,AX ;SET UP SOURCE SEG | ||
| 597 | MOV BL,01H ;ENABLE THIS BLOCK OF MEMORY | ||
| 598 | MOV BH,0 ;USING ID 0 | ||
| 599 | MOV DX,(640)/4 ;STARTING BLK IN SMAS ARRAY | ||
| 600 | ;DETERMINE HOW MUCH MEMORY TO TEST | ||
| 601 | MOV CX,CS:TOTAL_XMA_PAGES ;GET NUMBER OF 16K PAGES | ||
| 602 | SHR CX,1 ;CONVERT TO NUMBER | ||
| 603 | SHR CX,1 ; OF 64K SEGMENTS | ||
| 604 | SUB CX,640/64 ;SUBTRACT OFF 1ST 640K MEMORY | ||
| 605 | ;BEGIN TEST | ||
| 606 | MA1: | ||
| 607 | MOV CS:PAGE_UNDER_TEST,DX ;INDICATE WHICH 64K BLOCK | ||
| 608 | PUSH AX ;IS UNDER TEST | ||
| 609 | PUSH BX | ||
| 610 | PUSH CX | ||
| 611 | PUSH DX ;SAVE ALL REGISTERS | ||
| 612 | ; | ||
| 613 | MOV CX,16 ;TEST 64K AT ONE TIME | ||
| 614 | ;16 x 4K = 64K | ||
| 615 | CALL SETXLAT ;SET UP XLAT TABLE | ||
| 616 | CALL STGTST ;TEST 64K OF STORAGE | ||
| 617 | JNZ MA2 ;WAS THERE AN ERROR | ||
| 618 | POP DX | ||
| 619 | POP CX | ||
| 620 | POP BX | ||
| 621 | POP AX ;RESTORE REGISTERS | ||
| 622 | ; | ||
| 623 | PUSHF ;SAVE FLAGS FOR ADDITION | ||
| 624 | |||
| 625 | CALL KB_OK ;INDICATE HOW MUCH | ||
| 626 | ;MEMORY HAS BEEN TESTED | ||
| 627 | |||
| 628 | |||
| 629 | ADD DX,16 ;POINT TO NEXT 64K BLOCK | ||
| 630 | POPF ;RESTORE FLAGS | ||
| 631 | LOOP MA1 ;LOOP FOR NEXT 64K | ||
| 632 | JMP MA3 ;EXIT WHEN COMPLETE | ||
| 633 | MA2: | ||
| 634 | POP DX | ||
| 635 | POP CX | ||
| 636 | POP BX ;BX IS POPPED TWICE | ||
| 637 | POP BX ;TO RESTORE STACK WHILE | ||
| 638 | ;MAINTAINING AX | ||
| 639 | MA3: | ||
| 640 | PUSH AX | ||
| 641 | PUSH DX | ||
| 642 | PUSHF ;SAVE THESE REGS...THEY CONTAIN | ||
| 643 | ;USEFULL ERROR INFO | ||
| 644 | ;PUT THE SMAS CARD INTO REAL MODE | ||
| 645 | MOV DX,MODE_REG ;READY FOR I/O TO MODE REG | ||
| 646 | IN AL,DX ;READ IT | ||
| 647 | AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT | ||
| 648 | OUT DX,AL ;WRITE IT TO MODE REG | ||
| 649 | POPF | ||
| 650 | POP DX | ||
| 651 | POP AX ;RESTORE THESE REGS | ||
| 652 | RET | ||
| 653 | ; | ||
| 654 | MEMARRAY ENDP | ||
| 655 | |||
| 656 | |||
| 657 | |||
| 658 | |||
| 659 | PAGE | ||
| 660 | ;--------------------------------------------------------------------- | ||
| 661 | ;--------------------------------------------------------------------- | ||
| 662 | ; LO MEMORY TEST | ||
| 663 | ; | ||
| 664 | ; DESCRIPTION : This routine tests the first 256K or 512K | ||
| 665 | ; of XMA memory depending on the starting | ||
| 666 | ; position of the starting address jumper on | ||
| 667 | ; the card. The memory that is used to | ||
| 668 | ; fill conventional memory space is not tested | ||
| 669 | ; it is tested during POST and may now contain | ||
| 670 | ; parts of COMMAND.COM. | ||
| 671 | ; | ||
| 672 | ; FUNCTION/ : See description | ||
| 673 | ; PURPOSE | ||
| 674 | ; | ||
| 675 | ; ENTRY POINT : LOMEMTST | ||
| 676 | ; | ||
| 677 | ; ENTRY : | ||
| 678 | ; CONDITIONS | ||
| 679 | ; | ||
| 680 | ; EXIT : All tested memory is set to zero | ||
| 681 | ; | ||
| 682 | ; (zero flag) = 0 if storage error | ||
| 683 | ; (AX) = expected data XOR'ed with actual data | ||
| 684 | ; if (AX)=0 and ZF=0 then parity error | ||
| 685 | ; DS:SI point to failing location | ||
| 686 | ; CS:PAGE_UNDER_TEST point to failing 64K block | ||
| 687 | ; | ||
| 688 | ; AX,BX,CX,DX,DI,SI,ES,DS ARE DESTROYED | ||
| 689 | ; | ||
| 690 | ;----------------------------------------------------------------------- | ||
| 691 | LOMEMTST PROC | ||
| 692 | |||
| 693 | MOV AL,LOMEM_TEST | ||
| 694 | MOV CS:TEST_ID,AL | ||
| 695 | |||
| 696 | ;MEMORY TEST MUST RUN IN PAGE MODE | ||
| 697 | CALL VIRT2REAL | ||
| 698 | |||
| 699 | ;INDICATE 0 KB OK AT START OF TEST | ||
| 700 | MOV DX,0FFF0H ;code for initial 0 kb | ||
| 701 | CALL KB_OK | ||
| 702 | |||
| 703 | ;DETERMINE HOW MUCH MEMORY TO TEST | ||
| 704 | MOV AX,CS:START_FILL ;get starting fill segment | ||
| 705 | XCHG AH,AL | ||
| 706 | MOV CL,4 | ||
| 707 | SHR AX,CL ;convert to 64k block number | ||
| 708 | MOV CS:TESTABLE_SEGMENTS,AX ;save...this is number of 64k blocks | ||
| 709 | ;that can be tested without | ||
| 710 | ;destroying DOS | ||
| 711 | ;SET UP FOR TEST OF XMA MEMORY | ||
| 712 | MOV AX,CS:PAGE_FRAME_STA ;test through page frame | ||
| 713 | MOV DS,AX ;set up ds | ||
| 714 | MOV ES,AX ;and es | ||
| 715 | MOV BL,01H ;enable this block of memory | ||
| 716 | MOV BH,0 ;using id=0 | ||
| 717 | XOR DX,DX ;start at block 0 in xma | ||
| 718 | MOV CX,640/64 ;loop counter is # 64k blocks in | ||
| 719 | ;conventional memory | ||
| 720 | LM1: | ||
| 721 | MOV CS:PAGE_UNDER_TEST,DX ;save page under test | ||
| 722 | PUSH AX | ||
| 723 | PUSH BX | ||
| 724 | PUSH CX | ||
| 725 | PUSH DX ;save these registers | ||
| 726 | |||
| 727 | MOV CX,16 ;test 64k at one time | ||
| 728 | ;16 * 4k = 64k | ||
| 729 | CALL SETXLAT ;set translate table | ||
| 730 | CMP CS:TESTABLE_SEGMENTS,0 ;if this segment under test is used for | ||
| 731 | ;fill then read only | ||
| 732 | JG LM2 ;else do storage test | ||
| 733 | CALL READ_ONLY | ||
| 734 | JMP LM3 | ||
| 735 | LM2: | ||
| 736 | CALL STGTST | ||
| 737 | LM3: | ||
| 738 | JNZ LM4 ;jump if there was an error | ||
| 739 | POP DX | ||
| 740 | POP CX | ||
| 741 | POP BX | ||
| 742 | POP AX ;recover registers | ||
| 743 | |||
| 744 | PUSHF ;save flags for addition | ||
| 745 | CALL KB_OK | ||
| 746 | ;indicate kb ok | ||
| 747 | ADD DX,16 ;next 64k block | ||
| 748 | DEC CS:TESTABLE_SEGMENTS ;dec testable pages | ||
| 749 | POPF ;recover flags | ||
| 750 | LOOP LM1 ;repeat for next 64k block | ||
| 751 | JMP LM5 ;exit when complete | ||
| 752 | LM4: | ||
| 753 | POP DX ;recover these registers | ||
| 754 | POP CX | ||
| 755 | POP BX ;bx is popped twice to restore | ||
| 756 | POP BX ;satck while maintaining ax | ||
| 757 | LM5: | ||
| 758 | PUSH AX ;save these ... they contain | ||
| 759 | PUSH DX ;useful error information | ||
| 760 | PUSHF | ||
| 761 | ;PUT CARD BACK TO REAL MODE | ||
| 762 | MOV DX,MODE_REG ;read mode reg | ||
| 763 | IN AL,DX | ||
| 764 | AND AL,REAL_MODE ;turn off virtual bit | ||
| 765 | OUT DX,AL ;write it to mode reg | ||
| 766 | POPF | ||
| 767 | POP DX | ||
| 768 | POP AX ;restore these registers | ||
| 769 | RET | ||
| 770 | |||
| 771 | |||
| 772 | READ_ONLY PROC ;INTERNAL PROC TO READ MEMORY WITHOUT DESTROYING CONTENTS | ||
| 773 | XOR SI,SI ;start of segment | ||
| 774 | XOR CX,CX ;test 64k | ||
| 775 | |||
| 776 | LODSW ;just read each byte | ||
| 777 | XOR AX,AX ;and set zf=1 for return | ||
| 778 | RET ;back to caller | ||
| 779 | READ_ONLY ENDP | ||
| 780 | |||
| 781 | LOMEMTST ENDP | ||
| 782 | |||
| 783 | |||
| 784 | |||
| 785 | PAGE | ||
| 786 | ;------------------------------------------------------------------------- | ||
| 787 | ;------------------------------------------------------------------------- | ||
| 788 | ; | ||
| 789 | ; PAGE TEST | ||
| 790 | ; | ||
| 791 | ; DESCRIPTION : This routine tests that the TASK ID register is | ||
| 792 | ; actually paging in unique segments of memory. | ||
| 793 | ; The test is performed through the page frame segment. | ||
| 794 | ; The test assumes that the memory test has already | ||
| 795 | ; completed successfully. The page test procedes as | ||
| 796 | ; follows: | ||
| 797 | ; (i) 6-64K blocks of XMA memory are mapped into a | ||
| 798 | ; 64K segment of PC space (the page frame) | ||
| 799 | ; These XMA blocks are from 640k to 1024k of XMA memory. | ||
| 800 | ; (ii) Each of these blocks is assigned to a unique | ||
| 801 | ; task ID ranging from 0 to 5. | ||
| 802 | ; (iii) For each task ID, the page frame is filled with | ||
| 803 | ; a pattern that is the same as the task ID. | ||
| 804 | ; (iv) The page frame is then read for each task ID | ||
| 805 | ; and compared with the expected data. | ||
| 806 | ; | ||
| 807 | ; FUNCTION/ : | ||
| 808 | ; PURPOSE | ||
| 809 | ; | ||
| 810 | ; ENTRY POINT : PAGETST | ||
| 811 | ; | ||
| 812 | ; ENTRY : NONE | ||
| 813 | ; CONDITIONS | ||
| 814 | ; | ||
| 815 | ; EXIT : (zero flag) = 0 indicates an error | ||
| 816 | ; (AL) expected data XOR'ed with actual data | ||
| 817 | ; | ||
| 818 | ; AX,BX,CX,DX,ES,DS,SI,DI ARE DESTROYED | ||
| 819 | ;------------------------------------------------------------------------- | ||
| 820 | ; | ||
| 821 | PAGETST PROC | ||
| 822 | ; | ||
| 823 | MOV AL,PAGE_TEST | ||
| 824 | MOV CS:TEST_ID,AL | ||
| 825 | ;MEMORY TEST MUST RUN IN PAGE MODE | ||
| 826 | CALL VIRT2REAL | ||
| 827 | ;INITIALIZE TRANSLATE TABLE FOR THIS TEST | ||
| 828 | MOV AX,CS:PAGE_FRAME_STA ;SEMENT OF PAGE FRAME | ||
| 829 | MOV BL,01H ;ENABLE CODE | ||
| 830 | MOV BH,0 ;START WITH TASK ID = 0 | ||
| 831 | MOV DX,640/4 ;START WITH XMA BLOCK 160 | ||
| 832 | MOV CX,6 ;LOOP COUNT...6 TASK ID's | ||
| 833 | ;EACH TASK ID IS ASSIGNED 64K | ||
| 834 | ;FROM 640K TO 1024K | ||
| 835 | PT1: | ||
| 836 | PUSH AX | ||
| 837 | PUSH BX | ||
| 838 | PUSH CX | ||
| 839 | PUSH DX ;SAVE ALL REGISTERS | ||
| 840 | ; | ||
| 841 | MOV CX,16 ;16-4K BLOCKS IN 64K | ||
| 842 | CALL SETXLAT ;SET TRANSLATE TABLE | ||
| 843 | POP DX | ||
| 844 | POP CX | ||
| 845 | POP BX | ||
| 846 | POP AX ;RECOVER ALL | ||
| 847 | INC BH ;POINT TO NEXT TASK ID | ||
| 848 | ADD DX,16 ;NEXT 64K IN XMA MEMORY | ||
| 849 | LOOP PT1 ;REPEAT FOR ALL TASK ID's | ||
| 850 | ;FILL MEMORY WITH A UNIQUE PATTERN FOR EACH TASK ID | ||
| 851 | MOV CX,6 ;6 TASK ID's | ||
| 852 | MOV DX,IDREG ;READY FOR I/O TO TASK ID REG | ||
| 853 | MOV AL,0 ;START WITH ID = 0 | ||
| 854 | PT2: | ||
| 855 | PUSH AX ;SAVE ID NUMBER | ||
| 856 | PUSH CX ;SAVE ID COUNT | ||
| 857 | OUT DX,AL ;SWITCH TASK ID | ||
| 858 | MOV BX,CS:PAGE_FRAME_STA | ||
| 859 | MOV ES,BX ;SEGMENT TO 1ST 64K 0F ID | ||
| 860 | SUB DI,DI ;POINT TO 1ST LOCATION | ||
| 861 | XOR CX,CX ;WRITE ALL 64K LOCATIONS | ||
| 862 | PT2X: | ||
| 863 | STOSB | ||
| 864 | LOOP PT2X | ||
| 865 | POP CX ;RECOVER ID COUNT | ||
| 866 | POP AX ;RECOVER CURRENT ID | ||
| 867 | INC AL | ||
| 868 | LOOP PT2 ;REPEAT FOR ALL TASK ID's | ||
| 869 | ;NOW CHECK THAT THERE ARE 16 UNIQUE PATTERNS IN MEMORY | ||
| 870 | MOV CX,6 ;USE 6 TASK ID's | ||
| 871 | MOV AH,0 ;START WITH ID = 0 | ||
| 872 | PT3: | ||
| 873 | MOV AL,AH ;GET TASK ID IN AL | ||
| 874 | PUSH AX | ||
| 875 | PUSH CX ;SAVE ID COUNT | ||
| 876 | OUT DX,AL ;SWITCH TASK ID | ||
| 877 | MOV BX,CS:PAGE_FRAME_STA | ||
| 878 | MOV DS,BX | ||
| 879 | MOV ES,BX ;SEGMENT AT 1ST 64K | ||
| 880 | SUB DI,DI ;POINT TO 1ST LOCATION | ||
| 881 | SUB SI,SI ;POINT TO 1ST LOCATION | ||
| 882 | XOR CX,CX ;READ ALL 64K LOCATIONS | ||
| 883 | PT3X: | ||
| 884 | LODSB | ||
| 885 | XOR AL,AH ;DATA AS EXPECTED ? | ||
| 886 | JNE PT4X ;NO - THEN EXIT | ||
| 887 | STOSB ;AL SHOULD CONTAIN 0...WRITE IT | ||
| 888 | LOOP PT3X | ||
| 889 | |||
| 890 | POP CX ;RECOVER ID COUNT | ||
| 891 | POP AX | ||
| 892 | INC AH ;NEXT TASK ID | ||
| 893 | LOOP PT3 ;REPEAT FOR ALL TASK ID's | ||
| 894 | XOR AL,AL ;IF WE GOT THIS FAR THEN | ||
| 895 | ;NO ERRORS...SET ZF TO | ||
| 896 | ;INDICATE SUCCESS | ||
| 897 | PT4: | ||
| 898 | PUSH AX | ||
| 899 | PUSH DX | ||
| 900 | PUSHF ;SAVE THESE REGS...THEY CONTAIN | ||
| 901 | ;USEFULL ERROR INFO | ||
| 902 | ;PUT THE SMAS CARD INTO REAL MODE | ||
| 903 | MOV DX,MODE_REG ;READY FOR I/O TO MODE REG | ||
| 904 | IN AL,DX ;READ IT | ||
| 905 | AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT | ||
| 906 | OUT DX,AL ;WRITE IT TO MODE REG | ||
| 907 | ;MAKE SURE WE EXIT WHILE IN TASK ID=0 | ||
| 908 | MOV DX,IDREG | ||
| 909 | XOR AL,AL | ||
| 910 | OUT DX,AL | ||
| 911 | |||
| 912 | POPF | ||
| 913 | POP DX | ||
| 914 | POP AX ;RESTORE THESE REGS | ||
| 915 | RET ;RETURN TO CALLER | ||
| 916 | PT4X: | ||
| 917 | POP CX ;ALTERNATE RETURN PATH | ||
| 918 | POP AX | ||
| 919 | JMP PT4 ;TO ADJUST STACK | ||
| 920 | ; | ||
| 921 | PAGETST ENDP | ||
| 922 | |||
| 923 | |||
| 924 | PAGE | ||
| 925 | ;------------------------------------------------------------------------- | ||
| 926 | ;------------------------------------------------------------------------- | ||
| 927 | ; | ||
| 928 | ; DMA CAPTURE TEST | ||
| 929 | ; | ||
| 930 | ; DESCRIPTION : This routine is a test of the DMA capture logic. | ||
| 931 | ; The test is as follows: | ||
| 932 | ; (i) A bit is rolled through the second entry in the | ||
| 933 | ; DMA cature register file. (The first entry is used | ||
| 934 | ; for refresh on a PC-XT). | ||
| 935 | ; (ii) A bit and address test is performed on the | ||
| 936 | ; remainder of the register file(s). | ||
| 937 | ; (iii) A test is made for the capture of both REQUEST and | ||
| 938 | ; MODE registers of the DMA controller. | ||
| 939 | ; (iv) DMA channel 0 is tested only on the PC-AT | ||
| 940 | ; | ||
| 941 | ; | ||
| 942 | ; FUNCTION/ : To verify the functionality of the DMA capture logic. | ||
| 943 | ; PURPOSE | ||
| 944 | ; | ||
| 945 | ; ENTRY POINT : CAPTST | ||
| 946 | ; | ||
| 947 | ; ENTRY : NONE | ||
| 948 | ; CONDITIONS | ||
| 949 | ; | ||
| 950 | ; EXIT : Each entry in the DMA capture register file is set to 0. | ||
| 951 | ; | ||
| 952 | ; (zero flag) = 0 indicates an error | ||
| 953 | ; '31A8'X points to failing DMA capture reg | ||
| 954 | ; (AL) expected data XOR'ed with actual data | ||
| 955 | ; | ||
| 956 | ; AX,BX,CX,DX,SI,DI ARE DESTROYED | ||
| 957 | ;------------------------------------------------------------------------- | ||
| 958 | ; | ||
| 959 | ; | ||
| 960 | CAPTST PROC | ||
| 961 | ; | ||
| 962 | MOV AL,DMA_CAPTURE | ||
| 963 | MOV CS:TEST_ID,AL | ||
| 964 | ; | ||
| 965 | ;ROLL A BIT THROUGH THE SECOND ENTRY IN THE DMA CAPTURE REGISTER FILE | ||
| 966 | ; | ||
| 967 | MOV BL,01H ;SET UP INITIAL PATTERN | ||
| 968 | MOV BH,01H ;SET UP DMA CHANNEL 1 | ||
| 969 | MOV DI,DMACAPT ;SAVE FOR I/O TO DMA CAPTURE REG | ||
| 970 | MOV SI,DMAREQ1 ;SAVE FOR I/O TO DMA CTRL 1 REQ REG | ||
| 971 | MOV CX,4 ;ROLL 4 BIT POSITIONS | ||
| 972 | C1: | ||
| 973 | MOV DX,IDREG ;I/O TO ID REG | ||
| 974 | MOV AL,BL ;PATTERN TO WRITE | ||
| 975 | OUT DX,AX ;SETUP ID REG WITH DATA PATTERN | ||
| 976 | MOV DX,SI ;DMA CTRL 1 | ||
| 977 | MOV AL,BH ;CHANNEL 1 | ||
| 978 | OUT DX,AL ;SETUP DMA CH 1...CAPT ID IN 2nd ENTRY | ||
| 979 | MOV DX,DI ;DMA CAPTURE REG | ||
| 980 | OUT DX,AL ;POINT TO 2nd ENTRY | ||
| 981 | IN AL,DX ;READ IT | ||
| 982 | XOR AL,BL ;DATA READ AS EXPECTED ? | ||
| 983 | JNE CAPT_ERROR ;NO - THEN ERROR | ||
| 984 | SHL BL,1 ;SHIFT BIT TO NEXT POSITION | ||
| 985 | LOOP C1 ;REPEAT | ||
| 986 | ; | ||
| 987 | MOV DI,DMAREQ2 ;SETUP FOR I/O TO DMA CTRL 2 REQ REG | ||
| 988 | MOV AL,05H ;DATA PATTERN TO CAPTURE | ||
| 989 | CALL CAPT_FILL ;FILL CAPTURE REGS WITH VALUE | ||
| 990 | ; | ||
| 991 | MOV AH,05H ;SETUP INITIAL PATTERN | ||
| 992 | MOV BX,0F0AH ;OTHER PATTERNS TO USE | ||
| 993 | C2: | ||
| 994 | CALL CAPT_RMW | ||
| 995 | JNZ CAPT_ERROR ;ERROR - THEN EXIT | ||
| 996 | CMP AH,BL ;ZERO PATTERN ? | ||
| 997 | JE CAPT_EXIT ;EXIT IF YES | ||
| 998 | MOV AH,BL ;SET UP | ||
| 999 | MOV BL,BH ; NEXT | ||
| 1000 | MOV BH,0 ; PATTERN | ||
| 1001 | JMP C2 ;REPEAT | ||
| 1002 | |||
| 1003 | ;NOW REPEAT TEST FOR CATPURE OF DMA MODE REGISTERS | ||
| 1004 | MOV SI,DMAMODE1 ;SETUP FOR I/O TO DMA CTRL 1 MODE REG | ||
| 1005 | MOV DI,DMAMODE2 ;SETUP FOR I/O TO DMA CTRL 2 MODE REG | ||
| 1006 | MOV AL,05H ;DATA PATTERN TO CAPTURE | ||
| 1007 | CALL CAPT_FILL ;FILL CAPTURE REGS WITH VALUE | ||
| 1008 | ; | ||
| 1009 | MOV AH,05H ;SETUP INITIAL PATTERN | ||
| 1010 | MOV BX,0F0AH ;OTHER PATTERNS TO USE | ||
| 1011 | C3: | ||
| 1012 | CALL CAPT_RMW | ||
| 1013 | JNZ CAPT_ERROR ;ERROR - THEN EXIT | ||
| 1014 | CMP AH,BL ;ZERO PATTERN ? | ||
| 1015 | JE CAPT_EXIT ;EXIT IF YES | ||
| 1016 | MOV AH,BL ;SET UP | ||
| 1017 | MOV BL,BH ; NEXT | ||
| 1018 | MOV BH,0 ; PATTERN | ||
| 1019 | JMP C3 ;REPEAT | ||
| 1020 | CAPT_ERROR: | ||
| 1021 | CAPT_EXIT: | ||
| 1022 | RET | ||
| 1023 | |||
| 1024 | CAPTST ENDP | ||
| 1025 | |||
| 1026 | |||
| 1027 | |||
| 1028 | PAGE | ||
| 1029 | |||
| 1030 | ;------------------------------------------------------------------------- | ||
| 1031 | ;------------------------------------------------------------------------- | ||
| 1032 | ; | ||
| 1033 | ; FILL DMA CAPTURE REG | ||
| 1034 | ; | ||
| 1035 | ; DESCRIPTION : This routine will fill the entire DMA capture register | ||
| 1036 | ; file with the pattern that is passed in AL | ||
| 1037 | ; | ||
| 1038 | ; FUNCTION/ : See Description. | ||
| 1039 | ; PURPOSE | ||
| 1040 | ; | ||
| 1041 | ; ENTRY POINT : CAPT_FILL | ||
| 1042 | ; | ||
| 1043 | ; ENTRY : AL contains the value to be captured into | ||
| 1044 | ; CONDITIONS the register file. | ||
| 1045 | ; SI contains the address of DMA controller 1 | ||
| 1046 | ; DI contains the address of DMA controller 2 | ||
| 1047 | ; | ||
| 1048 | ; EXIT : Each entry in the DMA capture register file is set to | ||
| 1049 | ; the value specified in AL. | ||
| 1050 | ;------------------------------------------------------------------------- | ||
| 1051 | ; | ||
| 1052 | CAPT_FILL PROC NEAR | ||
| 1053 | ; | ||
| 1054 | MOV DX,IDREG | ||
| 1055 | OUT DX,AL ;LOAD ID REG WITH PAT TO BE CAPTURED | ||
| 1056 | MOV DX,DI ;GET ADDRESS OF CTRL 2 | ||
| 1057 | MOV CX,3 ;REP FOR CHANNELS 7,6,5 | ||
| 1058 | CF1: | ||
| 1059 | MOV AL,CL ;CL CONTAINS WHICH DMA CHANNEL | ||
| 1060 | OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL | ||
| 1061 | LOOP CF1 ;REPEAT | ||
| 1062 | ; | ||
| 1063 | MOV DX,SI ;GET ADDRESS OF CTRL 1 | ||
| 1064 | MOV CX,3 ;REP FOR CHANNELS 3,2,1 | ||
| 1065 | CF2: | ||
| 1066 | MOV AL,CL ;CL CONTAINS WHICH DMA CHANNEL | ||
| 1067 | OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL | ||
| 1068 | LOOP CF2 ;REPEAT | ||
| 1069 | ;DO CHANNEL 0 IF NOT MODEL PC1, XT, AQUARIUS | ||
| 1070 | CMP CS:MODEL,PC1 ;IS THIS A PC1 ? | ||
| 1071 | JE CF3 ;YES - THEN EXIT ELSE TRY PC_XT | ||
| 1072 | CMP CS:MODEL,PC_XT ;IS THIS AN XT ? | ||
| 1073 | JE CF3 ;YES - THEN EXIT ELSE TRY AQUARIUS | ||
| 1074 | CMP CS:MODEL,XT_AQUARIUS ;IS THIS AN AQUARIUS? | ||
| 1075 | JE CF3 ;YES - THEN EXIT ELSE FILL CH 0 CAPT | ||
| 1076 | MOV AL,0 ;INDICATE CHANNEL 0 | ||
| 1077 | OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL | ||
| 1078 | CF3: | ||
| 1079 | RET ;RETURN TO CALLER | ||
| 1080 | ; | ||
| 1081 | CAPT_FILL ENDP | ||
| 1082 | |||
| 1083 | |||
| 1084 | |||
| 1085 | |||
| 1086 | PAGE | ||
| 1087 | ;------------------------------------------------------------------------- | ||
| 1088 | ;------------------------------------------------------------------------- | ||
| 1089 | ; | ||
| 1090 | ; READ-MODIFY-WRITE DMA CAPTURE REG | ||
| 1091 | ; | ||
| 1092 | ; DESCRIPTION : This routine will read the a DMA capture register | ||
| 1093 | ; and if the correct value is found will cause a capture | ||
| 1094 | ; of a new value. The next DMA capture reg is read and | ||
| 1095 | ; the process repeated. | ||
| 1096 | ; | ||
| 1097 | ; FUNCTION/ : See Description. | ||
| 1098 | ; PURPOSE | ||
| 1099 | ; | ||
| 1100 | ; ENTRY POINT : CAPT_RMW | ||
| 1101 | ; | ||
| 1102 | ; ENTRY : AH contains the value to be compared | ||
| 1103 | ; CONDITIONS BL contains the new value to be written | ||
| 1104 | ; SI contains the address of DMA controller 1 | ||
| 1105 | ; DI contains the address of DMA controller 2 | ||
| 1106 | ; | ||
| 1107 | ; EXIT : Each entry in the DMA capture register file is set to | ||
| 1108 | ; the value specified in BL. | ||
| 1109 | ; | ||
| 1110 | ; AL,CX,DX,ARE DESTROYED | ||
| 1111 | ;------------------------------------------------------------------------- | ||
| 1112 | ; | ||
| 1113 | CAPT_RMW PROC NEAR | ||
| 1114 | ; | ||
| 1115 | MOV CX,3 ;REP FOR CHANNELS 7,6,5 | ||
| 1116 | RMW1: | ||
| 1117 | MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG | ||
| 1118 | MOV AL,CL ;GET LOW BYTE OF COUNT | ||
| 1119 | ADD AL,4 ;ADD 4 TO POINT TO DMA CAPTURE | ||
| 1120 | CALL RMW | ||
| 1121 | JNZ RMW4 ;EXIT IF ERROR | ||
| 1122 | LOOP RMW1 ;REPEAT FOR CHANNEL 6,5 | ||
| 1123 | ; | ||
| 1124 | MOV CX,3 ;REP FOR CHANNELS 3,2,1 | ||
| 1125 | PUSH DI ;SAVE DMA CTRL 2 | ||
| 1126 | MOV DI,SI ;GET DMA CTRL 1 INTO DI FOR PROC RMW | ||
| 1127 | RMW2: | ||
| 1128 | MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG | ||
| 1129 | MOV AL,CL ;GET LOW BYTE OF COUNT | ||
| 1130 | CALL RMW | ||
| 1131 | JNZ RMW3 ;EXIT IF ERROR | ||
| 1132 | LOOP RMW2 ;REPEAT FOR DMA CHANNELS 2,1 | ||
| 1133 | ;DO CHANNEL 0 IF NOT MODEL PC1, XT, AQUARIUS | ||
| 1134 | CMP CS:MODEL,PC1 ;IS THIS A PC1 ? | ||
| 1135 | JE RMW3 ;YES - THEN EXIT ELSE TEST FOR PC_XT | ||
| 1136 | CMP CS:MODEL,PC_XT ;IS THIS AN XT ? | ||
| 1137 | JE RMW3 ;YES - THEN EXIT ELSE TEST FOR AQUARIUS | ||
| 1138 | CMP CS:MODEL,XT_AQUARIUS ;IS THIS AN AQUARIUS? | ||
| 1139 | JE RMW3 ;YES - THEN EXIT ELSE TEST CH 0 | ||
| 1140 | MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG | ||
| 1141 | MOV CL,0 ;INDICATE CHANNEL 0 | ||
| 1142 | MOV AL,CL ;ALSO INTO AL | ||
| 1143 | CALL RMW | ||
| 1144 | RMW3: | ||
| 1145 | POP DI ;RESTORE DI (ADDR OF DMA CTRL 2) | ||
| 1146 | RMW4: | ||
| 1147 | RET ;RETURN TO CALLER | ||
| 1148 | ; | ||
| 1149 | CAPT_RMW ENDP | ||
| 1150 | ; | ||
| 1151 | RMW PROC | ||
| 1152 | ; | ||
| 1153 | OUT DX,AL ;SETUP TO READ FROM DMA CAPTURE REG | ||
| 1154 | IN AL,DX ;READ IT | ||
| 1155 | XOR AL,AH ;DATA AS EXPECTED ? | ||
| 1156 | JNE RMW5 ;NO THEN EXIT | ||
| 1157 | ;DATA WAS GOOD---NOW GET NEXT PATTERN INTO THIS CAPTURE REG | ||
| 1158 | MOV DX,IDREG ;ADDRESS OF ID REG | ||
| 1159 | MOV AL,BL ;NEW PATTERN TO WRITE | ||
| 1160 | OUT DX,AL ;WRITE IT TO ID REG | ||
| 1161 | MOV DX,DI ;ADDRESS OF DMA CTRL 2 | ||
| 1162 | MOV AL,CL ;DMA CHANNEL TO SET UP | ||
| 1163 | OUT DX,AL ;SET UP DMA---THIS CAUSES CAPTURE OF ID | ||
| 1164 | RMW5: | ||
| 1165 | RET ;RETURN TO CALLER | ||
| 1166 | ; | ||
| 1167 | RMW ENDP | ||
| 1168 | |||
| 1169 | |||
| 1170 | |||
| 1171 | |||
| 1172 | PAGE | ||
| 1173 | ;------------------------------------------------------------------------- | ||
| 1174 | ;------------------------------------------------------------------------- | ||
| 1175 | ; | ||
| 1176 | ; INHIBIT A BLOCK OF MEMORY | ||
| 1177 | ; | ||
| 1178 | ; DESCRIPTION : This routine will set a block of SMAS memory with | ||
| 1179 | ; the code to enable or inhibit it. The user simply | ||
| 1180 | ; specifies the starting segment and length of the block in | ||
| 1181 | ; PC 'real' address space that is to be enabled/inhibited. | ||
| 1182 | ; The appropriate entries in the Translate Table are | ||
| 1183 | ; written so that this specified block in 'real' address | ||
| 1184 | ; is enabled or protected in all 16 possible TASK ID's. | ||
| 1185 | ; | ||
| 1186 | ; | ||
| 1187 | ; FUNCTION/ : To enable or inhibit SMAS memory in specified areas of | ||
| 1188 | ; PURPOSE PC 'real'address space (ie.,diplay buffer, BIOS, | ||
| 1189 | ; distributed ROS...) | ||
| 1190 | ; | ||
| 1191 | ; ENTRY POINT : INHIBLK | ||
| 1192 | ; | ||
| 1193 | ; ENTRY : (AX) starting segment in PC address space to be | ||
| 1194 | ; CONDITIONS protected/enabled. Must be on 4K boundary else | ||
| 1195 | ; this routine will round UP to next 4K block. | ||
| 1196 | ; | ||
| 1197 | ; (CX) number of 4K blocks to be protected | ||
| 1198 | ; | ||
| 1199 | ; (BL) 01 = ENABLE | ||
| 1200 | ; 00 = INHIBIT | ||
| 1201 | ; | ||
| 1202 | ; EXIT : specified entries in Translate Table are enabled or | ||
| 1203 | ; inhibited for all posible task ID's. | ||
| 1204 | ; | ||
| 1205 | ; AX,BH,CX,DX ARE DESTROYED | ||
| 1206 | ;------------------------------------------------------------------------- | ||
| 1207 | ; | ||
| 1208 | INHIBLK PROC | ||
| 1209 | ; | ||
| 1210 | ;ADJUST SI FOR TRANSLATE TABLE ENTRY | ||
| 1211 | XCHG AL,AH ;ROTATE RIGHT BY 8 | ||
| 1212 | XOR AH,AH ;CLEAR AH | ||
| 1213 | ;AX IS NOW ADJUSTED FOR ENTRY INTO | ||
| 1214 | ;XLAT TABLE FOR TASK ID=0 | ||
| 1215 | PUSH AX ;SAVE IT | ||
| 1216 | PUSH CX ;SAVE COUNT OF 4K BLOCKS | ||
| 1217 | ; | ||
| 1218 | MOV SI,TTDATA ;ADDRESS OF TT DATA REG | ||
| 1219 | MOV DI,AIDATA ;ADDRESS OF TT DATA WITH AUTO INC | ||
| 1220 | XOR BH,BH ;BH IS TASK ID | ||
| 1221 | INH1: | ||
| 1222 | MOV DX,TTPOINTER ;ADDRESS OF TT POINTER | ||
| 1223 | POP CX ;RESTORE COUNT | ||
| 1224 | POP AX ;RESTORE TT ENTRY | ||
| 1225 | PUSH AX ;SAVE BOTH | ||
| 1226 | PUSH CX ; OF THEM | ||
| 1227 | MOV AH,BH ;APPEND TASK ID TO TT POINTER | ||
| 1228 | OUT DX,AX ;SET TT POINTER TO STARTING ENTRY | ||
| 1229 | INH2: | ||
| 1230 | MOV DX,SI ;TT DATA REG | ||
| 1231 | IN AX,DX ;READ CURRENT ENTRY | ||
| 1232 | MOV DX,DI ;ADDRESS OF TT DATA WITH AUTO INC | ||
| 1233 | ;DETERMINE IF ENABLE OR INHIBIT BLOCK | ||
| 1234 | CMP BL,ENABLE ;WANT TO ENABLE THIS BLOCK ? | ||
| 1235 | JNE INH3 ;NO - THEN DISABLE IT | ||
| 1236 | AND AH,BLK_ON ;MASK OFF INHIBIT BIT | ||
| 1237 | JMP INH4 | ||
| 1238 | INH3: | ||
| 1239 | OR AH,BLK_OFF ;MASK ON INHIBIT BIT | ||
| 1240 | INH4: | ||
| 1241 | OUT DX,AX ;WRITE IT THEN INC TO NEXT TT ENTRY | ||
| 1242 | LOOP INH2 ;REPEAT FOR EACH BLOCK OF 4K | ||
| 1243 | INC BH ;NEXT TASK ID | ||
| 1244 | CMP BH,MAX_TASK_ID ;COMPLETED FOR ALL TASK ID's ? | ||
| 1245 | JBE INH1 ;NO - THEN LOOP TILL DONE | ||
| 1246 | INHIBLK_EXIT: | ||
| 1247 | POP CX | ||
| 1248 | POP AX | ||
| 1249 | RET | ||
| 1250 | ; | ||
| 1251 | INHIBLK ENDP | ||
| 1252 | |||
| 1253 | |||
| 1254 | |||
| 1255 | |||
| 1256 | PAGE | ||
| 1257 | ;------------------------------------------------------------------------- | ||
| 1258 | ;------------------------------------------------------------------------- | ||
| 1259 | ; | ||
| 1260 | ; STORAGE TEST | ||
| 1261 | ; | ||
| 1262 | ; DESCRIPTION : This routine performs a bit and address test on a | ||
| 1263 | ; 64K block of storage. | ||
| 1264 | ; | ||
| 1265 | ; (i) 55AA is written to each location. | ||
| 1266 | ; (ii) 55AA is read back | ||
| 1267 | ; (iii) if good, write AA55 and point to next location | ||
| 1268 | ; (iv) repeat step (iii) for all 64K locations | ||
| 1269 | ; (v) repeat steps (ii) to (iv) for AA55, FF00, 0101, 0000 | ||
| 1270 | ; (vi) check parity bits | ||
| 1271 | ; | ||
| 1272 | ; | ||
| 1273 | ; FUNCTION/ : See description | ||
| 1274 | ; PURPOSE | ||
| 1275 | ; | ||
| 1276 | ; ENTRY POINT : STGTST | ||
| 1277 | ; | ||
| 1278 | ; ENTRY : (ES) storage segment to be tested | ||
| 1279 | ; CONDITIONS (DS) storage segment to be tested | ||
| 1280 | ; | ||
| 1281 | ; EXIT : (zero flag) = 0 if storage error | ||
| 1282 | ; (AX) expected data XOR'ed with actual data | ||
| 1283 | ; if ax = 0 and zf = 0 then parity error | ||
| 1284 | ; DS:SI point to failing location | ||
| 1285 | ; | ||
| 1286 | ; AX,BX,CX,DX,DI,SI ARE DESTROYED | ||
| 1287 | ; | ||
| 1288 | ;------------------------------------------------------------------------- | ||
| 1289 | ; | ||
| 1290 | STGTST PROC | ||
| 1291 | ; | ||
| 1292 | CMP CS:WARM_START,'Y' ;is this a warm start? | ||
| 1293 | JNE STG1A ;if no then do mem test | ||
| 1294 | CALL CLEAR_MEM ;if yes then just clear memory | ||
| 1295 | XOR AX,AX ;set zero flag | ||
| 1296 | JMP STG6 ;exit | ||
| 1297 | |||
| 1298 | |||
| 1299 | ;DISABLE NMI AND ENABLE I/O CHANNEL CHECK | ||
| 1300 | STG1A: | ||
| 1301 | MOV AL,CS:MODEL ;GET SAVED MODEL BYTE | ||
| 1302 | CMP AL,PC1 ;IS IT A PC1? | ||
| 1303 | JE STG1 ;IF NO THEN TRY FOR PC_XT | ||
| 1304 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 1305 | JE STG1 ;IF NO THEN TRY FOR AQUARIUS | ||
| 1306 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 1307 | JE STG1 ;IF NO THEN USE AT NMI REGS | ||
| 1308 | ;USE PC-AT NMI REGISTER | ||
| 1309 | MOV DX,AT_NMI_REG ;AT's NMI REGISTER | ||
| 1310 | MOV AL,AT_NMI_OFF ;MASK OFF NMI | ||
| 1311 | OUT DX,AL ;OUTPUT IT | ||
| 1312 | MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG | ||
| 1313 | IN AL,DX ;READ IT | ||
| 1314 | OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 1315 | OUT DX,AL ;WRITE IT | ||
| 1316 | AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 1317 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 1318 | ;ENABLED | ||
| 1319 | ;USE PC1, XT, AQUARIUS REGISTERS | ||
| 1320 | STG1: | ||
| 1321 | MOV DX,XT_NMI_REG ;XT's NMI REGISTER | ||
| 1322 | MOV AL,XT_NMI_OFF ;MASK OFF NMI | ||
| 1323 | OUT DX,AL ;OUTPUT IT | ||
| 1324 | MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG | ||
| 1325 | IN AL,DX ;READ IT | ||
| 1326 | OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 1327 | OUT DX,AL ;WRITE IT | ||
| 1328 | AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 1329 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 1330 | ;ENABLED | ||
| 1331 | |||
| 1332 | |||
| 1333 | |||
| 1334 | ;ROLL A BIT THROUGH THE FIRST WORD | ||
| 1335 | SUB DI,DI ;FIRST LOCATION | ||
| 1336 | MOV CX,16 ;ROLL 16 BITS | ||
| 1337 | MOV AX,0001H ;FIRST PATTERN TO WRITE | ||
| 1338 | MOV BX,AX ;SAVE IT | ||
| 1339 | STG2: | ||
| 1340 | MOV [DI],AX ;WRITE PATTERN | ||
| 1341 | MOV [DI+2],0FFFFH ;CHARGE BUS | ||
| 1342 | MOV AX,[DI] ;READ PATTERN | ||
| 1343 | XOR AX,BX ;IS IT CORRECT ? | ||
| 1344 | JNE STG_EXIT ;IF NO - THEN EXIT | ||
| 1345 | SHL BX,1 ;SHIFT BIT | ||
| 1346 | MOV AX,BX ;GET IT INTO AX | ||
| 1347 | LOOP STG2 ;REPEAT | ||
| 1348 | ; | ||
| 1349 | CLD ;FILL FORWARD | ||
| 1350 | SUB DI,DI ;POINT TO FIRST LOCATION | ||
| 1351 | MOV CX,8000H ;32K WORDS | ||
| 1352 | MOV AX,55AAH ;INITIAL PATTERN TO WRITE | ||
| 1353 | REP STOSW ;FILL ENTIRE SEGMENT | ||
| 1354 | ; | ||
| 1355 | MOV BX,55AAH ;PATTERN TO LOOK FOR | ||
| 1356 | MOV DX,0AA55H ;NEXT PATTERN TO WRITE | ||
| 1357 | CALL STG_CNT | ||
| 1358 | JNZ STG_EXIT ;EXIT IF ERROR | ||
| 1359 | ; | ||
| 1360 | MOV BX,0AA55H ;PATTERN TO LOOK FOR | ||
| 1361 | MOV DX,0101H ;NEXT PATTERN TO WRITE | ||
| 1362 | CALL STG_CNT | ||
| 1363 | JNZ STG_EXIT ;EXIT IF ERROR | ||
| 1364 | ; | ||
| 1365 | MOV BX,0101H ;PATTERN TO LOOK FOR | ||
| 1366 | MOV DX,0000H ;NEXT PATTERN TO WRITE | ||
| 1367 | CALL STG_CNT | ||
| 1368 | JNZ STG_EXIT ;EXIT IF ERROR | ||
| 1369 | ; | ||
| 1370 | ; MOV BX,0000H ;PATTERN TO LOOK FOR | ||
| 1371 | ; MOV DX,0000H ;NEXT PATTERN TO WRITE | ||
| 1372 | ; CALL STG_CNT | ||
| 1373 | ; JNZ STG_EXIT ;EXIT IF ERROR | ||
| 1374 | ; | ||
| 1375 | ;IF TEST REACHES THIS POINT THEN MEMORY IS GOOD | ||
| 1376 | ;NEED TO CHECK PARITY BITS...IF PARITY ERROR EXISTS THEN | ||
| 1377 | ;CAN ASSUME BAD PARITY BIT OR BAD PARITY GENERATOR | ||
| 1378 | ; | ||
| 1379 | MOV AL,CS:MODEL ;GET SAVED MODEL BYTE | ||
| 1380 | CMP AL,PC1 ;IS IT A PC1? | ||
| 1381 | JE STG3 ;USE XT REGISTERS | ||
| 1382 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 1383 | JE STG3 ;USE XT REGISTERS | ||
| 1384 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 1385 | JE STG3 ;USE XT REGISTERS | ||
| 1386 | ;IF NONE OF THE ABOVE THEN... | ||
| 1387 | ;USE AT NMI REGISTER | ||
| 1388 | MOV DX,AT_CHCHK_REG ;AT's I/O CH CHK REG | ||
| 1389 | IN AL,DX ;READ IT | ||
| 1390 | AND AL,AT_CHCHK ;IS CH CHK BIT ON ? | ||
| 1391 | JZ STG4 ;IF NO - THEN EXIT | ||
| 1392 | MOV AX,0 ;ELSE - CLEAR AX TO INDICATE | ||
| 1393 | ;PARITY ERROR | ||
| 1394 | JMP STG4 ;EXIT | ||
| 1395 | ;USE XT/AQUARIUS NMI REGISTER | ||
| 1396 | STG3: | ||
| 1397 | MOV DX,XT_CHCHK_REG ;XT's I/O CH CHK REG | ||
| 1398 | IN AL,DX ;READ IT | ||
| 1399 | AND AL,XT_CHCHK ;IS CH CHK BIT ON ? | ||
| 1400 | JZ STG4 ;IF NO - THEN EXIT | ||
| 1401 | MOV AX,0 ;ELSE - CLEAR AX TO INDICATE | ||
| 1402 | ;PARITY ERROR | ||
| 1403 | STG4: | ||
| 1404 | STG_EXIT: | ||
| 1405 | PUSH AX ;SAVE THESE REGS | ||
| 1406 | PUSH DX ;THEY CONTAIN | ||
| 1407 | PUSH SI | ||
| 1408 | PUSHF ;USEFUL ERROR INFORMATION | ||
| 1409 | ;BEFORE NMI IS ENABLED, CLEAR PARITY CHECK LATCH ON XMA | ||
| 1410 | MOV SI,0 | ||
| 1411 | MOV AX,[SI] ;READ 1ST WORD OF THIS SEG | ||
| 1412 | MOV [SI],AX ;WRITE BACK SAME WORD | ||
| 1413 | ;THE WRITE WILL CLEAR PCHK LTCH | ||
| 1414 | ;CLEAR I/O CHANNEL CHECK LATCHES AND ENABLE NMI | ||
| 1415 | MOV AL,CS:MODEL ;GET SAVED MODEL BYTE | ||
| 1416 | CMP AL,PC1 ;IS IT A PC1? | ||
| 1417 | JE STG5 ;USE XT REGISTERS | ||
| 1418 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 1419 | JE STG5 ;USE XT REGISTERS | ||
| 1420 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 1421 | JE STG5 ;USE XT REGISTERS | ||
| 1422 | ;IF NONE OF THE ABOVE THEN... | ||
| 1423 | ;USE AT NMI REGISTER | ||
| 1424 | MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG | ||
| 1425 | IN AL,DX ;READ IT | ||
| 1426 | OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 1427 | OUT DX,AL ;WRITE IT | ||
| 1428 | AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 1429 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 1430 | ;ENABLED | ||
| 1431 | MOV DX,AT_NMI_REG ;AT's NMI REGISTER | ||
| 1432 | MOV AL,AT_NMI_ON ;MASK ON NMI | ||
| 1433 | OUT DX,AL ;OUTPUT IT | ||
| 1434 | ;USE XT/AQUARIUS NMI REGISTER | ||
| 1435 | STG5: | ||
| 1436 | MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG | ||
| 1437 | IN AL,DX ;READ IT | ||
| 1438 | OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 1439 | OUT DX,AL ;WRITE IT | ||
| 1440 | AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 1441 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 1442 | ;ENABLED | ||
| 1443 | MOV DX,XT_NMI_REG ;XT's NMI REGISTER | ||
| 1444 | MOV AL,XT_NMI_ON ;MASK ON NMI | ||
| 1445 | OUT DX,AL ;OUTPUT IT | ||
| 1446 | ; | ||
| 1447 | POPF | ||
| 1448 | POP SI | ||
| 1449 | POP DX | ||
| 1450 | POP AX ;RESTORE REGS | ||
| 1451 | STG6: | ||
| 1452 | RET ;RETURN TO CALLER | ||
| 1453 | |||
| 1454 | |||
| 1455 | |||
| 1456 | CLEAR_MEM PROC ;INTERNAL PROC TO CLEAR MEMORY | ||
| 1457 | XOR DI,DI ;start of segment | ||
| 1458 | XOR CX,CX ;clear entire segment | ||
| 1459 | XOR AX,AX ;write zeroes | ||
| 1460 | |||
| 1461 | STOSB ;just write | ||
| 1462 | RET ;back to caller | ||
| 1463 | CLEAR_MEM ENDP | ||
| 1464 | |||
| 1465 | |||
| 1466 | STGTST ENDP | ||
| 1467 | |||
| 1468 | |||
| 1469 | PAGE | ||
| 1470 | ;------------------------------------------------------------------------- | ||
| 1471 | ;------------------------------------------------------------------------- | ||
| 1472 | ; | ||
| 1473 | ; STORAGE TEST SUBROUTINE | ||
| 1474 | ; | ||
| 1475 | ; DESCRIPTION : This routine performs a bit and address test on a | ||
| 1476 | ; 64K block of storage. | ||
| 1477 | ; | ||
| 1478 | ; (i) a word is read and compared against the value in (BX) | ||
| 1479 | ; (ii) if good the value in (DX) is written into that location | ||
| 1480 | ; (iii) point to next location and repeat steps (i) to (ii) | ||
| 1481 | ; | ||
| 1482 | ; | ||
| 1483 | ; FUNCTION/ : See description | ||
| 1484 | ; PURPOSE | ||
| 1485 | ; | ||
| 1486 | ; ENTRY POINT : STG_CNT | ||
| 1487 | ; | ||
| 1488 | ; ENTRY : (ES) storage segment to be tested | ||
| 1489 | ; CONDITIONS (DS) storage segment to be tested | ||
| 1490 | ; (BX) value to be compared | ||
| 1491 | ; (DX) new value to be written | ||
| 1492 | ; | ||
| 1493 | ; EXIT : (zero flag) = 0 if storage error | ||
| 1494 | ; (AX) expected data XOR'ed with actual data | ||
| 1495 | ; if ax = 0 and zf = 0 then parity error | ||
| 1496 | ; DS:SI point to failing location | ||
| 1497 | ;------------------------------------------------------------------------- | ||
| 1498 | ; | ||
| 1499 | STG_CNT PROC | ||
| 1500 | ; | ||
| 1501 | MOV CX,8000H ;32K WORDS | ||
| 1502 | SUB DI,DI ;FIRST LOCATION | ||
| 1503 | MOV SI,DI ;FIRST LOCATION | ||
| 1504 | SC1: | ||
| 1505 | LODSW ;READ OLD WORD FROM STORAGE | ||
| 1506 | XOR AX,BX ;DATA AS EXPECTED ? | ||
| 1507 | JNE SC2 ;IF NO - THEN EXIT | ||
| 1508 | MOV AX,DX ;GET NEW PATTERN | ||
| 1509 | STOSW ;WRITE IT | ||
| 1510 | LOOP SC1 ;REPEAT | ||
| 1511 | SC2: | ||
| 1512 | RET | ||
| 1513 | |||
| 1514 | STG_CNT ENDP | ||
| 1515 | |||
| 1516 | |||
| 1517 | |||
| 1518 | |||
| 1519 | PAGE | ||
| 1520 | ;------------------------------------------------------------------------- | ||
| 1521 | ;------------------------------------------------------------------------- | ||
| 1522 | ; | ||
| 1523 | ; PRINT MEMORY GOOD | ||
| 1524 | ; | ||
| 1525 | ; DESCRIPTION : This routine will print to the screen how much memory | ||
| 1526 | ; has been tested. | ||
| 1527 | ; | ||
| 1528 | ; The format will be: xxxx KB TESTED | ||
| 1529 | ; | ||
| 1530 | ; FUNCTION/ : See description | ||
| 1531 | ; PURPOSE | ||
| 1532 | ; | ||
| 1533 | ; | ||
| 1534 | ; ENTRY POINT : KB_OK | ||
| 1535 | ; | ||
| 1536 | ; ENTRY : (DX) = 1/4 OF GOOD MEMORY + 64K IN KB | ||
| 1537 | ; CONDITIONS ex: if (DX) = 16 then | ||
| 1538 | ; (16 * 4) + 64 = 128KB is OK | ||
| 1539 | ; | ||
| 1540 | ; NOTE: if (DX) = FFF0 then 0 KB is OK | ||
| 1541 | ; | ||
| 1542 | ; | ||
| 1543 | ; EXIT : Message is displayed | ||
| 1544 | ; | ||
| 1545 | ; All registers are preserved | ||
| 1546 | ; | ||
| 1547 | ;------------------------------------------------------------------------- | ||
| 1548 | ; | ||
| 1549 | KB_OK PROC | ||
| 1550 | ; | ||
| 1551 | PUSH AX | ||
| 1552 | PUSH BX | ||
| 1553 | PUSH CX | ||
| 1554 | PUSH DX | ||
| 1555 | PUSH SI | ||
| 1556 | PUSH DI | ||
| 1557 | PUSH DS ;SAVE REGISTERS | ||
| 1558 | ; | ||
| 1559 | PUSH CS | ||
| 1560 | POP DS ;GET DS TO THIS CODE SEGMENT | ||
| 1561 | ;CONVERT DX TO KILO BYTES | ||
| 1562 | SHL DX,1 | ||
| 1563 | SHL DX,1 ;MULTIPLY BY 4 | ||
| 1564 | ADD DX,64 ;ADJUST BY 64 | ||
| 1565 | ; | ||
| 1566 | MOV AX,DX ;GET NUMBER INTO AX | ||
| 1567 | MOV BX,10 ;READY FOR DECIMAL CONVERT | ||
| 1568 | MOV CX,4 ;OF 4 DIGITS | ||
| 1569 | K1: | ||
| 1570 | XOR DX,DX ;CLEAR HI WORD OF DIVIDEND | ||
| 1571 | ;AX IS LOW WORD OF DIVIDEND | ||
| 1572 | DIV BX ;DIVIDE BY 10 | ||
| 1573 | OR DL,30H ;MAKE MODULO INTO ASCII | ||
| 1574 | PUSH DX ;SAVE IT | ||
| 1575 | LOOP K1 ;REPEAT FOR ALL DIGITS | ||
| 1576 | ; | ||
| 1577 | XOR SI,SI ;CLEAR SI | ||
| 1578 | MOV CX,4 | ||
| 1579 | K2: | ||
| 1580 | POP AX ;ASCII DIGIT GOES INTO AL | ||
| 1581 | MOV BX,OFFSET MEM_OK | ||
| 1582 | MOV CS:[BX+SI],AL ;BUILD ASCII MESSAGE | ||
| 1583 | INC SI | ||
| 1584 | LOOP K2 | ||
| 1585 | ;MOVE THE CURSOR AND PRINT MESSAGE | ||
| 1586 | MOV DX,CUR_SAVE | ||
| 1587 | MOV BH,ACTIVE_PAGE | ||
| 1588 | MOV AH,2 ;SET CURSOR | ||
| 1589 | IF DOS | ||
| 1590 | INT 10H ;BIOS VIDEO CALL SET CURSOR | ||
| 1591 | MOV AH,9 ;DOS PRINT STRING | ||
| 1592 | MOV DX,OFFSET SIZE_MSG1 + 1 ;OFFSET OF MEM_OK MSG | ||
| 1593 | INT 21H ;DISPLAY MESSAGE | ||
| 1594 | ELSE | ||
| 1595 | INT 85H ;SET CURSOR POSITION | ||
| 1596 | |||
| 1597 | MOV BX,OFFSET SIZE_MSG1 ;GET OFFSET OF MEM_OK MSG | ||
| 1598 | MOV AX,0905H ;MAGENTA MESSAGE | ||
| 1599 | INT 82H ;DISPLAY MESSAGE | ||
| 1600 | ENDIF | ||
| 1601 | |||
| 1602 | POP DS | ||
| 1603 | POP DI | ||
| 1604 | POP SI | ||
| 1605 | POP DX | ||
| 1606 | POP CX | ||
| 1607 | POP BX | ||
| 1608 | POP AX ;RESTORE ALL REGISTERS | ||
| 1609 | |||
| 1610 | RET ;RETURN TO CALLER | ||
| 1611 | |||
| 1612 | KB_OK ENDP | ||
| 1613 | |||
| 1614 | |||
| 1615 | PAGE | ||
| 1616 | ;-------------------------------------------------------------------- | ||
| 1617 | ;-------------------------------------------------------------------- | ||
| 1618 | ; GET MODEL BYTE | ||
| 1619 | ; | ||
| 1620 | GETMOD PROC | ||
| 1621 | ;GET COPY OF MODEL BYTE INTO THIS SEGMENT | ||
| 1622 | ; | ||
| 1623 | PUSH DS ;SAVE DS | ||
| 1624 | LDS SI,ADDR_MODEL_BYTE | ||
| 1625 | MOV AL,[SI] ;GET IT INTO AL | ||
| 1626 | MOV CS:MODEL,AL ;SAVE IT IN THIS SEGMENT | ||
| 1627 | POP DS ;RESTORE DS | ||
| 1628 | RET | ||
| 1629 | ; | ||
| 1630 | GETMOD ENDP | ||
| 1631 | |||
| 1632 | |||
| 1633 | |||
| 1634 | |||
| 1635 | PAGE | ||
| 1636 | ;------------------------------------------------------------------------- | ||
| 1637 | ;------------------------------------------------------------------------- | ||
| 1638 | ; | ||
| 1639 | ; SET TRANSLATE TABLE | ||
| 1640 | ; | ||
| 1641 | ; DESCRIPTION : This routine will write the Translate Table so that | ||
| 1642 | ; a specified block of PC 'real' address will be mapped | ||
| 1643 | ; to a specified block of SMAS physycal memory. Note that | ||
| 1644 | ; this routine will map only into CONTIGUOUS blocks of | ||
| 1645 | ; SMAS memory. PC memory is referenced by segments | ||
| 1646 | ; (must be on 4K boundaries) while SMAS memory is referenced | ||
| 1647 | ; by block number (each block is 4K). | ||
| 1648 | ; | ||
| 1649 | ; EXAMPLE: segment 4000 can be mapped to block 5 | ||
| 1650 | ; segment 4100 can be mapped to block 6 | ||
| 1651 | ; | ||
| 1652 | ; FUNCTION/ : To map PC 'real' addresses into SMAS physical memory. | ||
| 1653 | ; PURPOSE | ||
| 1654 | ; | ||
| 1655 | ; | ||
| 1656 | ; ENTRY POINT : SETXLAT | ||
| 1657 | ; | ||
| 1658 | ; ENTRY : (AX) starting segment in PC address space to be | ||
| 1659 | ; CONDITIONS mapped. Must be on 4K boundary else | ||
| 1660 | ; this routine will round UP to next 4K block. | ||
| 1661 | ; | ||
| 1662 | ; (CX) number of 4K blocks translated. | ||
| 1663 | ; | ||
| 1664 | ; (BH) task ID for this memory allocation | ||
| 1665 | ; | ||
| 1666 | ; (BL) 01 = ENABLE | ||
| 1667 | ; 00 = INHIBIT | ||
| 1668 | ; | ||
| 1669 | ; (DX) starting block number in SMAS memory | ||
| 1670 | ; | ||
| 1671 | ; | ||
| 1672 | ; EXIT : specified entries in Translate Table are enabled or | ||
| 1673 | ; inhibited for all posible task ID's. | ||
| 1674 | ; | ||
| 1675 | ; | ||
| 1676 | ; AX,CX,DX ARE DESTROYED | ||
| 1677 | ; | ||
| 1678 | ;------------------------------------------------------------------------- | ||
| 1679 | ; | ||
| 1680 | SETXLAT PROC | ||
| 1681 | ; | ||
| 1682 | ;ADJUST AX FOR TRANSLATE TABLE ENTRY | ||
| 1683 | XCHG AL,AH ;ROTATE RIGHT BY 8 | ||
| 1684 | MOV AH,BH ;TASK ID INTO BH | ||
| 1685 | ;AX IS NOW ADJUSTED FOR ENTRY INTO | ||
| 1686 | ;XLAT TABLE FOR TASK ID=(BH) | ||
| 1687 | PUSH DX ;SAVE STARTING SMAS BLOCK NUMBER | ||
| 1688 | ; | ||
| 1689 | MOV DX,TTPOINTER ;ADDRESS OF TT POINTER | ||
| 1690 | OUT DX,AX ;SET TT POINTER TO STARTING ENTRY | ||
| 1691 | POP AX ;GET STARTING BLOCK NUMBER INTO AX | ||
| 1692 | ; | ||
| 1693 | MOV DX,AIDATA ;TT DATA REG WITH AUTO INC | ||
| 1694 | ;DETERMINE IF ENABLE OR INHIBIT BLOCK | ||
| 1695 | CMP BL,ENABLE ;WANT TO ENABLE THIS BLOCK ? | ||
| 1696 | JE SETX1 ;YES - THEN SKIP THE DISABLE STEP | ||
| 1697 | OR AH,BLK_OFF ;MASK ON INHIBIT BIT | ||
| 1698 | SETX1: | ||
| 1699 | OUT DX,AX ;WRITE IT THEN INC TO NEXT TT ENTRY | ||
| 1700 | INC AX ;NEXT BLOCK OF SMAS MEMORY | ||
| 1701 | LOOP SETX1 ;REPEAT FOR EACH BLOCK OF 4K | ||
| 1702 | SETXLAT_EXIT: | ||
| 1703 | RET | ||
| 1704 | ; | ||
| 1705 | SETXLAT ENDP | ||
| 1706 | |||
| 1707 | PAGE | ||
| 1708 | ;------------------------------------------------------------------------- | ||
| 1709 | ;------------------------------------------------------------------------- | ||
| 1710 | ; | ||
| 1711 | ; AUTO-INCREMENT TEST | ||
| 1712 | ; | ||
| 1713 | ; DESCRIPTION : This routine will test the auto-increment of | ||
| 1714 | ; the Translate Table pointer. The test will procede | ||
| 1715 | ; in the following manner: | ||
| 1716 | ; (i) A basic check of the TT pointer reg is performed | ||
| 1717 | ; (ii) The TT pointer is initialized to '00'H | ||
| 1718 | ; (iii) The auto increment data reg is written | ||
| 1719 | ; (iv) The TT pointer is read and checked for increment | ||
| 1720 | ; (v) Repeat until TT pointer wraps from 'FFF'H to '000'H | ||
| 1721 | ; (vi) Repeat test for auto-increment for read of data reg | ||
| 1722 | ; | ||
| 1723 | ; FUNCTION/ : To ensure that the Translate Table pointer can auto | ||
| 1724 | ; PURPOSE increment when 31A5 is written or read. | ||
| 1725 | ; | ||
| 1726 | ; ENTRY POINT : INCTST | ||
| 1727 | ; | ||
| 1728 | ; ENTRY : NONE | ||
| 1729 | ; CONDITIONS | ||
| 1730 | ; | ||
| 1731 | ; EXIT : | ||
| 1732 | ; (zero flag) = 0 indicates an error | ||
| 1733 | ; (DX) failing register (ie.,TT pointer reg) | ||
| 1734 | ; (AX) expected data XOR'ed with actual data | ||
| 1735 | ;------------------------------------------------------------------------- | ||
| 1736 | ; | ||
| 1737 | ; | ||
| 1738 | INCTST PROC | ||
| 1739 | ; | ||
| 1740 | MOV AL,AUTO_INC | ||
| 1741 | MOV CS:TEST_ID,AL | ||
| 1742 | ; | ||
| 1743 | ;PERFORM SIMPLE TEST OF TTPOINTER REG | ||
| 1744 | ; | ||
| 1745 | MOV BX,0AA55H ;SET UP PATTERN TO WRITE | ||
| 1746 | MOV AX,BX | ||
| 1747 | MOV DX,TTPOINTER ;I/O TO TTPOINTER REG | ||
| 1748 | MOV SI,TTDATA ;SAVE FOR I/O TO TTDATA | ||
| 1749 | OUT DX,AX ;WRITE THE REGISTER | ||
| 1750 | XCHG DX,SI ;I/O TO TTDATA REG | ||
| 1751 | XCHG AH,AL ;INVERSE PATTERN | ||
| 1752 | OUT DX,AX ;CHARGE BUS WITH OPPOSITE PATTERN | ||
| 1753 | XCHG DX,SI ;I/O TO TTPOINTER REG | ||
| 1754 | IN AX,DX ;READ TTPOINTER REG | ||
| 1755 | XOR AX,BX ;READ AS EXPECTED | ||
| 1756 | AND AX,0FFFH ;MASK OFF HI NIBBLE (INVALID) | ||
| 1757 | JNE INC_ERROR ;NO - THEN EXIT | ||
| 1758 | ; | ||
| 1759 | ;CONTINUE WITH AUTO-INC TEST | ||
| 1760 | ; | ||
| 1761 | MOV DI,2 ;2 PASSES...1 WRITE , 1 READ | ||
| 1762 | AI1: | ||
| 1763 | MOV SI,AIDATA ;SAVE FOR I/O TO TTDATA WITH AUTO-INC | ||
| 1764 | AI2: | ||
| 1765 | MOV CX,1000H ;TTPOINTER RANGE 0 -> FFF | ||
| 1766 | MOV BX,0001H ;INITIAL COMPARE VALUE | ||
| 1767 | MOV AX,0 ;SET TTPONTER TO ZERO | ||
| 1768 | OUT DX,AX ;TTPOINTER IS INITIALIZED TO ZERO | ||
| 1769 | AI2X: | ||
| 1770 | XCHG DX,SI ;I/O TO TTDATA WITH AUTO-INC | ||
| 1771 | ; | ||
| 1772 | ;DETERMINE IF WRITE OR READ TEST | ||
| 1773 | ; | ||
| 1774 | CMP DI,2 ;DOING A AUTO-INC WRITE TEST ? | ||
| 1775 | JNE AI3 ;NO - THEN MUST BE AUTO-INC READ TEST | ||
| 1776 | OUT DX,AX ;WRITE TO AUTO-INC DATA REG | ||
| 1777 | JMP AI4 ;CONTINUE WITH TEST | ||
| 1778 | AI3: | ||
| 1779 | IN AX,DX ;READ FROM AUTO-INC DATA REG | ||
| 1780 | AI4: | ||
| 1781 | XCHG DX,SI ;I/O TO TTPOINTER REG | ||
| 1782 | IN AX,DX ;READ TTPOINTER (31A1 -> AH) | ||
| 1783 | XOR AX,BX ;DATA AS EXPECTED ? | ||
| 1784 | AND AX,0FFFH ;MASK OFF UPPER NIBBLE (INVALID) | ||
| 1785 | JNE INC_ERROR ;NO - GO TO ERROR | ||
| 1786 | INC BX ;NEXT VALUE TO LOOK FOR | ||
| 1787 | LOOP AI2X ;CONTINUE TIL ALL VALUES ARE TESTED | ||
| 1788 | ; | ||
| 1789 | DEC DI | ||
| 1790 | CMP DI,0 ;COMPLETE WITH WRITE AND READ TEST ? | ||
| 1791 | JE INC_EXIT ;YES - THEN EXIT | ||
| 1792 | JMP AI1 ;NO - THEN CONTINUE WITH READ TEST | ||
| 1793 | ; | ||
| 1794 | INC_ERROR: | ||
| 1795 | INC_EXIT: RET | ||
| 1796 | ; | ||
| 1797 | INCTST ENDP | ||
| 1798 | |||
| 1799 | PAGE | ||
| 1800 | ;------------------------------------------------------------------------- | ||
| 1801 | ;------------------------------------------------------------------------- | ||
| 1802 | ; | ||
| 1803 | ; TRANSLATE TABLE TEST | ||
| 1804 | ; | ||
| 1805 | ; DESCRIPTION : This routine performs a write/read storage test | ||
| 1806 | ; on the Translate Table. The test is as follows: | ||
| 1807 | ; (i) A bit is rolled through the first word of the TT | ||
| 1808 | ; (ii) A bit and address test is performed on the | ||
| 1809 | ; remainder of the TT. | ||
| 1810 | ; | ||
| 1811 | ; FUNCTION/ : To verify the integrity of the Translate Table. | ||
| 1812 | ; PURPOSE | ||
| 1813 | ; | ||
| 1814 | ; ENTRY POINT : XLATST | ||
| 1815 | ; | ||
| 1816 | ; ENTRY : NONE | ||
| 1817 | ; CONDITIONS | ||
| 1818 | ; | ||
| 1819 | ; EXIT : Entire Translate Table is left with FFF (passover code) | ||
| 1820 | ; | ||
| 1821 | ; (zero flag) = 0 indicates an error | ||
| 1822 | ; (DX) failing register (TT data register) | ||
| 1823 | ; (AX) expected data XOR'ed with actual data | ||
| 1824 | ; (31A0) address in TT of failure | ||
| 1825 | ;------------------------------------------------------------------------- | ||
| 1826 | ; | ||
| 1827 | XLATST PROC | ||
| 1828 | ; | ||
| 1829 | MOV AL,XLAT_TABLE_TEST | ||
| 1830 | MOV CS:TEST_ID,AL | ||
| 1831 | ; | ||
| 1832 | ;ROLL A BIT THROUGH THE FIRST BYTE | ||
| 1833 | ; | ||
| 1834 | MOV BX,0001H ;SET UP INITIAL PATTERN | ||
| 1835 | MOV SI,TTDATA ;SAVE FOR I/O TO DATA REG | ||
| 1836 | MOV DX,TTPOINTER ;I/O TO TTPOINTER REG | ||
| 1837 | MOV CX,12 ;ROLL 12 BIT POSITIONS | ||
| 1838 | XOR AX,AX ;CLEAR AX (WRITE TO 1st TT LOCATION) | ||
| 1839 | OUT DX,AX ;SET TT POINTER | ||
| 1840 | XCHG DX,SI ;READY FOR I/O TO TTDATA REG | ||
| 1841 | X1: | ||
| 1842 | MOV AX,BX ;GET BIT PATTERN | ||
| 1843 | OUT DX,AX ;WRITE BIT PATTERN TO TT | ||
| 1844 | XCHG DX,SI ;READY FOR I/O TO TTPOINTER REG | ||
| 1845 | XOR AX,AX ;CLEAR AX | ||
| 1846 | OUT DX,AX ;CHARGE BUS WITH 0000 PATTERN | ||
| 1847 | XCHG DX,SI ;READY FOR I/O TO TTDATA REG | ||
| 1848 | IN AX,DX ;READ TT (31A1 -> AH) | ||
| 1849 | XOR AX,BX ;DATA READ AS EXPECTED ? | ||
| 1850 | AND AX,0FFFH ;MASK OFF UPPER NIBBLE (INVALID) | ||
| 1851 | JNE XLA_ERROR ;NO - THEN EXIT | ||
| 1852 | SHL BX,1 ;SHIFT BIT TO NEXT POSITION | ||
| 1853 | LOOP X1 | ||
| 1854 | ; | ||
| 1855 | ;CONTINUE REMAINDER OF TRANSLATE TABLE | ||
| 1856 | ; | ||
| 1857 | MOV DX,AIDATA | ||
| 1858 | ; | ||
| 1859 | XCHG DX,SI ;READY FOR I/O TO TTPOINTER | ||
| 1860 | XOR AX,AX ;CLEAR AX | ||
| 1861 | OUT DX,AX ;TTPOINTER AT 1st LOCATION | ||
| 1862 | ; | ||
| 1863 | XCHG DX,SI ;READY FOR I/O TO TT DATA W/AUTO-INC | ||
| 1864 | MOV AX,0AA55H ;INITIAL DATA PATTERN | ||
| 1865 | MOV CX,TABLEN ;NUMBER OF TT ENTRIES | ||
| 1866 | X2: | ||
| 1867 | OUT DX,AX ;SETUP INVERSE PATTERN | ||
| 1868 | LOOP X2 ;FILL ENTIRE XLATE TABLE | ||
| 1869 | ; | ||
| 1870 | MOV SI,TTDATA ;ADDRESS OF TTDATA WITHOUT INC. | ||
| 1871 | MOV BX,AX ;SAVE VALUE FOR COMPARE | ||
| 1872 | MOV DI,055AAH ;NEXT PATTERN TO WRITE | ||
| 1873 | X3: | ||
| 1874 | MOV CX,TABLEN ;NUMBER OF TT ENTRIES | ||
| 1875 | X4: | ||
| 1876 | XCHG DX,SI ;GET IT INTO DX...SI GETS AUTO-INC | ||
| 1877 | IN AX,DX ;READ TABLE ENTRY (HI BYTE -> AH) | ||
| 1878 | XOR AX,BX ;DATA READ AS EXPECTED ? | ||
| 1879 | AND AX,0FFFH ;MASK OFF HI NIBBLE (INVALID) | ||
| 1880 | JNE XLA_ERROR ;NO - THE EXIT | ||
| 1881 | XCHG DX,SI ;GET TTDATA WITH AUTO-INC | ||
| 1882 | MOV AX,DI ;RECOVER NEXT PATTERN TO WRITE | ||
| 1883 | OUT DX,AX ;WRITE IT THEN INCREMENT | ||
| 1884 | LOOP X4 ;REPEAT TILL TABLE FILLED | ||
| 1885 | |||
| 1886 | |||
| 1887 | ; | ||
| 1888 | CMP DI,0FFFFH ;LAST PASS ? | ||
| 1889 | JE XLA_EXIT ;YES - THEN EXIT REG TEST | ||
| 1890 | ; | ||
| 1891 | XCHG BX,DI ;BX GETS NEXT PATTERN TO TEST | ||
| 1892 | ; | ||
| 1893 | CMP BX,055AAH ;LAST PASS FOR AA55,55AA PATTERN? | ||
| 1894 | JNE X5 ;NO | ||
| 1895 | MOV DI,0FF00H ;YES- PREPARE TO WRITE NEW PATTERN | ||
| 1896 | JMP X3 ;DO IT | ||
| 1897 | X5: | ||
| 1898 | CMP BX,0FF00H ;READY TO READ 0FF00 PATTERN | ||
| 1899 | JNE X6 ;NO | ||
| 1900 | MOV DI,00FFH ;YES- PREPARE TO WRITE NEW PATTERN | ||
| 1901 | JMP X3 ;DO IT | ||
| 1902 | X6: | ||
| 1903 | MOV DI,0FFFFH ;PREPARE TO SET ALL OF TT INACTIVE | ||
| 1904 | JMP X3 ;DO IT | ||
| 1905 | ; | ||
| 1906 | XLA_ERROR: | ||
| 1907 | XLA_EXIT: RET | ||
| 1908 | ; | ||
| 1909 | XLATST ENDP | ||
diff --git a/v4.0/src/DEV/XMA2EMS/EMSINIT.INC b/v4.0/src/DEV/XMA2EMS/EMSINIT.INC new file mode 100644 index 0000000..4c2213e --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/EMSINIT.INC | |||
| @@ -0,0 +1,886 @@ | |||
| 1 | |||
| 2 | ;------------------------------------------------------------------------; | ||
| 3 | ; Initialization... ; | ||
| 4 | ;------------------------------------------------------------------------; | ||
| 5 | |||
| 6 | RESR_EXT_PGS DW 0 ;Ext mem reserved here after EMS taken ;an002; dms; | ||
| 7 | |||
| 8 | MACH_MODEL_PTR DD 0F000FFFEh ;Byte in upper BIOS that indicates @RH1 | ||
| 9 | MODEL_BYTE DB (?) ; which system you are on. @RH1 | ||
| 10 | PC1 EQU 0FFh ;Values returned for: PC 1 @RH1 | ||
| 11 | PC_XT EQU 0FEh ; PC XT @RH1 | ||
| 12 | XT_AQUARIUS EQU 0FBH ; PC Aquarius @RH1 | ||
| 13 | PC_AT EQU 0FCh ; PC AT type - AT, PS/2 models @RH1 | ||
| 14 | ; 50 and 60, etc. | ||
| 15 | PS2MODEL80 EQU 0F8h ; 386 processor - PS/2 model 80 @RH1 | ||
| 16 | |||
| 17 | INT15_SEC_MOD EQU ES:BYTE PTR [BX+3] ;Secondary model byte @RH2 | ||
| 18 | SEC_MOD_TB EQU 4 ; PS/2 Model 50 @RH2 | ||
| 19 | SEC_MOD_RR EQU 5 ; PS/2 Model 60 @RH2 | ||
| 20 | |||
| 21 | START_BACMEM_SEG DW 0 ;Starting and ending segment addrs | ||
| 22 | END_BACMEM_SEG DW 0 ; of memory backed by the XMA card | ||
| 23 | |||
| 24 | INIT_ERR DW ? ;Initialization error flag @RH4 | ||
| 25 | NO_ERROR EQU 0 ; @RH4 | ||
| 26 | ERROR EQU 1 ; @RH4 | ||
| 27 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 28 | ;³ Device driver IOCTL call declares ³ | ||
| 29 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 30 | EMULATOR_DD_NAME DB '386XMAEM',0 ;Device driver names for the Emulator | ||
| 31 | XMAAVIRT_DD_NAME DB 'INDXMAII',0 ; and WSP's XMA/A init code | ||
| 32 | DD_FILE_HANDLE DW ? ;File handle from opening either DD | ||
| 33 | |||
| 34 | REQ_PACKET_STRUC STRUC ;Generic IOCTL parameter packet | ||
| 35 | PACKET_LEN DW 4 ;Packet length (in bytes) | ||
| 36 | PACKET_FCN DW 0 ;DD defined function number | ||
| 37 | PACKET_WORD DW 0 ;Data area | ||
| 38 | REQ_PACKET_STRUC ENDS | ||
| 39 | |||
| 40 | REQ_PACKET REQ_PACKET_STRUC <> ; | ||
| 41 | |||
| 42 | |||
| 43 | INIT PROC | ||
| 44 | |||
| 45 | PUSH CS | ||
| 46 | POP DS ;Get this segment into CS | ||
| 47 | |||
| 48 | MOV DX,SS ;save stack segment | ||
| 49 | MOV CX,SP ;save stack pointer | ||
| 50 | CLI ;ints off during swap | ||
| 51 | MOV AX,CS ;move cs to ss | ||
| 52 | MOV SS,AX ;through ax | ||
| 53 | MOV SP,OFFSET TOP_OF_STACK ;sp to end of code | ||
| 54 | STI ;ints back on | ||
| 55 | PUSH DX ;save old ss on new stack | ||
| 56 | PUSH CX ;save old sp on new stack | ||
| 57 | |||
| 58 | |||
| 59 | MOV DX,OFFSET WELCOME_MSG ;Print title and copy-right | ||
| 60 | MOV AH,9 ; | ||
| 61 | INT 21H | ||
| 62 | |||
| 63 | push ax ;save affected regs ;an000; dms; | ||
| 64 | push bx ; ;an000; dms; | ||
| 65 | push cx ; ;an000; dms; | ||
| 66 | push dx ; ;an000; dms; | ||
| 67 | push si ; ;an000; dms; | ||
| 68 | push di ; ;an000; dms; | ||
| 69 | push ds ; ;an000; dms; | ||
| 70 | |||
| 71 | CALL GET_PARMS ;Get the user parameters | ||
| 72 | |||
| 73 | pop ds ;restore affected regs ;an000; dms; | ||
| 74 | pop di ; ;an000; dms; | ||
| 75 | pop si ; ;an000; dms; | ||
| 76 | pop dx ; ;an000; dms; | ||
| 77 | pop cx ; ;an000; dms; | ||
| 78 | pop bx ; ;an000; dms; | ||
| 79 | pop ax ; ;an000; dms; | ||
| 80 | |||
| 81 | JE PARMS_OK | ||
| 82 | PUSH CS | ||
| 83 | POP DS | ||
| 84 | MOV DX,OFFSET PARM_ERR_MSG ;Print message indicating | ||
| 85 | MOV AH,9 ; parameter error using | ||
| 86 | INT 21H ; DOS function call | ||
| 87 | MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver | ||
| 88 | MOV AH,9 ; has not been installed | ||
| 89 | INT 21H ; | ||
| 90 | JMP GENERAL_FAILURE ;indicate general failure | ||
| 91 | PARMS_OK: | ||
| 92 | |||
| 93 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 94 | ;³ Does the system use the XMA Emulator? ³ | ||
| 95 | ;³ (PS/2 model 80 with 80386 processor) ³ | ||
| 96 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 97 | PUSH DS ; @RH1 | ||
| 98 | LDS SI,MACH_MODEL_PTR ; DS:SI points to model descriptor @RH1 | ||
| 99 | MOV AL,DS:BYTE PTR [SI] ; byte (F000:FEEE) @RH1 | ||
| 100 | MOV MODEL_BYTE,AL ; @RH1 | ||
| 101 | POP DS ; @RH1 | ||
| 102 | |||
| 103 | CMP MODEL_BYTE,PS2MODEL80 ;If the model byte is for a @RH7 | ||
| 104 | JE FIND_EMULATOR ; PS/2 model 80 @RH7 | ||
| 105 | JMP NOT_PS2MODEL80 ; then attempt to open the 80386 @RH7 | ||
| 106 | FIND_EMULATOR: ; XMA Emulator device driver @RH7 | ||
| 107 | MOV AX,3D00h ; (INDXMAEM.SYS) @RH7 | ||
| 108 | LEA DX,EMULATOR_DD_NAME ; @RH7 | ||
| 109 | INT 21h ;No carry means open successful @RH7 | ||
| 110 | JNC EMUL_INSTALLED ; and the DD is present @RH7 | ||
| 111 | PUSH CS ;Else open failed @RH7 | ||
| 112 | POP DS ;Print message indicating @RH7 | ||
| 113 | MOV DX,OFFSET NO_EMUL_MSG ; emulator not present @RH7 | ||
| 114 | MOV AH,9 ;dos prt string @RH7 | ||
| 115 | INT 21H ;write message @RH7 | ||
| 116 | MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver @RH7 | ||
| 117 | MOV AH,9 ; has not been installed @RH7 | ||
| 118 | INT 21H ; @RH7 | ||
| 119 | JMP GENERAL_FAILURE ;indicate general failure @RH7 | ||
| 120 | EMUL_INSTALLED: ;Emulator is present @RH7 | ||
| 121 | MOV DD_FILE_HANDLE,AX ;Do IOCTL to find # of XMA blocks @RH7 | ||
| 122 | MOV BX,AX ;Emulator DD handle in BX @RH7 | ||
| 123 | MOV AX,440Ch ;Handle generic IOCTL fcn code @RH7 | ||
| 124 | XOR CH,CH ;CH = 0 means "unknown" @RH7 | ||
| 125 | MOV CL,60h ;CL = 40h means set device info @RH7 | ||
| 126 | PUSH CS ; = 60h means get device info @RH7 | ||
| 127 | POP DS ; @RH7 | ||
| 128 | LEA DX,REQ_PACKET ;DS:DX -> generic IOCTL packet @RH7 | ||
| 129 | INT 21h ;Issue the generic IOCTL @RH7 | ||
| 130 | JNC EMUL_VER_GOOD ;No carry means the right @RH7 | ||
| 131 | PUSH CS ; version of the Emulator was @RH7 | ||
| 132 | POP DS ; installed (can handle IOCTL) @RH7 | ||
| 133 | MOV DX,OFFSET WRONG_EMUL_MSG ;Otherwise print message @RH7 | ||
| 134 | MOV AH,9 ; indicating incorrect version @RH7 | ||
| 135 | INT 21H ; of the Emulator detected @RH7 | ||
| 136 | MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver @RH7 | ||
| 137 | MOV AH,9 ; has not been installed @RH7 | ||
| 138 | INT 21H ; @RH7 | ||
| 139 | JMP GENERAL_FAILURE ;indicate general failure @RH7 | ||
| 140 | EMUL_VER_GOOD: | ||
| 141 | MOV AX,REQ_PACKET.PACKET_WORD ;Get the last available XMA block@RH7 | ||
| 142 | INC AX ; number from the emulator...add 1 @RH7 | ||
| 143 | XOR DX,DX ; to calc total XMA blocks and @RH7 | ||
| 144 | DIV BLOCKS_PER_PAGE ; convert it to EMS pages @RH7 | ||
| 145 | MOV TOTAL_SYS_PAGES,AX ;Set the number of total 16K pages @RH7 | ||
| 146 | MOV TOTAL_EMS_PAGES,AX ; (before and after mem backing) @RH7 | ||
| 147 | MOV FREE_PAGES,AX ; and the pages free for useage @RH7 | ||
| 148 | MOV START_BACMEM_SEG,0 ;Mark from 0-640K as taken to @RH7 | ||
| 149 | MOV END_BACMEM_SEG,0A000h ; back conventional memory and @RH7 | ||
| 150 | CALL BACK_CONV_MEM ; adjust TOTAL_EMS_PAGES @RH7 | ||
| 151 | MOV AX,3E00h ;Close the XMA Emulator device @RH7 | ||
| 152 | MOV BX,DD_FILE_HANDLE ; driver @RH7 | ||
| 153 | MOV MEMCARD_MODE,EMUL_VIRT ;Set flag for hardware used @RH7 | ||
| 154 | INT 21h ; @RH7 | ||
| 155 | JMP INT_67_INSTALL ;Install int 67 vector, end init @RH7 | ||
| 156 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 157 | NOT_PS2MODEL80: ;³ Does the system use the XMA\A or XMO card? ³ | ||
| 158 | ;³ (PS/2 models 50 and 60) ³ | ||
| 159 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 160 | CMP MODEL_BYTE,PC_AT ;If the model byte is for an 'AT' @RH2 | ||
| 161 | JE MODEL_AT ; type (80286 processor), check @RH2 | ||
| 162 | JMP FAMILY_1_MACH ; the secondary model byte to @RH2 | ||
| 163 | MODEL_AT: ; see if it's a model that uses @RH2 | ||
| 164 | MOV AH,0C0h ; the XMA/A or XMO card @RH2 | ||
| 165 | INT 15h ; @RH2 | ||
| 166 | CMP INT15_SEC_MOD,SEC_MOD_TB; @RH2 | ||
| 167 | JNE NOT_PS2MODEL50 ; @RH2 | ||
| 168 | MOV NUM_OF_SLOTS,4 ; PS2/50 has 4 adapter slots @RH2 | ||
| 169 | JMP PS2_5060 ; Init for XMA/A and XMO @RH2 | ||
| 170 | NOT_PS2MODEL50: ; @RH2 | ||
| 171 | CMP INT15_SEC_MOD,SEC_MOD_RR;If 'AT' but not PS/2 50 or 60, @RH2 | ||
| 172 | JE IS_PS2MODEL60 ; then family 1 (uses XMA 1 card) @RH2 | ||
| 173 | JMP FAMILY_1_MACH ; @RH2 | ||
| 174 | IS_PS2MODEL60: | ||
| 175 | MOV NUM_OF_SLOTS,8 ;PS2/60 has 8 adapter slots @RH2 | ||
| 176 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 177 | PS2_5060: ;³ Machine is a PS/2 Model 50 (TB) or 60 (RR). ³ | ||
| 178 | ;³ Check for the Workstation Program's XMA/A ³ | ||
| 179 | ;³ virtual mode device driver (INDXMAA.SYS). If ³ | ||
| 180 | ;³ present, use only that card in virtual mode. ³ | ||
| 181 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 182 | MOV AX,3D00h ;Attempt to open WSP's XMA/A @RH6 | ||
| 183 | LEA DX,XMAAVIRT_DD_NAME ; virtual mode device driver @RH6 | ||
| 184 | INT 21h ;Carry means open failed and the @RH6 | ||
| 185 | JC PS2_5060_REAL ; DD is not present. Use XMA/A @RH6 | ||
| 186 | ; in real mode and XMO card. @RH6 | ||
| 187 | INDXMAA_INSTALLED: ;Else driver found. XMA/A virtual @RH6 | ||
| 188 | MOV DD_FILE_HANDLE,AX ;Do IOCTL to find # of XMA/A blks @RH6 | ||
| 189 | MOV BX,AX ;INDXMAA.SYS DD handle in BX @RH6 | ||
| 190 | MOV AX,440Ch ;Handle generic IOCTL fcn code @RH6 | ||
| 191 | XOR CH,CH ;CH = 0 means "unknown" @RH6 | ||
| 192 | MOV CL,60h ;CL = 40h means set device info @RH6 | ||
| 193 | PUSH CS ; = 60h means get device info @RH6 | ||
| 194 | POP DS ; @RH6 | ||
| 195 | LEA DX,REQ_PACKET ;DS:DX -> generic IOCTL packet @RH6 | ||
| 196 | INT 21h ;Issue the generic IOCTL @RH6 | ||
| 197 | JNC XMAA_VER_GOOD ;No carry means the right @RH6 | ||
| 198 | PUSH CS ; version of the XMAA DD was @RH6 | ||
| 199 | POP DS ; installed (can handle IOCTL) @RH6 | ||
| 200 | MOV DX,OFFSET WRONG_XMAA_MSG ;Otherwise print message @RH6 | ||
| 201 | MOV AH,9 ; indicating incorrect version @RH6 | ||
| 202 | INT 21H ; of the XMAA DD detected @RH6 | ||
| 203 | MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver @RH6 | ||
| 204 | MOV AH,9 ; has not been installed @RH6 | ||
| 205 | INT 21H ; @RH6 | ||
| 206 | JMP GENERAL_FAILURE ;indicate general failure @RH6 | ||
| 207 | XMAA_VER_GOOD: | ||
| 208 | MOV AX,REQ_PACKET.PACKET_WORD ;Get the last available XMA/A blk@RH6 | ||
| 209 | INC AX ; number from the XMA/A DD...add 1 @RH6 | ||
| 210 | XOR DX,DX ; to calc total XMA/A blocks and @RH6 | ||
| 211 | DIV BLOCKS_PER_PAGE ; convert it to EMS pages @RH6 | ||
| 212 | MOV TOTAL_SYS_PAGES,AX ;Set the number of total 16K pages @RH6 | ||
| 213 | MOV TOTAL_EMS_PAGES,AX ; (before and after mem backing) @RH6 | ||
| 214 | MOV FREE_PAGES,AX ; and the pages free for useage @RH6 | ||
| 215 | MOV START_BACMEM_SEG,0 ;Mark from 0-640K as taken to @RH6 | ||
| 216 | MOV END_BACMEM_SEG,0A000h ; back conventional memory and @RH6 | ||
| 217 | CALL BACK_CONV_MEM ; adjust TOTAL_EMS_PAGES @RH6 | ||
| 218 | MOV AX,3E00h ;Close the XMA/A virtual mode @RH6 | ||
| 219 | MOV BX,DD_FILE_HANDLE ; device driver @RH6 | ||
| 220 | INT 21h ; @RH6 | ||
| 221 | MOV MEMCARD_MODE,XMAA_VIRT ;Set hardware flag to XMAA virtual @RH6 | ||
| 222 | JMP INT_67_INSTALL ;Install int 67 vector,end init @RH6 | ||
| 223 | |||
| 224 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 225 | PS2_5060_REAL: ;³ PS/2 Model 50 or 60 without XMA/A virtual DD. ³ | ||
| 226 | ;³ Use XMA/A card in real mode (Bank ID reg ³ | ||
| 227 | ;³ not used) or XMO card. ³ | ||
| 228 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 229 | CALL INIT_MOD_50_60 ;Init for XMA/A and XMO @RH2 | ||
| 230 | CMP INIT_ERR,ERROR ;If no error then install the @RH2 | ||
| 231 | JE PS2_5060_ERROR ; int 67 vector, print msgs @RH2 | ||
| 232 | JMP INT_67_INSTALL ; @RH2 | ||
| 233 | PS2_5060_ERROR: | ||
| 234 | ;Else error in intialization @RH2 | ||
| 235 | PUSH CS ; | ||
| 236 | POP DS ; | ||
| 237 | MOV AH,9 ; Barf out 1st part of msg @RH2 | ||
| 238 | INT 21H ; set by subproc (DX = ptr) @RH2 | ||
| 239 | MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver @RH2 | ||
| 240 | MOV AH,9 ; has not been installed @RH2 | ||
| 241 | INT 21H ; @RH2 | ||
| 242 | JMP GENERAL_FAILURE ;indicate general failure @RH2 | ||
| 243 | |||
| 244 | |||
| 245 | FAMILY_1_MACH: ;Family 1 machine (pre-PS/2) | ||
| 246 | mov rom_scan_type,family1 ; set flag for rom scan code - gga | ||
| 247 | MOV START_BACMEM_SEG,04000h ;Memory is backed from 256K to | ||
| 248 | MOV END_BACMEM_SEG,0A000h ; 640K on XMA 1 card | ||
| 249 | CALL PRESTST ;Insure XMA 1 card is present | ||
| 250 | JE XMA1_FOUND ;Zero flag = 1 means XMA 1 found | ||
| 251 | PUSH CS ;Else error..get this segment | ||
| 252 | POP DS ;into ds | ||
| 253 | MOV DX,OFFSET NOT_FOUND_MSG ;Print message for cannot | ||
| 254 | MOV AH,9 ; find adapter | ||
| 255 | INT 21H ;write message | ||
| 256 | MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver | ||
| 257 | MOV AH,9 ; has not been installed | ||
| 258 | INT 21H ; | ||
| 259 | JMP GENERAL_FAILURE ;indicate general failure | ||
| 260 | XMA1_FOUND: | ||
| 261 | MOV MEMCARD_MODE,XMA1_VIRT ;Indicate an XMA 1 card present @RH2 | ||
| 262 | CALL TRY4MEG ;determine the size of the XMA memory card | ||
| 263 | |||
| 264 | PUSH CS | ||
| 265 | POP DS | ||
| 266 | MOV DX,OFFSET DGS_START_MSG ;start of diagnostics message | ||
| 267 | MOV AH,9 ;dos prt string | ||
| 268 | INT 21H ;starting diagnostics message | ||
| 269 | CALL CUR_POS ;save cursor position for KB OK msg | ||
| 270 | |||
| 271 | MOV DX,MODE_REG ;determine if this is a warm start | ||
| 272 | IN AL,DX ;read mode reg | ||
| 273 | AND AL,WARM_MASK ;isolate warm start bit | ||
| 274 | JZ DO_XMA1DIAG ;If off perform full XMA 1 diags | ||
| 275 | MOV CS:WARM_START,'Y' ;Else warm start..limited diags | ||
| 276 | DO_XMA1DIAG: | ||
| 277 | CALL XMA1DIAGS ;Perform XMA 1 diagnostics | ||
| 278 | JE XMA1_OK ;Zero flag set means all OK | ||
| 279 | PUSH CS ;Else error..get this segment | ||
| 280 | POP DS ;into ds | ||
| 281 | MOV DX,OFFSET XMA1_ERR_MSG ;'XMA001 Adapter error' | ||
| 282 | MOV AH,9 ;dos prt string | ||
| 283 | INT 21H ;write message | ||
| 284 | MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver | ||
| 285 | MOV AH,9 ; has not been installed | ||
| 286 | INT 21H ; | ||
| 287 | JMP GENERAL_FAILURE ;indicate general failure | ||
| 288 | XMA1_OK: | ||
| 289 | PUSH CS ;get this segment | ||
| 290 | POP DS ;into ds | ||
| 291 | MOV DX,OFFSET DGS_END_MSG ;start of message | ||
| 292 | MOV AH,9 ;dos prt string | ||
| 293 | INT 21H ;write message | ||
| 294 | |||
| 295 | ;Set XMA in virtual mode to look like it was in real mode | ||
| 296 | CALL VIRT2REAL | ||
| 297 | ;Mark pages used on XMA card to back conventional memory | ||
| 298 | CALL BACK_CONV_MEM | ||
| 299 | |||
| 300 | |||
| 301 | ;Set up interrupt 67 vector | ||
| 302 | INT_67_INSTALL: | ||
| 303 | ;------------------------ | ||
| 304 | ; added by GGA | ||
| 305 | ;------------------------ | ||
| 306 | ;------------------------------------------------------------------- | ||
| 307 | call romscan ; just for grins | ||
| 308 | jc ROM_Scan_Fail ; error - prompt user to hit any key ;an000; dms; | ||
| 309 | jmp Skip_Pars ; continue load of XMA2EMS ;an000; dms; | ||
| 310 | |||
| 311 | ROM_Scan_Fail: | ||
| 312 | |||
| 313 | PUSH CS ;set up addressibility ;an000; dms; | ||
| 314 | POP DS ; ;an000; dms; | ||
| 315 | MOV DX,OFFSET Prompt_Msg ;Press any key to continue... ;an000; dms; | ||
| 316 | MOV AH,9 ;dos prt string ;an000; dms; | ||
| 317 | INT 21H ; | ||
| 318 | |||
| 319 | mov ah,07h ;keyboard input without ECHO ;an000; dms; | ||
| 320 | int 21h ;wait until input ;an000; dms; | ||
| 321 | jmp General_Failure ; | ||
| 322 | ;------------------------------------------------------------------- | ||
| 323 | skip_pars: | ||
| 324 | ;------------------------ | ||
| 325 | ; end of adds by GGA | ||
| 326 | ;------------------------ | ||
| 327 | |||
| 328 | CALL INIT_PAL ;Initialize the Page Allocation @RH8 | ||
| 329 | ; linked List RH8 | ||
| 330 | CALL STEAL_INT67 ; | ||
| 331 | |||
| 332 | |||
| 333 | |||
| 334 | |||
| 335 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 336 | ;³ Initialize the entries in the Page Allocation List ³ | ||
| 337 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 338 | MOV CX,TOTAL_SYS_PAGES | ||
| 339 | |||
| 340 | |||
| 341 | ;write variables into message string | ||
| 342 | PUSH CS ;get this segment | ||
| 343 | POP ES ;into es | ||
| 344 | MOV DI,OFFSET CONV_PAGES ;ascii string for numb fill pgs | ||
| 345 | MOV AX,END_BACMEM_SEG ;upper limit of fill | ||
| 346 | SUB AX,START_BACMEM_SEG ;minus lower start of fill | ||
| 347 | MOV CL,10 | ||
| 348 | SHR AX,CL ;convert to number 16k blocks | ||
| 349 | CALL CNVDECAT | ||
| 350 | |||
| 351 | MOV DI,OFFSET RES_PAGES ;ascii string for pinta reserved pages | ||
| 352 | MOV AX,STARTING_BLOCK ;number of 4k pages res for pinta | ||
| 353 | SHR AX,1 | ||
| 354 | SHR AX,1 ;convert to 16k pages | ||
| 355 | CALL CNVDECAT | ||
| 356 | |||
| 357 | MOV DI,OFFSET EMS_PAGES ;ascii string available ems pages | ||
| 358 | MOV AX,FREE_PAGES ;free pages | ||
| 359 | CALL CNVDECAT | ||
| 360 | |||
| 361 | MOV DI,OFFSET PF_START ;ascii string page frame | ||
| 362 | MOV AX,PAGE_FRAME_STA ;page frame | ||
| 363 | CALL CNVHEXAT | ||
| 364 | |||
| 365 | ;gga MOV DX,OFFSET PAGE_FRAME_MSG ;start of message | ||
| 366 | ;gga MOV AH,9 ;dos prt string | ||
| 367 | ;gga INT 21H ;status msg1 | ||
| 368 | |||
| 369 | CMP STARTING_BLOCK,0 | ||
| 370 | ; $IF A | ||
| 371 | JNA $$IF117 | ||
| 372 | MOV DX,OFFSET RESERVE_MSG ;start of message | ||
| 373 | MOV AH,9 ;dos prt string | ||
| 374 | INT 21H ;status msg2 | ||
| 375 | ; $ENDIF | ||
| 376 | $$IF117: | ||
| 377 | |||
| 378 | ;gga MOV DX,OFFSET AVAIL_MSG ;start of message | ||
| 379 | ;gga MOV AH,9 ;dos prt string | ||
| 380 | ;gga INT 21H ;status msg3 | ||
| 381 | |||
| 382 | ;indicate that the card has been tested | ||
| 383 | MOV DX,MODE_REG | ||
| 384 | IN AL,DX ;read mode reg | ||
| 385 | OR AL,WARM_MASK ;turn on warm start bit | ||
| 386 | OUT DX,AL ;write it back | ||
| 387 | |||
| 388 | call Calc_INT15_Space ;calculate remaining INT 15h space ;an000; dms; | ||
| 389 | call Steal_INT15 ;hook INT 15h ;an000; dms; | ||
| 390 | call Steal_Int13 ;hook INT 13h ;an004; dms; | ||
| 391 | |||
| 392 | JMP COMMON_EXIT_PATH | ||
| 393 | |||
| 394 | |||
| 395 | GENERAL_FAILURE: | ||
| 396 | |||
| 397 | LDS BX,CS:RH_PTRA ;ELSE ... | ||
| 398 | MOV AX,STAT_GENFAIL ;INDICATE A GENERAL FAILURE | ||
| 399 | MOV RH.RHC_STA,AX ;WRITE IT TO RH STATUS | ||
| 400 | ;------------------------ | ||
| 401 | ; adds by GGA | ||
| 402 | ;------------------------ | ||
| 403 | xor ax,ax ; zero segment and offset | ||
| 404 | mov rh.rh0_endo,ax ; offset of ending addr | ||
| 405 | push cs | ||
| 406 | pop ax | ||
| 407 | mov rh.rh0_ends,ax ; segment of ending addr | ||
| 408 | |||
| 409 | mov rh.rh0_err,0ffh ; error flag for DOS | ||
| 410 | |||
| 411 | mov rh.rh0_nun,al ; = 0 causes installation failure | ||
| 412 | |||
| 413 | jmp skip_size | ||
| 414 | ;------------------------ | ||
| 415 | COMMON_EXIT_PATH: | ||
| 416 | ;move cursor to next line so other messages are clear | ||
| 417 | PUSH CS ;get cs | ||
| 418 | POP DS ;into ds | ||
| 419 | MOV DX,OFFSET NEXT_LINE + 1 ;get offset of string | ||
| 420 | MOV AH,9 ;dos print string | ||
| 421 | INT 21H | ||
| 422 | |||
| 423 | LDS BX,CS:RH_PTRA ;ADDRESSABILITY INTO RH | ||
| 424 | MOV AX,OFFSET RESIDENT + STACK_SIZE + 100H | ||
| 425 | MOV RH.RH0_ENDO,AX ;OFFSET OF ENDING ADDR | ||
| 426 | PUSH CS | ||
| 427 | POP AX | ||
| 428 | MOV RH.RH0_ENDS,AX ;OFFSET OF ENDING ADDR | ||
| 429 | |||
| 430 | skip_size: ; gga | ||
| 431 | |||
| 432 | POP CX ;recover old ss | ||
| 433 | POP DX ;recover old sp | ||
| 434 | CLI ;ints off during swap | ||
| 435 | MOV SP,CX ;restore old sp | ||
| 436 | MOV SS,DX ;restore old ss | ||
| 437 | STI ;ints back on | ||
| 438 | |||
| 439 | |||
| 440 | RET | ||
| 441 | INIT ENDP | ||
| 442 | |||
| 443 | ;-----------------------------------------------------------------------; | ||
| 444 | ; STEAL_INT67 changes the INT 67H vector to point to this ; | ||
| 445 | ; Memory Manager to field subsequent calls. ; | ||
| 446 | ;-----------------------------------------------------------------------; | ||
| 447 | STEAL_INT67 PROC | ||
| 448 | PUSH DS | ||
| 449 | XOR AX,AX | ||
| 450 | MOV DS,AX ;set DS = 0 | ||
| 451 | ASSUME DS:INT_VEC | ||
| 452 | CLI ;disable interrupts | ||
| 453 | LES DI,DS:EMS_VEC ;get addressing into vector | ||
| 454 | MOV DS:EMS_VECO,OFFSET EMS_INT67 ;offset of new INT routine | ||
| 455 | MOV DS:EMS_VECS,CS ;segment of new INT routine | ||
| 456 | STI ;enable interrupts again | ||
| 457 | POP DS ;restore DS | ||
| 458 | RET | ||
| 459 | STEAL_INT67 ENDP | ||
| 460 | |||
| 461 | ;-----------------------------------------------------------------------; | ||
| 462 | ; VIRT2REAL puts the XMA into 'virtual' mode with the translate ; | ||
| 463 | ; table written such that memory is mapped just as it was ; | ||
| 464 | ; in 'real' mode. (Either 256-640k or 512-640k reamains fixed ; | ||
| 465 | ; for all ID's) ; | ||
| 466 | ; ; | ||
| 467 | ; all registers are preserved ; | ||
| 468 | ; ; | ||
| 469 | ;-----------------------------------------------------------------------; | ||
| 470 | VIRT2REAL PROC | ||
| 471 | PUSH AX | ||
| 472 | PUSH BX | ||
| 473 | PUSH CX | ||
| 474 | PUSH DX | ||
| 475 | PUSH DS ;save these registers | ||
| 476 | |||
| 477 | PUSH CS ;get this segment | ||
| 478 | POP DS ;into ds | ||
| 479 | ;inhibit all of XMA memory before going into virtual mode | ||
| 480 | XOR AX,AX ;start at segment 0 | ||
| 481 | XOR BL,BL ;inhibit | ||
| 482 | MOV CX,1024/4 ;all 4k blocks in pc space | ||
| 483 | CALL INHIBLK | ||
| 484 | ;now map virtual mode to look like real mode | ||
| 485 | MOV AX,START_BACMEM_SEG ;starting 'fill' segment | ||
| 486 | MOV DX,AX ;get it into dx | ||
| 487 | XCHG DH,DL ;and shr 8 to convert it to 4k block # | ||
| 488 | XOR BH,BH ;start at task ID=0 | ||
| 489 | MOV BL,1 ;enable | ||
| 490 | MOV CX,16 ;do for all 16 task ID's | ||
| 491 | ; $DO | ||
| 492 | $$DO119: | ||
| 493 | PUSH AX ;save these | ||
| 494 | PUSH CX ;because they are | ||
| 495 | PUSH DX ;destroyed by call | ||
| 496 | MOV CX,160 ;640K = 160*4K blocks | ||
| 497 | SUB CX,DX ;minus starting 4K block | ||
| 498 | ;is # 4K blocks to map for this ID | ||
| 499 | CALL SETXLAT ;write trans table accordingly | ||
| 500 | POP DX ;recover these registers | ||
| 501 | POP CX | ||
| 502 | POP AX | ||
| 503 | INC BH ;next ID | ||
| 504 | ; $ENDDO LOOP | ||
| 505 | LOOP $$DO119 | ||
| 506 | |||
| 507 | MOV DX,MODE_REG | ||
| 508 | IN AL,DX ;read mode reg | ||
| 509 | OR AL,VIRT_MODE ;turn on virtual bit | ||
| 510 | OUT DX,AL ;write it back | ||
| 511 | |||
| 512 | POP DS ;restore these registers | ||
| 513 | POP DX | ||
| 514 | POP CX | ||
| 515 | POP BX | ||
| 516 | POP AX | ||
| 517 | RET | ||
| 518 | VIRT2REAL ENDP | ||
| 519 | |||
| 520 | |||
| 521 | include romscan.inc ; code to do romscan for hole location/verification | ||
| 522 | INCLUDE PARMPARS.INC ;Routines to parse the parameters | ||
| 523 | ; on the CONFIG.SYS line | ||
| 524 | |||
| 525 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 526 | ;³ Subprocedure: BACK_CONV_MEM ³ | ||
| 527 | ;³ ³ | ||
| 528 | ;³ Purpose: Called when a portion of the XMA card is used to back ³ | ||
| 529 | ;³ conventional memory. This is the case on an XMA 1 ³ | ||
| 530 | ;³ card (256K - 640K disabled on planar) and on the ³ | ||
| 531 | ;³ XMA/A card when WSP's XMA/A initialization device ³ | ||
| 532 | ;³ driver has disabled the planar. ³ | ||
| 533 | ;³ This procedure will mark the Page Allocation List for ³ | ||
| 534 | ;³ these entries with an ASCII value (for debugging) that ³ | ||
| 535 | ;³ is above the range of eligible pointer values. ³ | ||
| 536 | ;³ At the time this proc is called the PAL has not been ³ | ||
| 537 | ;³ initialized. Initialization will skip these entries. ³ | ||
| 538 | ;³ ³ | ||
| 539 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 540 | BACK_CONV_MEM PROC | ||
| 541 | MOV AX,END_BACMEM_SEG ;upper segment of backed memory | ||
| 542 | SUB AX,START_BACMEM_SEG ;subtract seg of backed memory start | ||
| 543 | MOV CL,10 ;conver # of segments to # of 16 K | ||
| 544 | SHR AX,CL ; pages used for fill (div by 1024) | ||
| 545 | SUB TOTAL_EMS_PAGES,AX ;subtract from total EMS pages | ||
| 546 | ; (but not from TOTAL_SYStem_PAGES) | ||
| 547 | SUB FREE_PAGES,AX ;subtract from free EMS pages | ||
| 548 | MOV CX,AX ;Put # of backing pages into CX | ||
| 549 | PUSH CX ; and save it on stack | ||
| 550 | |||
| 551 | MOV AX,START_BACMEM_SEG ;Convert the segment value for the | ||
| 552 | MOV CL,10 ; start of backed memory to its | ||
| 553 | SHR AX,CL ; corresponding page number | ||
| 554 | MOV DX,TYPE PAGE_ALLOC_LIST ; then convert to the correct @RH8 | ||
| 555 | MUL DX ; entry in the page alloc list @RH8 | ||
| 556 | MOV SI,AX ; store PAL offset into SI | ||
| 557 | POP CX ;recover loop counter for # backed | ||
| 558 | ;mark these pages used in page list but do not assign a handle | ||
| 559 | BACK_MEM_PAL: | ||
| 560 | MOV PAGE_LIST_ENTRY,BACMEM_ALLOC ;Mark the PAL with ascii @RH8 | ||
| 561 | ADD SI,TYPE PAGE_ALLOC_LIST ;Next entry in PAL @RH8 | ||
| 562 | LOOP BACK_MEM_PAL | ||
| 563 | ;Remove code here that used to reserve pages for | ||
| 564 | ; WSP by reading a value on the CONFIG.SYS line. | ||
| 565 | ; Instead, WSP will make an IOCTL call for the | ||
| 566 | ; number of pages it needs. | ||
| 567 | BACK_CONV_MEM ENDP | ||
| 568 | |||
| 569 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 570 | ;³ Subprocedure: INIT_PAL ³ | ||
| 571 | ;³ ³ | ||
| 572 | ;³ Purpose: This subprocedure will link the Page Allocation List. ³ | ||
| 573 | ;³ The head pointer to the list of available pages ³ | ||
| 574 | ;³ (PAL_FREE_PTR) is initialized to the top EMS page, ³ | ||
| 575 | ;³ and all available pages are linked from top to bottom. ³ | ||
| 576 | ;³ All free pages will initially be contiguous, except on ³ | ||
| 577 | ;³ an XMA 1 system. With XMA 1, 256-640K on the card is ³ | ||
| 578 | ;³ used to back conventional memory. The free list will ³ | ||
| 579 | ;³ skip around these pages (pages 16 to 40). ³ | ||
| 580 | ;³ ³ | ||
| 581 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 582 | INIT_PAL PROC | ||
| 583 | push cs ;set up addressibility ;an000; dms; | ||
| 584 | pop ds ; ;an000; dms; | ||
| 585 | |||
| 586 | cmp Total_EMS_Pages,0 ;any pages? ;an000; dms; | ||
| 587 | je Init_Pal_End ;no - exit ;an000; dms; | ||
| 588 | |||
| 589 | mov ax,Total_Sys_Pages ;top of EMS pages = ;an000; dms; | ||
| 590 | add ax,Resr_Ext_Pgs ; total EMS pages + ;an000; dms; | ||
| 591 | dec ax ; rsv ext. pages - 1 ;an000; dms; | ||
| 592 | |||
| 593 | |||
| 594 | mov si,ax ;ptr to free page ;an000; dms; | ||
| 595 | shl si,1 ;make an index ;an000; dms; | ||
| 596 | mov Page_List_Entry,Pal_Null ;set last entry to null ;ac007; dms; | ||
| 597 | shr si,1 ;convert to ptr value ;an007; dms; | ||
| 598 | mov di,si ;place in di ;an007; dms; | ||
| 599 | |||
| 600 | dec ax ;next page ;an000; dms; | ||
| 601 | mov cx,Total_EMS_Pages ;loop for all entries ;an000; dms; | ||
| 602 | dec cx ; but the last ;an000; dms; | ||
| 603 | |||
| 604 | INIT_PAL_LP: | ||
| 605 | |||
| 606 | cmp cx,0 ;at end? ;an000; dms; | ||
| 607 | je Init_Pal_Loop_Exit ;yes - exit ;an000; dms; | ||
| 608 | |||
| 609 | mov si,ax ;ptr to next page ;ac007; dms; | ||
| 610 | shl si,1 ;make an index ;ac007; dms; | ||
| 611 | cmp Page_Alloc_List[si],BacMem_Alloc ;backfilled memory? ;ac007; dms; | ||
| 612 | jne Init_Pal_Entry ;no - set up ptr's ;an000; dms; | ||
| 613 | dec ax ;yes - next ptr value ;an000; dms; | ||
| 614 | jmp Init_Pal_LP ;keep on looping ;an000; dms; | ||
| 615 | INIT_PAL_ENTRY: | ||
| 616 | mov Page_List_Entry,di ;set up ptr value ;ac007; dms; | ||
| 617 | mov di,si ;next ptr value ;ac007; dms; | ||
| 618 | shr di,1 ;make a ptr value ;an007; dms; | ||
| 619 | INIT_PAL_BOT: | ||
| 620 | dec ax ;get next ptr value ;an000; dms; | ||
| 621 | dec cx ;dec loop counter ;an000; dms; | ||
| 622 | jmp INIT_PAL_LP ;continue looping ;an000; dms; | ||
| 623 | |||
| 624 | Init_Pal_Loop_Exit: | ||
| 625 | mov Pal_Free_Ptr,di ;init free ptr ;an007; dms; | ||
| 626 | |||
| 627 | INIT_PAL_END: | ||
| 628 | ret ;return to caller ;an000; dms; | ||
| 629 | INIT_PAL ENDP | ||
| 630 | |||
| 631 | ;-----------------------------------------------------------------------; | ||
| 632 | ; This routine will convert a number in (AX) to a ; | ||
| 633 | ; 4 byte ascii string equivalent to a 4 digit decimal ; | ||
| 634 | ; number and write it at the address pointed to ; | ||
| 635 | ; by ES:DI. Leading zeroes are suppressed. ; | ||
| 636 | ; ; | ||
| 637 | ; On entry: (AX) = number to be converted ; | ||
| 638 | ; ES:DI= address where string is to be written ; | ||
| 639 | ; ; | ||
| 640 | ; On exit: all registers are preserved ; | ||
| 641 | ; ; | ||
| 642 | ;-----------------------------------------------------------------------; | ||
| 643 | |||
| 644 | CNVDECAT PROC | ||
| 645 | |||
| 646 | PUSH AX | ||
| 647 | PUSH CX | ||
| 648 | PUSH DX | ||
| 649 | PUSH DI ;save these registers | ||
| 650 | |||
| 651 | MOV CX,4 ;loop counter 4 digits | ||
| 652 | ; $DO | ||
| 653 | $$DO152: | ||
| 654 | XOR DX,DX ;clear hi word of dividend | ||
| 655 | ;ax is low word of dividend | ||
| 656 | DIV CS:TEN ;divide by 10 | ||
| 657 | OR DL,30H ;make modulo into ascii digit | ||
| 658 | PUSH DX ;put it on stack | ||
| 659 | ; $ENDDO LOOP ;repeat for all 4 digits | ||
| 660 | LOOP $$DO152 | ||
| 661 | |||
| 662 | MOV CX,4 ;recover 4 digits from stack | ||
| 663 | ; $DO | ||
| 664 | $$DO154: | ||
| 665 | POP AX ;recover next most sign digit | ||
| 666 | CMP AL,'0' ;is it a '0' | ||
| 667 | ; $IF NE | ||
| 668 | JE $$IF155 | ||
| 669 | PUSH AX ;back on stack for next loop | ||
| 670 | JMP LEAD_DIGIT ;if not then we found leading non zero | ||
| 671 | ; $ENDIF | ||
| 672 | $$IF155: | ||
| 673 | ; $ENDDO LOOP ;else continiue til non zero found | ||
| 674 | LOOP $$DO154 | ||
| 675 | LEAD_DIGIT: | ||
| 676 | ; $IF NCXZ ;only if cx is non zero | ||
| 677 | JCXZ $$IF158 | ||
| 678 | ; $DO | ||
| 679 | $$DO159: | ||
| 680 | POP AX ;recover next digit | ||
| 681 | MOV ES:BYTE PTR [DI],AL ;write it to string | ||
| 682 | INC DI ;point to next byte | ||
| 683 | ; $ENDDO LOOP ;repeat for all digits | ||
| 684 | LOOP $$DO159 | ||
| 685 | ; $ENDIF | ||
| 686 | $$IF158: | ||
| 687 | |||
| 688 | POP DI ;recover these registers | ||
| 689 | POP DX | ||
| 690 | POP CX | ||
| 691 | POP AX | ||
| 692 | |||
| 693 | RET ;return to caller | ||
| 694 | CNVDECAT ENDP | ||
| 695 | |||
| 696 | |||
| 697 | |||
| 698 | ;-----------------------------------------------------------------------; | ||
| 699 | ; This routine will convert a number in (AX) to a ; | ||
| 700 | ; 4 byte ascii string equivalent to a 4 digit hexadecimal ; | ||
| 701 | ; number and write it at the address pointed to ; | ||
| 702 | ; by ES:DI. Leading zeroes are suppressed. ; | ||
| 703 | ; ; | ||
| 704 | ; On entry: (AX) = number to be converted ; | ||
| 705 | ; ES:DI= address where string is to be written ; | ||
| 706 | ; ; | ||
| 707 | ; On exit: all registers are preserved ; | ||
| 708 | ; ; | ||
| 709 | ;-----------------------------------------------------------------------; | ||
| 710 | |||
| 711 | DEC2ASCII DB '0123456789ABCDEF' | ||
| 712 | |||
| 713 | |||
| 714 | CNVHEXAT PROC | ||
| 715 | |||
| 716 | PUSH AX | ||
| 717 | PUSH BX | ||
| 718 | PUSH CX | ||
| 719 | PUSH DX | ||
| 720 | PUSH DI ;save these registers | ||
| 721 | PUSH DS | ||
| 722 | |||
| 723 | PUSH CS | ||
| 724 | POP DS | ||
| 725 | |||
| 726 | MOV BX,OFFSET DEC2ASCII | ||
| 727 | MOV CX,4 ;loop counter 4 digits | ||
| 728 | ; $DO | ||
| 729 | $$DO162: | ||
| 730 | XOR DX,DX ;clear hi word of dividend | ||
| 731 | ;ax is low word of dividend | ||
| 732 | DIV SIXTEEN ;divide by 10 | ||
| 733 | |||
| 734 | PUSH AX ;save quotient | ||
| 735 | MOV AX,DX ;get modulo into ax | ||
| 736 | XLAT DEC2ASCII ;convert al to ascii | ||
| 737 | MOV DX,AX ;get it into dx | ||
| 738 | POP AX ;recover quotient | ||
| 739 | PUSH DX ;put ascii modulo on stack | ||
| 740 | ; $ENDDO LOOP ;repeat for all 4 digits | ||
| 741 | LOOP $$DO162 | ||
| 742 | |||
| 743 | MOV CX,4 ;recover 4 digits from stack | ||
| 744 | ; $DO | ||
| 745 | $$DO164: | ||
| 746 | ;gga POP AX ;recover next most sign digit | ||
| 747 | ;gga CMP AL,'0' ;is it a '0' | ||
| 748 | ; $IF NE | ||
| 749 | ;gga JE $$IF165 | ||
| 750 | ;gga PUSH AX ;back on stack for next loop | ||
| 751 | ;gga JMP CNVH1 ;if not then we found leading non zero | ||
| 752 | ; $ENDIF | ||
| 753 | $$IF165: | ||
| 754 | ; $ENDDO LOOP ;else continiue til non zero found | ||
| 755 | ;gga LOOP $$DO164 | ||
| 756 | CNVH1: | ||
| 757 | ; $IF NCXZ ;only if cx is non zero | ||
| 758 | JCXZ $$IF168 | ||
| 759 | ; $DO | ||
| 760 | $$DO169: | ||
| 761 | POP AX ;recover next digit | ||
| 762 | MOV ES:BYTE PTR [DI],AL ;write it to string | ||
| 763 | INC DI ;point to next byte | ||
| 764 | ; $ENDDO LOOP ;repeat for all digits | ||
| 765 | LOOP $$DO169 | ||
| 766 | ; $ENDIF | ||
| 767 | $$IF168: | ||
| 768 | |||
| 769 | POP DS | ||
| 770 | POP DI ;recover these registers | ||
| 771 | POP DX | ||
| 772 | POP CX | ||
| 773 | POP BX | ||
| 774 | POP AX | ||
| 775 | |||
| 776 | RET ;return to caller | ||
| 777 | CNVHEXAT ENDP | ||
| 778 | |||
| 779 | ;-----------------------------------------------------------------------; | ||
| 780 | ; STEAL_INT15 changes the INT 15H vector to point to this EMS' ; | ||
| 781 | ; so that subsequent calls to INT15H may determine the actual ; | ||
| 782 | ; size of EM after EMS' allocation of it ; | ||
| 783 | ;-----------------------------------------------------------------------; | ||
| 784 | STEAL_INT15 PROC | ||
| 785 | PUSH DS | ||
| 786 | push ax | ||
| 787 | |||
| 788 | CMP MODEL_BYTE,PS2MODEL80 ;If a PS2/80 treat as XMA memory ;an000; dms; | ||
| 789 | je Steal_INT15_Exit ;do not hook INT15h ;an000; dms; | ||
| 790 | |||
| 791 | CMP MODEL_BYTE,PC_AT ;If the model byte is for an 'AT' @RH2 | ||
| 792 | jne Steal_INT15_Hook ; type (80286 processor), check @RH2 | ||
| 793 | |||
| 794 | MOV AH,0C0h ; the XMA/A or XMO card @RH2 | ||
| 795 | INT 15h ; @RH2 | ||
| 796 | CMP INT15_SEC_MOD,SEC_MOD_TB; @RH2 | ||
| 797 | JE Steal_INT15_Hook ; @RH2 | ||
| 798 | |||
| 799 | CMP INT15_SEC_MOD,SEC_MOD_RR;If 'AT' but not PS/2 50 or 60, @RH2 | ||
| 800 | JE Steal_INT15_Hook ; then family 1 (uses XMA 1 card) @RH2 | ||
| 801 | JMP Steal_INT15_Exit ; @RH2 | ||
| 802 | |||
| 803 | Steal_INT15_Hook: | ||
| 804 | |||
| 805 | XOR AX,AX | ||
| 806 | MOV DS,AX ;set DS = 0 | ||
| 807 | ASSUME DS:INT_VEC15 | ||
| 808 | CLI ;disable interrupts | ||
| 809 | LES DI,DS:EM_VEC ;get original vector's content | ||
| 810 | MOV CS:INTV15O,DI ;save original vector | ||
| 811 | MOV CS:INTV15S,ES | ||
| 812 | MOV DS:EM_VECO,OFFSET XMA_INT15 ;offset of new INT routine | ||
| 813 | MOV DS:EM_VECS,CS ;segment of new INT routine | ||
| 814 | STI ;enable interrupts again | ||
| 815 | |||
| 816 | Steal_INT15_Exit: | ||
| 817 | |||
| 818 | pop ax | ||
| 819 | POP DS ;restore DS | ||
| 820 | RET | ||
| 821 | STEAL_INT15 ENDP | ||
| 822 | |||
| 823 | |||
| 824 | ;-----------------------------------------------------------------------; | ||
| 825 | ; Calc_INT15_Space calculates the remaining extended memory for ; | ||
| 826 | ; the system. This value will be used by all subsequent calls ; | ||
| 827 | ; to function 88h, INT 15h. ; | ||
| 828 | ;-----------------------------------------------------------------------; | ||
| 829 | Calc_INT15_Space proc near ;an000; dms; | ||
| 830 | |||
| 831 | push ax ;save regs ;an000; dms; | ||
| 832 | push bx ; ;an000; dms; | ||
| 833 | push cx ; ;an002; dms; | ||
| 834 | push dx ; ;an000; dms; | ||
| 835 | |||
| 836 | mov ah,EM_Size_Get ;get extended mem ;an000; dms; | ||
| 837 | int 15h ; ;an000; dms; | ||
| 838 | |||
| 839 | mov cl,4 ;divide by 16 ;an002; dms; | ||
| 840 | shr ax,cl ; to get page count ;an002; dms; | ||
| 841 | |||
| 842 | sub ax,cs:Total_Sys_Pages ;new extended mem size ;an002; dms; | ||
| 843 | xor dx,dx ;get K count ;an002; dms; | ||
| 844 | mov bx,cs:Sixteen ; ;an002; dms; | ||
| 845 | mul bx ; ;an002; dms; | ||
| 846 | mov word ptr cs:EM_Ksize,ax ;save new size ;an000; dms; | ||
| 847 | |||
| 848 | pop dx ;restore regs ;an000; dms; | ||
| 849 | pop cx ; ;an002; dms; | ||
| 850 | pop bx ; ;an000; dms; | ||
| 851 | pop ax ; ;an000; dms; | ||
| 852 | |||
| 853 | ret | ||
| 854 | |||
| 855 | Calc_INT15_Space endp ;an000; dms; | ||
| 856 | |||
| 857 | |||
| 858 | ;-----------------------------------------------------------------------; | ||
| 859 | ; STEAL_INT13 changes the INT 13H vector to point to this EMS' ; | ||
| 860 | ; so that subsequent calls to INT13H may properly handle DMA ; | ||
| 861 | ; to EMS pages. ; | ||
| 862 | ;-----------------------------------------------------------------------; | ||
| 863 | Steal_Int13 PROC ;an004; dms; | ||
| 864 | PUSH DS ;an004; dms; | ||
| 865 | push ax ;an004; dms; | ||
| 866 | |||
| 867 | CMP MODEL_BYTE,PS2MODEL80 ;If not a PS2/80 don't hook INT 13h ;an004; dms; | ||
| 868 | jne Steal_INT15_Exit ; ;an004; dms; | ||
| 869 | |||
| 870 | XOR AX,AX | ||
| 871 | MOV DS,AX ;set DS = 0 | ||
| 872 | ASSUME DS:INT_VEC13 | ||
| 873 | CLI ;disable interrupts | ||
| 874 | LES DI,DS:DK_VEC ;get original vector's content | ||
| 875 | MOV CS:INTV13O,DI ;save original vector | ||
| 876 | MOV CS:INTV13S,ES | ||
| 877 | MOV DS:DK_VECO,OFFSET I13_Handler ;offset of new INT routine | ||
| 878 | MOV DS:DK_VECS,CS ;segment of new INT routine | ||
| 879 | STI ;enable interrupts again | ||
| 880 | |||
| 881 | Steal_INT13_Exit: | ||
| 882 | |||
| 883 | pop ax | ||
| 884 | POP DS ;restore DS | ||
| 885 | RET | ||
| 886 | STEAL_INT13 ENDP | ||
diff --git a/v4.0/src/DEV/XMA2EMS/EMS_US.MSG b/v4.0/src/DEV/XMA2EMS/EMS_US.MSG new file mode 100644 index 0000000..72100b8 --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/EMS_US.MSG | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | LF EQU 0AH ;ASCII line feed | ||
| 2 | CR EQU 0DH ;ASCII carriage return | ||
| 3 | |||
| 4 | CRLF DB CR,LF ; gga used to skip a blank line | ||
| 5 | db '$' | ||
| 6 | |||
| 7 | WELCOME_MSG DB 'XMA2EMS: Expanded Memory Manager' | ||
| 8 | DB CR,LF | ||
| 9 | DB '(c)Copyright 1988 Microsoft Corporation All rights reserved' | ||
| 10 | DB CR,LF | ||
| 11 | DB '$' | ||
| 12 | |||
| 13 | DGS_START_MSG DB CR,LF | ||
| 14 | DB 'Performing XMA diagnostics: ' | ||
| 15 | DB '$' | ||
| 16 | |||
| 17 | DGS_END_MSG DB CR,LF | ||
| 18 | DB 'Diagnostics completed ' | ||
| 19 | DB CR,LF,LF | ||
| 20 | DB '$' | ||
| 21 | |||
| 22 | PAGE_FRAME_MSG DB 'Page Frame starts at........................ ' | ||
| 23 | PF_START DB 'XXXX' | ||
| 24 | DB ':0' | ||
| 25 | DB CR,LF | ||
| 26 | DB 'Pages mapped to conventional memory......... ' | ||
| 27 | CONV_PAGES DB '0 ' | ||
| 28 | DB CR,LF | ||
| 29 | DB '$' | ||
| 30 | RESERVE_MSG DB 'Pages reserved for 3270 PC Control Program.. ' | ||
| 31 | RES_PAGES DB '0 ' | ||
| 32 | DB CR,LF | ||
| 33 | DB '$' | ||
| 34 | AVAIL_MSG DB 'Pages available for expanded memory......... ' | ||
| 35 | EMS_PAGES DB '0 ' | ||
| 36 | DB CR,LF | ||
| 37 | DB '$' | ||
| 38 | |||
| 39 | XMA1_ERR_MSG DB CR,LF | ||
| 40 | DB 'Adapter error ' | ||
| 41 | DB CR,LF | ||
| 42 | DB '$' | ||
| 43 | |||
| 44 | NOT_FOUND_MSG DB CR,LF | ||
| 45 | DB 'Cannot find adapter ' | ||
| 46 | DB CR,LF | ||
| 47 | DB '$' | ||
| 48 | |||
| 49 | PARM_ERR_MSG DB CR,LF | ||
| 50 | DB 'Parameter syntax or value error ' | ||
| 51 | DB CR,LF | ||
| 52 | DB '$' | ||
| 53 | |||
| 54 | NO_EMUL_MSG DB CR,LF | ||
| 55 | DB 'Cannot find XMA Emulator device driver ' | ||
| 56 | DB CR,LF | ||
| 57 | DB '$' | ||
| 58 | |||
| 59 | WRONG_EMUL_MSG DB CR,LF | ||
| 60 | DB 'Incorrect version of XMAEM.SYS ' | ||
| 61 | DB CR,LF | ||
| 62 | DB '$' | ||
| 63 | |||
| 64 | WRONG_XMAA_MSG DB CR,LF | ||
| 65 | DB 'Incorrect version of INDXMAA.SYS ' | ||
| 66 | DB CR,LF | ||
| 67 | DB '$' | ||
| 68 | |||
| 69 | REQ_EMS_ERR_MSG DB CR,LF | ||
| 70 | DB 'Too many EMS pages requested in /X parameter ' | ||
| 71 | DB CR,LF | ||
| 72 | DB '$' | ||
| 73 | |||
| 74 | NOT_INSTL_MSG DB 'Expanded Memory Manager has NOT been installed' | ||
| 75 | DB CR,LF | ||
| 76 | DB '$' | ||
| 77 | |||
| 78 | CONFLICT_MSG DB 'Specified page address conflicts with installed adapter at address ' | ||
| 79 | CONFL_ADDRESS DB '0 ' | ||
| 80 | DB CR,LF | ||
| 81 | DB '$' | ||
| 82 | |||
| 83 | HOLE_MSG DB 'Possible 16KB page available at address ' | ||
| 84 | HOLE_ADDRESS DB '0 ' | ||
| 85 | DB CR,LF | ||
| 86 | DB '$' | ||
| 87 | |||
| 88 | FRAME_MSG DB CR,LF | ||
| 89 | DB 'Possible 64KB frame available at address ' | ||
| 90 | FRAME_ADDRESS DB '0 ' | ||
| 91 | DB CR,LF | ||
| 92 | DB '$' | ||
| 93 | |||
| 94 | NO_PAGES_MSG DB 'No page addresses specified' | ||
| 95 | DB CR,LF | ||
| 96 | DB '$' | ||
| 97 | |||
| 98 | |||
| 99 | SIZE_MSG1 DB SIZE1_END - 2 -$ | ||
| 100 | MEM_OK DB 4 DUP (?) | ||
| 101 | DB ' KB OK$' | ||
| 102 | SIZE1_END EQU $ | ||
| 103 | |||
| 104 | NEXT_LINE DB NXT_LN_END - 2 -$ | ||
| 105 | DB ' ',CR,LF,'$' | ||
| 106 | NXT_LN_END EQU $ | ||
| 107 | |||
| 108 | Prompt_Msg db 'Press any key to continue . . .',CR,LF | ||
| 109 | db '$' | ||
| 110 | |||
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 | ||
diff --git a/v4.0/src/DEV/XMA2EMS/I13HOOK.INC b/v4.0/src/DEV/XMA2EMS/I13HOOK.INC new file mode 100644 index 0000000..2f981c2 --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/I13HOOK.INC | |||
| @@ -0,0 +1,449 @@ | |||
| 1 | |||
| 2 | include MSBDS.INC ;include BDS struc ;an000; dms; | ||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | ;========================================================================= | ||
| 8 | ; I13_Handler - This routine is the main driver of the | ||
| 9 | ; INT 13h hook. | ||
| 10 | ;========================================================================= | ||
| 11 | |||
| 12 | I13_Handler proc far ; ;an000; dms; | ||
| 13 | |||
| 14 | jmp I13_Handler_Start | ||
| 15 | |||
| 16 | |||
| 17 | I13_Max_Head db ? ;max head count on drive ;an000; dms; | ||
| 18 | I13_SPT db ? ;max sectors/track count ;an000; dms; | ||
| 19 | I13_BPS dw ? ;max number bytes/sector ;an000; dms; | ||
| 20 | I13_Bytes_Per_Para dw 10h ;number of bytes per paragraph ;an000; dms; | ||
| 21 | I13_Bytes_Per_EMS_Page dw 4000h ;bytes per EMS page ;an000; dms; | ||
| 22 | I13_Paras_Per_Sector dw ? ;paras per sector ;an000; dms; | ||
| 23 | I13_DD_Per_Sector dw ? ;double words per sector ;an000; dms; | ||
| 24 | I13_Operation db ? ;INT 13h function ;an000; dms; | ||
| 25 | I13_Sector_Count db ? ;sector count ;an000; dms; | ||
| 26 | I13_Track_Number dw ? ;track number ;an000; dms; | ||
| 27 | I13_Sector_Number db ? ;sector number ;an000; dms; | ||
| 28 | I13_Head_Number db ? ;head number ;an000; dms; | ||
| 29 | I13_Drive_Number db ? ;drive number ;an000; dms; | ||
| 30 | I13_Sectors_To_Trf db 1 ;current sectors to trf ;an000; dms; | ||
| 31 | I13_Curr_Trf_Cnt db ? ;total transfer count in secs ;an000; dms; | ||
| 32 | I13_Trf_Off dw ? ;current address for trf ;an000; dms; | ||
| 33 | I13_Trf_Seg dw ? ;an000; dms; | ||
| 34 | I13_512_Byte_Buffer db 512 dup(0) ;buffer for sector ;an000; dms; | ||
| 35 | |||
| 36 | I13_Handler_Start: | ||
| 37 | |||
| 38 | sti ;ints on ;an000; dms; | ||
| 39 | cmp ah,02h ;read operation? ;an000; dms; | ||
| 40 | je I13_Handler_Get_Parms ;yes - get drive parms ;an000; dms; | ||
| 41 | |||
| 42 | cmp ah,03h ;write operation? ;an000; dms; | ||
| 43 | je I13_Handler_Get_Parms ;yes - get drive parms ;an000; dms; | ||
| 44 | |||
| 45 | jmp cs:IntV13 ;neither - go to old INT 13h ;an000; dms; | ||
| 46 | |||
| 47 | I13_Handler_Get_Parms: | ||
| 48 | |||
| 49 | call I13_Get_Dev_Parms ;get device parms for this drive;an000; dms; | ||
| 50 | jnc I13_Handler_Range_Ck ;we have device data ;an000; dms; | ||
| 51 | jmp cs:IntV13 ;go to old INT 13h vector ;an000; dms; | ||
| 52 | |||
| 53 | I13_Handler_Range_Ck: | ||
| 54 | |||
| 55 | call I13_Target_Source_Range_Ck ;crosses the 640k boundary? ;an000; dms; | ||
| 56 | jc I13_Handler_Request_Break ;break up the request ;an000; dms; | ||
| 57 | jmp cs:IntV13 ;go to old INT 13h vector ;an000; dms; | ||
| 58 | |||
| 59 | I13_Handler_Request_Break: | ||
| 60 | |||
| 61 | call I13_Request_Break_Up ;break up I13 request ;an000; dms; | ||
| 62 | |||
| 63 | ret 2 ;return to caller ;an000; dms; | ||
| 64 | ;clear the flags from the stack | ||
| 65 | ; and pass back ours | ||
| 66 | I13_Handler endp ; ;an000; dms; | ||
| 67 | |||
| 68 | |||
| 69 | |||
| 70 | ;========================================================================= | ||
| 71 | ; I13_Target_Source_Range_Ck - This routine determines if the | ||
| 72 | ; target or source resides in an EMS | ||
| 73 | ; page. | ||
| 74 | ; | ||
| 75 | ; Inputs : ES:BX - Source/target address | ||
| 76 | ; | ||
| 77 | ; Outputs : CY - if address resides in an EMS page | ||
| 78 | ; NC - address not in an EMS page | ||
| 79 | ;========================================================================= | ||
| 80 | |||
| 81 | |||
| 82 | I13_Target_Source_Range_Ck proc near ; ;an000; dms; | ||
| 83 | |||
| 84 | push ax ;save regs ;an000; dms; | ||
| 85 | push bx ; ;an000; dms; | ||
| 86 | push cx ; ;an000; dms; | ||
| 87 | push si ; ;an000; dms; | ||
| 88 | push ds ; ;an000; dms; | ||
| 89 | |||
| 90 | mov ax,cs ;get cs addressibility ;an000; dms; | ||
| 91 | mov ds,ax ; ;an000; dms; | ||
| 92 | mov si,offset cs:Map_Table ;point to the map table ;an000; dms; | ||
| 93 | |||
| 94 | mov cx,cs:Map_Count ;get the number of phys. pages ;an000; dms; | ||
| 95 | |||
| 96 | I13_Target_Source_Loop: | ||
| 97 | |||
| 98 | cmp cx,0 ;at end? ;an000; dms; | ||
| 99 | je I13_Target_Source_Not_EMS_Page ;yes - source/target not in pg ;an000; dms; | ||
| 100 | |||
| 101 | mov ax,ds:[si].Phys_Page_Segment ;get the segment value ;an000; dms; | ||
| 102 | mov bx,es ; ;an000; dms; | ||
| 103 | cmp bx,ax ;source/target > EMS page? ;an000; dms; | ||
| 104 | jb I13_Target_Source_Not_EMS_Page ;no - we are OK for old INT 13 ;an000; dms; | ||
| 105 | ;must be >= EMS page | ||
| 106 | |||
| 107 | add ax,400h ;get end address of EMS page ;an000; dms; | ||
| 108 | cmp bx,ax ;source/target < end of EMS pg? ;an000; dms; | ||
| 109 | jb I13_Target_Source_In_EMS_Page ;yes - we are in a page ;an000; dms; | ||
| 110 | |||
| 111 | add si,type Mappable_Phys_Page_Struct ;adjust pointer to next page ;an000; dms; | ||
| 112 | dec cx ;dec counter ;an000; dms; | ||
| 113 | |||
| 114 | jmp I13_Target_Source_Loop ;continue loop ;an000; dms; | ||
| 115 | |||
| 116 | I13_Target_Source_Not_EMS_Page: | ||
| 117 | |||
| 118 | clc ;flag not in EMS page ;an000; dms; | ||
| 119 | jmp I13_Target_Source_Exit ;exit routine ;an000; dms; | ||
| 120 | |||
| 121 | I13_Target_Source_In_EMS_Page: | ||
| 122 | |||
| 123 | stc ;flag in an EMS page ;an000; dms; | ||
| 124 | |||
| 125 | I13_Target_Source_Exit: | ||
| 126 | |||
| 127 | pop ds ;restore regs ;an000; dms; | ||
| 128 | pop si ; ;an000; dms; | ||
| 129 | pop cx ; ;an000; dms; | ||
| 130 | pop bx ; ;an000; dms; | ||
| 131 | pop ax ; ;an000; dms; | ||
| 132 | |||
| 133 | ret ; ;an000; dms; | ||
| 134 | |||
| 135 | I13_Target_Source_Range_Ck endp ; ;an000; dms; | ||
| 136 | |||
| 137 | |||
| 138 | ;========================================================================= | ||
| 139 | ; I13_Request_Break_Up - Break up the INT 13h request onto 16k | ||
| 140 | ; boundaries. | ||
| 141 | ; | ||
| 142 | ; Inputs : AH - 02 (Read) | ||
| 143 | ; 03 (Write) | ||
| 144 | ; AL - Sector count | ||
| 145 | ; CH - Track number | ||
| 146 | ; CL - Sector number | ||
| 147 | ; DH - Head number | ||
| 148 | ; DL - Drive number | ||
| 149 | ; ES:BX - Buffer address | ||
| 150 | ; | ||
| 151 | ; Outputs : Data transferred | ||
| 152 | ;========================================================================= | ||
| 153 | |||
| 154 | |||
| 155 | I13_Request_Break_Up proc near ; ;an000; dms; | ||
| 156 | |||
| 157 | push bx ;save regs ;an000; dms; | ||
| 158 | push cx ; ;an000; dms; | ||
| 159 | push dx ; ;an000; dms; | ||
| 160 | push di ; ;an000; dms; | ||
| 161 | push si ; ;an000; dms; | ||
| 162 | push ds ; ;an000; dms; | ||
| 163 | push es ; ;an000; dms; | ||
| 164 | |||
| 165 | |||
| 166 | mov cs:I13_Trf_Seg,es ;save segment ;an000; dms; | ||
| 167 | mov cs:I13_Trf_Off,bx ;save offset ;an000; dms; | ||
| 168 | mov cs:I13_Curr_Trf_Cnt,0 ;init transfer count ;an000; dms; | ||
| 169 | mov cs:I13_Operation,ah ;save operation ;an000; dms; | ||
| 170 | mov cs:I13_Sector_Count,al ;save sector count ;an000; dms; | ||
| 171 | |||
| 172 | |||
| 173 | mov byte ptr cs:I13_Track_Number,ch ;save starting track number ;an000; dms; | ||
| 174 | mov ch,cl ;xchg bytes ;an000; dms; | ||
| 175 | shr ch,1 ;shift 6 bits ;an000; dms; | ||
| 176 | shr ch,1 ; ;an000; dms; | ||
| 177 | shr ch,1 ; ;an000; dms; | ||
| 178 | shr ch,1 ; ;an000; dms; | ||
| 179 | shr ch,1 ; ;an000; dms; | ||
| 180 | shr ch,1 ; ;an000; dms; | ||
| 181 | |||
| 182 | mov byte ptr cs:I13_Track_Number[+1],ch ;high byte for cylinder ;an000; dms; | ||
| 183 | and cl,00111111b ;get bits 0-5 for sector number ;an000; dms; | ||
| 184 | |||
| 185 | mov cs:I13_Sector_Number,cl ;save starting sector number ;an000; dms; | ||
| 186 | mov cs:I13_Head_Number,dh ;save starting head number ;an000; dms; | ||
| 187 | mov cs:I13_Drive_Number,dl ;save drive number ;an000; dms; | ||
| 188 | |||
| 189 | mov cl,cs:I13_Sector_Count ;while sectors ;an000; dms; | ||
| 190 | |||
| 191 | cmp cs:I13_Operation,02h ;read? ;an000; dms; | ||
| 192 | jne I13_Request_Write ;must be a write ;an000; dms; | ||
| 193 | |||
| 194 | I13_Request_Read: | ||
| 195 | |||
| 196 | cmp cl,0 ;at end? ;an000; dms; | ||
| 197 | je I13_Request_Success ;exit we are done ;an000; dms; | ||
| 198 | |||
| 199 | lea bx,cs:I13_512_Byte_Buffer ;point to 512 byte buffer ;an000; dms; | ||
| 200 | mov ax,cs ;pass cs to es ;an000; dms; | ||
| 201 | mov es,ax ; ;an000; dms; | ||
| 202 | |||
| 203 | call I13_Invoke ;do the INT 13h to our buffer ;an000; dms; | ||
| 204 | jc I13_Request_Failed ;signal failure ;an000; dms; | ||
| 205 | mov ax,cs ;point to our buffer to the ;an000; dms; | ||
| 206 | mov ds,ax ; transfer ;an000; dms; | ||
| 207 | mov si,offset cs:I13_512_Byte_Buffer; ;an000; dms; | ||
| 208 | |||
| 209 | mov es,cs:I13_Trf_Seg ;restore seg to target ;an000; dms; | ||
| 210 | mov di,cs:I13_Trf_Off ;restore off to target ;an000; dms; | ||
| 211 | |||
| 212 | push cx ;save cx across move ;an000; dms; | ||
| 213 | cld ;do a forward move ;an000; dms; | ||
| 214 | mov cx,cs:I13_DD_Per_Sector ; for 128 dd's ;an000; dms; | ||
| 215 | db 66h ;op code for dd word move ;an000; dms; | ||
| 216 | rep movsw ;do the move - wow that was fast;an000; dms; | ||
| 217 | pop cx ;restore it ;an000; dms; | ||
| 218 | |||
| 219 | call I13_Adjust ;adjust our pointers ;an000; dms; | ||
| 220 | |||
| 221 | dec cl ;decrease sector counter ;an000; dms; | ||
| 222 | jmp I13_Request_Read ;continue loop ;an000; dms; | ||
| 223 | |||
| 224 | I13_Request_Write: | ||
| 225 | |||
| 226 | cmp cl,0 ;at end? ;an000; dms; | ||
| 227 | je I13_Request_Success ;exit we are done ;an000; dms; | ||
| 228 | |||
| 229 | mov ax,cs ;point to 512 byte buffer ;an000; dms; | ||
| 230 | mov es,ax ; ;an000; dms; | ||
| 231 | mov di,offset cs:I13_512_Byte_Buffer; ;an000; dms; | ||
| 232 | |||
| 233 | mov ds,cs:I13_Trf_Seg ;get source segment ;an000; dms; | ||
| 234 | mov si,cs:I13_Trf_Off ;get source offset ;an000; dms; | ||
| 235 | |||
| 236 | push cx ;save cx across move ;an000; dms; | ||
| 237 | cld ;do a forward move ;an000; dms; | ||
| 238 | mov cx,cs:I13_DD_Per_Sector ; for 128 dd's ;an000; dms; | ||
| 239 | db 66h ;op code for dd word move ;an000; dms; | ||
| 240 | rep movsw ;do the move - wow that was fast;an000; dms; | ||
| 241 | pop cx ;restore it ;an000; dms; | ||
| 242 | |||
| 243 | lea bx,cs:I13_512_Byte_Buffer ;point to 512 byte buffer ;an000; dms; | ||
| 244 | mov ax,cs ;pass cs to es ;an000; dms; | ||
| 245 | mov es,ax ; ;an000; dms; | ||
| 246 | |||
| 247 | call I13_Invoke ;do the INT 13h to our buffer ;an000; dms; | ||
| 248 | jc I13_Request_Failed ;signal failure ;an000; dms; | ||
| 249 | call I13_Adjust ;adjust our pointers ;an000; dms; | ||
| 250 | |||
| 251 | dec cl ;decrease sector counter ;an000; dms; | ||
| 252 | jmp I13_Request_Write ;continue loop ;an000; dms; | ||
| 253 | |||
| 254 | I13_Request_Failed: | ||
| 255 | |||
| 256 | jmp I13_Request_Exit ;exit on error ;an000; dms; | ||
| 257 | |||
| 258 | |||
| 259 | I13_Request_Success: | ||
| 260 | |||
| 261 | xor ax,ax ;clear status byte ;an000; dms; | ||
| 262 | |||
| 263 | I13_Request_Exit: | ||
| 264 | |||
| 265 | pop es ;restore regs ;an000; dms; | ||
| 266 | pop ds ; ;an000; dms; | ||
| 267 | pop si ; ;an000; dms; | ||
| 268 | pop di ; ;an000; dms; | ||
| 269 | pop dx ; ;an000; dms; | ||
| 270 | pop cx ; ;an000; dms; | ||
| 271 | pop bx ; ;an000; dms; | ||
| 272 | |||
| 273 | |||
| 274 | ret ; ;an000; dms; | ||
| 275 | |||
| 276 | I13_Request_Break_Up endp ; ;an000; dms; | ||
| 277 | |||
| 278 | |||
| 279 | |||
| 280 | ;========================================================================= | ||
| 281 | ; I13_Adjust - This routine adjusts the needed fields for | ||
| 282 | ; the next iteration of INT 13h. | ||
| 283 | ; | ||
| 284 | ; Inputs : I13_Sectors_To_Trf - Sectors just read/written | ||
| 285 | ; I13_Sector_Number - Starting sector number for trf | ||
| 286 | ; I13_Head_Number - Starting head number for trf | ||
| 287 | ; I13_Track_Number - Starting track number for trf | ||
| 288 | ; | ||
| 289 | ; Outputs : I13_Sector_Number - New starting sector for trf | ||
| 290 | ; I13_Head_Number - New starting head for trf | ||
| 291 | ; I13_Track_Number - New starting track for trf | ||
| 292 | ;========================================================================= | ||
| 293 | |||
| 294 | |||
| 295 | I13_Adjust proc near ;adjust values ;an000; dms; | ||
| 296 | |||
| 297 | push ax ;save regs ;an000; dms; | ||
| 298 | |||
| 299 | inc cs:I13_Sector_Number ;next sector ;an000; dms; | ||
| 300 | mov al,cs:I13_Sector_Number ; ;an000; dms; | ||
| 301 | cmp al,cs:I13_SPT ;> sectors on track? ;an000; dms; | ||
| 302 | jna I13_Adjust_Exit ;no ;an000; dms; | ||
| 303 | mov cs:I13_Sector_Number,1 ;yes - start at next ;an000; dms; | ||
| 304 | inc cs:I13_Head_Number ;next head ;an000; dms; | ||
| 305 | mov al,cs:I13_Head_Number ; ;an000; dms; | ||
| 306 | cmp al,cs:I13_Max_Head ;> head count ;an000; dms; | ||
| 307 | jb I13_Adjust_Exit ;no ;an000; dms; | ||
| 308 | mov cs:I13_Head_Number,0 ;yes - head 0 ;an000; dms; | ||
| 309 | inc cs:I13_Track_Number ;next track ;an000; dms; | ||
| 310 | |||
| 311 | I13_Adjust_Exit: | ||
| 312 | |||
| 313 | mov ax,cs:I13_Paras_Per_Sector ;get bytes per sector ;an000; dms; | ||
| 314 | add cs:I13_Trf_Seg,ax ;adjust segment ;an000; dms; | ||
| 315 | |||
| 316 | pop ax ;restore regs ;an000; dms; | ||
| 317 | |||
| 318 | ret ; ;an000; dms; | ||
| 319 | |||
| 320 | I13_Adjust endp ; ;an000; dms; | ||
| 321 | |||
| 322 | |||
| 323 | ;========================================================================= | ||
| 324 | ; I13_Invoke - This routine sets up the regs for the INT 13h | ||
| 325 | ; and invokes it for the sector we need. | ||
| 326 | ; | ||
| 327 | ; Inputs : I13_Operation - read/write | ||
| 328 | ; I13_Track_Number - cylinder to read/write | ||
| 329 | ; I13_Sector_Number - starting sector for read/write | ||
| 330 | ; I13_Head_Number - starting head | ||
| 331 | ; I13_Drive_Number - starting drive | ||
| 332 | ; | ||
| 333 | ; Outputs : NC - good read/write | ||
| 334 | ; CY - bad read/write | ||
| 335 | ;========================================================================= | ||
| 336 | |||
| 337 | I13_Invoke proc near ;invoke INT 13h ;an000; dms; | ||
| 338 | |||
| 339 | push bx ;save regs ;an000; dms; | ||
| 340 | push cx ; ;an000; dms; | ||
| 341 | push dx ; ;an000; dms; | ||
| 342 | |||
| 343 | mov ah,cs:I13_Operation ;get function call ;an000; dms; | ||
| 344 | mov al,cs:I13_Sectors_To_Trf ;get sectors to transfer ;an000; dms; | ||
| 345 | |||
| 346 | mov ch,byte ptr cs:I13_Track_Number ;get track number ;an000; dms; | ||
| 347 | mov cl,byte ptr cs:I13_Track_Number[+1] ;get high 2 bits ;an000; dms; | ||
| 348 | shl cl,1 ;put bit is positions 6&7 ;an000; dms; | ||
| 349 | shl cl,1 ; ;an000; dms; | ||
| 350 | shl cl,1 ; ;an000; dms; | ||
| 351 | shl cl,1 ; ;an000; dms; | ||
| 352 | shl cl,1 ; ;an000; dms; | ||
| 353 | shl cl,1 ; ;an000; dms; | ||
| 354 | or cl,cs:I13_Sector_Number ;place the sector number in cl ;an000; dms; | ||
| 355 | |||
| 356 | mov dh,cs:I13_Head_Number ;get head number ;an000; dms; | ||
| 357 | mov dl,cs:I13_Drive_Number ;get drive number ;an000; dms; | ||
| 358 | pushf | ||
| 359 | call cs:IntV13 ;go to old vector ;an000; dms; | ||
| 360 | inc cs:I13_Curr_Trf_Cnt ;increment counter ;an000; dms; | ||
| 361 | |||
| 362 | pop dx ;restore regs ;an000; dms; | ||
| 363 | pop cx ; ;an000; dms; | ||
| 364 | pop bx ; ;an000; dms; | ||
| 365 | |||
| 366 | ret ; ;an000; dms; | ||
| 367 | |||
| 368 | I13_Invoke endp ; ;an000; dms; | ||
| 369 | |||
| 370 | |||
| 371 | ;========================================================================= | ||
| 372 | ; I13_Get_Dev_Parms - This routine obtains the device parameters for | ||
| 373 | ; the drive being accessed for the INT 13h. | ||
| 374 | ; | ||
| 375 | ; Inputs : DL - drive number | ||
| 376 | ; | ||
| 377 | ; Outputs : I13_Max_Head - max head count on drive | ||
| 378 | ; I13_SPT - max sectors/track count for drive | ||
| 379 | ; CY - error | ||
| 380 | ; NC - no error | ||
| 381 | ;========================================================================= | ||
| 382 | |||
| 383 | |||
| 384 | |||
| 385 | I13_Get_Dev_Parms proc near ;get sectors/track & head cnt. ;an000; dms; | ||
| 386 | |||
| 387 | push ax ;save regs ;an000; dms; | ||
| 388 | push bx ; ;an000; dms; | ||
| 389 | push cx ; ;an000; dms; | ||
| 390 | push dx ; ;an000; dms; | ||
| 391 | push di ; ;an000; dms; | ||
| 392 | push ds ; ;an000; dms; | ||
| 393 | |||
| 394 | mov ax,0803h ;get the BDS table ;an000; dms; | ||
| 395 | int 2fh ; ;an000; dms; | ||
| 396 | |||
| 397 | I13_Get_Dev_Next_Entry: | ||
| 398 | |||
| 399 | cmp ds:[di].Drivenum,dl ;do we have our drive? ;an000; dms; | ||
| 400 | je I13_Get_Dev_Save_Parms ;yes get data ;an000; dms; | ||
| 401 | cmp word ptr ds:[di].Link[+0],-1 ;last entry in list? ;an000; dms; | ||
| 402 | je I13_Get_Dev_Parms_Error_Exit ;yes - did not find drive ;an000; dms; | ||
| 403 | mov ax,word ptr ds:[di].Link[+0] ;get offset of next entry ;an000; dms; | ||
| 404 | mov bx,word ptr ds:[di].Link[+2] ;get segment of next entry ;an000; dms; | ||
| 405 | mov ds,bx ;stuff into ds:di ;an000; dms; | ||
| 406 | mov di,ax ; ;an000; dms; | ||
| 407 | jmp I13_Get_Dev_Next_Entry ;continue ;an000; dms; | ||
| 408 | |||
| 409 | I13_Get_Dev_Save_Parms: | ||
| 410 | |||
| 411 | mov ax,ds:[di].BytePerSec ;get byte count per sector ;an000; dms; | ||
| 412 | mov cs:I13_BPS,ax ; ;an000; dms; | ||
| 413 | |||
| 414 | xor dx,dx ;clear high word ;an000; dms; | ||
| 415 | div cs:I13_Bytes_Per_Para ;get number of paras in sector ;an000; dms; | ||
| 416 | mov cs:I13_Paras_Per_Sector,ax ;save it ;an000; dms; | ||
| 417 | shl ax,1 ;get DD's per sector ;an000; dms; | ||
| 418 | shl ax,1 ; ;an000; dms; | ||
| 419 | mov cs:I13_DD_Per_Sector,ax ; ;an000; dms; | ||
| 420 | |||
| 421 | mov ax,ds:[di].SecLim ;get sectors per track ;an000; dms; | ||
| 422 | mov cs:I13_SPT,al ; ;an000; dms; | ||
| 423 | |||
| 424 | mov ax,ds:[di].HdLim ;get max head count ;an000; dms; | ||
| 425 | mov cs:I13_Max_Head,al ; ;an000; dms; | ||
| 426 | |||
| 427 | clc ;flag data found ;an000; dms; | ||
| 428 | |||
| 429 | jmp I13_Get_Dev_Parms_Exit ; ;an000; dms; | ||
| 430 | |||
| 431 | |||
| 432 | I13_Get_Dev_Parms_Error_Exit: | ||
| 433 | |||
| 434 | stc ;flag no data found ;an000; dms; | ||
| 435 | |||
| 436 | I13_Get_Dev_Parms_Exit: | ||
| 437 | |||
| 438 | pop ds ;restore regs ;an000; dms; | ||
| 439 | pop di ; ;an000; dms; | ||
| 440 | pop dx ; ;an000; dms; | ||
| 441 | pop cx ; ;an000; dms; | ||
| 442 | pop bx ; ;an000; dms; | ||
| 443 | pop ax ; ;an000; dms; | ||
| 444 | |||
| 445 | ret ; ;an000; dms; | ||
| 446 | |||
| 447 | I13_Get_Dev_Parms endp ; ;an000; dms; | ||
| 448 | |||
| 449 | |||
diff --git a/v4.0/src/DEV/XMA2EMS/LIM40.INC b/v4.0/src/DEV/XMA2EMS/LIM40.INC new file mode 100644 index 0000000..8cd006c --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/LIM40.INC | |||
| @@ -0,0 +1,1792 @@ | |||
| 1 | page | ||
| 2 | ;------------------------------------------------------------------- | ||
| 3 | ; | ||
| 4 | ; Equates that are specific to LIM 4.0 functions go here | ||
| 5 | ; | ||
| 6 | ;------------------------------------------------------------------- | ||
| 7 | |||
| 8 | null equ 0 ; null value, used everywhere | ||
| 9 | max_phys_pages equ 255 ; largest allowable phys page | ||
| 10 | |||
| 11 | sf_pm_get equ 0 ; 4f00 - get partial map | ||
| 12 | sf_pm_set equ 1 ; 4f01 - set partial map | ||
| 13 | sf_pm_size equ 2 ; 4f02 - get partial map size | ||
| 14 | |||
| 15 | mu_ppn equ 0 ; 5000 - map/unmap multiple | ||
| 16 | mu_seg equ 1 ; 5001 - map/unmap multiple | ||
| 17 | mu_max_fcn equ 1 ; 50 - map/unmap multiple | ||
| 18 | |||
| 19 | Hn_Attr_Max_Fcn equ 2 ; 52xx - max subfunction ;an000; dms; | ||
| 20 | |||
| 21 | sf_hn_get equ 0 ; 5300 - get handle name | ||
| 22 | sf_hn_set equ 1 ; 5301 - set handle name | ||
| 23 | hn_max_fcn equ 1 ; 53 - handle name sub-functions 00, 01 | ||
| 24 | |||
| 25 | sf_hd_get equ 0 ; 5400 - get handle dir | ||
| 26 | sf_hd_search equ 1 ; 5401 - search for named handle | ||
| 27 | sf_hd_total equ 2 ; 5402 - get total number of handles | ||
| 28 | hd_max_fcn equ 2 ; 54 - get handle directory s-f's 00, 01, 02 | ||
| 29 | |||
| 30 | Add_Get_Array equ 0 ; 5800 - Get Mappable Physical Address Array | ||
| 31 | Add_Get_Size equ 1 ; 5801 - Get Mappable Physical Address Array Entries | ||
| 32 | |||
| 33 | hi_info equ 0 ; 5900 - hardware info | ||
| 34 | hi_raw equ 1 ; 5901 - # raw pages | ||
| 35 | |||
| 36 | am_get equ 0 ; 5b00 - get alternate map register set | ||
| 37 | am_set equ 1 ; 5b01 - set alternate map register set | ||
| 38 | am_size equ 2 ; 5b02 - get alternate map save array size | ||
| 39 | am_alloc equ 3 ; 5b03 - allocate alternate map register set | ||
| 40 | am_dealloc equ 4 ; 5b04 - deallocate alternate map register set | ||
| 41 | am_dma_alloc equ 5 ; 5b05 - allocate DMA register set | ||
| 42 | am_dma_enable equ 6 ; 5b06 - enable DMA register set | ||
| 43 | am_dma_disable equ 7 ; 5b07 - disable DMA register set | ||
| 44 | am_dma_dealloc equ 8 ; 5b08 - deallocate DMA register set | ||
| 45 | |||
| 46 | os_enable equ 0 ; 5d00 - enable OS/E function | ||
| 47 | os_disable equ 1 ; 5d01 - disable OS/E function | ||
| 48 | os_access equ 2 ; 5d02 - "return" access key function | ||
| 49 | |||
| 50 | map_pages_fcn equ 44h ; function code used to map pages | ||
| 51 | get_free_pages equ 42h ; function code used to get free page count | ||
| 52 | |||
| 53 | read_clock equ 2ch ; function code to read clock | ||
| 54 | dos_int equ 21h ; interrupt 21 | ||
| 55 | xor_mask equ 0ffffh ; mask used to confuse the random numbers a little | ||
| 56 | |||
| 57 | ppm_struct STRUC ; define the structure | ||
| 58 | phys_page_offset dw ? ; offsets into PPM entry | ||
| 59 | ppm_handle_offset dw ? | ||
| 60 | ppm_log_page_offset dw ? | ||
| 61 | ppm_struct ENDS | ||
| 62 | |||
| 63 | page | ||
| 64 | ;------------------------------------------------------------------- | ||
| 65 | ; | ||
| 66 | ; 4F - get/set partial page map | ||
| 67 | ; | ||
| 68 | ; INPUT: | ||
| 69 | ; AL = 00, get partial page map pm_get | ||
| 70 | ; 01, set partial page map pm_set | ||
| 71 | ; 02, get partial page map size pm_size | ||
| 72 | ; | ||
| 73 | ; OUTPUT: | ||
| 74 | ; See individual function headers | ||
| 75 | ; | ||
| 76 | ;------------------------------------------------------------------- | ||
| 77 | partial_map proc | ||
| 78 | |||
| 79 | ; use AL value to select sub-function | ||
| 80 | |||
| 81 | cmp al,sf_pm_get ; al = 00, get partial page map | ||
| 82 | je pm_get | ||
| 83 | |||
| 84 | cmp al,sf_pm_set ; al = 01, set partial page map | ||
| 85 | je pm_set | ||
| 86 | |||
| 87 | cmp al,sf_pm_size ; al = 02, get partial page map size | ||
| 88 | jne pm_invalid_sfcn | ||
| 89 | jmp pm_size | ||
| 90 | |||
| 91 | |||
| 92 | ; invalid sub-function, report the error | ||
| 93 | |||
| 94 | pm_invalid_sfcn: | ||
| 95 | mov ah,ems_code8F ; invalid sub-function code | ||
| 96 | ret | ||
| 97 | |||
| 98 | page | ||
| 99 | ;------------------------------------------------------------------- | ||
| 100 | ; | ||
| 101 | ; 4F00 - get partial page map | ||
| 102 | ; | ||
| 103 | ; INPUT: | ||
| 104 | ; DS:SI -> partial page map | ||
| 105 | ; | ||
| 106 | ; dw ? ; segment count (number | ||
| 107 | ; ; of following entries) | ||
| 108 | ; dw ? ; segment address to save | ||
| 109 | ; : ; (repeats count times) | ||
| 110 | ; : | ||
| 111 | ; | ||
| 112 | ; ES:DI -> user array for mapping info | ||
| 113 | ; size determined by function 4F02 | ||
| 114 | ; | ||
| 115 | ; | ||
| 116 | ; OUTPUT: | ||
| 117 | ; AH = 00, No error | ||
| 118 | ; 80H, Software error | ||
| 119 | ; 81H, Hardware error | ||
| 120 | ; 84H, Invalid function | ||
| 121 | ; 8FH, Invalid sub-function | ||
| 122 | ; A3H, Contents of control structure are invalid | ||
| 123 | ; | ||
| 124 | ; ES:DI -> saved partial state array | ||
| 125 | ; format for this is un-disclosed to the user | ||
| 126 | ; but will be: | ||
| 127 | ; | ||
| 128 | ; ppm_count dw ? ; number of saved entries | ||
| 129 | ; ppm_phys_page dw ? ; physical page | ||
| 130 | ; ppm_handle dw ? ; handle | ||
| 131 | ; ppm_log_page dw ? ; logical page | ||
| 132 | ; : ; repeats for each requested page | ||
| 133 | ; : | ||
| 134 | ; | ||
| 135 | ; | ||
| 136 | ;------------------------------------------------------------------- | ||
| 137 | pm_get: | ||
| 138 | |||
| 139 | push bx ; save some regs | ||
| 140 | push cx | ||
| 141 | push dx | ||
| 142 | push di | ||
| 143 | push si | ||
| 144 | push ds | ||
| 145 | |||
| 146 | mov di,cs:[bp].IE_Saved_DI_Reg ; restore caller's DI, pointer to mapping control structure | ||
| 147 | |||
| 148 | |||
| 149 | ;------------------------------------------------------------------- | ||
| 150 | |||
| 151 | ; get count from caller's control structure | ||
| 152 | |||
| 153 | mov cx,ds:[si] ; the first word of the control | ||
| 154 | ; structure holds the # of entries | ||
| 155 | |||
| 156 | cmp cx,0 ; 0 pages requested? ;an000; dms; | ||
| 157 | je PM_Get_Error_A3 ; yes - flag an error ;an000; dms; | ||
| 158 | |||
| 159 | cmp cx,cs:Map_Count ; do some sanity checking | ||
| 160 | jbe pm_phys_ok ; requested number is ok, do the copies | ||
| 161 | |||
| 162 | ; They asked for more than we can possibly have. Sounds like trouble. | ||
| 163 | |||
| 164 | PM_Get_Error_A3: | ||
| 165 | |||
| 166 | mov ah,ems_codea3 ; bad stuff in the control structure | ||
| 167 | jmp pm_exit00 ; return the error code | ||
| 168 | |||
| 169 | pm_phys_ok: | ||
| 170 | mov cx,DS:word ptr [si] ; get count from control structure | ||
| 171 | mov ES:word ptr [di],cx ; save count in save area | ||
| 172 | add di,2 ; increment save area pointer | ||
| 173 | |||
| 174 | ;------------------------------------------------------------------- | ||
| 175 | ; | ||
| 176 | ; everything is OK so far, copy the entries requested | ||
| 177 | ; | ||
| 178 | ;------------------------------------------------------------------- | ||
| 179 | |||
| 180 | ppm_copies: | ||
| 181 | |||
| 182 | add si,2 ; point to next segment number | ||
| 183 | mov ax,DS:word ptr [si] ; get segment value from control structure | ||
| 184 | |||
| 185 | push si ; save user's si | ||
| 186 | push ds ; save user's ds | ||
| 187 | push cx ; save counter for outer loop | ||
| 188 | |||
| 189 | ; ready to do the lookup and copy operation | ||
| 190 | |||
| 191 | push cs ; make DS:SI point to internal data area | ||
| 192 | pop ds | ||
| 193 | lea si,map_table | ||
| 194 | |||
| 195 | mov cx,map_count ; number of mappable segments | ||
| 196 | |||
| 197 | ppm_inner_copy_loop: | ||
| 198 | cmp ax,ds:word ptr [si+phys_page_segment] ; is this entry the requested? | ||
| 199 | jne ppm_not_yet ; no, try again | ||
| 200 | |||
| 201 | mov cx,ppm_size ; number of bytes to copy | ||
| 202 | cld ; make sure direction flag is right | ||
| 203 | add si,2 ; point to phys_page_number | ||
| 204 | |||
| 205 | rep movsb ; copy the entry | ||
| 206 | |||
| 207 | sub si,2 ; reset si | ||
| 208 | |||
| 209 | jmp ppm_entry_done ; done with this copy, go on | ||
| 210 | |||
| 211 | ppm_not_yet: | ||
| 212 | add si,type mappable_phys_page_struct ; point to next entry | ||
| 213 | loop ppm_inner_copy_loop ; try some more | ||
| 214 | |||
| 215 | pop cx ; restore counter for outer loop | ||
| 216 | pop ds ; restore user's ds | ||
| 217 | pop si ; restore user's si | ||
| 218 | mov ah,EMS_Code8B ; we have an invalid segment specified ;an000; dms; | ||
| 219 | jmp PM_Exit00 ; exit the program | ||
| 220 | |||
| 221 | ppm_entry_done: | ||
| 222 | |||
| 223 | ; restore pointer to control structure | ||
| 224 | |||
| 225 | pop cx ; restore counter for outer loop | ||
| 226 | pop ds ; restore user's ds | ||
| 227 | pop si ; restore user's si | ||
| 228 | |||
| 229 | |||
| 230 | loop ppm_copies ; keep going until proper number of | ||
| 231 | ; entries have been copied | ||
| 232 | |||
| 233 | xor ah,ah ; good return code | ||
| 234 | ;------------------------------------------------------------------- | ||
| 235 | pm_exit00: | ||
| 236 | pop ds ; restore these registers | ||
| 237 | pop si | ||
| 238 | pop di | ||
| 239 | pop dx | ||
| 240 | pop cx | ||
| 241 | pop bx | ||
| 242 | |||
| 243 | ret ; return to caller | ||
| 244 | |||
| 245 | |||
| 246 | |||
| 247 | page | ||
| 248 | ;------------------------------------------------------------------- | ||
| 249 | ; | ||
| 250 | ; 4F01 - set partial page map | ||
| 251 | ; | ||
| 252 | ; INPUT: | ||
| 253 | ; DS:SI -> source array | ||
| 254 | ; Format: | ||
| 255 | ; | ||
| 256 | ; ppm_count dw ? ; number of saved entries | ||
| 257 | ; ppm_phys_page dw ? ; physical page | ||
| 258 | ; ppm_handle dw ? ; handle | ||
| 259 | ; ppm_log_page dw ? ; logical page | ||
| 260 | ; : ; repeats ppm_count times | ||
| 261 | ; : | ||
| 262 | ; | ||
| 263 | ; | ||
| 264 | ; OUTPUT: | ||
| 265 | ; AH = 00, No error | ||
| 266 | ; 80H, Software error | ||
| 267 | ; 81H, Hardware error | ||
| 268 | ; 84H, Invalid function | ||
| 269 | ; 8FH, Invalid sub-function | ||
| 270 | ; A3H, Contents of source array invalid | ||
| 271 | ; | ||
| 272 | ;------------------------------------------------------------------- | ||
| 273 | pm_set: | ||
| 274 | |||
| 275 | push bx ; save some regs | ||
| 276 | push cx | ||
| 277 | push dx | ||
| 278 | push di | ||
| 279 | push si | ||
| 280 | push ds | ||
| 281 | |||
| 282 | mov cx,DS:word ptr [si] ; get number of entries in save area | ||
| 283 | |||
| 284 | cmp cx,0 ; is the count zero? | ||
| 285 | je pm_set_error_A3 ; yes - error ;an000; dms; | ||
| 286 | |||
| 287 | cmp cx,cs:Map_Count ; greater than phys pages avail? ;an000; dms; | ||
| 288 | jbe count_ok ; no - data not corrupted ;an000; dms; | ||
| 289 | |||
| 290 | pm_set_error_A3: | ||
| 291 | |||
| 292 | mov ah,EMS_CODEA3 ; control structure error | ||
| 293 | jmp pm_exit01 ; exit | ||
| 294 | |||
| 295 | count_ok: | ||
| 296 | add si,2 ; point to first entry in save area | ||
| 297 | |||
| 298 | pm01_loop: | ||
| 299 | |||
| 300 | mov ax,DS:word ptr [si+phys_page_offset] ; set up regs for map_l_to_p | ||
| 301 | mov ah,map_pages_fcn | ||
| 302 | mov dx,DS:word ptr [si+ppm_handle_offset] | ||
| 303 | mov bx,DS:word ptr [si+ppm_log_page_offset] | ||
| 304 | |||
| 305 | cmp dx,0ffffh ; is there a real entry? | ||
| 306 | je no_map ; no, skip the call to map_l_to_p | ||
| 307 | |||
| 308 | call map_l_to_p ; make the mapping call | ||
| 309 | |||
| 310 | no_map: | ||
| 311 | add si,type ppm_struct ; point to next entry | ||
| 312 | |||
| 313 | loop pm01_loop ; | ||
| 314 | |||
| 315 | xor ah,ah ; good return code | ||
| 316 | pm_exit01: | ||
| 317 | |||
| 318 | pop ds ; restore these registers | ||
| 319 | pop si | ||
| 320 | pop di | ||
| 321 | pop dx | ||
| 322 | pop cx | ||
| 323 | pop bx | ||
| 324 | |||
| 325 | ret ; return to caller | ||
| 326 | |||
| 327 | |||
| 328 | page | ||
| 329 | ;------------------------------------------------------------------- | ||
| 330 | ; | ||
| 331 | ; 4F02 - get partial page map size | ||
| 332 | ; | ||
| 333 | ; INPUT: | ||
| 334 | ; AX = 4f02h | ||
| 335 | ; | ||
| 336 | ; BX = number of pages in partial page map | ||
| 337 | ; | ||
| 338 | ; OUTPUT: | ||
| 339 | ; AH = 00, No error | ||
| 340 | ; 80H, Software error | ||
| 341 | ; 81H, Hardware error | ||
| 342 | ; 84H, Invalid function | ||
| 343 | ; 8FH, Invalid sub-function | ||
| 344 | ; | ||
| 345 | ; AL = size of partial page map save array | ||
| 346 | ; number of bytes that will be needed | ||
| 347 | ; to save the requested number of pages | ||
| 348 | ; | ||
| 349 | ;------------------------------------------------------------------- | ||
| 350 | pm_size: | ||
| 351 | |||
| 352 | push dx ; save dx | ||
| 353 | |||
| 354 | cmp bx,0 ; 0 pages requested? ;an000; dms; | ||
| 355 | je PM_Size_Error_8B ; yes flag an error ;an000; dms; | ||
| 356 | |||
| 357 | cmp bx,cs:Map_Count ; page count > phys pages? ;an000; dms; | ||
| 358 | jbe PM_Size_Return ; no - continue ;an000; dms; | ||
| 359 | |||
| 360 | PM_Size_Error_8B: | ||
| 361 | |||
| 362 | mov ah,EMS_Code8B ; signal page count exceeded ;an000; dms; | ||
| 363 | jmp PM_Exit02 ; exit routine ;an000; dms; | ||
| 364 | |||
| 365 | PM_Size_Return: | ||
| 366 | |||
| 367 | mov dx,bx ; number of pages times ... | ||
| 368 | mov ax,ppm_size ; * size of an entry ... | ||
| 369 | mul dx ; = number of bytes in save array | ||
| 370 | add ax,2 ; increase by 2 to include count word | ||
| 371 | |||
| 372 | xor ah,ah ; good return code | ||
| 373 | |||
| 374 | pm_exit02: | ||
| 375 | pop dx ; restore dx | ||
| 376 | |||
| 377 | ret ; return to caller | ||
| 378 | |||
| 379 | partial_map endp | ||
| 380 | |||
| 381 | |||
| 382 | page | ||
| 383 | ;------------------------------------------------------------------- | ||
| 384 | ; | ||
| 385 | ; 50 - map/unmap multiple handle pages | ||
| 386 | ; | ||
| 387 | ; INPUT: | ||
| 388 | ; AH = 00 physical page numbers | ||
| 389 | ; 01 segment numbers | ||
| 390 | ; | ||
| 391 | ;------------------------------------------------------------------- | ||
| 392 | map_mult proc | ||
| 393 | |||
| 394 | cmp al,mu_ppn ; is this a map request? | ||
| 395 | je mu_ppn_fcn ; yes, go do it | ||
| 396 | |||
| 397 | cmp al,mu_seg ; no, is this an unmap request? | ||
| 398 | je mu_seg_fcn ; yes, go do it | ||
| 399 | |||
| 400 | xor al,al ; clear al, why not? | ||
| 401 | mov ah,ems_code8f ; no, return invalid sub-function code | ||
| 402 | ret ; return to caller | ||
| 403 | |||
| 404 | ;------------------------------------------------------------------- | ||
| 405 | ; | ||
| 406 | ; 5000 - map/unmap multiple handle pages using physical page numbers | ||
| 407 | ; | ||
| 408 | ; INPUT: | ||
| 409 | ; AX = 5000h | ||
| 410 | ; | ||
| 411 | ; DX = handle | ||
| 412 | ; | ||
| 413 | ; CX = num entries in control structure | ||
| 414 | ; | ||
| 415 | ; DS:SI -> points to control structure | ||
| 416 | ; Format: | ||
| 417 | ; | ||
| 418 | ; log_pg_num dw ? ; logical page number | ||
| 419 | ; phys_pg_num dw ? ; physical page number | ||
| 420 | ; : ; repeats CX times | ||
| 421 | ; : | ||
| 422 | ; | ||
| 423 | ; OUTPUT: | ||
| 424 | ; | ||
| 425 | ; AH = 00, No error | ||
| 426 | ; 80H, Software error | ||
| 427 | ; 81H, Hardware error | ||
| 428 | ; 83H, Invalid handle | ||
| 429 | ; 84H, Invalid function | ||
| 430 | ; 8AH, Invalid logical page | ||
| 431 | ; 8BH, Invalid physical page | ||
| 432 | ; 8FH, Invalid sub-function | ||
| 433 | ; | ||
| 434 | ;------------------------------------------------------------------- | ||
| 435 | |||
| 436 | mu_ppn_fcn: | ||
| 437 | |||
| 438 | push bx ; save regs ;an000; dms; | ||
| 439 | push cx ; save count | ||
| 440 | push dx ; ;an000; dms; | ||
| 441 | push si ; save pointer | ||
| 442 | |||
| 443 | xor ah,ah ; good return code | ||
| 444 | cmp cx,0 ; is count 0? | ||
| 445 | je mu_ppn_exit | ||
| 446 | |||
| 447 | mu_ppn_loop: | ||
| 448 | mov bx,ds:word ptr[si+0] ; get logical page number | ||
| 449 | mov ax,ds:word ptr[si+2] ; get physical page number | ||
| 450 | mov ah,map_pages_fcn ; fcn code for mapping | ||
| 451 | |||
| 452 | push cx | ||
| 453 | call map_l_to_p ; call the mapping routine | ||
| 454 | pop cx | ||
| 455 | |||
| 456 | cmp ah,0 ; was return code OK | ||
| 457 | jne mu_ppn_error | ||
| 458 | |||
| 459 | add si,4 ; point to next entry | ||
| 460 | |||
| 461 | loop mu_ppn_loop ; do it again | ||
| 462 | |||
| 463 | xor ah,ah ; good return code | ||
| 464 | jmp mu_ppn_exit | ||
| 465 | |||
| 466 | mu_ppn_error: | ||
| 467 | mu_ppn_exit: | ||
| 468 | pop si ; restore pointer | ||
| 469 | pop dx ; ;an000; dms; | ||
| 470 | pop cx ; restore count | ||
| 471 | pop bx ; restore regs ;an000; dms; | ||
| 472 | |||
| 473 | ret ; return to caller | ||
| 474 | |||
| 475 | |||
| 476 | ;------------------------------------------------------------------- | ||
| 477 | ; | ||
| 478 | ; 5001 - map/unmap multiple handle pages using segment addresses | ||
| 479 | ; | ||
| 480 | ; INPUT: | ||
| 481 | ; AX = 5001h | ||
| 482 | ; | ||
| 483 | ; DX = handle | ||
| 484 | ; | ||
| 485 | ; CX = num entries in control structure | ||
| 486 | ; | ||
| 487 | ; DS:SI -> points to control structure | ||
| 488 | ; Format: | ||
| 489 | ; | ||
| 490 | ; log_pg_num dw ? ; logical page number | ||
| 491 | ; seg_address dw ? ; physical segment address | ||
| 492 | ; : ; repeats CX times | ||
| 493 | ; : | ||
| 494 | ; | ||
| 495 | ; OUTPUT: | ||
| 496 | ; | ||
| 497 | ; AH = 00, No error | ||
| 498 | ; 80H, Software error | ||
| 499 | ; 81H, Hardware error | ||
| 500 | ; 83H, Invalid handle | ||
| 501 | ; 84H, Invalid function | ||
| 502 | ; 8AH, Invalid logical page | ||
| 503 | ; 8BH, Invalid physical page | ||
| 504 | ; 8FH, Invalid sub-function | ||
| 505 | ; | ||
| 506 | ;------------------------------------------------------------------- | ||
| 507 | |||
| 508 | mu_seg_fcn: | ||
| 509 | |||
| 510 | push bx ; save regs ;an000; dms; | ||
| 511 | push cx ; save count | ||
| 512 | push dx ; ;an000; dms; | ||
| 513 | push si ; save pointer | ||
| 514 | |||
| 515 | xor ah,ah ; good return code | ||
| 516 | cmp cx,0 ; is count 0? | ||
| 517 | je mu_seg_exit | ||
| 518 | |||
| 519 | mu_seg_loop: | ||
| 520 | mov bx,ds:word ptr[si+0] ; get logical page number | ||
| 521 | |||
| 522 | push dx ; save handle | ||
| 523 | mov dx,ds:word ptr[si+2] ; get physical page number | ||
| 524 | call Get_Phys_Seg_Page ; convert to logical page circle | ||
| 525 | mov ax,dx ; must be in AX | ||
| 526 | pop dx ; restore handle | ||
| 527 | |||
| 528 | mov ah,map_pages_fcn ; fcn code for mapping | ||
| 529 | |||
| 530 | push cx | ||
| 531 | call map_l_to_p ; call the mapping routine | ||
| 532 | pop cx | ||
| 533 | |||
| 534 | cmp ah,0 ; was return code OK | ||
| 535 | jne mu_seg_error | ||
| 536 | |||
| 537 | add si,4 ; point to next entry | ||
| 538 | |||
| 539 | loop mu_seg_loop ; do it again | ||
| 540 | |||
| 541 | xor ah,ah ; good return code | ||
| 542 | jmp mu_seg_exit | ||
| 543 | |||
| 544 | mu_seg_error: | ||
| 545 | mu_seg_exit: | ||
| 546 | pop si ; restore pointer | ||
| 547 | pop dx ; ;an000; dms; | ||
| 548 | pop cx ; restore count | ||
| 549 | pop bx ; restore regs ;an000; dms; | ||
| 550 | |||
| 551 | ret ; return to caller | ||
| 552 | |||
| 553 | map_mult endp | ||
| 554 | |||
| 555 | ;------------------------------------------------------------------- | ||
| 556 | include lim40b.inc | ||
| 557 | ;------------------------------------------------------------------- | ||
| 558 | |||
| 559 | page | ||
| 560 | ;------------------------------------------------------------------- | ||
| 561 | ; | ||
| 562 | ; 52 - get/set handle attributes | ||
| 563 | ; | ||
| 564 | ; The LIM 4.0 spec strongly advises EMS implementers to avoid this | ||
| 565 | ; call. Our current implementation of this function is not to provide | ||
| 566 | ; support. Possibly in future releases it will be supported, if | ||
| 567 | ; the proper hardware becomes available. | ||
| 568 | ; | ||
| 569 | ; DMS 4/29/88 | ||
| 570 | ; | ||
| 571 | ;------------------------------------------------------------------- | ||
| 572 | handle_attrib proc | ||
| 573 | |||
| 574 | |||
| 575 | cmp al,Hn_Attr_Max_Fcn ;maximum subfunction number ;an000; dms; | ||
| 576 | jbe Handle_Attrib_Cont ;continue routine ;an000; dms; | ||
| 577 | mov ah,EMS_Code8F ;we have an invalid subfunction ;an000; dms; | ||
| 578 | jmp Handle_Attrib_Exit ; exit the routine ;an000; dms; | ||
| 579 | |||
| 580 | Handle_Attrib_Cont: | ||
| 581 | |||
| 582 | mov ah,EMS_Code91 ;this function is not supported ;an000; dms; | ||
| 583 | |||
| 584 | Handle_Attrib_Exit: | ||
| 585 | |||
| 586 | RET ; return to caller | ||
| 587 | |||
| 588 | handle_attrib endp | ||
| 589 | |||
| 590 | page | ||
| 591 | ;------------------------------------------------------------------- | ||
| 592 | ; | ||
| 593 | ; 53 - get/set handle name | ||
| 594 | ; | ||
| 595 | ; Virtual Mode Note: The Handle Name functions (53 and 54) will @RH6 | ||
| 596 | ; be handled differently when running on a system in virtual mode. @RH6 | ||
| 597 | ; This is to accommadate the Workstation Program's bank switching. @RH6 | ||
| 598 | ; In this case, handle names and ID's will only be returned for @RH6 | ||
| 599 | ; handles allocated in the same PC bank, or for handles in bank 0. @RH6 | ||
| 600 | ; Bank 0 is for device drivers, system extensions, or applications @RH6 | ||
| 601 | ; that install resident before WSP loads. @RH6 | ||
| 602 | ; When interfacing with handles in bank 0, one must be aware of @RH6 | ||
| 603 | ; the problem of two PC applications running simultaneously that @RH6 | ||
| 604 | ; get the handle ID of the resident program and map its pages. @RH6 | ||
| 605 | ; Data corruption will occur if both map and write to the same page @RH6 | ||
| 606 | ; at the same time. @RH6 | ||
| 607 | ; While these new LIM 4.0 functions will return info only for @RH6 | ||
| 608 | ; bank 0 and the current bank, the existing LIM 3.2 functions will @RH6 | ||
| 609 | ; continue to return total system values. For example, function 4B @RH6 | ||
| 610 | ; will return the number of active handles in all banks. @RH6 | ||
| 611 | ; | ||
| 612 | ; INPUT: | ||
| 613 | ; AL = sub-function code | ||
| 614 | ; 00 = get handle name hn_get | ||
| 615 | ; 01 = set handle name hn_set | ||
| 616 | ; | ||
| 617 | ; DX = handle | ||
| 618 | ; | ||
| 619 | ; ES:DI -> Get caller's name buffer (8 char's) | ||
| 620 | ; DS:SI -> Set caller's name buffer (8 char's) | ||
| 621 | ; | ||
| 622 | ; | ||
| 623 | ; OUTPUT: | ||
| 624 | ; AH = 00, No error | ||
| 625 | ; 80H, Software error | ||
| 626 | ; 81H, Hardware error | ||
| 627 | ; 83H, Handle not found | ||
| 628 | ; 84H, Invalid function | ||
| 629 | ; 8FH, Invalid sub-function | ||
| 630 | ; | ||
| 631 | ; AL = 0 | ||
| 632 | ; | ||
| 633 | ; | ||
| 634 | ; gga 8/21/87 | ||
| 635 | ; | ||
| 636 | ;------------------------------------------------------------------- | ||
| 637 | |||
| 638 | Null_Handle_Name db 8 dup(0) ;null handle value ;an000; dms; | ||
| 639 | |||
| 640 | handle_name proc | ||
| 641 | |||
| 642 | push bx ; save some regs | ||
| 643 | push cx | ||
| 644 | push dx | ||
| 645 | push di | ||
| 646 | push si | ||
| 647 | push ds | ||
| 648 | |||
| 649 | PUSH CS ;Set addressability to our tables @RH8 | ||
| 650 | POP DS ;Must restore DS for Set name @RH8 | ||
| 651 | |||
| 652 | cmp al,hn_max_fcn ; al = 00 or 01, anything else = error | ||
| 653 | jbe hn_val_sf | ||
| 654 | |||
| 655 | ; invalid sub-function, report the error | ||
| 656 | |||
| 657 | mov ah,ems_code8F ; invalid sub-function code | ||
| 658 | jmp hn_exit ; exit | ||
| 659 | |||
| 660 | ; check the handle for valid range | ||
| 661 | |||
| 662 | hn_val_sf: | ||
| 663 | |||
| 664 | cmp dx,num_handles-1 ; handle within range ? | ||
| 665 | jnae hn_range_ok ; yes, get down to business | ||
| 666 | |||
| 667 | mov ah,ems_code83 ; handle not found | ||
| 668 | jmp hn_exit ; exit | ||
| 669 | |||
| 670 | ;------------------------ | ||
| 671 | ; handle is within valid range, now see if it is valid handle (i.e. in use) | ||
| 672 | |||
| 673 | hn_range_ok: | ||
| 674 | |||
| 675 | push ax ; save fcn code | ||
| 676 | push dx ; save handle | ||
| 677 | |||
| 678 | MOV AX,DX ;DX = handle id | ||
| 679 | MOV DX,TYPE H_LOOKUP_STRUC ;DI = entry's offset into | ||
| 680 | MUL DX ; the handle lookup table | ||
| 681 | MOV DI,AX ; | ||
| 682 | POP DX ; restore handle | ||
| 683 | POP AX ; restore fcn code | ||
| 684 | |||
| 685 | CMP HANDLE_LOOKUP_TABLE.H_PAGES[DI],REUSABLE_HANDLE | ||
| 686 | JNE HN_IN_USE ;Is this handle valid (in use)? | ||
| 687 | ; No...error | ||
| 688 | mov ah,ems_code83 ; handle not found | ||
| 689 | jmp hn_exit ; return the error code | ||
| 690 | |||
| 691 | HN_IN_USE: ;Check bank ID if in virutal mode | ||
| 692 | |||
| 693 | mov bx,ax ;save ax ;an000; dms; | ||
| 694 | TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6 | ||
| 695 | JZ HN_VALID ; (i.e. bank swapping), then read @RH6 | ||
| 696 | MOV DX,IDREG ; the current bank ID. @RH6 | ||
| 697 | IN AL,DX ; @RH6 | ||
| 698 | CMP HANDLE_LOOKUP_TABLE.H_BANK[DI],AL ;If handle's bank ID @RH6 | ||
| 699 | JE HN_VALID ; is 0 (resident) or @RH6 | ||
| 700 | CMP HANDLE_LOOKUP_TABLE.H_BANK[DI],0 ; = requesters bank @RH6 | ||
| 701 | JE HN_VALID ; then OK @RH6 | ||
| 702 | ;Else invalid requester bank @RH6 | ||
| 703 | MOV AH,EMS_CODE83 ;Indicate handle not found @RH6 | ||
| 704 | JMP HN_EXIT | ||
| 705 | |||
| 706 | ;------------------------ | ||
| 707 | ; find out if get or set operation | ||
| 708 | |||
| 709 | hn_valid: | ||
| 710 | mov ax,bx ;restore ax ;an000; dms; | ||
| 711 | cmp al,sf_hn_get ; al = 00 means GET | ||
| 712 | je hn_get | ||
| 713 | |||
| 714 | cmp al,sf_hn_set ; = 01 means SET | ||
| 715 | je hn_set | ||
| 716 | |||
| 717 | ; invalid sub-function, report the error | ||
| 718 | |||
| 719 | mov ah,ems_code8F ; invalid sub-function code | ||
| 720 | jmp hn_exit ; exit | ||
| 721 | |||
| 722 | |||
| 723 | |||
| 724 | page | ||
| 725 | ;------------------------------------------------------------------- | ||
| 726 | ; | ||
| 727 | ; 5300 - GET sub-function | ||
| 728 | ; ES:DI -> User's area where name is stored | ||
| 729 | ;------------------------------------------------------------------- | ||
| 730 | hn_get: | ||
| 731 | ;Here DI = offset into h lookup | ||
| 732 | LEA SI,HANDLE_LOOKUP_TABLE ;Set the source SI to the handle's | ||
| 733 | ADD SI,DI ; name field in the handle lookup | ||
| 734 | ADD SI,H_NAME ; lookup table | ||
| 735 | |||
| 736 | MOV DI,cs:[bp].IE_Saved_DI_Reg ;Restore the user's dest where | ||
| 737 | ; the handle name will be stored | ||
| 738 | |||
| 739 | MOV CX,8 ; want to copy 8 characters | ||
| 740 | CLD ; make sure direction flag is right | ||
| 741 | REP MOVSB ; copy the string | ||
| 742 | |||
| 743 | XOR AH,AH ; set good return code | ||
| 744 | JMP HN_EXIT ; exit | ||
| 745 | |||
| 746 | |||
| 747 | page | ||
| 748 | ;------------------------------------------------------------------- | ||
| 749 | ; | ||
| 750 | ; 5301 - SET sub-function | ||
| 751 | ; DS:SI -> User's area where name comes from | ||
| 752 | ; | ||
| 753 | ;------------------------------------------------------------------- | ||
| 754 | |||
| 755 | hn_set: | ||
| 756 | |||
| 757 | POP DS ;Restore the user's source where @RH6 | ||
| 758 | PUSH DS ; the handle name will come from | ||
| 759 | |||
| 760 | |||
| 761 | ;------------------------ | ||
| 762 | push si ;save regs ;an000; dms; | ||
| 763 | push di ; ;an000; dms; | ||
| 764 | push cx ; ;an000; dms; | ||
| 765 | push es ; ;an000; dms; | ||
| 766 | |||
| 767 | push cs ;swap segs for compare ;an000; dms; | ||
| 768 | pop es ; ;an000; dms; | ||
| 769 | |||
| 770 | mov di,offset cs:Null_Handle_Name ;point to null handle name ;an000; dms; | ||
| 771 | mov cx,8 ;8 bytes to compare ;an000; dms; | ||
| 772 | cld | ||
| 773 | cli ;ints off ;an000; dms; | ||
| 774 | rep cmpsb ;null string entered? ;an000; dms; | ||
| 775 | sti ;ints on ;an000; dms; | ||
| 776 | |||
| 777 | pop es ;restore regs ;an000; dms; | ||
| 778 | pop cx ; ;an000; dms; | ||
| 779 | pop di ; ;an000; dms; | ||
| 780 | pop si ; ;an000; dms; | ||
| 781 | je HN_Set_Null_Entered ;continue - don't look for match ;an000; dms; | ||
| 782 | |||
| 783 | push dx | ||
| 784 | call hd_named_handle ; find out if name is in use | ||
| 785 | pop dx | ||
| 786 | |||
| 787 | cmp ah,0 ; is return code good | ||
| 788 | je name_in_use | ||
| 789 | |||
| 790 | HN_Set_Null_Entered: | ||
| 791 | |||
| 792 | ;------------------------ | ||
| 793 | ;Here DI = offset into h lookup | ||
| 794 | ADD DI,OFFSET HANDLE_LOOKUP_TABLE ;Set the dest. DI to the @RH6 | ||
| 795 | ADD DI,OFFSET H_NAME ; handle's name field in @RH6 | ||
| 796 | ; the handle lookup table @RH6 | ||
| 797 | |||
| 798 | PUSH ES ;Make ES:DI -> destination in | ||
| 799 | PUSH CS ; the handle lookup table where | ||
| 800 | POP ES ; the name will be stored | ||
| 801 | |||
| 802 | mov cx,8 ; want to copy 8 characters | ||
| 803 | cld ; clear DF to auto-increment | ||
| 804 | rep movsb ; copy the string | ||
| 805 | |||
| 806 | ; all done with the SET function, set good return code and exit | ||
| 807 | |||
| 808 | pop es ; restore user's ES | ||
| 809 | xor ax,ax ; set good return code | ||
| 810 | jmp hn_exit | ||
| 811 | |||
| 812 | |||
| 813 | ;------------------------ | ||
| 814 | name_in_use: | ||
| 815 | mov ah,ems_codea1 ; name is use error | ||
| 816 | |||
| 817 | |||
| 818 | hn_exit: | ||
| 819 | pop ds ; restore these registers | ||
| 820 | pop si | ||
| 821 | pop di | ||
| 822 | pop dx | ||
| 823 | pop cx | ||
| 824 | pop bx | ||
| 825 | |||
| 826 | ret | ||
| 827 | |||
| 828 | handle_name endp | ||
| 829 | |||
| 830 | |||
| 831 | |||
| 832 | page | ||
| 833 | ;------------------------------------------------------------------- | ||
| 834 | ; | ||
| 835 | ; 54 - get handle directory | ||
| 836 | ; | ||
| 837 | ; SUB-FCNS: | ||
| 838 | ; AL = 00, get handle directory hd_directory | ||
| 839 | ; 01, search for named handle hd_named_handle | ||
| 840 | ; 02, get total handles hd_total_handles | ||
| 841 | ; | ||
| 842 | ;------------------------------------------------------------------- | ||
| 843 | handle_dir proc | ||
| 844 | |||
| 845 | cmp al,sf_hd_get ; 00 get handle dir | ||
| 846 | je hd_directory | ||
| 847 | |||
| 848 | cmp al,sf_hd_search ; 01 search for named handle | ||
| 849 | je hd_named_handle | ||
| 850 | |||
| 851 | cmp al,sf_hd_total ; 02 get total number of handles | ||
| 852 | jne hd_invalid_sfcn ; must be an invalid function code | ||
| 853 | |||
| 854 | jmp hd_total_handles ; go display total handles | ||
| 855 | |||
| 856 | |||
| 857 | ; invalid sub-function, report the error | ||
| 858 | |||
| 859 | hd_invalid_sfcn: | ||
| 860 | mov ah,ems_code8F ; invalid sub-function code | ||
| 861 | |||
| 862 | ; invalid sub-function, fall through to exit | ||
| 863 | |||
| 864 | hd_exit: | ||
| 865 | |||
| 866 | ret | ||
| 867 | |||
| 868 | |||
| 869 | ;------------------------------------------------------------------- | ||
| 870 | ; 5400 - get handle directory | ||
| 871 | ; | ||
| 872 | ; | ||
| 873 | ; INPUT: | ||
| 874 | ; AL = 00, get handle directory | ||
| 875 | ; | ||
| 876 | ; ES:DI -> caller's buffer for handle directory | ||
| 877 | ; | ||
| 878 | ; OUTPUT: | ||
| 879 | ; AH = 00H, no error | ||
| 880 | ; 80H, software error | ||
| 881 | ; 81H, hardware error | ||
| 882 | ; 84H, invalid function | ||
| 883 | ; 8FH, invalid subfunction | ||
| 884 | ; | ||
| 885 | ; AL = number of entries in handle directory | ||
| 886 | ; | ||
| 887 | ; ES:DI -> handle directory | ||
| 888 | ; | ||
| 889 | ; dw ? ; handle number | ||
| 890 | ; db 8 dup(?) ; handle name | ||
| 891 | ; : | ||
| 892 | ; : ; repeats AL times | ||
| 893 | ; | ||
| 894 | ;------------------------------------------------------------------- | ||
| 895 | hd_directory: | ||
| 896 | |||
| 897 | push bx ; save some regs | ||
| 898 | push cx | ||
| 899 | push dx | ||
| 900 | push di | ||
| 901 | push si | ||
| 902 | push ds | ||
| 903 | |||
| 904 | TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6 | ||
| 905 | JZ HD_LOOP_INIT ; (i.e. bank swapping), then read @RH6 | ||
| 906 | MOV DX,IDREG ; the current bank ID and save it. @RH6 | ||
| 907 | IN AL,DX ; @RH6 | ||
| 908 | MOV cs:BANKID,AL | ||
| 909 | |||
| 910 | |||
| 911 | ; initialize some things for the loop | ||
| 912 | HD_LOOP_INIT: | ||
| 913 | mov di,cs:[bp].IE_Saved_DI_Reg ;restore users DI ;an000; dms; | ||
| 914 | xor al,al ; al = num entries | ||
| 915 | xor dx,dx ; dx = handle index | ||
| 916 | mov cx,NUM_HANDLES ; loop enough for all handles | ||
| 917 | cld ; make sure direction flag cleared | ||
| 918 | |||
| 919 | push cs ; get cs | ||
| 920 | pop ds ; into ds | ||
| 921 | XOR SI,SI ; SI = offset into handle lookup @RH6 | ||
| 922 | ; table | ||
| 923 | hd_loop: | ||
| 924 | CMP HANDLE_LOOKUP_TABLE.h_pages[SI],REUSABLE_HANDLE | ||
| 925 | ; If handle not active, then @RH6 | ||
| 926 | je hd_next_hndl ; loop and look again | ||
| 927 | ;------------------------- | ||
| 928 | ; Active handle...if in virtual mode check bank ID @RH6 | ||
| 929 | ;------------------------- | ||
| 930 | |||
| 931 | TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6 | ||
| 932 | JZ HD_ACTIVE ; (i.e. bank swapping), then check @RH6 | ||
| 933 | MOV BL,cs:BANKID ; handle's bank id @RH6 | ||
| 934 | CMP HANDLE_LOOKUP_TABLE.H_BANK[SI],BL ;If handle's bank ID @RH6 | ||
| 935 | JE HD_Active ; is 0 (resident) or @RH6 | ||
| 936 | CMP HANDLE_LOOKUP_TABLE.H_BANK[SI],0 ; = requesters bank @RH6 | ||
| 937 | JE HD_Active ; then OK @RH6 | ||
| 938 | jmp HD_Next_Hndl ;Else skip to next one @RH6 | ||
| 939 | |||
| 940 | ;------------------------ | ||
| 941 | ; found an active handle, copy info to directory | ||
| 942 | ;------------------------ | ||
| 943 | hd_active: | ||
| 944 | mov es:word ptr[di],dx ; put handle number in directory | ||
| 945 | add di,2 ; move directory table pointer along, | ||
| 946 | ; must point to area for handle name now | ||
| 947 | |||
| 948 | push cx ; save counter for outer loop | ||
| 949 | push si ; save si for outer loop | ||
| 950 | |||
| 951 | mov cx,8 ; need to copy 8 chars | ||
| 952 | add si,offset Handle_LookUp_Table ;point to entry ;an000; dms; | ||
| 953 | add si,h_name ; make DS:SI -> handle name in lookup table | ||
| 954 | |||
| 955 | rep movsb ; copy the string | ||
| 956 | |||
| 957 | pop si ; restore si for outer loop | ||
| 958 | pop cx ; restore counter for outer loop | ||
| 959 | inc al ; increment entry count | ||
| 960 | |||
| 961 | ;------------------------ | ||
| 962 | ; done with the copy | ||
| 963 | ;------------------------ | ||
| 964 | |||
| 965 | hd_next_hndl: | ||
| 966 | inc dx ; update handle index | ||
| 967 | add si,type h_lookup_struc ; point to next entry in lookup table | ||
| 968 | loop hd_loop ; look for more | ||
| 969 | |||
| 970 | xor ah,ah ; good return code | ||
| 971 | |||
| 972 | ; all done, fall through to exit | ||
| 973 | |||
| 974 | hd_exit00: | ||
| 975 | |||
| 976 | pop ds ;restore these registers | ||
| 977 | pop si | ||
| 978 | pop di | ||
| 979 | pop dx | ||
| 980 | pop cx | ||
| 981 | pop bx | ||
| 982 | |||
| 983 | ret | ||
| 984 | |||
| 985 | |||
| 986 | |||
| 987 | page | ||
| 988 | ;------------------------------------------------------------------- | ||
| 989 | ; | ||
| 990 | ; 5401 - Search for named handle sub-function | ||
| 991 | ; | ||
| 992 | ; | ||
| 993 | ; INPUT: | ||
| 994 | ; AL = 01, search for named handle | ||
| 995 | ; | ||
| 996 | ; DS:SI = Pointer to handle name to search for | ||
| 997 | ; | ||
| 998 | ; | ||
| 999 | ; OUTPUT sub-fcn 01: Search for named handle | ||
| 1000 | ; | ||
| 1001 | ; AH = 00H, no error | ||
| 1002 | ; 80H, software error | ||
| 1003 | ; 81H, hardware error | ||
| 1004 | ; 84H, invalid function | ||
| 1005 | ; 8FH, invalid subfunction | ||
| 1006 | ; A0H, no matching handle found | ||
| 1007 | ; A1H, duplicate handle found | ||
| 1008 | ; | ||
| 1009 | ; DX = value of named handle | ||
| 1010 | ; | ||
| 1011 | ;------------------------------------------------------------------- | ||
| 1012 | |||
| 1013 | hd_named_handle: | ||
| 1014 | |||
| 1015 | push bx ; save some regs | ||
| 1016 | push cx | ||
| 1017 | push di | ||
| 1018 | push si | ||
| 1019 | push ds | ||
| 1020 | push es ;an000; dms; | ||
| 1021 | |||
| 1022 | TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6 | ||
| 1023 | JZ HD1_LOOP_INIT ; (i.e. bank swapping), then read @RH6 | ||
| 1024 | MOV DX,IDREG ; the current bank ID and save it. @RH6 | ||
| 1025 | IN AL,DX ; @RH6 | ||
| 1026 | MOV cs:BANKID,AL | ||
| 1027 | |||
| 1028 | |||
| 1029 | ; initialize some things for the loop | ||
| 1030 | HD1_LOOP_INIT: | ||
| 1031 | xor ah,ah ; good return code | ||
| 1032 | xor dx,dx ; dx = handle index | ||
| 1033 | mov cx,NUM_HANDLES ; loop enough for all handles | ||
| 1034 | cld ; make sure direction flag cleared | ||
| 1035 | |||
| 1036 | push cs ; get cs | ||
| 1037 | pop es ; into es | ||
| 1038 | XOR DI,DI ; DI = offset into handle lookup @RH6 | ||
| 1039 | ; table @RH6 | ||
| 1040 | hd1_loop: | ||
| 1041 | CMP ES:HANDLE_LOOKUP_TABLE.h_pages[DI],REUSABLE_HANDLE | ||
| 1042 | ; If handle not active, then @RH6 | ||
| 1043 | je hd1_next_hndl ; loop and look again | ||
| 1044 | ;------------------------- | ||
| 1045 | ; Active handle...if in virtual mode check bank ID @RH6 | ||
| 1046 | ;------------------------- | ||
| 1047 | |||
| 1048 | TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6 | ||
| 1049 | JZ HD1_ACTIVE ; (i.e. bank swapping), then check @RH6 | ||
| 1050 | MOV BL,cs:BANKID ; handle's bank id @RH6 | ||
| 1051 | CMP ES:HANDLE_LOOKUP_TABLE.H_BANK[DI],BL ;If handle's bank ID @RH6 | ||
| 1052 | JE HD1_Active ; is 0 (resident) or @RH6 | ||
| 1053 | CMP ES:HANDLE_LOOKUP_TABLE.H_BANK[DI],0 ; = requesters bank @RH6 | ||
| 1054 | JE HD1_Active ; then OK @RH6 | ||
| 1055 | jmp HD1_Next_Hndl ;Else skip to next one @RH6 | ||
| 1056 | ;------------------------ | ||
| 1057 | ; found an active handle, check the name | ||
| 1058 | ;------------------------ | ||
| 1059 | |||
| 1060 | HD1_ACTIVE: | ||
| 1061 | push cx ; save counter for outer loop | ||
| 1062 | push si ; save si for outer loop | ||
| 1063 | push di ; save di for outer loop | ||
| 1064 | |||
| 1065 | mov cx,8 ; need to compare 8 chars | ||
| 1066 | add di,offset Handle_LookUp_Table ;point to entry ;an000; dms; | ||
| 1067 | add di,offset H_Name ; must point to area for handle name now;an000; dms; | ||
| 1068 | |||
| 1069 | rep cmpsb ; compare the strings | ||
| 1070 | |||
| 1071 | pop di ; restore di for outer loop | ||
| 1072 | pop si ; restore si for outer loop | ||
| 1073 | pop cx ; restore counter for outer loop | ||
| 1074 | je hd_exit01 ; found a match, exit | ||
| 1075 | |||
| 1076 | ;------------------------ | ||
| 1077 | ; done with the check | ||
| 1078 | ;------------------------ | ||
| 1079 | |||
| 1080 | hd1_next_hndl: | ||
| 1081 | inc dx ; update handle index | ||
| 1082 | add di,type h_lookup_struc ; point to next entry in lookup table | ||
| 1083 | loop hd1_loop ; look for more | ||
| 1084 | |||
| 1085 | |||
| 1086 | |||
| 1087 | ; all done, if we fall through loop without finding a match, | ||
| 1088 | ; must report the error | ||
| 1089 | |||
| 1090 | mov ah,ems_codea0 ; no matching handle | ||
| 1091 | xor dx,dx ; invalid handle | ||
| 1092 | |||
| 1093 | hd_exit01: | ||
| 1094 | |||
| 1095 | |||
| 1096 | pop es ;restore these registers ;an000; dms; | ||
| 1097 | pop ds | ||
| 1098 | pop si | ||
| 1099 | pop di | ||
| 1100 | pop cx | ||
| 1101 | pop bx | ||
| 1102 | |||
| 1103 | ret | ||
| 1104 | |||
| 1105 | |||
| 1106 | |||
| 1107 | page | ||
| 1108 | ;------------------------------------------------------------------- | ||
| 1109 | ; | ||
| 1110 | ; 5402 - Get total handles sub-function | ||
| 1111 | ; | ||
| 1112 | ; INPUT: | ||
| 1113 | ; AL = 02, get total handles | ||
| 1114 | ; | ||
| 1115 | ; | ||
| 1116 | ; OUTPUT: | ||
| 1117 | ; AH = 00H, no error | ||
| 1118 | ; 80H, software error | ||
| 1119 | ; 81H, hardware error | ||
| 1120 | ; 84H, invalid function | ||
| 1121 | ; 8FH, invalid subfunction | ||
| 1122 | ; | ||
| 1123 | ; BX = total number of handles (includes OS handle, 0) | ||
| 1124 | ; | ||
| 1125 | ;------------------------------------------------------------------- | ||
| 1126 | |||
| 1127 | hd_total_handles: | ||
| 1128 | |||
| 1129 | mov bx,NUM_HANDLES ; return number of handles | ||
| 1130 | xor ah,ah ; good return code | ||
| 1131 | |||
| 1132 | ; all done, fall through to exit | ||
| 1133 | |||
| 1134 | hd_exit02: | ||
| 1135 | |||
| 1136 | ret ; return to caller | ||
| 1137 | |||
| 1138 | handle_dir endp | ||
| 1139 | |||
| 1140 | page | ||
| 1141 | ;------------------------------------------------------------------- | ||
| 1142 | ; | ||
| 1143 | ; 58 - Get mappable physical address array | ||
| 1144 | ; | ||
| 1145 | ; | ||
| 1146 | ; INPUT: | ||
| 1147 | ; AX = 5800h | ||
| 1148 | ; | ||
| 1149 | ; ES:DI -> mappable physical array address | ||
| 1150 | ; | ||
| 1151 | ; OUTPUT: | ||
| 1152 | ; AH = 00, no error | ||
| 1153 | ; 80H, software error | ||
| 1154 | ; 81H, hardware error | ||
| 1155 | ; 84H, invalid function | ||
| 1156 | ; 8FH, invalid subfunction | ||
| 1157 | ; | ||
| 1158 | ; CX = number of entries returned in the table below | ||
| 1159 | ; | ||
| 1160 | ; ES:DI -> DW ? ; phys_page_segment | ||
| 1161 | ; DW ? ; phys_page_number | ||
| 1162 | ; : | ||
| 1163 | ; : ; repeats CX times | ||
| 1164 | ; | ||
| 1165 | ;------------------------------------------------------------------- | ||
| 1166 | address_array proc | ||
| 1167 | |||
| 1168 | cmp al,Add_Get_Array ; subfunction 00 Get Mappable Physical ;an000; dms; | ||
| 1169 | ; Address Array | ||
| 1170 | je Address_Get_Physical_Address | ||
| 1171 | |||
| 1172 | cmp al,Add_Get_Size ; subfunction 01 Get Mappable Physical ;an000; dms; | ||
| 1173 | ; Address Array Entries | ||
| 1174 | je Address_Get_Size_Entries | ||
| 1175 | |||
| 1176 | mov ah,EMS_Code8F ; none of the above - invalid sub parm ;an000; dms; | ||
| 1177 | |||
| 1178 | ret | ||
| 1179 | |||
| 1180 | |||
| 1181 | Address_Get_Physical_Address: | ||
| 1182 | |||
| 1183 | push si ; save some regs | ||
| 1184 | push di ; save di ;an000; dms; | ||
| 1185 | push ds ; save DS | ||
| 1186 | |||
| 1187 | |||
| 1188 | ; set up some things for the loop | ||
| 1189 | |||
| 1190 | mov di,cs:[bp].IE_Saved_DI_Reg ; restore caller's DI, pointer to handle area | ||
| 1191 | |||
| 1192 | mov cx,map_count ; number of entries in table | ||
| 1193 | |||
| 1194 | push cs ; make DS:SI -> array | ||
| 1195 | pop ds | ||
| 1196 | |||
| 1197 | lea si,map_table | ||
| 1198 | |||
| 1199 | cld ; make sure direction flag is right | ||
| 1200 | |||
| 1201 | copy_address_array: | ||
| 1202 | |||
| 1203 | mov ax,DS:[si+phys_page_segment] | ||
| 1204 | mov ES:[di],ax | ||
| 1205 | add di,2 ; increment destination pointer | ||
| 1206 | mov ax,DS:[si+phys_page_number] | ||
| 1207 | mov ES:[di],ax | ||
| 1208 | |||
| 1209 | add si,type mappable_phys_page_struct ; increment pointer | ||
| 1210 | add di,2 ; increment destination pointer | ||
| 1211 | |||
| 1212 | loop copy_address_array | ||
| 1213 | |||
| 1214 | mov cx,map_count ; number of entries | ||
| 1215 | xor ah,ah ; good return code | ||
| 1216 | |||
| 1217 | pop ds ; restore DS | ||
| 1218 | pop di ; restore di | ||
| 1219 | pop si ; restore SI | ||
| 1220 | |||
| 1221 | RET ; return to caller | ||
| 1222 | |||
| 1223 | Address_Get_Size_Entries: | ||
| 1224 | |||
| 1225 | mov cx,cs:Map_Count ; return the number of pages allocated ;an000; dms; | ||
| 1226 | xor ax,ax ; clear error flag ;an000; dms; | ||
| 1227 | ret ; return to caller ;an000; dms; | ||
| 1228 | |||
| 1229 | |||
| 1230 | address_array endp | ||
| 1231 | |||
| 1232 | |||
| 1233 | |||
| 1234 | page | ||
| 1235 | ;------------------------------------------------------------------- | ||
| 1236 | ; | ||
| 1237 | ; 59 - Get extended momory hardware information | ||
| 1238 | ; | ||
| 1239 | ;------------------------------------------------------------------- | ||
| 1240 | hardware_info proc | ||
| 1241 | |||
| 1242 | cmp ose_functions,ose_enabled ; first, check for fcns enabled | ||
| 1243 | je hi_enabled ; | ||
| 1244 | |||
| 1245 | |||
| 1246 | mov ah,EMS_CODEA4 ; access denied | ||
| 1247 | jmp hi_exit ; exit | ||
| 1248 | |||
| 1249 | hi_enabled: | ||
| 1250 | cmp al,hi_info ; 5900 - hardware info fcn | ||
| 1251 | je hi_info_fcn | ||
| 1252 | |||
| 1253 | cmp al,hi_raw ; 5901 - unallocated raw page count | ||
| 1254 | je hi_raw_fcn | ||
| 1255 | |||
| 1256 | mov ah,EMS_CODE8F ; invalid sub-function | ||
| 1257 | |||
| 1258 | hi_exit: | ||
| 1259 | RET ; return to caller | ||
| 1260 | |||
| 1261 | |||
| 1262 | page | ||
| 1263 | ;------------------------------------------------------------------- | ||
| 1264 | ; | ||
| 1265 | ; hi_info_fcn | ||
| 1266 | ; | ||
| 1267 | ;------------------------------------------------------------------- | ||
| 1268 | |||
| 1269 | hi_info_fcn: | ||
| 1270 | |||
| 1271 | mov di,cs:[bp].IE_Saved_DI_Reg ; get di register | ||
| 1272 | |||
| 1273 | mov es:word ptr[di+0],1024 ; raw page size = 16KB | ||
| 1274 | mov es:word ptr[di+2],0 ; number of alternate register sets | ||
| 1275 | mov es:word ptr[di+4],type H_SAVE_STRUC ; size of save array | ||
| 1276 | mov es:word ptr[di+6],0 ; number of DMA register sets | ||
| 1277 | mov es:word ptr[di+8],1 ; 1 = no special DMA register sets | ||
| 1278 | |||
| 1279 | xor ah,ah ; good return code | ||
| 1280 | ret ; return to caller | ||
| 1281 | |||
| 1282 | page | ||
| 1283 | ;------------------------------------------------------------------- | ||
| 1284 | ; | ||
| 1285 | ; hi_raw_fcn | ||
| 1286 | ; | ||
| 1287 | ;------------------------------------------------------------------- | ||
| 1288 | |||
| 1289 | hi_raw_fcn: | ||
| 1290 | |||
| 1291 | mov ah,get_free_pages ; function code to get free pages | ||
| 1292 | |||
| 1293 | call q_pages ; pass this one through, since our | ||
| 1294 | ; raw pages = 16 KB | ||
| 1295 | ; this fcn returns exacly the same | ||
| 1296 | ; regs as are needed here | ||
| 1297 | |||
| 1298 | ret ; return to caller | ||
| 1299 | |||
| 1300 | hardware_info endp | ||
| 1301 | |||
| 1302 | page | ||
| 1303 | ;------------------------------------------------------------------- | ||
| 1304 | ; | ||
| 1305 | ; 5B - alternate map register set | ||
| 1306 | ; | ||
| 1307 | ;------------------------------------------------------------------- | ||
| 1308 | |||
| 1309 | AM_ES_Save dw 0 ;ES save variable ;an000; dms; | ||
| 1310 | AM_DI_Save dw 0 ;DI save variable ;an000; dms; | ||
| 1311 | AM_Set_Flag db 0 ;set called flag ;an000; dms; | ||
| 1312 | |||
| 1313 | alternate_map proc | ||
| 1314 | |||
| 1315 | cmp ose_functions,ose_enabled ; first, check for fcns enabled | ||
| 1316 | je am_enabled ; | ||
| 1317 | |||
| 1318 | |||
| 1319 | mov ah,EMS_CODEA4 ; access denied | ||
| 1320 | jmp am_exit ; exit | ||
| 1321 | |||
| 1322 | am_enabled: | ||
| 1323 | cmp al,am_get ; 5b00 - get alternate map register set | ||
| 1324 | je _am_get | ||
| 1325 | |||
| 1326 | cmp al,am_set ; 5b01 - set alternate map register set | ||
| 1327 | je _am_set | ||
| 1328 | |||
| 1329 | cmp al,am_size ; 5b02 - get alternate map save array size | ||
| 1330 | je _am_size | ||
| 1331 | |||
| 1332 | cmp al,am_alloc ; 5b03 - allocate alternate map register set | ||
| 1333 | je _am_alloc | ||
| 1334 | |||
| 1335 | cmp al,am_dealloc ; 5b04 - deallocate alternate map register set | ||
| 1336 | je _am_dealloc | ||
| 1337 | |||
| 1338 | cmp al,am_dma_alloc ; 5b05 - allocate DMA register set | ||
| 1339 | je _am_dma_alloc | ||
| 1340 | |||
| 1341 | cmp al,am_dma_enable ; 5b06 - enable DMA register set | ||
| 1342 | je _am_dma_enable | ||
| 1343 | |||
| 1344 | cmp al,am_dma_disable ; 5b07 - disable DMA register set | ||
| 1345 | je _am_dma_disable | ||
| 1346 | |||
| 1347 | cmp al,am_dma_dealloc ; 5b08 - deallocate DMA register set | ||
| 1348 | je _am_dma_dealloc | ||
| 1349 | |||
| 1350 | mov ah,EMS_CODE8F ; invalid sub-function | ||
| 1351 | |||
| 1352 | am_exit: | ||
| 1353 | ret ; return to caller | ||
| 1354 | |||
| 1355 | |||
| 1356 | page | ||
| 1357 | ;------------------------------------------------------------------- | ||
| 1358 | ; | ||
| 1359 | ; _am_get | ||
| 1360 | ; | ||
| 1361 | ;------------------------------------------------------------------- | ||
| 1362 | _am_get: | ||
| 1363 | |||
| 1364 | cmp cs:AM_Set_Flag,0 ;flag set? ;an000; dms; | ||
| 1365 | jne AM_Get_Continue ;yes ;an000; dms; | ||
| 1366 | xor di,di ;signal set has not ;an000; dms; | ||
| 1367 | mov es,di ; been performed ;an000; dms; | ||
| 1368 | xor ah,ah ;signal good exit ;an000; dms; | ||
| 1369 | jmp AM_Get_Exit ;exit routine ;an000; dms; | ||
| 1370 | |||
| 1371 | AM_Get_Continue: | ||
| 1372 | |||
| 1373 | mov di,cs:AM_DI_Save | ||
| 1374 | mov es,cs:AM_ES_Save | ||
| 1375 | mov cs:[bp].IE_Saved_DI_Reg,di;set instance table entry ;an000; dms; | ||
| 1376 | |||
| 1377 | call GET_SUBFCN ; copy the save area info to user's buffer | ||
| 1378 | |||
| 1379 | xor bl,bl ; bl = 0 for our implementation | ||
| 1380 | ; this indicates to user that ES:DI | ||
| 1381 | ; buffer has been filled in with save | ||
| 1382 | ; area info | ||
| 1383 | AM_Get_Exit: | ||
| 1384 | |||
| 1385 | ret | ||
| 1386 | |||
| 1387 | page | ||
| 1388 | ;------------------------------------------------------------------- | ||
| 1389 | ; | ||
| 1390 | ; _am_set | ||
| 1391 | ; | ||
| 1392 | ;------------------------------------------------------------------- | ||
| 1393 | _am_set: | ||
| 1394 | |||
| 1395 | push si | ||
| 1396 | push ds | ||
| 1397 | |||
| 1398 | cmp bl,null ; bl must be 0 for us | ||
| 1399 | jne _am_set_error ; set error code and exit | ||
| 1400 | |||
| 1401 | mov di,cs:[bp].IE_Saved_DI_Reg ; restore caller's DI, pointer to mapping control structure | ||
| 1402 | |||
| 1403 | mov cs:AM_ES_Save,es ; save es value ;an000; dms; | ||
| 1404 | mov cs:AM_DI_Save,di ; save di value ;an000; dms; | ||
| 1405 | mov cs:AM_Set_Flag,01 ; flag indicates set performed ;an000; dms; | ||
| 1406 | mov si,di ; restore_pgfrm_map expects DS:SI to point to save area | ||
| 1407 | push es | ||
| 1408 | pop ds | ||
| 1409 | |||
| 1410 | call RESTORE_PGFRM_MAP | ||
| 1411 | |||
| 1412 | xor ah,ah ; good return code | ||
| 1413 | |||
| 1414 | jmp _am_set_exit | ||
| 1415 | |||
| 1416 | _am_set_error: | ||
| 1417 | mov ah,EMS_CODE9C ; fast regs not supported and BL != 0 | ||
| 1418 | |||
| 1419 | _am_set_exit: | ||
| 1420 | |||
| 1421 | pop ds | ||
| 1422 | pop si | ||
| 1423 | |||
| 1424 | ret | ||
| 1425 | |||
| 1426 | page | ||
| 1427 | ;------------------------------------------------------------------- | ||
| 1428 | ; | ||
| 1429 | ; _am_size | ||
| 1430 | ; | ||
| 1431 | ;------------------------------------------------------------------- | ||
| 1432 | _am_size: | ||
| 1433 | |||
| 1434 | mov dx,type h_save_struc ; get size requirements for save area | ||
| 1435 | |||
| 1436 | xor ah,ah ; good return code | ||
| 1437 | |||
| 1438 | ret | ||
| 1439 | |||
| 1440 | page | ||
| 1441 | ;------------------------------------------------------------------- | ||
| 1442 | ; | ||
| 1443 | ; _am_alloc | ||
| 1444 | ; | ||
| 1445 | ;------------------------------------------------------------------- | ||
| 1446 | _am_alloc: | ||
| 1447 | |||
| 1448 | |||
| 1449 | xor bl,bl ; We don't support this function | ||
| 1450 | ; in hardware, so return 0. | ||
| 1451 | ; This indicates we will do software | ||
| 1452 | ; emulation of these register sets. | ||
| 1453 | |||
| 1454 | xor ah,ah ; good return code | ||
| 1455 | |||
| 1456 | ret | ||
| 1457 | |||
| 1458 | page | ||
| 1459 | ;------------------------------------------------------------------- | ||
| 1460 | ; | ||
| 1461 | ; _am_dealloc - 5b04 | ||
| 1462 | ; | ||
| 1463 | ;------------------------------------------------------------------- | ||
| 1464 | _am_dealloc: | ||
| 1465 | |||
| 1466 | xor ah,ah ; assume good return code | ||
| 1467 | |||
| 1468 | cmp bl,0 ; is this a deallocate for 0? | ||
| 1469 | je _am_dealloc_exit ; yes, goo return code | ||
| 1470 | |||
| 1471 | mov ah,EMS_CODE9C ; error code for dealloc of unsupported | ||
| 1472 | ; register set | ||
| 1473 | |||
| 1474 | _am_dealloc_exit: | ||
| 1475 | |||
| 1476 | ret | ||
| 1477 | |||
| 1478 | page | ||
| 1479 | ;------------------------------------------------------------------- | ||
| 1480 | ; | ||
| 1481 | ; _am_dma_alloc | ||
| 1482 | ; | ||
| 1483 | ;------------------------------------------------------------------- | ||
| 1484 | _am_dma_alloc: | ||
| 1485 | |||
| 1486 | xor ah,ah ; good return code | ||
| 1487 | xor bl,bl ; no DMA sets available | ||
| 1488 | |||
| 1489 | ret | ||
| 1490 | |||
| 1491 | page | ||
| 1492 | ;------------------------------------------------------------------- | ||
| 1493 | ; | ||
| 1494 | ; _am_dma_enable | ||
| 1495 | ; | ||
| 1496 | ;------------------------------------------------------------------- | ||
| 1497 | _am_dma_enable: | ||
| 1498 | |||
| 1499 | mov ah,EMS_CODE9E ; dedicated DMA not supported | ||
| 1500 | |||
| 1501 | ret | ||
| 1502 | |||
| 1503 | page | ||
| 1504 | ;------------------------------------------------------------------- | ||
| 1505 | ; | ||
| 1506 | ; _am_dma_disable | ||
| 1507 | ; | ||
| 1508 | ;------------------------------------------------------------------- | ||
| 1509 | _am_dma_disable: | ||
| 1510 | |||
| 1511 | mov ah,EMS_CODE9E ; dedicated DMA not supported | ||
| 1512 | |||
| 1513 | ret | ||
| 1514 | |||
| 1515 | page | ||
| 1516 | ;------------------------------------------------------------------- | ||
| 1517 | ; | ||
| 1518 | ; _am_dma_dealloc | ||
| 1519 | ; | ||
| 1520 | ;------------------------------------------------------------------- | ||
| 1521 | _am_dma_dealloc: | ||
| 1522 | |||
| 1523 | xor ah,ah ; assume good return code | ||
| 1524 | |||
| 1525 | cmp bl,null ; is the DMA channel 0? | ||
| 1526 | je _am_dma_de_exit | ||
| 1527 | |||
| 1528 | mov ah,EMS_CODE9C ; DMA register sets are not | ||
| 1529 | ; supported and bl != 0 | ||
| 1530 | |||
| 1531 | _am_dma_de_exit: | ||
| 1532 | ret | ||
| 1533 | |||
| 1534 | |||
| 1535 | alternate_map endp | ||
| 1536 | |||
| 1537 | page | ||
| 1538 | ;------------------------------------------------------------------- | ||
| 1539 | ; | ||
| 1540 | ; 5D - enable/disable OS/E functions set functions | ||
| 1541 | ; | ||
| 1542 | ;------------------------------------------------------------------- | ||
| 1543 | enable_os proc | ||
| 1544 | |||
| 1545 | cmp al,os_enable ; fcn code for enable | ||
| 1546 | je os_enable_fcn | ||
| 1547 | |||
| 1548 | cmp al,os_disable ; fcn code for disable | ||
| 1549 | je os_disable_fcn | ||
| 1550 | |||
| 1551 | cmp al,os_access ; fcn code for access key return | ||
| 1552 | je os_access_fcn | ||
| 1553 | |||
| 1554 | mov ah,EMS_CODE8F ;invalid sub-function code error | ||
| 1555 | |||
| 1556 | ret ; return to caller | ||
| 1557 | |||
| 1558 | page | ||
| 1559 | ;------------------------------------------------------------------- | ||
| 1560 | ; | ||
| 1561 | ; 5d00 - enable OS/E function set | ||
| 1562 | ; | ||
| 1563 | ; INPUT: | ||
| 1564 | ; | ||
| 1565 | ; BX,CX = Access key | ||
| 1566 | ; | ||
| 1567 | ; OUTPUT: | ||
| 1568 | ; | ||
| 1569 | ; AH = 00h, no error | ||
| 1570 | ; 80H, software error | ||
| 1571 | ; 81H, hardware error | ||
| 1572 | ; 84H, invalid function | ||
| 1573 | ; 8FH, invalid subfunction | ||
| 1574 | ; A4H, access denied, incorrect access key supplied | ||
| 1575 | ; | ||
| 1576 | ;------------------------------------------------------------------- | ||
| 1577 | os_enable_fcn: | ||
| 1578 | |||
| 1579 | ; find out if this is the first time | ||
| 1580 | |||
| 1581 | cmp word ptr access_code[0],0 ; access_code = 0, means enabled | ||
| 1582 | jne ose_check_code ; not 0, must check access code | ||
| 1583 | |||
| 1584 | cmp word ptr access_code[2],0 ; access_code = 0, means enabled | ||
| 1585 | jne ose_check_code ; not 0, must check access code | ||
| 1586 | |||
| 1587 | call get_code ; get access code to return | ||
| 1588 | |||
| 1589 | xor ah,ah ; good return code | ||
| 1590 | jmp ose_exit | ||
| 1591 | |||
| 1592 | ; not the first time, must check access code | ||
| 1593 | |||
| 1594 | ose_check_code: | ||
| 1595 | |||
| 1596 | cmp word ptr access_code[0],bx ; does it match? | ||
| 1597 | jne ose_bad ; no, return access denied error | ||
| 1598 | |||
| 1599 | cmp word ptr access_code[2],cx ; get second word of access code | ||
| 1600 | jne ose_bad ; no, return access denied error | ||
| 1601 | |||
| 1602 | ; access code was OK, enable functions and return no error condition | ||
| 1603 | |||
| 1604 | mov word ptr ose_functions,ose_enabled ; reset enabled flag | ||
| 1605 | |||
| 1606 | xor ah,ah ; good return code | ||
| 1607 | jmp ose_exit ; all done, exit | ||
| 1608 | |||
| 1609 | ose_bad: | ||
| 1610 | mov ah,EMS_CODEA4 ; return access denied error code | ||
| 1611 | |||
| 1612 | ose_exit: | ||
| 1613 | ret ; return to caller | ||
| 1614 | |||
| 1615 | |||
| 1616 | page | ||
| 1617 | ;------------------------------------------------------------------- | ||
| 1618 | ; | ||
| 1619 | ; 5d01 - disable OS/E function set | ||
| 1620 | ; | ||
| 1621 | ; INPUT: | ||
| 1622 | ; | ||
| 1623 | ; BX,CX = Access key | ||
| 1624 | ; | ||
| 1625 | ; OUTPUT: | ||
| 1626 | ; | ||
| 1627 | ; AH = 00h, no error | ||
| 1628 | ; 80H, software error | ||
| 1629 | ; 81H, hardware error | ||
| 1630 | ; 84H, invalid function | ||
| 1631 | ; 8FH, invalid subfunction | ||
| 1632 | ; A4H, access denied, incorrect access key supplied | ||
| 1633 | ; | ||
| 1634 | ;------------------------------------------------------------------- | ||
| 1635 | os_disable_fcn: | ||
| 1636 | |||
| 1637 | ; find out if this is the first time | ||
| 1638 | |||
| 1639 | cmp word ptr access_code[0],0 ; access_code = 0, means enabled | ||
| 1640 | jne osd_check_code ; not 0, must check access code | ||
| 1641 | |||
| 1642 | cmp word ptr access_code[2],0 ; access_code = 0, means enabled | ||
| 1643 | jne osd_check_code ; not 0, must check access code | ||
| 1644 | |||
| 1645 | ; yes, first time, must set access code and disable fcns | ||
| 1646 | |||
| 1647 | call get_code ; get access code to return | ||
| 1648 | |||
| 1649 | mov word ptr ose_functions,ose_disabled ; disable fcns | ||
| 1650 | |||
| 1651 | xor ah,ah ; good return code | ||
| 1652 | jmp osd_exit | ||
| 1653 | |||
| 1654 | ; not the first time, must check access code | ||
| 1655 | |||
| 1656 | osd_check_code: | ||
| 1657 | |||
| 1658 | cmp word ptr access_code[0],bx ; does it match? | ||
| 1659 | jne osd_bad ; no, return access denied error | ||
| 1660 | |||
| 1661 | cmp word ptr access_code[2],cx ; get second word of access code | ||
| 1662 | jne osd_bad ; no, return access denied error | ||
| 1663 | |||
| 1664 | ; access code was OK, enable functions and return no error condition | ||
| 1665 | |||
| 1666 | mov word ptr ose_functions,ose_disabled ; disable functions | ||
| 1667 | |||
| 1668 | xor ah,ah ; good return code | ||
| 1669 | jmp osd_exit ; all done, exit | ||
| 1670 | |||
| 1671 | osd_bad: | ||
| 1672 | mov ah,EMS_CODEA4 ; return access denied error code | ||
| 1673 | |||
| 1674 | osd_exit: | ||
| 1675 | ret ; return to caller | ||
| 1676 | |||
| 1677 | page | ||
| 1678 | ;------------------------------------------------------------------- | ||
| 1679 | ; | ||
| 1680 | ; 5d02 - return OS/E function set access code | ||
| 1681 | ; | ||
| 1682 | ; INPUT: | ||
| 1683 | ; | ||
| 1684 | ; BX,CX = Access key | ||
| 1685 | ; | ||
| 1686 | ; OUTPUT: | ||
| 1687 | ; | ||
| 1688 | ; AH = 00h, no error | ||
| 1689 | ; 80H, software error | ||
| 1690 | ; 81H, hardware error | ||
| 1691 | ; 84H, invalid function | ||
| 1692 | ; 8FH, invalid subfunction | ||
| 1693 | ; A4H, access denied, incorrect access key supplied | ||
| 1694 | ; | ||
| 1695 | ;------------------------------------------------------------------- | ||
| 1696 | os_access_fcn: | ||
| 1697 | |||
| 1698 | ; check access code | ||
| 1699 | |||
| 1700 | |||
| 1701 | cmp word ptr access_code[0],bx ; does it match? | ||
| 1702 | jne osa_bad ; no, return access denied error | ||
| 1703 | |||
| 1704 | cmp word ptr access_code[2],cx ; get second word of access code | ||
| 1705 | jne osa_bad ; no, return access denied error | ||
| 1706 | |||
| 1707 | ; clear access code and return "no error" return code (AH = 00) | ||
| 1708 | |||
| 1709 | xor ax,ax ; clear ax | ||
| 1710 | mov word ptr access_code[0],ax ; clear access code | ||
| 1711 | mov word ptr access_code[2],ax ; clear access code | ||
| 1712 | |||
| 1713 | jmp osa_exit | ||
| 1714 | |||
| 1715 | osa_bad: | ||
| 1716 | mov ah,ems_codeA4 ; access denied error code | ||
| 1717 | |||
| 1718 | osa_exit: | ||
| 1719 | ret ; return to caller | ||
| 1720 | |||
| 1721 | |||
| 1722 | |||
| 1723 | |||
| 1724 | page | ||
| 1725 | ;------------------------------------------------------------------- | ||
| 1726 | ; | ||
| 1727 | ; get_code - returns random access code in cx,dx and stores it in | ||
| 1728 | ; system variable access_code. Access_code is a double-word | ||
| 1729 | ; which is used to save the bx,cx combination making up the | ||
| 1730 | ; "password" for OS/E functions. | ||
| 1731 | ; | ||
| 1732 | ;------------------------------------------------------------------- | ||
| 1733 | |||
| 1734 | get_code: | ||
| 1735 | |||
| 1736 | push dx ; save dx | ||
| 1737 | |||
| 1738 | ; get a "random" number for first word of access code | ||
| 1739 | |||
| 1740 | redo1: | ||
| 1741 | call get_rand ; returns "random" num in dx | ||
| 1742 | xor dx,xor_mask ; confuse it a little | ||
| 1743 | |||
| 1744 | cmp dx,0 ; make sure we didn't end up w/0 | ||
| 1745 | je redo1 | ||
| 1746 | |||
| 1747 | mov word ptr access_code[0],dx ; save it away | ||
| 1748 | mov bx,dx | ||
| 1749 | |||
| 1750 | ; get another one for second word of access code | ||
| 1751 | |||
| 1752 | redo2: | ||
| 1753 | call get_rand | ||
| 1754 | add dx,dx ; confuse it a little | ||
| 1755 | xor dx,xor_mask | ||
| 1756 | |||
| 1757 | cmp dx,0 ; make sure we didn't end up w/0 | ||
| 1758 | je redo2 | ||
| 1759 | |||
| 1760 | mov word ptr access_code[2],dx ; save it away | ||
| 1761 | mov cx,dx ; put second word in cx | ||
| 1762 | |||
| 1763 | pop dx ; restore | ||
| 1764 | |||
| 1765 | ret ; return to caller | ||
| 1766 | |||
| 1767 | |||
| 1768 | ;------------------------------------------------------------------- | ||
| 1769 | ; | ||
| 1770 | ; get_rand - returns a "random" number in dx | ||
| 1771 | ; | ||
| 1772 | ;------------------------------------------------------------------- | ||
| 1773 | get_rand: | ||
| 1774 | |||
| 1775 | push ax ; save some regs | ||
| 1776 | push cx | ||
| 1777 | |||
| 1778 | redo: | ||
| 1779 | mov ah,read_clock ; function code to read clock | ||
| 1780 | int dos_int ; read the time | ||
| 1781 | ; keep DX since it changes the most | ||
| 1782 | |||
| 1783 | cmp dx,0 ; did we end up with 0? | ||
| 1784 | je redo ; yes, redo it ... never want 0 | ||
| 1785 | |||
| 1786 | pop cx ; restore some regs | ||
| 1787 | pop ax | ||
| 1788 | |||
| 1789 | ret ; return to caller | ||
| 1790 | |||
| 1791 | enable_os endp | ||
| 1792 | |||
diff --git a/v4.0/src/DEV/XMA2EMS/LIM40B.INC b/v4.0/src/DEV/XMA2EMS/LIM40B.INC new file mode 100644 index 0000000..1e7683f --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/LIM40B.INC | |||
| @@ -0,0 +1,3468 @@ | |||
| 1 | |||
| 2 | page | ||
| 3 | ;========================================================================= | ||
| 4 | ; This module contains all the EQU's, STRUC's, data, and routines necessary | ||
| 5 | ; for LIMDMS.INC. | ||
| 6 | ; This module is to be INCLUDE'd as part of LIMDMS.INC. | ||
| 7 | ; | ||
| 8 | ;========================================================================= | ||
| 9 | |||
| 10 | ;========================================================================= | ||
| 11 | ;========== Begin EQUate Definitions ===================================== | ||
| 12 | ;========================================================================= | ||
| 13 | |||
| 14 | AAJ_Option_Max equ 1h ;max option value ;an000; dms; | ||
| 15 | AAJ_Segment equ 1h ;segment request value ;an000; dms; | ||
| 16 | AAJ_No_Pages_To_Map equ 0h ;0 page map request ;an000; dms; | ||
| 17 | |||
| 18 | MAC_Stack_Status_Request equ 02h ;stack size request ;an000; dms; | ||
| 19 | |||
| 20 | ER_Conv_Memory equ 00h ;conv. memory request ;an000; dms; | ||
| 21 | ER_EMS_Memory equ 01h ;EMS memory request ;an000; dms; | ||
| 22 | EMS_Page_Size_In_Bytes equ (16*1024)-1 ;page size in bytes ;an000; dms; | ||
| 23 | ER_Max_Type equ 01h ;max type possible ;an000; dms; | ||
| 24 | ER_Max_Function equ 01h ;max function possible ;an000; dms; | ||
| 25 | ER_Move equ 00h ;move data ;an000; dms; | ||
| 26 | ER_Exchange equ 01h ;exchange data ;an000; dms; | ||
| 27 | ER_EMS_Page_FE equ 0FEh ;phys. page FEh ;an000; dms; | ||
| 28 | ER_EMS_Page_FF equ 0FFh ;phys. page FFh ;an000; dms; | ||
| 29 | ER_Dest_EMS_Memory equ 01h ;bit 0 set ;an000; dms; | ||
| 30 | ER_Source_EMS_Memory equ 02h ;bit 1 set ;an000; dms; | ||
| 31 | ER_Up equ 00h ;signal forward move ;an000; dms; | ||
| 32 | ER_Down equ 0ffh ;signal reverse move | ||
| 33 | ER_10H equ 10h ;equ for 10h ;an000; dms; | ||
| 34 | |||
| 35 | AR_Sub_Max equ 01h ;5ah max. sub functions ;an000; dms; | ||
| 36 | |||
| 37 | ;========================================================================= | ||
| 38 | ;========== End EQUate Definitions ======================================= | ||
| 39 | ;========================================================================= | ||
| 40 | |||
| 41 | page | ||
| 42 | ;========================================================================= | ||
| 43 | ;========== Begin STRUC Definitions ====================================== | ||
| 44 | ;========================================================================= | ||
| 45 | |||
| 46 | Log_Phys_Map_Struc struc ;page structure ;an000; dms; | ||
| 47 | |||
| 48 | Log_Page_Number dw ? ;logical page number ;an000; dms; | ||
| 49 | Phys_Page_Number_Seg dw ? ;physical page or seg ;an000; dms; | ||
| 50 | ; determined by AL | ||
| 51 | Log_Phys_Map_Struc ends | ||
| 52 | |||
| 53 | |||
| 54 | Map_And_Jump_Struc struc ;carries jump info. ;an000; dms; | ||
| 55 | |||
| 56 | Target_Address dd ? ;jump address ;an000; dms; | ||
| 57 | Log_Phys_Map_Len db ? ;entry count in ;an000; dms; | ||
| 58 | ; Log_Phys_Map_Struct | ||
| 59 | Log_Phys_Map_Ptr dd ? ;Log_Phys_Map_Struct ptr;an000; dms; | ||
| 60 | |||
| 61 | Map_And_Jump_Struc ends ;an000; dms; | ||
| 62 | |||
| 63 | |||
| 64 | Map_And_Call_Struc struc ;carries jump info. ;an000; dms; | ||
| 65 | |||
| 66 | MAC_Target_Address dd ? ;jump address ;an000; dms; | ||
| 67 | MAC_New_Page_Map_Len db ? ;entry count in ;an000; dms; | ||
| 68 | ; Log_Phys_Map_Struct | ||
| 69 | ; for new map scheme | ||
| 70 | MAC_New_Page_Map_Ptr dd ? ;Log_Phys_Map_Struc ptr ;an000; dms; | ||
| 71 | ; for new map scheme | ||
| 72 | MAC_Old_Page_Map_Len db ? ;entry count in ;an000; dms; | ||
| 73 | ; Log_Phys_Map_Struc | ||
| 74 | ; for old map scheme | ||
| 75 | MAC_Old_Page_Map_Ptr dd ? ;Log_Phys_Map_Struc ptr ;an000; dms; | ||
| 76 | ; for old map scheme | ||
| 77 | MAC_Reserved dw 4 DUP (?) ;Used to restore map ;an000; dms; | ||
| 78 | ; context | ||
| 79 | |||
| 80 | Map_And_Call_Struc ends ;an000; dms; | ||
| 81 | |||
| 82 | |||
| 83 | Move_Source_Dest_Struc struc ;structure for move ;an000; dms; | ||
| 84 | |||
| 85 | Region_Length_Low_Word dw ? ; | ||
| 86 | Region_Length_High_Word dw ? ;length of region ;an000; dms; | ||
| 87 | |||
| 88 | Source_Memory_Type db ? ;conv/EMS ;an000; dms; | ||
| 89 | Source_Handle dw ? ;handle if EMS, else 0 ;an000; dms; | ||
| 90 | Source_Initial_Offset dw ? ;offset of source region;an000; dms; | ||
| 91 | Source_Initial_Seg_Page dw ? ;logical page if EMS ;an000; dms; | ||
| 92 | ; seg if conv. | ||
| 93 | Dest_Memory_Type db ? ;conv/EMS ;an000; dms; | ||
| 94 | Dest_Handle dw ? ;handle if EMS, else 0 ;an000; dms; | ||
| 95 | Dest_Initial_Offset dw ? ;offset of source region;an000; dms; | ||
| 96 | Dest_Initial_Seg_Page dw ? ;logical page if EMS ;an000; dms; | ||
| 97 | ; seg if conv. | ||
| 98 | Move_Source_Dest_Struc ends ;end structure ;an000; dms; | ||
| 99 | |||
| 100 | Realloc_Struc Struc ;BP addressible struc ;an000; dms; | ||
| 101 | |||
| 102 | Realloc_Reserved db size Instance_Entry_Struc dup (?) ;an000; dms; | ||
| 103 | Realloc_Alloc_Byte db ? ;reserved ;an000; dms; | ||
| 104 | Realloc_Reg_DI dw ? ;reserved ;an000; dms; | ||
| 105 | Realloc_Handle dw ? ;handle ;an000; dms; | ||
| 106 | |||
| 107 | Realloc_Page_Count dw ? ;new page count ;an000; dms; | ||
| 108 | Realloc_Page_Alloc dw ? ;pages to be allocated ;an000; dms; | ||
| 109 | Realloc_Page_Dealloc dw ? ;pages to be deallocated ;an000; dms; | ||
| 110 | |||
| 111 | Realloc_Handle_Xref_Index dw ? ;index to end of handle table ;an000; dms; | ||
| 112 | Realloc_LookUp_Index dw ? ;index to applicable handle ;an000; dms; | ||
| 113 | Realloc_Mult dw ? ;multiplier ;an000; dms; | ||
| 114 | |||
| 115 | Realloc_Struc Ends ;end structure ;an000; dms; | ||
| 116 | |||
| 117 | AAJ_Struc Struc ;BP addressible struc ;an000; dms; | ||
| 118 | |||
| 119 | AAJ_Reserved db size Instance_Entry_Struc dup (?) ;an000; dms; | ||
| 120 | AAJ_Xref_Pages dw ? ;save logical page count ;an000; dms; | ||
| 121 | AAJ_Handle dw ? ;saved handle ;an000; dms; | ||
| 122 | AAJ_Option db ? ;saved selector state ;an000; dms; | ||
| 123 | AAJ_LookUp_Index dw ? ;save index ;an000; dms; | ||
| 124 | AAJ_Mult dw ? ;multiplier ;an000; dms; | ||
| 125 | |||
| 126 | AAJ_Struc Ends ;end structure ;an000; dms; | ||
| 127 | |||
| 128 | MAC_Struc Struc ;BP addressible struc ;an000; dms; | ||
| 129 | |||
| 130 | MAC_Reserved_Area db size Instance_Entry_Struc dup (?) ;an000; dms; | ||
| 131 | MAC_LookUp_Index dw ? ;save index ;an000; dms; | ||
| 132 | MAC_Xref_Pages dw ? ;save logical page count ;an000; dms; | ||
| 133 | MAC_Option db ? ;saved selector state ;an000; dms; | ||
| 134 | |||
| 135 | EMS_Reg_ES dw ? ;ES reg ;an000; dms; | ||
| 136 | EMS_Reg_DS dw ? ;DS reg ;an000; dms; | ||
| 137 | EMS_Reg_FL dw ? ;FL reg ;an000; dms; | ||
| 138 | EMS_Reg_SI dw ? ;SI reg ;an000; dms; | ||
| 139 | EMS_Reg_DI dw ? ;DI reg ;an000; dms; | ||
| 140 | EMS_Reg_DX dw ? ;DX reg ;an000; dms; | ||
| 141 | EMS_Reg_CX dw ? ;CX reg ;an000; dms; | ||
| 142 | EMS_Reg_BX dw ? ;BX reg ;an000; dms; | ||
| 143 | |||
| 144 | MAC_M_C_Data db size Map_And_Call_Struc dup (?) ;an000; dms; | ||
| 145 | MAC_M_C_Log db size Log_Phys_Map_Struc*Map_Count_Def dup (?) ;an000; dms; | ||
| 146 | MAC_Map_Table db size Mappable_Phys_Page_Struct*Map_Count_Def dup (?) ;an000; dms; | ||
| 147 | MAC_Mult dw ? ;multiplier ;an000; dms; | ||
| 148 | |||
| 149 | MAC_Struc Ends ;end structure ;an000; dms; | ||
| 150 | |||
| 151 | |||
| 152 | ER_Struc Struc ;BP addressible struc ;an000; dms; | ||
| 153 | |||
| 154 | ER_Reserved db size Instance_Entry_Struc dup (?) ;an000; dms; | ||
| 155 | ER_Direction_Flag db ER_Up ;default to forward move;an000; dms; | ||
| 156 | |||
| 157 | ER_Sub_Function db ? ;save subfunction byte ;an000; dms; | ||
| 158 | |||
| 159 | ER_Src_Abs_Beg_Low dw ? ;abs add of src EMS page;an000; dms; | ||
| 160 | ER_Src_Abs_Beg_High dw ? ; beginning of trf area;an000; dms; | ||
| 161 | ER_Src_Abs_End_Low dw ? ;abs add of src EMS page;an000; dms; | ||
| 162 | ER_Src_Abs_End_High dw ? ; end of trf area ;an000; dms; | ||
| 163 | |||
| 164 | ER_Dst_Abs_Beg_Low dw ? ;abs add of src EMS page;an000; dms; | ||
| 165 | ER_Dst_Abs_Beg_High dw ? ; beginning of trf area;an000; dms; | ||
| 166 | ER_Dst_Abs_End_Low dw ? ;abs add of src EMS page;an000; dms; | ||
| 167 | ER_Dst_Abs_End_High dw ? ; end of trf area ;an000; dms; | ||
| 168 | |||
| 169 | ER_Current_Move_Count dw ? ;bytes moved this time ;an000; dms; | ||
| 170 | |||
| 171 | ER_Move_Xchg_Buffer1 db 10h dup (?) ;buffer for move/xchg ;an000; dms; | ||
| 172 | ER_Move_Xchg_Buffer2 db 10h dup (?) ;buffer for move/xchg ;an000; dms; | ||
| 173 | |||
| 174 | ER_Move_Count_Low dw ? ;low word of count ;an000; dms; | ||
| 175 | ER_Move_Count_High dw ? ;high word of count ;an000; dms; | ||
| 176 | |||
| 177 | ER_Source_Phys_Page dw ? ;page number of source ;an000; dms; | ||
| 178 | ER_Dest_Phys_Page dw ? ;page number of dest ;an000; dms; | ||
| 179 | |||
| 180 | ER_Source_Page dw ? ;active source page ;an000; dms; | ||
| 181 | ER_Dest_Page dw ? ;active dest page ;an000; dms; | ||
| 182 | |||
| 183 | ER_Source_Handle dw ? ;active handle ;an000; dms; | ||
| 184 | ER_Dest_Handle dw ? ;active handle ;an000; dms; | ||
| 185 | ; 10h byte moves | ||
| 186 | |||
| 187 | ER_Save_Context_Buffer dw 2*Type Mappable_Phys_Page_Struct dup (0) ;room for 2 pgs;an000; dms; | ||
| 188 | |||
| 189 | ER_Dest_Seg dw ? ;seg value of dest ;an000; dms; | ||
| 190 | ER_Source_Seg dw ? ;seg value of source ;an000; dms; | ||
| 191 | |||
| 192 | ER_Dest_Off dw ? ;off value of dest ;an000; dms; | ||
| 193 | ER_Source_Off dw ? ;off value of source ;an000; dms; | ||
| 194 | |||
| 195 | ER_Mem_Type dw ? ;memory type ;an000; dms; | ||
| 196 | |||
| 197 | |||
| 198 | ER_Struc Ends ;end structure ;an000; dms; | ||
| 199 | |||
| 200 | ;========================================================================= | ||
| 201 | ;========== End STRUC Definitions ======================================== | ||
| 202 | ;========================================================================= | ||
| 203 | |||
| 204 | page | ||
| 205 | ;========================================================================= | ||
| 206 | ;========== Begin Macro Definitions ====================================== | ||
| 207 | ;========================================================================= | ||
| 208 | |||
| 209 | |||
| 210 | ;========================================================================= | ||
| 211 | ; MAC_Expand_Stack_And_Copy : This routine will place data in the | ||
| 212 | ; instance table by copying the data pointed | ||
| 213 | ; at by ES:DI. | ||
| 214 | ; | ||
| 215 | ; Inputs : AX - Size of stack adjustment | ||
| 216 | ; ES:DI - Pointer to data to be copied to stack | ||
| 217 | ; | ||
| 218 | ; Outputs : BP - data place in instance table | ||
| 219 | ; | ||
| 220 | ;========================================================================= | ||
| 221 | |||
| 222 | MAC_Expand_Stack_And_Copy proc | ||
| 223 | |||
| 224 | mov cx,ax ;get adjustment factor ;an000; dms; | ||
| 225 | shr cx,1 ;convert to word move ;an000; dms; | ||
| 226 | mov ax,es ;get data source seg ;an000; dms; | ||
| 227 | mov ds,ax ;place in ds ;an000; dms; | ||
| 228 | mov si,di ;get data source off ;an000; dms; | ||
| 229 | |||
| 230 | mov ax,cs ;get dest. seg ;an000; dms; | ||
| 231 | mov es,ax ;place in es ;an000; dms; | ||
| 232 | mov di,bx ;get dest. off ;an000; dms; | ||
| 233 | |||
| 234 | cli ;ints off ;an000; dms; | ||
| 235 | rep movsw ;move data to stack ;an000; dms; | ||
| 236 | sti ;ints on ;an000; dms; | ||
| 237 | |||
| 238 | ret ;end routine ;an000; dms; | ||
| 239 | |||
| 240 | MAC_Expand_Stack_And_Copy endp | ||
| 241 | |||
| 242 | page | ||
| 243 | ;========================================================================= | ||
| 244 | ; MAC_Shrink_Stack_And_Copy : This routine move data from the instance | ||
| 245 | ; table and place it at ES:DI. | ||
| 246 | ; | ||
| 247 | ; Inputs : AX - Size of stack adjustment | ||
| 248 | ; ES:DI - Pointer to where data is to be copied | ||
| 249 | ; | ||
| 250 | ; Outputs : BP - data removed from instance table | ||
| 251 | ; | ||
| 252 | ;========================================================================= | ||
| 253 | |||
| 254 | MAC_Shrink_Stack_And_Copy proc | ||
| 255 | |||
| 256 | mov cx,ax ;get adjustment factor ;an000; dms; | ||
| 257 | mov ax,cs ;get data source seg ;an000; dms; | ||
| 258 | mov ds,ax ;place in ds ;an000; dms; | ||
| 259 | mov si,bx ;get data source off ;an000; dms; | ||
| 260 | mov ax,cx ;save count across move ;an000; dms; | ||
| 261 | shr cx,1 ;convert to word move ;an000; dms; | ||
| 262 | |||
| 263 | cli ;ints off ;an000; dms; | ||
| 264 | rep movsw ;move data from stack ;an000; dms; | ||
| 265 | sti ;ints on ;an000; dms; | ||
| 266 | |||
| 267 | ret ;end routine ;an000; dms; | ||
| 268 | |||
| 269 | MAC_Shrink_Stack_And_Copy endp | ||
| 270 | |||
| 271 | |||
| 272 | ;========================================================================= | ||
| 273 | ;========== End Macro Definitions ======================================== | ||
| 274 | ;========================================================================= | ||
| 275 | |||
| 276 | page | ||
| 277 | ;========================================================================= | ||
| 278 | ;========== Begin Generic PROC Definitions =============================== | ||
| 279 | ;========================================================================= | ||
| 280 | |||
| 281 | ;========================================================================= | ||
| 282 | ; Map_Pages : This routine will map the pages being | ||
| 283 | ; requested in the struc pointed to by | ||
| 284 | ; DS:SI. | ||
| 285 | ; | ||
| 286 | ; Inputs : ES:DI - Pointer to data in Log_Phys_Map_Struc format | ||
| 287 | ; CX - Count of data iterations in ES:DI | ||
| 288 | ; DX - handle | ||
| 289 | ; BX - page count for handle | ||
| 290 | ; AL - option | ||
| 291 | ; | ||
| 292 | ; Outputs : Revised map | ||
| 293 | ; AH - 0 = no error | ||
| 294 | ; > 0 = error | ||
| 295 | ;========================================================================= | ||
| 296 | |||
| 297 | Map_Pages proc ; ;an000; dms; | ||
| 298 | |||
| 299 | push si ;save reg ;an000; dms; | ||
| 300 | |||
| 301 | mov si,ax ;save option ;an000; dms; | ||
| 302 | cmp cx,AAJ_No_Pages_To_Map ;no pages? ;an000; dms; | ||
| 303 | je Map_Error_Exit ;yes - exit loop ;an000; dms; | ||
| 304 | |||
| 305 | Map_Loop_Continue: | ||
| 306 | |||
| 307 | cmp [di].Log_Page_Number,bx ;logical page out of ;an000; dms; | ||
| 308 | ; range? | ||
| 309 | jbe Map_Get_Segment ;no - in range ;an000; dms; | ||
| 310 | mov ah,EMS_Code8A ;yes - out of range ;an000; dms; | ||
| 311 | jmp Map_Error_Exit ;exit routine ;an000; dms; | ||
| 312 | |||
| 313 | Map_Get_Segment: | ||
| 314 | |||
| 315 | cmp si,AAJ_Segment ;segment request? ;an000; dms; | ||
| 316 | mov ax,[di].Phys_Page_Number_Seg ;get physical page ;an000; dms; | ||
| 317 | jne Map_Page_Request ;no - page request ;an000; dms; | ||
| 318 | push dx ;save handle | ||
| 319 | mov dx,[di].Phys_Page_Number_Seg ;get segment ;an000; dms; | ||
| 320 | call Get_Phys_Seg_Page ;get the associated ;an000; dms; | ||
| 321 | ; page for the segment | ||
| 322 | mov ax,dx ;place page in ax ;an000; dms; | ||
| 323 | pop dx ;restore handle | ||
| 324 | jnc Map_Page_Request ;no error - continue ;an000; dms; | ||
| 325 | mov ah,EMS_Code8B ;phys page not found ;an000; dms; | ||
| 326 | jmp Map_Error_Exit ;exit routine ;an000; dms; | ||
| 327 | |||
| 328 | Map_Page_Request: | ||
| 329 | |||
| 330 | push bx ;save bx across call ;an000; dms; | ||
| 331 | mov bx,[di].Log_Page_Number ;logical page to map ;an000; dms; | ||
| 332 | call Map_L_To_P ;map the page ;an000; dms; | ||
| 333 | pop bx ;restore bx ;an000; dms; | ||
| 334 | or ah,ah ;error? ;an000; dms; | ||
| 335 | jnz Map_Error_Exit ;pass error on & exit ;an000; dms; | ||
| 336 | add di,Type Log_Phys_Map_Struc ;adjust pointer ;an000; dms; | ||
| 337 | loop Map_Loop_Continue ;continue loop ;an000; dms; | ||
| 338 | xor ax,ax ;signal good finish ;an000; dms; | ||
| 339 | |||
| 340 | Map_Error_Exit: | ||
| 341 | |||
| 342 | pop si ;restore reg ;an000; dms; | ||
| 343 | |||
| 344 | ret ;return to caller ;an000; dms; | ||
| 345 | |||
| 346 | Map_Pages endp ;end proc ;an000; dms; | ||
| 347 | |||
| 348 | |||
| 349 | page | ||
| 350 | ;========================================================================= | ||
| 351 | ; Get_Phys_Seg_Page : This routine will obtain the physical page | ||
| 352 | ; number for a given segment. | ||
| 353 | ; | ||
| 354 | ; Inputs : DX - Segment value | ||
| 355 | ; Outputs : DX - Physical page number | ||
| 356 | ; CY - Error | ||
| 357 | ; NC - No error | ||
| 358 | ;========================================================================= | ||
| 359 | |||
| 360 | Get_Phys_Seg_Page proc ;begin routine ;an000; dms; | ||
| 361 | |||
| 362 | push ax ;save regs ;an000; dms; | ||
| 363 | push cx ; ;an000; dms; | ||
| 364 | push di ; ;an000; dms; | ||
| 365 | |||
| 366 | cli ;ints off ;an000; dms; | ||
| 367 | mov di,offset Map_Table ;point to table map ;an000; dms; | ||
| 368 | mov cx,Map_Count ;number of table entries;an000; dms; | ||
| 369 | sti ;ints on ;an000; dms; | ||
| 370 | |||
| 371 | GPSP_Loop: | ||
| 372 | |||
| 373 | cli ;ints off ;an000; dms; | ||
| 374 | cmp dx,cs:[di].Phys_Page_Segment ;segment match? ;an000; dms; | ||
| 375 | je GPSP_Got_Segment ;yes ;an000; dms; | ||
| 376 | add di,Type Mappable_Phys_Page_Struct ;adjust pointer ;an000; dms; | ||
| 377 | loop GPSP_Loop ;continue search ;an000; dms; | ||
| 378 | |||
| 379 | GPSP_Got_Segment: | ||
| 380 | |||
| 381 | sti ;ints on ;an000; dms; | ||
| 382 | cmp cx,0 ;data found? ;an000; dms; | ||
| 383 | je GPSP_Not_Found ;exit with error ;an000; dms; | ||
| 384 | mov dx,cs:[di].Phys_Page_Number ;exit with page number ;an000; dms; | ||
| 385 | clc ;clear cy ;an000; dms; | ||
| 386 | jmp GPSP_Found ;exit ;an000; dms; | ||
| 387 | |||
| 388 | GPSP_Not_Found: | ||
| 389 | |||
| 390 | stc ;signal error ;an000; dms; | ||
| 391 | |||
| 392 | GPSP_Found: ;exit ;an000; dms; | ||
| 393 | |||
| 394 | pop di ;restore regs ;an000; dms; | ||
| 395 | pop cx ; ;an000; dms; | ||
| 396 | pop ax ; ;an000; dms; | ||
| 397 | |||
| 398 | ret ;return to caller ;an000; dms; | ||
| 399 | |||
| 400 | Get_Phys_Seg_Page endp ;end proc ;an000; dms; | ||
| 401 | |||
| 402 | |||
| 403 | ;========================================================================= | ||
| 404 | ;========== End Generic PROC Definitions ================================= | ||
| 405 | ;========================================================================= | ||
| 406 | |||
| 407 | |||
| 408 | |||
| 409 | page | ||
| 410 | |||
| 411 | ;------------------------------------------------------------------- | ||
| 412 | ; Reallocate Pages - Function 18 | ||
| 413 | ; | ||
| 414 | ; Entry - AX = 51?? | ||
| 415 | ; BX = count of new allocation pages | ||
| 416 | ; DX = handle | ||
| 417 | ; | ||
| 418 | ; Exit - AH = status | ||
| 419 | ; BX = new page count | ||
| 420 | ; if error - original page count | ||
| 421 | ;------------------------------------------------------------------- | ||
| 422 | reallocate proc | ||
| 423 | |||
| 424 | push cx ;save affected regs ;an000; dms; | ||
| 425 | push dx ; ;an000; dms; | ||
| 426 | push di ; ;an000; dms; | ||
| 427 | push si ; ;an000; dms; | ||
| 428 | |||
| 429 | push ds ;save segments ;an000; dms; | ||
| 430 | push es ; ;an000; dms; | ||
| 431 | |||
| 432 | mov ax,cs ;get code segment ;an000; dms; | ||
| 433 | mov ds,ax ;put int ds and ;an000; dms; | ||
| 434 | mov es,ax ; es ;an000; dms; | ||
| 435 | |||
| 436 | |||
| 437 | mov cs:[bp].Realloc_Page_Count,bx ;new page count ;an000; dms; | ||
| 438 | mov cs:[bp].Realloc_Handle,dx ;handle ;an000; dms; | ||
| 439 | |||
| 440 | |||
| 441 | |||
| 442 | mov ax,cs:[bp].Realloc_Handle ;get handle for search ;an000; dms; | ||
| 443 | mov cs:[bp].Realloc_Mult,Type H_LookUp_Struc;handle lookup table ;an000; dms; | ||
| 444 | mul cs:[bp].Realloc_Mult ;obtain index position ;an000; dms; | ||
| 445 | mov cs:[bp].Realloc_LookUp_Index,ax ;index to handle ;an000; dms; | ||
| 446 | mov di,ax ;place index in si ;an000; dms; | ||
| 447 | mov dx,cs:[bp].Realloc_Handle ;get handle number ;an000; dms; | ||
| 448 | |||
| 449 | |||
| 450 | cmp dx,Num_Handles-1 ;dx > handle count? ;an000; dms; | ||
| 451 | jbe Realloc_Handle_Search ;handle within range ;an000; dms; | ||
| 452 | mov ah,EMS_Code83 ;EMS handle non-existent;an000; dms; | ||
| 453 | jmp Realloc_Error_Exit ;exit program ;an000; dms; | ||
| 454 | |||
| 455 | Realloc_Handle_Search: | ||
| 456 | |||
| 457 | cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; | ||
| 458 | jne Realloc_Status_Of_Handle ;handle good ;an000; dms; | ||
| 459 | mov ah,EMS_Code83 ;EMS handle not alloc ;an000; dms; | ||
| 460 | jmp Realloc_Error_Exit ;exit program ;an000; dms; | ||
| 461 | |||
| 462 | Realloc_Status_Of_Handle: | ||
| 463 | |||
| 464 | |||
| 465 | mov ax,Handle_LookUp_Table.H_Pages[di] ;get current page count ;an000; dms; | ||
| 466 | sub ax,cs:[bp].Realloc_Page_Count ;more or less pages? ;an000; dms; | ||
| 467 | jc Realloc_More_Pages ;more pages to alloc ;an000; dms; | ||
| 468 | |||
| 469 | Realloc_Less_Pages: | ||
| 470 | |||
| 471 | mov bx,ax ;pages to deallocate ;an000; dms; | ||
| 472 | mov cs:[bp].Realloc_Page_Dealloc,ax ;save dealloc value ;an000; dms; | ||
| 473 | |||
| 474 | mov si,Handle_LookUp_Table.H_Pal_Ptr[di] ;get start of links ;an000; dms; | ||
| 475 | mov cx,Handle_LookUp_Table.H_Pages[di] ;current pages allocated;an000; dms; | ||
| 476 | sub cx,bx ;pages to remain alloc ;an000; dms; | ||
| 477 | |||
| 478 | |||
| 479 | Realloc_Dealloc_Loop1: | ||
| 480 | |||
| 481 | cmp cx,0 ;pages? ;an000; dms; | ||
| 482 | je Realloc_Dealloc_Loop1_Exit ;no - exit ;an000; dms; | ||
| 483 | shl si,1 | ||
| 484 | mov si,Page_Alloc_List[si] ;get next pointer ;an000; dms; | ||
| 485 | dec cx ;dec loop count ;an000; dms; | ||
| 486 | jmp Realloc_Dealloc_Loop1 ;continue ;an000; dms; | ||
| 487 | |||
| 488 | Realloc_Dealloc_Loop1_Exit: | ||
| 489 | |||
| 490 | ;***** Adjust pointers ***** | ||
| 491 | |||
| 492 | mov cx,cs:[bp].Realloc_Page_Dealloc ;get dealloc count ;an000; dms; | ||
| 493 | mov ax,cs:PAL_Free_Ptr ;get the free ptr ;an001; dms; | ||
| 494 | cmp cx,0 ;0 pages to dealloc? ;an001; dms; | ||
| 495 | je Realloc_Dealloc_Loop2_Exit1 ;yes - bypass dealloc ;an001; dms; | ||
| 496 | mov cs:PAL_Free_Ptr,si ;no - set new free ptr ;an001; dms; | ||
| 497 | dec cx ;don't loop past last pg;an001; dms; | ||
| 498 | |||
| 499 | Realloc_Dealloc_Loop2: | ||
| 500 | |||
| 501 | cmp cx,0 ;end of deallocate? ;an000; dms; | ||
| 502 | je Realloc_Dealloc_Loop2_Exit ;yes - exit ;an000; dms; | ||
| 503 | shl si,1 ;get index entry ;an001; dms; | ||
| 504 | mov si,Page_Alloc_List[si] ;get next ptr ;an001; dms; | ||
| 505 | dec cx ;decrement counter ;an000; dms; | ||
| 506 | jmp Realloc_Dealloc_Loop2 | ||
| 507 | |||
| 508 | Realloc_Dealloc_Loop2_Exit: | ||
| 509 | |||
| 510 | shl si,1 ;get index entry ;an001; dms; | ||
| 511 | mov Page_Alloc_List[si],ax ;pt. last page to orig. ;an001; dms; | ||
| 512 | ; free ptr. | ||
| 513 | |||
| 514 | Realloc_Dealloc_Loop2_Exit1: | ||
| 515 | |||
| 516 | mov ax,cs:[bp].Realloc_Page_Count ;new page count ;an000; dms; | ||
| 517 | mov Handle_LookUp_Table.H_Pages[di],ax ; ;an000; dms; | ||
| 518 | |||
| 519 | mov ax,cs:[bp].Realloc_Page_Dealloc ;adj. value ;an000; dms; | ||
| 520 | add cs:Free_Pages,ax ;free up page ;an000; dms; | ||
| 521 | |||
| 522 | mov bx,cs:[bp].Realloc_Page_Count ;pass back page request ;an000; dms; | ||
| 523 | xor ah,ah ;clear error ;an000; dms; | ||
| 524 | jmp Realloc_Exit ;exit ;an000; dms; | ||
| 525 | |||
| 526 | Realloc_More_Pages: | ||
| 527 | |||
| 528 | mov cx,cs:[bp].Realloc_Page_Count ;get page request count ;an000; dms; | ||
| 529 | mov di,cs:[bp].Realloc_LookUp_Index ;get LookUp Table ptr ;an000; dms; | ||
| 530 | mov ax,Handle_LookUp_Table.H_Pages[di] ;get current page count ;an000; dms; | ||
| 531 | sub cx,ax ;get additional pages ;an000; dms; | ||
| 532 | mov cs:[bp].Realloc_Page_Alloc,cx ;new pages to alloc ;an000; dms; | ||
| 533 | cmp cx,Free_Pages ;> pages remaining? ;an000; dms; | ||
| 534 | jbe Realloc_Pages ;reallocate pages ;an000; dms; | ||
| 535 | mov ah,EMS_Code87 ;Too few pages avail ;an000; dms; | ||
| 536 | jmp Realloc_Error_Exit ;exit prog ;an000; dms; | ||
| 537 | |||
| 538 | Realloc_Pages: | ||
| 539 | |||
| 540 | mov cx,Handle_LookUp_Table.H_Pages[di] ;current pages allocated;an000; dms; | ||
| 541 | cmp cx,0 ;any pages? ;an000; dms; | ||
| 542 | jne Realloc_More_Pages_Cont ;yes ;an000; dms; | ||
| 543 | cmp cs:[bp].Realloc_Page_Alloc,0 ;any pages requested? ;an000; dms; | ||
| 544 | je Realloc_Alloc_Loop1_Exit ;continue ;an000; dms; | ||
| 545 | |||
| 546 | mov cx,cs:[bp].Realloc_Page_Alloc ;get new page count ;an001; dms; | ||
| 547 | cli ;ints off ;an001; dms; | ||
| 548 | call EMS_Page_Contig_Chk ;contig pages avail? ;an001; dms; | ||
| 549 | jnc Realloc_New_Pages | ||
| 550 | mov ah,EMS_Code87 ;Too few pages avail ;an000; dms; | ||
| 551 | sti ;ints on ;an001; dms; | ||
| 552 | jmp Realloc_Error_Exit ;exit prog ;an000; dms; | ||
| 553 | |||
| 554 | Realloc_New_Pages: | ||
| 555 | |||
| 556 | call EMS_Link_Set ;set up page list ;an001; dms; | ||
| 557 | |||
| 558 | mov Handle_LookUp_Table.H_Pal_Ptr[di],si ;set table to pointer ;an000; dms; | ||
| 559 | mov Handle_LookUp_Table.H_Pages[di],cx ;new page count ;an000; dms; | ||
| 560 | mov bx,cs:[bp].Realloc_Page_Count ;return new page count ;an001; dms; | ||
| 561 | sub cs:Free_Pages,bx ;new free count ;an000; dms; | ||
| 562 | sti ;ints on ;an001; dms; | ||
| 563 | xor ax,ax ;clear error flag ;an001; dms; | ||
| 564 | |||
| 565 | jmp Realloc_Exit ;exit routine ;an001; dms; | ||
| 566 | |||
| 567 | |||
| 568 | Realloc_More_Pages_Cont: | ||
| 569 | |||
| 570 | dec cx | ||
| 571 | mov si,Handle_LookUp_Table.H_Pal_Ptr[di] ;get start of links ;an000; dms; | ||
| 572 | |||
| 573 | Realloc_Alloc_Loop1: | ||
| 574 | cmp cx,0 ;at end ;an000; dms; | ||
| 575 | je Realloc_Alloc_Loop1_Exit ;yes ;an000; dms; | ||
| 576 | shl si,1 ;word entry ;an000; dms; | ||
| 577 | mov si,Page_Alloc_List[si] ;get next pointer ;an000; dms; | ||
| 578 | dec cx ;decrement loop count ;an000; dms; | ||
| 579 | jmp Realloc_Alloc_Loop1 ;continue ;an000; dms; | ||
| 580 | |||
| 581 | Realloc_Alloc_Loop1_Exit: | ||
| 582 | |||
| 583 | mov cx,cs:[bp].Realloc_Page_Alloc ;new pages to alloc ;an000; dms; | ||
| 584 | cmp cx,0 ;pages requested? ;an001; dms; | ||
| 585 | je Realloc_Alloc_Exit ;no - exit routine ;an001; dms; | ||
| 586 | |||
| 587 | mov bx,si ;save si ;an001; dms; | ||
| 588 | cli ;ints off ;an001; dms; | ||
| 589 | call EMS_Page_Contig_Chk ;contig pages? ;an001; dms; | ||
| 590 | jnc Realloc_Next_Pages ;yes ;an001; dms; | ||
| 591 | mov ah,EMS_Code87 ;Too few pages avail ;an000; dms; | ||
| 592 | sti ;ints on ;an001; dms; | ||
| 593 | jmp Realloc_Error_Exit ;exit prog ;an000; dms; | ||
| 594 | |||
| 595 | Realloc_Next_Pages: | ||
| 596 | |||
| 597 | ;;;; mov ax,si ;ptr to new list ;an001; dms; | ||
| 598 | ;;;; inc ax ;contig to new links? ;an001; dms; | ||
| 599 | ;;;; cmp ax,bx ; ;an001; dms; | ||
| 600 | ;;;; je Realloc_Next_Pages1 ;yes continue ;an001; dms; | ||
| 601 | ;;;; mov ah,EMS_Code87 ;Too few pages avail ;an000; dms; | ||
| 602 | ;;;; sti ;ints on ;an001; dms; | ||
| 603 | ;;;; jmp Realloc_Error_Exit ;exit prog ;an000; dms; | ||
| 604 | |||
| 605 | Realloc_Next_Pages1: | ||
| 606 | |||
| 607 | call EMS_Link_Set ;set up page list ;an001; dms; | ||
| 608 | mov ax,si ;ptr to new list ;an001; dms; | ||
| 609 | mov si,bx ;end of old list ;an001; dms; | ||
| 610 | shl si,1 ;index entry ;an001; dms; | ||
| 611 | mov Page_Alloc_List[si],ax ;pick up new links ;an001; dms; | ||
| 612 | |||
| 613 | Realloc_Alloc_Exit: | ||
| 614 | |||
| 615 | mov bx,cs:[bp].Realloc_Page_Alloc ;additional pages ;an001; dms; | ||
| 616 | sub cs:Free_Pages,bx ;new free count ;an000; dms; | ||
| 617 | mov bx,cs:[bp].Realloc_Page_Count ;pass back page request ;an000; dms; | ||
| 618 | mov Handle_LookUp_Table.H_Pages[di],bx ;new page count ;an000; dms; | ||
| 619 | sti ;ints on ;an001; dms; | ||
| 620 | xor ah,ah ;clear ah ;an000; dms; | ||
| 621 | jmp Realloc_Exit ;exit ;an000; dms; | ||
| 622 | |||
| 623 | |||
| 624 | Realloc_Error_Exit: | ||
| 625 | |||
| 626 | cli ;ints off ;an000; dms; | ||
| 627 | mov si,cs:[bp].Realloc_LookUp_Index ;get handle index ;an000; dms; | ||
| 628 | mov bx,Handle_LookUp_Table.H_Pages[si] ;get orig. count ;an000; dms; | ||
| 629 | mov Handle_LookUp_Table.H_Pages[si],bx ;new page count ;an000; dms; | ||
| 630 | sti ;ints on ;an000; dms; | ||
| 631 | |||
| 632 | Realloc_Exit: | ||
| 633 | |||
| 634 | pop es ;restore segments ;an000; dms; | ||
| 635 | pop ds ; ;an000; dms; | ||
| 636 | |||
| 637 | pop si ;restore regs ;an000; dms; | ||
| 638 | pop di ; ;an000; dms; | ||
| 639 | pop dx ; ;an000; dms; | ||
| 640 | pop cx ; ;an000; dms; | ||
| 641 | |||
| 642 | ret ;return to caller ;an000; dms; | ||
| 643 | |||
| 644 | reallocate endp | ||
| 645 | |||
| 646 | |||
| 647 | |||
| 648 | page | ||
| 649 | ;========================================================================= | ||
| 650 | ;=============== Function 55h Logic - Alter Page Map & Jump ============= | ||
| 651 | ;========================================================================= | ||
| 652 | ;========================================================================= | ||
| 653 | ; Alter_And_Jump - This routine alters the page map and jumps | ||
| 654 | ; to the specified address. | ||
| 655 | ; | ||
| 656 | ; Inputs : AH - 55h (Alter page map & jump) | ||
| 657 | ; AL - Physical page number/segment selector | ||
| 658 | ; 0 = Physical page numbers specified | ||
| 659 | ; 1 = Segment addresses specified in lieu of | ||
| 660 | ; physical page numbers | ||
| 661 | ; DX - handle number | ||
| 662 | ; DS:SI - Pointer to map and jump structure | ||
| 663 | ; (see Map_And_Jump_Struct above) | ||
| 664 | ; | ||
| 665 | ; Outputs : Revised map | ||
| 666 | ; AH - Non-zero if error | ||
| 667 | ; | ||
| 668 | ;========================================================================= | ||
| 669 | Alter_And_Jump proc ;modify map ;an000; dms; | ||
| 670 | |||
| 671 | push bx ;save regs for jump ;an000; dms; | ||
| 672 | push cx ; ;an000; dms; | ||
| 673 | push di ; ;an000; dms; | ||
| 674 | push si ; ;an000; dms; | ||
| 675 | |||
| 676 | pushf ;save flags ;an000; dms; | ||
| 677 | push ds ;save segments ;an000; dms; | ||
| 678 | push es ; ;an000; dms; | ||
| 679 | |||
| 680 | mov bx,cs ;get code segment ;an000; dms; | ||
| 681 | mov es,bx ; es ;an000; dms; | ||
| 682 | |||
| 683 | mov cs:[bp].AAJ_Handle,dx ;save handle ;an000; dms; | ||
| 684 | mov cs:[bp].AAJ_Option,al ;save selector option ;an000; dms; | ||
| 685 | |||
| 686 | |||
| 687 | |||
| 688 | cmp dx,Num_Handles-1 ;dx > handle count ;an000; dms; | ||
| 689 | jbe AAJ_Check_Reusable ;continue test ;an000; dms; | ||
| 690 | mov ah,EMS_Code83 ;EMS handle bad ;an000; dms; | ||
| 691 | jmp AAJ_Error_Exit ;exit routine ;an000; dms; | ||
| 692 | |||
| 693 | AAJ_Check_Reusable: | ||
| 694 | |||
| 695 | mov ax,dx ;get handle ;an000; dms; | ||
| 696 | mov cs:[bp].AAJ_Mult,Type H_LookUp_Struc ;handle lookup table ;an000; dms; | ||
| 697 | mul cs:[bp].AAJ_Mult ;obtain index position ;an000; dms; | ||
| 698 | mov cs:[bp].AAJ_LookUp_Index,ax ;index to handle ;an000; dms; | ||
| 699 | mov di,ax ;place index in di ;an000; dms; | ||
| 700 | |||
| 701 | cli ;ints off ;an000; dms; | ||
| 702 | mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms; | ||
| 703 | mov cs:[bp].AAJ_Xref_Pages,ax ;save logical page count;an000; dms; | ||
| 704 | sti ;ints on ;an000; dms; | ||
| 705 | cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; | ||
| 706 | jne AAJ_Good_Handle ;handle good ;an000; dms; | ||
| 707 | mov ah,EMS_Code83 ;EMS handle bad ;an000; dms; | ||
| 708 | jmp AAJ_Error_Exit ;exit routine ;an000; dms; | ||
| 709 | |||
| 710 | AAJ_Good_Handle: | ||
| 711 | |||
| 712 | cmp cs:[bp].AAJ_Option,AAJ_Option_Max ;option in range? ;an000; dms; | ||
| 713 | jbe AAJ_Good_Option ;option good ;an000; dms; | ||
| 714 | mov ah,EMS_Code8F ;bad option ;an000; dms; | ||
| 715 | jmp AAJ_Error_Exit ;exit routine ;an000; dms; | ||
| 716 | |||
| 717 | AAJ_Good_Option: | ||
| 718 | |||
| 719 | les di,[si].Log_Phys_Map_Ptr ;point to map data ;an000; dms; | ||
| 720 | xor cx,cx ;clear loop counter ;an000; dms; | ||
| 721 | mov cl,[si].Log_Phys_Map_Len ;get loop count ;an000; dms; | ||
| 722 | mov dx,cs:[bp].AAJ_Handle ;get handle for call ;an000; dms; | ||
| 723 | mov bx,cs:[bp].AAJ_Xref_Pages ;logical page count ;an000; dms; | ||
| 724 | xor ah,ah ;clear high word ;an000; dms; | ||
| 725 | mov al,cs:[bp].AAJ_Option ;option selected ;an000; dms; | ||
| 726 | call Map_Pages ;map the pages requested;an000; dms; | ||
| 727 | or ah,ah ;error? ;an000; dms; | ||
| 728 | jnz AAJ_Error_Exit ;exit with error cond. ;an000; dms; | ||
| 729 | |||
| 730 | AAJ_Loop_Exit: | ||
| 731 | |||
| 732 | pop es ;restore regs ;an000; dms; | ||
| 733 | pop ds ; ;an000; dms; | ||
| 734 | popf ; ;an000; dms; | ||
| 735 | pop si ; ;an000; dms; | ||
| 736 | pop di ; ;an000; dms; | ||
| 737 | pop cx ; ;an000; dms; | ||
| 738 | pop bx ; ;an000; dms; | ||
| 739 | |||
| 740 | mov cs:[bp].IE_Alloc_Byte,Unallocated ;deallocate instance ;an000; dms; | ||
| 741 | |||
| 742 | jmp dword ptr [si].Target_Address ;jump to address & run ;an000; dms; | ||
| 743 | |||
| 744 | AAJ_Error_Exit: | ||
| 745 | |||
| 746 | pop es ;restore regs ;an000; dms; | ||
| 747 | pop ds ; ;an000; dms; | ||
| 748 | popf ; ;an000; dms; | ||
| 749 | pop si ; ;an000; dms; | ||
| 750 | pop di ; ;an000; dms; | ||
| 751 | pop cx ; ;an000; dms; | ||
| 752 | pop bx ; ;an000; dms; | ||
| 753 | |||
| 754 | |||
| 755 | ret ;return to caller ;an000; dms; | ||
| 756 | |||
| 757 | Alter_And_Jump endp ;end proc ;an000; dms; | ||
| 758 | |||
| 759 | |||
| 760 | |||
| 761 | page | ||
| 762 | ;========================================================================= | ||
| 763 | ;=============== Function 56h Logic - Alter Page Map & Call ============= | ||
| 764 | ;========================================================================= | ||
| 765 | |||
| 766 | |||
| 767 | |||
| 768 | ;========================================================================= | ||
| 769 | ; Alter_And_Call - This routine alters the page map and calls | ||
| 770 | ; the specified address. The mapping context | ||
| 771 | ; is saved on entry to the routine and restored | ||
| 772 | ; on exit from the routine. | ||
| 773 | ; | ||
| 774 | ; Inputs : AH - 56h (Alter page map & call) | ||
| 775 | ; AL - Physical page number/segment selector | ||
| 776 | ; 0 = Physical page numbers specified | ||
| 777 | ; 1 = Segment addresses specified in lieu of | ||
| 778 | ; physical page numbers | ||
| 779 | ; 2 = Give minimum required stack size | ||
| 780 | ; DX - handle number | ||
| 781 | ; DS:SI - Pointer to map and jump structure | ||
| 782 | ; (see Map_And_Call_Struc above) | ||
| 783 | ; | ||
| 784 | ; Outputs : Revised map | ||
| 785 | ; AH - Non-zero if error | ||
| 786 | ; BX - Function 2 = size in bytes needed for stack | ||
| 787 | ; | ||
| 788 | ;========================================================================= | ||
| 789 | |||
| 790 | |||
| 791 | Alter_And_Call proc ;modify map & call ;an000; dms; | ||
| 792 | |||
| 793 | cmp al,MAC_Stack_Status_Request ;stack report? ;an000; dms; | ||
| 794 | je MAC_Calc_Stack_Status ;yes ;an000; dms; | ||
| 795 | jb MAC_Alter_And_Call ;no - new mapping ;an000; dms; | ||
| 796 | mov ah,EMS_Code8F ;error occurred ;an000; dms; | ||
| 797 | jmp MAC_Stack_Exit ;exit routine ;an000; dms; | ||
| 798 | |||
| 799 | MAC_Calc_Stack_Status: | ||
| 800 | |||
| 801 | mov bx,8h ;room for call address ;an000; dms; | ||
| 802 | ; and return address | ||
| 803 | xor ax,ax ;signal no error ;an000; dms; | ||
| 804 | jmp MAC_Stack_Exit ;exit routine ;an000; dms; | ||
| 805 | |||
| 806 | MAC_Alter_And_Call: | ||
| 807 | |||
| 808 | cli ;ints off ;an000; dms; | ||
| 809 | mov cs:[bp].EMS_Reg_BX,bx ; ;an000; dms; | ||
| 810 | mov bx,ax ;save ax across flags ;an000; dms; | ||
| 811 | lahf ;move flags to ah ;an000; dms; | ||
| 812 | mov cs:[bp].EMS_Reg_FL,ax ;save flags ;an000; dms; | ||
| 813 | mov ax,bx ;restore ax ;an000; dms; | ||
| 814 | mov cs:[bp].EMS_Reg_CX,cx ; ;an000; dms; | ||
| 815 | mov cs:[bp].EMS_Reg_DX,dx ; ;an000; dms; | ||
| 816 | mov cs:[bp].EMS_Reg_DI,di ; ;an000; dms; | ||
| 817 | mov cs:[bp].EMS_Reg_SI,si ; ;an000; dms; | ||
| 818 | mov cs:[bp].EMS_Reg_DS,ds ; ;an000; dms; | ||
| 819 | mov cs:[bp].EMS_Reg_ES,es ; ;an000; dms; | ||
| 820 | |||
| 821 | mov cs:[bp].MAC_Option,al ;save option ;an000; dms; | ||
| 822 | sti ;ints on ;an000; dms; | ||
| 823 | cmp dx,Num_Handles-1 ;dx > handle count ;an000; dms; | ||
| 824 | jbe MAC_Check_Reusable ;continue test ;an000; dms; | ||
| 825 | mov ah,EMS_Code83 ;EMS handle bad ;an000; dms; | ||
| 826 | jmp MAC_Error_Exit ;exit routine ;an000; dms; | ||
| 827 | |||
| 828 | MAC_Check_Reusable: | ||
| 829 | |||
| 830 | mov ax,dx ;get handle ;an000; dms; | ||
| 831 | mov cs:[bp].MAC_Mult,Type H_LookUp_Struc ;handle lookup table ;an000; dms; | ||
| 832 | mul cs:[bp].MAC_Mult ;obtain index position ;an000; dms; | ||
| 833 | mov cs:[bp].MAC_LookUp_Index,ax ;index to handle ;an000; dms; | ||
| 834 | mov di,ax ;place index in di ;an000; dms; | ||
| 835 | |||
| 836 | cli ;ints off ;an000; dms; | ||
| 837 | mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms; | ||
| 838 | mov cs:[bp].MAC_Xref_Pages,ax ;save logical page count;an000; dms; | ||
| 839 | cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; | ||
| 840 | sti ;ints on ;an000; dms; | ||
| 841 | jne MAC_Verify_New_Count ;handle good ;an000; dms; | ||
| 842 | mov ah,EMS_Code83 ;EMS handle bad ;an000; dms; | ||
| 843 | jmp MAC_Error_Exit ;exit routine ;an000; dms; | ||
| 844 | |||
| 845 | MAC_Verify_New_Count: | ||
| 846 | |||
| 847 | cli ;ints off ;an000; dms; | ||
| 848 | mov ax,Map_Count ;get phys. page count ;an000; dms; | ||
| 849 | sti ;ints on ;an000; dms; | ||
| 850 | cmp [si].MAC_New_Page_Map_Len,al ;> physical pages ;an000; dms; | ||
| 851 | jbe MAC_Verify_Old_Count ;no - continue ;an000; dms; | ||
| 852 | mov ah,EMS_Code8B ;out of range ;an000; dms; | ||
| 853 | jmp MAC_Error_Exit ;exit routine ;an000; dms; | ||
| 854 | |||
| 855 | MAC_Verify_Old_Count: | ||
| 856 | |||
| 857 | cli ;ints off ;an000; dms; | ||
| 858 | mov ax,Map_Count ;get phys. page count ;an000; dms; | ||
| 859 | sti ;ints on ;an000; dms; | ||
| 860 | cmp [si].MAC_Old_Page_Map_Len,al ;> physical pages ;an000; dms; | ||
| 861 | jbe MAC_Do_Alter_and_Call ;no - continue ;an000; dms; | ||
| 862 | mov ah,EMS_Code8B ;yes - error ;an000; dms; | ||
| 863 | jmp MAC_Error_Exit ;exit routine ;an000; dms; | ||
| 864 | |||
| 865 | MAC_Do_Alter_And_Call: | ||
| 866 | |||
| 867 | jmp MAC_Build_Stack_And_Map ;build stack and map ;an000; dms; | ||
| 868 | ; new pages | ||
| 869 | MAC_Return_Routine: | ||
| 870 | |||
| 871 | jmp MAC_Strip_Stack_And_Map ;restore data strucs ;an000; dms; | ||
| 872 | ; and map old pages | ||
| 873 | |||
| 874 | MAC_Exit: | ||
| 875 | MAC_Error_Exit: | ||
| 876 | |||
| 877 | cli ;ints off ;an000; dms; | ||
| 878 | mov bx,ax ;save ax ;an000; dms; | ||
| 879 | mov ax,cs:[bp].EMS_Reg_FL ;obtain entry flag stat ;an000; dms; | ||
| 880 | sahf ;put in flags reg ;an000; dms; | ||
| 881 | mov ax,bx ;restore ax ;an000; dms; | ||
| 882 | mov bx,cs:[bp].EMS_Reg_BX ; ;an000; dms; | ||
| 883 | mov cx,cs:[bp].EMS_Reg_CX ; ;an000; dms; | ||
| 884 | mov dx,cs:[bp].EMS_Reg_DX ; ;an000; dms; | ||
| 885 | mov di,cs:[bp].EMS_Reg_DI ; ;an000; dms; | ||
| 886 | mov si,cs:[bp].EMS_Reg_SI ; ;an000; dms; | ||
| 887 | mov ds,cs:[bp].EMS_Reg_DS ; ;an000; dms; | ||
| 888 | mov es,cs:[bp].EMS_Reg_ES ; ;an000; dms; | ||
| 889 | sti ;ints on ;an000; dms; | ||
| 890 | |||
| 891 | MAC_Stack_Exit: | ||
| 892 | |||
| 893 | ret ;return to caller ;an000; dms; | ||
| 894 | |||
| 895 | |||
| 896 | ;========================================================================= | ||
| 897 | ; MAC_Build_Stack_And_Map : This routine will build the required | ||
| 898 | ; stack structure for a re-entrant | ||
| 899 | ; routine and map the new pages. | ||
| 900 | ; | ||
| 901 | ; Inputs : DS:SI - Pointer to data in Map_And_Call_Struc format | ||
| 902 | ; | ||
| 903 | ; Outputs : BP - Instance table to reflect data copyied to it | ||
| 904 | ; New mapped pages | ||
| 905 | ; AH - 0 = no error | ||
| 906 | ; >0 = error (determined by Map_Pages) | ||
| 907 | ; | ||
| 908 | ; Instance Table carries this data: Old Map Data | ||
| 909 | ; New Map Data | ||
| 910 | ; Map & Call Data | ||
| 911 | ; Context | ||
| 912 | ;========================================================================= | ||
| 913 | |||
| 914 | MAC_Build_Stack_And_Map: | ||
| 915 | |||
| 916 | mov cs:[bp].EMS_Reg_DS,ds ;save DS ;an000; dms; | ||
| 917 | mov cs:[bp].EMS_Reg_SI,si ;save SI ;an000; dms; | ||
| 918 | |||
| 919 | mov ax,word ptr [si].MAC_Old_Page_Map_Ptr[+2];get the segment ;an000; dms; | ||
| 920 | mov es,ax ; of the old map ;an000; dms; | ||
| 921 | mov di,word ptr [si].MAC_Old_Page_Map_Ptr[+0];get its offset ;an000; dms; | ||
| 922 | |||
| 923 | mov al,[si].MAC_Old_Page_Map_Len ;get length of data ;an000; dms; | ||
| 924 | cbw ;convert to word ;an000; dms; | ||
| 925 | xor dx,dx ;clear high word ;an000; dms; | ||
| 926 | mov bx,Type Log_Phys_Map_Struc ;struc size | ||
| 927 | mul bx ;get total byte count ;an000; dms; | ||
| 928 | cli ;ints off ;an000; dms; | ||
| 929 | mov bx,offset MAC_M_C_Log ;offset in struc ;an000; dms; | ||
| 930 | sti ;ints on ;an000; dms; | ||
| 931 | add bx,bp ;actual offset ;an000; dms; | ||
| 932 | call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms; | ||
| 933 | ; copy of data and | ||
| 934 | ; copy the data | ||
| 935 | mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; | ||
| 936 | mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; | ||
| 937 | |||
| 938 | mov ax,word ptr [si].MAC_New_Page_Map_Ptr[+2];get the segment ;an000; dms; | ||
| 939 | mov es,ax ; of the old map ;an000; dms; | ||
| 940 | mov di,word ptr [si].MAC_New_Page_Map_Ptr[+0];get its offset ;an000; dms; | ||
| 941 | |||
| 942 | mov al,[si].MAC_New_Page_Map_Len ;get length of data ;an000; dms; | ||
| 943 | cbw ;conver to word ;an000; dms; | ||
| 944 | xor dx,dx ;clear high word ;an000; dms; | ||
| 945 | mov bx,Type Log_Phys_Map_Struc ;struc size | ||
| 946 | mul bx ;get total byte count ;an000; dms; | ||
| 947 | cli ;ints off ;an000; dms; | ||
| 948 | mov bx,offset MAC_M_C_Log ;Ptr in struc ;an000; dms; | ||
| 949 | add bx,size MAC_M_C_Log/2 ;next entry ;an000; dms; | ||
| 950 | sti ;ints on ;an000; dms; | ||
| 951 | add bx,bp ;offset BP relative ;an000; dms; | ||
| 952 | call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms; | ||
| 953 | ; copy of data and | ||
| 954 | ; copy the data | ||
| 955 | mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; | ||
| 956 | mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; | ||
| 957 | |||
| 958 | mov ax,ds ;move seg of data to ;an000; dms; | ||
| 959 | mov es,ax ; es ;an000; dms; | ||
| 960 | mov di,si ;move off of data ;an000; dms; | ||
| 961 | mov ax,Type Map_And_Call_Struc ;get size of structure ;an000; dms; | ||
| 962 | cli ;ints off ;an000; dms; | ||
| 963 | mov bx,offset MAC_M_C_Data | ||
| 964 | sti ;ints on ;an000; dms; | ||
| 965 | add bx,bp ;offset BP relative ;an000; dms; | ||
| 966 | call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms; | ||
| 967 | ; copy of data and | ||
| 968 | ; copy the data | ||
| 969 | mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; | ||
| 970 | mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; | ||
| 971 | |||
| 972 | mov ax,cs ;get seg of context ;an000; dms; | ||
| 973 | mov es,ax ; in es ;an000; dms; | ||
| 974 | cli ;ints off ;an000; dms; | ||
| 975 | mov di,offset cs:Map_Table ;get offset of context ;an000; dms; | ||
| 976 | mov ax,Map_Count ;get context entry count;an000; dms; | ||
| 977 | sti ;ints on ;an000; dms; | ||
| 978 | xor dx,dx ;clear dx ;an000; dms; | ||
| 979 | mov bx,Type Mappable_Phys_Page_Struct ;get struc size ;an000; dms; | ||
| 980 | mul bx ;get size in bytes ;an000; dms; | ||
| 981 | cli ;ints off ;an000; dms; | ||
| 982 | mov bx,offset cs:MAC_Map_Table | ||
| 983 | sti ;ints on ;an000; dms; | ||
| 984 | add bx,bp ;offset BP relative ;an000; dms; | ||
| 985 | call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms; | ||
| 986 | ; copy of data and | ||
| 987 | ; copy the data | ||
| 988 | mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; | ||
| 989 | mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; | ||
| 990 | |||
| 991 | push cs ;save return segment ;an000; dms; | ||
| 992 | mov ax,offset MAC_Return_Routine ;save return offset ;an000; dms; | ||
| 993 | push ax ; ;an000; dms; | ||
| 994 | |||
| 995 | mov ax,word ptr [si].MAC_Target_Address[+2] ;get seg of call far ;an000; dms; | ||
| 996 | mov bx,word ptr [si].MAC_Target_Address[+0] ;get offset of call far ;an000; dms; | ||
| 997 | push ax ;put on stack ;an000; dms; | ||
| 998 | push bx ; ;an000; dms; | ||
| 999 | |||
| 1000 | les di,[si].MAC_New_Page_Map_Ptr ;set up for call ;an000; dms; | ||
| 1001 | xor cx,cx ;clear cx ;an000; dms; | ||
| 1002 | mov cl,[si].MAC_New_Page_Map_Len ;get array size ;an000; dms; | ||
| 1003 | mov dx,cs:[bp].EMS_Reg_DX ;get handle for call ;an000; dms; | ||
| 1004 | mov bx,cs:[bp].MAC_Xref_Pages ;get handle page count ;an000; dms; | ||
| 1005 | xor ah,ah ;clear high word ;an000; dms; | ||
| 1006 | mov al,cs:[bp].MAC_Option ;get option ;an000; dms; | ||
| 1007 | |||
| 1008 | call Map_Pages ;map the new pages ;an000; dms; | ||
| 1009 | or ah,ah ;error? ;an000; dms; | ||
| 1010 | jnz MAC_Error_Strip_Stack ;take data off stack ;an000; dms; | ||
| 1011 | |||
| 1012 | cli ;ints off ;an000; dms; | ||
| 1013 | mov ax,cs:[bp].EMS_Reg_FL ;obtain entry flag stat ;an000; dms; | ||
| 1014 | sahf ;put in flags reg ;an000; dms; | ||
| 1015 | mov bx,cs:[bp].EMS_Reg_BX ; ;an000; dms; | ||
| 1016 | mov cx,cs:[bp].EMS_Reg_CX ; ;an000; dms; | ||
| 1017 | mov dx,cs:[bp].EMS_Reg_DX ; ;an000; dms; | ||
| 1018 | mov di,cs:[bp].EMS_Reg_DI ; ;an000; dms; | ||
| 1019 | mov si,cs:[bp].EMS_Reg_SI ; ;an000; dms; | ||
| 1020 | mov ds,cs:[bp].EMS_Reg_DS ; ;an000; dms; | ||
| 1021 | mov es,cs:[bp].EMS_Reg_ES ; ;an000; dms; | ||
| 1022 | sti ;ints on ;an000; dms; | ||
| 1023 | |||
| 1024 | Retf_Fake_Out Proc Far ;this proc is to ;an000; dms; | ||
| 1025 | ; simulate a RETF | ||
| 1026 | ; instruction | ||
| 1027 | ret ;performs a far return ;an000; dms; | ||
| 1028 | |||
| 1029 | Retf_Fake_Out Endp ;end of retf fake out ;an000; dms; | ||
| 1030 | |||
| 1031 | |||
| 1032 | MAC_Error_Strip_Stack: | ||
| 1033 | |||
| 1034 | add sp,8h ;adjust for return add. ;an000; dms; | ||
| 1035 | ; and target add. on | ||
| 1036 | ; error | ||
| 1037 | jmp MAC_Error_Exit ;exit routine ;an000; dms; | ||
| 1038 | |||
| 1039 | |||
| 1040 | ;========================================================================= | ||
| 1041 | ; MAC_Strip_Stack_And_Map : This routine will strip the stack of all | ||
| 1042 | ; the data placed on by MAC_Build_Stack_And_Map. | ||
| 1043 | ; | ||
| 1044 | ; Inputs : CS:BP - Pointer to data on the instance table | ||
| 1045 | ; | ||
| 1046 | ; Outputs : All data area restored | ||
| 1047 | ; Pages remapped to original | ||
| 1048 | ; AH - 0 = no error | ||
| 1049 | ; >0 = error (determined by Map_Pages) | ||
| 1050 | ; | ||
| 1051 | ; Instance Table carries this data: Old Map Data | ||
| 1052 | ; New Map Data | ||
| 1053 | ; Map & Call Data | ||
| 1054 | ; Context | ||
| 1055 | ;========================================================================= | ||
| 1056 | |||
| 1057 | MAC_Strip_Stack_And_Map: ;an000; dms; | ||
| 1058 | |||
| 1059 | mov ax,cs ;seg of context ;an000; dms; | ||
| 1060 | mov es,ax ;place in es ;an000; dms; | ||
| 1061 | cli ;ints off ;an000; dms; | ||
| 1062 | mov di,offset cs:Map_Table ;get off of context ;an000; dms; | ||
| 1063 | mov ax,Map_Count ;get entries in context ;an000; dms; | ||
| 1064 | sti ;ints on ;an000; dms; | ||
| 1065 | xor dx,dx ;clear dx ;an000; dms; | ||
| 1066 | mov bx,Type Mappable_Phys_Page_Struct ;struc size ;an000; dms; | ||
| 1067 | mul bx ;get byte count ;an000; dms; | ||
| 1068 | cli ;ints off ;an000; dms; | ||
| 1069 | mov bx,offset MAC_Map_Table | ||
| 1070 | sti ;ints on ;an000; dms; | ||
| 1071 | add bx,bp ;offset BP relative ;an000; dms; | ||
| 1072 | call MAC_Shrink_Stack_And_Copy ;restore context ;an000; dms; | ||
| 1073 | |||
| 1074 | mov si,cs:[bp].EMS_Reg_SI ;restore pointer ;an000; dms; | ||
| 1075 | mov ds,cs:[bp].EMS_Reg_DS ; to data struc ;an000; dms; | ||
| 1076 | |||
| 1077 | mov ax,ds ;transfer seg of struc ;an000; dms; | ||
| 1078 | mov es,ax ; to dest. segment ;an000; dms; | ||
| 1079 | mov di,si ;di=dest. offset ;an000; dms; | ||
| 1080 | mov ax,Type Map_And_Call_Struc ;get size to move ;an000; dms; | ||
| 1081 | cli ;ints off ;an000; dms; | ||
| 1082 | mov bx,offset MAC_M_C_Data | ||
| 1083 | sti ;ints on ;an000; dms; | ||
| 1084 | add bx,bp ;offset BP relative ;an000; dms; | ||
| 1085 | call MAC_Shrink_Stack_And_Copy ;restore Map & Call buf ;an000; dms; | ||
| 1086 | |||
| 1087 | mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; | ||
| 1088 | mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; | ||
| 1089 | |||
| 1090 | mov ax,word ptr [si].MAC_New_Page_Map_Ptr[+2];get the segment ;an000; dms; | ||
| 1091 | mov es,ax ; of the old map ;an000; dms; | ||
| 1092 | mov di,word ptr [si].MAC_New_Page_Map_Ptr[+0];get its offset ;an000; dms; | ||
| 1093 | |||
| 1094 | mov al,[si].MAC_New_Page_Map_Len ;get length of data ;an000; dms; | ||
| 1095 | cbw ;convert to word ;an000; dms; | ||
| 1096 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1097 | mov bx,Type Log_Phys_Map_Struc ;struc size ;an000; dms; | ||
| 1098 | mul bx ;get total byte count ;an000; dms; | ||
| 1099 | cli ;ints off ;an000; dms; | ||
| 1100 | mov bx,offset MAC_M_C_Log | ||
| 1101 | sti ;ints on ;an000; dms; | ||
| 1102 | add bx,size MAC_M_C_Log/2 | ||
| 1103 | add bx,bp ;offset BP relative ;an000; dms; | ||
| 1104 | call MAC_Shrink_Stack_And_Copy ;restore new page data ;an000; dms; | ||
| 1105 | |||
| 1106 | mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; | ||
| 1107 | mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; | ||
| 1108 | |||
| 1109 | mov ax,word ptr [si].MAC_Old_Page_Map_Ptr[+2];get the segment ;an000; dms; | ||
| 1110 | mov es,ax ; of the old map ;an000; dms; | ||
| 1111 | mov di,word ptr [si].MAC_Old_Page_Map_Ptr[+0];get its offset ;an000; dms; | ||
| 1112 | |||
| 1113 | mov al,[si].MAC_Old_Page_Map_Len ;get length of data ;an000; dms; | ||
| 1114 | cbw ;convert to word ;an000; dms; | ||
| 1115 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1116 | mov bx,Type Log_Phys_Map_Struc ;struc size ;an000; dms; | ||
| 1117 | mul bx ;get total byte count ;an000; dms; | ||
| 1118 | cli ;ints off ;an000; dms; | ||
| 1119 | mov bx,offset MAC_M_C_Log | ||
| 1120 | sti ;ints on ;an000; dms; | ||
| 1121 | add bx,bp ;offset BP relative ;an000; dms; | ||
| 1122 | call MAC_Shrink_Stack_And_Copy ;set up stack for ;an000; dms; | ||
| 1123 | |||
| 1124 | mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; | ||
| 1125 | mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; | ||
| 1126 | |||
| 1127 | mov dx,cs:[bp].EMS_Reg_DX ;get DX reg | ||
| 1128 | |||
| 1129 | les di,[si].MAC_Old_Page_Map_Ptr ;set up for call ;an000; dms; | ||
| 1130 | xor cx,cx ;clear cx ;an000; dms; | ||
| 1131 | mov cl,[si].MAC_Old_Page_Map_Len ;get array size ;an000; dms; | ||
| 1132 | mov bx,cs:[bp].MAC_Xref_Pages ;get handle page count ;an000; dms; | ||
| 1133 | xor ah,ah ;clear high byte ;an000; dms; | ||
| 1134 | mov al,cs:[bp].MAC_Option ;get option ;an000; dms; | ||
| 1135 | |||
| 1136 | call Map_Pages ;map the new pages ;an000; dms; | ||
| 1137 | |||
| 1138 | jmp MAC_Exit ;exit the program ;an000; dms; | ||
| 1139 | |||
| 1140 | |||
| 1141 | Alter_And_Call endp ;end proc ;an000; dms; | ||
| 1142 | |||
| 1143 | |||
| 1144 | page | ||
| 1145 | ;========================================================================= | ||
| 1146 | ;=============== Function 57h Logic - Move/Exchange Memory Region ======= | ||
| 1147 | ;========================================================================= | ||
| 1148 | |||
| 1149 | ;========================================================================= | ||
| 1150 | ; Exchng_Region - This routine moves/exchanges memory regions | ||
| 1151 | ; specified by the user. The following types of | ||
| 1152 | ; moves/exchanges are possible: | ||
| 1153 | ; | ||
| 1154 | ; Source Destination | ||
| 1155 | ; ------------------- ---------------------- | ||
| 1156 | ; Conventional Memory Expanded Memory | ||
| 1157 | ; Expanded Memory Conventional Memory | ||
| 1158 | ; Expanded Memory Expanded Memory | ||
| 1159 | ; | ||
| 1160 | ; Inputs : AH - 57h (Move/Exchange Memory Region) | ||
| 1161 | ; AL - Type of transfer | ||
| 1162 | ; 0 = Move memory | ||
| 1163 | ; 1 = Exchange memory | ||
| 1164 | ; DS:SI - Pointer to Move_Source_Dest Structure | ||
| 1165 | ; | ||
| 1166 | ; Outputs : Revised map | ||
| 1167 | ; AH - Non-zero if error | ||
| 1168 | ;========================================================================= | ||
| 1169 | |||
| 1170 | |||
| 1171 | Exchng_Region proc | ||
| 1172 | |||
| 1173 | push bx ;save regs ;an000; dms; | ||
| 1174 | push cx ; ;an000; dms; | ||
| 1175 | push dx ; ;an000; dms; | ||
| 1176 | push di ; ;an000; dms; | ||
| 1177 | push si ; ;an000; dms; | ||
| 1178 | push ds ; ;an000; dms; | ||
| 1179 | push es ; ;an000; dms; | ||
| 1180 | |||
| 1181 | mov cs:[bp].ER_Sub_Function,al ;save subfunction ;an000; dms; | ||
| 1182 | cmp al,ER_Max_Function ;valid function? ;an000; dms; | ||
| 1183 | jbe ER_Valid_Sub_Function ;yes - continue ;an000; dms; | ||
| 1184 | mov ah,EMS_Code8F ;no - error ;an000; dms; | ||
| 1185 | jmp ER_Error_Exit ;exit routine ;an000; dms; | ||
| 1186 | |||
| 1187 | ER_Valid_Sub_Function: | ||
| 1188 | |||
| 1189 | call ER_Type_Check ;Proper types & ;an000; dms; | ||
| 1190 | or ah,ah ; type combinations? ;an000; dms; | ||
| 1191 | jnz ER_Error_Exit ;no - exit routine ;an000; dms; | ||
| 1192 | |||
| 1193 | call ER_Handle_Check ;valid handles? ;an000; dms; | ||
| 1194 | or ah,ah ; ;an000; dms; | ||
| 1195 | jnz ER_Error_Exit ;no - exit routine ;an000; dms; | ||
| 1196 | |||
| 1197 | call ER_Length_Check ;Region fits in page ;an000; dms; | ||
| 1198 | or ah,ah ; and <= 1Mb? ;an000; dms; | ||
| 1199 | jnz ER_Error_Exit ;no - exit routine ;an000; dms; | ||
| 1200 | |||
| 1201 | call ER_Wrap_Check ;> 1Mb wrap on move? ;an000; dms; | ||
| 1202 | or ah,ah ; ;an000; dms; | ||
| 1203 | jnz ER_Error_Exit ;yes - exit routine ;an000; dms; | ||
| 1204 | |||
| 1205 | call ER_Overlap_Check ;conv. memory overlaps ;an000; dms; | ||
| 1206 | or ah,ah ; EMS page frame? ;an000; dms; | ||
| 1207 | jnz ER_Error_Exit ;yes - exit routine ;an000; dms; | ||
| 1208 | |||
| 1209 | call ER_Log_Page_Test ;offset valid for log. ;an000; dms; | ||
| 1210 | or ah,ah ; page? ;an000; dms; | ||
| 1211 | jnz ER_Error_Exit ;no - exit routine ;an000; dms; | ||
| 1212 | |||
| 1213 | cmp cs:[bp].ER_Sub_Function,ER_Move ;move? ;an000; dms; | ||
| 1214 | je ER_Move_Call ;yes - perform move ;an000; dms; | ||
| 1215 | call ER_EMS_Overlap_Check ;EMS pages overlap? ;an000; dms; | ||
| 1216 | or ah,ah ; | ||
| 1217 | jz ER_Exchange_No_Overlap ;no - exit with error ;an000; dms; | ||
| 1218 | mov ah,EMS_Code97 ;signal error ;an000; dms; | ||
| 1219 | jmp ER_Error_Exit ;exit with error code ;an000; dms; | ||
| 1220 | |||
| 1221 | ER_Exchange_No_Overlap: | ||
| 1222 | |||
| 1223 | call ER_Exchange_Data ;no - perform exchange ;an000; dms; | ||
| 1224 | jmp ER_Exit ;exit the routine ;an000; dms; | ||
| 1225 | |||
| 1226 | ER_Move_Call: | ||
| 1227 | |||
| 1228 | call ER_EMS_Overlap_Check ;see if we had a move ;an000; dms; | ||
| 1229 | ; overlap | ||
| 1230 | push ax ;save result across call;an000; dms; | ||
| 1231 | call ER_Move_Data ;perform the move ;an000; dms; | ||
| 1232 | pop ax ;restore result ;an000; dms; | ||
| 1233 | |||
| 1234 | ER_Exit: | ||
| 1235 | ER_Error_Exit: | ||
| 1236 | |||
| 1237 | pop es ;restore regs ;an000; dms; | ||
| 1238 | pop ds ; ;an000; dms; | ||
| 1239 | pop si ; ;an000; dms; | ||
| 1240 | pop di ; ;an000; dms; | ||
| 1241 | pop dx ; ;an000; dms; | ||
| 1242 | pop cx ; ;an000; dms; | ||
| 1243 | pop bx ; ;an000; dms; | ||
| 1244 | |||
| 1245 | ret ;return to caller ;an000; dms; | ||
| 1246 | |||
| 1247 | Exchng_Region endp | ||
| 1248 | |||
| 1249 | |||
| 1250 | ;========================================================================= | ||
| 1251 | ; ER_Handle_Check : This routine checks to see if the EMS handles | ||
| 1252 | ; specified are valid. | ||
| 1253 | ; | ||
| 1254 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 1255 | ; | ||
| 1256 | ; Outputs : AH - Non-zero on error | ||
| 1257 | ; Possible error codes: 83h | ||
| 1258 | ;========================================================================= | ||
| 1259 | |||
| 1260 | ER_Handle_Check proc ;check requested handles;an000; dms; | ||
| 1261 | |||
| 1262 | push dx ;save regs ;an000; dms; | ||
| 1263 | push di ; ;an000; dms; | ||
| 1264 | |||
| 1265 | cmp [si].Source_Memory_Type,ER_Conv_Memory ;Conv memory for source?;an000; dms; | ||
| 1266 | je ER_Handle_Check_Dest ;yes - ck dest. handle ;an000; dms; | ||
| 1267 | |||
| 1268 | push dx ;save dx ;an000; dms; | ||
| 1269 | xor dx,dx ;clear it ;an000; dms; | ||
| 1270 | mov ax,[si].Source_Handle ;get handle requested ;an000; dms; | ||
| 1271 | mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms; | ||
| 1272 | mul dx ;obtain index position ;an000; dms; | ||
| 1273 | mov di,ax ;place index in di ;an000; dms; | ||
| 1274 | pop dx ;restore dx ;an000; dms; | ||
| 1275 | |||
| 1276 | cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; | ||
| 1277 | je ER_Handle_Check_Error_Exit ;handle not allocated ;an000; dms; | ||
| 1278 | |||
| 1279 | ER_Handle_Check_Dest: | ||
| 1280 | |||
| 1281 | cmp [si].Dest_Memory_Type,ER_Conv_Memory ;Conv memory for dest? ;an000; dms; | ||
| 1282 | je ER_Handle_Check_Good_Exit ;yes - exit routine ;an000; dms; | ||
| 1283 | |||
| 1284 | push dx ;save dx ;an000; dms; | ||
| 1285 | xor dx,dx ;clear it ;an000; dms; | ||
| 1286 | mov ax,[si].Dest_Handle ;get handle requested ;an000; dms; | ||
| 1287 | mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms; | ||
| 1288 | mul dx ;obtain index position ;an000; dms; | ||
| 1289 | mov di,ax ;place index in di ;an000; dms; | ||
| 1290 | pop dx ;restore dx ;an000; dms; | ||
| 1291 | |||
| 1292 | cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; | ||
| 1293 | je ER_Handle_Check_Error_Exit ;handle not allocated ;an000; dms; | ||
| 1294 | |||
| 1295 | ER_Handle_Check_Good_Exit: | ||
| 1296 | |||
| 1297 | xor ah,ah ;signal no error ;an000; dms; | ||
| 1298 | jmp ER_Handle_Check_Exit ;exit program ;an000; dms; | ||
| 1299 | |||
| 1300 | ER_Handle_Check_Error_Exit: | ||
| 1301 | |||
| 1302 | mov ah,EMS_Code83 ;signal error ;an000; dms; | ||
| 1303 | |||
| 1304 | ER_Handle_Check_Exit: | ||
| 1305 | |||
| 1306 | pop di ;restore regs ;an000; dms; | ||
| 1307 | pop dx ; ;an000; dms; | ||
| 1308 | |||
| 1309 | ret ;return to caller ;an000; dms; | ||
| 1310 | |||
| 1311 | ER_Handle_Check endp ;end proc ;an000; dms; | ||
| 1312 | |||
| 1313 | |||
| 1314 | |||
| 1315 | ;========================================================================= | ||
| 1316 | ; ER_Length_Check : This routine checks to see if the region length | ||
| 1317 | ; specified exceeds the page count of either the | ||
| 1318 | ; source or destination EMS handle pages allocated. | ||
| 1319 | ; It also checks to determine if the region length | ||
| 1320 | ; exceeds 1 Mb. | ||
| 1321 | ; | ||
| 1322 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 1323 | ; | ||
| 1324 | ; Outputs : AH - Non-zero on error | ||
| 1325 | ; Possible error codes: 93h | ||
| 1326 | ; 96h | ||
| 1327 | ; 8Ah | ||
| 1328 | ;========================================================================= | ||
| 1329 | |||
| 1330 | ER_Length_Check proc ;check region length ;an000; dms; | ||
| 1331 | |||
| 1332 | push bx ;save regs ;an000; dms; | ||
| 1333 | push cx ; ;an000; dms; | ||
| 1334 | push dx ; ;an000; dms; | ||
| 1335 | push di ; ;an000; dms; | ||
| 1336 | |||
| 1337 | mov cx,[si].Region_Length_High_Word ;get size of the region ;an000; dms; | ||
| 1338 | mov bx,[si].Region_Length_Low_Word ; in CX:BX ;an000; dms; | ||
| 1339 | cmp cx,ER_10H ;> 1Mb ;an000; dms; | ||
| 1340 | ja ER_Length_Check_Error96 ;exit with error ;an000; dms; | ||
| 1341 | cmp cx,ER_10H ;high word = 10h? ;an000; dms; | ||
| 1342 | jne ER_Length_Check_Cont ;no - continue ;an000; dms; | ||
| 1343 | cmp bx,0 ;low word other than 0? ;an000; dms; | ||
| 1344 | je ER_Length_Check_Cont ;no - good value ;an000; dms; | ||
| 1345 | |||
| 1346 | ER_Length_Check_Error96: | ||
| 1347 | |||
| 1348 | mov ah,EMS_Code96 ;signal error ;an000; dms; | ||
| 1349 | jmp ER_Length_Check_Exit ;exit routine | ||
| 1350 | |||
| 1351 | ER_Length_Check_Cont: | ||
| 1352 | |||
| 1353 | cmp [si].Source_Memory_Type,ER_Conv_Memory ;Conv memory for source?;an000; dms; | ||
| 1354 | je ER_Length_Check_Dest ;yes - ck dest. length ;an000; dms; | ||
| 1355 | |||
| 1356 | push dx ;save dx ;an000; dms; | ||
| 1357 | xor dx,dx ;clear it ;an000; dms; | ||
| 1358 | mov ax,[si].Source_Handle ;get handle requested ;an000; dms; | ||
| 1359 | mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms; | ||
| 1360 | mul dx ;obtain index position ;an000; dms; | ||
| 1361 | mov di,ax ;place index in di ;an000; dms; | ||
| 1362 | pop dx ;restore dx ;an000; dms; | ||
| 1363 | |||
| 1364 | mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms; | ||
| 1365 | ; for source handle | ||
| 1366 | sub ax,[si].Source_Initial_Seg_Page ;pages in EMS to fill ;an000; dms; | ||
| 1367 | push ax ;save ax ;an000; dms; | ||
| 1368 | dec ax ;make it 0 based ;an000; dms; | ||
| 1369 | pop ax ;restore ax ;an000; dms; | ||
| 1370 | js ER_Length_Check_Error8A_Exit ;page out of range ;an000; dms; | ||
| 1371 | |||
| 1372 | xor dx,dx ;clear it ;an000; dms; | ||
| 1373 | mov dx,EMS_Page_Size_In_Bytes+1 ;page size in bytes ;an000; dms; | ||
| 1374 | mul dx ;get total bytes to trf ;an000; dms; | ||
| 1375 | sub ax,[si].Source_Initial_Offset ;get byte count in 1st ;an000; dms; | ||
| 1376 | sbb dx,0 | ||
| 1377 | |||
| 1378 | mov bx,ax ;prepare for DWORD comp ;an000; dms; | ||
| 1379 | mov ax,dx ; ;an000; dms; | ||
| 1380 | |||
| 1381 | mov cx,[si].Region_Length_High_Word ;get size of the region ;an000; dms; | ||
| 1382 | mov dx,[si].Region_Length_Low_Word ; in CX:BX ;an000; dms; | ||
| 1383 | |||
| 1384 | call ER_Dword_Compare ;region > target? ;an000; dms; | ||
| 1385 | jc ER_Length_Check_Error93_Exit ;CY = region > target ;an000; dms; | ||
| 1386 | |||
| 1387 | |||
| 1388 | ER_Length_Check_Dest: | ||
| 1389 | |||
| 1390 | cmp [si].Dest_Memory_Type,ER_Conv_Memory ;Conv memory for dest? ;an000; dms; | ||
| 1391 | je ER_Length_Check_Good_Exit ;yes - exit routine ;an000; dms; | ||
| 1392 | |||
| 1393 | push dx ;save dx ;an000; dms; | ||
| 1394 | xor dx,dx ;clear it ;an000; dms; | ||
| 1395 | mov ax,[si].Dest_Handle ;get handle requested ;an000; dms; | ||
| 1396 | mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms; | ||
| 1397 | mul dx ;obtain index position ;an000; dms; | ||
| 1398 | mov di,ax ;place index in di ;an000; dms; | ||
| 1399 | pop dx ;restore dx ;an000; dms; | ||
| 1400 | |||
| 1401 | mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms; | ||
| 1402 | |||
| 1403 | sub ax,[si].Dest_Initial_Seg_Page ;pages in EMS to fill ;an000; dms; | ||
| 1404 | push ax ;save ax ;an000; dms; | ||
| 1405 | dec ax ;make it 0 based ;an000; dms; | ||
| 1406 | pop ax ;restore ax ;an000; dms; | ||
| 1407 | js ER_Length_Check_Error8A_Exit ;page out of range ;an000; dms; | ||
| 1408 | |||
| 1409 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1410 | mov dx,EMS_Page_Size_In_Bytes+1 ;page size in bytes ;an000; dms; | ||
| 1411 | mul dx ;get total bytes to trf ;an000; dms; | ||
| 1412 | sub ax,[si].Dest_Initial_Offset ;get byte count in 1st ;an000; dms; | ||
| 1413 | sbb dx,0 | ||
| 1414 | |||
| 1415 | mov bx,ax ;prepare for DWORD comp ;an000; dms; | ||
| 1416 | mov ax,dx ; ;an000; dms; | ||
| 1417 | |||
| 1418 | mov cx,[si].Region_Length_High_Word ;get size of the region ;an000; dms; | ||
| 1419 | mov dx,[si].Region_Length_Low_Word ; in CX:BX ;an000; dms; | ||
| 1420 | |||
| 1421 | call ER_Dword_Compare ;region > target? ;an000; dms; | ||
| 1422 | jc ER_Length_Check_Error93_Exit ;CY = region > target ;an000; dms; | ||
| 1423 | |||
| 1424 | |||
| 1425 | ER_Length_Check_Good_Exit: | ||
| 1426 | |||
| 1427 | xor ah,ah ;signal no error ;an000; dms; | ||
| 1428 | jmp ER_Length_Check_Exit ;exit routine ;an000; dms; | ||
| 1429 | |||
| 1430 | ER_Length_Check_Error93_Exit: | ||
| 1431 | |||
| 1432 | mov ah,EMS_Code93 ;signal error ;an000; dms; | ||
| 1433 | jmp ER_Length_Check_Exit ;exit routine ;an000; dms; | ||
| 1434 | |||
| 1435 | ER_Length_Check_Error8A_Exit: | ||
| 1436 | |||
| 1437 | mov ah,EMS_Code8A ;signal error ;an000; dms; | ||
| 1438 | |||
| 1439 | ER_Length_Check_Exit: ;main exit ;an000; dms; | ||
| 1440 | |||
| 1441 | pop di ;restore regs ;an000; dms; | ||
| 1442 | pop dx ; ;an000; dms; | ||
| 1443 | pop cx ; ;an000; dms; | ||
| 1444 | pop bx ; ;an000; dms; | ||
| 1445 | |||
| 1446 | ret ;return to caller ;an000; dms; | ||
| 1447 | |||
| 1448 | ER_Length_Check endp ;end proc ;an000; dms; | ||
| 1449 | |||
| 1450 | |||
| 1451 | ;========================================================================= | ||
| 1452 | ; ER_Type_Check : This routine checks the source/destination type | ||
| 1453 | ; specified to determine if they are within the | ||
| 1454 | ; proper range. | ||
| 1455 | ; | ||
| 1456 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 1457 | ; | ||
| 1458 | ; Outputs : AH - Non-zero on error | ||
| 1459 | ; Possible error codes: 98h | ||
| 1460 | ;========================================================================= | ||
| 1461 | |||
| 1462 | ER_Type_Check proc ;check type ;an000; dms; | ||
| 1463 | |||
| 1464 | cmp [si].Source_Memory_Type,ER_Max_Type ;type within range? ;an000; dms; | ||
| 1465 | ja ER_Type_Check_Error_Exit ;no - error exit ;an000; dms; | ||
| 1466 | |||
| 1467 | cmp [si].Dest_Memory_Type,ER_Max_Type ;type within range? ;an000; dms; | ||
| 1468 | ja ER_Type_Check_Error_Exit ;no - error exit ;an000; dms; | ||
| 1469 | |||
| 1470 | |||
| 1471 | ER_Type_Check_Good_Exit: | ||
| 1472 | |||
| 1473 | xor ah,ah ;signal no error ;an000; dms; | ||
| 1474 | jmp ER_Type_Check_Exit ;exit routine ;an000; dms; | ||
| 1475 | |||
| 1476 | ER_Type_Check_Error_Exit: | ||
| 1477 | |||
| 1478 | mov ah,EMS_Code98 ;signal error ;an000; dms; | ||
| 1479 | |||
| 1480 | ER_Type_Check_Exit: | ||
| 1481 | |||
| 1482 | ret ;return to caller ;an000; dms; | ||
| 1483 | |||
| 1484 | ER_Type_Check endp ;end proc ;an000; dms; | ||
| 1485 | |||
| 1486 | |||
| 1487 | ;========================================================================= | ||
| 1488 | ; ER_Wrap_Check : This routine checks to determine if there will be | ||
| 1489 | ; a wrap of conventional memory beyond 1Mb. | ||
| 1490 | ; | ||
| 1491 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 1492 | ; | ||
| 1493 | ; Outputs : AH - Non-zero on error | ||
| 1494 | ; Possible error codes: A2h | ||
| 1495 | ;========================================================================= | ||
| 1496 | |||
| 1497 | ER_Wrap_Check proc ;cks. conv. mem. wrap ;an000; dms; | ||
| 1498 | |||
| 1499 | push dx ;save regs ;an000; dms; | ||
| 1500 | push bx ; ;an000; dms; | ||
| 1501 | |||
| 1502 | cmp [si].Source_Memory_Type,ER_Conv_Memory ;conv. memory? ;an000; dms; | ||
| 1503 | jne ER_Wrap_Check_Dest ;no -check dest. ;an000; dms; | ||
| 1504 | |||
| 1505 | mov ax,[si].Source_Initial_Seg_Page ;get segment ;an000; dms; | ||
| 1506 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1507 | mov bx,ER_10H ;adjust segment to ;an000; dms; | ||
| 1508 | ; absolute address | ||
| 1509 | mul bx ; ;an000; dms; | ||
| 1510 | add ax,[si].Source_Initial_Offset ;add in offset ;an000; dms; | ||
| 1511 | adc dx,0 ;pick up carry if any ;an000; dms; | ||
| 1512 | |||
| 1513 | add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; | ||
| 1514 | ; trf size | ||
| 1515 | adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; | ||
| 1516 | ; trf size | ||
| 1517 | cmp dx,ER_10H ;> 1Mb? ;an000; dms; | ||
| 1518 | jae ER_Wrap_Check_Error_Exit ;yes - signal error ;an000; dms; | ||
| 1519 | jmp ER_Wrap_Check_Good_Exit ;no - signal no error ;an000; dms; | ||
| 1520 | |||
| 1521 | ER_Wrap_Check_Dest: | ||
| 1522 | |||
| 1523 | cmp [si].Dest_Memory_Type,ER_Conv_Memory ;conv. memory? ;an000; dms; | ||
| 1524 | jne ER_Wrap_Check_Good_Exit ;no - exit routine ;an000; dms; | ||
| 1525 | |||
| 1526 | mov ax,[si].Dest_Initial_Seg_Page ;get segment ;an000; dms; | ||
| 1527 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1528 | mov bx,ER_10H ;adjust segment to ;an000; dms; | ||
| 1529 | ; absolute address | ||
| 1530 | mul bx ; ;an000; dms; | ||
| 1531 | add ax,[si].Dest_Initial_Offset ;add in offset ;an000; dms; | ||
| 1532 | adc dx,0 ;pick up carry if any ;an000; dms; | ||
| 1533 | |||
| 1534 | add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; | ||
| 1535 | ; trf size | ||
| 1536 | adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; | ||
| 1537 | ; trf size | ||
| 1538 | cmp dx,ER_10H ;> 1Mb? ;an000; dms; | ||
| 1539 | jae ER_Wrap_Check_Error_Exit ;yes - signal error ;an000; dms; | ||
| 1540 | |||
| 1541 | ER_Wrap_Check_Good_Exit: | ||
| 1542 | |||
| 1543 | xor ah,ah ;signal no error ;an000; dms; | ||
| 1544 | jmp ER_Wrap_Check_Exit ;exit routine ;an000; dms; | ||
| 1545 | |||
| 1546 | ER_Wrap_Check_Error_Exit: | ||
| 1547 | |||
| 1548 | mov ah,EMS_CodeA2 ;signal error ;an000; dms; | ||
| 1549 | |||
| 1550 | ER_Wrap_Check_Exit: | ||
| 1551 | |||
| 1552 | pop bx ;restore regs ;an000; dms; | ||
| 1553 | pop dx ; ;an000; dms; | ||
| 1554 | |||
| 1555 | ret ;return to caller ;an000; dms; | ||
| 1556 | |||
| 1557 | ER_Wrap_Check endp ;end proc ;an000; dms; | ||
| 1558 | |||
| 1559 | |||
| 1560 | ;========================================================================= | ||
| 1561 | ; ER_Overlap_Check : This routine checks to determine if the conventional | ||
| 1562 | ; memory region and expanded memory region overlap. | ||
| 1563 | ; Specifically, does the conventional memory region | ||
| 1564 | ; overlap the physical page addresses used for | ||
| 1565 | ; expanded memory? | ||
| 1566 | ; | ||
| 1567 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 1568 | ; | ||
| 1569 | ; Outputs : AH - Non-zero on error | ||
| 1570 | ; Possible error codes: 94h | ||
| 1571 | ; | ||
| 1572 | ; Algorithm : | ||
| 1573 | ; | ||
| 1574 | ; If Beg.Src.Add. < Beg.Dst.Add | ||
| 1575 | ; If (End.Src.Add - Beg.Dst.Add) > 0 | ||
| 1576 | ; signal OVERLAP | ||
| 1577 | ; Else | ||
| 1578 | ; signal NO-OVERLAP | ||
| 1579 | ; EndIf | ||
| 1580 | ; Else | ||
| 1581 | ; If (End.Dst.Add - Beg.Src.Add) > 0 | ||
| 1582 | ; signal OVERLAP | ||
| 1583 | ; Else | ||
| 1584 | ; signal NO-OVERLAP | ||
| 1585 | ; EndIf | ||
| 1586 | ; EndIf | ||
| 1587 | ;========================================================================= | ||
| 1588 | |||
| 1589 | ER_Overlap_Check proc ;check for overlap ;an000; dms; | ||
| 1590 | |||
| 1591 | push dx ;save regs ;an000; dms; | ||
| 1592 | call ER_Save_Context ;save context ;an000; dms; | ||
| 1593 | |||
| 1594 | cmp [si].Source_Memory_Type,ER_Conv_Memory ;conventional memory? ;an000; dms; | ||
| 1595 | je ER_Overlap_Check_Source ;yes - check overlap ;an000; dms; | ||
| 1596 | ;no - see if dest is | ||
| 1597 | ; conv. memory | ||
| 1598 | |||
| 1599 | cmp [si].Dest_Memory_Type,ER_Conv_Memory ;conventional memory? ;an000; dms; | ||
| 1600 | jne ER_Overlap_Jump_Good ;no - exit routine ;an000; dms; | ||
| 1601 | |||
| 1602 | ER_Overlap_Check_Dest: | ||
| 1603 | |||
| 1604 | mov di,offset cs:ER_Save_Context_Buffer ;get addressibility to ;an000; dms; | ||
| 1605 | ; the page frame save | ||
| 1606 | ;buffer | ||
| 1607 | add di,bp ;offset BP relative ;an000; dms; | ||
| 1608 | cli ;ints off ;an000; dms; | ||
| 1609 | cmp Map_Count,2 ;>= 2 page frames ;an000; dms; | ||
| 1610 | sti ;ints on ;an000; dms; | ||
| 1611 | jb ER_Overlap_Check_Dest_1_Frame ;no - use 1st. frame ;an000; dms; | ||
| 1612 | add di,Type Mappable_Phys_Page_Struct ;yes - adjust ptr to ;an000; dms; | ||
| 1613 | ; next frame for dest. | ||
| 1614 | ER_Overlap_Check_Dest_1_Frame: | ||
| 1615 | |||
| 1616 | ;**** calc abs address of the bottom of EMS transfer area | ||
| 1617 | |||
| 1618 | mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; | ||
| 1619 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1620 | mov bx,ER_10H ;para size ;an000; dms; | ||
| 1621 | mul bx ;make abs address ;an000; dms; | ||
| 1622 | mov cs:[bp].ER_Src_Abs_Beg_Low,ax ;save abs. address of ;an000; dms; | ||
| 1623 | mov cs:[bp].ER_Src_Abs_Beg_High,dx ; phys page beg. ;an000; dms; | ||
| 1624 | |||
| 1625 | ;**** calc abs address of the top of EMS transfer area | ||
| 1626 | |||
| 1627 | add ax,EMS_Page_Size_In_Bytes ;make abs address ;an000; dms; | ||
| 1628 | adc dx,0 ; ;an000; dms; | ||
| 1629 | mov cs:[bp].ER_Src_Abs_End_Low,ax ;save abs. address ;an000; dms; | ||
| 1630 | mov cs:[bp].ER_Src_Abs_End_High,dx ; of phys page end ;an000; dms; | ||
| 1631 | |||
| 1632 | ;**** calc abs address of the bottom of CONV transfer area | ||
| 1633 | |||
| 1634 | mov ax,[si].Dest_Initial_Seg_Page ;get segment ;an000; dms; | ||
| 1635 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1636 | mov bx,ER_10H ;para size ;an000; dms; | ||
| 1637 | mul bx ;make abs address ;an000; dms; | ||
| 1638 | add ax,[si].Dest_Initial_Offset ;get offset ;an000; dms; | ||
| 1639 | adc dx,0 ;pick up carry ;an000; dms; | ||
| 1640 | mov cs:[bp].ER_Dst_Abs_Beg_Low,ax ;save initial seg start ;an000; dms; | ||
| 1641 | mov cs:[bp].ER_Dst_Abs_Beg_High,dx ;save initial off start ;an000; dms; | ||
| 1642 | |||
| 1643 | ;**** calc abs address of the top of CONV transfer area | ||
| 1644 | |||
| 1645 | add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; | ||
| 1646 | ; trf size | ||
| 1647 | adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; | ||
| 1648 | mov cs:[bp].ER_Dst_Abs_End_Low,ax ;save initial seg start ;an000; dms; | ||
| 1649 | mov cs:[bp].ER_Dst_Abs_End_High,dx ;save initial off start ;an000; dms; | ||
| 1650 | |||
| 1651 | call ER_General_Overlap_Test ;test for overlap ;an000; dms; | ||
| 1652 | |||
| 1653 | jc ER_Overlap_Error_Exit ;exit with error ;an000; dms; | ||
| 1654 | |||
| 1655 | ER_Overlap_Jump_Good: | ||
| 1656 | |||
| 1657 | jmp ER_Overlap_Good_Exit ;exit good ;an000; dms; | ||
| 1658 | |||
| 1659 | ER_Overlap_Check_Source: | ||
| 1660 | |||
| 1661 | mov di,offset cs:ER_Save_Context_Buffer ;get addressibility to ;an000; dms; | ||
| 1662 | ; the page frame save | ||
| 1663 | ;buffer | ||
| 1664 | add di,bp ;offset BP relative ;an000; dms; | ||
| 1665 | |||
| 1666 | ;**** calc abs address of the bottom of EMS transfer area | ||
| 1667 | |||
| 1668 | mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; | ||
| 1669 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1670 | mov bx,ER_10H ;para size ;an000; dms; | ||
| 1671 | mul bx ;make abs address ;an000; dms; | ||
| 1672 | mov cs:[bp].ER_Src_Abs_Beg_Low,ax ;save abs. address of ;an000; dms; | ||
| 1673 | mov cs:[bp].ER_Src_Abs_Beg_High,dx ; phys page beg. ;an000; dms; | ||
| 1674 | |||
| 1675 | ;**** calc abs address of the top of EMS transfer area | ||
| 1676 | |||
| 1677 | mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; | ||
| 1678 | mov dx,EMS_Page_Size_In_Bytes ;get end of phys page ;an000; dms; | ||
| 1679 | mov bx,ER_10H ;para size ;an000; dms; | ||
| 1680 | mul bx ;make abs address ;an000; dms; | ||
| 1681 | mov cs:[bp].ER_Src_Abs_End_Low,ax ;save abs. address ;an000; dms; | ||
| 1682 | mov cs:[bp].ER_Src_Abs_End_High,dx ; of phys page end ;an000; dms; | ||
| 1683 | |||
| 1684 | ;**** calc abs address of the bottom of CONV transfer area | ||
| 1685 | |||
| 1686 | mov ax,[si].Source_Initial_Seg_Page ;get segment ;an000; dms; | ||
| 1687 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1688 | mov bx,ER_10H ;para size ;an000; dms; | ||
| 1689 | mul bx ;make abs address ;an000; dms; | ||
| 1690 | add ax,[si].Source_Initial_Offset ;get offset ;an000; dms; | ||
| 1691 | adc dx,0 ;pick up carry ;an000; dms; | ||
| 1692 | mov cs:[bp].ER_Dst_Abs_Beg_Low,ax ;save initial seg start ;an000; dms; | ||
| 1693 | mov cs:[bp].ER_Dst_Abs_Beg_High,dx ;save initial off start ;an000; dms; | ||
| 1694 | |||
| 1695 | ;**** calc abs address of the top of CONV transfer area | ||
| 1696 | |||
| 1697 | add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; | ||
| 1698 | ; trf size | ||
| 1699 | adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; | ||
| 1700 | mov cs:[bp].ER_Dst_Abs_End_Low,ax ;save initial seg start ;an000; dms; | ||
| 1701 | mov cs:[bp].ER_Dst_Abs_End_High,dx ;save initial off start ;an000; dms; | ||
| 1702 | |||
| 1703 | call ER_General_Overlap_Test ;test for overlap ;an000; dms; | ||
| 1704 | |||
| 1705 | jnc ER_Overlap_Good_Exit ;exit good ;an000; dms; | ||
| 1706 | jmp ER_Overlap_Error_Exit ;exit bad | ||
| 1707 | |||
| 1708 | ER_Overlap_Good_Exit: | ||
| 1709 | |||
| 1710 | xor ah,ah ;signal no error ;an000; dms; | ||
| 1711 | jmp ER_Overlap_Exit ;exit ;an000; dms; | ||
| 1712 | |||
| 1713 | ER_Overlap_Error_Exit: | ||
| 1714 | |||
| 1715 | mov ah,EMS_Code94 ;signal error ;an000; dms; | ||
| 1716 | |||
| 1717 | ER_Overlap_Exit: | ||
| 1718 | |||
| 1719 | call ER_Restore_Context ;restore context ;an000; dms; | ||
| 1720 | |||
| 1721 | pop dx ;restore regs ;an000; dms; | ||
| 1722 | |||
| 1723 | ret ;return to caller ;an000; dms; | ||
| 1724 | |||
| 1725 | ER_Overlap_Check endp ;end proc ;an000; dms; | ||
| 1726 | |||
| 1727 | |||
| 1728 | ;========================================================================= | ||
| 1729 | ; ER_EMS_Overlap_Check : This routine determines if the source and target | ||
| 1730 | ; EMS regions overlap when both the source and target | ||
| 1731 | ; reside in EMS. | ||
| 1732 | ; | ||
| 1733 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 1734 | ; | ||
| 1735 | ; Outputs : AH - Non-zero on error | ||
| 1736 | ; Possible error codes: 92h | ||
| 1737 | ; | ||
| 1738 | ; Algorithm : | ||
| 1739 | ; | ||
| 1740 | ; If Beg.Src.Add. < Beg.Dst.Add | ||
| 1741 | ; If (End.Src.Add - Beg.Dst.Add) > 0 | ||
| 1742 | ; signal OVERLAP | ||
| 1743 | ; Else | ||
| 1744 | ; signal NO-OVERLAP | ||
| 1745 | ; EndIf | ||
| 1746 | ; Else | ||
| 1747 | ; If (End.Dst.Add - Beg.Src.Add) > 0 | ||
| 1748 | ; signal OVERLAP | ||
| 1749 | ; Else | ||
| 1750 | ; signal NO-OVERLAP | ||
| 1751 | ; EndIf | ||
| 1752 | ; EndIf | ||
| 1753 | ;========================================================================= | ||
| 1754 | |||
| 1755 | ER_EMS_Overlap_Check proc ;check for overlap ;an000; dms; | ||
| 1756 | |||
| 1757 | push bx ;save regs ;an000; dms; | ||
| 1758 | push dx ; ;an000; dms; | ||
| 1759 | |||
| 1760 | cmp [si].Source_Memory_Type,ER_EMS_Memory ;Source EMS? ;an000; dms; | ||
| 1761 | jne ER_EMS_Overlap_Exit ;no - exit routine ;an000; dms; | ||
| 1762 | |||
| 1763 | cmp [si].Dest_Memory_Type,ER_EMS_Memory ;Dest. EMS? ;an000; dms; | ||
| 1764 | jne ER_EMS_Overlap_Exit ;no - exit routine ;an000; dms; | ||
| 1765 | |||
| 1766 | mov bx,[si].Source_Handle ;get source handle ;an000; dms; | ||
| 1767 | cmp bx,[si].Dest_Handle ;source = dest? ;an000; dms; | ||
| 1768 | jne ER_EMS_Overlap_Good_Exit ;no - exit routine ;an000; dms; | ||
| 1769 | |||
| 1770 | ER_EMS_Overlap_Calc_N_Ck: | ||
| 1771 | |||
| 1772 | ;**** calc absolute beginning address of source page | ||
| 1773 | |||
| 1774 | mov ax,[si].Source_Initial_Seg_Page ;get start page ;an000; dms; | ||
| 1775 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1776 | mov bx,EMS_Page_Size_In_Bytes ;get page size ;an000; dms; | ||
| 1777 | mul bx ;convert page to abs ;an000; dms; | ||
| 1778 | ; address | ||
| 1779 | add ax,[si].Source_Initial_Offset ;add in offset value ;an000; dms; | ||
| 1780 | adc dx,0 ;pick up carry ;an000; dms; | ||
| 1781 | |||
| 1782 | mov cs:[bp].ER_Src_Abs_Beg_Low,ax ;save low word of add | ||
| 1783 | mov cs:[bp].ER_Src_Abs_Beg_High,dx ;save high word of add ;an000; dms; | ||
| 1784 | |||
| 1785 | ;**** calc absolute ending address of source page | ||
| 1786 | |||
| 1787 | add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; | ||
| 1788 | ; length | ||
| 1789 | adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; | ||
| 1790 | ; length | ||
| 1791 | mov cs:[bp].ER_Src_Abs_End_Low,ax ;save low word of end ;an000; dms; | ||
| 1792 | mov cs:[bp].ER_Src_Abs_End_High,dx ;save high word of end ;an000; dms; | ||
| 1793 | |||
| 1794 | ;**** calc absolute beginning address of dest. page | ||
| 1795 | |||
| 1796 | mov ax,[si].Dest_Initial_Seg_Page ;get start page ;an000; dms; | ||
| 1797 | xor dx,dx ;clear high word ;an000; dms; | ||
| 1798 | mov bx,EMS_Page_Size_In_Bytes ;get page size ;an000; dms; | ||
| 1799 | mul bx ;convert page to abs ;an000; dms; | ||
| 1800 | ; address | ||
| 1801 | add ax,[si].Dest_Initial_Offset ;add in offset value ;an000; dms; | ||
| 1802 | adc dx,0 ;pick up carry ;an000; dms; | ||
| 1803 | |||
| 1804 | mov cs:[bp].ER_Dst_Abs_Beg_Low,ax ;save low word of add | ||
| 1805 | mov cs:[bp].ER_Dst_Abs_Beg_High,dx ;save high word of add ;an000; dms; | ||
| 1806 | |||
| 1807 | ;**** calc absolute ending address of dest. page | ||
| 1808 | |||
| 1809 | add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; | ||
| 1810 | ; length | ||
| 1811 | adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; | ||
| 1812 | ; length | ||
| 1813 | mov cs:[bp].ER_Dst_Abs_End_Low,ax ;save low word of end ;an000; dms; | ||
| 1814 | mov cs:[bp].ER_Dst_Abs_End_High,dx ;save high word of end ;an000; dms; | ||
| 1815 | |||
| 1816 | ;**** Actual test for overlap - corresponds to algorithm above | ||
| 1817 | |||
| 1818 | call ER_General_Overlap_Test ;test for overlap ;an000; dms; | ||
| 1819 | jnc ER_EMS_Overlap_Good_Exit ;no error ;an000; dms; | ||
| 1820 | |||
| 1821 | ER_EMS_Overlap_Error_Exit: | ||
| 1822 | |||
| 1823 | mov ah,EMS_Code92 ;signal error ;an000; dms; | ||
| 1824 | jmp ER_EMS_Overlap_Exit ;exit ;an000; dms; | ||
| 1825 | |||
| 1826 | ER_EMS_Overlap_Good_Exit: | ||
| 1827 | |||
| 1828 | xor ah,ah ;no error ;an000; dms; | ||
| 1829 | |||
| 1830 | ER_EMS_Overlap_Exit: | ||
| 1831 | |||
| 1832 | pop dx ;restore regs ;an000; dms; | ||
| 1833 | pop bx ; ;an000; dms; | ||
| 1834 | |||
| 1835 | ret ;return to caller ;an000; dms; | ||
| 1836 | |||
| 1837 | ER_EMS_Overlap_Check endp ;end proc ;an000; dms; | ||
| 1838 | |||
| 1839 | |||
| 1840 | ;========================================================================= | ||
| 1841 | ; ER_General_Overlap_Test:This routine determines if the source and target | ||
| 1842 | ; EMS regions overlap when both the source and target | ||
| 1843 | ; reside in EMS. | ||
| 1844 | ; | ||
| 1845 | ; Inputs : ER_Src_Abs_Beg_Low - Low word of beginning trf area of source | ||
| 1846 | ; ER_Src_Abs_Beg_High - High word of beginning trf area of source | ||
| 1847 | ; | ||
| 1848 | ; ER_Src_Abs_End_Low - Low word of ending trf area of source | ||
| 1849 | ; ER_Src_Abs_End_High - High word of ending trf area of source | ||
| 1850 | ; | ||
| 1851 | ; : ER_Dst_Abs_Beg_Low - Low word of beginning trf area of dest. | ||
| 1852 | ; ER_Dst_Abs_Beg_High - High word of beginning trf area of dest. | ||
| 1853 | ; | ||
| 1854 | ; ER_Dst_Abs_End_Low - Low word of ending trf area of dest. | ||
| 1855 | ; ER_Dst_Abs_End_High - High word of ending trf area of dest. | ||
| 1856 | ; | ||
| 1857 | ; Outputs : NC - no overlap | ||
| 1858 | ; CY - overlap | ||
| 1859 | ; | ||
| 1860 | ; Algorithm : | ||
| 1861 | ; | ||
| 1862 | ; If Beg.Src.Add. < Beg.Dst.Add | ||
| 1863 | ; If (End.Src.Add - Beg.Dst.Add) > 0 | ||
| 1864 | ; signal OVERLAP | ||
| 1865 | ; Else | ||
| 1866 | ; signal NO-OVERLAP | ||
| 1867 | ; EndIf | ||
| 1868 | ; Else | ||
| 1869 | ; If (End.Dst.Add - Beg.Src.Add) > 0 | ||
| 1870 | ; signal OVERLAP | ||
| 1871 | ; Else | ||
| 1872 | ; signal NO-OVERLAP | ||
| 1873 | ; EndIf | ||
| 1874 | ; EndIf | ||
| 1875 | ;========================================================================= | ||
| 1876 | |||
| 1877 | ER_General_Overlap_Test proc ; ;an000; dms; | ||
| 1878 | |||
| 1879 | push ax ;save regs ;an000; dms; | ||
| 1880 | push bx ; ;an000; dms; | ||
| 1881 | push cx ; ;an000; dms; | ||
| 1882 | push dx ; ;an000; dms; | ||
| 1883 | |||
| 1884 | mov ax,cs:[bp].ER_Src_Abs_Beg_High ;get source beg. add. ;an000; dms; | ||
| 1885 | mov bx,cs:[bp].ER_Src_Abs_Beg_Low ; ;an000; dms; | ||
| 1886 | mov cx,cs:[bp].ER_Dst_Abs_Beg_High ;get dest. beg. add. ;an000; dms; | ||
| 1887 | mov dx,cs:[bp].ER_Dst_Abs_Beg_Low ; ;an000; dms; | ||
| 1888 | call ER_Dword_Compare ; | ||
| 1889 | ; $if c ;< dest. beg. add.? ;an000; dms; | ||
| 1890 | JNC ER_IF1 | ||
| 1891 | mov ax,cs:[bp].ER_Src_Abs_End_Low ;get end address ;an000; dms; | ||
| 1892 | mov dx,cs:[bp].ER_Src_Abs_End_High ; ;an000; dms; | ||
| 1893 | sub ax,cs:[bp].ER_Dst_Abs_Beg_Low ;End.Src.Add-Beg.Dst.Add;an000; dms; | ||
| 1894 | sbb dx,cs:[bp].ER_Dst_Abs_Beg_High ; ;an000; dms; | ||
| 1895 | ; $if ns ;yes - overlap ;an000; dms; | ||
| 1896 | JS ER_IF2 | ||
| 1897 | stc ;signal error ;an000; dms; | ||
| 1898 | mov cs:[bp].ER_Direction_Flag,ER_Down ;signal reverse move ;an000; dms; | ||
| 1899 | ; $else ;no - not sure yet ;an000; dms; | ||
| 1900 | JMP SHORT ER_EN2 | ||
| 1901 | ER_IF2: | ||
| 1902 | clc ;signal no overlap ;an000; dms; | ||
| 1903 | mov cs:[bp].ER_Direction_Flag,ER_Up ;forward move ;an000; dms; | ||
| 1904 | ; $endif ; ;an000; dms; | ||
| 1905 | ER_EN2: | ||
| 1906 | ; $else ;not sure if src < dst ;an000; dms; | ||
| 1907 | JMP SHORT ER_EN1 | ||
| 1908 | ER_IF1: | ||
| 1909 | mov ax,cs:[bp].ER_Dst_Abs_End_Low ;get end address ;an000; dms; | ||
| 1910 | mov dx,cs:[bp].ER_Dst_Abs_End_High ; ;an000; dms; | ||
| 1911 | sub ax,cs:[bp].ER_Src_Abs_Beg_Low ;End.Dst.Add-Beg.Src.Add;an000; dms; | ||
| 1912 | sbb dx,cs:[bp].ER_Src_Abs_Beg_High ; ;an000; dms; | ||
| 1913 | ; $if ns ;yes - overlap ;an000; dms; | ||
| 1914 | JS ER_IF6 | ||
| 1915 | stc ;signal error ;an000; dms; | ||
| 1916 | mov cs:[bp].ER_Direction_Flag,ER_Up ;forward move ;an000; dms; | ||
| 1917 | ; $else ;no - not sure yet ;an000; dms; | ||
| 1918 | JMP SHORT ER_EN6 | ||
| 1919 | ER_IF6: | ||
| 1920 | clc ;signal no overlap ;an000; dms; | ||
| 1921 | mov cs:[bp].ER_Direction_Flag,ER_Up ;forward move ;an000; dms; | ||
| 1922 | ; $endif ; ;an000; dms; | ||
| 1923 | ER_EN6: | ||
| 1924 | ; $endif ; ;an000; dms; | ||
| 1925 | ER_EN1: | ||
| 1926 | |||
| 1927 | pop dx ;restore regs ;an000; dms; | ||
| 1928 | pop cx ; ;an000; dms; | ||
| 1929 | pop bx ; ;an000; dms; | ||
| 1930 | pop ax ; ;an000; dms; | ||
| 1931 | |||
| 1932 | ret ;return to caller ;an000; dms; | ||
| 1933 | |||
| 1934 | ER_General_Overlap_Test endp ;end proc ;an000; dms; | ||
| 1935 | |||
| 1936 | |||
| 1937 | ;========================================================================= | ||
| 1938 | ; ER_Dword_Compare : This routine determines whether or not a dword | ||
| 1939 | ; value is greater than another dword value. | ||
| 1940 | ; | ||
| 1941 | ; Inputs : AX - Source high word | ||
| 1942 | ; BX - Source low word | ||
| 1943 | ; CX - Destination high word | ||
| 1944 | ; DX - Destination low word | ||
| 1945 | ; | ||
| 1946 | ; Outputs : NC - source >= destination | ||
| 1947 | ; CY - source < destination | ||
| 1948 | ;========================================================================= | ||
| 1949 | |||
| 1950 | ER_Dword_Compare proc ; ;an000; dms; | ||
| 1951 | |||
| 1952 | cmp ax,cx ;src high < dest high? ;an000; dms; | ||
| 1953 | ; $if b ;yes ;an000; dms; | ||
| 1954 | JNB ER_IF10 | ||
| 1955 | stc ;signal less than ;an000; dms; | ||
| 1956 | ; $else ;no ;an000; dms; | ||
| 1957 | JMP SHORT ER_EN10 | ||
| 1958 | ER_IF10: | ||
| 1959 | cmp ax,cx ;src high > dest high? ;an000; dms; | ||
| 1960 | ; $if a ;yes ;an000; dms; | ||
| 1961 | JNA ER_IF12 | ||
| 1962 | clc ;signal greater than ;an000; dms; | ||
| 1963 | ; $else ;no ;an000; dms; | ||
| 1964 | JMP SHORT ER_EN12 | ||
| 1965 | ER_IF12: | ||
| 1966 | cmp bx,dx ;src low < dest low? ;an000; dms; | ||
| 1967 | ; $if b ;yes ;an000; dms; | ||
| 1968 | JNB ER_IF14 | ||
| 1969 | stc ;signal less than ;an000; dms; | ||
| 1970 | ; $else ;no ;an000; dms; | ||
| 1971 | JMP SHORT ER_EN14 | ||
| 1972 | ER_IF14: | ||
| 1973 | cmp bx,dx ;src low > dest low? ;an000; dms; | ||
| 1974 | ; $if a ;yes ;an000; dms; | ||
| 1975 | JNA ER_IF16 | ||
| 1976 | clc ;signal greater than ;an000; dms; | ||
| 1977 | ; $else ;no ;an000; dms; | ||
| 1978 | JMP SHORT ER_EN16 | ||
| 1979 | ER_IF16: | ||
| 1980 | clc ; ;an000; dms; | ||
| 1981 | ; $endif ; ;an000; dms; | ||
| 1982 | ER_EN16: | ||
| 1983 | ; $endif ; ;an000; dms; | ||
| 1984 | ER_EN14: | ||
| 1985 | ; $endif ; ;an000; dms; | ||
| 1986 | ER_EN12: | ||
| 1987 | ; $endif ; ;an000; dms; | ||
| 1988 | ER_EN10: | ||
| 1989 | |||
| 1990 | ret ; ;an000; dms; | ||
| 1991 | |||
| 1992 | ER_Dword_Compare endp ; ;an000; dms; | ||
| 1993 | |||
| 1994 | |||
| 1995 | |||
| 1996 | ;========================================================================= | ||
| 1997 | ; ER_Segment_Adjust : This routine adjusts the segment:offset to a value | ||
| 1998 | ; with an offset less than 16. | ||
| 1999 | ; | ||
| 2000 | ; Inputs : AX:DX - Segment:Offset to be adjusted | ||
| 2001 | ; | ||
| 2002 | ; Outputs : AX:DX - New Segment:Offset value | ||
| 2003 | ;========================================================================= | ||
| 2004 | |||
| 2005 | ER_Segment_Adjust proc ;adjust segment value ;an000; dms; | ||
| 2006 | |||
| 2007 | push bx ;save bx ;an000; dms; | ||
| 2008 | push cx ; ;an000; dms; | ||
| 2009 | |||
| 2010 | mov bx,ax ;save segment value ;an000; dms; | ||
| 2011 | mov ax,dx ;get offset ;an000; dms; | ||
| 2012 | xor dx,dx ;clear high word ;an000; dms; | ||
| 2013 | mov cx,ER_10h ;divide by 10h ;an000; dms; | ||
| 2014 | div cx ;get seg adjustment ;an000; dms; | ||
| 2015 | ; factor | ||
| 2016 | add ax,bx ;adjust segment up ;an000; dms; | ||
| 2017 | ; dx contains new off. ;an000; dms; | ||
| 2018 | pop cx ;restore regs ;an000; dms; | ||
| 2019 | pop bx ;restore bx ;an000; dms; | ||
| 2020 | |||
| 2021 | ret ;return to caller ;an000; dms; | ||
| 2022 | |||
| 2023 | ER_Segment_Adjust endp ;end proc ;an000; dms; | ||
| 2024 | |||
| 2025 | |||
| 2026 | ;========================================================================= | ||
| 2027 | ; ER_Log_Page_Test : This routine checks the offset specified for | ||
| 2028 | ; the logical page to determine if the offset is | ||
| 2029 | ; within the valid ranges for the page size. | ||
| 2030 | ; | ||
| 2031 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 2032 | ; | ||
| 2033 | ; Outputs : AH - Non-zero on error | ||
| 2034 | ; Possible error codes: 95h | ||
| 2035 | ;========================================================================= | ||
| 2036 | |||
| 2037 | ER_Log_Page_Test proc ; ;an000; dms; | ||
| 2038 | |||
| 2039 | mov ax,EMS_Page_Size_In_Bytes ;get page size ;an000; dms; | ||
| 2040 | |||
| 2041 | cmp [si].Source_Memory_Type,ER_EMS_Memory ;EMS memory specified? ;an000; dms; | ||
| 2042 | jne ER_Log_Dest_Test ;no - check dest. ;an000; dms; | ||
| 2043 | |||
| 2044 | cmp ax,[si].Source_Initial_Offset ;> EMS page size ;an000; dms; | ||
| 2045 | jae ER_Log_Good_Exit ;good exit ;an000; dms; | ||
| 2046 | jmp ER_Log_Error_Exit ;error - bad exit ;an000; dms; | ||
| 2047 | |||
| 2048 | ER_Log_Dest_Test: | ||
| 2049 | |||
| 2050 | cmp [si].Dest_Memory_Type,ER_EMS_Memory ;EMS memory specified? ;an000; dms; | ||
| 2051 | jne ER_Log_Good_Exit ;good exit ;an000; dms; | ||
| 2052 | |||
| 2053 | cmp ax,[si].Dest_Initial_Offset ;> EMS page size ;an000; dms; | ||
| 2054 | jae ER_Log_Good_Exit ;good exit ;an000; dms; | ||
| 2055 | |||
| 2056 | ER_Log_Error_Exit: | ||
| 2057 | |||
| 2058 | mov ah,EMS_Code95 ;signal error ;an000; dms; | ||
| 2059 | jmp ER_Log_Exit ;exit routine ;an000; dms; | ||
| 2060 | |||
| 2061 | ER_Log_Good_Exit: | ||
| 2062 | |||
| 2063 | xor ah,ah ;signal no error ;an000; dms; | ||
| 2064 | |||
| 2065 | ER_Log_Exit: | ||
| 2066 | |||
| 2067 | ret ;return to caller ;an000; dms; | ||
| 2068 | |||
| 2069 | ER_Log_Page_Test endp ;end proc ;an000; dms; | ||
| 2070 | |||
| 2071 | ;========================================================================= | ||
| 2072 | ; ER_Save_Context : This routine saves the context for page frames | ||
| 2073 | ; needed for the move/exchange. | ||
| 2074 | ; | ||
| 2075 | ; Inputs : none | ||
| 2076 | ; | ||
| 2077 | ; Outputs : ER_Save_Context_Buffer - save context for the needed page frames | ||
| 2078 | ;========================================================================= | ||
| 2079 | |||
| 2080 | ER_Save_Context proc ;save contexts ;an000; dms; | ||
| 2081 | |||
| 2082 | push ax ;save regs ;an000; dms; | ||
| 2083 | push cx ; ;an000; dms; | ||
| 2084 | push di ; ;an000; dms; | ||
| 2085 | push si ; ;an000; dms; | ||
| 2086 | push ds ; ;an000; dms; | ||
| 2087 | push es ; ;an000; dms; | ||
| 2088 | |||
| 2089 | mov ax,cs ;make ds/es = cs ;an000; dms; | ||
| 2090 | mov ds,ax ; ;an000; dms; | ||
| 2091 | mov es,ax ; ;an000; dms; | ||
| 2092 | |||
| 2093 | mov si,offset cs:Map_Table ;ptr to page frame table;an000; dms; | ||
| 2094 | mov di,offset cs:ER_Save_Context_Buffer ;get dest. offset | ||
| 2095 | add di,bp ;offset BP relative ;an000; dms; | ||
| 2096 | |||
| 2097 | mov cx,2 ;default frame save ;an000; dms; | ||
| 2098 | cli ;ints off ;an000; dms; | ||
| 2099 | cmp Map_Count,2 ;2 page frames? ;an000; dms; | ||
| 2100 | jae ER_Save_Context_Loop ;< = 2 - continue ;an000; dms; | ||
| 2101 | mov cx,Map_Count ;max frame count to save;an000; dms; | ||
| 2102 | |||
| 2103 | ER_Save_Context_Loop: | ||
| 2104 | |||
| 2105 | sti ;ints on ;an000; dms; | ||
| 2106 | push cx ;save cx ;an000; dms; | ||
| 2107 | mov cx,Type Mappable_Phys_Page_Struct ;get byte count to trf ;an000; dms; | ||
| 2108 | cli ;ints off ;an000; dms; | ||
| 2109 | rep movsb ;perform save ;an000; dms; | ||
| 2110 | sti ;ints on ;an000; dms; | ||
| 2111 | pop cx ;restore cx ;an000; dms; | ||
| 2112 | loop ER_Save_Context_Loop ;continue ;an000; dms; | ||
| 2113 | |||
| 2114 | ER_Save_Exit: | ||
| 2115 | |||
| 2116 | pop es ;restore regs ;an000; dms; | ||
| 2117 | pop ds ; ;an000; dms; | ||
| 2118 | pop si ; ;an000; dms; | ||
| 2119 | pop di ; ;an000; dms; | ||
| 2120 | pop cx ; ;an000; dms; | ||
| 2121 | pop ax ; ;an000; dms; | ||
| 2122 | |||
| 2123 | ret ;return to caller ;an000; dms; | ||
| 2124 | |||
| 2125 | ER_Save_Context endp ;end proc ;an000; dms; | ||
| 2126 | |||
| 2127 | |||
| 2128 | ;========================================================================= | ||
| 2129 | ; ER_Restore_Context : This routine restores the context for page frames | ||
| 2130 | ; saved. These pages were used for the | ||
| 2131 | ; move/exchange requested. | ||
| 2132 | ; | ||
| 2133 | ; Inputs : ER_Save_Context_Buffer - contains saved context | ||
| 2134 | ; | ||
| 2135 | ; Outputs : restored context for the saved page frames | ||
| 2136 | ;========================================================================= | ||
| 2137 | |||
| 2138 | ER_Restore_Context proc ;restore contexts ;an000; dms; | ||
| 2139 | |||
| 2140 | push ax ;save regs ;an000; dms; | ||
| 2141 | push cx ; ;an000; dms; | ||
| 2142 | push di ; ;an000; dms; | ||
| 2143 | push si ; ;an000; dms; | ||
| 2144 | push ds ; ;an000; dms; | ||
| 2145 | push es ; ;an000; dms; | ||
| 2146 | |||
| 2147 | mov ax,cs ;make ds/es = cs ;an000; dms; | ||
| 2148 | mov ds,ax ; ;an000; dms; | ||
| 2149 | mov es,ax ; ;an000; dms; | ||
| 2150 | |||
| 2151 | mov di,offset cs:Map_Table ;ptr to page frame table;an000; dms; | ||
| 2152 | mov si,offset cs:ER_Save_Context_Buffer ;get dest. offset | ||
| 2153 | add si,bp ;offset BP relative ;an000; dms; | ||
| 2154 | |||
| 2155 | mov cx,2 ;default frame restore ;an000; dms; | ||
| 2156 | cli ;ints off ;an000; dms; | ||
| 2157 | cmp Map_Count,2 ;2 page frames? ;an000; dms; | ||
| 2158 | jae ER_Restore_Context_Loop ;< = 2 - continue ;an000; dms; | ||
| 2159 | mov cx,Map_Count ;max frame count to rest;an000; dms; | ||
| 2160 | |||
| 2161 | ER_Restore_Context_Loop: | ||
| 2162 | |||
| 2163 | sti ;ints on ;an000; dms; | ||
| 2164 | mov al,byte ptr ds:[si].Phys_Page_Number ;get physical page num. ;an000; dms; | ||
| 2165 | mov bx,word ptr ds:[si].PPM_Log_Page ;get logical page num. ;an000; dms; | ||
| 2166 | mov dx,word ptr ds:[si].PPM_Handle ;get handle number ;an000; dms; | ||
| 2167 | call Map_L_To_P ;map in orig. page ;an000; dms; | ||
| 2168 | |||
| 2169 | push cx ;save cx ;an000; dms; | ||
| 2170 | mov cx,Type Mappable_Phys_Page_Struct ;get byte count to trf ;an000; dms; | ||
| 2171 | cli ;ints off ;an000; dms; | ||
| 2172 | rep movsb ;perform save ;an000; dms; | ||
| 2173 | sti ;ints on ;an000; dms; | ||
| 2174 | pop cx ;restore cx ;an000; dms; | ||
| 2175 | loop ER_Restore_Context_Loop ;continue ;an000; dms; | ||
| 2176 | |||
| 2177 | ER_Restore_Exit: | ||
| 2178 | |||
| 2179 | pop es ;restore regs ;an000; dms; | ||
| 2180 | pop ds ; ;an000; dms; | ||
| 2181 | pop si ; ;an000; dms; | ||
| 2182 | pop di ; ;an000; dms; | ||
| 2183 | pop cx ; ;an000; dms; | ||
| 2184 | pop ax ; ;an000; dms; | ||
| 2185 | |||
| 2186 | ret ;return to caller ;an000; dms; | ||
| 2187 | |||
| 2188 | ER_Restore_Context endp ;end proc ;an000; dms; | ||
| 2189 | |||
| 2190 | |||
| 2191 | |||
| 2192 | ;========================================================================= | ||
| 2193 | ; ER_Det_Src_Dest_Seg : This routine determines the applicable segment, | ||
| 2194 | ; offset, and page to be used for the move/exchange. | ||
| 2195 | ; This routine sets the pages/addresses to the end | ||
| 2196 | ; of the area to be moved/exchanged, if the move | ||
| 2197 | ; is to be a reverse move. If the move is to be | ||
| 2198 | ; a forward move, the pages/addresses are set to | ||
| 2199 | ; the beginning of the area to be moved/exchanged. | ||
| 2200 | ; In this way an overlapping move can be | ||
| 2201 | ; performed without overlaying data it is to move. | ||
| 2202 | ; | ||
| 2203 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 2204 | ; | ||
| 2205 | ; Outputs : ER_Source_Seg - Segment value of source | ||
| 2206 | ; ER_Dest_Seg - Segment value of destination | ||
| 2207 | ; | ||
| 2208 | ; ER_Source_Off - Offset value of source | ||
| 2209 | ; ER_Dest_Off - Offset value of destination | ||
| 2210 | ; | ||
| 2211 | ; ER_Source_Page - Source EMS page | ||
| 2212 | ; ER_Dest_Page - Destination EMS page | ||
| 2213 | ; | ||
| 2214 | ; ER_Source_Handle - Source handle | ||
| 2215 | ; ER_Dest_Handle - Destination handle | ||
| 2216 | ; | ||
| 2217 | ; ER_Source_Phys_Page - Physical page number | ||
| 2218 | ; ER_Dest_Phys_Page - Physical page number | ||
| 2219 | ;========================================================================= | ||
| 2220 | |||
| 2221 | ER_Det_Src_Dest_Seg proc ; ;an000; dms; | ||
| 2222 | |||
| 2223 | push ax ;save regs ;an000; dms; | ||
| 2224 | push bx ; ;an000; dms; | ||
| 2225 | push cx ; ;an000; dms; | ||
| 2226 | push dx ; ;an000; dms; | ||
| 2227 | push di ; ;an000; dms; | ||
| 2228 | push ds ; ;an000; dms; | ||
| 2229 | push es ; ;an000; dms; | ||
| 2230 | |||
| 2231 | |||
| 2232 | cmp [si].Source_Memory_Type,ER_EMS_Memory ;EMS? ;an000; dms; | ||
| 2233 | jne ER_Det_Source_Conv ;no - conventional mem. ;an000; dms; | ||
| 2234 | |||
| 2235 | mov di,offset cs:ER_Save_Context_Buffer ;get addressibility to ;an000; dms; | ||
| 2236 | ; the page frame save | ||
| 2237 | ;buffer | ||
| 2238 | add di,bp ;offset BP relative | ||
| 2239 | mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; | ||
| 2240 | mov cs:[bp].ER_Source_Seg,ax ;save it in variable ;an000; dms; | ||
| 2241 | |||
| 2242 | mov ax,[si].Source_Handle ;get source handle ;an000; dms; | ||
| 2243 | mov cs:[bp].ER_Source_Handle,ax ;save handle ;an000; dms; | ||
| 2244 | |||
| 2245 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2246 | ; $if e ;yes ;an000; dms; | ||
| 2247 | JNE ER_IF22 | ||
| 2248 | mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms; | ||
| 2249 | mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms; | ||
| 2250 | add ax,[si].Source_Initial_Offset ;pick up offset value ;an000; dms; | ||
| 2251 | adc dx,0 ;pick up carry ;an000; dms; | ||
| 2252 | mov bx,4000h ;get page size ;an000; dms; | ||
| 2253 | div bx ;get end logical page ;an000; dms; | ||
| 2254 | add ax,[si].Source_Initial_Seg_Page ;adjust it for 1st. ;an000; dms; | ||
| 2255 | mov cs:[bp].ER_Source_Page,ax ;save log. page ;an000; dms; | ||
| 2256 | dec dx ;adjust to end point ;an000; dms; | ||
| 2257 | mov cs:[bp].ER_Source_Off,dx ;save offset in last pg ;an000; dms; | ||
| 2258 | |||
| 2259 | ; $else ;forward move ;an000; dms; | ||
| 2260 | JMP SHORT ER_EN22 | ||
| 2261 | ER_IF22: | ||
| 2262 | mov ax,[si].Source_Initial_Seg_Page ;get page ;an000; dms; | ||
| 2263 | mov dx,[si].Source_Initial_Offset ;get offset ;an000; dms; | ||
| 2264 | mov cs:[bp].ER_Source_Page,ax ;save page ;an000; dms; | ||
| 2265 | mov cs:[bp].ER_Source_Off,dx ;save offset ;an000; dms; | ||
| 2266 | ; $endif ; ;an000; dms; | ||
| 2267 | ER_EN22: | ||
| 2268 | mov ax,cs:[di].Phys_Page_Number ;get phys. page ;an000; dms; | ||
| 2269 | mov cs:[bp].ER_Source_Phys_Page,ax ;save it ;an000; dms; | ||
| 2270 | jmp ER_Det_Dest_Check ;jump to dest check ;an000; dms; | ||
| 2271 | |||
| 2272 | ER_Det_Source_Conv: | ||
| 2273 | |||
| 2274 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2275 | ; $if e ;yes ;an000; dms; | ||
| 2276 | JNE ER_IF25 | ||
| 2277 | mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms; | ||
| 2278 | mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms; | ||
| 2279 | mov bx,ER_10h ;get bytes/para ;an000; dms; | ||
| 2280 | div bx ;get para count ;an000; dms; | ||
| 2281 | ; AX = para's | ||
| 2282 | ; DX = offset | ||
| 2283 | mov bx,ax ;save across adjust call;an000; dms; | ||
| 2284 | mov cx,dx ; ;an000; dms; | ||
| 2285 | mov ax,[si].Source_Initial_Seg_Page ;get seg value ;an000; dms; | ||
| 2286 | mov dx,[si].Source_Initial_Offset ;get off value ;an000; dms; | ||
| 2287 | dec dx ;adjust to end byte | ||
| 2288 | call ER_Segment_Adjust ;adjust it downward ;an000; dms; | ||
| 2289 | add ax,bx ;new segment value ;an000; dms; | ||
| 2290 | add dx,cx ;new offset value ;an000; dms; | ||
| 2291 | |||
| 2292 | mov cs:[bp].ER_Source_Seg,ax ;save it in variable ;an000; dms; | ||
| 2293 | mov cs:[bp].ER_Source_Off,dx ;save offset in var ;an000; dms; | ||
| 2294 | ; $else ;forward move ;an000; dms; | ||
| 2295 | JMP SHORT ER_EN25 | ||
| 2296 | ER_IF25: | ||
| 2297 | mov ax,[si].Source_Initial_Seg_Page ;get seg value ;an000; dms; | ||
| 2298 | mov dx,[si].Source_Initial_Offset ;get off value ;an000; dms; | ||
| 2299 | mov cs:[bp].ER_Source_Seg,ax ;save it in variable ;an000; dms; | ||
| 2300 | mov cs:[bp].ER_Source_Off,dx ;save offset in var ;an000; dms; | ||
| 2301 | ; $endif ; ;an000; dms; | ||
| 2302 | ER_EN25: | ||
| 2303 | |||
| 2304 | |||
| 2305 | ER_Det_Dest_Check: | ||
| 2306 | |||
| 2307 | cmp [si].Dest_Memory_Type,ER_EMS_Memory ;Dest. EMS? ;an000; dms; | ||
| 2308 | jne ER_Det_Dest_Conv ;no - conventional mem. ;an000; dms; | ||
| 2309 | |||
| 2310 | mov di,offset cs:ER_Save_Context_Buffer ;save frame buffer ;an000; dms; | ||
| 2311 | add di,bp ;offset BP relative ;an000; dms; | ||
| 2312 | cli ;ints off ;an000; dms; | ||
| 2313 | cmp Map_Count,1 ;> 1 page frame? ;an000; dms; | ||
| 2314 | sti ;ints on ;an000; dms; | ||
| 2315 | jb ER_Det_Dest_Check1 ;don't adjust pointer ;an000; dms; | ||
| 2316 | add di,Type Mappable_Phys_Page_Struct ;next entry in save buf ;an000; dms; | ||
| 2317 | |||
| 2318 | ER_Det_Dest_Check1: | ||
| 2319 | |||
| 2320 | mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; | ||
| 2321 | mov cs:[bp].ER_Dest_Seg,ax ;save it in variable ;an000; dms; | ||
| 2322 | |||
| 2323 | mov ax,[si].Dest_Handle ;get dest. handle ;an000; dms; | ||
| 2324 | mov cs:[bp].ER_Dest_Handle,ax ;save handle ;an000; dms; | ||
| 2325 | |||
| 2326 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2327 | ; $if e ;yes ;an000; dms; | ||
| 2328 | JNE ER_IF28 | ||
| 2329 | mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms; | ||
| 2330 | mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms; | ||
| 2331 | add ax,[si].Dest_Initial_Offset ;pick up offset value ;an000; dms; | ||
| 2332 | adc dx,0 ;pick up carry ;an000; dms; | ||
| 2333 | |||
| 2334 | mov bx,4000h ;get page size ;an000; dms; | ||
| 2335 | div bx ;get end logical page ;an000; dms; | ||
| 2336 | add ax,[si].Dest_Initial_Seg_Page ;adjust it for 1st. ;an000; dms; | ||
| 2337 | mov cs:[bp].ER_Dest_Page,ax ;save log. page ;an000; dms; | ||
| 2338 | dec dx ;adjust to end point ;an000; dms; | ||
| 2339 | mov cs:[bp].ER_Dest_Off,dx ;save off. in last page ;an000; dms; | ||
| 2340 | |||
| 2341 | ; $else ;forward move ;an000; dms; | ||
| 2342 | JMP SHORT ER_EN28 | ||
| 2343 | ER_IF28: | ||
| 2344 | mov ax,[si].Dest_Initial_Seg_Page ;get page ;an000; dms; | ||
| 2345 | mov dx,[si].Dest_Initial_Offset ;get offset ;an000; dms; | ||
| 2346 | mov cs:[bp].ER_Dest_Page,ax ;save log. page ;an000; dms; | ||
| 2347 | mov cs:[bp].ER_Dest_Off,dx ;save off. in last page ;an000; dms; | ||
| 2348 | ; $endif ; ;an000; dms; | ||
| 2349 | ER_EN28: | ||
| 2350 | mov ax,cs:[di].Phys_Page_Number ;get phys page number ;an000; dms; | ||
| 2351 | mov cs:[bp].ER_Dest_Phys_Page,ax ;save it ;an000; dms; | ||
| 2352 | jmp ER_Det_Exit ;exit routine ;an000; dms; | ||
| 2353 | |||
| 2354 | ER_Det_Dest_Conv: | ||
| 2355 | |||
| 2356 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2357 | ; $if e ;yes ;an000; dms; | ||
| 2358 | JNE ER_IF31 | ||
| 2359 | mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms; | ||
| 2360 | mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms; | ||
| 2361 | mov bx,ER_10H ;get bytes/para ;an000; dms; | ||
| 2362 | div bx ;get para count ;an000; dms; | ||
| 2363 | ; AX = para's | ||
| 2364 | ; DX = offset | ||
| 2365 | mov bx,ax ;save across adjust call;an000; dms; | ||
| 2366 | mov cx,dx ; ;an000; dms; | ||
| 2367 | mov ax,[si].Dest_Initial_Seg_Page ;get seg value ;an000; dms; | ||
| 2368 | mov dx,[si].Dest_Initial_Offset ;get off value ;an000; dms; | ||
| 2369 | dec dx ;adjust to end byte ;an000; dms; | ||
| 2370 | call ER_Segment_Adjust ;adjust it downward ;an000; dms; | ||
| 2371 | add ax,bx ;new segment value ;an000; dms; | ||
| 2372 | add dx,cx ;new offset value ;an000; dms; | ||
| 2373 | |||
| 2374 | mov cs:[bp].ER_Dest_Seg,ax ;save it in variable ;an000; dms; | ||
| 2375 | mov cs:[bp].ER_Dest_Off,dx ;save offset in var ;an000; dms; | ||
| 2376 | ; $else ;forward move ;an000; dms; | ||
| 2377 | JMP SHORT ER_EN31 | ||
| 2378 | ER_IF31: | ||
| 2379 | mov ax,[si].Dest_Initial_Seg_Page ;get seg value ;an000; dms; | ||
| 2380 | mov dx,[si].Dest_Initial_Offset ;get off value ;an000; dms; | ||
| 2381 | mov cs:[bp].ER_Dest_Seg,ax ;save it in variable ;an000; dms; | ||
| 2382 | mov cs:[bp].ER_Dest_Off,dx ;save offset in var ;an000; dms; | ||
| 2383 | ; $endif ; ;an000; dms; | ||
| 2384 | ER_EN31: | ||
| 2385 | |||
| 2386 | |||
| 2387 | ER_Det_Exit: | ||
| 2388 | |||
| 2389 | pop es ;restore regs ;an000; dms; | ||
| 2390 | pop ds ; ;an000; dms; | ||
| 2391 | pop di ; ;an000; dms; | ||
| 2392 | pop dx ; ;an000; dms; | ||
| 2393 | pop cx ; ;an000; dms; | ||
| 2394 | pop bx ; ;an000; dms; | ||
| 2395 | pop ax ; ;an000; dms; | ||
| 2396 | |||
| 2397 | ret ;return to caller ;an000; dms; | ||
| 2398 | |||
| 2399 | ER_Det_Src_Dest_Seg endp ;end proc ;an000; dms; | ||
| 2400 | |||
| 2401 | |||
| 2402 | ;========================================================================= | ||
| 2403 | ; ER_Det_Move_Count : This initializes the count variables for the | ||
| 2404 | ; loop iteration counter of the move/exchange. | ||
| 2405 | ; | ||
| 2406 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 2407 | ; | ||
| 2408 | ; Outputs : ER_Move_Count_Low - low word value of move count | ||
| 2409 | ; ER_Move_Count_High - high word value of move count | ||
| 2410 | ;========================================================================= | ||
| 2411 | |||
| 2412 | |||
| 2413 | ER_Det_Move_Count proc ; ;an000; dms; | ||
| 2414 | |||
| 2415 | push ax ;save regs ;an000; dms; | ||
| 2416 | push dx ; ;an000; dms; | ||
| 2417 | |||
| 2418 | mov ax,[si].Region_Length_Low_Word ;get low word count ;an000; dms; | ||
| 2419 | mov dx,[si].Region_Length_High_Word ;get high word count ;an000; dms; | ||
| 2420 | mov cs:[bp].ER_Move_Count_Low,ax ;save low word ;an000; dms; | ||
| 2421 | mov cs:[bp].ER_Move_Count_High,dx ;save high word ;an000; dms; | ||
| 2422 | |||
| 2423 | pop dx ;restore regs ;an000; dms; | ||
| 2424 | pop ax ; ;an000; dms; | ||
| 2425 | |||
| 2426 | ret ;return to caller ;an000; dms; | ||
| 2427 | |||
| 2428 | ER_Det_Move_Count endp ;end proc ;an000; dms; | ||
| 2429 | |||
| 2430 | ;========================================================================= | ||
| 2431 | ; ER_Move_Source_To_Buffer : This routine moves the source data to | ||
| 2432 | ; the buffer before it is transferred to | ||
| 2433 | ; its final destination. | ||
| 2434 | ; | ||
| 2435 | ; Inputs : BP - carries type of memory for source/dest | ||
| 2436 | ; Bit 0 - Destination (EMS if set) | ||
| 2437 | ; Bit 1 - Source (EMS if set) | ||
| 2438 | ; | ||
| 2439 | ; Outputs : ER_Move_Xchg_Buffer1 - Source data | ||
| 2440 | ;========================================================================= | ||
| 2441 | |||
| 2442 | ER_Move_Source_To_Buffer proc ; ;an000; dms; | ||
| 2443 | |||
| 2444 | push ax ;save regs ;an000; dms; | ||
| 2445 | push bx ; ;an000; dms; | ||
| 2446 | push dx ; ;an000; dms; | ||
| 2447 | push di ; ;an000; dms; | ||
| 2448 | push es ; ;an000; dms; | ||
| 2449 | |||
| 2450 | test cs:[bp].ER_Mem_Type,ER_Source_EMS_Memory;Source EMS? ;an000; dms; | ||
| 2451 | jz ER_Move_Source_Conv_Mem ;no - adjust seg:off ;an000; dms; | ||
| 2452 | jmp ER_Move_Source_EMS_Mem ;yes- continue move ;an000; dms; | ||
| 2453 | |||
| 2454 | ER_Move_Source_Conv_Mem: | ||
| 2455 | |||
| 2456 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2457 | ; $if e ;yes ;an000; dms; | ||
| 2458 | JNE ER_IF34 | ||
| 2459 | mov ax,ds ;adjust segment:off ;an000; dms; | ||
| 2460 | dec ax ;segment - 1 para ;an000; dms; | ||
| 2461 | mov ds,ax ; ;an000; dms; | ||
| 2462 | add si,ER_10H ;adjust offset for 1 ;an000; dms; | ||
| 2463 | ; $else ;forward move ;an000; dms; | ||
| 2464 | JMP SHORT ER_EN34 | ||
| 2465 | ER_IF34: | ||
| 2466 | mov ax,ds ;get segment value ;an000; dms; | ||
| 2467 | mov dx,si ;get offset value ;an000; dms; | ||
| 2468 | call ER_Segment_Adjust ;adjust the seg:off ;an000; dms; | ||
| 2469 | mov ds,ax ;restore ds ;an000; dms; | ||
| 2470 | mov si,dx ;restore offset ;an000; dms; | ||
| 2471 | ; $endif ; ;an000; dms; | ||
| 2472 | ER_EN34: | ||
| 2473 | jmp ER_Move_Source_Count ;determine count ;an000; dms; | ||
| 2474 | |||
| 2475 | ER_Move_Source_EMS_Mem: | ||
| 2476 | |||
| 2477 | |||
| 2478 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2479 | ; $if e ;yes ;an000; dms; | ||
| 2480 | JNE ER_IF37 | ||
| 2481 | cmp si,0ffffh ;beginning of log page ;an000; dms; | ||
| 2482 | ; $if e ;yes ;an000; dms; | ||
| 2483 | JNE ER_IF38 | ||
| 2484 | dec cs:[bp].ER_Source_Page ;adjust page ptr ;an000; dms; | ||
| 2485 | mov si,EMS_Page_Size_In_Bytes;get page size ;an000; dms; | ||
| 2486 | ; $endif ; ;an000; dms; | ||
| 2487 | ER_IF38: | ||
| 2488 | ; $else ;forward move ;an000; dms; | ||
| 2489 | JMP SHORT ER_EN37 | ||
| 2490 | ER_IF37: | ||
| 2491 | cmp si,4000h ;wrap beyond page ;an000; dms; | ||
| 2492 | ; $if e ;yes ;an000; dms; | ||
| 2493 | JNE ER_IF41 | ||
| 2494 | inc cs:[bp].ER_Source_Page ;adjust page ptr ;an000; dms; | ||
| 2495 | xor si,si ;clear si ;an000; dms; | ||
| 2496 | ; $endif ; ;an000; dms; | ||
| 2497 | ER_IF41: | ||
| 2498 | ; $endif ; ;an000; dms; | ||
| 2499 | ER_EN37: | ||
| 2500 | mov bx,cs:[bp].ER_Source_Page ;pass page to map ;an000; dms; | ||
| 2501 | call ER_Map_Next_Src_Page ;no - map in current pg;an000; dms; | ||
| 2502 | |||
| 2503 | ER_Move_Source_Count: | ||
| 2504 | |||
| 2505 | mov cx,ER_10H ;default count ;an000; dms; | ||
| 2506 | cmp cs:[bp].ER_Move_Count_High,0 ;high word set ;an000; dms; | ||
| 2507 | jne ER_Move_Source_High_Set ;yes - use default ;an000; dms; | ||
| 2508 | cmp cs:[bp].ER_Move_Count_Low,cx ;>= 10h bytes ;an000; dms; | ||
| 2509 | jae ER_Move_Source_High_Set ;yes - use default ;an000; dms; | ||
| 2510 | mov cx,cs:[bp].ER_Move_Count_Low ;no - use last few bytes;an000; dms; | ||
| 2511 | |||
| 2512 | ER_Move_Source_High_Set: | ||
| 2513 | |||
| 2514 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2515 | ; $if e ;yes ;an000; dms; | ||
| 2516 | JNE ER_IF44 | ||
| 2517 | cmp si,di ;source >= dest? ;an000; dms; | ||
| 2518 | ; $if b ;no ;an000; dms; | ||
| 2519 | JNB ER_IF45 | ||
| 2520 | cmp si,ER_10H ;source >= 10h? ;an000; dms; | ||
| 2521 | ; $if b ;no ;an000; dms; | ||
| 2522 | JNB ER_IF46 | ||
| 2523 | mov cx,si ;get move count ;an000; dms; | ||
| 2524 | inc cx ;always 1 byte off ;an000; dms; | ||
| 2525 | ; $endif ; ;an000; dms; | ||
| 2526 | ER_IF46: | ||
| 2527 | ; $else ;source >= dest ;an000; dms; | ||
| 2528 | JMP SHORT ER_EN45 | ||
| 2529 | ER_IF45: | ||
| 2530 | cmp di,ER_10H ;dest >= 10h? ;an000; dms; | ||
| 2531 | ; $if b ;no ;an000; dms; | ||
| 2532 | JNB ER_IF49 | ||
| 2533 | mov cx,di ;get move count ;an000; dms; | ||
| 2534 | inc cx ;always 1 byte off ;an000; dms; | ||
| 2535 | ; $endif ; ;an000; dms; | ||
| 2536 | ER_IF49: | ||
| 2537 | ; $endif ; ;an000; dms; | ||
| 2538 | ER_EN45: | ||
| 2539 | ; $else ;forward move ;an000; dms; | ||
| 2540 | JMP SHORT ER_EN44 | ||
| 2541 | ER_IF44: | ||
| 2542 | cmp si,di ;source >= dest? ;an000; dms; | ||
| 2543 | ; $if a ;yes ;an000; dms; | ||
| 2544 | JNA ER_IF53 | ||
| 2545 | mov ax,4000h ;get end of page ;an000; dms; | ||
| 2546 | sub ax,si ;get bytes remaining ;an000; dms; | ||
| 2547 | cmp ax,ER_10H ;source >= 10h ;an000; dms; | ||
| 2548 | ; $if b ;no ;an000; dms; | ||
| 2549 | JNB ER_IF54 | ||
| 2550 | mov cx,ax ;get remaining count ;an000; dms; | ||
| 2551 | ; $endif ; ;an000; dms; | ||
| 2552 | ER_IF54: | ||
| 2553 | ; $else ;source >= dest ;an000; dms; | ||
| 2554 | JMP SHORT ER_EN53 | ||
| 2555 | ER_IF53: | ||
| 2556 | mov ax,4000h ;get end of page ;an000; dms; | ||
| 2557 | sub ax,di ;get bytes remaining ;an000; dms; | ||
| 2558 | cmp ax,ER_10H ;dest >= 10h ;an000; dms; | ||
| 2559 | ; $if b ;no ;an000; dms; | ||
| 2560 | JNB ER_IF57 | ||
| 2561 | mov cx,ax ;get remaining count ;an000; dms; | ||
| 2562 | ; $endif ; ;an000; dms; | ||
| 2563 | ER_IF57: | ||
| 2564 | ; $endif ; ;an000; dms; | ||
| 2565 | ER_EN53: | ||
| 2566 | ; $endif ; ;an000; dms; | ||
| 2567 | ER_EN44: | ||
| 2568 | |||
| 2569 | jmp ER_Move_Source_Default_Count ;continue routine ;an000; dms; | ||
| 2570 | |||
| 2571 | ER_Move_Source_Default_Count: | ||
| 2572 | |||
| 2573 | mov cs:[bp].ER_Current_Move_Count,cx ;save current move cnt ;an000; dms; | ||
| 2574 | |||
| 2575 | sub cs:[bp].ER_Move_Count_Low,cx ;get new count ;an000; dms; | ||
| 2576 | sbb cs:[bp].ER_Move_Count_High,0 ;pick up borrow ;an000; dms; | ||
| 2577 | |||
| 2578 | mov ax,cs ;get seg for buffer ;an000; dms; | ||
| 2579 | mov es,ax ;put into es ;an000; dms; | ||
| 2580 | mov di,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms; | ||
| 2581 | add di,bp ;offset BP relative ;an000; dms; | ||
| 2582 | |||
| 2583 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2584 | ; $if e ;yes ;an000; dms; | ||
| 2585 | JNE ER_IF61 | ||
| 2586 | add di,ER_10H ;end of buffer + 1 ;an000; dms; | ||
| 2587 | dec di ;end of buffer ;an000; dms; | ||
| 2588 | ; $endif ; ;an000; dms; | ||
| 2589 | ER_IF61: | ||
| 2590 | |||
| 2591 | |||
| 2592 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2593 | ; $if e ;yes ;an000; dms; | ||
| 2594 | JNE ER_IF63 | ||
| 2595 | std ;reverse move ;an000; dms; | ||
| 2596 | ; $else ;forward move ;an000; dms; | ||
| 2597 | JMP SHORT ER_EN63 | ||
| 2598 | ER_IF63: | ||
| 2599 | cld ; ;an000; dms; | ||
| 2600 | ; $endif ; ;an000; dms; | ||
| 2601 | ER_EN63: | ||
| 2602 | cli ;ints off ;an000; dms; | ||
| 2603 | rep movsb ;move the data ;an000; dms; | ||
| 2604 | sti ;ints on ;an000; dms; | ||
| 2605 | |||
| 2606 | ER_Move_Source_Exit: | ||
| 2607 | |||
| 2608 | pop es ;restore regs ;an000; dms; | ||
| 2609 | pop di ; ;an000; dms; | ||
| 2610 | pop dx ; ;an000; dms; | ||
| 2611 | pop bx ; ;an000; dms; | ||
| 2612 | pop ax ; ;an000; dms; | ||
| 2613 | |||
| 2614 | ret ;return to caller ;an000; dms; | ||
| 2615 | |||
| 2616 | ER_Move_Source_To_Buffer endp ;end proc ;an000; dms; | ||
| 2617 | |||
| 2618 | |||
| 2619 | ;========================================================================= | ||
| 2620 | ; ER_Move_Buffer_To_Dest : This routine moves the data in the buffer | ||
| 2621 | ; to the destination specified by the user. | ||
| 2622 | ; | ||
| 2623 | ; Inputs : BP - carries type of memory for source/dest | ||
| 2624 | ; Bit 0 - Destination (EMS if set) | ||
| 2625 | ; Bit 1 - Source (EMS if set) | ||
| 2626 | ; ER_Move_Xchg_Buffer1 - Source data | ||
| 2627 | ; | ||
| 2628 | ; Outputs : Adjusted segment:offset or page/offset | ||
| 2629 | ;========================================================================= | ||
| 2630 | |||
| 2631 | ER_Move_Buffer_To_Dest proc ; ;an000; dms; | ||
| 2632 | |||
| 2633 | push ax ;save regs ;an000; dms; | ||
| 2634 | push bx ; ;an000; dms; | ||
| 2635 | push dx ; ;an000; dms; | ||
| 2636 | push si ; ;an000; dms; | ||
| 2637 | push ds ; ;an000; dms; | ||
| 2638 | |||
| 2639 | test cs:[bp].ER_Mem_Type,ER_Dest_EMS_Memory ;Source EMS? ;an000; dms; | ||
| 2640 | jz ER_Move_Buffer_Conv_Mem ;no - adjust seg:off ;an000; dms; | ||
| 2641 | jmp ER_Move_Buffer_EMS_Mem ;yes- continue move ;an000; dms; | ||
| 2642 | |||
| 2643 | ER_Move_Buffer_Conv_Mem: | ||
| 2644 | |||
| 2645 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2646 | ; $if e ;yes ;an000; dms; | ||
| 2647 | JNE ER_IF66 | ||
| 2648 | mov ax,es ;adjust segment:off ;an000; dms; | ||
| 2649 | dec ax ;segment - 1 para ;an000; dms; | ||
| 2650 | mov es,ax ; ;an000; dms; | ||
| 2651 | add di,ER_10H ;adjust offset for 1 ;an000; dms; | ||
| 2652 | ; $else ;forward move? ;an000; dms; | ||
| 2653 | JMP SHORT ER_EN66 | ||
| 2654 | ER_IF66: | ||
| 2655 | mov ax,es ;adjust seg:off ;an000; dms; | ||
| 2656 | mov dx,di ; ;an000; dms; | ||
| 2657 | call ER_Segment_Adjust ; ;an000; dms; | ||
| 2658 | mov es,ax ;new seg:off ;an000; dms; | ||
| 2659 | mov di,dx ; ;an000; dms; | ||
| 2660 | ; $endif ; ;an000; dms; | ||
| 2661 | ER_EN66: | ||
| 2662 | ; para | ||
| 2663 | jmp ER_Move_Buffer_Count ;determine count ;an000; dms; | ||
| 2664 | |||
| 2665 | ER_Move_Buffer_EMS_Mem: | ||
| 2666 | |||
| 2667 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2668 | ; $if e ;yes ;an000; dms; | ||
| 2669 | JNE ER_IF69 | ||
| 2670 | cmp di,0ffffh ;beginning of log page ;an000; dms; | ||
| 2671 | ; $if e ;yes ;an000; dms; | ||
| 2672 | JNE ER_IF70 | ||
| 2673 | dec cs:[bp].ER_Dest_Page ;next page ;an000; dms; | ||
| 2674 | mov di,EMS_Page_Size_In_Bytes;end of page ;an000; dms; | ||
| 2675 | ; $endif ; ;an000; dms; | ||
| 2676 | ER_IF70: | ||
| 2677 | ; $else ;forward move ;an000; dms; | ||
| 2678 | JMP SHORT ER_EN69 | ||
| 2679 | ER_IF69: | ||
| 2680 | cmp di,4000h ;end of page? ;an000; dms; | ||
| 2681 | ; $if e ;yes ;an000; dms; | ||
| 2682 | JNE ER_IF73 | ||
| 2683 | inc cs:[bp].ER_Dest_Page ;next page ;an000; dms; | ||
| 2684 | xor di,di ;clear di ;an000; dms; | ||
| 2685 | ; $endif ; ;an000; dms; | ||
| 2686 | ER_IF73: | ||
| 2687 | ; $endif ; ;an000; dms; | ||
| 2688 | ER_EN69: | ||
| 2689 | mov bx,cs:[bp].ER_Dest_Page ;pass page to map ;an000; dms; | ||
| 2690 | call ER_Map_Next_Dest_Page ;map in the page ;an000; dms; | ||
| 2691 | |||
| 2692 | ER_Move_Buffer_Count: | ||
| 2693 | |||
| 2694 | mov cx,cs:[bp].ER_Current_Move_Count ;get move from source ;an000; dms; | ||
| 2695 | |||
| 2696 | mov ax,cs ;get seg for buffer ;an000; dms; | ||
| 2697 | mov ds,ax ;put into es ;an000; dms; | ||
| 2698 | mov si,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms; | ||
| 2699 | add si,bp ;offset BP relative ;an000; dms; | ||
| 2700 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2701 | ; $if e ;yes ;an000; dms; | ||
| 2702 | JNE ER_IF76 | ||
| 2703 | add si,ER_10H ;end of buffer + 1 ;an000; dms; | ||
| 2704 | dec si ;end of buffer ;an000; dms; | ||
| 2705 | ; $endif ; ;an000; dms; | ||
| 2706 | ER_IF76: | ||
| 2707 | |||
| 2708 | cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; | ||
| 2709 | ; $if e ;yes ;an000; dms; | ||
| 2710 | JNE ER_IF78 | ||
| 2711 | std ;reverse move ;an000; dms; | ||
| 2712 | ; $else ;forward move ;an000; dms; | ||
| 2713 | JMP SHORT ER_EN78 | ||
| 2714 | ER_IF78: | ||
| 2715 | cld ; ;an000; dms; | ||
| 2716 | ; $endif ; ;an000; dms; | ||
| 2717 | ER_EN78: | ||
| 2718 | cli ;ints off ;an000; dms; | ||
| 2719 | rep movsb ;move the data ;an000; dms; | ||
| 2720 | sti ;ints on ;an000; dms; | ||
| 2721 | |||
| 2722 | ER_Move_Dest_Exit: | ||
| 2723 | |||
| 2724 | pop ds ;restore regs ;an000; dms; | ||
| 2725 | pop si ; ;an000; dms; | ||
| 2726 | pop dx ; ;an000; dms; | ||
| 2727 | pop bx ; ;an000; dms; | ||
| 2728 | pop ax ; ;an000; dms; | ||
| 2729 | |||
| 2730 | ret ;return to caller ;an000; dms; | ||
| 2731 | |||
| 2732 | ER_Move_Buffer_To_Dest endp ;end proc ;an000; dms; | ||
| 2733 | |||
| 2734 | |||
| 2735 | ;========================================================================= | ||
| 2736 | ; ER_Xchg_Source_To_Buffer : This routine moves the source data to | ||
| 2737 | ; the buffer before it is exchanged with | ||
| 2738 | ; the destination data. | ||
| 2739 | ; | ||
| 2740 | ; Inputs : BP - carries type of memory for source/dest | ||
| 2741 | ; Bit 0 - Destination (EMS if set) | ||
| 2742 | ; Bit 1 - Source (EMS if set) | ||
| 2743 | ; | ||
| 2744 | ; Outputs : ER_Move_Xchg_Buffer1 - Source data | ||
| 2745 | ;========================================================================= | ||
| 2746 | |||
| 2747 | ER_Xchg_Source_To_Buffer proc ; ;an000; dms; | ||
| 2748 | |||
| 2749 | push ax ;save regs ;an000; dms; | ||
| 2750 | push bx ; ;an000; dms; | ||
| 2751 | push dx ; ;an000; dms; | ||
| 2752 | push di ; ;an000; dms; | ||
| 2753 | push si ; ;an000; dms; | ||
| 2754 | push ds ; ;an000; dms; | ||
| 2755 | push es ; ;an000; dms; | ||
| 2756 | |||
| 2757 | test cs:[bp].ER_Mem_Type,ER_Source_EMS_Memory;Source EMS? ;an000; dms; | ||
| 2758 | jz ER_Xchg_Source_Conv_Mem ;no - adjust seg:off ;an000; dms; | ||
| 2759 | jmp ER_Xchg_Source_EMS_Mem ;yes- continue move ;an000; dms; | ||
| 2760 | |||
| 2761 | ER_Xchg_Source_Conv_Mem: | ||
| 2762 | |||
| 2763 | mov ax,ds ;adjust segment:off ;an000; dms; | ||
| 2764 | mov dx,si ; ;an000; dms; | ||
| 2765 | call ER_Segment_Adjust ; ;an000; dms; | ||
| 2766 | mov ds,ax ;new segment:off ;an000; dms; | ||
| 2767 | mov si,dx ; ;an000; dms; | ||
| 2768 | jmp ER_Xchg_Source_Count ;determine count ;an000; dms; | ||
| 2769 | |||
| 2770 | ER_Xchg_Source_EMS_Mem: | ||
| 2771 | |||
| 2772 | cmp si,4000h ;beginning of log page ;an000; dms; | ||
| 2773 | je ER_Xchg_Source_EMS_Next ;yes - get next page ;an000; dms; | ||
| 2774 | mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms; | ||
| 2775 | call ER_Map_Next_Src_Page ;no - map in current pg;an000; dms; | ||
| 2776 | jmp ER_Xchg_Source_Count ;get count for move ;an000; dms; | ||
| 2777 | |||
| 2778 | ER_Xchg_Source_EMS_Next: | ||
| 2779 | |||
| 2780 | mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms; | ||
| 2781 | inc bx ; adjusted upward ;an000; dms; | ||
| 2782 | call ER_Map_Next_Src_Page ;map in the page ;an000; dms; | ||
| 2783 | xor si,si ;reinit pointer ;an000; dms; | ||
| 2784 | |||
| 2785 | ER_Xchg_Source_Count: | ||
| 2786 | |||
| 2787 | mov cx,ER_10H ;default count ;an000; dms; | ||
| 2788 | cmp cs:[bp].ER_Move_Count_High,0 ;high word set ;an000; dms; | ||
| 2789 | jne ER_Xchg_Source_High_Set ;yes - use default ;an000; dms; | ||
| 2790 | cmp cs:[bp].ER_Move_Count_Low,cx ;>= 10h bytes ;an000; dms; | ||
| 2791 | jae ER_Xchg_Source_High_Set ;yes - use default ;an000; dms; | ||
| 2792 | mov cx,cs:[bp].ER_Move_Count_Low ;no - use last few bytes;an000; dms; | ||
| 2793 | |||
| 2794 | ER_Xchg_Source_High_Set: | ||
| 2795 | |||
| 2796 | cmp si,di ;source >= dest? ;an000; dms; | ||
| 2797 | ; $if b ;no ;an000; dms; | ||
| 2798 | JNB ER_IF81 | ||
| 2799 | mov ax,4000h ;get end of page ;an000; dms; | ||
| 2800 | sub ax,si ;get bytes remaining ;an000; dms; | ||
| 2801 | cmp ax,ER_10H ;source >= 10h ;an000; dms; | ||
| 2802 | ; $if b ;no ;an000; dms; | ||
| 2803 | JNB ER_IF82 | ||
| 2804 | mov cx,ax ;get remaining count ;an000; dms; | ||
| 2805 | ; $endif ; ;an000; dms; | ||
| 2806 | ER_IF82: | ||
| 2807 | ; $else ;source >= dest ;an000; dms; | ||
| 2808 | JMP SHORT ER_EN81 | ||
| 2809 | ER_IF81: | ||
| 2810 | mov ax,4000h ;get end of page ;an000; dms; | ||
| 2811 | sub ax,di ;get bytes remaining ;an000; dms; | ||
| 2812 | cmp ax,ER_10H ;dest >= 10h ;an000; dms; | ||
| 2813 | ; $if b ;no ;an000; dms; | ||
| 2814 | JNB ER_IF85 | ||
| 2815 | mov cx,ax ;get remaining count ;an000; dms; | ||
| 2816 | ; $endif ; ;an000; dms; | ||
| 2817 | ER_IF85: | ||
| 2818 | ; $endif ; ;an000; dms; | ||
| 2819 | ER_EN81: | ||
| 2820 | |||
| 2821 | ER_Xchg_Source_Default_Count: | ||
| 2822 | |||
| 2823 | mov cs:[bp].ER_Current_Move_Count,cx ;save current move cnt ;an000; dms; | ||
| 2824 | |||
| 2825 | sub cs:[bp].ER_Move_Count_Low,cx ;get new count ;an000; dms; | ||
| 2826 | sbb cs:[bp].ER_Move_Count_High,0 ;pick up borrow ;an000; dms; | ||
| 2827 | |||
| 2828 | mov ax,cs ;get seg for buffer ;an000; dms; | ||
| 2829 | mov es,ax ;put into es ;an000; dms; | ||
| 2830 | mov di,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms; | ||
| 2831 | add di,bp ;offset BP relative ;an000; dms; | ||
| 2832 | |||
| 2833 | cld ;forward move ;an000; dms; | ||
| 2834 | cli ;ints off ;an000; dms; | ||
| 2835 | rep movsb ;move the data ;an000; dms; | ||
| 2836 | sti ;ints on ;an000; dms; | ||
| 2837 | |||
| 2838 | ER_Xchg_Source_Exit: | ||
| 2839 | |||
| 2840 | pop es ;restore regs ;an000; dms; | ||
| 2841 | pop ds ; ;an000; dms; | ||
| 2842 | pop si ; ;an000; dms; | ||
| 2843 | pop di ; ;an000; dms; | ||
| 2844 | pop dx ; ;an000; dms; | ||
| 2845 | pop bx ; ;an000; dms; | ||
| 2846 | pop ax ; ;an000; dms; | ||
| 2847 | |||
| 2848 | ret ;return to caller ;an000; dms; | ||
| 2849 | |||
| 2850 | ER_Xchg_Source_To_Buffer endp ;end proc ;an000; dms; | ||
| 2851 | |||
| 2852 | |||
| 2853 | ;========================================================================= | ||
| 2854 | ; ER_Xchg_Dest_To_Buffer : This routine moves the destination data to | ||
| 2855 | ; the buffer before it is exchanged with | ||
| 2856 | ; the source data. | ||
| 2857 | ; | ||
| 2858 | ; Inputs : BP - carries type of memory for source/dest | ||
| 2859 | ; Bit 0 - Destination (EMS if set) | ||
| 2860 | ; Bit 1 - Source (EMS if set) | ||
| 2861 | ; | ||
| 2862 | ; Outputs : ER_Move_Xchg_Buffer2 - Destination data | ||
| 2863 | ;========================================================================= | ||
| 2864 | |||
| 2865 | ER_Xchg_Dest_To_Buffer proc ; ;an000; dms; | ||
| 2866 | |||
| 2867 | push ax ;save regs ;an000; dms; | ||
| 2868 | push bx ; ;an000; dms; | ||
| 2869 | push dx ; ;an000; dms; | ||
| 2870 | push di ; ;an000; dms; | ||
| 2871 | push si ; ;an000; dms; | ||
| 2872 | push ds ; ;an000; dms; | ||
| 2873 | push es ; ;an000; dms; | ||
| 2874 | |||
| 2875 | test cs:[bp].ER_Mem_Type,ER_Dest_EMS_Memory ;Dest EMS? ;an000; dms; | ||
| 2876 | jz ER_Xchg_Dest_Conv_Mem ;no - adjust seg:off ;an000; dms; | ||
| 2877 | jmp ER_Xchg_Dest_EMS_Mem ;yes- continue move ;an000; dms; | ||
| 2878 | |||
| 2879 | ER_Xchg_Dest_Conv_Mem: | ||
| 2880 | |||
| 2881 | mov ax,es ;adjust segment:off ;an000; dms; | ||
| 2882 | mov dx,di ; ;an000; dms; | ||
| 2883 | call ER_Segment_Adjust ; ;an000; dms; | ||
| 2884 | mov es,ax ;new segment:off ;an000; dms; | ||
| 2885 | mov di,dx ; ;an000; dms; | ||
| 2886 | jmp ER_Xchg_Dest_Count ;determine count ;an000; dms; | ||
| 2887 | |||
| 2888 | ER_Xchg_Dest_EMS_Mem: | ||
| 2889 | |||
| 2890 | cmp di,4000h ;beginning of log page ;an000; dms; | ||
| 2891 | je ER_Xchg_Dest_EMS_Next ;yes - get next page ;an000; dms; | ||
| 2892 | mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms; | ||
| 2893 | call ER_Map_Next_Dest_Page ;no - map in current pg;an000; dms; | ||
| 2894 | jmp ER_Xchg_Dest_Count ;get count for move ;an000; dms; | ||
| 2895 | |||
| 2896 | ER_Xchg_Dest_EMS_Next: | ||
| 2897 | |||
| 2898 | mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms; | ||
| 2899 | inc bx ; adjusted upward ;an000; dms; | ||
| 2900 | call ER_Map_Next_Dest_Page ;map in the page ;an000; dms; | ||
| 2901 | xor di,di ;reinit pointer ;an000; dms; | ||
| 2902 | |||
| 2903 | ER_Xchg_Dest_Count: | ||
| 2904 | |||
| 2905 | mov cx,cs:[bp].ER_Current_Move_Count ;get move count ;an000; dms; | ||
| 2906 | mov ax,es ;get destination seg ;an000; dms; | ||
| 2907 | mov ds,ax ;put into ds for buffer ;an000; dms; | ||
| 2908 | ; transfer | ||
| 2909 | mov si,di ;get destination off ;an000; dms; | ||
| 2910 | mov ax,cs ;get seg for buffer ;an000; dms; | ||
| 2911 | mov es,ax ;put into es ;an000; dms; | ||
| 2912 | mov di,offset cs:ER_Move_Xchg_Buffer2 ;offset of buffer ;an000; dms; | ||
| 2913 | add di,bp ;offset BP relative ;an000; dms; | ||
| 2914 | |||
| 2915 | cld ;forward move ;an000; dms; | ||
| 2916 | cli ;ints off ;an000; dms; | ||
| 2917 | rep movsb ;move the data ;an000; dms; | ||
| 2918 | sti ;ints on ;an000; dms; | ||
| 2919 | |||
| 2920 | ER_Xchg_Dest_Exit: | ||
| 2921 | |||
| 2922 | pop es ;restore regs ;an000; dms; | ||
| 2923 | pop ds ; ;an000; dms; | ||
| 2924 | pop si ; ;an000; dms; | ||
| 2925 | pop di ; ;an000; dms; | ||
| 2926 | pop dx ; ;an000; dms; | ||
| 2927 | pop bx ; ;an000; dms; | ||
| 2928 | pop ax ; ;an000; dms; | ||
| 2929 | |||
| 2930 | ret ;return to caller ;an000; dms; | ||
| 2931 | |||
| 2932 | ER_Xchg_Dest_To_Buffer endp ;end proc ;an000; dms; | ||
| 2933 | |||
| 2934 | |||
| 2935 | |||
| 2936 | |||
| 2937 | ;========================================================================= | ||
| 2938 | ; ER_Xchg_Buffer_To_Source ; This routine performs the actual exchange | ||
| 2939 | ; from the destination buffer to the source | ||
| 2940 | ; buffer. | ||
| 2941 | ; | ||
| 2942 | ; Inputs : BP - carries type of memory for source/dest | ||
| 2943 | ; Bit 0 - Destination (EMS if set) | ||
| 2944 | ; Bit 1 - Source (EMS if set) | ||
| 2945 | ; ER_Move_Xchg_Buffer2 - Destination data | ||
| 2946 | ; | ||
| 2947 | ; Outputs : Adjusted segment:offset or page/offset | ||
| 2948 | ;========================================================================= | ||
| 2949 | |||
| 2950 | ER_Xchg_Buffer_To_Source proc ; ;an000; dms; | ||
| 2951 | |||
| 2952 | push ax ;save regs ;an000; dms; | ||
| 2953 | push bx ; ;an000; dms; | ||
| 2954 | push dx ; ;an000; dms; | ||
| 2955 | push di ; ;an000; dms; | ||
| 2956 | push es ; ;an000; dms; | ||
| 2957 | |||
| 2958 | test cs:[bp].ER_Mem_Type,ER_Source_EMS_Memory;Source EMS? ;an000; dms; | ||
| 2959 | jz ER_Xchg_Buf2_Conv_Mem ;no - adjust seg:off ;an000; dms; | ||
| 2960 | jmp ER_Xchg_Buf2_EMS_Mem ;yes- continue move ;an000; dms; | ||
| 2961 | |||
| 2962 | ER_Xchg_Buf2_Conv_Mem: | ||
| 2963 | |||
| 2964 | mov ax,ds ;adjust segment:off ;an000; dms; | ||
| 2965 | mov dx,si ; ;an000; dms; | ||
| 2966 | call ER_Segment_Adjust ; ;an000; dms; | ||
| 2967 | mov ds,ax ;new segment:off ;an000; dms; | ||
| 2968 | mov si,dx ; ;an000; dms; | ||
| 2969 | jmp ER_Xchg_Buf2_Count ;determine count ;an000; dms; | ||
| 2970 | |||
| 2971 | ER_Xchg_Buf2_EMS_Mem: | ||
| 2972 | |||
| 2973 | cmp si,4000h ;beginning of log page ;an000; dms; | ||
| 2974 | je ER_Xchg_Buf2_EMS_Next ;yes - get next page ;an000; dms; | ||
| 2975 | mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms; | ||
| 2976 | call ER_Map_Next_Src_Page ;no - map in current pg;an000; dms; | ||
| 2977 | jmp ER_Xchg_Buf2_Count ;get count for move ;an000; dms; | ||
| 2978 | |||
| 2979 | ER_Xchg_Buf2_EMS_Next: | ||
| 2980 | |||
| 2981 | inc cs:[bp].ER_Source_Page ;adjust log page ;an000; dms; | ||
| 2982 | mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms; | ||
| 2983 | call ER_Map_Next_Src_Page ;map in the page ;an000; dms; | ||
| 2984 | xor si,si ;reinit pointer ;an000; dms; | ||
| 2985 | |||
| 2986 | ER_Xchg_Buf2_Count: | ||
| 2987 | |||
| 2988 | mov cx,cs:[bp].ER_Current_Move_Count ;get move count ;an000; dms; | ||
| 2989 | |||
| 2990 | mov ax,ds ;get destination seg ;an000; dms; | ||
| 2991 | mov es,ax ;put into ds for buffer ;an000; dms; | ||
| 2992 | ; transfer | ||
| 2993 | mov di,si ;get destination off ;an000; dms; | ||
| 2994 | add si,cx ;adjust source ptr ;an000; dms; | ||
| 2995 | push si ;save across xchg ;an000; dms; | ||
| 2996 | push ds ; ;an000; dms; | ||
| 2997 | |||
| 2998 | mov ax,cs ;get seg for buffer ;an000; dms; | ||
| 2999 | mov ds,ax ;put into es ;an000; dms; | ||
| 3000 | mov si,offset cs:ER_Move_Xchg_Buffer2 ;offset of buffer ;an000; dms; | ||
| 3001 | add si,bp ;offset BP relative ;an000; dms; | ||
| 3002 | |||
| 3003 | cld ;forward move ;an000; dms; | ||
| 3004 | cli ;ints off ;an000; dms; | ||
| 3005 | rep movsb ;move the data ;an000; dms; | ||
| 3006 | sti ;ints on ;an000; dms; | ||
| 3007 | |||
| 3008 | pop ds ;restore ptr ;an000; dms; | ||
| 3009 | pop si ; ;an000; dms; | ||
| 3010 | |||
| 3011 | ER_Xchg_Buf2_Exit: | ||
| 3012 | |||
| 3013 | pop es ;restore regs ;an000; dms; | ||
| 3014 | pop di ; ;an000; dms; | ||
| 3015 | pop dx ; ;an000; dms; | ||
| 3016 | pop bx ; ;an000; dms; | ||
| 3017 | pop ax ; ;an000; dms; | ||
| 3018 | |||
| 3019 | ret ;return to caller ;an000; dms; | ||
| 3020 | |||
| 3021 | ER_Xchg_Buffer_To_Source endp ;end proc ;an000; dms; | ||
| 3022 | |||
| 3023 | |||
| 3024 | |||
| 3025 | ;========================================================================= | ||
| 3026 | ; ER_Xchg_Buffer_To_Dest ; This routine performs the actual exchange | ||
| 3027 | ; from the source buffer to the destination. | ||
| 3028 | ; | ||
| 3029 | ; Inputs : BP - carries type of memory for source/dest | ||
| 3030 | ; Bit 0 - Destination (EMS if set) | ||
| 3031 | ; Bit 1 - Source (EMS if set) | ||
| 3032 | ; ER_Move_Xchg_Buffer1 - Source data | ||
| 3033 | ; | ||
| 3034 | ; Outputs : Adjusted segment:offset or page/offset | ||
| 3035 | ;========================================================================= | ||
| 3036 | |||
| 3037 | ER_Xchg_Buffer_To_Dest proc ; ;an000; dms; | ||
| 3038 | |||
| 3039 | push ax ;save regs ;an000; dms; | ||
| 3040 | push bx ; ;an000; dms; | ||
| 3041 | push dx ; ;an000; dms; | ||
| 3042 | push si ; ;an000; dms; | ||
| 3043 | push ds ; ;an000; dms; | ||
| 3044 | |||
| 3045 | test cs:[bp].ER_Mem_Type,ER_Dest_EMS_Memory ;Dest EMS? ;an000; dms; | ||
| 3046 | jz ER_Xchg_Buf1_Conv_Mem ;no - adjust seg:off ;an000; dms; | ||
| 3047 | jmp ER_Xchg_Buf1_EMS_Mem ;yes- continue move ;an000; dms; | ||
| 3048 | |||
| 3049 | ER_Xchg_Buf1_Conv_Mem: | ||
| 3050 | |||
| 3051 | mov ax,es ;adjust segment:off ;an000; dms; | ||
| 3052 | mov dx,di ; ;an000; dms; | ||
| 3053 | call ER_Segment_Adjust ; ;an000; dms; | ||
| 3054 | mov es,ax ;new segment:off ;an000; dms; | ||
| 3055 | mov di,dx ; ;an000; dms; | ||
| 3056 | jmp ER_Xchg_Buf1_Count ;determine count ;an000; dms; | ||
| 3057 | |||
| 3058 | ER_Xchg_Buf1_EMS_Mem: | ||
| 3059 | |||
| 3060 | cmp di,4000h ;beginning of log page ;an000; dms; | ||
| 3061 | je ER_Xchg_Buf1_EMS_Next ;yes - get next page ;an000; dms; | ||
| 3062 | mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms; | ||
| 3063 | call ER_Map_Next_Dest_Page ;no - map in current pg;an000; dms; | ||
| 3064 | jmp ER_Xchg_Buf1_Count ;get count for move ;an000; dms; | ||
| 3065 | |||
| 3066 | ER_Xchg_Buf1_EMS_Next: | ||
| 3067 | |||
| 3068 | inc cs:[bp].ER_Dest_Page ;adjust log page ;an000; dms; | ||
| 3069 | mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms; | ||
| 3070 | call ER_Map_Next_Dest_Page ;map in the page ;an000; dms; | ||
| 3071 | mov di,EMS_Page_Size_In_Bytes ;reinit pointer ;an000; dms; | ||
| 3072 | |||
| 3073 | ER_Xchg_Buf1_Count: | ||
| 3074 | |||
| 3075 | mov cx,cs:[bp].ER_Current_Move_Count ;get move count ;an000; dms; | ||
| 3076 | mov ax,cs ;get seg for buffer ;an000; dms; | ||
| 3077 | mov ds,ax ;put into es ;an000; dms; | ||
| 3078 | mov si,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms; | ||
| 3079 | add si,bp ;offset BP relative ;an000; dms; | ||
| 3080 | |||
| 3081 | cld ;forward move ;an000; dms; | ||
| 3082 | cli ;ints off ;an000; dms; | ||
| 3083 | rep movsb ;move the data ;an000; dms; | ||
| 3084 | sti ;ints on ;an000; dms; | ||
| 3085 | |||
| 3086 | ER_Xchg_Buf1_Exit: | ||
| 3087 | |||
| 3088 | pop ds ;restore regs ;an000; dms; | ||
| 3089 | pop si ; ;an000; dms; | ||
| 3090 | pop dx ; ;an000; dms; | ||
| 3091 | pop bx ; ;an000; dms; | ||
| 3092 | pop ax ; ;an000; dms; | ||
| 3093 | |||
| 3094 | ret ;return to caller ;an000; dms; | ||
| 3095 | |||
| 3096 | ER_Xchg_Buffer_To_Dest endp ;end proc ;an000; dms; | ||
| 3097 | |||
| 3098 | |||
| 3099 | |||
| 3100 | ;========================================================================= | ||
| 3101 | ; ER_Map_Next_Src_Page : This routine maps in the page needed by | ||
| 3102 | ; the source of the move/exchange. | ||
| 3103 | ; | ||
| 3104 | ; Inputs : ER_Source_Phys_Page - Physical page of source | ||
| 3105 | ; ER_Source_Handle - Handle of source | ||
| 3106 | ; BX - logical page | ||
| 3107 | ; | ||
| 3108 | ; Outputs : newly mapped page | ||
| 3109 | ;========================================================================= | ||
| 3110 | |||
| 3111 | ER_Map_Next_Src_Page proc ;map next src. page ;an000; dms; | ||
| 3112 | |||
| 3113 | mov ax,cs:[bp].ER_Source_Phys_Page ;map the source page ;an000; dms; | ||
| 3114 | mov dx,cs:[bp].ER_Source_Handle ;handle to use ;an000; dms; | ||
| 3115 | call Map_L_To_P ;map the page ;an000; dms; | ||
| 3116 | |||
| 3117 | ret ;return to caller ;an000; dms; | ||
| 3118 | |||
| 3119 | ER_Map_Next_Src_Page endp ;end proc ;an000; dms; | ||
| 3120 | |||
| 3121 | ;========================================================================= | ||
| 3122 | ; ER_Map_Next_Dest_Page : This routine maps in the page needed by | ||
| 3123 | ; the destination of the move/exchange. | ||
| 3124 | ; | ||
| 3125 | ; Inputs : ER_Dest_Phys_Page - Physical page of source | ||
| 3126 | ; ER_Dest_Handle - Handle of source | ||
| 3127 | ; BX - logical page to map | ||
| 3128 | ; | ||
| 3129 | ; Outputs : newly mapped page | ||
| 3130 | ;========================================================================= | ||
| 3131 | |||
| 3132 | ER_Map_Next_Dest_Page proc ;map next dest. page ;an000; dms; | ||
| 3133 | |||
| 3134 | mov ax,cs:[bp].ER_Dest_Phys_Page ;map the dest. page ;an000; dms; | ||
| 3135 | mov dx,cs:[bp].ER_Dest_Handle ;handle to use ;an000; dms; | ||
| 3136 | call Map_L_To_P ;map the page ;an000; dms; | ||
| 3137 | |||
| 3138 | ret ;return to caller ;an000; dms; | ||
| 3139 | |||
| 3140 | ER_Map_Next_Dest_Page endp ;end proc ;an000; dms; | ||
| 3141 | |||
| 3142 | ;========================================================================= | ||
| 3143 | ; ER_Move_Data : This routine will perform the actual move of the | ||
| 3144 | ; data for the function 5700h. | ||
| 3145 | ; | ||
| 3146 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 3147 | ; | ||
| 3148 | ; Outputs : AH - Non-zero on error | ||
| 3149 | ;========================================================================= | ||
| 3150 | |||
| 3151 | ER_Move_Data proc ;move the data ;an000; dms; | ||
| 3152 | |||
| 3153 | push bx ;save regs ;an000; dms; | ||
| 3154 | push cx ; ;an000; dms; | ||
| 3155 | push dx ; ;an000; dms; | ||
| 3156 | push di ; ;an000; dms; | ||
| 3157 | push si ; ;an000; dms; | ||
| 3158 | push ds ; ;an000; dms; | ||
| 3159 | push es ; ;an000; dms; | ||
| 3160 | |||
| 3161 | call ER_Save_Context ;save off max of 2 pages;an000; dms; | ||
| 3162 | call ER_Det_Src_Dest_Seg ;determine segs ;an000; dms; | ||
| 3163 | call ER_Det_Move_Count ;ER_10h_Move_Count = ;an000; dms; | ||
| 3164 | ; # of 10h moves | ||
| 3165 | ;ER_10h_Move_Remainder = | ||
| 3166 | ; # of bytes remaining | ||
| 3167 | |||
| 3168 | ER_Move_Data_Now: | ||
| 3169 | |||
| 3170 | ;set the flags to signal | ||
| 3171 | ;the memory type in use | ||
| 3172 | ;for Source/Destination. | ||
| 3173 | |||
| 3174 | xor al,al ;al signals type of mem ;an000; dms; | ||
| 3175 | or al,[si].Source_Memory_Type ;get source memory type ;an000; dms; | ||
| 3176 | shl al,1 ;put into bit 1 ;an000; dms; | ||
| 3177 | or al,[si].Dest_Memory_Type ;get dest. memory type ;an000; dms; | ||
| 3178 | cbw ;make it a word value ;an000; dms; | ||
| 3179 | mov cs:[bp].ER_Mem_Type,ax ;put flags in var ;an000; dms; | ||
| 3180 | ;bp = bit 0 - dest mem | ||
| 3181 | ; bit 1 - src mem | ||
| 3182 | |||
| 3183 | mov di,cs:[bp].ER_Dest_Off ;get dest. offset ;an000; dms; | ||
| 3184 | mov es,cs:[bp].ER_Dest_Seg ;get dest. seg ;an000; dms; | ||
| 3185 | |||
| 3186 | mov si,cs:[bp].ER_Source_Off ;get src. offset ;an000; dms; | ||
| 3187 | mov ds,cs:[bp].ER_Source_Seg ;get src. seg ;an000; dms; | ||
| 3188 | |||
| 3189 | ER_Move_Data_Loop: | ||
| 3190 | |||
| 3191 | call ER_Move_Source_To_Buffer ;move data to buffer ;an000; dms; | ||
| 3192 | call ER_Move_Buffer_To_Dest ;move buffer to dest. ;an000; dms; | ||
| 3193 | |||
| 3194 | cmp cs:[bp].ER_Move_Count_High,0 ;end of move? ;an000; dms; | ||
| 3195 | jne ER_Move_Data_Loop ;no - continue loop ;an000; dms; | ||
| 3196 | cmp cs:[bp].ER_Move_Count_Low,0 ;end of move? ;an000; dms; | ||
| 3197 | jne ER_Move_Data_Loop ;no - continue loop ;an000; dms; | ||
| 3198 | ;yes - end of loop ;an000; dms; | ||
| 3199 | |||
| 3200 | ER_Move_Data_Error_Exit: | ||
| 3201 | |||
| 3202 | call ER_Restore_Context ;restore the context ;an000; dms; | ||
| 3203 | |||
| 3204 | pop es ;restore regs ;an000; dms; | ||
| 3205 | pop ds ; ;an000; dms; | ||
| 3206 | pop si ; ;an000; dms; | ||
| 3207 | pop di ; ;an000; dms; | ||
| 3208 | pop dx ; ;an000; dms; | ||
| 3209 | pop cx ; ;an000; dms; | ||
| 3210 | pop bx ; ;an000; dms; | ||
| 3211 | |||
| 3212 | ret ;return to caller ;an000; dms; | ||
| 3213 | |||
| 3214 | ER_Move_Data endp ;end proc ;an000; dms; | ||
| 3215 | |||
| 3216 | |||
| 3217 | |||
| 3218 | ;========================================================================= | ||
| 3219 | ; ER_Exchange_Data : This routine will perform the actual exchange of | ||
| 3220 | ; data for the function 5701h. | ||
| 3221 | ; | ||
| 3222 | ; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data | ||
| 3223 | ; | ||
| 3224 | ; Outputs : AH - Non-zero on error | ||
| 3225 | ;========================================================================= | ||
| 3226 | |||
| 3227 | ER_Exchange_Data proc ;xchg the data ;an000; dms; | ||
| 3228 | |||
| 3229 | push bx ;save regs ;an000; dms; | ||
| 3230 | push cx ; ;an000; dms; | ||
| 3231 | push dx ; ;an000; dms; | ||
| 3232 | push di ; ;an000; dms; | ||
| 3233 | push si ; ;an000; dms; | ||
| 3234 | push ds ; ;an000; dms; | ||
| 3235 | push es ; ;an000; dms; | ||
| 3236 | |||
| 3237 | call ER_Save_Context ;save off max of 2 pages;an000; dms; | ||
| 3238 | call ER_Det_Src_Dest_Seg ;determine segs ;an000; dms; | ||
| 3239 | call ER_Det_Move_Count ;ER_10h_Move_Count = ;an000; dms; | ||
| 3240 | ; # of 10h moves | ||
| 3241 | ;ER_10h_Move_Remainder = | ||
| 3242 | ; # of bytes remaining | ||
| 3243 | |||
| 3244 | ER_Xchg_Data_Now: | ||
| 3245 | |||
| 3246 | ;set the flags to signal | ||
| 3247 | ;the memory type in use | ||
| 3248 | ;for Source/Destination. | ||
| 3249 | |||
| 3250 | xor al,al ;al signals type of mem ;an000; dms; | ||
| 3251 | or al,[si].Source_Memory_Type ;get source memory type ;an000; dms; | ||
| 3252 | shl al,1 ;put into bit 1 ;an000; dms; | ||
| 3253 | or al,[si].Dest_Memory_Type ;get dest. memory type ;an000; dms; | ||
| 3254 | cbw ;make it a word value ;an000; dms; | ||
| 3255 | mov cs:[bp].ER_Mem_Type,ax ;put flags in var ;an000; dms; | ||
| 3256 | ;bp = bit 0 - dest mem | ||
| 3257 | ; bit 1 - src mem | ||
| 3258 | |||
| 3259 | mov di,cs:[bp].ER_Dest_Off ;get dest. offset ;an000; dms; | ||
| 3260 | mov es,cs:[bp].ER_Dest_Seg ;get dest. seg ;an000; dms; | ||
| 3261 | |||
| 3262 | mov si,cs:[bp].ER_Source_Off ;get src. offset ;an000; dms; | ||
| 3263 | mov ds,cs:[bp].ER_Source_Seg ;get src. seg ;an000; dms; | ||
| 3264 | |||
| 3265 | ER_Xchg_Data_Loop: | ||
| 3266 | |||
| 3267 | call ER_Xchg_Source_To_Buffer ;move source to buf 1 ;an000; dms; | ||
| 3268 | call ER_Xchg_Dest_To_Buffer ;move dest. to buf 2 ;an000; dms; | ||
| 3269 | call ER_Xchg_Buffer_To_Source ;move buf2 to source ;an000; dms; | ||
| 3270 | call ER_Xchg_Buffer_To_Dest ;move buf1 to dest. ;an000; dms; | ||
| 3271 | |||
| 3272 | cmp cs:[bp].ER_Move_Count_High,0 ;end of move? ;an000; dms; | ||
| 3273 | jne ER_Xchg_Data_Loop ;no - continue loop ;an000; dms; | ||
| 3274 | cmp cs:[bp].ER_Move_Count_Low,0 ;end of move? ;an000; dms; | ||
| 3275 | jne ER_Xchg_Data_Loop ;no - continue loop ;an000; dms; | ||
| 3276 | ;yes - end of loop ;an000; dms; | ||
| 3277 | |||
| 3278 | ER_Xchg_Data_Error_Exit: | ||
| 3279 | |||
| 3280 | call ER_Restore_Context ;restore the context ;an000; dms; | ||
| 3281 | |||
| 3282 | pop es ;restore regs ;an000; dms; | ||
| 3283 | pop ds ; ;an000; dms; | ||
| 3284 | pop si ; ;an000; dms; | ||
| 3285 | pop di ; ;an000; dms; | ||
| 3286 | pop dx ; ;an000; dms; | ||
| 3287 | pop cx ; ;an000; dms; | ||
| 3288 | pop bx ; ;an000; dms; | ||
| 3289 | |||
| 3290 | ret ;return to caller ;an000; dms; | ||
| 3291 | |||
| 3292 | ER_Exchange_Data endp ;end proc ;an000; dms; | ||
| 3293 | |||
| 3294 | |||
| 3295 | |||
| 3296 | page | ||
| 3297 | |||
| 3298 | ;========================================================================= | ||
| 3299 | ;=============== Function 5Ah Logic - Allocate Raw Pages ============= | ||
| 3300 | ;========================================================================= | ||
| 3301 | |||
| 3302 | |||
| 3303 | ;========================================================================= | ||
| 3304 | ; Alloc_Raw - This routine allocates raw EMS pages, pages | ||
| 3305 | ; less than the standard 16k page. These pages | ||
| 3306 | ; are a sub-multiple of 16k. In the IBM version | ||
| 3307 | ; of this implementation the raw page is defined | ||
| 3308 | ; as 16k, thus we do not need to do anything | ||
| 3309 | ; special here. We map this call to the proc | ||
| 3310 | ; GET_HANDLE (function 43h) to allocate a handle. | ||
| 3311 | ; | ||
| 3312 | ; Inputs : AH - 5Ah (Allocate Raw Pages) | ||
| 3313 | ; BX - Number of raw pages to allocate | ||
| 3314 | ; | ||
| 3315 | ; Outputs : AH - Non-zero if error (Determined by Get_Handle proc) | ||
| 3316 | ; DX - Handle if no error | ||
| 3317 | ;========================================================================= | ||
| 3318 | |||
| 3319 | Alloc_Raw proc ;Allocate raw pages ;an000; dms; | ||
| 3320 | |||
| 3321 | PUSH BX | ||
| 3322 | PUSH CX | ||
| 3323 | PUSH DI | ||
| 3324 | PUSH SI | ||
| 3325 | PUSH DS ;save these registers | ||
| 3326 | |||
| 3327 | PUSH CS ;get cs | ||
| 3328 | POP DS ;into ds | ||
| 3329 | |||
| 3330 | ;Remove test for BX = 0. This is @RH4 | ||
| 3331 | ; valid under LIM 4.0 | ||
| 3332 | |||
| 3333 | cmp al,AR_Sub_Max ;sub function out of range? ;an000; dms; | ||
| 3334 | jna AR_OKSub ;no ;an000; dms; | ||
| 3335 | mov ah,EMS_Code8F ;yes-signal error ;an000; dms; | ||
| 3336 | jmp AR_Exit ;exit routine ;an000; dms; | ||
| 3337 | |||
| 3338 | AR_OKSub: | ||
| 3339 | |||
| 3340 | CMP BX,TOTAL_EMS_PAGES ;Enough total EMS pages? | ||
| 3341 | JNA AR_OKTOTAL | ||
| 3342 | MOV AH,EMS_CODE87 | ||
| 3343 | JMP AR_EXIT | ||
| 3344 | |||
| 3345 | AR_OKTOTAL: | ||
| 3346 | cli ;ints off ;an000; dms; | ||
| 3347 | CMP BX,FREE_PAGES ;Enough unallocated pages? | ||
| 3348 | sti ;ints on ;an000; dms; | ||
| 3349 | JNA AR_OKFREE | ||
| 3350 | MOV AH,EMS_CODE88 | ||
| 3351 | JMP AR_EXIT | ||
| 3352 | ;----------------------------------------------------- | ||
| 3353 | ; Search for a free handle @RH1 º | ||
| 3354 | ;----------------------------------------------------- | ||
| 3355 | AR_OKFREE: | ||
| 3356 | MOV CX,NUM_HANDLES ;loop counter is #handles | ||
| 3357 | DEC CX ;handle 0 reserved for op. sys. @RH1 | ||
| 3358 | MOV DX,1 ;handle assignment set to 1 @RH1 | ||
| 3359 | MOV DI,TYPE H_LOOKUP_STRUC ;init table index to 1st entry @RH1 | ||
| 3360 | ;-------------------------------- | ||
| 3361 | CLI ;interrupts OFF during allocation | ||
| 3362 | ;-------------------------------- | ||
| 3363 | AR_FREEHSRCH: | ||
| 3364 | CMP HANDLE_LOOKUP_TABLE.H_PAGES[DI],REUSABLE_HANDLE | ||
| 3365 | ;Is this handle available? @RH1 | ||
| 3366 | JE AR_HFREE ;yes end search dx=handle id @RH1 | ||
| 3367 | INC DX ;next handle assignment | ||
| 3368 | ADD DI,TYPE H_LOOKUP_STRUC ;next entry in handle lookup @RH1 | ||
| 3369 | ;repeat for all table entries | ||
| 3370 | LOOP AR_FREEHSRCH | ||
| 3371 | MOV AH,EMS_CODE85 ;no available handles | ||
| 3372 | JMP AR_EXIT ;go to exit ;GGA | ||
| 3373 | |||
| 3374 | ;----------------------------------------------------- | ||
| 3375 | ; If here then there's enough pages for request. @RH1 º | ||
| 3376 | ; DX = handle #, DI = ptr to hndl lookup entry @RH1 º | ||
| 3377 | AR_HFREE: | ||
| 3378 | |||
| 3379 | MOV CX,NUM_HANDLES ;loop counter | ||
| 3380 | DEC CX ;handle 0 reserved for op. sys. @RH1 | ||
| 3381 | ;si = index to hndl lookup tbl @RH1 | ||
| 3382 | MOV SI,TYPE H_LOOKUP_STRUC ; for adding pages (skip 0 entry) @RH1 | ||
| 3383 | XOR AX,AX ;clear page counter | ||
| 3384 | CLC ;clear carry for addition | ||
| 3385 | AR_PAGESUM: | ||
| 3386 | CMP HANDLE_LOOKUP_TABLE.H_PAGES[SI],REUSABLE_HANDLE | ||
| 3387 | JE AR_PGSUM_BOT ;If handle is free don't add @RH4 | ||
| 3388 | ADD AX,HANDLE_LOOKUP_TABLE.H_PAGES[SI] | ||
| 3389 | ;add lengths (pages) of PALs @RH1 | ||
| 3390 | ADD SI,TYPE H_LOOKUP_STRUC ; next entry in handle lookup @RH1 | ||
| 3391 | AR_PGSUM_BOT: | ||
| 3392 | LOOP AR_PAGESUM | ||
| 3393 | CMP AX,TOTAL_EMS_PAGES ;pages in handle lookup > total? @RH1 | ||
| 3394 | JNA AR_CALCHLUP ;no OK @RH1 | ||
| 3395 | MOV AH,EMS_CODE80 ;software error..we screwed up @RH1 | ||
| 3396 | JMP AR_EXIT ;go to exit @RH1 ;GGA | ||
| 3397 | |||
| 3398 | AR_CALCHLUP: ;calculate entry in hndl lkup tbl @RH1 | ||
| 3399 | cmp bx,0 ;page request? ;an000; dms; | ||
| 3400 | jne AR_Alloc_Cont ;yes continue ;an000; dms; | ||
| 3401 | cli ;ints off ;an001; dms; | ||
| 3402 | mov Handle_LookUp_Table.H_Pages[di],bx ;new page count ;an001; dms; | ||
| 3403 | sti ;ints on ;an001; dms; | ||
| 3404 | xor ah,ah ;clear flag ;an000; dms; | ||
| 3405 | jmp AR_Exit ;exit routine ;an000; dms; | ||
| 3406 | |||
| 3407 | AR_Alloc_Cont: | ||
| 3408 | |||
| 3409 | cli ;ints off ;an001; dms; | ||
| 3410 | mov cx,bx ;alloc count ;an000; dms; | ||
| 3411 | call EMS_Page_Contig_Chk ;do we have contig pgs. ;an001; dms; | ||
| 3412 | jnc AR_Alloc ;yes continue process ;an001; dms; | ||
| 3413 | mov ah,EMS_Code88 ;no signal error ;an001; dms; | ||
| 3414 | sti ;ints on ;an001; dms; | ||
| 3415 | jmp AR_Exit ;exit routine ;an001; dms; | ||
| 3416 | |||
| 3417 | AR_Alloc: | ||
| 3418 | |||
| 3419 | call EMS_Link_Set ;set up links ;an001; dms; | ||
| 3420 | |||
| 3421 | |||
| 3422 | sub Free_Pages,bx ;free = free - requested pages | ||
| 3423 | mov Handle_LookUp_Table.H_Pages[di],bx ;page count ;an000; dms; | ||
| 3424 | mov Handle_LookUp_Table.H_Pal_Ptr[di],si ;initialize to ptr for ;ac001; dms; | ||
| 3425 | ; pages | ||
| 3426 | sti ;ints on ;an001; dms; | ||
| 3427 | xor ah,ah ;clear flag ;an000; dms; | ||
| 3428 | |||
| 3429 | |||
| 3430 | AR_EXIT: ;GGA | ||
| 3431 | |||
| 3432 | POP DS | ||
| 3433 | POP SI | ||
| 3434 | POP DI | ||
| 3435 | POP CX | ||
| 3436 | POP BX | ||
| 3437 | |||
| 3438 | ret ;return to caller ;an000; dms; | ||
| 3439 | |||
| 3440 | Alloc_Raw endp ;end proc ;an000; dms; | ||
| 3441 | |||
| 3442 | page | ||
| 3443 | ;========================================================================= | ||
| 3444 | ;=============== Function 5Ch Logic - Prepare for Warm Boot ============= | ||
| 3445 | ;========================================================================= | ||
| 3446 | |||
| 3447 | |||
| 3448 | ;========================================================================= | ||
| 3449 | ; Prepare_Boot - This routine prepares the hardware for a | ||
| 3450 | ; warm boot. Since we have no special hardware | ||
| 3451 | ; requirements at this time, this routine sets | ||
| 3452 | ; a good error level and returns to the caller. | ||
| 3453 | ; | ||
| 3454 | ; Inputs : AH - 5Ch (Prepare for Warm Boot) | ||
| 3455 | ; | ||
| 3456 | ; Outputs : AH - Non-zero if error (Determined by Get_Handle proc) | ||
| 3457 | ;========================================================================= | ||
| 3458 | |||
| 3459 | Prepare_Boot proc ;prepare for warm boot ;an000; dms; | ||
| 3460 | |||
| 3461 | xor ah,ah ;signal no error ;an000; dms; | ||
| 3462 | |||
| 3463 | ret ;return to caller ;an000; dms; | ||
| 3464 | |||
| 3465 | Prepare_Boot endp ;end proc ;an000; dms; | ||
| 3466 | |||
| 3467 | |||
| 3468 | |||
diff --git a/v4.0/src/DEV/XMA2EMS/MAKEFILE b/v4.0/src/DEV/XMA2EMS/MAKEFILE new file mode 100644 index 0000000..c739b08 --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/MAKEFILE | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #************************ makefile for dev\xma2ems************************ | ||
| 2 | |||
| 3 | msg =..\..\messages | ||
| 4 | dos =..\..\dos | ||
| 5 | inc =..\..\inc | ||
| 6 | hinc =..\..\h | ||
| 7 | |||
| 8 | # | ||
| 9 | ####################### dependencies begin here. ######################### | ||
| 10 | # | ||
| 11 | |||
| 12 | all: xma2ems.sys | ||
| 13 | |||
| 14 | xma2ems.ctl: xma2ems.skl $(MSG)\$(country).MSG makefile | ||
| 15 | |||
| 16 | xma2ems.obj: xma2ems.asm xma1diag.inc xma2ems.cl1 $(inc)\COPYRIGH.INC \ | ||
| 17 | parmpars.inc lim40.inc ps2_5060.inc makefile \ | ||
| 18 | emsinit.inc genioctl.inc xma2emsp.inc lim40b.inc romscan.inc \ | ||
| 19 | $(inc)\psdata.inc | ||
| 20 | |||
| 21 | xma2ems.sys: xma2ems.obj makefile | ||
| 22 | link xma2ems; | ||
| 23 | exe2bin xma2ems.exe xma2ems.sys | ||
| 24 | del xma2ems.exe | ||
diff --git a/v4.0/src/DEV/XMA2EMS/PARMPARS.INC b/v4.0/src/DEV/XMA2EMS/PARMPARS.INC new file mode 100644 index 0000000..42ea6e8 --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/PARMPARS.INC | |||
| @@ -0,0 +1,530 @@ | |||
| 1 | PAGE | ||
| 2 | ;-----------------------------------------------------------------------; | ||
| 3 | ; GET_PARMS extracts parameters from the command line buffer ; | ||
| 4 | ; ; | ||
| 5 | ; On entry: all letters after 'Device=' have been changed ; | ||
| 6 | ; to upper case ; | ||
| 7 | ; ; | ||
| 8 | ; On exit: (zf)=0 if syntax error ; | ||
| 9 | ; if (zf)=1 then... ; | ||
| 10 | ; ; | ||
| 11 | ; EMM_START_BLOCK has been updated ; | ||
| 12 | ; ; | ||
| 13 | ; AX,BX,CX,DX,DI,SI,DS are destroyed ; | ||
| 14 | ;-----------------------------------------------------------------------; | ||
| 15 | |||
| 16 | include xma2emsp.inc ; include parser things | ||
| 17 | include parse.asm | ||
| 18 | |||
| 19 | GET_PARMS PROC | ||
| 20 | LDS BX,CS:RH_PTRA ;make ds:bx point to request header | ||
| 21 | |||
| 22 | LDS SI,RH.RH0_BPBA ;make ds:si point to bios paramter buffer | ||
| 23 | CLD | ||
| 24 | mov cs:EMS_Pgs_Parm,E_Parm_Def ;default to all of memory ;an000; dms; | ||
| 25 | |||
| 26 | ;------------------------------------------------------------------- | ||
| 27 | ; parser support added by GGA | ||
| 28 | ;------------------------------------------------------------------- | ||
| 29 | push cs ; make ES:DI point to parm block | ||
| 30 | pop es | ||
| 31 | lea di,p_block | ||
| 32 | |||
| 33 | xor cx,cx ; cx = 0, ordinal | ||
| 34 | xor dx,dx ; dx = 0, reserved | ||
| 35 | |||
| 36 | push ds ; save ds | ||
| 37 | |||
| 38 | get_args: | ||
| 39 | pop ds ; restore ds | ||
| 40 | call SysParse ; call the parser | ||
| 41 | cmp ax,0 ; end of line? | ||
| 42 | je check_frame ; no, find out what we got this time | ||
| 43 | cmp ax,-1 ; end of parse? | ||
| 44 | je end_of_input_line1 ; yes | ||
| 45 | cmp ax,-1 ; flag an error | ||
| 46 | ret ; return to caller | ||
| 47 | |||
| 48 | end_of_input_line1: | ||
| 49 | |||
| 50 | jmp end_of_input_line ; | ||
| 51 | |||
| 52 | ; find out which arg was processed this time | ||
| 53 | |||
| 54 | check_frame: | ||
| 55 | |||
| 56 | ; make ds point to data area for these comparisons, must restore before | ||
| 57 | ; calling parser again | ||
| 58 | |||
| 59 | push ds ; save ds | ||
| 60 | push es ; make ds point to save areas | ||
| 61 | pop ds | ||
| 62 | |||
| 63 | cmp frame_result.$P_Type,2 ; was there a FRAME= in this pass? | ||
| 64 | jne check_p0 ; no, look for a P0 | ||
| 65 | |||
| 66 | mov parse_flag,1 ; set parse flag | ||
| 67 | |||
| 68 | mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another | ||
| 69 | mov frame_result.$P_Type,0 ; clear this so we don't get fooled later | ||
| 70 | |||
| 71 | mov byte ptr p0_ctl+9,0 ; turn these off so we don't allow any | ||
| 72 | mov byte ptr p1_ctl+9,0 ; others that would conflict | ||
| 73 | mov byte ptr p2_ctl+9,0 | ||
| 74 | mov byte ptr p3_ctl+9,0 | ||
| 75 | |||
| 76 | push si ;save regs | ||
| 77 | |||
| 78 | mov si,word ptr frame_result.$P_Picked_Val[+0] | ||
| 79 | |||
| 80 | mov word ptr ds:[si+0],0 ;clear the | ||
| 81 | mov word ptr ds:[si+4],0 ; pages | ||
| 82 | mov word ptr ds:[si+8],0 | ||
| 83 | mov word ptr ds:[si+12],0 | ||
| 84 | |||
| 85 | pop si ;restore regs | ||
| 86 | |||
| 87 | |||
| 88 | ; set flags for later code to fill in map_table | ||
| 89 | |||
| 90 | or page_flags,frame_flag ; set frame flag | ||
| 91 | |||
| 92 | jmp get_args ; go get another argument | ||
| 93 | |||
| 94 | check_p0: | ||
| 95 | cmp p0_result.$P_Type,2 ; was there a P0= in this pass? | ||
| 96 | jne check_p1 ; no, look for a P0 | ||
| 97 | |||
| 98 | mov parse_flag,1 ; set parse flag | ||
| 99 | |||
| 100 | mov byte ptr p0_ctl+9,0 ; turn this off so we don't allow another | ||
| 101 | mov p0_result.$P_Type,0 ; clear this so we don't get fooled later | ||
| 102 | |||
| 103 | mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another | ||
| 104 | |||
| 105 | push si ;save regs | ||
| 106 | |||
| 107 | mov si,word ptr p0_result.$P_Picked_Val[+0] | ||
| 108 | |||
| 109 | mov word ptr ds:[si+0],0 | ||
| 110 | |||
| 111 | pop si ;restore regs | ||
| 112 | ; set flags for later code to fill in map_table | ||
| 113 | |||
| 114 | or page_flags,p0_flag ; set p0 flag | ||
| 115 | |||
| 116 | jmp get_args ; go get another argument | ||
| 117 | |||
| 118 | check_p1: | ||
| 119 | cmp p1_result.$P_Type,2 ; was there a p1= in this pass? | ||
| 120 | jne check_p2 ; no, look for a P2 | ||
| 121 | |||
| 122 | mov parse_flag,1 ; set parse flag | ||
| 123 | |||
| 124 | mov byte ptr p1_ctl+9,0 ; turn this off so we don't allow another | ||
| 125 | mov p1_result.$P_Type,0 ; clear this so we don't get fooled later | ||
| 126 | |||
| 127 | mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another | ||
| 128 | |||
| 129 | push si ;save regs | ||
| 130 | |||
| 131 | mov si,word ptr p1_result.$P_Picked_Val[+0] | ||
| 132 | |||
| 133 | mov word ptr ds:[si+0],0 | ||
| 134 | |||
| 135 | pop si ;restore regs | ||
| 136 | ; set flags for later code to fill in map_table | ||
| 137 | |||
| 138 | or page_flags,p1_flag ; set p1 flag | ||
| 139 | |||
| 140 | jmp get_args ; go get another argument | ||
| 141 | |||
| 142 | check_p2: | ||
| 143 | cmp p2_result.$P_Type,2 ; was there a p2= in this pass? | ||
| 144 | jne check_p3 ; no, look for a p3 | ||
| 145 | |||
| 146 | mov parse_flag,1 ; set parse flag | ||
| 147 | |||
| 148 | mov byte ptr p2_ctl+9,0 ; turn this off so we don't allow another | ||
| 149 | mov p2_result.$P_Type,0 ; clear this so we don't get fooled later | ||
| 150 | |||
| 151 | mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another | ||
| 152 | |||
| 153 | push si ;save regs | ||
| 154 | |||
| 155 | mov si,word ptr p2_result.$P_Picked_Val[+0] | ||
| 156 | |||
| 157 | mov word ptr ds:[si+0],0 | ||
| 158 | |||
| 159 | pop si ;restore regs | ||
| 160 | ; set flags for later code to fill in map_table | ||
| 161 | |||
| 162 | or page_flags,p2_flag ; set p2 flag | ||
| 163 | |||
| 164 | jmp get_args ; go get another argument | ||
| 165 | |||
| 166 | check_p3: | ||
| 167 | cmp p3_result.$P_Type,2 ; was there a p3= in this pass? | ||
| 168 | jne check_p254 ; no, look for a P254 | ||
| 169 | |||
| 170 | mov parse_flag,1 ; set parse flag | ||
| 171 | |||
| 172 | mov byte ptr p3_ctl+9,0 ; turn this off so we don't allow another | ||
| 173 | mov p3_result.$P_Type,0 ; clear this so we don't get fooled later | ||
| 174 | |||
| 175 | mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another | ||
| 176 | |||
| 177 | push si ;save regs | ||
| 178 | |||
| 179 | mov si,word ptr p3_result.$P_Picked_Val[+0] | ||
| 180 | |||
| 181 | mov word ptr ds:[si+0],0 | ||
| 182 | |||
| 183 | pop si ;restore regs | ||
| 184 | ; set flags for later code to fill in map_table | ||
| 185 | |||
| 186 | or page_flags,p3_flag ; set p3 flag | ||
| 187 | |||
| 188 | jmp get_args ; go get another argument | ||
| 189 | |||
| 190 | check_p254: | ||
| 191 | cmp p254_result.$P_Type,2 ; was there a p254= in this pass? | ||
| 192 | jne check_p255 ; no, look for a P255 | ||
| 193 | |||
| 194 | mov parse_flag,1 ; set parse flag | ||
| 195 | |||
| 196 | mov byte ptr p254_ctl+9,0 ; turn this off so we don't allow another | ||
| 197 | mov p254_result.$P_Type,0 ; clear this so we don't get fooled later | ||
| 198 | |||
| 199 | push si ;save regs | ||
| 200 | |||
| 201 | mov si,word ptr p254_result.$P_Picked_Val[+0] | ||
| 202 | |||
| 203 | mov word ptr ds:[si+0],0 | ||
| 204 | |||
| 205 | pop si ;restore regs | ||
| 206 | ; set flags for later code to fill in map_table | ||
| 207 | |||
| 208 | or page_flags,p254_flag ; set p254 flag | ||
| 209 | |||
| 210 | jmp get_args ; go get another argument | ||
| 211 | |||
| 212 | check_p255: | ||
| 213 | cmp p255_result.$P_Type,2 ; was there a P255= in this pass? | ||
| 214 | je do_p255 ; yes, process it | ||
| 215 | jmp Check_X ; no, find out if /X was included | ||
| 216 | |||
| 217 | do_p255: | ||
| 218 | mov parse_flag,1 ; set parse flag | ||
| 219 | |||
| 220 | mov byte ptr p255_ctl+9,0 ; turn this off so we don't allow another | ||
| 221 | mov p255_result.$P_Type,0 ; clear this so we don't get fooled later | ||
| 222 | |||
| 223 | push si ;save regs | ||
| 224 | |||
| 225 | mov si,word ptr p255_result.$P_Picked_Val[+0] | ||
| 226 | |||
| 227 | mov word ptr ds:[si+0],0 | ||
| 228 | |||
| 229 | pop si ;restore regs | ||
| 230 | ; set flags for later code to fill in map_table | ||
| 231 | |||
| 232 | or page_flags,p255_flag ; set p255 flag | ||
| 233 | |||
| 234 | jmp get_args ; go get another argument | ||
| 235 | |||
| 236 | Check_X: | ||
| 237 | cmp es:X_Result.$P_SYNONYM_Ptr,offset es:X_Switch.$P_KeyorSW ; switch Ptr ;an000; dms; | ||
| 238 | je Do_X ; yes, process it | ||
| 239 | jmp get_args ; no, must have been the positional, ignore it and go on | ||
| 240 | |||
| 241 | Do_X: | ||
| 242 | |||
| 243 | push ax ; save regs | ||
| 244 | mov ax,es:word ptr X_Result.$P_Picked_Val ;get low word of result ;an000; dms; | ||
| 245 | mov cs:EMS_Pgs_Parm,ax ; pass to program ;an000; dms; | ||
| 246 | pop ax ; restore regs | ||
| 247 | |||
| 248 | jmp get_args ; go get another argument | ||
| 249 | |||
| 250 | |||
| 251 | |||
| 252 | |||
| 253 | ; getting here means invalid argument, figure out what to do later | ||
| 254 | |||
| 255 | end_of_input_line: | ||
| 256 | |||
| 257 | cmp parse_flag,null ; were there command line args? | ||
| 258 | jne cmd_line_args ; yes, process them | ||
| 259 | jmp null_cmd_line ; no, skip processing | ||
| 260 | |||
| 261 | cmd_line_args: | ||
| 262 | |||
| 263 | ; put the stuff into map_table, this is done by looking at flags set | ||
| 264 | ; by the above code and putting the addresses into map_table | ||
| 265 | |||
| 266 | push ax ; save some regs | ||
| 267 | push bx | ||
| 268 | push cx | ||
| 269 | push dx | ||
| 270 | push di | ||
| 271 | |||
| 272 | xor di,di ; clear index pointer | ||
| 273 | |||
| 274 | mov map_count,null ; clear map count default | ||
| 275 | |||
| 276 | test page_flags,frame_flag ; was FRAME= included? | ||
| 277 | jz chk_p0 ; no, try p0 | ||
| 278 | |||
| 279 | ; yes, fix up page count and fill in map_table | ||
| 280 | |||
| 281 | mov map_count,4 ; FRAME= takes up 4 map entries | ||
| 282 | |||
| 283 | ; convert the item tag into a segment address | ||
| 284 | |||
| 285 | xor ah,ah ; make 0 | ||
| 286 | mov al,frame_result.$P_Item_Tag ; get item tag | ||
| 287 | mov cx,8 ; need to shift left eight bits | ||
| 288 | shl ax,cl ; to convert to a segment address | ||
| 289 | |||
| 290 | ; do some math with di | ||
| 291 | |||
| 292 | xor di,di ; clear index pointer | ||
| 293 | |||
| 294 | ; save the segment addresses in map_table | ||
| 295 | |||
| 296 | mov map_table.phys_page_segment[di],ax ; store p0 segment | ||
| 297 | mov map_table.phys_page_number[di],0 ; p0 page number | ||
| 298 | mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms; | ||
| 299 | ; diags. | ||
| 300 | |||
| 301 | add ax,400h ; increase segment ID by 16K | ||
| 302 | add di,type mappable_phys_page_struct | ||
| 303 | |||
| 304 | mov map_table.phys_page_segment[di],ax ; store p1 segment | ||
| 305 | mov map_table.phys_page_number[di],1 ; p1 page number | ||
| 306 | |||
| 307 | add ax,400h ; increase segment ID by 16K | ||
| 308 | add di,type mappable_phys_page_struct | ||
| 309 | |||
| 310 | mov map_table.phys_page_segment[di],ax ; store p2 segment | ||
| 311 | mov map_table.phys_page_number[di],2 ; p2 page number | ||
| 312 | |||
| 313 | add ax,400h ; increase segment ID by 16K | ||
| 314 | add di,type mappable_phys_page_struct | ||
| 315 | |||
| 316 | mov map_table.phys_page_segment[di],ax ; store p3 segment | ||
| 317 | mov map_table.phys_page_number[di],3 ; p3 page number | ||
| 318 | |||
| 319 | ; do some math with di, this will be used as a pointer into map_table | ||
| 320 | |||
| 321 | add di,type mappable_phys_page_struct | ||
| 322 | |||
| 323 | jmp chk_p254 ; FRAME= implies that p0 - p3 were not present, | ||
| 324 | ; skip ahead and look for p254 and p255 | ||
| 325 | |||
| 326 | ; check for p0 | ||
| 327 | |||
| 328 | chk_p0: | ||
| 329 | |||
| 330 | test page_flags,p0_flag ; was p0= included? | ||
| 331 | jz chk_p1 ; no, try p1 | ||
| 332 | |||
| 333 | ; yes, fix up page count and fill in map_table | ||
| 334 | |||
| 335 | add map_count,1 ; one extra map entry | ||
| 336 | |||
| 337 | ; convert the item tag into a segment address | ||
| 338 | |||
| 339 | xor ah,ah ; make 0 | ||
| 340 | mov al,p0_result.$P_Item_Tag; get item tag | ||
| 341 | mov cx,8 ; need to shift left eight bits | ||
| 342 | shl ax,cl ; to convert to a segment address | ||
| 343 | |||
| 344 | |||
| 345 | ; save the segment addresses in map_table | ||
| 346 | |||
| 347 | mov map_table.phys_page_segment[di],ax ; store p0 segment | ||
| 348 | mov map_table.phys_page_number[di],0 ; p0 page number | ||
| 349 | mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms; | ||
| 350 | ; diags. | ||
| 351 | |||
| 352 | ; do some math with di, this will be used as a pointer into map_table | ||
| 353 | |||
| 354 | add di,type mappable_phys_page_struct | ||
| 355 | |||
| 356 | ;------------------------ | ||
| 357 | ; check for p1 | ||
| 358 | ;------------------------ | ||
| 359 | |||
| 360 | chk_p1: | ||
| 361 | |||
| 362 | test page_flags,p1_flag ; was p1= included? | ||
| 363 | jz chk_p2 ; no, try p2 | ||
| 364 | |||
| 365 | ; yes, fix up page count and fill in map_table | ||
| 366 | |||
| 367 | add map_count,1 ; one extra map entry | ||
| 368 | |||
| 369 | ; convert the item tag into a segment address | ||
| 370 | |||
| 371 | xor ah,ah ; make 0 | ||
| 372 | mov al,p1_result.$P_Item_Tag; get item tag | ||
| 373 | mov cx,8 ; need to shift left eight bits | ||
| 374 | shl ax,cl ; to convert to a segment address | ||
| 375 | |||
| 376 | |||
| 377 | ; save the segment addresses in map_table | ||
| 378 | |||
| 379 | mov map_table.phys_page_segment[di],ax ; store p1 segment | ||
| 380 | mov map_table.phys_page_number[di],1 ; p0 page number | ||
| 381 | mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms; | ||
| 382 | ; diags. | ||
| 383 | |||
| 384 | ; do some math with di, this will be used as a pointer into map_table | ||
| 385 | |||
| 386 | add di,type mappable_phys_page_struct | ||
| 387 | |||
| 388 | ;------------------------ | ||
| 389 | ; check for p2 | ||
| 390 | ;------------------------ | ||
| 391 | |||
| 392 | chk_p2: | ||
| 393 | |||
| 394 | test page_flags,p2_flag ; was p2= included? | ||
| 395 | jz chk_p3 ; no, try p3 | ||
| 396 | |||
| 397 | ; yes, fix up page count and fill in map_table | ||
| 398 | |||
| 399 | add map_count,1 ; one extra map entry | ||
| 400 | |||
| 401 | ; convert the item tag into a segment address | ||
| 402 | |||
| 403 | xor ah,ah ; make 0 | ||
| 404 | mov al,p2_result.$P_Item_Tag; get item tag | ||
| 405 | mov cx,8 ; need to shift left eight bits | ||
| 406 | shl ax,cl ; to convert to a segment address | ||
| 407 | |||
| 408 | |||
| 409 | ; save the segment addresses in map_table | ||
| 410 | |||
| 411 | mov map_table.phys_page_segment[di],ax ; store p2 segment | ||
| 412 | mov map_table.phys_page_number[di],2 ; p2 page number | ||
| 413 | mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms; | ||
| 414 | ; diags. | ||
| 415 | |||
| 416 | ; do some math with di, this will be used as a pointer into map_table | ||
| 417 | |||
| 418 | add di,type mappable_phys_page_struct | ||
| 419 | |||
| 420 | ;------------------------ | ||
| 421 | ; check for p3 | ||
| 422 | ;------------------------ | ||
| 423 | |||
| 424 | chk_p3: | ||
| 425 | |||
| 426 | test page_flags,p3_flag ; was p3= included? | ||
| 427 | jz chk_p254 ; no, try p254 | ||
| 428 | |||
| 429 | ; yes, fix up page count and fill in map_table | ||
| 430 | |||
| 431 | add map_count,1 ; one extra map entry | ||
| 432 | |||
| 433 | ; convert the item tag into a segment address | ||
| 434 | |||
| 435 | xor ah,ah ; make 0 | ||
| 436 | mov al,p3_result.$P_Item_Tag; get item tag | ||
| 437 | mov cx,8 ; need to shift left eight bits | ||
| 438 | shl ax,cl ; to convert to a segment address | ||
| 439 | |||
| 440 | |||
| 441 | ; save the segment addresses in map_table | ||
| 442 | |||
| 443 | mov map_table.phys_page_segment[di],ax ; store p3 segment | ||
| 444 | mov map_table.phys_page_number[di],3 ; p3 page number | ||
| 445 | mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms; | ||
| 446 | ; diags. | ||
| 447 | |||
| 448 | ; do some math with di, this will be used as a pointer into map_table | ||
| 449 | |||
| 450 | add di,type mappable_phys_page_struct | ||
| 451 | |||
| 452 | ;------------------------ | ||
| 453 | ; check for p254 | ||
| 454 | ;------------------------ | ||
| 455 | |||
| 456 | chk_p254: | ||
| 457 | |||
| 458 | test page_flags,p254_flag ; was p254= included? | ||
| 459 | jz chk_p255 ; no, try p255 | ||
| 460 | |||
| 461 | ; yes, fix up page count and fill in map_table | ||
| 462 | |||
| 463 | add map_count,1 ; one extra map entry | ||
| 464 | |||
| 465 | ; convert the item tag into a segment address | ||
| 466 | |||
| 467 | xor ah,ah ; make 0 | ||
| 468 | mov al,p254_result.$P_Item_Tag; get item tag | ||
| 469 | mov cx,8 ; need to shift left eight bits | ||
| 470 | shl ax,cl ; to convert to a segment address | ||
| 471 | |||
| 472 | |||
| 473 | ; save the segment addresses in map_table | ||
| 474 | |||
| 475 | mov map_table.phys_page_segment[di],ax ; store p254 segment | ||
| 476 | mov map_table.phys_page_number[di],0feh ; p254 page number | ||
| 477 | mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms; | ||
| 478 | ; diags. | ||
| 479 | |||
| 480 | ; do some math with di, this will be used as a pointer into map_table | ||
| 481 | |||
| 482 | add di,type mappable_phys_page_struct | ||
| 483 | |||
| 484 | ;------------------------ | ||
| 485 | ; check for p255 | ||
| 486 | ;------------------------ | ||
| 487 | |||
| 488 | chk_p255: | ||
| 489 | |||
| 490 | test page_flags,p255_flag ; was p255= included? | ||
| 491 | jz Chk_X ; no, /X switch | ||
| 492 | |||
| 493 | ; yes, fix up page count and fill in map_table | ||
| 494 | |||
| 495 | add map_count,1 ; one extra map entry | ||
| 496 | |||
| 497 | ; convert the item tag into a segment address | ||
| 498 | |||
| 499 | xor ah,ah ; make 0 | ||
| 500 | mov al,p255_result.$P_Item_Tag; get item tag | ||
| 501 | mov cx,8 ; need to shift left eight bits | ||
| 502 | shl ax,cl ; to convert to a segment address | ||
| 503 | |||
| 504 | |||
| 505 | ; save the segment addresses in map_table | ||
| 506 | |||
| 507 | mov map_table.phys_page_segment[di],ax ; store p255 segment | ||
| 508 | mov map_table.phys_page_number[di],0ffh ; p255 page number | ||
| 509 | mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms; | ||
| 510 | ; diags. | ||
| 511 | |||
| 512 | ; do some math with di, this will be used as a pointer into map_table | ||
| 513 | |||
| 514 | add di,type mappable_phys_page_struct | ||
| 515 | |||
| 516 | Chk_X: | ||
| 517 | |||
| 518 | pop di ; restore some regs | ||
| 519 | pop dx | ||
| 520 | pop cx | ||
| 521 | pop bx | ||
| 522 | pop ax | ||
| 523 | |||
| 524 | |||
| 525 | null_cmd_line: | ||
| 526 | CMP AL,AL ; else set zf to indicate no error | ||
| 527 | ret ; return to calling routine | ||
| 528 | |||
| 529 | |||
| 530 | GET_PARMS ENDP | ||
diff --git a/v4.0/src/DEV/XMA2EMS/PS2_5060.INC b/v4.0/src/DEV/XMA2EMS/PS2_5060.INC new file mode 100644 index 0000000..96425f5 --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/PS2_5060.INC | |||
| @@ -0,0 +1,735 @@ | |||
| 1 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 2 | ;³ Include File: PS2_5060.INC ³ | ||
| 3 | ;³ ³ | ||
| 4 | ;³ Purpose: Initialization code for the Personal Systems/2 ³ | ||
| 5 | ;³ models 50 and 60. ³ | ||
| 6 | ;³ ³ | ||
| 7 | ;³ Returns: INIT_ERR ³ | ||
| 8 | ;³ Flag indicating if an error was detected. ³ | ||
| 9 | ;³ DX = ptr to error message string if error. ³ | ||
| 10 | ;³ ³ | ||
| 11 | ;³ This procedure is called to initialize the XMO and/or XMA/A ³ | ||
| 12 | ;³ card(s) on a PS/2 mod 50 or 60. Any mix of multiple XMA and ³ | ||
| 13 | ;³ XMO cards are supported. The XMA cards will be used in ³ | ||
| 14 | ;³ 'real' mode, meaning the virtual mode ports providing bank ³ | ||
| 15 | ;³ swapping are not used (since this only works on 1 XMA card). ³ | ||
| 16 | ;³ This procedure is not called if WSP's XMA/A device driver ³ | ||
| 17 | ;³ (INDXMAA.SYS) is installed. In this case only the single XMA ³ | ||
| 18 | ;³ card is used for EMS, and it is spoken to in 'virtual' mode. ³ | ||
| 19 | ;³ The procedure searches each adapter slot for the presence of ³ | ||
| 20 | ;³ an XMA or a XMO card by checking the card ID. It checks ³ | ||
| 21 | ;³ the configuration registers on the cards to determine the amount ³ | ||
| 22 | ;³ of memory they contain. ³ | ||
| 23 | ;³ The procedure will then calculate for the /E parameter. This ³ | ||
| 24 | ;³ states how much of the extended memory the user wants for EMS. ³ | ||
| 25 | ;³ Extended memory will come from the top of the address range, ³ | ||
| 26 | ;³ and EMS will come off the bottom (i.e. starting at 1M+384K). ³ | ||
| 27 | ;³ Memory kept as extended has to be marked unusable in the Page ³ | ||
| 28 | ;³ Allocation List. Translate table entries in extended memory ³ | ||
| 29 | ;³ are disabled for memory used for EMS. ³ | ||
| 30 | ;³ Note that the /E parameter is only valid within this ³ | ||
| 31 | ;³ procedure, i.e. for PS/2 mod 50 and 60's. On family 1 machines, ³ | ||
| 32 | ;³ only the XMA 1 card is supported, and it doesn't come up as ³ | ||
| 33 | ;³ extended memory. On mod 50 or 60 with the XMA/A driver, the ³ | ||
| 34 | ;³ driver takes all of the (uppermost) XMA card and resets CMOS. ³ | ||
| 35 | ;³ On the mod 80 with the XMA emulator, this XMA/extended split ³ | ||
| 36 | ;³ must be specified on the Emulator's parm line. ³ | ||
| 37 | ;³ ³ | ||
| 38 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 39 | |||
| 40 | include SYSVAR.INC ;system variables structure ;an007; dms; | ||
| 41 | |||
| 42 | |||
| 43 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 44 | ;³ XMA/A declares ³ | ||
| 45 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 46 | HI6BIT_MASK EQU 00000011b ;Mask for 2 bit bank descriptor | ||
| 47 | LO2BIT_FLIP EQU 00000011b ;Reverses bottom 2 bits in bank des | ||
| 48 | ; gives # of 1/2M in that bank | ||
| 49 | NUM_CONFR_BANKS EQU 3 ;Number of memory banks described | ||
| 50 | ; by the XMA/A config register | ||
| 51 | ; Bank 4 is on the control reg. | ||
| 52 | X_CONF_REG_VAL DB ? ;temporary holder for XMAA's | ||
| 53 | ; config (memory size) register | ||
| 54 | X_CTRL_REG_VAL DB ? ;temporary holder for XMAA's | ||
| 55 | ; control (mem size bank 4) reg. | ||
| 56 | X_BLKS_PER_HALFM DB 128 ;4K blocks per half meg of memory | ||
| 57 | XMAA_NUM_BLOCKS DW ? ;temp for # of 4K blocks on xmaa @RH2 | ||
| 58 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 59 | ;³ Expanded Memory Option (XMO) declares ³ | ||
| 60 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 61 | NUM_CINFO_BANKS EQU 3 ;# of complete memory banks (4-2) | ||
| 62 | ; described by the XMO card info reg | ||
| 63 | ; Bank 1 - hi 1/2 bit - info, lo CC/P | ||
| 64 | H_CARD_INFO_VAL DB ? ;temporary holder for XMO card's | ||
| 65 | ; info (memory size) register | ||
| 66 | H_BLKS_PER_HALFM DB 32 ;16K XMO card blocks per 1/2M of mem | ||
| 67 | HLST_NUM_BLOCKS DW ? ;temp for # of 16K blocks on hlstr @RH3 | ||
| 68 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 69 | ;³ /E option declares ³ | ||
| 70 | ;³ (used to set extended memory) ³ | ||
| 71 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 72 | ems_pgs_parm dw 0 ;temp value for /E parameter | ||
| 73 | e_parm_def equ 0FFFFh ;default...take all for ems | ||
| 74 | MIN_EXTMEM_H EQU (1024+384)/16 ;Translate table pointer for the lowest | ||
| 75 | MIN_EXTMEM_X EQU (1024+384)/4 ; addr extended memory can start at on | ||
| 76 | BASE_MEM EQU 1024 ;Base planer memory ;an007; dms; | ||
| 77 | ; a PS/2 (16K XMO and 4K XMA) | ||
| 78 | PREV_EXT_PGS DW 0 ;Extended memory claimed by previous | ||
| 79 | ; drivers | ||
| 80 | NEEDED_EMS_PGS DW ? ;Pages that will go for EMS use | ||
| 81 | CARDS_PGS DW ? ;Number of pages on card being checked | ||
| 82 | CARD_EXT_S16K DW ? ; and where its extended memory starts | ||
| 83 | ; expressed in 16K blocks | ||
| 84 | |||
| 85 | INIT_MOD_50_60 PROC | ||
| 86 | |||
| 87 | PUSH AX | ||
| 88 | PUSH BX | ||
| 89 | PUSH CX | ||
| 90 | PUSH SI | ||
| 91 | PUSH DI | ||
| 92 | |||
| 93 | MOV INIT_ERR,NO_ERROR ;Initialize error flag @RH4 | ||
| 94 | MOV TOTAL_SYS_PAGES,0 ;Init total number of pages in the @RH2 | ||
| 95 | MOV NUM_MEM_CARDS,0 ; system & # of memory cards found @RH2 | ||
| 96 | XOR DI,DI ;Clear offset into mem card table @RH2 | ||
| 97 | |||
| 98 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 99 | ;³ Search for XMO cards ³ | ||
| 100 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 101 | XOR CX,CX ;Check all system slots starting @RH2 | ||
| 102 | ; at slot 0 RH2 | ||
| 103 | H_SLOT_SCAN: | ||
| 104 | MOV AL,CL ;Enable the specific slot by ORing @RH2 | ||
| 105 | OR AL,SLOT_SETUP ; the slot (bits 0-2) with the @RH2 | ||
| 106 | OUT 96h,AL ; setup flag (bit 3). @RH2 | ||
| 107 | |||
| 108 | MOV DX,CARD_ID_LO ;Read the signature ID of the card @RH2 | ||
| 109 | IN AL,DX ; @RH2 | ||
| 110 | XCHG AL,AH ; @RH2 | ||
| 111 | MOV DX,CARD_ID_HI ; @RH2 | ||
| 112 | IN AL,DX ; @RH2 | ||
| 113 | HLST_CHECK: | ||
| 114 | CMP AX,HLST_CARD_ID ;If it's a XMO card then @RH3 | ||
| 115 | JNE H_NEXT_SLOT ; calculate the amount of memory @RH3 | ||
| 116 | CALL HLST_MEM_ADD ; on the card @RH3 | ||
| 117 | MOV WTT_CARD_SLOT,CL ;Set default slot # and card type @RH5 | ||
| 118 | MOV MEMCARD_MODE,HOLS_REAL ; for single card support @RH5 | ||
| 119 | |||
| 120 | MOV BX,HLST_NUM_BLOCKS ;1 XMO card block = an EMS page | ||
| 121 | |||
| 122 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 123 | ;³ Save info in the memory card table ³ | ||
| 124 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 125 | MOV MEM_CARD_TABLE.CARD_ID[DI],AX ;Save the card ID and @RH5 | ||
| 126 | MOV MEM_CARD_TABLE.CARD_SLOT[DI],CL ; slot # of this card @RH5 | ||
| 127 | MOV AX,TOTAL_SYS_PAGES ;Set # of the 1st EMS @RH5 | ||
| 128 | MOV MEM_CARD_TABLE.START_PG_NUM[DI],AX ; page this card maps @RH5 | ||
| 129 | ADD AX,BX ;Last page mapped = @RH5 | ||
| 130 | DEC AX ; 1st pg + pages on @RH5 | ||
| 131 | MOV MEM_CARD_TABLE.END_PG_NUM[DI],AX ; this card - 1. @RH5 | ||
| 132 | |||
| 133 | ADD TOTAL_SYS_PAGES,BX ;Add card's pgs to tot. @RH5 | ||
| 134 | INC NUM_MEM_CARDS ;Inc # of cards found @RH5 | ||
| 135 | ADD DI,TYPE MEM_CARD_STRUC ;Next entry in card @RH5 | ||
| 136 | ; descriptor table RH5 | ||
| 137 | |||
| 138 | H_NEXT_SLOT: | ||
| 139 | INC CL ;Check next adapter slot @RH2 | ||
| 140 | CMP CL,NUM_OF_SLOTS ;Is it <= system slots? @RH2 | ||
| 141 | JB H_SLOT_SCAN ;Yes..check next slot ;ac000; dms; | ||
| 142 | ;No fall through loop RH2 | ||
| 143 | |||
| 144 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 145 | ;³ Search for XMA/A cards ³ | ||
| 146 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 147 | XOR CX,CX ;Check all slots starting at 0 @RH2 | ||
| 148 | X_SLOT_SCAN: | ||
| 149 | MOV AL,CL ;Enable the specific slot by ORing @RH2 | ||
| 150 | OR AL,SLOT_SETUP ; the slot (bits 0-2) with the @RH2 | ||
| 151 | OUT 96h,AL ; setup flag (bit 3). @RH2 | ||
| 152 | |||
| 153 | MOV DX,CARD_ID_LO ;Read the signature ID of the card @RH2 | ||
| 154 | IN AL,DX ; @RH2 | ||
| 155 | XCHG AL,AH ; @RH2 | ||
| 156 | MOV DX,CARD_ID_HI ; @RH2 | ||
| 157 | IN AL,DX ; @RH2 | ||
| 158 | XMAA_CHECK: | ||
| 159 | CMP AX,XMAA_CARD_ID ;If it's an XMA/A card then @RH2 | ||
| 160 | JNE X_NEXT_SLOT ; calculate the amount of memory @RH2 | ||
| 161 | CALL XMAA_MEM_ADD ; on the card @RH2 | ||
| 162 | MOV WTT_CARD_SLOT,CL ;Set default slot # and card type @RH5 | ||
| 163 | MOV MEMCARD_MODE,XMAA_REAL ; for single card support @RH5 | ||
| 164 | |||
| 165 | MOV BX,XMAA_NUM_BLOCKS ;Divide the # of 4K XMA/A blocks @RH2 | ||
| 166 | SHR BX,1 ; by 4 to get number or 16K EMS @RH2 | ||
| 167 | SHR BX,1 ; pages on this card @RH2 | ||
| 168 | |||
| 169 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 170 | ;³ Save info in the memory card table ³ | ||
| 171 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 172 | MOV MEM_CARD_TABLE.CARD_ID[DI],AX ;Save the card ID and @RH5 | ||
| 173 | MOV MEM_CARD_TABLE.CARD_SLOT[DI],CL ; slot # of this card @RH5 | ||
| 174 | MOV AX,TOTAL_SYS_PAGES ;Set # of the 1st EMS @RH5 | ||
| 175 | MOV MEM_CARD_TABLE.START_PG_NUM[DI],AX ; page this card maps @RH5 | ||
| 176 | ADD AX,BX ;Last page mapped = @RH5 | ||
| 177 | DEC AX ; 1st pg + pages on @RH5 | ||
| 178 | MOV MEM_CARD_TABLE.END_PG_NUM[DI],AX ; this card - 1. @RH5 | ||
| 179 | |||
| 180 | ADD TOTAL_SYS_PAGES,BX ;Add card's pgs to tot. @RH5 | ||
| 181 | INC NUM_MEM_CARDS ;Inc # of cards found @RH5 | ||
| 182 | ADD DI,TYPE MEM_CARD_STRUC ;Next entry in card @RH5 | ||
| 183 | ; descriptor table RH5 | ||
| 184 | |||
| 185 | X_NEXT_SLOT: | ||
| 186 | INC CL ;Check next adapter slot @RH2 | ||
| 187 | CMP CL,NUM_OF_SLOTS ;Is it <= system slots? @RH2 | ||
| 188 | JB X_SLOT_SCAN ;Yes..check next slot ;ac000; dms; | ||
| 189 | ;No fall through loop RH2 | ||
| 190 | |||
| 191 | CMP TOTAL_SYS_PAGES,0 ;If one or more cards are found @RH4 | ||
| 192 | JA CALC_EXTENDED ; then everythang's cool so far @RH4 | ||
| 193 | MOV INIT_ERR,ERROR ;Else no card...set @RH4 | ||
| 194 | MOV DX,OFFSET NOT_FOUND_MSG ; 1st part of error msg @RH4 | ||
| 195 | JMP INIT_50_60_RET ; for no card found @RH4 | ||
| 196 | |||
| 197 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 198 | ;³ Calculate /E parameter - amount of memory for EMS ³ | ||
| 199 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 200 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 201 | ;³ Find ext mem addr of bottom card ³ | ||
| 202 | ;³ in case card memory ever starts at ³ | ||
| 203 | ;³ something other than 1M + 384K ³ | ||
| 204 | ;³ (i.e. if more planar memory is ³ | ||
| 205 | ;³ added or a new unsupported card ³ | ||
| 206 | ;³ comes in below XMO card) ³ | ||
| 207 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 208 | CALC_EXTENDED: | ||
| 209 | push es ;this call kills these regs ;an007; dms; | ||
| 210 | push bx ; ;an007; dms; | ||
| 211 | |||
| 212 | mov ah,52h ;get the sysvars ptr ;an007; dms; | ||
| 213 | int 21h ; to get total ext. memory at boot ;an007; dms; | ||
| 214 | mov ax,word ptr es:[bx].SYSI_Ext_Mem ; ;an007; dms; | ||
| 215 | |||
| 216 | pop bx ;restore regs ;an007; dms; | ||
| 217 | pop es ; ;an007; dms; | ||
| 218 | |||
| 219 | add ax,Base_Mem ; + base memory ;an007; dms; | ||
| 220 | MOV CL,4 ; convert to 16Kb pages ;an007; dms; | ||
| 221 | SHR AX,CL ; ;an007; dms; | ||
| 222 | sub ax,cs:Total_Sys_Pages ;get page where card begins ;an007; dms; | ||
| 223 | |||
| 224 | xor di,di ;init. index value ;an008; dms | ||
| 225 | CMP MEM_CARD_TABLE.CARD_ID[DI],HLST_CARD_ID ;If 1st card holst @RH4 | ||
| 226 | JE FIND_H_1ST_TT ; then get hlst TT @RH4 | ||
| 227 | FIND_X_1ST_TT: ;XMAA is 1st card (lowest ext mem) @RH4 | ||
| 228 | ;;;;; MOV AX,MIN_EXTMEM_X ;Set XMAA TT ptr at 1.384M and @RH4 | ||
| 229 | shl ax,1 ; ;an000; dms; | ||
| 230 | shl ax,1 ; ;an000; dms; | ||
| 231 | FIND_X_1ST_LOOP: ; search for start of ext mem @RH4 | ||
| 232 | CALL X_READ_TT ;Read trans tbl data at this addr @RH4 | ||
| 233 | CMP BX,XMA_TT_INHIBIT ;If not inhibitted then mem here. @RH4 | ||
| 234 | JE FIND_X_1ST_NEXT ;Divide the 4K translate table ptr @RH4 | ||
| 235 | MOV CL,2 ; by 4 to convert it to 16K format @RH4 | ||
| 236 | SHR AX,CL ; AX = start of ext mem (in 16K) @RH4 | ||
| 237 | JMP FIRST_EXT_FOUND ; @RH4 | ||
| 238 | FIND_X_1ST_NEXT: ; @RH4 | ||
| 239 | INC AX ;Else no mem...inc TT ptr and see @RH4 | ||
| 240 | JMP FIND_X_1ST_LOOP ; if ext mem starts at next 4K @RH4 | ||
| 241 | |||
| 242 | FIND_H_1ST_TT: ;XMO is 1st card (lowest ext mem) @RH4 | ||
| 243 | ;;;;; MOV AX,MIN_EXTMEM_H ;Set hlst TT ptr at 1.384M and @RH4 | ||
| 244 | FIND_H_1ST_LOOP: ; search for start of ext mem @RH4 | ||
| 245 | CALL H_READ_TT ;Read trans tbl data at this addr @RH4 | ||
| 246 | CMP BL,H_TT_INHIBIT ;If not inhibitted then mem here. @RH4 | ||
| 247 | JNE FIRST_EXT_FOUND ; found start of card ext mem @RH4 | ||
| 248 | INC AX ;Else no mem...inc TT ptr and see @RH4 | ||
| 249 | JMP FIND_H_1ST_LOOP ; if ext mem starts at next 16K @RH4 | ||
| 250 | FIRST_EXT_FOUND: | ||
| 251 | MOV CARD_EXT_S16K,AX ;Save the start of ext mem ptr @RH4 | ||
| 252 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 253 | ;³ Calc pages for extended memory ³ | ||
| 254 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 255 | MOV AH,88H ;Go to BIOS and find amount of @RH4 | ||
| 256 | INT 15H ; extended memory (assume previous @RH4 | ||
| 257 | MOV CL,4 ; drivers have hooked INT 15h) @RH4 | ||
| 258 | SHR AX,CL ;Get # of 16k pages @RH4 | ||
| 259 | |||
| 260 | MOV BX,CARD_EXT_S16K ;Pages of extended memory used @RH4 | ||
| 261 | ADD BX,TOTAL_SYS_PAGES ; by previous drivers = @RH4 | ||
| 262 | SUB BX,1024/16 ; what we know is the # of ext @RH4 | ||
| 263 | SUB BX,AX ; pages minus what BIOS tells us @RH4 | ||
| 264 | MOV PREV_EXT_PGS,BX ; @RH4 | ||
| 265 | |||
| 266 | CMP EMS_PGS_PARM,E_PARM_DEF ;If no /E parm specified then @RH4 | ||
| 267 | JNE CHECK_E_PARM ; use the remaining pages for EMS @RH4 | ||
| 268 | MOV AX,TOTAL_SYS_PAGES ; (total on cards minus previously @RH4 | ||
| 269 | cmp Prev_Ext_Pgs,ax ;Previous ext pages >= avail on cards? ;an000; dms; | ||
| 270 | jae Default_Mem_Err_Exit ;yes - we have used the whole card ;an000; dms; | ||
| 271 | SUB AX,PREV_EXT_PGS ; used for extended memory) @RH4 | ||
| 272 | MOV NEEDED_EMS_PGS,AX ;Set counter for marking PAL and TT@RH4 | ||
| 273 | JMP SHORT MARK_EXT_IN_PAL | ||
| 274 | |||
| 275 | Default_Mem_Err_Exit: | ||
| 276 | |||
| 277 | mov Init_Err,Error ;flag an error occurred ;an000; dms; | ||
| 278 | lea dx,No_EMS_Memory ;no memory on cards left ;an000; dms; | ||
| 279 | jmp Init_50_60_Ret ;exit routine ;an000; dms; | ||
| 280 | |||
| 281 | CHECK_E_PARM: ;Else test user specified # EMS pgs@RH4 | ||
| 282 | MOV BX,EMS_PGS_PARM ;Set counter for marking Page @RH4 | ||
| 283 | MOV NEEDED_EMS_PGS,BX ; Allocation List and TT entries @RH4 | ||
| 284 | MOV AX,TOTAL_SYS_PAGES ;If the requested EMS pages are @RH4 | ||
| 285 | SUB AX,PREV_EXT_PGS ; more than what's left @RH4 | ||
| 286 | CMP AX,EMS_PGS_PARM ; (total pages minus pages @RH4 | ||
| 287 | JGE MARK_EXT_IN_PAL ; used by other drivers) then set @RH4 | ||
| 288 | MOV INIT_ERR,ERROR ; an error condition flag @RH4 | ||
| 289 | LEA DX,REQ_EMS_ERR_MSG ; Set first part of error message @RH4 | ||
| 290 | JMP INIT_50_60_RET ; @RH4 | ||
| 291 | |||
| 292 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 293 | ;³ Mark PAL for extended memory pages ³ | ||
| 294 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 295 | MARK_EXT_IN_PAL: | ||
| 296 | xor di,di ;start at bottom of PAL to init EXT ;an002; dms; | ||
| 297 | MARK_NEW_IN_PAL: | ||
| 298 | MOV CX,TOTAL_SYS_PAGES ;Loop for the 'new' extended pages @RH4 | ||
| 299 | SUB CX,NEEDED_EMS_PGS ; (left over from /E parm and not @RH4 | ||
| 300 | SUB CX,PREV_EXT_PGS ; reserved by a previous driver) @RH4 | ||
| 301 | MOV RESR_EXT_PGS,CX ; @RH4 | ||
| 302 | CMP CX,0 ; This assumes that others anyone @RH4 | ||
| 303 | JE MARK_PREV_IN_PAL ; using extended memory after us @RH4 | ||
| 304 | MARK_NEW_LP: ; will take it from the top @RH4 | ||
| 305 | MOV PAGE_ALLOC_LIST[DI],RESR_EXT ;Place a 'RE' in the PAL @RH4 | ||
| 306 | ADD DI,TYPE PAGE_ALLOC_LIST ; (Reserved Extended) for @RH4 | ||
| 307 | LOOP MARK_NEW_LP ; these entries @RH4 | ||
| 308 | |||
| 309 | MARK_PREV_IN_PAL: | ||
| 310 | MOV AX,NEEDED_EMS_PGS ;Set offset into Page Alloc List @RH4 | ||
| 311 | add ax,Resr_Ext_Pgs ;get end of area for EMS pages ;an002; dms; | ||
| 312 | MOV DX,TYPE PAGE_ALLOC_LIST ; for the page where extended mem @RH4 | ||
| 313 | MUL DX ; starts. This is done by skipping@RH4 | ||
| 314 | MOV DI,AX ; over the EMS pages on bottom @RH4 | ||
| 315 | MOV CX,PREV_EXT_PGS ;Loop for the previous extended @RH4 | ||
| 316 | CMP CX,0 ; memory pages (if any). This is @RH4 | ||
| 317 | JE DIS_EMS_TT ; ext mem claimed before we load @RH4 | ||
| 318 | MARK_PREV_LP: ; @RH4 | ||
| 319 | MOV PAGE_ALLOC_LIST[DI],PREV_EXT ;Place a 'PE' in the PAL @RH4 | ||
| 320 | ADD DI,TYPE PAGE_ALLOC_LIST ; (Previous Extended) for @RH4 | ||
| 321 | LOOP MARK_PREV_LP ; these entries @RH4 | ||
| 322 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 323 | ;³ Disable translate table entries ³ | ||
| 324 | ;³ in extended memory for memory ³ | ||
| 325 | ;³ used as EMS ³ | ||
| 326 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 327 | |||
| 328 | DIS_EMS_TT: | ||
| 329 | |||
| 330 | mov cx,Resr_Ext_Pgs ;get extended page count ;ac008; dms; | ||
| 331 | ;1 based page count | ||
| 332 | |||
| 333 | xor di,di ;set mem card table ptr ;an002; dms; | ||
| 334 | |||
| 335 | Card_Find_Chk: | ||
| 336 | |||
| 337 | cmp cx,Mem_Card_Table.End_Pg_Num[di];page > ending page on card? ;ac008; dms; | ||
| 338 | ja Card_Find_Loop ;yes - next card please ;an002; dms; | ||
| 339 | add Card_Ext_S16K,cx ;get 1st. avail page ;an008; dms; | ||
| 340 | mov cx,Mem_Card_Table.End_Pg_Num[di];Calc # pages remaining on card ;an002; dms; | ||
| 341 | sub cx,Resr_Ext_Pgs ; ;ac008; dms; | ||
| 342 | inc cx ; ;an002; dms; | ||
| 343 | jmp Calc_Cards_EMS ; ;an002; dms; | ||
| 344 | |||
| 345 | Card_Find_Loop: | ||
| 346 | |||
| 347 | add di,Type Mem_Card_Struc ;next pointer ;an002; dms; | ||
| 348 | jmp Card_Find_Chk ;continue loop ;an002; dms; | ||
| 349 | |||
| 350 | |||
| 351 | CALC_CARDS_EMS: | ||
| 352 | |||
| 353 | MOV CARDS_PGS,CX ; @RH4 | ||
| 354 | |||
| 355 | ;Calc # of pages to inhibit for. @RH4 | ||
| 356 | CMP CX,NEEDED_EMS_PGS ;If the card has less pgs than @RH4 | ||
| 357 | JBE ADJUST_NEEDED_EMS ; # needed for EMS then just loop @RH4 | ||
| 358 | MOV CX,NEEDED_EMS_PGS ; for card. Else loop for needed. @RH4 | ||
| 359 | |||
| 360 | ADJUST_NEEDED_EMS: | ||
| 361 | SUB NEEDED_EMS_PGS,CX ;Remaining EMS pages to inhibit @RH4 | ||
| 362 | ; after this card is taken care of @RH4 | ||
| 363 | |||
| 364 | MOV AL,MEM_CARD_TABLE.CARD_SLOT[DI] ;Activate the slot of @RH4 | ||
| 365 | OR AL,SLOT_SETUP ; the card and set ptr @RH4 | ||
| 366 | OUT 96h,AL ; to where it's ext mem @RH4 | ||
| 367 | MOV AX,CARD_EXT_S16K ; starts @RH4 | ||
| 368 | |||
| 369 | CMP MEM_CARD_TABLE.CARD_ID[DI],HLST_CARD_ID ;Test card type @RH4 | ||
| 370 | JE H_INHIBIT_EMS ; @RH4 | ||
| 371 | X_INHIBIT_EMS: ;Inhibit TT on XMA/A for EMS @RH4 | ||
| 372 | PUSH CX ;Save ctr for # EMS on this card @RH4 | ||
| 373 | MOV CL,2 ;Convert 16K start of EMS ptr to @RH4 | ||
| 374 | SHL AX,CL ; 4K XMA/A translate table format @RH4 | ||
| 375 | POP CX ;Restore # EMS pages counter @RH4 | ||
| 376 | X_INH_EMS_PGS: ;----Loop for all XMA EMS pages----@RH4 | ||
| 377 | PUSH CX ;Save # EMS pages ctr @RH4 | ||
| 378 | MOV CX,BLOCKS_PER_PAGE ;Loop for all XMA blocks in a pg @RH4 | ||
| 379 | X_INH_ONE_PAGE: ;----Loop for one XMA EMS page-----@RH4 | ||
| 380 | CALL X_INH_FOR_EMS ;Inhibit TT entry (AX = 4K ptr) @RH4 | ||
| 381 | INC AX ;Next XMA block @RH4 | ||
| 382 | LOOP X_INH_ONE_PAGE ; @RH4 | ||
| 383 | POP CX ;Restore ctr for # EMS pgs on card @RH4 | ||
| 384 | LOOP X_INH_EMS_PGS ;Loop for # EMS pgs on card @RH4 | ||
| 385 | JMP short next_card_ems ;Now go fix that page alloc table @RH4 | ||
| 386 | |||
| 387 | H_INHIBIT_EMS: ;Inhibit TT on XMO for EMS @RH4 | ||
| 388 | CALL H_INH_FOR_EMS ;Inhibit one TT entry per EMS page @RH4 | ||
| 389 | INC AX ;Next 16K pointer @RH4 | ||
| 390 | LOOP H_INHIBIT_EMS ; and do it again yahoooooo @RH4 | ||
| 391 | |||
| 392 | NEXT_CARD_EMS: | ||
| 393 | CMP NEEDED_EMS_PGS,0 ;If this card had the rest of the @RH4 | ||
| 394 | JE INIT_50_60_RET ; EMS pages then done disabling TT @RH4 | ||
| 395 | ;Else EMS on next card. Set ptr @RH4 | ||
| 396 | MOV AX,CARDS_PGS ; to where next card's ext mem @RH4 | ||
| 397 | ADD CARD_EXT_S16K,AX ; starts (in units of 16K) and save@RH4 | ||
| 398 | |||
| 399 | ADD DI,TYPE MEM_CARD_STRUC ;Next entry in the memory card @RH4 | ||
| 400 | |||
| 401 | mov cx,Mem_Card_Table.End_Pg_Num[di] ;calc pages on ;an002; dms; | ||
| 402 | sub cx,Mem_Card_Table.Start_Pg_Num[di] ;card ;an002; dms; | ||
| 403 | inc cx ; ;an002; dms; | ||
| 404 | |||
| 405 | JMP CALC_CARDS_EMS ; table. @RH4 | ||
| 406 | |||
| 407 | INIT_50_60_RET: | ||
| 408 | |||
| 409 | MOV AX,TOTAL_SYS_PAGES ;Total EMS pages in the system = @RH4 | ||
| 410 | SUB AX,PREV_EXT_PGS ; pages on cards - amount used @RH4 | ||
| 411 | SUB AX,RESR_EXT_PGS ; as extended memory @RH4 | ||
| 412 | MOV TOTAL_SYS_PAGES,AX ;Initialize values for: @RH4 | ||
| 413 | MOV TOTAL_EMS_PAGES,AX ; EMS pages - pages to back planar @RH4 | ||
| 414 | MOV FREE_PAGES,AX ; EMS pages free for applications @RH4 | ||
| 415 | |||
| 416 | MOV AL,0 ;Reset the slot ID @RH5 | ||
| 417 | OUT 96h,AL ; @RH5 | ||
| 418 | |||
| 419 | POP DI | ||
| 420 | POP SI | ||
| 421 | POP CX | ||
| 422 | POP BX | ||
| 423 | POP AX | ||
| 424 | RET | ||
| 425 | INIT_MOD_50_60 ENDP | ||
| 426 | |||
| 427 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 428 | ;³ HLST_MEM_ADD subprocedure ³ | ||
| 429 | ;³ Calculates the amount of memory on the XMO card ³ | ||
| 430 | ;³ on entry: (CL) = card slot # ³ | ||
| 431 | ;³ card is in setup mode ³ | ||
| 432 | ;³ ³ | ||
| 433 | ;³ The following describes how to read memory size, where the 2 bit ³ | ||
| 434 | ;³ pattern indicates SIP size. There are 2 SIPs per bank. ³ | ||
| 435 | ;³ ³ | ||
| 436 | ;³ Reg: Card Info Channel Check, Presence ³ | ||
| 437 | ;³ Port: 102h 105h ³ | ||
| 438 | ;³ SIPS: bank 4 bank 3 bank 2 bank 1 bank 1 ³ | ||
| 439 | ;³ Bit: 7 6 5 4 3 2 1 0 ³ | ||
| 440 | ;³ -----------------------------------------------------------------³ | ||
| 441 | ;³ 1 1 1 1 1 1 1 1 No memory,error ³ | ||
| 442 | ;³ 1 0 1 0 1 0 1 0 256K ³ | ||
| 443 | ;³ 0 1 0 1 0 1 0 1 512K ³ | ||
| 444 | ;³ 0 0 0 0 0 0 0 0 1M ³ | ||
| 445 | ;³ ³ | ||
| 446 | ;³ Note that for bank 0, 102's bit 1 forms the upper bit and ³ | ||
| 447 | ;³ 105's bit 0 forms the lower of the 2 bit presence pattern. ³ | ||
| 448 | ;³ Therefore, if the pattern is '10'B, then the bank has 256K. ³ | ||
| 449 | ;³ ³ | ||
| 450 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 451 | HLST_MEM_ADD PROC | ||
| 452 | PUSH DX ; @RH3 | ||
| 453 | PUSH CX ; @RH3 | ||
| 454 | PUSH AX ; @RH3 | ||
| 455 | |||
| 456 | MOV HLST_NUM_BLOCKS,0 ;Init # of 16K blocks on card @RH3 | ||
| 457 | |||
| 458 | MOV DX,H_CARD_INFO ;Read & store card info reg (102h) @RH3 | ||
| 459 | IN AL,DX ; bits 7-2 describe banks 4-2 @RH3 | ||
| 460 | AND AL,11111110B ; bit 1 upper half of bank 1 descr @RH3 | ||
| 461 | MOV H_CARD_INFO_VAL,AL ; (don't care about sleep bit 0) @RH3 | ||
| 462 | MOV DX,H_CC_PRES ;Read chan. check & presence (105) @RH3 | ||
| 463 | IN AL,DX ; for bit 0 - lower half of bank 1 @RH3 | ||
| 464 | AND AL,00000001B ; Turn off all other bits @RH3 | ||
| 465 | OR AL,H_CARD_INFO_VAL ;Join 2 bits - bank 1 descriptor @RH3 | ||
| 466 | |||
| 467 | XOR AL,LO2BIT_FLIP ;Flip these 2 to get # of 1/2 Megs @RH3 | ||
| 468 | ; in bank 1 of XMO card @RH3 | ||
| 469 | AND AL,HI6BIT_MASK ;Clear other bits @RH3 | ||
| 470 | CMP AL,LO2BIT_FLIP ;Are both bits on (i.e. 1M sips)? @RH3 | ||
| 471 | JNE H_B1_HMEG_OK ;No # of 1/2 M for bank OK (0,1,2)@RH3 | ||
| 472 | INC AL ;Yes # of 1/2 M should be 4 not 3 @RH3 | ||
| 473 | H_B1_HMEG_OK: | ||
| 474 | MUL H_BLKS_PER_HALFM ;Multiply by # of 16k Blocks per @RH3 | ||
| 475 | ; half meg to get bank's blocks @RH3 | ||
| 476 | ADD HLST_NUM_BLOCKS,AX ;Add bank 1 to the total @RH3 | ||
| 477 | |||
| 478 | SHR H_CARD_INFO_VAL,1 ;Shift bank 4-2 descriptors to @RH3 | ||
| 479 | SHR H_CARD_INFO_VAL,1 ; bits 0-5 @RH3 | ||
| 480 | |||
| 481 | MOV CX,NUM_CINFO_BANKS ; Loop for banks accounted for by @RH3 | ||
| 482 | ; the XMO card info register @RH3 | ||
| 483 | HLST_MEM_LOOP: | ||
| 484 | MOV AL,H_CARD_INFO_VAL ;Get 2 bit bank descriptor & flip @RH3 | ||
| 485 | XOR AL,LO2BIT_FLIP ; the 2 bits. Bits now indicate @RH3 | ||
| 486 | ; the # of 1/2 meg in the bank @RH3 | ||
| 487 | AND AL,HI6BIT_MASK ;Ignore other banks @RH3 | ||
| 488 | CMP AL,LO2BIT_FLIP ;Are both bits on (i.e. 1M sips)? @RH3 | ||
| 489 | JNE H_B42_HMEG_OK ;No # of 1/2 M for bank OK (0,1,2)@RH3 | ||
| 490 | INC AL ;Yes # of 1/2 M should be 4 not 3 @RH3 | ||
| 491 | H_B42_HMEG_OK: | ||
| 492 | MUL H_BLKS_PER_HALFM ;Multiply by # of 4k blocks per @RH3 | ||
| 493 | ; half meg to get bank's blocks @RH3 | ||
| 494 | ADD HLST_NUM_BLOCKS,AX ;Add XMO banks 4-2 to total @RH3 | ||
| 495 | SHR H_CARD_INFO_VAL,1 ;Get next bank @RH3 | ||
| 496 | SHR H_CARD_INFO_VAL,1 ; @RH3 | ||
| 497 | LOOP HLST_MEM_LOOP ; @RH3 | ||
| 498 | |||
| 499 | POP AX ; @RH3 | ||
| 500 | POP CX ; @RH3 | ||
| 501 | POP DX ; @RH3 | ||
| 502 | |||
| 503 | RET | ||
| 504 | HLST_MEM_ADD ENDP | ||
| 505 | |||
| 506 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 507 | ;³ XMAA_MEM_ADD subprocedure ³ | ||
| 508 | ;³ Calculates the amount of memory on the XMAA card ³ | ||
| 509 | ;³ on entry: (CL) = card slot # ³ | ||
| 510 | ;³ card is in setup mode ³ | ||
| 511 | ;³ ³ | ||
| 512 | ;³ The following describes how to read memory size, where the 2 bit ³ | ||
| 513 | ;³ pattern indicates SIP size. There are 2 SIPs per bank. ³ | ||
| 514 | ;³ ³ | ||
| 515 | ;³ Reg: Control Reg Config, Channel Check reg ³ | ||
| 516 | ;³ Port: 102h 105h ³ | ||
| 517 | ;³ SIPS: bank 4 bank 3 bank 2 bank 1 ³ | ||
| 518 | ;³ Bit: 7 6 5 4 3 2 1 0 ³ | ||
| 519 | ;³ ------------------------------------------------- ³ | ||
| 520 | ;³ 1 1 1 1 1 1 1 1 No memory or error ³ | ||
| 521 | ;³ 1 0 1 0 1 0 1 0 256K ³ | ||
| 522 | ;³ 0 1 0 1 0 1 0 1 512K ³ | ||
| 523 | ;³ 0 0 0 0 0 0 0 0 1M ³ | ||
| 524 | ;³ ³ | ||
| 525 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 526 | XMAA_MEM_ADD PROC | ||
| 527 | PUSH DX ; @RH2 | ||
| 528 | PUSH CX ; @RH2 | ||
| 529 | PUSH AX ; @RH2 | ||
| 530 | |||
| 531 | ;Insure XMA/A init ROM is disabled @RH2 | ||
| 532 | ;When the high byte of the TT data @RH2 | ||
| 533 | MOV DX,X_CTRL_REG | ||
| 534 | IN AL,DX ; is read or written using port @RH2 | ||
| 535 | MOV X_CTRL_REG_VAL,AL ; SAVE FOR MEM COUNT | ||
| 536 | AND AL,CR_ROMSLEEP_DIS ; 104h (real mode), the upper @RH2 | ||
| 537 | OUT DX,AL ; nibble has info for setting the @RH2 | ||
| 538 | ; initialization ROM addresses. To @RH2 | ||
| 539 | ; insure this causes no problems, @RH2 | ||
| 540 | ; disable XMA/A ROM by clearing @RH2 | ||
| 541 | ; ROM sleep bit in the control reg @RH2 | ||
| 542 | |||
| 543 | MOV XMAA_NUM_BLOCKS,0 ; @RH2 | ||
| 544 | |||
| 545 | MOV AL,X_CTRL_REG_VAL ;Get bits 6&7 of control register @RH2 | ||
| 546 | MOV CL,6 ; to get memory configuration of @RH2 | ||
| 547 | SHR AL,CL ; bank 4 @RH2 | ||
| 548 | XOR AL,LO2BIT_FLIP ;Flip these 2 to get # of 1/2M @RH2 | ||
| 549 | ; in bank 4 of XMA/A card @RH2 | ||
| 550 | AND AL,HI6BIT_MASK ;Clear other bits @RH2 | ||
| 551 | CMP AL,LO2BIT_FLIP ;Are both bits on (i.e. 1M sips)? @RH2 | ||
| 552 | JNE CTRL_HMEG_OK ;No # of 1/2 M for bank OK (0,1,2)@RH2 | ||
| 553 | INC AL ;Yes # of 1/2 M should be 4 not 3 @RH2 | ||
| 554 | CTRL_HMEG_OK: | ||
| 555 | MUL X_BLKS_PER_HALFM ;Multiply by # of 4k blocks per @RH2 | ||
| 556 | ; half meg to get bank's blocks @RH2 | ||
| 557 | ADD XMAA_NUM_BLOCKS,AX | ||
| 558 | |||
| 559 | |||
| 560 | MOV DX,X_CONF_REG ;Read the config, channel check @RH2 | ||
| 561 | IN AL,DX ; register to get mem size of @RH2 | ||
| 562 | MOV X_CONF_REG_VAL,AL ; banks 1-3 @RH2 | ||
| 563 | |||
| 564 | MOV CX,NUM_CONFR_BANKS ; Loop for banks accounted for by @RH2 | ||
| 565 | ; the config register @RH2 | ||
| 566 | XMAA_MEM_LOOP: | ||
| 567 | MOV AL,X_CONF_REG_VAL ;Get 2 bit bank descriptor & flip @RH2 | ||
| 568 | XOR AL,LO2BIT_FLIP ; the 2 bits. Bits now indicate @RH2 | ||
| 569 | ; the # of 1/2 meg in the bank @RH2 | ||
| 570 | AND AL,HI6BIT_MASK ;Ignore other banks @RH2 | ||
| 571 | CMP AL,LO2BIT_FLIP ;Are both bits on (i.e. 1M sips)? @RH2 | ||
| 572 | JNE CONF_HMEG_OK ;No # of 1/2 M for bank OK (0,1,2)@RH2 | ||
| 573 | INC AL ;Yes # of 1/2 M should be 4 not 3 @RH2 | ||
| 574 | CONF_HMEG_OK: | ||
| 575 | MUL X_BLKS_PER_HALFM ;Multiply by # of 4k blocks per @RH2 | ||
| 576 | ; half meg to get bank's blocks @RH2 | ||
| 577 | ADD XMAA_NUM_BLOCKS,AX ; @RH2 | ||
| 578 | SHR X_CONF_REG_VAL,1 ;Get next bank @RH2 | ||
| 579 | SHR X_CONF_REG_VAL,1 ; @RH2 | ||
| 580 | LOOP XMAA_MEM_LOOP ; @RH2 | ||
| 581 | |||
| 582 | POP AX ; @RH2 | ||
| 583 | POP CX ; @RH2 | ||
| 584 | POP DX ; @RH2 | ||
| 585 | |||
| 586 | RET | ||
| 587 | XMAA_MEM_ADD ENDP | ||
| 588 | |||
| 589 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 590 | ;³ H_READ_TT subprocedure ³ | ||
| 591 | ;³ Reads the contents of a translate table entry on a XMO card ³ | ||
| 592 | ;³ on entry: (AX) = Translate table pointer ³ | ||
| 593 | ;³ on exit: (BL) = Data (byte) at that entry ³ | ||
| 594 | ;³ ³ | ||
| 595 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 596 | H_READ_TT PROC | ||
| 597 | PUSH AX ;Save the TT pointer @RH4 | ||
| 598 | MOV DX,H_TTPTR_LO ;Set the low and high bytes of @RH4 | ||
| 599 | OUT DX,AL ; the XMO translate table @RH4 | ||
| 600 | XCHG AL,AH ; pointer, then read the value @RH4 | ||
| 601 | MOV DX,H_TTPTR_HI ; of the data for that entry @RH4 | ||
| 602 | OUT DX,AL ; @RH4 | ||
| 603 | MOV DX,H_TTDATA ; @RH4 | ||
| 604 | IN AL,DX ;Read the data into AL @RH4 | ||
| 605 | MOV BL,AL ; and store it in BL @RH4 | ||
| 606 | POP AX ;Restore TT pointer @RH4 | ||
| 607 | RET ; @RH4 | ||
| 608 | H_READ_TT ENDP | ||
| 609 | |||
| 610 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 611 | ;³ X_READ_TT subprocedure ³ | ||
| 612 | ;³ Reads the contents of a translate table entry on an XMA/A card ³ | ||
| 613 | ;³ on entry: (AX) = Translate table pointer ³ | ||
| 614 | ;³ on exit: (BX) = Data (12 bits) at that entry ³ | ||
| 615 | ;³ ³ | ||
| 616 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 617 | X_READ_TT PROC | ||
| 618 | PUSH AX ;Save the TT pointer @RH4 | ||
| 619 | MOV DX,RM_TTPTR_LO ;Set the low and high bytes of @RH4 | ||
| 620 | OUT DX,AL ; the XMA/A translate table @RH4 | ||
| 621 | XCHG AL,AH ; pointer, then read the value @RH4 | ||
| 622 | MOV DX,RM_TTPTR_HI ; of the data for that entry @RH4 | ||
| 623 | OUT DX,AL ; @RH4 | ||
| 624 | |||
| 625 | MOV DX,RM_TTDATA_HI ;Read 12 bit TT data high byte @RH4 | ||
| 626 | IN AL,DX ; first, then read low byte. @RH4 | ||
| 627 | XCHG AL,AH ; @RH4 | ||
| 628 | MOV DX,RM_TTDATA_LO ; @RH4 | ||
| 629 | IN AL,DX ; @RH4 | ||
| 630 | MOV BX,AX ;Store result in BX @RH4 | ||
| 631 | AND BX,XMA_TT_MASK ;Turn off useless upper 4 bits @RH4 | ||
| 632 | POP AX ;Restore TT pointer @RH4 | ||
| 633 | RET ; @RH4 | ||
| 634 | X_READ_TT ENDP | ||
| 635 | |||
| 636 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 637 | ;³ H_INH_FOR_EMS subprocedure ³ | ||
| 638 | ;³ Inhibits a single translate table entry of extended memory ³ | ||
| 639 | ;³ on a XMO card. This entry (16K) is for use by EMS. ³ | ||
| 640 | ;³ on entry: (AX) = XMO Translate table pointer (# of K / 16) ³ | ||
| 641 | ;³ ³ | ||
| 642 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 643 | H_INH_FOR_EMS PROC | ||
| 644 | PUSH AX ;Save the TT pointer @RH4 | ||
| 645 | MOV DX,H_TTPTR_LO ;Set the low and high bytes of @RH4 | ||
| 646 | OUT DX,AL ; the XMO translate table @RH4 | ||
| 647 | XCHG AL,AH ; pointer, @RH4 | ||
| 648 | MOV DX,H_TTPTR_HI ; @RH4 | ||
| 649 | OUT DX,AL ; @RH4 | ||
| 650 | |||
| 651 | MOV AL,H_TT_INHIBIT ;AL = XMO TT inhibit data @RH4 | ||
| 652 | MOV DX,H_TTDATA ;Inhibit this TT entry so that @RH4 | ||
| 653 | OUT DX,AL ; it is no longer extended memory @RH4 | ||
| 654 | POP AX ;Restore TT pointer @RH4 | ||
| 655 | RET ; @RH4 | ||
| 656 | H_INH_FOR_EMS ENDP | ||
| 657 | |||
| 658 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 659 | ;³ X_INH_FOR_EMS subprocedure ³ | ||
| 660 | ;³ Inhibits a single translate table entry of extended memory ³ | ||
| 661 | ;³ on a XMA/A card. This entry (4K) is for use by EMS. ³ | ||
| 662 | ;³ on entry: (AX) = XMA/A Translate table pointer (# of K / 4) ³ | ||
| 663 | ;³ ³ | ||
| 664 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 665 | X_INH_FOR_EMS PROC | ||
| 666 | PUSH AX ;Save the TT pointer @RH4 | ||
| 667 | MOV DX,RM_TTPTR_LO ;Set the low and high bytes of @RH4 | ||
| 668 | OUT DX,AL ; the XMA/A translate table @RH4 | ||
| 669 | XCHG AL,AH ; pointer, then read the value @RH4 | ||
| 670 | MOV DX,RM_TTPTR_HI ; of the data for that entry @RH4 | ||
| 671 | OUT DX,AL ; @RH4 | ||
| 672 | |||
| 673 | MOV AX,XMA_TT_INHIBIT ;AX = XMA 12 bit TT inhibit data @RH4 | ||
| 674 | MOV DX,RM_TTDATA_LO ;Write 12 bit TT data low byte @RH4 | ||
| 675 | OUT DX,AL ; first, then write high byte. @RH4 | ||
| 676 | XCHG AL,AH ; @RH4 | ||
| 677 | MOV DX,RM_TTDATA_HI ; @RH4 | ||
| 678 | OUT DX,AL ; @RH4 | ||
| 679 | POP AX ;Restore TT pointer @RH4 | ||
| 680 | RET ; @RH4 | ||
| 681 | X_INH_FOR_EMS ENDP | ||
| 682 | |||
| 683 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 684 | ;³ ADJUST_CMOS subprocedure ³ | ||
| 685 | ;³ Reset the CMOS value for amount of extended memory. The ³ | ||
| 686 | ;³ memory off the 'top' (upper addresses) is used by EMS. ³ | ||
| 687 | ;³ on entry: ³ | ||
| 688 | ;³ CARD_EXT_S16K = First 16K translate table pointer past the ³ | ||
| 689 | ;³ top of the last card. Example - One 2M card ³ | ||
| 690 | ;³ that started at 1M+384K, AX = 58h + 80H = D8h ³ | ||
| 691 | ;³ ³ | ||
| 692 | ;³ ³ | ||
| 693 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 694 | ADJUST_CMOS PROC | ||
| 695 | CMOS_LO EQU 70h ;Port addrs of CMOS controller | ||
| 696 | CMOS_HI EQU 71h | ||
| 697 | |||
| 698 | MOV BX,CARD_EXT_S16K ;Convert to 1st 16K TT ptr past @RH4 | ||
| 699 | SUB BX,ems_pgs_parm ; entries reserved for ext mem @RH4 | ||
| 700 | SUB BX,1024/16 ;Convert to # of 16K above 1M | ||
| 701 | MOV CL,4 ;Multiply by 16 to get # of K | ||
| 702 | SHL BX,CL ; above 1 Megabyte | ||
| 703 | |||
| 704 | MOV AX,8800h ;Get BIOS' current value for # | ||
| 705 | INT 15h ; of K extended (above 1M) | ||
| 706 | |||
| 707 | CMP AX,BX ;If already set below what we think | ||
| 708 | JBE CMOS_RET ; think then don't adjust it | ||
| 709 | |||
| 710 | PUSHF ;Else adjust CMOS...save state of | ||
| 711 | CLI ; interrupts and disable | ||
| 712 | MOV AL,0B5h ;Select NMI off byte 35 | ||
| 713 | OUT CMOS_LO,AL ;Write to CMOS controller | ||
| 714 | JMP $+2 ; delay | ||
| 715 | MOV AL,BL ;Write low data byte to CMOS | ||
| 716 | OUT CMOS_HI,AL ; | ||
| 717 | JMP $+2 ; | ||
| 718 | |||
| 719 | MOV AL,0B6h ;Select NMI off byte 36 | ||
| 720 | OUT CMOS_LO,AL ;Write to CMOS controller | ||
| 721 | JMP $+2 ; delay | ||
| 722 | MOV AL,BH ;Write high data byte to CMOS | ||
| 723 | OUT CMOS_HI,AL ; | ||
| 724 | JMP $+2 ; | ||
| 725 | |||
| 726 | MOV AL,0Fh ;Select NMI on byte 0f | ||
| 727 | OUT CMOS_LO,AL ;Write to CMOS controller | ||
| 728 | JMP $+2 ; delay | ||
| 729 | IN AL,CMOS_HI ;Reset CMOS like BIOS does | ||
| 730 | POPF ;Restore interrupt state | ||
| 731 | CMOS_RET: | ||
| 732 | RET ; @RH4 | ||
| 733 | ADJUST_CMOS ENDP | ||
| 734 | |||
| 735 | \ No newline at end of file | ||
diff --git a/v4.0/src/DEV/XMA2EMS/ROMSCAN.INC b/v4.0/src/DEV/XMA2EMS/ROMSCAN.INC new file mode 100644 index 0000000..8eeb1b8 --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/ROMSCAN.INC | |||
| @@ -0,0 +1,420 @@ | |||
| 1 | |||
| 2 | page | ||
| 3 | ;------------------------------------------------------------------- | ||
| 4 | ; | ||
| 5 | ; This file contains the code to do a pseudo-rom scan looking | ||
| 6 | ; for possible EMS holes | ||
| 7 | ; | ||
| 8 | ;------------------------------------------------------------------- | ||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | romscan proc near | ||
| 13 | |||
| 14 | push ax | ||
| 15 | push dx | ||
| 16 | push cx | ||
| 17 | push di | ||
| 18 | |||
| 19 | push cs ; make es and ds point to segment where messages are | ||
| 20 | pop es | ||
| 21 | |||
| 22 | push cs | ||
| 23 | pop ds | ||
| 24 | |||
| 25 | ; must do rom scan with interrupts disabled | ||
| 26 | |||
| 27 | cli | ||
| 28 | |||
| 29 | ;------------------------ | ||
| 30 | |||
| 31 | cmp map_count,0 ; no segments specified, do rom scan | ||
| 32 | je no_pages_spec | ||
| 33 | |||
| 34 | mov cx,map_count ; number of segments to check | ||
| 35 | xor di,di ; use di as pointer into table | ||
| 36 | |||
| 37 | check_segs: | ||
| 38 | mov ax,map_table.phys_page_segment[di] | ||
| 39 | |||
| 40 | call CHK_FREE_SEGMENT ; check a 16K block | ||
| 41 | jnc segment_ok | ||
| 42 | |||
| 43 | ; display the error | ||
| 44 | |||
| 45 | mov segment_error,1 ; set segment error flag | ||
| 46 | |||
| 47 | |||
| 48 | ; display conflict message | ||
| 49 | |||
| 50 | push ax ; save some regs | ||
| 51 | push dx | ||
| 52 | push di | ||
| 53 | |||
| 54 | MOV DI,OFFSET confl_address ; ascii string page frame | ||
| 55 | CALL CNVHEXAT | ||
| 56 | |||
| 57 | MOV DX,OFFSET conflict_msg ; start of message | ||
| 58 | MOV AH,9 ; dos prt string | ||
| 59 | INT 21H ; | ||
| 60 | |||
| 61 | pop di ; restore some regs | ||
| 62 | pop dx | ||
| 63 | pop ax | ||
| 64 | |||
| 65 | segment_ok: | ||
| 66 | add di,type mappable_phys_page_struct | ||
| 67 | loop check_segs | ||
| 68 | |||
| 69 | ;------------------------ | ||
| 70 | ; if there were no conflicts, then exit with no error | ||
| 71 | |||
| 72 | cmp segment_error,0 | ||
| 73 | je rom_scan_no_error ; exit with no error (carry = 0) | ||
| 74 | |||
| 75 | ;------------------------ | ||
| 76 | |||
| 77 | MOV DX,OFFSET CRLF ; skip a blank line | ||
| 78 | MOV AH,9 ; dos prt string | ||
| 79 | INT 21H ; | ||
| 80 | |||
| 81 | jmp rom_scan_code | ||
| 82 | |||
| 83 | ; display no pages message | ||
| 84 | |||
| 85 | no_pages_spec: | ||
| 86 | MOV DX,OFFSET NO_PAGES_MSG ; skip a blank line | ||
| 87 | MOV AH,9 ; dos prt string | ||
| 88 | INT 21H | ||
| 89 | |||
| 90 | MOV DX,OFFSET CRLF ; skip a blank line | ||
| 91 | MOV AH,9 ; dos prt string | ||
| 92 | INT 21H ; | ||
| 93 | |||
| 94 | ;------------------------------------------------------------------- | ||
| 95 | ; | ||
| 96 | ; This routine scans the address range from c000 - FFFF looking | ||
| 97 | ; for 16 K gaps. | ||
| 98 | ; | ||
| 99 | ;------------------------------------------------------------------- | ||
| 100 | |||
| 101 | rom_scan_code: | ||
| 102 | |||
| 103 | mov ax,0c000h ; start at c000 | ||
| 104 | xor bx,bx ; bx holds count of contiguous pages | ||
| 105 | mov cx,15 ; loop counter | ||
| 106 | mov dx,ax ; dx holds start of frame | ||
| 107 | |||
| 108 | fam2_loop: | ||
| 109 | call CHK_FREE_SEGMENT ; check a 16K block | ||
| 110 | jc bad_seg | ||
| 111 | |||
| 112 | ; good 16 segment | ||
| 113 | |||
| 114 | call FoundBlock | ||
| 115 | |||
| 116 | add bx,1 ; add another page to frame counter | ||
| 117 | cmp bx,4 ; 4 means frame is found | ||
| 118 | jne no_frame_yet | ||
| 119 | |||
| 120 | ; a frame has been found | ||
| 121 | |||
| 122 | mov bx,100 ; make sure we don't look for more frames | ||
| 123 | |||
| 124 | no_frame_yet: | ||
| 125 | add ax,0400h ; point to next segment | ||
| 126 | jmp continue_loop | ||
| 127 | |||
| 128 | ; bad 16 segment | ||
| 129 | |||
| 130 | bad_seg: | ||
| 131 | add ax,0400h ; point to next segment | ||
| 132 | cmp bx,100 | ||
| 133 | jae continue_loop ; don't reset frame info if one has been found | ||
| 134 | |||
| 135 | xor bx,bx ; clear contiguous page counter | ||
| 136 | mov dx,ax ; make frame pointer point to next page | ||
| 137 | |||
| 138 | continue_loop: | ||
| 139 | |||
| 140 | loop fam2_loop | ||
| 141 | jmp rom_scan_exit | ||
| 142 | |||
| 143 | |||
| 144 | rom_scan_no_error: | ||
| 145 | clc | ||
| 146 | jmp clean_exit | ||
| 147 | |||
| 148 | |||
| 149 | ;------------------------------------------------------------------- | ||
| 150 | |||
| 151 | rom_scan_exit: | ||
| 152 | |||
| 153 | ; display frame if found | ||
| 154 | |||
| 155 | cmp bx,100 ; >= 100 means frame was found | ||
| 156 | jb no_frame_exit | ||
| 157 | |||
| 158 | mov ax,dx ; get frame address in ax | ||
| 159 | call FoundFrame ; display frame address | ||
| 160 | |||
| 161 | |||
| 162 | no_frame_exit: | ||
| 163 | STC ; carry = 1 means error | ||
| 164 | |||
| 165 | clean_exit: | ||
| 166 | sti | ||
| 167 | |||
| 168 | |||
| 169 | pop di | ||
| 170 | pop dx | ||
| 171 | pop cx | ||
| 172 | pop ax | ||
| 173 | |||
| 174 | ret | ||
| 175 | |||
| 176 | romscan endp | ||
| 177 | |||
| 178 | |||
| 179 | |||
| 180 | ;------------------------------------------------------------------- | ||
| 181 | ; | ||
| 182 | ; FoundBlock assumes AX = segment address of good 16 K block | ||
| 183 | ; | ||
| 184 | ;------------------------------------------------------------------- | ||
| 185 | |||
| 186 | FoundBlock proc near | ||
| 187 | |||
| 188 | push ax | ||
| 189 | push dx | ||
| 190 | push es | ||
| 191 | push di | ||
| 192 | |||
| 193 | push cs | ||
| 194 | pop es | ||
| 195 | |||
| 196 | push cs | ||
| 197 | pop ds | ||
| 198 | |||
| 199 | MOV DI,OFFSET hole_address ; ascii string page frame | ||
| 200 | CALL CNVHEXAT | ||
| 201 | |||
| 202 | MOV DX,OFFSET hole_msg ; start of message | ||
| 203 | MOV AH,9 ; dos prt string | ||
| 204 | INT 21H ; | ||
| 205 | |||
| 206 | |||
| 207 | pop di | ||
| 208 | pop es | ||
| 209 | pop dx | ||
| 210 | pop ax | ||
| 211 | |||
| 212 | ret | ||
| 213 | |||
| 214 | FoundBlock endp | ||
| 215 | |||
| 216 | ;------------------------------------------------------------------- | ||
| 217 | ; | ||
| 218 | ; FoundFrame assumes AX = segment address of good 64 K block | ||
| 219 | ; | ||
| 220 | ;------------------------------------------------------------------- | ||
| 221 | |||
| 222 | FoundFrame proc near | ||
| 223 | |||
| 224 | push ax | ||
| 225 | push dx | ||
| 226 | push es | ||
| 227 | push di | ||
| 228 | |||
| 229 | push cs | ||
| 230 | pop es | ||
| 231 | |||
| 232 | push cs | ||
| 233 | pop ds | ||
| 234 | |||
| 235 | MOV DI,OFFSET frame_address ; ascii string page frame | ||
| 236 | CALL CNVHEXAT | ||
| 237 | |||
| 238 | MOV DX,OFFSET frame_msg ; start of message | ||
| 239 | MOV AH,9 ; dos prt string | ||
| 240 | INT 21H ; | ||
| 241 | |||
| 242 | |||
| 243 | pop di | ||
| 244 | pop es | ||
| 245 | pop dx | ||
| 246 | pop ax | ||
| 247 | |||
| 248 | ret | ||
| 249 | |||
| 250 | FoundFrame endp | ||
| 251 | |||
| 252 | |||
| 253 | |||
| 254 | |||
| 255 | |||
| 256 | |||
| 257 | ;------------------------------------------------------------------- | ||
| 258 | ;------------------------------------------------------------------- | ||
| 259 | ;------------------------------------------------------------------- | ||
| 260 | ;------------------------------------------------------------------- | ||
| 261 | ;------------------------------------------------------------------- | ||
| 262 | ;------------------------------------------------------------------- | ||
| 263 | ;------------------------------------------------------------------- | ||
| 264 | ;------------------------------------------------------------------- | ||
| 265 | ;------------------------------------------------------------------- | ||
| 266 | ;------------------------------------------------------------------- | ||
| 267 | ;------------------------------------------------------------------- | ||
| 268 | ;------------------------------------------------------------------- | ||
| 269 | ;------------------------------------------------------------------------ | ||
| 270 | ; 03/04/88 jwg: | ||
| 271 | ; PROCEDURE NAME: CHK_FREE_SEGMENT : | ||
| 272 | ; : | ||
| 273 | ; THIS PROCEDURE CHECKS EACH OF THE 2K BOUNDARIES IN THE 16K SEGMENT : | ||
| 274 | ; TO DETERMINE IF A ROM SEGMENT IS EMPTY. IT VERIFIES THAT NO ROM : | ||
| 275 | ; FROM A PRECEEDING ADDRESS EXTENDS INTO THIS 16K SEGMENT. ALSO THE : | ||
| 276 | ; 16K BLOCK IS CHECKED FOR THE PRESENCE OF ANY RESPONDING CARD. : | ||
| 277 | ; : | ||
| 278 | ; ENTRY: AX - CONTAINS 16K SEGMENT ADDRESS : | ||
| 279 | ; EXIT: CARRY FLAG = 0 - SEGMENT FREE : | ||
| 280 | ; CARRY FLAG = 1 - SEGMENT IN USE : | ||
| 281 | ; : | ||
| 282 | ;------------------------------------------------------------------------ | ||
| 283 | |||
| 284 | ROM_SCAN EQU 0AA55H | ||
| 285 | CARD_SEL_PORT EQU 091h ; CARD SELECTED LATCH PORT | ||
| 286 | |||
| 287 | |||
| 288 | CHK_FREE_SEGMENT PROC NEAR | ||
| 289 | |||
| 290 | PUSH AX ; Save work registers | ||
| 291 | PUSH BX | ||
| 292 | PUSH CX | ||
| 293 | PUSH DX | ||
| 294 | PUSH DI | ||
| 295 | PUSH ES ; Save data segment register | ||
| 296 | MOV BX,AX ; Save segment start address | ||
| 297 | MOV CX,AX ; Save in work register | ||
| 298 | ADD CX,0400h ; Determine End segment address of FIFE | ||
| 299 | ; MOV DX,0C000h-00100h ; Get address of start of ROM area | ||
| 300 | mov dx,ax ; gga | ||
| 301 | sub dx,0100h ; gga | ||
| 302 | CHK_FREE_NEXT: | ||
| 303 | ADD DX,00100h ; Add offset to get next 2K segment | ||
| 304 | CMP DX,CX ; Check for past end of 16K ROM area | ||
| 305 | JAE CHK_FREE_OK ; IF (NC) then Exit, segment was free | ||
| 306 | |||
| 307 | ; CHECK FOR ROM BLOCK SIGNATURE | ||
| 308 | MOV ES,DX ; Change to new ROM segment | ||
| 309 | CMP ES:WORD PTR [0],ROM_SCAN; Check if a ROM module is present | ||
| 310 | JE CHK_FREE_SIZE ; Go check length if ROM SCAN signature | ||
| 311 | |||
| 312 | CMP BX,DX ; Check if into the target segment yet | ||
| 313 | JA CHK_FREE_NEXT ; Loop and check next 2K block in not | ||
| 314 | |||
| 315 | ; CHECK FOR CARD RESPONDING IN 2K | ||
| 316 | NOP ; Following sequence can not be traced.. | ||
| 317 | ;;;;; CALL CARD_SEL_NOW ; Reset CARD SELECTED FEED BACK latch . | ||
| 318 | XOR DI,DI ; Clear source pointer . | ||
| 319 | MOV AX,0FFFFh ; Get expected floating bus pattern . | ||
| 320 | PUSH CX ; Save CX . | ||
| 321 | MOV CX,00400h ; Get count of 1 K words (2K bytes) . | ||
| 322 | REPE SCASW ; Check for all bits on in block ES:DI . | ||
| 323 | POP CX ; Recover end segment address . | ||
| 324 | JNE CHK_FREE_ERROR ; Exit if anything there . | ||
| 325 | |||
| 326 | ;;;;;; cmp rom_scan_type,family1 ; gga only do the card select check on PS2's | ||
| 327 | ;;;;;; je skip_ps2_check | ||
| 328 | |||
| 329 | ;;;;;; CALL CARD_SEL_NOW ; Check for a CARD SELECTED by scan . | ||
| 330 | ;;;;;; JC CHK_FREE_ERROR ; Exit (CY) if a card responded ........ | ||
| 331 | |||
| 332 | ;;;;;;skip_ps2_check: | ||
| 333 | JMP CHK_FREE_NEXT ; ELSE check next 2K address | ||
| 334 | |||
| 335 | CHK_FREE_SIZE: ; CHECK LENGTH INTO 16K SEGMENT | ||
| 336 | push cx ; gga | ||
| 337 | MOV AL,ES:BYTE PTR [2] ; Get ROM module length in 512 bytes | ||
| 338 | MOV AH,0 ; Clear high byte | ||
| 339 | mov cl,5 ; gga | ||
| 340 | SHL AX,cl ; gga convert to segment length (16 byte) | ||
| 341 | pop cx ; gga | ||
| 342 | ADD AX,DX ; Determine ending segment size | ||
| 343 | CMP BX,AX ; Does ROM extend into this 16K segment | ||
| 344 | JNB CHK_FREE_NEXT ; IF not then continue search | ||
| 345 | |||
| 346 | CHK_FREE_ERROR: | ||
| 347 | STC ; ELSE (CY), Exit with segment not free | ||
| 348 | CHK_FREE_OK: | ||
| 349 | POP ES ; restore segment register | ||
| 350 | POP DI | ||
| 351 | POP DX | ||
| 352 | POP CX ; restore all registers | ||
| 353 | POP BX | ||
| 354 | POP AX | ||
| 355 | RET ; EXIT (NC) if segment free to test | ||
| 356 | |||
| 357 | CHK_FREE_SEGMENT ENDP | ||
| 358 | |||
| 359 | |||
| 360 | ;------------------------------------------------------------------------ | ||
| 361 | ; 03/04/88 jwg: | ||
| 362 | ; PROCEDURE NAME: CARD_SEL_FBK : | ||
| 363 | ; : | ||
| 364 | ; THIS PROCEDURE CHECKS THE CARD SELECTED FEEDBACK LINE AND LATCH : | ||
| 365 | ; TO VERIFY THAT THIS LINE WAS ACTIVATED. METHOD IS TO CLEAR THE : | ||
| 366 | ; LATCH AND READ A LOCATION USING THE PASSED SEGMENT ADDRESS. IF : | ||
| 367 | ; ANY CARD RESPONDS THE LATCH WILL BE SET ON. : | ||
| 368 | ; : | ||
| 369 | ; NOTE: These routines can not be traced with a debug-er : | ||
| 370 | ; as VIDEO updates also set the card selected latch. : | ||
| 371 | ; : | ||
| 372 | ; ENTRY: AX - ADDRESS OF SELECTED SEGMENT : | ||
| 373 | ; : | ||
| 374 | ; EXIT: CARRY FLAG = 0 - CARD SELECTED LATCH WAS NOT SET (OFF) : | ||
| 375 | ; CARRY FLAG = 1 - CARD SELECTED LATCH WAS SET BY TEST : | ||
| 376 | ; : | ||
| 377 | ;------------------------------------------------------------------------ | ||
| 378 | |||
| 379 | ;;;;;CARD_SEL_FBK PROC NEAR ; TEST CARD SELECTED FEED BACK | ||
| 380 | |||
| 381 | ;;;;; CLI ; Block interrupts during operation | ||
| 382 | ;;;;; CALL CARD_SEL_NOW ; Read current port value to clear | ||
| 383 | ;;;;; PUSH DS ; Save segment register | ||
| 384 | ;;;;; MOV DS,AX ; Set segment | ||
| 385 | ;;;;; CMP DS:BYTE PTR [0],AL ; Read first byte with dummy compare | ||
| 386 | ;;;;; POP DS ; Restore segment selector | ||
| 387 | ;;;;; CALL CARD_SEL_NOW ; Read current port value and clear | ||
| 388 | ;;;;; STI ; Enable interrupts | ||
| 389 | ;;;;; RET ; RETurn (CY)= 1 if latch set by read | ||
| 390 | |||
| 391 | ;;;;;CARD_SEL_FBK ENDP | ||
| 392 | |||
| 393 | ;------------------------------------------------------------------------ | ||
| 394 | ; 03/04/88 jwg: | ||
| 395 | ; PROCEDURE NAME: CARD_SEL_NOW (CURRENT VALUE) : | ||
| 396 | ; : | ||
| 397 | ; THIS PROCEDURE READS AND RESETS THE CURRENT CARD SELECTED FEEDBACK : | ||
| 398 | ; LATCH AND RETURNS THE STATUS. : | ||
| 399 | ; : | ||
| 400 | ; NOTE: This routine can not be traced with a debug-er : | ||
| 401 | ; as VIDEO updates also set the card selected latch. : | ||
| 402 | ; : | ||
| 403 | ; ENTRY: NONE : | ||
| 404 | ; : | ||
| 405 | ; EXIT: CARRY FLAG = 0 - CARD SELECTED LATCH WAS NOT SET (OFF) : | ||
| 406 | ; CARRY FLAG = 1 - CARD SELECTED LATCH WAS SET ON WHEN READ : | ||
| 407 | ; : | ||
| 408 | ;------------------------------------------------------------------------ | ||
| 409 | |||
| 410 | ;;;;;CARD_SEL_NOW PROC NEAR ; READ CARD SELECTED FEED BACK | ||
| 411 | |||
| 412 | ;;;;; PUSH AX ; Save segment address | ||
| 413 | ;;;;; IN AL,CARD_SEL_PORT ; Read current port value and clear | ||
| 414 | ;;;;; RCR AL,1 ; Move bit 0 into CY flag | ||
| 415 | ;;;;; POP AX ; Recover segment address | ||
| 416 | ;;;;; RET ; RETurn (CY)= 0 if latch set | ||
| 417 | |||
| 418 | ;;;;;CARD_SEL_NOW ENDP | ||
| 419 | |||
| 420 | \ No newline at end of file | ||
diff --git a/v4.0/src/DEV/XMA2EMS/XMA1DIAG.INC b/v4.0/src/DEV/XMA2EMS/XMA1DIAG.INC new file mode 100644 index 0000000..bbf3875 --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/XMA1DIAG.INC | |||
| @@ -0,0 +1,1870 @@ | |||
| 1 | ;-----------------------------------------------------------------------; | ||
| 2 | ; This section contains the prescence test and diagnostic ; | ||
| 3 | ; routines for the XMA 1 card. ; | ||
| 4 | ; ; | ||
| 5 | ;-----------------------------------------------------------------------; | ||
| 6 | |||
| 7 | ;-----------------------------------------------------------------------; | ||
| 8 | ; DATA THAT IS UNIQUE TO THE DIAGNOSTICS PORTION OF ; | ||
| 9 | ; THE DEVICE DRIVER. THIS AREA WILL NOT REMAIN PRESENT ; | ||
| 10 | ; AFTER INITIALIZATION. ; | ||
| 11 | ;-----------------------------------------------------------------------; | ||
| 12 | |||
| 13 | MEM_INST DB '1' | ||
| 14 | TEST_ID DB ? ;SAVE AREA FOR CURRENT TEST ID | ||
| 15 | CTRLPARM DW ? ;SAVE AREA FOR CONTROL PARM | ||
| 16 | PAGE_UNDER_TEST DW 0 ;SAVE AREA FOR PAGE UNDER TEST | ||
| 17 | CUR_SAVE DW ? ;SAVE AREA FOR NEXT AVAILABLE LINE | ||
| 18 | ;FOR MESSAGES | ||
| 19 | ACTIVE_PAGE DB ? ;ACTIVE DISPLAY PAGE | ||
| 20 | TESTABLE_SEGMENTS DW ? | ||
| 21 | |||
| 22 | |||
| 23 | PAGE | ||
| 24 | ;-----------------------------------------------------------------------; | ||
| 25 | ; EQUATES THAT ARE UNIQUE TO THE DIAGNOSTICS PORTION OF ; | ||
| 26 | ; THE DEVICE DRIVER. ; | ||
| 27 | ;-----------------------------------------------------------------------; | ||
| 28 | BLK_ON EQU 11110111B ;MASK FOR ENABLING A BLOCK | ||
| 29 | BLK_OFF EQU 00001000B ;MASK FOR INHIBITING A BLOCK | ||
| 30 | VIRT_MODE EQU 00000010B ;MASK FOR VIRTUAL MODE | ||
| 31 | REAL_MODE EQU 11111101B ;MASK FOR REAL MODE | ||
| 32 | MAX_TASK_ID EQU 15 ;MAXIMIM TASK ID | ||
| 33 | ENABLE EQU 01H ;INDICATES THAT BLOCK SHOULD BE ENABLED | ||
| 34 | TABLEN EQU 1000H ;NUMBER OF ENTRIES IN XLAT TABLE | ||
| 35 | DMAREQ1 EQU 0009H ;I/O ADDRESS OF DMA CTRL 1 REQ REG | ||
| 36 | DMAREQ2 EQU 00D2H ;I/O ADDRESS OF DMA CTRL 2 REQ REG | ||
| 37 | DMAMODE1 EQU 000BH ;I/O ADDRESS OF DMA CTRL 1 MODE REG | ||
| 38 | DMAMODE2 EQU 00D6H ;I/O ADDRESS OF DMA CTRL 2 MODE REG | ||
| 39 | AT_NMI_REG EQU 70H ;AT NMI REG | ||
| 40 | AT_NMI_OFF EQU 80H ;AT NMI OFF MASK | ||
| 41 | AT_NMI_ON EQU 00H ;AT NMI ON MASK | ||
| 42 | AT_CHCHK_EN_REG EQU 61H ;AT CH CHK ENABLE REG | ||
| 43 | AT_CHCHK_REG EQU 61H ;AT CH CHK REG | ||
| 44 | AT_CHCHK_EN EQU 0F7H ;AT CH CHK ENABLE MASK | ||
| 45 | AT_CHCHK_DIS EQU 08H ;AT CH CHK DISABLE MASK | ||
| 46 | AT_CHCHK EQU 40H ;AT CH CHK MASK | ||
| 47 | XT_NMI_REG EQU 0A0H ;XT NMI REG | ||
| 48 | XT_NMI_OFF EQU 00H ;XT NMI OFF MASK | ||
| 49 | XT_NMI_ON EQU 80H ;XT NMI ON MASK | ||
| 50 | XT_CHCHK_EN_REG EQU 61H ;XT CH CHK ENABLE REG | ||
| 51 | XT_CHCHK_REG EQU 62H ;XT CH CHK REG | ||
| 52 | XT_CHCHK_EN EQU 0DFH ;XT CH CHK ENABLE MASK | ||
| 53 | XT_CHCHK_DIS EQU 20H ;XT CH CHK DISABLE MASK | ||
| 54 | XT_CHCHK EQU 40H ;XT CH CHK MASK | ||
| 55 | CR EQU 0DH ;CARRIAGE RETURN | ||
| 56 | LF EQU 0AH ;LINE FEED | ||
| 57 | PRES_TEST EQU 01 ;PRESENCE TEST ID | ||
| 58 | REG_TEST EQU 02 ;REG TEST ID | ||
| 59 | AUTO_INC EQU 03 ;AUTO INC TEST ID | ||
| 60 | XLAT_TABLE_TEST EQU 04 ;TT TEST ID | ||
| 61 | LOMEM_TEST EQU 05 ;ABOVE 640K TEST ID | ||
| 62 | DMA_CAPTURE EQU 06 ;DMA CAPTURE TEST ID | ||
| 63 | PAGE_TEST EQU 07 ;PAGE TEST ID | ||
| 64 | MEM_TEST EQU 10 ;MEMORY TEST ID | ||
| 65 | |||
| 66 | ;------------------------------------------------------------------------- | ||
| 67 | ; | ||
| 68 | ; PRESENCE TEST | ||
| 69 | ; | ||
| 70 | ; DESCRIPTION : This routine will determine if the XMA is in the system. | ||
| 71 | ; It will also determine the amount of memory installed | ||
| 72 | ; on the card in 1Meg increments (up to 4Meg). | ||
| 73 | ; | ||
| 74 | ; FUNCTION/ : See description | ||
| 75 | ; PURPOSE | ||
| 76 | ; | ||
| 77 | ; ENTRY POINT : PRESTST | ||
| 78 | ; | ||
| 79 | ; ENTRY : The assumption is that at least 1MB of memory is installed. | ||
| 80 | ; CONDITIONS If the 2nd, 3rd or 4th MB of memory is installed then the | ||
| 81 | ; TOTAL_SYS_PAGES, TOTAL_EMS_PAGES, FREE_PAGES and | ||
| 82 | ; MEM_INST words are Revised accordingly. | ||
| 83 | ; | ||
| 84 | ; | ||
| 85 | ; | ||
| 86 | ; EXIT : (zero flag) = 0 indicates that the XMA is not installed. | ||
| 87 | ; if (zero flag) <> 0 then | ||
| 88 | ; TOTAL_SYS_PAGES, TOTAL_EMS_PAGES, FREE_PAGES and | ||
| 89 | ; MEM_INST words are Revised accordingly. | ||
| 90 | ; | ||
| 91 | ; AX,BX,CX,DX ARE DESTROYED | ||
| 92 | ;------------------------------------------------------------------------- | ||
| 93 | ; | ||
| 94 | PRESTST PROC | ||
| 95 | ; | ||
| 96 | MOV AL,PRES_TEST | ||
| 97 | MOV CS:TEST_ID,AL | ||
| 98 | |||
| 99 | ;SAVE CONTENTS OF MODE REG | ||
| 100 | MOV DX,MODE_REG | ||
| 101 | IN AL,DX | ||
| 102 | PUSH AX | ||
| 103 | |||
| 104 | ; TRANSLATE TABLE ADDRESS AND DATA REGISTERS | ||
| 105 | ; | ||
| 106 | MOV AX,0AA55H ;DATA PATTERN (IN REAL MODE) | ||
| 107 | ;BE CERTAIN MODE REG GETS | ||
| 108 | ;REAL MODE | ||
| 109 | MOV DX,MODE_REG ;I/O TO MODE REG | ||
| 110 | OUT DX,AL ;WRITE PATTERN | ||
| 111 | MOV DX,TTPOINTER + 1 ;I/O TO TT POINTER (ODD ADDR) | ||
| 112 | XCHG AL,AH ;CHRG BUS WITH INVERSE PATTERN | ||
| 113 | OUT DX,AL ;WRITE IT | ||
| 114 | MOV DX,MODE_REG | ||
| 115 | IN AL,DX ;READ BACK MODE REG | ||
| 116 | XOR AL,AH | ||
| 117 | AND AL,0FH ;MASK OFF UNUSED BITS | ||
| 118 | ;ZERO FLAG = 0 IF ERROR | ||
| 119 | END_PRES: | ||
| 120 | POP AX | ||
| 121 | PUSHF ;SAVE FLAGS | ||
| 122 | MOV DX,MODE_REG | ||
| 123 | OUT DX,AL ;RESTORE MODE REG TO INITIAL STATE | ||
| 124 | POPF ;RESTORE FLAGS | ||
| 125 | RET ;BACK TO CALLER | ||
| 126 | ; | ||
| 127 | PRESTST ENDP | ||
| 128 | |||
| 129 | PAGE | ||
| 130 | |||
| 131 | ;------------------------------------------------------------------------; | ||
| 132 | ; Diagnostics...on exit if ZF=0 then error ; | ||
| 133 | ;------------------------------------------------------------------------; | ||
| 134 | XMA1DIAGS PROC | ||
| 135 | |||
| 136 | MOV CS:TEST_ID,00H ;CLEAR TEST ID BYTE | ||
| 137 | MOV CS:CTRLPARM,0100H ;SAVE CONTROL PARM | ||
| 138 | CALL CUR_POS ;GET CURSOR READY FOR MESSAGES | ||
| 139 | CALL REGTST ;TEST XMA REGISTERS | ||
| 140 | JNE FOUND_ERROR ;JUMP IF ERROR | ||
| 141 | CALL INCTST | ||
| 142 | JNE FOUND_ERROR | ||
| 143 | CALL XLATST | ||
| 144 | JNE FOUND_ERROR | ||
| 145 | CALL LOMEMTST ;TEST FOR BELOW 640K | ||
| 146 | JNE FOUND_ERROR ;JUMP IF ERROR | ||
| 147 | CALL MEMARRAY ;TEST MEMORY ABOVE 640K | ||
| 148 | JNE FOUND_ERROR ;JUMP IF ERROR | ||
| 149 | CALL PAGETST | ||
| 150 | JNE FOUND_ERROR | ||
| 151 | CALL CAPTST ;TEST DMA CAPTURE | ||
| 152 | JNE FOUND_ERROR ;JUMP IF ERROR | ||
| 153 | FOUND_ERROR: | ||
| 154 | RET | ||
| 155 | XMA1DIAGS ENDP | ||
| 156 | |||
| 157 | |||
| 158 | |||
| 159 | PAGE | ||
| 160 | ;------------------------------------------------------------------------- | ||
| 161 | ;------------------------------------------------------------------------- | ||
| 162 | ; | ||
| 163 | ; SAVES CURSOR POSITION | ||
| 164 | ; | ||
| 165 | ; DESCRIPTION : This routine simply saves the cursor location | ||
| 166 | ; in CS:CUR_SAVE. This cursor position | ||
| 167 | ; should be used by the KB_OK routine to insure proper | ||
| 168 | ; format of the screen. | ||
| 169 | ; | ||
| 170 | ; FUNCTION/ : See description | ||
| 171 | ; PURPOSE | ||
| 172 | ; | ||
| 173 | ; | ||
| 174 | ; ENTRY POINT : CUR_POS | ||
| 175 | ; | ||
| 176 | ; ENTRY : | ||
| 177 | ; CONDITIONS | ||
| 178 | ; | ||
| 179 | ; | ||
| 180 | ; EXIT : new cursor position is saved in CS:CUR_SAVE | ||
| 181 | ; | ||
| 182 | ; All registers are preserved | ||
| 183 | ; | ||
| 184 | ;------------------------------------------------------------------------- | ||
| 185 | ; | ||
| 186 | CUR_POS PROC | ||
| 187 | ; | ||
| 188 | PUSH AX | ||
| 189 | PUSH BX | ||
| 190 | PUSH CX | ||
| 191 | PUSH DX | ||
| 192 | PUSH SI | ||
| 193 | PUSH DI | ||
| 194 | PUSH DS ;SAVE REGISTERS | ||
| 195 | ; | ||
| 196 | PUSH CS | ||
| 197 | POP DS ;GET DS TO THIS CODE SEGMENT | ||
| 198 | ;MOVE CURSOR TO NEXT AVAILABLE LINE | ||
| 199 | ;IF DOS | ||
| 200 | ; MOV AH,9 ;DOS PRINT STRING | ||
| 201 | ; MOV DX,OFFSET NEXT_LINE + 1 ;OFFSET OF NEXT LINE MSG | ||
| 202 | ; INT 21H ;DISPLAY MESSAGE | ||
| 203 | ;ELSE | ||
| 204 | ; MOV BX,OFFSET NEXT_LINE ;GET OFFSET OF NEXT LINE MSG | ||
| 205 | ; MOV AH,0 ;TELL DCP TO DISPLAY | ||
| 206 | ; INT 82H ;DISPLAY MESSAGE | ||
| 207 | ;ENDIF | ||
| 208 | ; rsh001 fix scroll problem | ||
| 209 | ; and remove IF DOS crap | ||
| 210 | ;READ CURRENT VIDEO PAGE ; rsh001 | ||
| 211 | MOV AH,15 ;READ CURRENT Video Page | ||
| 212 | INT 10H ;VIDEO CALL | ||
| 213 | MOV ACTIVE_PAGE,BH ;SAVE ACTIVE PAGE | ||
| 214 | |||
| 215 | ;READ CURRENT CURSOR POSITION | ||
| 216 | MOV AH,3 ;READ CURRENT CURSOR POS | ||
| 217 | INT 10H ;VIDEO CALL | ||
| 218 | MOV CUR_SAVE,DX ;SAVE CURSOR POSITION | ||
| 219 | |||
| 220 | ;RESTORE ALL REGISTERS | ||
| 221 | POP DS | ||
| 222 | POP DI | ||
| 223 | POP SI | ||
| 224 | POP DX | ||
| 225 | POP CX | ||
| 226 | POP BX | ||
| 227 | POP AX ;RESTORE ALL REGISTERS | ||
| 228 | |||
| 229 | RET ;RETURN TO CALLER | ||
| 230 | |||
| 231 | CUR_POS ENDP | ||
| 232 | |||
| 233 | |||
| 234 | |||
| 235 | |||
| 236 | |||
| 237 | PAGE | ||
| 238 | ;------------------------------------------------------------------------- | ||
| 239 | ;------------------------------------------------------------------------- | ||
| 240 | ; | ||
| 241 | ; TEST FOR PRESENCE OF MORE THAN 1 MEGABYTE OF MEMORY | ||
| 242 | ; | ||
| 243 | ; DESCRIPTION : This routine will determine if the 2nd, 3rd or 4th MB is | ||
| 244 | ; installed. Since there are no switches or other indicators | ||
| 245 | ; to be tested, this test will make a "best guess" as to | ||
| 246 | ; the presence of this memory. This test will roll a 0 | ||
| 247 | ; and a 1 through the 1st word of the next Meg and if | ||
| 248 | ; at least 1 bit is consistently good then it is assumed | ||
| 249 | ; that the optional memory is installed. If successful | ||
| 250 | ; then try next Meg. | ||
| 251 | ; | ||
| 252 | ; FUNCTION/ : See description | ||
| 253 | ; PURPOSE | ||
| 254 | ; | ||
| 255 | ; ENTRY POINT : TRY4MEG | ||
| 256 | ; | ||
| 257 | ; ENTRY : none | ||
| 258 | ; CONDITIONS | ||
| 259 | ; | ||
| 260 | ; EXIT : | ||
| 261 | ; | ||
| 262 | ; AX,BX,CX,DX ARE DESTROYED | ||
| 263 | ;------------------------------------------------------------------------- | ||
| 264 | ; | ||
| 265 | TRY4MEG PROC | ||
| 266 | |||
| 267 | ;MEMORY TEST MUST RUN IN PAGE MODE | ||
| 268 | ;BEFORE CARD IS PUT INTO PAGE MODE...MUST SET UP XLAT TABLE TO PASSOVER | ||
| 269 | ;RESERVED MEMORY SPACES (IE.,BIOS, DISPLAY, DISTRIBUTED ROS, ETC) | ||
| 270 | ; | ||
| 271 | CALL VIRT2REAL | ||
| 272 | |||
| 273 | MOV DX,IDREG ;I/O TO ID REGISTER | ||
| 274 | MOV AL,0 ;ID = 0 | ||
| 275 | OUT DX,AL ;SWITCH TO ID = 0 | ||
| 276 | ; | ||
| 277 | ;DISABLE NMI AND ENABLE I/O CHANNEL CHECK | ||
| 278 | MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE | ||
| 279 | CMP AL,PC1 ;IS IT A PC1? | ||
| 280 | JE TR2M1 ;IF NO THEN TRY FOR PC_XT | ||
| 281 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 282 | JE TR2M1 ;IF NO THEN TRY FOR AQUARIUS | ||
| 283 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 284 | JE TR2M1 ;IF NO THEN USE AT NMI REGS | ||
| 285 | ;USE PC-AT NMI REGISTER | ||
| 286 | MOV DX,AT_NMI_REG ;AT's NMI REGISTER | ||
| 287 | MOV AL,AT_NMI_OFF ;MASK OFF NMI | ||
| 288 | OUT DX,AL ;OUTPUT IT | ||
| 289 | MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG | ||
| 290 | IN AL,DX ;READ IT | ||
| 291 | OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 292 | OUT DX,AL ;WRITE IT | ||
| 293 | AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 294 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 295 | ;ENABLED | ||
| 296 | ;USE PC1, XT, AQUARIUS REGISTERS | ||
| 297 | TR2M1: | ||
| 298 | MOV DX,XT_NMI_REG ;XT's NMI REGISTER | ||
| 299 | MOV AL,XT_NMI_OFF ;MASK OFF NMI | ||
| 300 | OUT DX,AL ;OUTPUT IT | ||
| 301 | MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG | ||
| 302 | IN AL,DX ;READ IT | ||
| 303 | OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 304 | OUT DX,AL ;WRITE IT | ||
| 305 | AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 306 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 307 | ;ENABLED | ||
| 308 | ; | ||
| 309 | ;MAP FIRST 64K OF 2ND MEG INTO PC SPACE BEGINNING AT 512K | ||
| 310 | ;***jnw MOV CX,3 ;LOOK FOR PRESENCE OF NEXT 3 MB IN 1MB STEPS | ||
| 311 | MOV CX,99*1024/16 ;***jnw ;LOOK FOR PRESENCE OF NEXT n MB IN 1MB STEPS | ||
| 312 | MOV AX,CS:PAGE_FRAME_STA ;SEGMENT AT PAGE FRAME | ||
| 313 | ;***jnw MOV DX,256 ;BEGINNING AT 2ND MEG OF XMA | ||
| 314 | MOV DX,256+3 ;***jnw ;AT end of 16k | ||
| 315 | MOV BH,0 ;ASSIGNED TO TASK ID 0 | ||
| 316 | MOV BL,01H ;ENABLE THIS MEMORY | ||
| 317 | TR2M1A: | ||
| 318 | PUSH AX | ||
| 319 | PUSH BX | ||
| 320 | PUSH CX | ||
| 321 | PUSH DX | ||
| 322 | ;***jnw MOV CX,16 ;16 * 4K = 64K BLOCK | ||
| 323 | MOV CX,1 ;***jnw ;1 * 4K = 4K BLOCK | ||
| 324 | CALL SETXLAT ;SET TRANSLATE TABLE | ||
| 325 | ; | ||
| 326 | MOV AX,CS:PAGE_FRAME_STA | ||
| 327 | MOV DS,AX ;SET SEGMENT AND | ||
| 328 | MOV SI,0 ;OFFSET TO TEST | ||
| 329 | MOV BX,0000000000000001B ;ROLL 1 THROUGH WORD | ||
| 330 | MOV DX,1111111111111110B ;ROLL 0 THROUGH WORD | ||
| 331 | MOV CX,16 ;16 BITS TO TEST | ||
| 332 | TR2M2: | ||
| 333 | MOV [SI],BX ;WRITE ROLLING 1 PATTERN | ||
| 334 | LOCK MOV [SI+2],DX ;CHARGE BUS INVERSE PATTERN | ||
| 335 | LOCK MOV AX,[SI] ;READ BACK INITIAL PATTERN | ||
| 336 | AND AX,BX ;ISOLATE BIT UNDER TEST | ||
| 337 | ;***jnw JZ TR2M3 ;IF ZERO TRY ANOTHER BIT | ||
| 338 | JZ quit ;IF ZERO quit ***jnw | ||
| 339 | MOV [SI],DX ;WRITE ROLLING 0 PATTERN | ||
| 340 | LOCK MOV [SI+2],BX ;CHARGE BUS INVERSE PATTERN | ||
| 341 | LOCK MOV AX,[SI] ;READ BACK INITIAL PATTERN | ||
| 342 | AND AX,BX ;ISOLATE BIT UNDER TEST | ||
| 343 | AND AX,BX ;ISOLATE BIT UNDER TEST | ||
| 344 | ;***jnw JZ TR2M4 ;IF ZERO THEN FOUND GOOD BIT | ||
| 345 | Jnz quit ;IF nonzero then quit ***jnw | ||
| 346 | TR2M3: | ||
| 347 | ROL BX,1 ;ROLL 1 TO NEXT POSITION | ||
| 348 | ROL DX,1 ;ROLL 0 TO NEXT POSITION | ||
| 349 | LOOP TR2M2 ;REPEAT FOR 16 BITS | ||
| 350 | jmp tr2m4 ;all 16 bits passed test ***jnw | ||
| 351 | quit: ;***jnw | ||
| 352 | ;AT THIS POINT THERE ARE NO GOOD BITS SO END SEARCH FOR NEXT MB | ||
| 353 | POP DX ;RECOVER THESES REGISTERS | ||
| 354 | POP CX | ||
| 355 | POP BX | ||
| 356 | POP AX | ||
| 357 | JMP TR2M5 ;EXIT | ||
| 358 | ;AT THIS POINT WE KNOW THERE IS MEMORY IN THIS MEG THAT WAS JUST TESTED | ||
| 359 | TR2M4: | ||
| 360 | ;***jnw ADD CS:MEM_INST,1 ;ADD 1 MB TO THIS FLAG | ||
| 361 | ;***jnw ADD CS:TOTAL_XMA_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG | ||
| 362 | ;***jnw ADD CS:TOTAL_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG | ||
| 363 | ;***jnw ADD CS:FREE_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG | ||
| 364 | ADD CS:TOTAL_SYS_PAGES,1 ;Add 16k ***jnw | ||
| 365 | ADD CS:TOTAL_EMS_PAGES,1 ;Add 16k ***jnw | ||
| 366 | ADD CS:FREE_PAGES,1 ;Add 16k ***jnw | ||
| 367 | POP DX ;RECOVER THESE REGISTERS | ||
| 368 | POP CX | ||
| 369 | POP BX | ||
| 370 | POP AX | ||
| 371 | ;***jnw ADD DX,256 ;TRY NEXT MB | ||
| 372 | ADD DX,4 ;TRY NEXT 16k ***jnw | ||
| 373 | LOOP TR2M1A ;REPEAT LOOP | ||
| 374 | TR2M5: | ||
| 375 | ;BEFORE NMI IS ENABLED, CLEAR PARITY CHECK LATCH ON XMA | ||
| 376 | MOV SI,0 | ||
| 377 | MOV AX,[SI] ;READ 1ST WORD OF THIS SEG | ||
| 378 | MOV [SI],AX ;WRITE BACK SAME WORD | ||
| 379 | ;THE WRITE WILL CLEAR PCHK LTCH | ||
| 380 | ;PUT THE XMA CARD BACK INTO REAL MODE | ||
| 381 | MOV DX,MODE_REG ;READY FOR I/O TO MODE REG | ||
| 382 | IN AL,DX ;READ IT | ||
| 383 | AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT | ||
| 384 | OUT DX,AL ;WRITE IT TO MODE REG | ||
| 385 | ;CLEAR I/O CHANNEL CHECK LATCHES AND ENABLE NMI | ||
| 386 | MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE | ||
| 387 | CMP AL,PC1 ;IS IT A PC1? | ||
| 388 | JE TR2M6 ;USE XT REGISTERS | ||
| 389 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 390 | JE TR2M6 ;USE XT REGISTERS | ||
| 391 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 392 | JE TR2M6 ;USE XT REGISTERS | ||
| 393 | ;IF NONE OF THE ABOVE THEN... | ||
| 394 | ;USE AT NMI REGISTER | ||
| 395 | MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG | ||
| 396 | IN AL,DX ;READ IT | ||
| 397 | OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 398 | OUT DX,AL ;WRITE IT | ||
| 399 | AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 400 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 401 | ;ENABLED | ||
| 402 | MOV DX,AT_NMI_REG ;AT's NMI REGISTER | ||
| 403 | MOV AL,AT_NMI_ON ;MASK ON NMI | ||
| 404 | OUT DX,AL ;OUTPUT IT | ||
| 405 | ;USE XT/AQUARIUS NMI REGISTER | ||
| 406 | TR2M6: | ||
| 407 | MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG | ||
| 408 | IN AL,DX ;READ IT | ||
| 409 | OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 410 | OUT DX,AL ;WRITE IT | ||
| 411 | AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 412 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 413 | ;ENABLED | ||
| 414 | MOV DX,XT_NMI_REG ;XT's NMI REGISTER | ||
| 415 | MOV AL,XT_NMI_ON ;MASK ON NMI | ||
| 416 | OUT DX,AL ;OUTPUT IT | ||
| 417 | ; | ||
| 418 | RET ;RETURN TO CALLER | ||
| 419 | |||
| 420 | TRY4MEG ENDP | ||
| 421 | |||
| 422 | |||
| 423 | PAGE | ||
| 424 | ;------------------------------------------------------------------------- | ||
| 425 | ;------------------------------------------------------------------------- | ||
| 426 | ; | ||
| 427 | ; REGISTER TESTS | ||
| 428 | ; | ||
| 429 | ; DESCRIPTION : This routine will test the following subset | ||
| 430 | ; of XMA registers: | ||
| 431 | ; 31A0...8 bits | ||
| 432 | ; 31A1...4 bits | ||
| 433 | ; 31A6...4 bits | ||
| 434 | ; 31A7...4 bits (BIT 1 IS HELD LOW TO DISABLE | ||
| 435 | ; THE VIRTUAL MODE) | ||
| 436 | ; | ||
| 437 | ; The test is performed by writing and reading | ||
| 438 | ; AA, 55, FF, 00 from each of the above locations. | ||
| 439 | ; | ||
| 440 | ; NOTE: Regs 31A6 and 31A7 should always return 0 in | ||
| 441 | ; the high nibble. | ||
| 442 | ; | ||
| 443 | ; The remainding registers will be tested in | ||
| 444 | ; subsequent routines. | ||
| 445 | ; | ||
| 446 | ; | ||
| 447 | ; FUNCTION/ : To ensure integrity of XMA registers that will be used | ||
| 448 | ; PURPOSE in subsequent routines. | ||
| 449 | ; | ||
| 450 | ; ENTRY POINT : REGTST | ||
| 451 | ; | ||
| 452 | ; ENTRY : none | ||
| 453 | ; CONDITIONS | ||
| 454 | ; | ||
| 455 | ; EXIT : XMA registers are set to zero | ||
| 456 | ; | ||
| 457 | ; (zero flag) = 0 indicates an error | ||
| 458 | ; (DX) failing register | ||
| 459 | ; (AL) expected data XOR'ed with actual data | ||
| 460 | ; | ||
| 461 | ;------------------------------------------------------------------------- | ||
| 462 | ; | ||
| 463 | REGTST PROC | ||
| 464 | ; | ||
| 465 | MOV AL,REG_TEST | ||
| 466 | MOV CS:TEST_ID,AL | ||
| 467 | |||
| 468 | ;SAVE CONTENTS OF MODE REG | ||
| 469 | MOV DX,MODE_REG | ||
| 470 | IN AL,DX | ||
| 471 | PUSH AX | ||
| 472 | |||
| 473 | ; TRANSLATE TABLE ADDRESS AND DATA REGISTERS | ||
| 474 | ; | ||
| 475 | MOV BX,0AA55H ;SET UP INITIAL DATA PATTERN | ||
| 476 | MOV AX,BX | ||
| 477 | MOV CX,BX | ||
| 478 | |||
| 479 | R1: | ||
| 480 | MOV DX,TTPOINTER ;FIRST REGISTER PAIR TO WRITE | ||
| 481 | |||
| 482 | OUT DX,AX ;WRITE PATTERN TO REGS | ||
| 483 | ADD DX,6 ;POINT TO NEXT REG PAIR | ||
| 484 | XCHG AL,AH ;SETUP INVERSE PATTERN | ||
| 485 | AND AH,11111101B ;MASK OFF BIT 1 | ||
| 486 | OUT DX,AX ;BECAUSE AH -> 21B7 | ||
| 487 | R2: | ||
| 488 | SUB DX,6 ;POINT TO FIRST REGISTER PAIR | ||
| 489 | IN AX,DX ;READ REGISTER (21B1 -> AH) | ||
| 490 | XOR AX,BX ;DATA READ AS EXPECTED ? | ||
| 491 | AND AX,0FFFH ;MASK OFF UPPER NIBBLE OF 21B1 | ||
| 492 | JNE R_ERROR ;MISMATCH - GO TO ERROR ROUTINE | ||
| 493 | XCHG BH,BL ;NEXT PATTERN TO TEST | ||
| 494 | AND BX,0F0FH ;REGS RETURN 0 IN HI NIBBLE | ||
| 495 | ADD DX,6 ;POINT TO NEXT REGISTER PAIR | ||
| 496 | IN AX,DX ;READ IT (21B7 -> AH) | ||
| 497 | XOR AX,BX ;DATA READ AS EXPECTED ? | ||
| 498 | AND AX,0DFFH ;MASK OFF BIT 1 IN REG 21B7 | ||
| 499 | JNE R_ERROR ;MISMATCH - GO TO ERROR ROUTINE | ||
| 500 | ; | ||
| 501 | CMP CH,CL ;LAST PASS ? | ||
| 502 | JE R_EXIT ;YES - THEN EXIT REG TEST | ||
| 503 | ; | ||
| 504 | CMP CX,055AAH ;END OF AA55,55AA PATTERNS? | ||
| 505 | JNE R3 ; | ||
| 506 | MOV CX,000FFH ;SET UP NEXT VALUE TO WRITE | ||
| 507 | JMP R4 | ||
| 508 | R3: | ||
| 509 | CMP CX,00FFH ;END OF FF00,00FF PATTERNS? | ||
| 510 | JNE R4 ; | ||
| 511 | MOV CX,0 ;YES, THEN SET UP FOR LAST PASS | ||
| 512 | R4: | ||
| 513 | XCHG CL,CH ;SET UP INVERSE PATTERN | ||
| 514 | MOV AX,CX ;SAVE IT | ||
| 515 | MOV BX,CX ;SAVE IT | ||
| 516 | R5: | ||
| 517 | JMP R1 ;CONTINUE TILL ZERO PATTERN | ||
| 518 | |||
| 519 | R_ERROR: | ||
| 520 | R_EXIT: | ||
| 521 | POP AX | ||
| 522 | MOV DX,MODE_REG | ||
| 523 | OUT DX,AL ;restore mode reg | ||
| 524 | RET | ||
| 525 | ; | ||
| 526 | REGTST ENDP | ||
| 527 | |||
| 528 | |||
| 529 | |||
| 530 | |||
| 531 | PAGE | ||
| 532 | ;------------------------------------------------------------------------- | ||
| 533 | ;------------------------------------------------------------------------- | ||
| 534 | ; | ||
| 535 | ; MEMORY ARRAY TEST | ||
| 536 | ; | ||
| 537 | ; DESCRIPTION : This routine test all 1Meg (or 2Meg) of XMA memory | ||
| 538 | ; through a 64K window in PC space beginning at PF:0 | ||
| 539 | ; (where PF is the Page Frame Segment) | ||
| 540 | ; This module looks at TOTAL_SYS_PAGES | ||
| 541 | ; to determine the memory size to be tested. | ||
| 542 | ; | ||
| 543 | ; (i) write the Translate Table for the 1st 64K block | ||
| 544 | ; of XMA memory to be mapped into PF:0 in PC space | ||
| 545 | ; (ii) test PF:0 to PF:FFFF | ||
| 546 | ; (iii) if good...write Translate Table to map next 64K block | ||
| 547 | ; into PF:0 | ||
| 548 | ; (iv) repeat 'till all XMA memory is tested | ||
| 549 | ; | ||
| 550 | ; FUNCTION/ : See description | ||
| 551 | ; PURPOSE | ||
| 552 | ; | ||
| 553 | ; | ||
| 554 | ; ENTRY POINT : MEMARRAY | ||
| 555 | ; | ||
| 556 | ; ENTRY : | ||
| 557 | ; CONDITIONS | ||
| 558 | ; | ||
| 559 | ; EXIT : All SMAS memory is set to zero. | ||
| 560 | ; | ||
| 561 | ; (zero flag) = 0 if storage error | ||
| 562 | ; (AX) expected data XOR'ed with actual data | ||
| 563 | ; if AX = 0 and ZF = 0 then parity error | ||
| 564 | ; DS:SI point to failing location | ||
| 565 | ; CS:PAGE_UNDER_TEST point failing 64k block | ||
| 566 | ; | ||
| 567 | ; AX,BX,CX,DX,DS,ES,SI,DI ARE DESTROYED | ||
| 568 | ; | ||
| 569 | ;------------------------------------------------------------------------- | ||
| 570 | |||
| 571 | MEMARRAY PROC | ||
| 572 | |||
| 573 | MOV AL,MEM_TEST | ||
| 574 | MOV CS:TEST_ID,AL | ||
| 575 | |||
| 576 | ;MEMORY TEST MUST RUN IN PAGE MODE | ||
| 577 | |||
| 578 | CALL VIRT2REAL | ||
| 579 | |||
| 580 | ;INDICATE 0 KB OK | ||
| 581 | MOV DX,(640-16)/4 ;CODE FOR 640 KB OK | ||
| 582 | CALL KB_OK | ||
| 583 | ;SETUP FOR TEST OF SMAS MEMORY ARRAY | ||
| 584 | MOV AX,CS:PAGE_FRAME_STA ;PAGE MEMORY FROM THIS SEGMENT | ||
| 585 | MOV ES,AX ;SET UP DEST SEG | ||
| 586 | MOV DS,AX ;SET UP SOURCE SEG | ||
| 587 | MOV BL,01H ;ENABLE THIS BLOCK OF MEMORY | ||
| 588 | MOV BH,0 ;USING ID 0 | ||
| 589 | MOV DX,(640)/4 ;STARTING BLK IN SMAS ARRAY | ||
| 590 | ;DETERMINE HOW MUCH MEMORY TO TEST | ||
| 591 | MOV CX,CS:TOTAL_SYS_PAGES ;GET NUMBER OF 16K PAGES | ||
| 592 | SUB CX,640/16 ;SUBTRACT OFF 1ST 640K MEMORY ;an000; dms; | ||
| 593 | ;BEGIN TEST | ||
| 594 | MA1: | ||
| 595 | MOV CS:PAGE_UNDER_TEST,DX ;INDICATE WHICH 64K BLOCK | ||
| 596 | PUSH AX ;IS UNDER TEST | ||
| 597 | PUSH BX | ||
| 598 | PUSH CX | ||
| 599 | PUSH DX ;SAVE ALL REGISTERS | ||
| 600 | ; | ||
| 601 | MOV CX,4 ;test 16k at one time ;an000; dms; | ||
| 602 | ;4 x 4K = 16K | ||
| 603 | CALL SETXLAT ;SET UP XLAT TABLE | ||
| 604 | CALL STGTST ;TEST 64K OF STORAGE | ||
| 605 | JNZ MA2 ;WAS THERE AN ERROR | ||
| 606 | POP DX | ||
| 607 | POP CX | ||
| 608 | POP BX | ||
| 609 | POP AX ;RESTORE REGISTERS | ||
| 610 | ; | ||
| 611 | PUSHF ;SAVE FLAGS FOR ADDITION | ||
| 612 | |||
| 613 | CALL KB_OK ;INDICATE HOW MUCH | ||
| 614 | ;MEMORY HAS BEEN TESTED | ||
| 615 | |||
| 616 | |||
| 617 | ADD DX,4 ;POINT TO NEXT 64K BLOCK | ||
| 618 | POPF ;RESTORE FLAGS | ||
| 619 | LOOP MA1 ;LOOP FOR NEXT 64K | ||
| 620 | JMP MA3 ;EXIT WHEN COMPLETE | ||
| 621 | MA2: | ||
| 622 | POP DX | ||
| 623 | POP CX | ||
| 624 | POP BX ;BX IS POPPED TWICE | ||
| 625 | POP BX ;TO RESTORE STACK WHILE | ||
| 626 | ;MAINTAINING AX | ||
| 627 | MA3: | ||
| 628 | PUSH AX | ||
| 629 | PUSH DX | ||
| 630 | PUSHF ;SAVE THESE REGS...THEY CONTAIN | ||
| 631 | ;USEFULL ERROR INFO | ||
| 632 | ;PUT THE SMAS CARD INTO REAL MODE | ||
| 633 | MOV DX,MODE_REG ;READY FOR I/O TO MODE REG | ||
| 634 | IN AL,DX ;READ IT | ||
| 635 | AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT | ||
| 636 | OUT DX,AL ;WRITE IT TO MODE REG | ||
| 637 | POPF | ||
| 638 | POP DX | ||
| 639 | POP AX ;RESTORE THESE REGS | ||
| 640 | RET | ||
| 641 | ; | ||
| 642 | MEMARRAY ENDP | ||
| 643 | |||
| 644 | |||
| 645 | |||
| 646 | |||
| 647 | PAGE | ||
| 648 | ;--------------------------------------------------------------------- | ||
| 649 | ;--------------------------------------------------------------------- | ||
| 650 | ; LO MEMORY TEST | ||
| 651 | ; | ||
| 652 | ; DESCRIPTION : This routine tests the first 256K or 512K | ||
| 653 | ; of XMA memory depending on the starting | ||
| 654 | ; position of the starting address jumper on | ||
| 655 | ; the card. The memory that is used to | ||
| 656 | ; fill conventional memory space is not tested | ||
| 657 | ; it is tested during POST and may now contain | ||
| 658 | ; parts of COMMAND.COM. | ||
| 659 | ; | ||
| 660 | ; FUNCTION/ : See description | ||
| 661 | ; PURPOSE | ||
| 662 | ; | ||
| 663 | ; ENTRY POINT : LOMEMTST | ||
| 664 | ; | ||
| 665 | ; ENTRY : | ||
| 666 | ; CONDITIONS | ||
| 667 | ; | ||
| 668 | ; EXIT : All tested memory is set to zero | ||
| 669 | ; | ||
| 670 | ; (zero flag) = 0 if storage error | ||
| 671 | ; (AX) = expected data XOR'ed with actual data | ||
| 672 | ; if (AX)=0 and ZF=0 then parity error | ||
| 673 | ; DS:SI point to failing location | ||
| 674 | ; CS:PAGE_UNDER_TEST point to failing 64K block | ||
| 675 | ; | ||
| 676 | ; AX,BX,CX,DX,DI,SI,ES,DS ARE DESTROYED | ||
| 677 | ; | ||
| 678 | ;----------------------------------------------------------------------- | ||
| 679 | LOMEMTST PROC | ||
| 680 | |||
| 681 | MOV AL,LOMEM_TEST | ||
| 682 | MOV CS:TEST_ID,AL | ||
| 683 | |||
| 684 | ;MEMORY TEST MUST RUN IN PAGE MODE | ||
| 685 | CALL VIRT2REAL | ||
| 686 | |||
| 687 | ;INDICATE 0 KB OK AT START OF TEST | ||
| 688 | MOV DX,03ffcH ;code for initial 0 kb ;an000; dms; | ||
| 689 | CALL KB_OK | ||
| 690 | |||
| 691 | ;DETERMINE HOW MUCH MEMORY TO TEST | ||
| 692 | MOV AX,CS:START_BACMEM_SEG ;get starting fill segment | ||
| 693 | XCHG AH,AL | ||
| 694 | MOV CL,2 ; ;an000; dms; | ||
| 695 | SHR AX,CL ;convert to 16k block number | ||
| 696 | MOV CS:TESTABLE_SEGMENTS,AX ;save...this is number of 64k blocks | ||
| 697 | ;that can be tested without | ||
| 698 | ;destroying DOS | ||
| 699 | ;SET UP FOR TEST OF XMA MEMORY | ||
| 700 | MOV AX,CS:PAGE_FRAME_STA ;test through page frame | ||
| 701 | MOV DS,AX ;set up ds | ||
| 702 | MOV ES,AX ;and es | ||
| 703 | MOV BL,01H ;enable this block of memory | ||
| 704 | MOV BH,0 ;using id=0 | ||
| 705 | XOR DX,DX ;start at block 0 in xma | ||
| 706 | MOV CX,640/16 ;loop counter is # 16k blocks in | ||
| 707 | ;conventional memory | ||
| 708 | LM1: | ||
| 709 | MOV CS:PAGE_UNDER_TEST,DX ;save page under test | ||
| 710 | PUSH AX | ||
| 711 | PUSH BX | ||
| 712 | PUSH CX | ||
| 713 | PUSH DX ;save these registers | ||
| 714 | |||
| 715 | MOV CX,4 ;test 16k at one time ;an000; dms; | ||
| 716 | ;4 * 4k = 16k | ||
| 717 | CALL SETXLAT ;set translate table | ||
| 718 | CMP CS:TESTABLE_SEGMENTS,0 ;if this segment under test is used for | ||
| 719 | ;fill then read only | ||
| 720 | JG LM2 ;else do storage test | ||
| 721 | CALL READ_ONLY | ||
| 722 | JMP LM3 | ||
| 723 | LM2: | ||
| 724 | CALL STGTST | ||
| 725 | LM3: | ||
| 726 | JNZ LM4 ;jump if there was an error | ||
| 727 | POP DX | ||
| 728 | POP CX | ||
| 729 | POP BX | ||
| 730 | POP AX ;recover registers | ||
| 731 | |||
| 732 | PUSHF ;save flags for addition | ||
| 733 | CALL KB_OK | ||
| 734 | ;indicate kb ok | ||
| 735 | ADD DX,4 ;next 16k block ;an000; dms; | ||
| 736 | DEC CS:TESTABLE_SEGMENTS ;dec testable pages | ||
| 737 | POPF ;recover flags | ||
| 738 | LOOP LM1 ;repeat for next 64k block | ||
| 739 | JMP LM5 ;exit when complete | ||
| 740 | LM4: | ||
| 741 | POP DX ;recover these registers | ||
| 742 | POP CX | ||
| 743 | POP BX ;bx is popped twice to restore | ||
| 744 | POP BX ;satck while maintaining ax | ||
| 745 | LM5: | ||
| 746 | PUSH AX ;save these ... they contain | ||
| 747 | PUSH DX ;useful error information | ||
| 748 | PUSHF | ||
| 749 | ;PUT CARD BACK TO REAL MODE | ||
| 750 | MOV DX,MODE_REG ;read mode reg | ||
| 751 | IN AL,DX | ||
| 752 | AND AL,REAL_MODE ;turn off virtual bit | ||
| 753 | OUT DX,AL ;write it to mode reg | ||
| 754 | POPF | ||
| 755 | POP DX | ||
| 756 | POP AX ;restore these registers | ||
| 757 | RET | ||
| 758 | |||
| 759 | |||
| 760 | READ_ONLY PROC ;INTERNAL PROC TO READ MEMORY WITHOUT DESTROYING CONTENTS | ||
| 761 | XOR SI,SI ;start of segment | ||
| 762 | XOR CX,CX ;test 64k | ||
| 763 | |||
| 764 | LODSW ;just read each byte | ||
| 765 | XOR AX,AX ;and set zf=1 for return | ||
| 766 | RET ;back to caller | ||
| 767 | READ_ONLY ENDP | ||
| 768 | |||
| 769 | LOMEMTST ENDP | ||
| 770 | |||
| 771 | |||
| 772 | |||
| 773 | PAGE | ||
| 774 | ;------------------------------------------------------------------------- | ||
| 775 | ;------------------------------------------------------------------------- | ||
| 776 | ; | ||
| 777 | ; PAGE TEST | ||
| 778 | ; | ||
| 779 | ; DESCRIPTION : This routine tests that the TASK ID register is | ||
| 780 | ; actually paging in unique segments of memory. | ||
| 781 | ; The test is performed through the page frame segment. | ||
| 782 | ; The test assumes that the memory test has already | ||
| 783 | ; completed successfully. The page test procedes as | ||
| 784 | ; follows: | ||
| 785 | ; (i) 6-64K blocks of XMA memory are mapped into a | ||
| 786 | ; 64K segment of PC space (the page frame) | ||
| 787 | ; These XMA blocks are from 640k to 1024k of XMA memory. | ||
| 788 | ; (ii) Each of these blocks is assigned to a unique | ||
| 789 | ; task ID ranging from 0 to 5. | ||
| 790 | ; (iii) For each task ID, the page frame is filled with | ||
| 791 | ; a pattern that is the same as the task ID. | ||
| 792 | ; (iv) The page frame is then read for each task ID | ||
| 793 | ; and compared with the expected data. | ||
| 794 | ; | ||
| 795 | ; FUNCTION/ : | ||
| 796 | ; PURPOSE | ||
| 797 | ; | ||
| 798 | ; ENTRY POINT : PAGETST | ||
| 799 | ; | ||
| 800 | ; ENTRY : NONE | ||
| 801 | ; CONDITIONS | ||
| 802 | ; | ||
| 803 | ; EXIT : (zero flag) = 0 indicates an error | ||
| 804 | ; (AL) expected data XOR'ed with actual data | ||
| 805 | ; | ||
| 806 | ; AX,BX,CX,DX,ES,DS,SI,DI ARE DESTROYED | ||
| 807 | ;------------------------------------------------------------------------- | ||
| 808 | ; | ||
| 809 | PAGETST PROC | ||
| 810 | ; | ||
| 811 | MOV AL,PAGE_TEST | ||
| 812 | MOV CS:TEST_ID,AL | ||
| 813 | ;MEMORY TEST MUST RUN IN PAGE MODE | ||
| 814 | CALL VIRT2REAL | ||
| 815 | ;INITIALIZE TRANSLATE TABLE FOR THIS TEST | ||
| 816 | MOV AX,CS:PAGE_FRAME_STA ;SEMENT OF PAGE FRAME | ||
| 817 | MOV BL,01H ;ENABLE CODE | ||
| 818 | MOV BH,0 ;START WITH TASK ID = 0 | ||
| 819 | MOV DX,640/4 ;START WITH XMA BLOCK 160 | ||
| 820 | MOV CX,6 ;LOOP COUNT...6 TASK ID's | ||
| 821 | ;EACH TASK ID IS ASSIGNED 16K | ||
| 822 | ;FROM 640K TO 1024K | ||
| 823 | PT1: | ||
| 824 | PUSH AX | ||
| 825 | PUSH BX | ||
| 826 | PUSH CX | ||
| 827 | PUSH DX ;SAVE ALL REGISTERS | ||
| 828 | ; | ||
| 829 | MOV CX,4 ;4 -4K BLOCKS IN 16K ;an000; dms; | ||
| 830 | CALL SETXLAT ;SET TRANSLATE TABLE | ||
| 831 | POP DX | ||
| 832 | POP CX | ||
| 833 | POP BX | ||
| 834 | POP AX ;RECOVER ALL | ||
| 835 | INC BH ;POINT TO NEXT TASK ID | ||
| 836 | ADD DX,4 ;NEXT 64K IN XMA MEMORY ;an000; dms; | ||
| 837 | LOOP PT1 ;REPEAT FOR ALL TASK ID's | ||
| 838 | ;FILL MEMORY WITH A UNIQUE PATTERN FOR EACH TASK ID | ||
| 839 | MOV CX,6 ;6 TASK ID's | ||
| 840 | MOV DX,IDREG ;READY FOR I/O TO TASK ID REG | ||
| 841 | MOV AL,0 ;START WITH ID = 0 | ||
| 842 | PT2: | ||
| 843 | PUSH AX ;SAVE ID NUMBER | ||
| 844 | PUSH CX ;SAVE ID COUNT | ||
| 845 | OUT DX,AL ;SWITCH TASK ID | ||
| 846 | MOV BX,CS:PAGE_FRAME_STA | ||
| 847 | MOV ES,BX ;SEGMENT TO 1ST 64K 0F ID | ||
| 848 | SUB DI,DI ;POINT TO 1ST LOCATION | ||
| 849 | mov cx,4000h ;WRITE ALL 16K LOCATIONS ;an000; dms; | ||
| 850 | PT2X: | ||
| 851 | STOSB | ||
| 852 | LOOP PT2X | ||
| 853 | POP CX ;RECOVER ID COUNT | ||
| 854 | POP AX ;RECOVER CURRENT ID | ||
| 855 | INC AL | ||
| 856 | LOOP PT2 ;REPEAT FOR ALL TASK ID's | ||
| 857 | ;NOW CHECK THAT THERE ARE 16 UNIQUE PATTERNS IN MEMORY | ||
| 858 | MOV CX,6 ;USE 6 TASK ID's | ||
| 859 | MOV AH,0 ;START WITH ID = 0 | ||
| 860 | PT3: | ||
| 861 | MOV AL,AH ;GET TASK ID IN AL | ||
| 862 | PUSH AX | ||
| 863 | PUSH CX ;SAVE ID COUNT | ||
| 864 | OUT DX,AL ;SWITCH TASK ID | ||
| 865 | MOV BX,CS:PAGE_FRAME_STA | ||
| 866 | MOV DS,BX | ||
| 867 | MOV ES,BX ;SEGMENT AT 1ST 64K | ||
| 868 | SUB DI,DI ;POINT TO 1ST LOCATION | ||
| 869 | SUB SI,SI ;POINT TO 1ST LOCATION | ||
| 870 | mov cx,4000h ;READ ALL 16K LOCATIONS | ||
| 871 | PT3X: | ||
| 872 | LODSB | ||
| 873 | XOR AL,AH ;DATA AS EXPECTED ? | ||
| 874 | JNE PT4X ;NO - THEN EXIT | ||
| 875 | STOSB ;AL SHOULD CONTAIN 0...WRITE IT | ||
| 876 | LOOP PT3X | ||
| 877 | |||
| 878 | POP CX ;RECOVER ID COUNT | ||
| 879 | POP AX | ||
| 880 | INC AH ;NEXT TASK ID | ||
| 881 | LOOP PT3 ;REPEAT FOR ALL TASK ID's | ||
| 882 | XOR AL,AL ;IF WE GOT THIS FAR THEN | ||
| 883 | ;NO ERRORS...SET ZF TO | ||
| 884 | ;INDICATE SUCCESS | ||
| 885 | PT4: | ||
| 886 | PUSH AX | ||
| 887 | PUSH DX | ||
| 888 | PUSHF ;SAVE THESE REGS...THEY CONTAIN | ||
| 889 | ;USEFULL ERROR INFO | ||
| 890 | ;PUT THE SMAS CARD INTO REAL MODE | ||
| 891 | MOV DX,MODE_REG ;READY FOR I/O TO MODE REG | ||
| 892 | IN AL,DX ;READ IT | ||
| 893 | AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT | ||
| 894 | OUT DX,AL ;WRITE IT TO MODE REG | ||
| 895 | ;MAKE SURE WE EXIT WHILE IN TASK ID=0 | ||
| 896 | MOV DX,IDREG | ||
| 897 | XOR AL,AL | ||
| 898 | OUT DX,AL | ||
| 899 | |||
| 900 | POPF | ||
| 901 | POP DX | ||
| 902 | POP AX ;RESTORE THESE REGS | ||
| 903 | RET ;RETURN TO CALLER | ||
| 904 | PT4X: | ||
| 905 | POP CX ;ALTERNATE RETURN PATH | ||
| 906 | POP AX | ||
| 907 | JMP PT4 ;TO ADJUST STACK | ||
| 908 | ; | ||
| 909 | PAGETST ENDP | ||
| 910 | |||
| 911 | |||
| 912 | PAGE | ||
| 913 | ;------------------------------------------------------------------------- | ||
| 914 | ;------------------------------------------------------------------------- | ||
| 915 | ; | ||
| 916 | ; DMA CAPTURE TEST | ||
| 917 | ; | ||
| 918 | ; DESCRIPTION : This routine is a test of the DMA capture logic. | ||
| 919 | ; The test is as follows: | ||
| 920 | ; (i) A bit is rolled through the second entry in the | ||
| 921 | ; DMA cature register file. (The first entry is used | ||
| 922 | ; for refresh on a PC-XT). | ||
| 923 | ; (ii) A bit and address test is performed on the | ||
| 924 | ; remainder of the register file(s). | ||
| 925 | ; (iii) A test is made for the capture of both REQUEST and | ||
| 926 | ; MODE registers of the DMA controller. | ||
| 927 | ; (iv) DMA channel 0 is tested only on the PC-AT | ||
| 928 | ; | ||
| 929 | ; | ||
| 930 | ; FUNCTION/ : To verify the functionality of the DMA capture logic. | ||
| 931 | ; PURPOSE | ||
| 932 | ; | ||
| 933 | ; ENTRY POINT : CAPTST | ||
| 934 | ; | ||
| 935 | ; ENTRY : NONE | ||
| 936 | ; CONDITIONS | ||
| 937 | ; | ||
| 938 | ; EXIT : Each entry in the DMA capture register file is set to 0. | ||
| 939 | ; | ||
| 940 | ; (zero flag) = 0 indicates an error | ||
| 941 | ; '31A8'X points to failing DMA capture reg | ||
| 942 | ; (AL) expected data XOR'ed with actual data | ||
| 943 | ; | ||
| 944 | ; AX,BX,CX,DX,SI,DI ARE DESTROYED | ||
| 945 | ;------------------------------------------------------------------------- | ||
| 946 | ; | ||
| 947 | ; | ||
| 948 | CAPTST PROC | ||
| 949 | ; | ||
| 950 | MOV AL,DMA_CAPTURE | ||
| 951 | MOV CS:TEST_ID,AL | ||
| 952 | ; | ||
| 953 | ;ROLL A BIT THROUGH THE SECOND ENTRY IN THE DMA CAPTURE REGISTER FILE | ||
| 954 | ; | ||
| 955 | MOV BL,01H ;SET UP INITIAL PATTERN | ||
| 956 | MOV BH,01H ;SET UP DMA CHANNEL 1 | ||
| 957 | MOV DI,DMACAPT ;SAVE FOR I/O TO DMA CAPTURE REG | ||
| 958 | MOV SI,DMAREQ1 ;SAVE FOR I/O TO DMA CTRL 1 REQ REG | ||
| 959 | MOV CX,4 ;ROLL 4 BIT POSITIONS | ||
| 960 | C1: | ||
| 961 | MOV DX,IDREG ;I/O TO ID REG | ||
| 962 | MOV AL,BL ;PATTERN TO WRITE | ||
| 963 | OUT DX,AX ;SETUP ID REG WITH DATA PATTERN | ||
| 964 | MOV DX,SI ;DMA CTRL 1 | ||
| 965 | MOV AL,BH ;CHANNEL 1 | ||
| 966 | OUT DX,AL ;SETUP DMA CH 1...CAPT ID IN 2nd ENTRY | ||
| 967 | MOV DX,DI ;DMA CAPTURE REG | ||
| 968 | OUT DX,AL ;POINT TO 2nd ENTRY | ||
| 969 | IN AL,DX ;READ IT | ||
| 970 | XOR AL,BL ;DATA READ AS EXPECTED ? | ||
| 971 | JNE CAPT_ERROR ;NO - THEN ERROR | ||
| 972 | SHL BL,1 ;SHIFT BIT TO NEXT POSITION | ||
| 973 | LOOP C1 ;REPEAT | ||
| 974 | ; | ||
| 975 | MOV DI,DMAREQ2 ;SETUP FOR I/O TO DMA CTRL 2 REQ REG | ||
| 976 | MOV AL,05H ;DATA PATTERN TO CAPTURE | ||
| 977 | CALL CAPT_FILL ;FILL CAPTURE REGS WITH VALUE | ||
| 978 | ; | ||
| 979 | MOV AH,05H ;SETUP INITIAL PATTERN | ||
| 980 | MOV BX,0F0AH ;OTHER PATTERNS TO USE | ||
| 981 | C2: | ||
| 982 | CALL CAPT_RMW | ||
| 983 | JNZ CAPT_ERROR ;ERROR - THEN EXIT | ||
| 984 | CMP AH,BL ;ZERO PATTERN ? | ||
| 985 | JE CAPT_EXIT ;EXIT IF YES | ||
| 986 | MOV AH,BL ;SET UP | ||
| 987 | MOV BL,BH ; NEXT | ||
| 988 | MOV BH,0 ; PATTERN | ||
| 989 | JMP C2 ;REPEAT | ||
| 990 | |||
| 991 | ;NOW REPEAT TEST FOR CATPURE OF DMA MODE REGISTERS | ||
| 992 | MOV SI,DMAMODE1 ;SETUP FOR I/O TO DMA CTRL 1 MODE REG | ||
| 993 | MOV DI,DMAMODE2 ;SETUP FOR I/O TO DMA CTRL 2 MODE REG | ||
| 994 | MOV AL,05H ;DATA PATTERN TO CAPTURE | ||
| 995 | CALL CAPT_FILL ;FILL CAPTURE REGS WITH VALUE | ||
| 996 | ; | ||
| 997 | MOV AH,05H ;SETUP INITIAL PATTERN | ||
| 998 | MOV BX,0F0AH ;OTHER PATTERNS TO USE | ||
| 999 | C3: | ||
| 1000 | CALL CAPT_RMW | ||
| 1001 | JNZ CAPT_ERROR ;ERROR - THEN EXIT | ||
| 1002 | CMP AH,BL ;ZERO PATTERN ? | ||
| 1003 | JE CAPT_EXIT ;EXIT IF YES | ||
| 1004 | MOV AH,BL ;SET UP | ||
| 1005 | MOV BL,BH ; NEXT | ||
| 1006 | MOV BH,0 ; PATTERN | ||
| 1007 | JMP C3 ;REPEAT | ||
| 1008 | CAPT_ERROR: | ||
| 1009 | CAPT_EXIT: | ||
| 1010 | RET | ||
| 1011 | |||
| 1012 | CAPTST ENDP | ||
| 1013 | |||
| 1014 | |||
| 1015 | |||
| 1016 | PAGE | ||
| 1017 | |||
| 1018 | ;------------------------------------------------------------------------- | ||
| 1019 | ;------------------------------------------------------------------------- | ||
| 1020 | ; | ||
| 1021 | ; FILL DMA CAPTURE REG | ||
| 1022 | ; | ||
| 1023 | ; DESCRIPTION : This routine will fill the entire DMA capture register | ||
| 1024 | ; file with the pattern that is passed in AL | ||
| 1025 | ; | ||
| 1026 | ; FUNCTION/ : See Description. | ||
| 1027 | ; PURPOSE | ||
| 1028 | ; | ||
| 1029 | ; ENTRY POINT : CAPT_FILL | ||
| 1030 | ; | ||
| 1031 | ; ENTRY : AL contains the value to be captured into | ||
| 1032 | ; CONDITIONS the register file. | ||
| 1033 | ; SI contains the address of DMA controller 1 | ||
| 1034 | ; DI contains the address of DMA controller 2 | ||
| 1035 | ; | ||
| 1036 | ; EXIT : Each entry in the DMA capture register file is set to | ||
| 1037 | ; the value specified in AL. | ||
| 1038 | ;------------------------------------------------------------------------- | ||
| 1039 | ; | ||
| 1040 | CAPT_FILL PROC NEAR | ||
| 1041 | ; | ||
| 1042 | MOV DX,IDREG | ||
| 1043 | OUT DX,AL ;LOAD ID REG WITH PAT TO BE CAPTURED | ||
| 1044 | MOV DX,DI ;GET ADDRESS OF CTRL 2 | ||
| 1045 | MOV CX,3 ;REP FOR CHANNELS 7,6,5 | ||
| 1046 | CF1: | ||
| 1047 | MOV AL,CL ;CL CONTAINS WHICH DMA CHANNEL | ||
| 1048 | OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL | ||
| 1049 | LOOP CF1 ;REPEAT | ||
| 1050 | ; | ||
| 1051 | MOV DX,SI ;GET ADDRESS OF CTRL 1 | ||
| 1052 | MOV CX,3 ;REP FOR CHANNELS 3,2,1 | ||
| 1053 | CF2: | ||
| 1054 | MOV AL,CL ;CL CONTAINS WHICH DMA CHANNEL | ||
| 1055 | OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL | ||
| 1056 | LOOP CF2 ;REPEAT | ||
| 1057 | ;DO CHANNEL 0 IF NOT PC1, XT, AQUARIUS | ||
| 1058 | CMP CS:MODEL_BYTE,PC1 ;IS THIS A PC1 ? | ||
| 1059 | JE CF3 ;YES - THEN EXIT ELSE TRY PC_XT | ||
| 1060 | CMP CS:MODEL_BYTE,PC_XT ;IS THIS AN XT ? | ||
| 1061 | JE CF3 ;YES - THEN EXIT ELSE TRY AQUARIUS | ||
| 1062 | CMP CS:MODEL_BYTE,XT_AQUARIUS ;IS THIS AN AQUARIUS? | ||
| 1063 | JE CF3 ;YES - THEN EXIT ELSE FILL CH 0 CAPT | ||
| 1064 | MOV AL,0 ;INDICATE CHANNEL 0 | ||
| 1065 | OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL | ||
| 1066 | CF3: | ||
| 1067 | RET ;RETURN TO CALLER | ||
| 1068 | ; | ||
| 1069 | CAPT_FILL ENDP | ||
| 1070 | |||
| 1071 | |||
| 1072 | |||
| 1073 | |||
| 1074 | PAGE | ||
| 1075 | ;------------------------------------------------------------------------- | ||
| 1076 | ;------------------------------------------------------------------------- | ||
| 1077 | ; | ||
| 1078 | ; READ-MODIFY-WRITE DMA CAPTURE REG | ||
| 1079 | ; | ||
| 1080 | ; DESCRIPTION : This routine will read the a DMA capture register | ||
| 1081 | ; and if the correct value is found will cause a capture | ||
| 1082 | ; of a new value. The next DMA capture reg is read and | ||
| 1083 | ; the process repeated. | ||
| 1084 | ; | ||
| 1085 | ; FUNCTION/ : See Description. | ||
| 1086 | ; PURPOSE | ||
| 1087 | ; | ||
| 1088 | ; ENTRY POINT : CAPT_RMW | ||
| 1089 | ; | ||
| 1090 | ; ENTRY : AH contains the value to be compared | ||
| 1091 | ; CONDITIONS BL contains the new value to be written | ||
| 1092 | ; SI contains the address of DMA controller 1 | ||
| 1093 | ; DI contains the address of DMA controller 2 | ||
| 1094 | ; | ||
| 1095 | ; EXIT : Each entry in the DMA capture register file is set to | ||
| 1096 | ; the value specified in BL. | ||
| 1097 | ; | ||
| 1098 | ; AL,CX,DX,ARE DESTROYED | ||
| 1099 | ;------------------------------------------------------------------------- | ||
| 1100 | ; | ||
| 1101 | CAPT_RMW PROC NEAR | ||
| 1102 | ; | ||
| 1103 | MOV CX,3 ;REP FOR CHANNELS 7,6,5 | ||
| 1104 | RMW1: | ||
| 1105 | MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG | ||
| 1106 | MOV AL,CL ;GET LOW BYTE OF COUNT | ||
| 1107 | ADD AL,4 ;ADD 4 TO POINT TO DMA CAPTURE | ||
| 1108 | CALL RMW | ||
| 1109 | JNZ RMW4 ;EXIT IF ERROR | ||
| 1110 | LOOP RMW1 ;REPEAT FOR CHANNEL 6,5 | ||
| 1111 | ; | ||
| 1112 | MOV CX,3 ;REP FOR CHANNELS 3,2,1 | ||
| 1113 | PUSH DI ;SAVE DMA CTRL 2 | ||
| 1114 | MOV DI,SI ;GET DMA CTRL 1 INTO DI FOR PROC RMW | ||
| 1115 | RMW2: | ||
| 1116 | MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG | ||
| 1117 | MOV AL,CL ;GET LOW BYTE OF COUNT | ||
| 1118 | CALL RMW | ||
| 1119 | JNZ RMW3 ;EXIT IF ERROR | ||
| 1120 | LOOP RMW2 ;REPEAT FOR DMA CHANNELS 2,1 | ||
| 1121 | ;DO CHANNEL 0 IF NOT PC1, XT, AQUARIUS | ||
| 1122 | CMP CS:MODEL_BYTE,PC1 ;IS THIS A PC1 ? | ||
| 1123 | JE RMW3 ;YES - THEN EXIT ELSE TEST FOR PC_XT | ||
| 1124 | CMP CS:MODEL_BYTE,PC_XT ;IS THIS AN XT ? | ||
| 1125 | JE RMW3 ;YES - THEN EXIT ELSE TEST FOR AQUARIUS | ||
| 1126 | CMP CS:MODEL_BYTE,XT_AQUARIUS ;IS THIS AN AQUARIUS? | ||
| 1127 | JE RMW3 ;YES - THEN EXIT ELSE TEST CH 0 | ||
| 1128 | MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG | ||
| 1129 | MOV CL,0 ;INDICATE CHANNEL 0 | ||
| 1130 | MOV AL,CL ;ALSO INTO AL | ||
| 1131 | CALL RMW | ||
| 1132 | RMW3: | ||
| 1133 | POP DI ;RESTORE DI (ADDR OF DMA CTRL 2) | ||
| 1134 | RMW4: | ||
| 1135 | RET ;RETURN TO CALLER | ||
| 1136 | ; | ||
| 1137 | CAPT_RMW ENDP | ||
| 1138 | ; | ||
| 1139 | RMW PROC | ||
| 1140 | ; | ||
| 1141 | OUT DX,AL ;SETUP TO READ FROM DMA CAPTURE REG | ||
| 1142 | IN AL,DX ;READ IT | ||
| 1143 | XOR AL,AH ;DATA AS EXPECTED ? | ||
| 1144 | JNE RMW5 ;NO THEN EXIT | ||
| 1145 | ;DATA WAS GOOD---NOW GET NEXT PATTERN INTO THIS CAPTURE REG | ||
| 1146 | MOV DX,IDREG ;ADDRESS OF ID REG | ||
| 1147 | MOV AL,BL ;NEW PATTERN TO WRITE | ||
| 1148 | OUT DX,AL ;WRITE IT TO ID REG | ||
| 1149 | MOV DX,DI ;ADDRESS OF DMA CTRL 2 | ||
| 1150 | MOV AL,CL ;DMA CHANNEL TO SET UP | ||
| 1151 | OUT DX,AL ;SET UP DMA---THIS CAUSES CAPTURE OF ID | ||
| 1152 | RMW5: | ||
| 1153 | RET ;RETURN TO CALLER | ||
| 1154 | ; | ||
| 1155 | RMW ENDP | ||
| 1156 | |||
| 1157 | |||
| 1158 | |||
| 1159 | |||
| 1160 | PAGE | ||
| 1161 | ;------------------------------------------------------------------------- | ||
| 1162 | ;------------------------------------------------------------------------- | ||
| 1163 | ; | ||
| 1164 | ; INHIBIT A BLOCK OF MEMORY | ||
| 1165 | ; | ||
| 1166 | ; DESCRIPTION : This routine will set a block of SMAS memory with | ||
| 1167 | ; the code to enable or inhibit it. The user simply | ||
| 1168 | ; specifies the starting segment and length of the block in | ||
| 1169 | ; PC 'real' address space that is to be enabled/inhibited. | ||
| 1170 | ; The appropriate entries in the Translate Table are | ||
| 1171 | ; written so that this specified block in 'real' address | ||
| 1172 | ; is enabled or protected in all 16 possible TASK ID's. | ||
| 1173 | ; | ||
| 1174 | ; | ||
| 1175 | ; FUNCTION/ : To enable or inhibit SMAS memory in specified areas of | ||
| 1176 | ; PURPOSE PC 'real'address space (ie.,diplay buffer, BIOS, | ||
| 1177 | ; distributed ROS...) | ||
| 1178 | ; | ||
| 1179 | ; ENTRY POINT : INHIBLK | ||
| 1180 | ; | ||
| 1181 | ; ENTRY : (AX) starting segment in PC address space to be | ||
| 1182 | ; CONDITIONS protected/enabled. Must be on 4K boundary else | ||
| 1183 | ; this routine will round UP to next 4K block. | ||
| 1184 | ; | ||
| 1185 | ; (CX) number of 4K blocks to be protected | ||
| 1186 | ; | ||
| 1187 | ; (BL) 01 = ENABLE | ||
| 1188 | ; 00 = INHIBIT | ||
| 1189 | ; | ||
| 1190 | ; EXIT : specified entries in Translate Table are enabled or | ||
| 1191 | ; inhibited for all posible task ID's. | ||
| 1192 | ; | ||
| 1193 | ; AX,BH,CX,DX ARE DESTROYED | ||
| 1194 | ;------------------------------------------------------------------------- | ||
| 1195 | ; | ||
| 1196 | INHIBLK PROC | ||
| 1197 | ; | ||
| 1198 | ;ADJUST SI FOR TRANSLATE TABLE ENTRY | ||
| 1199 | XCHG AL,AH ;ROTATE RIGHT BY 8 | ||
| 1200 | XOR AH,AH ;CLEAR AH | ||
| 1201 | ;AX IS NOW ADJUSTED FOR ENTRY INTO | ||
| 1202 | ;XLAT TABLE FOR TASK ID=0 | ||
| 1203 | PUSH AX ;SAVE IT | ||
| 1204 | PUSH CX ;SAVE COUNT OF 4K BLOCKS | ||
| 1205 | ; | ||
| 1206 | MOV SI,TTDATA ;ADDRESS OF TT DATA REG | ||
| 1207 | MOV DI,AIDATA ;ADDRESS OF TT DATA WITH AUTO INC | ||
| 1208 | XOR BH,BH ;BH IS TASK ID | ||
| 1209 | INH1: | ||
| 1210 | MOV DX,TTPOINTER ;ADDRESS OF TT POINTER | ||
| 1211 | POP CX ;RESTORE COUNT | ||
| 1212 | POP AX ;RESTORE TT ENTRY | ||
| 1213 | PUSH AX ;SAVE BOTH | ||
| 1214 | PUSH CX ; OF THEM | ||
| 1215 | MOV AH,BH ;APPEND TASK ID TO TT POINTER | ||
| 1216 | OUT DX,AX ;SET TT POINTER TO STARTING ENTRY | ||
| 1217 | INH2: | ||
| 1218 | MOV DX,SI ;TT DATA REG | ||
| 1219 | IN AX,DX ;READ CURRENT ENTRY | ||
| 1220 | MOV DX,DI ;ADDRESS OF TT DATA WITH AUTO INC | ||
| 1221 | ;DETERMINE IF ENABLE OR INHIBIT BLOCK | ||
| 1222 | CMP BL,ENABLE ;WANT TO ENABLE THIS BLOCK ? | ||
| 1223 | JNE INH3 ;NO - THEN DISABLE IT | ||
| 1224 | AND AH,BLK_ON ;MASK OFF INHIBIT BIT | ||
| 1225 | JMP INH4 | ||
| 1226 | INH3: | ||
| 1227 | OR AH,BLK_OFF ;MASK ON INHIBIT BIT | ||
| 1228 | INH4: | ||
| 1229 | OUT DX,AX ;WRITE IT THEN INC TO NEXT TT ENTRY | ||
| 1230 | LOOP INH2 ;REPEAT FOR EACH BLOCK OF 4K | ||
| 1231 | INC BH ;NEXT TASK ID | ||
| 1232 | CMP BH,MAX_TASK_ID ;COMPLETED FOR ALL TASK ID's ? | ||
| 1233 | JBE INH1 ;NO - THEN LOOP TILL DONE | ||
| 1234 | INHIBLK_EXIT: | ||
| 1235 | POP CX | ||
| 1236 | POP AX | ||
| 1237 | RET | ||
| 1238 | ; | ||
| 1239 | INHIBLK ENDP | ||
| 1240 | |||
| 1241 | |||
| 1242 | |||
| 1243 | |||
| 1244 | PAGE | ||
| 1245 | ;------------------------------------------------------------------------- | ||
| 1246 | ;------------------------------------------------------------------------- | ||
| 1247 | ; | ||
| 1248 | ; STORAGE TEST | ||
| 1249 | ; | ||
| 1250 | ; DESCRIPTION : This routine performs a bit and address test on a | ||
| 1251 | ; 64K block of storage. | ||
| 1252 | ; | ||
| 1253 | ; (i) 55AA is written to each location. | ||
| 1254 | ; (ii) 55AA is read back | ||
| 1255 | ; (iii) if good, write AA55 and point to next location | ||
| 1256 | ; (iv) repeat step (iii) for all 64K locations | ||
| 1257 | ; (v) repeat steps (ii) to (iv) for AA55, FF00, 0101, 0000 | ||
| 1258 | ; (vi) check parity bits | ||
| 1259 | ; | ||
| 1260 | ; | ||
| 1261 | ; FUNCTION/ : See description | ||
| 1262 | ; PURPOSE | ||
| 1263 | ; | ||
| 1264 | ; ENTRY POINT : STGTST | ||
| 1265 | ; | ||
| 1266 | ; ENTRY : (ES) storage segment to be tested | ||
| 1267 | ; CONDITIONS (DS) storage segment to be tested | ||
| 1268 | ; | ||
| 1269 | ; EXIT : (zero flag) = 0 if storage error | ||
| 1270 | ; (AX) expected data XOR'ed with actual data | ||
| 1271 | ; if ax = 0 and zf = 0 then parity error | ||
| 1272 | ; DS:SI point to failing location | ||
| 1273 | ; | ||
| 1274 | ; AX,BX,CX,DX,DI,SI ARE DESTROYED | ||
| 1275 | ; | ||
| 1276 | ;------------------------------------------------------------------------- | ||
| 1277 | ; | ||
| 1278 | STGTST PROC | ||
| 1279 | ; | ||
| 1280 | CMP CS:WARM_START,'Y' ;is this a warm start? | ||
| 1281 | JNE STG1A ;if no then do mem test | ||
| 1282 | CALL CLEAR_MEM ;if yes then just clear memory | ||
| 1283 | XOR AX,AX ;set zero flag | ||
| 1284 | JMP STG6 ;exit | ||
| 1285 | |||
| 1286 | |||
| 1287 | ;DISABLE NMI AND ENABLE I/O CHANNEL CHECK | ||
| 1288 | STG1A: | ||
| 1289 | MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE | ||
| 1290 | CMP AL,PC1 ;IS IT A PC1? | ||
| 1291 | JE STG1 ;IF NO THEN TRY FOR PC_XT | ||
| 1292 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 1293 | JE STG1 ;IF NO THEN TRY FOR AQUARIUS | ||
| 1294 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 1295 | JE STG1 ;IF NO THEN USE AT NMI REGS | ||
| 1296 | ;USE PC-AT NMI REGISTER | ||
| 1297 | MOV DX,AT_NMI_REG ;AT's NMI REGISTER | ||
| 1298 | MOV AL,AT_NMI_OFF ;MASK OFF NMI | ||
| 1299 | OUT DX,AL ;OUTPUT IT | ||
| 1300 | MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG | ||
| 1301 | IN AL,DX ;READ IT | ||
| 1302 | OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 1303 | OUT DX,AL ;WRITE IT | ||
| 1304 | AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 1305 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 1306 | ;ENABLED | ||
| 1307 | ;USE PC1, XT, AQUARIUS REGISTERS | ||
| 1308 | STG1: | ||
| 1309 | MOV DX,XT_NMI_REG ;XT's NMI REGISTER | ||
| 1310 | MOV AL,XT_NMI_OFF ;MASK OFF NMI | ||
| 1311 | OUT DX,AL ;OUTPUT IT | ||
| 1312 | MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG | ||
| 1313 | IN AL,DX ;READ IT | ||
| 1314 | OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 1315 | OUT DX,AL ;WRITE IT | ||
| 1316 | AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 1317 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 1318 | ;ENABLED | ||
| 1319 | |||
| 1320 | |||
| 1321 | |||
| 1322 | ;ROLL A BIT THROUGH THE FIRST WORD | ||
| 1323 | SUB DI,DI ;FIRST LOCATION | ||
| 1324 | MOV CX,16 ;ROLL 16 BITS | ||
| 1325 | MOV AX,0001H ;FIRST PATTERN TO WRITE | ||
| 1326 | MOV BX,AX ;SAVE IT | ||
| 1327 | STG2: | ||
| 1328 | MOV [DI],AX ;WRITE PATTERN | ||
| 1329 | MOV [DI+2],0FFFFH ;CHARGE BUS | ||
| 1330 | MOV AX,[DI] ;READ PATTERN | ||
| 1331 | XOR AX,BX ;IS IT CORRECT ? | ||
| 1332 | JNE STG_EXIT ;IF NO - THEN EXIT | ||
| 1333 | SHL BX,1 ;SHIFT BIT | ||
| 1334 | MOV AX,BX ;GET IT INTO AX | ||
| 1335 | LOOP STG2 ;REPEAT | ||
| 1336 | ; | ||
| 1337 | CLD ;FILL FORWARD | ||
| 1338 | SUB DI,DI ;POINT TO FIRST LOCATION | ||
| 1339 | MOV CX,2000H ;8K WORDS ;an000; dms; | ||
| 1340 | MOV AX,55AAH ;INITIAL PATTERN TO WRITE | ||
| 1341 | REP STOSW ;FILL ENTIRE SEGMENT | ||
| 1342 | ; | ||
| 1343 | MOV BX,55AAH ;PATTERN TO LOOK FOR | ||
| 1344 | MOV DX,0AA55H ;NEXT PATTERN TO WRITE | ||
| 1345 | CALL STG_CNT | ||
| 1346 | JNZ STG_EXIT ;EXIT IF ERROR | ||
| 1347 | ; | ||
| 1348 | MOV BX,0AA55H ;PATTERN TO LOOK FOR | ||
| 1349 | MOV DX,0101H ;NEXT PATTERN TO WRITE | ||
| 1350 | CALL STG_CNT | ||
| 1351 | JNZ STG_EXIT ;EXIT IF ERROR | ||
| 1352 | ; | ||
| 1353 | MOV BX,0101H ;PATTERN TO LOOK FOR | ||
| 1354 | MOV DX,0000H ;NEXT PATTERN TO WRITE | ||
| 1355 | CALL STG_CNT | ||
| 1356 | JNZ STG_EXIT ;EXIT IF ERROR | ||
| 1357 | ; | ||
| 1358 | ; MOV BX,0000H ;PATTERN TO LOOK FOR | ||
| 1359 | ; MOV DX,0000H ;NEXT PATTERN TO WRITE | ||
| 1360 | ; CALL STG_CNT | ||
| 1361 | ; JNZ STG_EXIT ;EXIT IF ERROR | ||
| 1362 | ; | ||
| 1363 | ;IF TEST REACHES THIS POINT THEN MEMORY IS GOOD | ||
| 1364 | ;NEED TO CHECK PARITY BITS...IF PARITY ERROR EXISTS THEN | ||
| 1365 | ;CAN ASSUME BAD PARITY BIT OR BAD PARITY GENERATOR | ||
| 1366 | ; | ||
| 1367 | MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE | ||
| 1368 | CMP AL,PC1 ;IS IT A PC1? | ||
| 1369 | JE STG3 ;USE XT REGISTERS | ||
| 1370 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 1371 | JE STG3 ;USE XT REGISTERS | ||
| 1372 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 1373 | JE STG3 ;USE XT REGISTERS | ||
| 1374 | ;IF NONE OF THE ABOVE THEN... | ||
| 1375 | ;USE AT NMI REGISTER | ||
| 1376 | MOV DX,AT_CHCHK_REG ;AT's I/O CH CHK REG | ||
| 1377 | IN AL,DX ;READ IT | ||
| 1378 | AND AL,AT_CHCHK ;IS CH CHK BIT ON ? | ||
| 1379 | JZ STG4 ;IF NO - THEN EXIT | ||
| 1380 | MOV AX,0 ;ELSE - CLEAR AX TO INDICATE | ||
| 1381 | ;PARITY ERROR | ||
| 1382 | JMP STG4 ;EXIT | ||
| 1383 | ;USE XT/AQUARIUS NMI REGISTER | ||
| 1384 | STG3: | ||
| 1385 | MOV DX,XT_CHCHK_REG ;XT's I/O CH CHK REG | ||
| 1386 | IN AL,DX ;READ IT | ||
| 1387 | AND AL,XT_CHCHK ;IS CH CHK BIT ON ? | ||
| 1388 | JZ STG4 ;IF NO - THEN EXIT | ||
| 1389 | MOV AX,0 ;ELSE - CLEAR AX TO INDICATE | ||
| 1390 | ;PARITY ERROR | ||
| 1391 | STG4: | ||
| 1392 | STG_EXIT: | ||
| 1393 | PUSH AX ;SAVE THESE REGS | ||
| 1394 | PUSH DX ;THEY CONTAIN | ||
| 1395 | PUSH SI | ||
| 1396 | PUSHF ;USEFUL ERROR INFORMATION | ||
| 1397 | ;BEFORE NMI IS ENABLED, CLEAR PARITY CHECK LATCH ON XMA | ||
| 1398 | MOV SI,0 | ||
| 1399 | MOV AX,[SI] ;READ 1ST WORD OF THIS SEG | ||
| 1400 | MOV [SI],AX ;WRITE BACK SAME WORD | ||
| 1401 | ;THE WRITE WILL CLEAR PCHK LTCH | ||
| 1402 | ;CLEAR I/O CHANNEL CHECK LATCHES AND ENABLE NMI | ||
| 1403 | MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE | ||
| 1404 | CMP AL,PC1 ;IS IT A PC1? | ||
| 1405 | JE STG5 ;USE XT REGISTERS | ||
| 1406 | CMP AL,PC_XT ;IS IT AN XT? | ||
| 1407 | JE STG5 ;USE XT REGISTERS | ||
| 1408 | CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS? | ||
| 1409 | JE STG5 ;USE XT REGISTERS | ||
| 1410 | ;IF NONE OF THE ABOVE THEN... | ||
| 1411 | ;USE AT NMI REGISTER | ||
| 1412 | MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG | ||
| 1413 | IN AL,DX ;READ IT | ||
| 1414 | OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 1415 | OUT DX,AL ;WRITE IT | ||
| 1416 | AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 1417 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 1418 | ;ENABLED | ||
| 1419 | MOV DX,AT_NMI_REG ;AT's NMI REGISTER | ||
| 1420 | MOV AL,AT_NMI_ON ;MASK ON NMI | ||
| 1421 | OUT DX,AL ;OUTPUT IT | ||
| 1422 | ;USE XT/AQUARIUS NMI REGISTER | ||
| 1423 | STG5: | ||
| 1424 | MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG | ||
| 1425 | IN AL,DX ;READ IT | ||
| 1426 | OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE | ||
| 1427 | OUT DX,AL ;WRITE IT | ||
| 1428 | AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE | ||
| 1429 | OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE | ||
| 1430 | ;ENABLED | ||
| 1431 | MOV DX,XT_NMI_REG ;XT's NMI REGISTER | ||
| 1432 | MOV AL,XT_NMI_ON ;MASK ON NMI | ||
| 1433 | OUT DX,AL ;OUTPUT IT | ||
| 1434 | ; | ||
| 1435 | POPF | ||
| 1436 | POP SI | ||
| 1437 | POP DX | ||
| 1438 | POP AX ;RESTORE REGS | ||
| 1439 | STG6: | ||
| 1440 | RET ;RETURN TO CALLER | ||
| 1441 | |||
| 1442 | |||
| 1443 | |||
| 1444 | CLEAR_MEM PROC ;INTERNAL PROC TO CLEAR MEMORY | ||
| 1445 | XOR DI,DI ;start of segment | ||
| 1446 | XOR CX,CX ;clear entire segment | ||
| 1447 | XOR AX,AX ;write zeroes | ||
| 1448 | |||
| 1449 | STOSB ;just write | ||
| 1450 | RET ;back to caller | ||
| 1451 | CLEAR_MEM ENDP | ||
| 1452 | |||
| 1453 | |||
| 1454 | STGTST ENDP | ||
| 1455 | |||
| 1456 | |||
| 1457 | PAGE | ||
| 1458 | ;------------------------------------------------------------------------- | ||
| 1459 | ;------------------------------------------------------------------------- | ||
| 1460 | ; | ||
| 1461 | ; STORAGE TEST SUBROUTINE | ||
| 1462 | ; | ||
| 1463 | ; DESCRIPTION : This routine performs a bit and address test on a | ||
| 1464 | ; 64K block of storage. | ||
| 1465 | ; | ||
| 1466 | ; (i) a word is read and compared against the value in (BX) | ||
| 1467 | ; (ii) if good the value in (DX) is written into that location | ||
| 1468 | ; (iii) point to next location and repeat steps (i) to (ii) | ||
| 1469 | ; | ||
| 1470 | ; | ||
| 1471 | ; FUNCTION/ : See description | ||
| 1472 | ; PURPOSE | ||
| 1473 | ; | ||
| 1474 | ; ENTRY POINT : STG_CNT | ||
| 1475 | ; | ||
| 1476 | ; ENTRY : (ES) storage segment to be tested | ||
| 1477 | ; CONDITIONS (DS) storage segment to be tested | ||
| 1478 | ; (BX) value to be compared | ||
| 1479 | ; (DX) new value to be written | ||
| 1480 | ; | ||
| 1481 | ; EXIT : (zero flag) = 0 if storage error | ||
| 1482 | ; (AX) expected data XOR'ed with actual data | ||
| 1483 | ; if ax = 0 and zf = 0 then parity error | ||
| 1484 | ; DS:SI point to failing location | ||
| 1485 | ;------------------------------------------------------------------------- | ||
| 1486 | ; | ||
| 1487 | STG_CNT PROC | ||
| 1488 | ; | ||
| 1489 | MOV CX,2000H ;8K WORDS ;an000; dms; | ||
| 1490 | SUB DI,DI ;FIRST LOCATION | ||
| 1491 | MOV SI,DI ;FIRST LOCATION | ||
| 1492 | SC1: | ||
| 1493 | LODSW ;READ OLD WORD FROM STORAGE | ||
| 1494 | XOR AX,BX ;DATA AS EXPECTED ? | ||
| 1495 | JNE SC2 ;IF NO - THEN EXIT | ||
| 1496 | MOV AX,DX ;GET NEW PATTERN | ||
| 1497 | STOSW ;WRITE IT | ||
| 1498 | LOOP SC1 ;REPEAT | ||
| 1499 | SC2: | ||
| 1500 | RET | ||
| 1501 | |||
| 1502 | STG_CNT ENDP | ||
| 1503 | |||
| 1504 | |||
| 1505 | |||
| 1506 | |||
| 1507 | PAGE | ||
| 1508 | ;------------------------------------------------------------------------- | ||
| 1509 | ;------------------------------------------------------------------------- | ||
| 1510 | ; | ||
| 1511 | ; PRINT MEMORY GOOD | ||
| 1512 | ; | ||
| 1513 | ; DESCRIPTION : This routine will print to the screen how much memory | ||
| 1514 | ; has been tested. | ||
| 1515 | ; | ||
| 1516 | ; The format will be: xxxx KB TESTED | ||
| 1517 | ; | ||
| 1518 | ; FUNCTION/ : See description | ||
| 1519 | ; PURPOSE | ||
| 1520 | ; | ||
| 1521 | ; | ||
| 1522 | ; ENTRY POINT : KB_OK | ||
| 1523 | ; | ||
| 1524 | ; ENTRY : (DX) = 1/4 OF GOOD MEMORY + 64K IN KB | ||
| 1525 | ; CONDITIONS ex: if (DX) = 16 then | ||
| 1526 | ; (16 * 4) + 64 = 128KB is OK | ||
| 1527 | ; | ||
| 1528 | ; NOTE: if (DX) = FFF0 then 0 KB is OK | ||
| 1529 | ; | ||
| 1530 | ; | ||
| 1531 | ; EXIT : Message is displayed | ||
| 1532 | ; | ||
| 1533 | ; All registers are preserved | ||
| 1534 | ; | ||
| 1535 | ;------------------------------------------------------------------------- | ||
| 1536 | ; | ||
| 1537 | KB_OK PROC | ||
| 1538 | ; | ||
| 1539 | PUSH AX | ||
| 1540 | PUSH BX | ||
| 1541 | PUSH CX | ||
| 1542 | PUSH DX | ||
| 1543 | PUSH SI | ||
| 1544 | PUSH DI | ||
| 1545 | PUSH DS ;SAVE REGISTERS | ||
| 1546 | ; | ||
| 1547 | PUSH CS | ||
| 1548 | POP DS ;GET DS TO THIS CODE SEGMENT | ||
| 1549 | ;CONVERT DX TO KILO BYTES | ||
| 1550 | SHL DX,1 | ||
| 1551 | SHL DX,1 ;MULTIPLY BY 4 | ||
| 1552 | ADD DX,16 ;ADJUST BY 16 ;an000; dms; | ||
| 1553 | ; | ||
| 1554 | MOV AX,DX ;GET NUMBER INTO AX | ||
| 1555 | MOV BX,10 ;READY FOR DECIMAL CONVERT | ||
| 1556 | MOV CX,4 ;OF 4 DIGITS | ||
| 1557 | K1: | ||
| 1558 | XOR DX,DX ;CLEAR HI WORD OF DIVIDEND | ||
| 1559 | ;AX IS LOW WORD OF DIVIDEND | ||
| 1560 | DIV BX ;DIVIDE BY 10 | ||
| 1561 | OR DL,30H ;MAKE MODULO INTO ASCII | ||
| 1562 | PUSH DX ;SAVE IT | ||
| 1563 | LOOP K1 ;REPEAT FOR ALL DIGITS | ||
| 1564 | ; | ||
| 1565 | XOR SI,SI ;CLEAR SI | ||
| 1566 | MOV CX,4 | ||
| 1567 | K2: | ||
| 1568 | POP AX ;ASCII DIGIT GOES INTO AL | ||
| 1569 | MOV BX,OFFSET MEM_OK | ||
| 1570 | MOV CS:[BX+SI],AL ;BUILD ASCII MESSAGE | ||
| 1571 | INC SI | ||
| 1572 | LOOP K2 | ||
| 1573 | ;MOVE THE CURSOR AND PRINT MESSAGE | ||
| 1574 | MOV DX,CUR_SAVE | ||
| 1575 | MOV BH,ACTIVE_PAGE | ||
| 1576 | MOV AH,2 ;SET CURSOR | ||
| 1577 | |||
| 1578 | INT 10H ;BIOS VIDEO CALL SET CURSOR | ||
| 1579 | MOV AH,9 ;DOS PRINT STRING | ||
| 1580 | MOV DX,OFFSET SIZE_MSG1 + 1 ;OFFSET OF MEM_OK MSG | ||
| 1581 | INT 21H ;DISPLAY MESSAGE | ||
| 1582 | |||
| 1583 | POP DS | ||
| 1584 | POP DI | ||
| 1585 | POP SI | ||
| 1586 | POP DX | ||
| 1587 | POP CX | ||
| 1588 | POP BX | ||
| 1589 | POP AX ;RESTORE ALL REGISTERS | ||
| 1590 | |||
| 1591 | RET ;RETURN TO CALLER | ||
| 1592 | |||
| 1593 | KB_OK ENDP | ||
| 1594 | |||
| 1595 | |||
| 1596 | PAGE | ||
| 1597 | ;------------------------------------------------------------------------- | ||
| 1598 | ;------------------------------------------------------------------------- | ||
| 1599 | ; | ||
| 1600 | ; SET TRANSLATE TABLE | ||
| 1601 | ; | ||
| 1602 | ; DESCRIPTION : This routine will write the Translate Table so that | ||
| 1603 | ; a specified block of PC 'real' address will be mapped | ||
| 1604 | ; to a specified block of SMAS physycal memory. Note that | ||
| 1605 | ; this routine will map only into CONTIGUOUS blocks of | ||
| 1606 | ; SMAS memory. PC memory is referenced by segments | ||
| 1607 | ; (must be on 4K boundaries) while SMAS memory is referenced | ||
| 1608 | ; by block number (each block is 4K). | ||
| 1609 | ; | ||
| 1610 | ; EXAMPLE: segment 4000 can be mapped to block 5 | ||
| 1611 | ; segment 4100 can be mapped to block 6 | ||
| 1612 | ; | ||
| 1613 | ; FUNCTION/ : To map PC 'real' addresses into SMAS physical memory. | ||
| 1614 | ; PURPOSE | ||
| 1615 | ; | ||
| 1616 | ; | ||
| 1617 | ; ENTRY POINT : SETXLAT | ||
| 1618 | ; | ||
| 1619 | ; ENTRY : (AX) starting segment in PC address space to be | ||
| 1620 | ; CONDITIONS mapped. Must be on 4K boundary else | ||
| 1621 | ; this routine will round UP to next 4K block. | ||
| 1622 | ; | ||
| 1623 | ; (CX) number of 4K blocks translated. | ||
| 1624 | ; | ||
| 1625 | ; (BH) task ID for this memory allocation | ||
| 1626 | ; | ||
| 1627 | ; (BL) 01 = ENABLE | ||
| 1628 | ; 00 = INHIBIT | ||
| 1629 | ; | ||
| 1630 | ; (DX) starting block number in SMAS memory | ||
| 1631 | ; | ||
| 1632 | ; | ||
| 1633 | ; EXIT : specified entries in Translate Table are enabled or | ||
| 1634 | ; inhibited for all posible task ID's. | ||
| 1635 | ; | ||
| 1636 | ; | ||
| 1637 | ; AX,CX,DX ARE DESTROYED | ||
| 1638 | ; | ||
| 1639 | ;------------------------------------------------------------------------- | ||
| 1640 | ; | ||
| 1641 | SETXLAT PROC | ||
| 1642 | ; | ||
| 1643 | ;ADJUST AX FOR TRANSLATE TABLE ENTRY | ||
| 1644 | XCHG AL,AH ;ROTATE RIGHT BY 8 | ||
| 1645 | MOV AH,BH ;TASK ID INTO BH | ||
| 1646 | ;AX IS NOW ADJUSTED FOR ENTRY INTO | ||
| 1647 | ;XLAT TABLE FOR TASK ID=(BH) | ||
| 1648 | PUSH DX ;SAVE STARTING SMAS BLOCK NUMBER | ||
| 1649 | ; | ||
| 1650 | MOV DX,TTPOINTER ;ADDRESS OF TT POINTER | ||
| 1651 | OUT DX,AX ;SET TT POINTER TO STARTING ENTRY | ||
| 1652 | POP AX ;GET STARTING BLOCK NUMBER INTO AX | ||
| 1653 | ; | ||
| 1654 | MOV DX,AIDATA ;TT DATA REG WITH AUTO INC | ||
| 1655 | ;DETERMINE IF ENABLE OR INHIBIT BLOCK | ||
| 1656 | CMP BL,ENABLE ;WANT TO ENABLE THIS BLOCK ? | ||
| 1657 | JE SETX1 ;YES - THEN SKIP THE DISABLE STEP | ||
| 1658 | OR AH,BLK_OFF ;MASK ON INHIBIT BIT | ||
| 1659 | SETX1: | ||
| 1660 | OUT DX,AX ;WRITE IT THEN INC TO NEXT TT ENTRY | ||
| 1661 | INC AX ;NEXT BLOCK OF SMAS MEMORY | ||
| 1662 | LOOP SETX1 ;REPEAT FOR EACH BLOCK OF 4K | ||
| 1663 | SETXLAT_EXIT: | ||
| 1664 | RET | ||
| 1665 | ; | ||
| 1666 | SETXLAT ENDP | ||
| 1667 | |||
| 1668 | PAGE | ||
| 1669 | ;------------------------------------------------------------------------- | ||
| 1670 | ;------------------------------------------------------------------------- | ||
| 1671 | ; | ||
| 1672 | ; AUTO-INCREMENT TEST | ||
| 1673 | ; | ||
| 1674 | ; DESCRIPTION : This routine will test the auto-increment of | ||
| 1675 | ; the Translate Table pointer. The test will procede | ||
| 1676 | ; in the following manner: | ||
| 1677 | ; (i) A basic check of the TT pointer reg is performed | ||
| 1678 | ; (ii) The TT pointer is initialized to '00'H | ||
| 1679 | ; (iii) The auto increment data reg is written | ||
| 1680 | ; (iv) The TT pointer is read and checked for increment | ||
| 1681 | ; (v) Repeat until TT pointer wraps from 'FFF'H to '000'H | ||
| 1682 | ; (vi) Repeat test for auto-increment for read of data reg | ||
| 1683 | ; | ||
| 1684 | ; FUNCTION/ : To ensure that the Translate Table pointer can auto | ||
| 1685 | ; PURPOSE increment when 31A5 is written or read. | ||
| 1686 | ; | ||
| 1687 | ; ENTRY POINT : INCTST | ||
| 1688 | ; | ||
| 1689 | ; ENTRY : NONE | ||
| 1690 | ; CONDITIONS | ||
| 1691 | ; | ||
| 1692 | ; EXIT : | ||
| 1693 | ; (zero flag) = 0 indicates an error | ||
| 1694 | ; (DX) failing register (ie.,TT pointer reg) | ||
| 1695 | ; (AX) expected data XOR'ed with actual data | ||
| 1696 | ;------------------------------------------------------------------------- | ||
| 1697 | ; | ||
| 1698 | ; | ||
| 1699 | INCTST PROC | ||
| 1700 | ; | ||
| 1701 | MOV AL,AUTO_INC | ||
| 1702 | MOV CS:TEST_ID,AL | ||
| 1703 | ; | ||
| 1704 | ;PERFORM SIMPLE TEST OF TTPOINTER REG | ||
| 1705 | ; | ||
| 1706 | MOV BX,0AA55H ;SET UP PATTERN TO WRITE | ||
| 1707 | MOV AX,BX | ||
| 1708 | MOV DX,TTPOINTER ;I/O TO TTPOINTER REG | ||
| 1709 | MOV SI,TTDATA ;SAVE FOR I/O TO TTDATA | ||
| 1710 | OUT DX,AX ;WRITE THE REGISTER | ||
| 1711 | XCHG DX,SI ;I/O TO TTDATA REG | ||
| 1712 | XCHG AH,AL ;INVERSE PATTERN | ||
| 1713 | OUT DX,AX ;CHARGE BUS WITH OPPOSITE PATTERN | ||
| 1714 | XCHG DX,SI ;I/O TO TTPOINTER REG | ||
| 1715 | IN AX,DX ;READ TTPOINTER REG | ||
| 1716 | XOR AX,BX ;READ AS EXPECTED | ||
| 1717 | AND AX,0FFFH ;MASK OFF HI NIBBLE (INVALID) | ||
| 1718 | JNE INC_ERROR ;NO - THEN EXIT | ||
| 1719 | ; | ||
| 1720 | ;CONTINUE WITH AUTO-INC TEST | ||
| 1721 | ; | ||
| 1722 | MOV DI,2 ;2 PASSES...1 WRITE , 1 READ | ||
| 1723 | AI1: | ||
| 1724 | MOV SI,AIDATA ;SAVE FOR I/O TO TTDATA WITH AUTO-INC | ||
| 1725 | AI2: | ||
| 1726 | MOV CX,1000H ;TTPOINTER RANGE 0 -> FFF | ||
| 1727 | MOV BX,0001H ;INITIAL COMPARE VALUE | ||
| 1728 | MOV AX,0 ;SET TTPONTER TO ZERO | ||
| 1729 | OUT DX,AX ;TTPOINTER IS INITIALIZED TO ZERO | ||
| 1730 | AI2X: | ||
| 1731 | XCHG DX,SI ;I/O TO TTDATA WITH AUTO-INC | ||
| 1732 | ; | ||
| 1733 | ;DETERMINE IF WRITE OR READ TEST | ||
| 1734 | ; | ||
| 1735 | CMP DI,2 ;DOING A AUTO-INC WRITE TEST ? | ||
| 1736 | JNE AI3 ;NO - THEN MUST BE AUTO-INC READ TEST | ||
| 1737 | OUT DX,AX ;WRITE TO AUTO-INC DATA REG | ||
| 1738 | JMP AI4 ;CONTINUE WITH TEST | ||
| 1739 | AI3: | ||
| 1740 | IN AX,DX ;READ FROM AUTO-INC DATA REG | ||
| 1741 | AI4: | ||
| 1742 | XCHG DX,SI ;I/O TO TTPOINTER REG | ||
| 1743 | IN AX,DX ;READ TTPOINTER (31A1 -> AH) | ||
| 1744 | XOR AX,BX ;DATA AS EXPECTED ? | ||
| 1745 | AND AX,0FFFH ;MASK OFF UPPER NIBBLE (INVALID) | ||
| 1746 | JNE INC_ERROR ;NO - GO TO ERROR | ||
| 1747 | INC BX ;NEXT VALUE TO LOOK FOR | ||
| 1748 | LOOP AI2X ;CONTINUE TIL ALL VALUES ARE TESTED | ||
| 1749 | ; | ||
| 1750 | DEC DI | ||
| 1751 | CMP DI,0 ;COMPLETE WITH WRITE AND READ TEST ? | ||
| 1752 | JE INC_EXIT ;YES - THEN EXIT | ||
| 1753 | JMP AI1 ;NO - THEN CONTINUE WITH READ TEST | ||
| 1754 | ; | ||
| 1755 | INC_ERROR: | ||
| 1756 | INC_EXIT: RET | ||
| 1757 | ; | ||
| 1758 | INCTST ENDP | ||
| 1759 | |||
| 1760 | PAGE | ||
| 1761 | ;------------------------------------------------------------------------- | ||
| 1762 | ;------------------------------------------------------------------------- | ||
| 1763 | ; | ||
| 1764 | ; TRANSLATE TABLE TEST | ||
| 1765 | ; | ||
| 1766 | ; DESCRIPTION : This routine performs a write/read storage test | ||
| 1767 | ; on the Translate Table. The test is as follows: | ||
| 1768 | ; (i) A bit is rolled through the first word of the TT | ||
| 1769 | ; (ii) A bit and address test is performed on the | ||
| 1770 | ; remainder of the TT. | ||
| 1771 | ; | ||
| 1772 | ; FUNCTION/ : To verify the integrity of the Translate Table. | ||
| 1773 | ; PURPOSE | ||
| 1774 | ; | ||
| 1775 | ; ENTRY POINT : XLATST | ||
| 1776 | ; | ||
| 1777 | ; ENTRY : NONE | ||
| 1778 | ; CONDITIONS | ||
| 1779 | ; | ||
| 1780 | ; EXIT : Entire Translate Table is left with FFF (passover code) | ||
| 1781 | ; | ||
| 1782 | ; (zero flag) = 0 indicates an error | ||
| 1783 | ; (DX) failing register (TT data register) | ||
| 1784 | ; (AX) expected data XOR'ed with actual data | ||
| 1785 | ; (31A0) address in TT of failure | ||
| 1786 | ;------------------------------------------------------------------------- | ||
| 1787 | ; | ||
| 1788 | XLATST PROC | ||
| 1789 | ; | ||
| 1790 | MOV AL,XLAT_TABLE_TEST | ||
| 1791 | MOV CS:TEST_ID,AL | ||
| 1792 | ; | ||
| 1793 | ;ROLL A BIT THROUGH THE FIRST BYTE | ||
| 1794 | ; | ||
| 1795 | MOV BX,0001H ;SET UP INITIAL PATTERN | ||
| 1796 | MOV SI,TTDATA ;SAVE FOR I/O TO DATA REG | ||
| 1797 | MOV DX,TTPOINTER ;I/O TO TTPOINTER REG | ||
| 1798 | MOV CX,12 ;ROLL 12 BIT POSITIONS | ||
| 1799 | XOR AX,AX ;CLEAR AX (WRITE TO 1st TT LOCATION) | ||
| 1800 | OUT DX,AX ;SET TT POINTER | ||
| 1801 | XCHG DX,SI ;READY FOR I/O TO TTDATA REG | ||
| 1802 | X1: | ||
| 1803 | MOV AX,BX ;GET BIT PATTERN | ||
| 1804 | OUT DX,AX ;WRITE BIT PATTERN TO TT | ||
| 1805 | XCHG DX,SI ;READY FOR I/O TO TTPOINTER REG | ||
| 1806 | XOR AX,AX ;CLEAR AX | ||
| 1807 | OUT DX,AX ;CHARGE BUS WITH 0000 PATTERN | ||
| 1808 | XCHG DX,SI ;READY FOR I/O TO TTDATA REG | ||
| 1809 | IN AX,DX ;READ TT (31A1 -> AH) | ||
| 1810 | XOR AX,BX ;DATA READ AS EXPECTED ? | ||
| 1811 | AND AX,0FFFH ;MASK OFF UPPER NIBBLE (INVALID) | ||
| 1812 | JNE XLA_ERROR ;NO - THEN EXIT | ||
| 1813 | SHL BX,1 ;SHIFT BIT TO NEXT POSITION | ||
| 1814 | LOOP X1 | ||
| 1815 | ; | ||
| 1816 | ;CONTINUE REMAINDER OF TRANSLATE TABLE | ||
| 1817 | ; | ||
| 1818 | MOV DX,AIDATA | ||
| 1819 | ; | ||
| 1820 | XCHG DX,SI ;READY FOR I/O TO TTPOINTER | ||
| 1821 | XOR AX,AX ;CLEAR AX | ||
| 1822 | OUT DX,AX ;TTPOINTER AT 1st LOCATION | ||
| 1823 | ; | ||
| 1824 | XCHG DX,SI ;READY FOR I/O TO TT DATA W/AUTO-INC | ||
| 1825 | MOV AX,0AA55H ;INITIAL DATA PATTERN | ||
| 1826 | MOV CX,TABLEN ;NUMBER OF TT ENTRIES | ||
| 1827 | X2: | ||
| 1828 | OUT DX,AX ;SETUP INVERSE PATTERN | ||
| 1829 | LOOP X2 ;FILL ENTIRE XLATE TABLE | ||
| 1830 | ; | ||
| 1831 | MOV SI,TTDATA ;ADDRESS OF TTDATA WITHOUT INC. | ||
| 1832 | MOV BX,AX ;SAVE VALUE FOR COMPARE | ||
| 1833 | MOV DI,055AAH ;NEXT PATTERN TO WRITE | ||
| 1834 | X3: | ||
| 1835 | MOV CX,TABLEN ;NUMBER OF TT ENTRIES | ||
| 1836 | X4: | ||
| 1837 | XCHG DX,SI ;GET IT INTO DX...SI GETS AUTO-INC | ||
| 1838 | IN AX,DX ;READ TABLE ENTRY (HI BYTE -> AH) | ||
| 1839 | XOR AX,BX ;DATA READ AS EXPECTED ? | ||
| 1840 | AND AX,0FFFH ;MASK OFF HI NIBBLE (INVALID) | ||
| 1841 | JNE XLA_ERROR ;NO - THE EXIT | ||
| 1842 | XCHG DX,SI ;GET TTDATA WITH AUTO-INC | ||
| 1843 | MOV AX,DI ;RECOVER NEXT PATTERN TO WRITE | ||
| 1844 | OUT DX,AX ;WRITE IT THEN INCREMENT | ||
| 1845 | LOOP X4 ;REPEAT TILL TABLE FILLED | ||
| 1846 | |||
| 1847 | |||
| 1848 | ; | ||
| 1849 | CMP DI,0FFFFH ;LAST PASS ? | ||
| 1850 | JE XLA_EXIT ;YES - THEN EXIT REG TEST | ||
| 1851 | ; | ||
| 1852 | XCHG BX,DI ;BX GETS NEXT PATTERN TO TEST | ||
| 1853 | ; | ||
| 1854 | CMP BX,055AAH ;LAST PASS FOR AA55,55AA PATTERN? | ||
| 1855 | JNE X5 ;NO | ||
| 1856 | MOV DI,0FF00H ;YES- PREPARE TO WRITE NEW PATTERN | ||
| 1857 | JMP X3 ;DO IT | ||
| 1858 | X5: | ||
| 1859 | CMP BX,0FF00H ;READY TO READ 0FF00 PATTERN | ||
| 1860 | JNE X6 ;NO | ||
| 1861 | MOV DI,00FFH ;YES- PREPARE TO WRITE NEW PATTERN | ||
| 1862 | JMP X3 ;DO IT | ||
| 1863 | X6: | ||
| 1864 | MOV DI,0FFFFH ;PREPARE TO SET ALL OF TT INACTIVE | ||
| 1865 | JMP X3 ;DO IT | ||
| 1866 | ; | ||
| 1867 | XLA_ERROR: | ||
| 1868 | XLA_EXIT: RET | ||
| 1869 | ; | ||
| 1870 | XLATST ENDP | ||
diff --git a/v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM b/v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM new file mode 100644 index 0000000..43f038f --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM | |||
| @@ -0,0 +1,2591 @@ | |||
| 1 | |||
| 2 | PAGE 85,132 ;Set for 5182 Pageprinter | ||
| 3 | ;85 lines per page, 132 col per line | ||
| 4 | ;(formerly 60,132) | ||
| 5 | |||
| 6 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 7 | ;º º | ||
| 8 | ;º This is the new version of the XMA2EMS driver for DOS 3.3. º | ||
| 9 | ;º It contains the following revisions and code flags: º | ||
| 10 | ;º º | ||
| 11 | ;º @RH0 - Correct scrolling problem º | ||
| 12 | ;º @RH1 - Expand table to 32M º | ||
| 13 | ;º @RH2 - Real Mode support (XMA/A card) º | ||
| 14 | ;º @RH3 - Memory Expansion Option (MXO a.k.a. XMO) support º | ||
| 15 | ;º @RH4 - LIM 4.0 support º | ||
| 16 | ;º @RH5 - Multicard support º | ||
| 17 | ;º @RH6 - WSP interfaces º | ||
| 18 | ;º @RH7 - 386 XMA Emulator support º | ||
| 19 | ;º @RH8 - Make driver reentrant º | ||
| 20 | ;º º | ||
| 21 | ;º AN007 P5134 - Provide variable planar size support. º | ||
| 22 | ;º Modify linked list to forward link vs. the º | ||
| 23 | ;º reverse linked list. º | ||
| 24 | ;º º | ||
| 25 | ;º AN008 P5150 - Fix incorrect access of slot 0 when no º | ||
| 26 | ;º Catskill/Holster card is in slot 0. º | ||
| 27 | ;º º | ||
| 28 | ;ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ | ||
| 29 | ;º It should be noted that certain EMS calls will alter the contents º | ||
| 30 | ;º of the translate table pointer for any supported memory cards or º | ||
| 31 | ;º emulators (i.e. MXO, XMA, XMA/A cards, 80386 XMA emulator). º | ||
| 32 | ;º Therefore, software that writes to the translate table(s) has the º | ||
| 33 | ;º responsiblity of keeping the integrity of the TT pointer. For º | ||
| 34 | ;º example, programs should disable interrupts between setting the º | ||
| 35 | ;º TT pointer and writing the TT data. This will prevent: An interrupt º | ||
| 36 | ;º occurring between the two, control going to another application º | ||
| 37 | ;º that makes an EMS call and thus screws up the TT ptr. The EMS calls º | ||
| 38 | ;º that do this are: º | ||
| 39 | ;º Function # EMS Call º | ||
| 40 | ;º 5 Map logical to physical page º | ||
| 41 | ;º 8, 15/0 Save (Get) mapping array º | ||
| 42 | ;º 9, 15/1 Restore (Set) mapping array º | ||
| 43 | ;º 15/2 Get and Set mapping array º | ||
| 44 | ;º º | ||
| 45 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 46 | |||
| 47 | ;XMA2EMS provides a Lotus/Intel/Microsoft Expanded Memory (EMS) interface | ||
| 48 | ;for the IBM Expanded Memory Adapter (XMA). | ||
| 49 | |||
| 50 | ;Program Property of Microsoft | ||
| 51 | |||
| 52 | ;Add the following statement to CONFIG.SYS | ||
| 53 | ; DEVICE=[d:][path]XMA2EMS.SYS | ||
| 54 | |||
| 55 | |||
| 56 | ;-----------------------------------------------------------------------; | ||
| 57 | ; Equates go here ; | ||
| 58 | ;-----------------------------------------------------------------------; | ||
| 59 | EMS_INT EQU 67H ;EMS INTERRUPT | ||
| 60 | EM_INT EQU 15H ;EM INTERRUPT ;an000; dms; | ||
| 61 | DK_Int equ 13h ;disk interrupt ;an004; dms; | ||
| 62 | EM_Size_Get EQU 88h ;get EM size ;an000; dms; | ||
| 63 | EMM_VERSION EQU 40H ;VERSION 4.0 | ||
| 64 | PF_HI_LIMIT EQU 0E000H ;highest allowable page frame segment | ||
| 65 | PF_LOW_LIMIT EQU 0A000H ;lowest allowable page frame segment | ||
| 66 | OK EQU 'OK' ;card is good | ||
| 67 | HW_ERROR EQU 'HW' ;card is not functional...HardWare error | ||
| 68 | SW_ERROR EQU 'SW' ;SoftWare error has been detected | ||
| 69 | PAGE_INHIBITTED EQU 0FFFFh ;Entry in the save area indicating | ||
| 70 | ; a page is currently inhibitted | ||
| 71 | REUSABLE_HANDLE EQU 'HR' ;Reusable (free) entry in the @RH1 | ||
| 72 | ; handle lookup table. Placed in @RH1 | ||
| 73 | ; the 'pages' field @RH1 | ||
| 74 | REUSABLE_SAVEA EQU 'SR' ;Reusable (free) entry in the @RH1 | ||
| 75 | ; handle save area. 0 is a valid @RH1 | ||
| 76 | ; page #, and 'FFFF' is for saving @RH1 | ||
| 77 | ; an inhibitted field, so S(ave) @RH1 | ||
| 78 | ; R(eusable) is stored. Page 5352 @RH1 | ||
| 79 | ; not a valid page (5352 = 333Meg) @RH1 | ||
| 80 | ;Page Allocation List entries | ||
| 81 | ; Allocated pages have the handle # | ||
| 82 | UNALLOCATED EQU 'U' ; Unused entry | ||
| 83 | ALLOCATED EQU 'X' ; Temporary...used by reallocate @RH4 | ||
| 84 | PAL_NULL EQU '--' ; End of list marker @RH8 | ||
| 85 | EXTENDED EQU 'ME' ; Extended memory (not for EMS use)@RH8 | ||
| 86 | BACMEM_ALLOC EQU 'MB' ; Allocated to back conventional @RH8 | ||
| 87 | ; memory (back disabled planar) | ||
| 88 | WSP_ALLOC EQU 'SW' ; Allocated to Workstation Program @RH8 | ||
| 89 | ; Pages kept as extended memory by: | ||
| 90 | RESR_EXT EQU 'ER' ; /E parameter | ||
| 91 | PREV_EXT EQU 'EP' ; Previously loaded drivers | ||
| 92 | ; These values are OK as long as the | ||
| 93 | ; # of handles supported (40h) is | ||
| 94 | ; not above the ascii 'B' (42h) | ||
| 95 | WARM_MASK EQU 1 ;ISOLATE WARM START BIT | ||
| 96 | OFFSET_IN_XREF EQU BYTE PTR[BX+SI] | ||
| 97 | LENGTH_IN_XREF EQU BYTE PTR[BX+SI+1] | ||
| 98 | PAGE_LIST_ENTRY EQU WORD PTR[SI + OFFSET PAGE_ALLOC_LIST] ; @RH8 | ||
| 99 | page_table_entry EQU byte PTR[SI + OFFSET PAGE_ALLOC_table] ;temp for assembl | ||
| 100 | XREF_TABLE_ENTRY EQU word PTR[DI + OFFSET HANDLE_XREF_TABLE] ; @RH1 | ||
| 101 | NUM_PHYSICAL_PAGES EQU 4 | ||
| 102 | STACK_SIZE EQU 100H | ||
| 103 | Instance_Size EQU 150 ;instance size ;an000; dms; | ||
| 104 | Instance_Count EQU 3 ;number of instances ;an000; dms; | ||
| 105 | |||
| 106 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 107 | ;³ Common memory adapter declares ³ | ||
| 108 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 109 | SLOT_SETUP EQU 08h ;Mask to put the desired adapter @RH2 | ||
| 110 | ; slot into setup mode, activating @RH2 | ||
| 111 | ; the 10X registers @RH2 | ||
| 112 | CARD_ID_LO EQU 100H ;PS/2 Adapter card id low and @RH2 | ||
| 113 | CARD_ID_HI EQU 101H ; high bytes - read only @RH2 | ||
| 114 | ;Card IDs read from port 100,101 @RH2 | ||
| 115 | XMAA_CARD_ID EQU 0FEF7h ; XMA/A Card ID @RH2 | ||
| 116 | HLST_CARD_ID EQU 0FEFEh ; MXO @RH3 | ||
| 117 | NO_CARD EQU 0FFFFh ; No card present @RH5 | ||
| 118 | ;Values for the flag MEMCARD_MODE @RH5 | ||
| 119 | ; indicating what type of memory @RH5 | ||
| 120 | ; card is being used. @RH5 | ||
| 121 | XMA1_VIRT EQU 00000001B ; XMA 1...always in virtual | ||
| 122 | XMAA_VIRT EQU 00000010B ; XMA/A card (PS/2) in virtual | ||
| 123 | EMUL_VIRT EQU 00000100B ; XMA emulator on 80386 @RH7 | ||
| 124 | XMAA_REAL EQU 00001000B ; XMA/A in real mode...no banking @RH3 | ||
| 125 | HOLS_REAL EQU 00010000B ; MXO card @RH3 | ||
| 126 | ;Combinations | ||
| 127 | XMA1A_VIRT EQU 00000011B ; XMA1 or XMA/A in virtual mode | ||
| 128 | WSP_VIRT EQU 00000111B ; Any virtual mode...banking used | ||
| 129 | |||
| 130 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 131 | ;³ XMA, XMA\A, and XMA emulator declares ³ | ||
| 132 | ;³ ³ | ||
| 133 | ;³ The XMA translate table is a 4K x 12 bit ³ | ||
| 134 | ;³ array. A 12 bit address points to entries ³ | ||
| 135 | ;³ in the TT. The data in the entry is: ³ | ||
| 136 | ;³ ³ | ||
| 137 | ;³ Bit Contents ³ | ||
| 138 | ;³ 12 Inhibit bit (1 = inhibit xlate) ³ | ||
| 139 | ;³ 10-0 On XMA 1, pointer to 4K block ³ | ||
| 140 | ;³ for up to 4 meg capability ³ | ||
| 141 | ;³ 11-0 On XMA/A, pointer to 4K block ³ | ||
| 142 | ;³ for up to 8 meg capability ³ | ||
| 143 | ;³ ³ | ||
| 144 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 145 | ;All are byte ports unless indicated | ||
| 146 | |||
| 147 | X_CTRL_REG EQU 102H ;Control register - en/disable functions | ||
| 148 | X_CONF_REG EQU 105H ;Config (mem size), channel check reg. | ||
| 149 | RM_TTPTR_LO EQU 106H ;Translate table pointer low and | ||
| 150 | RM_TTPTR_HI EQU 107H ; high bytes | ||
| 151 | RM_TTDATA_LO EQU 103H ;TT data - high and low bytes | ||
| 152 | RM_TTDATA_HI EQU 104H ; Low byte (103) auto incs the TT ptr | ||
| 153 | |||
| 154 | ;Virtual mode port addresses for: | ||
| 155 | TTPOINTER EQU 31A0H ; Translate Table Pointer (word) | ||
| 156 | TTDATA EQU 31A2H ; Translate Table Data (word) | ||
| 157 | AIDATA EQU 31A4H ; TT Data with auto increment (word) | ||
| 158 | IDREG EQU 31A6H ; Bank ID register | ||
| 159 | MODE_REG EQU 31A7H ; Mode register | ||
| 160 | DMACAPT EQU 31A8H ; DMA capture register | ||
| 161 | |||
| 162 | CR_ROMSLEEP_DIS EQU 11011111B ;XMA/A control register mask to | ||
| 163 | ; disable the ROM on XMA/A card | ||
| 164 | XMA_TT_INHIBIT EQU 0000100000000000B ;XMA mask for an inhibitted TT entry | ||
| 165 | XMA_TT_MASK EQU 0000111111111111B ;XMA mask for anding off unused bits | ||
| 166 | EMUL_TTDATA_ON EQU 1000000000000000B ;XMA translate table data - mask for | ||
| 167 | ; the emulator. On XMA cards, data | ||
| 168 | ; is only 12 bits. On the emulator, | ||
| 169 | ; bit 15 turned on indicates data is | ||
| 170 | ; 15 bits. This allows the emulator | ||
| 171 | ; to use more than 8 Meg. Note that | ||
| 172 | ; both 0FFFh and FFFFh are inhibit. | ||
| 173 | |||
| 174 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 175 | ;³ MXO declares ³ | ||
| 176 | ;³ ³ | ||
| 177 | ;³ The MXO translate table is a 1K x 8 bit ³ | ||
| 178 | ;³ array. A 10 bit address points to entries ³ | ||
| 179 | ;³ in the TT. The data in the entry is: ³ | ||
| 180 | ;³ ³ | ||
| 181 | ;³ Bit Contents ³ | ||
| 182 | ;³ 8 Inhibit bit (0 = inhibit xlate) ³ | ||
| 183 | ;³ 7-0 Pointer to 16K block for up to ³ | ||
| 184 | ;³ 2 meg capability ³ | ||
| 185 | ;³ ³ | ||
| 186 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 187 | ;All are byte ports | ||
| 188 | H_CARD_INFO EQU 102H ;Info Bits 7-1 mem size Bit 0 sleep | ||
| 189 | H_CC_PRES EQU 105H ;Channel check, presence (Bit 0) | ||
| 190 | H_TTPTR_LO EQU 106H ;Translate table pointer low and | ||
| 191 | H_TTPTR_HI EQU 107H ; high bytes | ||
| 192 | H_TTDATA EQU 103H ;TT data - one byte. No auto inc. | ||
| 193 | |||
| 194 | H_TT_INHIBIT EQU 00000000B ;MXO value for setting inhibitted | ||
| 195 | ; translate table entry | ||
| 196 | H_TT_ENBMASK EQU 10000000B ;Pattern to test if TT entry read is | ||
| 197 | ; enabled. 'and' with entry,jz inhib | ||
| 198 | |||
| 199 | ;EMS ERROR CODES | ||
| 200 | EMS_CODE80 EQU 80H ; Sotware malfunction | ||
| 201 | EMS_CODE81 EQU 81H ; Hardware malfunction | ||
| 202 | EMS_CODE82 EQU 82H ; This return code not used | ||
| 203 | EMS_CODE83 EQU 83H ; Handle not found | ||
| 204 | EMS_CODE84 EQU 84H ; Invalid function code | ||
| 205 | EMS_CODE85 EQU 85H ; All handles used | ||
| 206 | EMS_CODE86 EQU 86H ; Save or restore mapping error | ||
| 207 | EMS_CODE87 EQU 87H ; Not enough pages to satisfy request | ||
| 208 | EMS_CODE88 EQU 88H ; Not enough unallocated pages | ||
| 209 | EMS_CODE89 EQU 89H ; Can't allocate zero pages | ||
| 210 | EMS_CODE8A EQU 8AH ; Logical page out of range | ||
| 211 | EMS_CODE8B EQU 8BH ; Physical page out of range | ||
| 212 | EMS_CODE8C EQU 8CH ; Hardware save area is full | ||
| 213 | EMS_CODE8D EQU 8DH ; Save area already saved for handle | ||
| 214 | EMS_CODE8E EQU 8EH ; Save area not saved for this handle | ||
| 215 | EMS_CODE8F EQU 8FH ; Subfunction parameter not defined | ||
| 216 | ;------------------------------------------------------------------- | ||
| 217 | EMS_CODE91 EQU 091H | ||
| 218 | EMS_CODE92 EQU 092H ; added for DMS ;an000; | ||
| 219 | EMS_CODE93 EQU 093H ;an000; | ||
| 220 | EMS_CODE94 EQU 094H ;an000; | ||
| 221 | EMS_CODE95 EQU 095H ;an000; | ||
| 222 | EMS_CODE96 EQU 096H ;an000; | ||
| 223 | EMS_CODE97 EQU 097H ;an000; | ||
| 224 | EMS_CODE98 EQU 098H ;an000; | ||
| 225 | EMS_CODE9E EQU 09EH ;an000; | ||
| 226 | EMS_CODE9C EQU 09CH ;an000; | ||
| 227 | ;------------------------------------------------------------------- ;an000; | ||
| 228 | EMS_CODEA0 EQU 0A0h ; No matching handle | ||
| 229 | EMS_CODEA1 EQU 0A1h ; Duplicate handle name | ||
| 230 | EMS_CODEA2 EQU 0A2h ; Memory wrap error | ||
| 231 | EMS_CODEA3 EQU 0A3h ; Data in control structure corrupted | ||
| 232 | EMS_CODEA4 EQU 0A4h ; Access to this function denied | ||
| 233 | |||
| 234 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 235 | ;³ Request Header (Common portion) ³ | ||
| 236 | ;³ ³ | ||
| 237 | ;³ This structure defines the portion that is common to ³ | ||
| 238 | ;³ all Request Headers. ³ | ||
| 239 | ;³ ³ | ||
| 240 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 241 | RH EQU DS:[BX] ;addressability to Request Header structure | ||
| 242 | |||
| 243 | RHC STRUC ;fields common to all request types | ||
| 244 | DB ? ;length of Request Header (including data) | ||
| 245 | DB ? ;unit code (subunit) | ||
| 246 | RHC_CMD DB ? ;command code | ||
| 247 | RHC_STA DW ? ;status | ||
| 248 | DQ ? ;reserved for DOS | ||
| 249 | RHC ENDS ;end of common portion | ||
| 250 | |||
| 251 | CMD_INPUT EQU 4 ;RHC_CMD is INPUT request | ||
| 252 | |||
| 253 | ;status values for RHC_STA | ||
| 254 | |||
| 255 | STAT_GOOD EQU 0000H ;invalid command code error | ||
| 256 | STAT_DONE EQU 0100H ;function complete status (OR on bit) | ||
| 257 | STAT_CMDERR EQU 8003H ;invalid command code error | ||
| 258 | STAT_CRC EQU 8004H ;CRC error | ||
| 259 | STAT_SNF EQU 8008H ;sector not found error | ||
| 260 | STAT_GENFAIL EQU 800CH ;general failure | ||
| 261 | NOT_BUSY EQU 11111101B ;busy bit (9) NOT BUSY mask (high order byte) | ||
| 262 | BUSY_MASK EQU 00000010B ;busy bit (9) BUSY mask (high order byte) | ||
| 263 | |||
| 264 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 265 | ;³ Request Header for INIT command ³ | ||
| 266 | ;³ ³ | ||
| 267 | ;³ This structure defines the Request Header for the ³ | ||
| 268 | ;³ INIT command ³ | ||
| 269 | ;³ ³ | ||
| 270 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 271 | RH0 STRUC | ||
| 272 | DB (TYPE RHC) DUP (?) ;common portion | ||
| 273 | |||
| 274 | RH0_NUN DB ? ;number of units | ||
| 275 | ;set to 1 if installation succeeds, | ||
| 276 | ;set to 0 to cause installation failure | ||
| 277 | RH0_ENDO DW ? ;offset of ending address | ||
| 278 | RH0_ENDS DW ? ;segment of ending address | ||
| 279 | RH0_BPBO DW ? ;offset of BPB array address | ||
| 280 | RH0_BPBS DW ? ;segment of BPB array address | ||
| 281 | RH0_DRIV DB ? ;drive code (DOS 3 only) | ||
| 282 | RH0_ERR DW 0 ; error flag used by DOS - gga | ||
| 283 | RH0 ENDS | ||
| 284 | |||
| 285 | RH0_BPBA EQU DWORD PTR RH0_BPBO ;OFFSET/SEGMENT OF BPB | ||
| 286 | ;note RH0_BPBA at entry to init points to all after DEVICE= on CONFIG.SYS stmt | ||
| 287 | |||
| 288 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 289 | ;³ Request Header for OUTPUT STATUS command ³ | ||
| 290 | ;³ ³ | ||
| 291 | ;³ This structure defines the Request Header for the ³ | ||
| 292 | ;³ Output Status command. ³ | ||
| 293 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 294 | RH10 STRUC | ||
| 295 | DB (TYPE RHC) DUP (?) ;common portion | ||
| 296 | RH10 ENDS | ||
| 297 | |||
| 298 | |||
| 299 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 300 | ;³ Request Header for Generic IOCTL Request ³ | ||
| 301 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 302 | |||
| 303 | RH19 STRUC | ||
| 304 | DB (TYPE RHC) DUP (?) ; Reserve space for the header @RH6 | ||
| 305 | |||
| 306 | RH19_MAJF DB ? ; Major function @RH6 | ||
| 307 | RH19_MINF DB ? ; Minor function @RH6 | ||
| 308 | RH19_SI DW ? ; Contents of SI @RH6 | ||
| 309 | RH19_DI DW ? ; Contents of DI @RH6 | ||
| 310 | RH19_RQPK DD ? ; Pointer to Generic IOCTL request packet @RH6 | ||
| 311 | RH19 ENDS | ||
| 312 | |||
| 313 | |||
| 314 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 315 | ;³ Map EMS INT 67H vector in low storage ³ | ||
| 316 | ;³ ³ | ||
| 317 | ;³ The vector for the interrupt handler for INT 67H ³ | ||
| 318 | ;³ is defined here. ³ | ||
| 319 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 320 | INT_VEC SEGMENT AT 00H | ||
| 321 | ORG 4*EMS_INT | ||
| 322 | EMS_VEC LABEL DWORD | ||
| 323 | EMS_VECO DW ? ;offset | ||
| 324 | EMS_VECS DW ? ;segment | ||
| 325 | INT_VEC ENDS | ||
| 326 | |||
| 327 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 328 | ;³ Map EM INT 15H vector in low storage ³ | ||
| 329 | ;³ ³ | ||
| 330 | ;³ The vector for the extended memory interrupt handler INT 15h ³ | ||
| 331 | ;³ is defined here. ³ | ||
| 332 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 333 | INT_VEC15 SEGMENT AT 00H ;an000; dms; | ||
| 334 | ORG 4*EM_INT ;an000; dms; | ||
| 335 | EM_VEC LABEL DWORD ;an000; dms; | ||
| 336 | EM_VECO DW ? ;offset ;an000; dms; | ||
| 337 | EM_VECS DW ? ;segment ;an000; dms; | ||
| 338 | INT_VEC15 ENDS ;an000; dms; | ||
| 339 | |||
| 340 | |||
| 341 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 342 | ;³ Map INT 13h vector in low storage ³ | ||
| 343 | ;³ ³ | ||
| 344 | ;³ The vector for the disk access interrupt handler INT 13h ³ | ||
| 345 | ;³ is defined here. ³ | ||
| 346 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 347 | INT_VEC13 SEGMENT AT 00H ;an004; dms; | ||
| 348 | ORG 4*DK_INT ;an004; dms; | ||
| 349 | DK_VEC LABEL DWORD ;an004; dms; | ||
| 350 | DK_VECO DW ? ;offset ;an004; dms; | ||
| 351 | DK_VECS DW ? ;segment ;an004; dms; | ||
| 352 | INT_VEC13 ENDS ;an004; dms; | ||
| 353 | |||
| 354 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 355 | ;º This marks the start of the device driver code segment º | ||
| 356 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 357 | |||
| 358 | CSEG SEGMENT PARA PUBLIC 'CODE' | ||
| 359 | ASSUME CS:CSEG | ||
| 360 | |||
| 361 | START EQU $ ;begin resident XMA2EMS data & code | ||
| 362 | |||
| 363 | ;DEVICE HEADER - must be at offset zero within device driver | ||
| 364 | DD -1 ;becomes pointer to next device header | ||
| 365 | DW 0C040H ;attribute (character device) | ||
| 366 | DW OFFSET STRATEGY ;pointer to device "strategy" routine | ||
| 367 | DW OFFSET IRPT ;pointer to device "interrupt handler" | ||
| 368 | DB 'EMMXXXX0' ;device name | ||
| 369 | |||
| 370 | |||
| 371 | ;-----------------------------------------------------------------------; | ||
| 372 | ; The next word is used to inform the 3270 Workstation Program ; | ||
| 373 | ; which 4K block in XMA marks the start of EMS Expanded Memory. ; | ||
| 374 | ;-----------------------------------------------------------------------; | ||
| 375 | EMS_START_IN_XMA DW 0 ;initially, memory manager uses all | ||
| 376 | |||
| 377 | ;-----------------------------------------------------------------------; | ||
| 378 | ; The following is the Code Label: | ||
| 379 | ;-----------------------------------------------------------------------; | ||
| 380 | COPYRIGHT DB '74X9921 (C)COPYRIGHT 1988 Microsoft ' | ||
| 381 | DB 'LEVEL 1.00 LICENSED MATERIAL - PROGRAM ' | ||
| 382 | DB 'PROPERTY OF Microsoft ' | ||
| 383 | |||
| 384 | ;-----------------------------------------------------------------------; | ||
| 385 | ; Request Header (RH) address, saved here by "strategy" routine ; | ||
| 386 | ;-----------------------------------------------------------------------; | ||
| 387 | RH_PTRA LABEL DWORD | ||
| 388 | RH_PTRO DW ? ;offset | ||
| 389 | RH_PTRS DW ? ;segment | ||
| 390 | db 7 dup(0) ;align following tables on seg. | ||
| 391 | |||
| 392 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 393 | ;³ HANDLE LOOKUP TABLE ³ | ||
| 394 | ;³ ³ | ||
| 395 | ;³ This table keeps track of EMS handles and pages assigned ³ | ||
| 396 | ;³ to each handle. An entry exists for each of the 64 handles ³ | ||
| 397 | ;³ supported. If the handle is active, the first field will ³ | ||
| 398 | ;³ contain the number of pages it owns. Otherwise, the field ³ | ||
| 399 | ;³ will indicate the handle is free. The second field is a head ³ | ||
| 400 | ;³ pointer to the handle's pages in the linked Page Allocation List. ³ | ||
| 401 | ;³ ³ | ||
| 402 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 403 | H_LOOKUP_STRUC STRUC ;Structure for Handle lookup table @RH1 | ||
| 404 | H_PAGES DW REUSABLE_HANDLE ;If handle is active, # of owned @RH8 | ||
| 405 | ; pages. Init to reusable handle RH8 | ||
| 406 | H_PAL_PTR DW PAL_NULL ;Head ptr for owned pages in PAL @RH8 | ||
| 407 | H_NAME DB 8 DUP(0) ;Name - new for LIM 4.0 @GGA | ||
| 408 | H_BANK DB 0 ;If virtual, this handle's bank @RH6 | ||
| 409 | xref_pages dw 0 ;temp to compile | ||
| 410 | xref_index dw 0 ;temp to compile | ||
| 411 | H_LOOKUP_STRUC ENDS | ||
| 412 | |||
| 413 | NUM_HANDLES EQU 64 ;One structure @RH1 | ||
| 414 | HANDLE_LOOKUP_TABLE H_LOOKUP_STRUC <0,,,,,> ; initialize handle 0 | ||
| 415 | H_LOOKUP_STRUC NUM_HANDLES-1 DUP (<>) ; for OS use - gga | ||
| 416 | |||
| 417 | ;-----------------------------------------------------------------------; | ||
| 418 | ; HANDLE CROSS REFERENCE (XREF) TABLE ; | ||
| 419 | ; Each entry in the Handle_Xref_Table points to a corresponding ; | ||
| 420 | ; page in the page allocation table. Entries in the XREF table ; | ||
| 421 | ; are contiguous for a handle, while PAT entries may not be. ; | ||
| 422 | ;-----------------------------------------------------------------------; | ||
| 423 | XREF_TABLE_LEN EQU 2048 ; @RH1 | ||
| 424 | |||
| 425 | HANDLE_XREF_TABLE DW XREF_TABLE_LEN DUP(0) ; Changed from byte to @RH1 | ||
| 426 | ; word table @RH1 | ||
| 427 | XREF_TABLE_END EQU ($) ;Used for table shift on deallocate @RH1 | ||
| 428 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 429 | ;³ PAGE ALLOCATION LIST ³ | ||
| 430 | ;³ ³ | ||
| 431 | ;³ This is the structure pointed to by the handle lookup table. ³ | ||
| 432 | ;³ The Page Allocation list is a linked list governing EMS pages. ³ | ||
| 433 | ;³ Each 16KB EMS page has an entry in the PAGE_ALLOC_LIST. ³ | ||
| 434 | ;³ The entries correspond to the physical blocks on the extended ³ | ||
| 435 | ;³ memory cards (ex. the first 2 Meg card in a system will use the ³ | ||
| 436 | ;³ first 128 entries in the PAL). ³ | ||
| 437 | ;³ At initialization time, a 'free' pointer will point to the last³ | ||
| 438 | ;³ (top) page in the PAL, and all entries will be linked from top ³ | ||
| 439 | ;³ down. Whenever pages are allocated they are retreived from the ³ | ||
| 440 | ;³ free chain, and deallocated pages are placed back on the free ³ | ||
| 441 | ;³ chain. ³ | ||
| 442 | ;³ ³ | ||
| 443 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 444 | EMS_PAGES_SUPPORTED EQU 1024 ;Support up to 16 Megabytes of EMS @RH8 | ||
| 445 | |||
| 446 | PAGE_ALLOC_LIST DW EMS_PAGES_SUPPORTED DUP(0) | ||
| 447 | ;Page Allocation List (PAL) @RH8 | ||
| 448 | page_alloc_table db 1024 dup(unallocated) ;temp for assemble | ||
| 449 | ;-----------------------------------------------------------------------; | ||
| 450 | ; HANDLE SAVE AREA ; | ||
| 451 | ; Each handle has 4 entries where the page frame map can ; | ||
| 452 | ; be stored. Each entry contains a word for the handle and ; | ||
| 453 | ; a word for the logical page active there. If no save has ; | ||
| 454 | ; occurred for a handle, then the logical page field in the ; | ||
| 455 | ; save area will contain a value indicating it's reusable. ; | ||
| 456 | ;-----------------------------------------------------------------------; | ||
| 457 | H_SAVEA_ENTRY STRUC ;This is an overlay for one page's @RH5 | ||
| 458 | HSA_HNDL DW ? ; entry in the handle save area. @RH5 | ||
| 459 | HSA_LP DW ? ; It is used to clear the save @RH5 | ||
| 460 | H_SAVEA_ENTRY ENDS ; area after a restore. While not @RH5 | ||
| 461 | ; directly used by the structure @RH5 | ||
| 462 | ; below, its size should match @RH5 | ||
| 463 | ; that for one page entry @RH5 | ||
| 464 | |||
| 465 | H_SAVE_STRUC STRUC ;Structure for Handle Save Area @RH1 | ||
| 466 | PG0_HNDL DW 0 | ||
| 467 | PG0_LP DW REUSABLE_SAVEA | ||
| 468 | PG1_HNDL DW 0 | ||
| 469 | PG1_LP DW REUSABLE_SAVEA | ||
| 470 | PG2_HNDL DW 0 | ||
| 471 | PG2_LP DW REUSABLE_SAVEA | ||
| 472 | PG3_HNDL DW 0 | ||
| 473 | PG3_LP DW REUSABLE_SAVEA | ||
| 474 | PGFE_HNDL DW 0 ;AN006; | ||
| 475 | PGFE_LP DW REUSABLE_SAVEA ;AN006; | ||
| 476 | PGFF_HNDL DW 0 ;AN006; | ||
| 477 | PGFF_LP DW REUSABLE_SAVEA ;AN006; | ||
| 478 | H_SAVE_STRUC ENDS | ||
| 479 | |||
| 480 | HANDLE_SAVE_AREA H_SAVE_STRUC NUM_HANDLES DUP (<>) | ||
| 481 | ;One structure for each handle @RH1 | ||
| 482 | |||
| 483 | H_SAVE_ENTRY EQU WORD PTR[DI + OFFSET HANDLE_SAVE_AREA] ; @RH1 | ||
| 484 | |||
| 485 | |||
| 486 | ;------------------------------------------------------------------- | ||
| 487 | ; | ||
| 488 | ; mappable_phys_page table | ||
| 489 | ; | ||
| 490 | ; This table is used by function 5800h | ||
| 491 | ; | ||
| 492 | ;------------------------------------------------------------------- | ||
| 493 | |||
| 494 | mappable_phys_page_struct STRUC ; define the structure | ||
| 495 | phys_page_segment dw ? ; segment | ||
| 496 | phys_page_number dw ? ; page ID | ||
| 497 | ppm_handle dw ? ; handle, -1 means unused | ||
| 498 | ppm_log_page dw ? ; logical page, -1 means unused | ||
| 499 | mappable_phys_page_struct ENDS | ||
| 500 | |||
| 501 | ; allocate the storage | ||
| 502 | |||
| 503 | map_table mappable_phys_page_struct <-1, -1, -1, -1> ;p0 no default | ||
| 504 | mappable_phys_page_struct <-1, -1, -1, -1> ;p1 no default | ||
| 505 | mappable_phys_page_struct <-1, -1, -1, -1> ;p2 no default | ||
| 506 | mappable_phys_page_struct <-1, -1, -1, -1> ;p3 no default | ||
| 507 | mappable_phys_page_struct <-1, -1, -1, -1> ;p254 no default | ||
| 508 | mappable_phys_page_struct <-1, -1, -1, -1> ;p255 no default | ||
| 509 | |||
| 510 | map_count_def equ 6 ; default 6 | ||
| 511 | map_count dw 0 ; | ||
| 512 | map_size dw type mappable_phys_page_struct * map_count_def ; size of default table | ||
| 513 | ppm_size equ 6 ;size of partial page map entry | ||
| 514 | |||
| 515 | ; flags and a word used in setting up map_table stuff, see parmpars.inc | ||
| 516 | |||
| 517 | p0_flag equ 0001h ; flags used to indicate which p's were | ||
| 518 | p1_flag equ 0002h ; set on command line | ||
| 519 | p2_flag equ 0004h | ||
| 520 | p3_flag equ 0008h | ||
| 521 | p254_flag equ 0010h | ||
| 522 | p255_flag equ 0020h | ||
| 523 | frame_flag equ 8000h ; special flag used when FRAME= was found | ||
| 524 | |||
| 525 | page_flags dw 0 ; word of above flags used in setting map_table | ||
| 526 | parse_flag dw 0 ; flag used to indicate command line args were encountered | ||
| 527 | |||
| 528 | ;------------------------------------------------------------------- | ||
| 529 | ; rom scan stuff | ||
| 530 | ;------------------------------------------------------------------- | ||
| 531 | family1 equ 1 | ||
| 532 | micro_channel equ 2 | ||
| 533 | |||
| 534 | |||
| 535 | rom_scan_type dw micro_channel ; | ||
| 536 | segment_error dw 0 ; segment error flag = 0 means all OK | ||
| 537 | |||
| 538 | ;----------------------------------------------------------------------- | ||
| 539 | ; Tables added for multicard support º | ||
| 540 | ; º | ||
| 541 | ; These tables manage the mapping of multiple memory cards º | ||
| 542 | ; on a PS/2 Model 50 and 60. These systems may have a combination º | ||
| 543 | ; of MXO and XMA/A cards. The model 80 is excluded, since º | ||
| 544 | ; it uses the XMA emulator. º | ||
| 545 | ; º | ||
| 546 | ;----------------------------------------------------------------------- | ||
| 547 | ;----------------------------------------------- | ||
| 548 | ; Memory Card Descriptor Table º | ||
| 549 | ;----------------------------------------------- | ||
| 550 | |||
| 551 | MEM_CARD_STRUC STRUC ;Structure for the memory cards @RH5 | ||
| 552 | CARD_ID DW NO_CARD ;Card ID from ports 100 and 101 @RH5 | ||
| 553 | CARD_SLOT DB ? ;Physical slot of card (0 based) @RH5 | ||
| 554 | START_PG_NUM DW ? ;Starting and ending #s of the @RH5 | ||
| 555 | END_PG_NUM DW ? ; pages this card has within the @RH5 | ||
| 556 | MEM_CARD_STRUC ENDS ; total EMS page pool (0 based) @RH5 | ||
| 557 | |||
| 558 | ;Memory Card Table - entries are @RH5 | ||
| 559 | ; filled in ascending order (from @RH5 | ||
| 560 | ; slot 0) for each card found. @RH5 | ||
| 561 | ; MXOs scanned 1st, then XMA/A @RH5 | ||
| 562 | MAX_SLOTS EQU 8 ;Max of 8, but most @RH5 | ||
| 563 | MEM_CARD_TABLE MEM_CARD_STRUC MAX_SLOTS DUP (<>) ; likely 1 or 2 cards @RH5 | ||
| 564 | |||
| 565 | ;----------------------------------------------- | ||
| 566 | ; Multicard Page Frame Descriptor Table º | ||
| 567 | ;----------------------------------------------- | ||
| 568 | MULTIC_PM_STRUC STRUC ;Structure for storing the card ID @RH5 | ||
| 569 | PG_CARD DW NO_CARD ; and slot of the card currently @RH5 | ||
| 570 | PG_SLOT DB 0 ; mapped to this page of the page @RH5 | ||
| 571 | MULTIC_PM_STRUC ENDS ; frame @RH5 | ||
| 572 | |||
| 573 | ;Multicard Page Mapping Table. | ||
| 574 | ; Entry for each page of the page | ||
| 575 | ; frame (including pages FE & FF) | ||
| 576 | MC_PM_TABLE MULTIC_PM_STRUC MAP_COUNT_DEF DUP (<>) | ||
| 577 | |||
| 578 | ;----------------------------------------------- | ||
| 579 | ; Assorted Multicard declares º | ||
| 580 | ;----------------------------------------------- | ||
| 581 | NUM_MEM_CARDS DW 0 | ||
| 582 | NUM_OF_SLOTS DB ? ;Number of adapter slots RR 8 TB 4 @RH2 | ||
| 583 | WTT_CARD_SLOT DB ? ;Slot # of the memory card being @RH2 | ||
| 584 | ; used to map a page @RH2 | ||
| 585 | |||
| 586 | |||
| 587 | Instance_Entry_Struc struc ;required data in first 2 entries ;an000; dms; | ||
| 588 | IE_Alloc_Byte db ? ;instance allocated byte ;an000; dms; | ||
| 589 | IE_Saved_DI_Reg dw ? ;saved di register ;an000; dms; | ||
| 590 | Instance_Entry_Struc ends ;end struc ;an000; dms; | ||
| 591 | |||
| 592 | ;-----------------------------------------------------------------------; | ||
| 593 | ; Table of DOS command processing routine entry points ; | ||
| 594 | ; ; | ||
| 595 | ; An '*' in the comment area indicates the command is handled ; | ||
| 596 | ; by meaningful code. All other commands simply set a good ; | ||
| 597 | ; return code and exit back to DOS. ; | ||
| 598 | ;-----------------------------------------------------------------------; | ||
| 599 | CMD_TABLE LABEL WORD | ||
| 600 | DW OFFSET INIT ; 0 - *Initialization | ||
| 601 | DW OFFSET MEDIA_CHECK ; 1 - Media check | ||
| 602 | DW OFFSET BLD_BPB ; 2 - Build BPB | ||
| 603 | DW OFFSET INPUT_IOCTL ; 3 - IOCTL input | ||
| 604 | DW OFFSET INPUT ; 4 - Input | ||
| 605 | DW OFFSET INPUT_NOWAIT ; 5 - Non destructive input no wait | ||
| 606 | DW OFFSET INPUT_STATUS ; 6 - Input status | ||
| 607 | DW OFFSET INPUT_FLUSH ; 7 - Input flush | ||
| 608 | DW OFFSET OUTPUT ; 8 - Output | ||
| 609 | DW OFFSET OUTPUT_VERIFY ; 9 - Output with verify | ||
| 610 | DW OFFSET OUTPUT_STATUS ;10 - *Output status | ||
| 611 | DW OFFSET OUTPUT_FLUSH ;11 - Output flush | ||
| 612 | DW OFFSET OUTPUT_IOCTL ;12 - IOCTL output | ||
| 613 | DW OFFSET DEVICE_OPEN ;13 - Device OPEN | ||
| 614 | DW OFFSET DEVICE_CLOSE ;14 - Device CLOSE | ||
| 615 | DW OFFSET REMOVABLE_MEDIA ;15 - Removable media | ||
| 616 | DW OFFSET INVALID_FCN ;16 - Invalid IOCTL function gga ;AN003; | ||
| 617 | DW OFFSET INVALID_FCN ;17 - Invalid IOCTL function gga ;AN003; | ||
| 618 | DW OFFSET INVALID_FCN ;18 - Invalid IOCTL function gga ;AN003; | ||
| 619 | DW OFFSET GENERIC_IOCTL ;19 - *Generic IOCTL function gga ;AN003; | ||
| 620 | DW OFFSET INVALID_FCN ;20 - Invalid IOCTL function gga ;AN003; | ||
| 621 | DW OFFSET INVALID_FCN ;21 - Invalid IOCTL function gga ;AN003; | ||
| 622 | DW OFFSET INVALID_FCN ;22 - Invalid IOCTL function gga ;AN003; | ||
| 623 | DW OFFSET GET_LOG_DEVICE ;23 - Invalid IOCTL function gga ;AN003; | ||
| 624 | MAX_CMD EQU ($-CMD_TABLE)/2 ;highest valid command follows | ||
| 625 | DW OFFSET SET_LOG_DEVICE ;24 - Invalid IOCTL function gga ;AN003; | ||
| 626 | |||
| 627 | ;-----------------------------------------------------------------------; | ||
| 628 | ; Table of Expanded Memory Manager routine entry points ; | ||
| 629 | ;-----------------------------------------------------------------------; | ||
| 630 | FCN_TABLE LABEL WORD | ||
| 631 | DW OFFSET EMM_STATUS ;40 - Get status of memory manager | ||
| 632 | DW OFFSET Q_PAGE_FRAME ;41 - Get segment of page frame | ||
| 633 | DW OFFSET Q_PAGES ;42 - Get number of alloc & unalloc pgs | ||
| 634 | DW OFFSET GET_HANDLE ;43 - Request ID and allocate n pages | ||
| 635 | DW OFFSET MAP_L_TO_P ;44 - Map logical to physical page | ||
| 636 | DW OFFSET DE_ALLOCATE ;45 - Deallocate all pages of ID n | ||
| 637 | DW OFFSET Q_VERSION ;46 - Get version number | ||
| 638 | DW OFFSET SAVE_MAP ;47 - Save mapping array | ||
| 639 | DW OFFSET RESTORE_MAP ;48 - Restore mapping array | ||
| 640 | DW OFFSET GET_PORT_ARRAY ;49 - Get I/O port array | ||
| 641 | DW OFFSET GET_L_TO_P ;4A - Get logical to physical array | ||
| 642 | DW OFFSET Q_OPEN ;4B - Get number of open ID's | ||
| 643 | DW OFFSET Q_ALLOCATE ;4C - Get pages allocated to ID n | ||
| 644 | DW OFFSET Q_OPEN_ALL ;4D - Get all ID's and pages allocated | ||
| 645 | DW OFFSET GET_SET_MAP ;4E - Group of subfunctions that Get | ||
| 646 | ;and/or Set the page map | ||
| 647 | |||
| 648 | ;------------------------------------------------------------------- ;GGA | ||
| 649 | ; these functions were added for LIM 4.0 support ;GGA | ||
| 650 | ;------------------------------------------------------------------- ;GGA | ||
| 651 | ;GGA | ||
| 652 | dw offset partial_map ; 4F - get/set partial page map ;GGA | ||
| 653 | dw offset map_mult ; 50 - map/unmap multiple handle pages ;GGA | ||
| 654 | dw offset reallocate ; 51 - reallocate pages ;GGA | ||
| 655 | dw offset handle_attrib ; 52 - get/set handle attributes ;GGA | ||
| 656 | dw offset handle_name ; 53 - get/set handle name ;GGA | ||
| 657 | dw offset handle_dir ; 54 - get handle directory ;GGA | ||
| 658 | dw offset alter_and_jump ; 55 - alter page map and jump ;GGA | ||
| 659 | dw offset alter_and_call ; 56 - alter page map and call ;GGA | ||
| 660 | dw offset exchng_region ; 57 - move/exchange memory region ;GGA | ||
| 661 | dw offset address_array ; 58 - Get mappable physical address array ;GGA | ||
| 662 | dw offset hardware_info ; 59 - Get extended momory hardware information ;GGA | ||
| 663 | dw offset alloc_raw ; 5A - allocate raw pages ;GGA | ||
| 664 | dw offset alternate_map ; 5B - alternate map register set ;GGA | ||
| 665 | dw offset prepare_boot ; 5C - Prepare for WarmBoot ;GGA | ||
| 666 | MAX_FCN EQU ($-FCN_TABLE)/2 ; highest valid command follows ;GGA | ||
| 667 | dw offset enable_os ; 5D - enable/disable OS/E functions ;GGA | ||
| 668 | |||
| 669 | ;-----------------------------------------------------------------------; | ||
| 670 | ; Data variables go here ; | ||
| 671 | ;-----------------------------------------------------------------------; | ||
| 672 | PAGE_FRAME_STA DW 0D000H ;STARTING SEG OF PAGE FRAME | ||
| 673 | TOTAL_SYS_PAGES DW 1024/16 ;Total number of 16k pages on the | ||
| 674 | ; memory card(s) that are initially | ||
| 675 | ; expanded memory. On PS/2 50 + 60, | ||
| 676 | ; pages used as extended are subtracted. | ||
| 677 | TOTAL_EMS_PAGES DW 1024/16 ;Pages left after conventional | ||
| 678 | ; memory is backed | ||
| 679 | FREE_PAGES DW 1024/16 ;Total unallocated pages for EMS use | ||
| 680 | EM_Ksize dw ? ;size in Kb of extended memory ;an000; dms; | ||
| 681 | CARD_STATUS DW 'OK' ;STATUS OF THE HARDWARE | ||
| 682 | ; DEFAULT='OK' FAILURE='HW' | ||
| 683 | MANAGER_STATUS DW 'OK' ;STATUS OF THE MEMORY MANAGER | ||
| 684 | ; DEFAULT='OK' FAILURE='SW' | ||
| 685 | STARTING_BLOCK DW 0 ;number of 4K blocks reserved by pinta | ||
| 686 | OVERFLOW DB 0 | ||
| 687 | WARM_START DB 'N' ;initially not a warm start | ||
| 688 | MULTIPLIER DW ? ;Used for figuring table offsets @RH1 | ||
| 689 | TEN DW 10 ; via multiplication...not the @RH1 | ||
| 690 | SIXTEEN DW 16 ; most efficient, but flexible @RH1 | ||
| 691 | MEMCARD_MODE DB XMA1_VIRT ;Flag indicating the type of memory@RH2 | ||
| 692 | ; card being used. Default to @RH2 | ||
| 693 | ; XMA 1 card. | ||
| 694 | BANKID DB ? ;Current XMA Bank ID @RH1 | ||
| 695 | BLOCKS_PER_PAGE DW 4 ;XMA blocks per EMS page (multiply)@RH1 | ||
| 696 | SEG_PER_PAGE DW 1024 ;Segments(16 bytes) per EMS page @RH1 | ||
| 697 | |||
| 698 | INTV15 LABEL DWORD ;an000; dms; | ||
| 699 | INTV15O DW ? ;offset ;an000; dms; | ||
| 700 | INTV15S DW ? ;segment ;an000; dms; | ||
| 701 | |||
| 702 | INTV13 LABEL DWORD ;an004; dms; | ||
| 703 | INTV13O DW ? ;offset ;an004; dms; | ||
| 704 | INTV13S DW ? ;segment ;an004; dms; | ||
| 705 | |||
| 706 | PAL_FREE_PTR DW PAL_NULL | ||
| 707 | ;------------------------------------------------------------------- | ||
| 708 | ; define some flags and storage for the enable/disable functions | ||
| 709 | ;------------------------------------------------------------------- | ||
| 710 | |||
| 711 | ose_enabled equ 1 ; flags used to enable/disable OS/E fcns ;an000; | ||
| 712 | ose_disabled equ 0 ;an000; | ||
| 713 | |||
| 714 | access_code dd 0 ; access code used by OS/E functions ;an000; | ||
| 715 | ose_functions dw ose_enabled ; OS/E functions 1 = enabled, 0 = disabled ;an000; | ||
| 716 | |||
| 717 | ;------------------------------------------------------------------- | ||
| 718 | ; define some storage for the ROM scan logic | ||
| 719 | ;------------------------------------------------------------------- | ||
| 720 | where_to_start dw 0a000h ; start ROM scan at A000 | ||
| 721 | |||
| 722 | |||
| 723 | ;-----------------------------------------------------------------------; | ||
| 724 | ; INT 15H Interrupt Handler routine ; | ||
| 725 | ;-----------------------------------------------------------------------; | ||
| 726 | |||
| 727 | ;========================================================================= | ||
| 728 | ; XMA_INT15 : This routine traps the INT 15h requests to perform its | ||
| 729 | ; own unique services. This routine provides 1 INT 15h | ||
| 730 | ; service; function 8800h. | ||
| 731 | ; | ||
| 732 | ; Service - Function 8800h: Obtains the size of EM from the word | ||
| 733 | ; value EM_KSize | ||
| 734 | ; Call With: AX - 8800h | ||
| 735 | ; Returns : AX - Kbyte size of EM | ||
| 736 | ; | ||
| 737 | ;========================================================================= | ||
| 738 | XMA_INT15 PROC ;an000; dms; | ||
| 739 | |||
| 740 | cmp ah,EM_Size_Get ;an000; dms;function 88h? | ||
| 741 | jne XMA_INT15_Jump ;an000; dms;no - jump to old INT 15h | ||
| 742 | mov ax,cs:EM_KSize ;an000; dms;return size | ||
| 743 | clc ;an000; dms;clear CY | ||
| 744 | jmp XMA_INT15_Exit ;an000; dms;exit handler | ||
| 745 | |||
| 746 | XMA_INT15_Jump: ;an000; dms; | ||
| 747 | |||
| 748 | jmp cs:INTV15 ;an000; dms;jump to org. vector | ||
| 749 | |||
| 750 | XMA_INT15_Exit: ;an000; dms; | ||
| 751 | |||
| 752 | |||
| 753 | iret ;an000; dms; | ||
| 754 | |||
| 755 | XMA_INT15 ENDP ;an000; dms; | ||
| 756 | |||
| 757 | include I13HOOK.INC ;an004; dms; | ||
| 758 | |||
| 759 | |||
| 760 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 761 | ;º Device "strategy" entry point º | ||
| 762 | ;º º | ||
| 763 | ;º Retain the Request Header address for use by Interrupt routine º | ||
| 764 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 765 | STRATEGY PROC FAR | ||
| 766 | MOV CS:RH_PTRO,BX ;offset | ||
| 767 | MOV CS:RH_PTRS,ES ;segment | ||
| 768 | RET | ||
| 769 | STRATEGY ENDP | ||
| 770 | |||
| 771 | |||
| 772 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 773 | ;º DOS Device "interrupt" entry point º | ||
| 774 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 775 | IRPT PROC FAR ;device interrupt entry point | ||
| 776 | PUSH DS ;save all registers Revised | ||
| 777 | PUSH ES | ||
| 778 | PUSH AX | ||
| 779 | PUSH BX | ||
| 780 | PUSH CX | ||
| 781 | PUSH DX | ||
| 782 | PUSH DI | ||
| 783 | PUSH SI | ||
| 784 | ;BP isn't used, so it isn't saved | ||
| 785 | CLD ;all moves forward | ||
| 786 | |||
| 787 | LDS BX,CS:RH_PTRA ;get RH address passed to "strategy" into DS:BX | ||
| 788 | |||
| 789 | MOV AL,RH.RHC_CMD ;command code from Request Header | ||
| 790 | CBW ;zero AH (if AL > 7FH, next compare will | ||
| 791 | ;catch that error) | ||
| 792 | |||
| 793 | CMP AL,MAX_CMD ;if command code is not too high | ||
| 794 | JNA IRPT_CMD_OK ; then handle the command | ||
| 795 | MOV RH.RHC_STA,STAT_CMDERR ;"invalid command" and error | ||
| 796 | JMP IRPT_CMD_EXIT | ||
| 797 | |||
| 798 | IRPT_CMD_OK: | ||
| 799 | MOV RH.RHC_STA,STAT_GOOD ;initialize return to "no error" | ||
| 800 | |||
| 801 | ADD AX,AX ;double command code for table offset | ||
| 802 | MOV DI,AX ;put into index register for JMP | ||
| 803 | |||
| 804 | ;At entry to command processing routine: | ||
| 805 | ; DS:BX = Request Header address | ||
| 806 | ; CS = VDISK code segment address | ||
| 807 | ; AX = 0 | ||
| 808 | |||
| 809 | CALL CS:CMD_TABLE[DI] ;call routine to handle the command | ||
| 810 | |||
| 811 | |||
| 812 | IRPT_CMD_EXIT: ;return from command routine | ||
| 813 | ;AX = value to OR into status word | ||
| 814 | LDS BX,CS:RH_PTRA ;restore DS:BX as Request Header pointer | ||
| 815 | OR RH.RHC_STA,STAT_DONE ;add "done" bit to status word | ||
| 816 | POP SI ;restore registers | ||
| 817 | POP DI | ||
| 818 | POP DX | ||
| 819 | POP CX | ||
| 820 | POP BX | ||
| 821 | POP AX | ||
| 822 | POP ES | ||
| 823 | POP DS | ||
| 824 | |||
| 825 | RET ;far return back to DOS | ||
| 826 | IRPT ENDP | ||
| 827 | |||
| 828 | include genioctl.inc ; include code for genioctl fcn gga | ||
| 829 | |||
| 830 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 831 | ;º Set 'OUTPUT STATUS' entry point º | ||
| 832 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 833 | OUTPUT_STATUS PROC ;Output status | ||
| 834 | LDS BX,CS:RH_PTRA ;DS:BX as pointer to request header | ||
| 835 | MOV AX,RH.RHC_STA ;get status word | ||
| 836 | OS1: | ||
| 837 | AND AH,NOT_BUSY ;turn off busy bit | ||
| 838 | OS2: | ||
| 839 | MOV RH.RHC_STA,AX ;write it back to request header | ||
| 840 | RET | ||
| 841 | OUTPUT_STATUS ENDP | ||
| 842 | |||
| 843 | |||
| 844 | IGNORED_CMDS PROC | ||
| 845 | IRPT_CMD_ERROR: ;CALLed for unsupported character mode commands | ||
| 846 | |||
| 847 | MEDIA_CHECK: ;Media check | ||
| 848 | BLD_BPB: ;Build BPB | ||
| 849 | INPUT_IOCTL: ;IOCTL input | ||
| 850 | INPUT: ;Input | ||
| 851 | INPUT_NOWAIT: ;Non destructive input no wait | ||
| 852 | INPUT_STATUS: ;Input status | ||
| 853 | INPUT_FLUSH: ;Input flush | ||
| 854 | OUTPUT: ;Output | ||
| 855 | OUTPUT_VERIFY: ;Output with verify | ||
| 856 | OUTPUT_FLUSH: ;Output flush | ||
| 857 | OUTPUT_IOCTL: ;IOCTL output | ||
| 858 | DEVICE_OPEN: ;Device OPEN | ||
| 859 | DEVICE_CLOSE: ;Device CLOSE | ||
| 860 | REMOVABLE_MEDIA: ;Removable media | ||
| 861 | INVALID_FCN: ; invalid IOCTL function ;AN003; | ||
| 862 | GET_LOG_DEVICE: ; get logical device ;AN003; | ||
| 863 | SET_LOG_DEVICE: ; set logical device ;AN003; | ||
| 864 | RET | ||
| 865 | IGNORED_CMDS ENDP | ||
| 866 | |||
| 867 | |||
| 868 | |||
| 869 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 870 | ;º Entry point for EMM interrupt handler º | ||
| 871 | ;º º | ||
| 872 | ;º º | ||
| 873 | ;º The interrupt vector 67H points here. º | ||
| 874 | ;º º | ||
| 875 | ;º On Entry: º | ||
| 876 | ;º The AH register contains the function number and the º | ||
| 877 | ;º necessary parameters are passed in registers defined º | ||
| 878 | ;º by the Expanded Memory Specification. º | ||
| 879 | ;º º | ||
| 880 | ;º On Exit: º | ||
| 881 | ;º (AH) = 0 if no error º | ||
| 882 | ;º (AH) = error # if error º | ||
| 883 | ;º º | ||
| 884 | ;º other register contain information as specified by EMSº | ||
| 885 | ;º otherwise all registers remain unchanged º | ||
| 886 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 887 | EMS_INT67 PROC | ||
| 888 | push bp ;save instance pointer ;an000; dms; | ||
| 889 | call Set_Instance ;set BP to proper instance entry ;an000; dms; | ||
| 890 | jc INT67_Instance_Exit ;not enough instances ;an000; dms; | ||
| 891 | |||
| 892 | mov cs:[bp].IE_Saved_DI_Reg,di ;save reg in instance table ;an000; dms; | ||
| 893 | |||
| 894 | |||
| 895 | SUB AH,40H ;adjust to range of fcn table | ||
| 896 | CMP AH,0 ;too low? | ||
| 897 | ; $IF GE,AND | ||
| 898 | JNGE $$IF1 | ||
| 899 | CMP AH,MAX_FCN ;too high? | ||
| 900 | ; $IF LE | ||
| 901 | JNLE $$IF1 | ||
| 902 | MOV DI,OFFSET INT67_EXIT ;get common exit addr | ||
| 903 | PUSH DI ;put it on stack | ||
| 904 | PUSH AX ;save ax...al may contain parms | ||
| 905 | XCHG AH,AL ;adjust | ||
| 906 | XOR AH,AH ; for ax | ||
| 907 | ADD AX,AX ; to be offset into table | ||
| 908 | MOV DI,AX ;use di for index into table | ||
| 909 | POP AX ;recover ax ... parms in al | ||
| 910 | ;At entry to function handler: | ||
| 911 | ; CS = INT67 code segment | ||
| 912 | ; TOP OF STACK is return address, INT67_EXIT | ||
| 913 | |||
| 914 | JMP CS:FCN_TABLE[DI] ;call routine handler | ||
| 915 | ; $ENDIF | ||
| 916 | $$IF1: | ||
| 917 | MOV AH,EMS_CODE84 ;function call out of range | ||
| 918 | |||
| 919 | |||
| 920 | |||
| 921 | INT67_EXIT: | ||
| 922 | |||
| 923 | mov di,cs:[bp].IE_Saved_DI_Reg ;save reg in instance table ;an000; dms; | ||
| 924 | call Reset_Instance ;deallocte instance entry ;an000; dms; | ||
| 925 | |||
| 926 | INT67_Instance_Exit: | ||
| 927 | |||
| 928 | pop bp ;restore instance pointer ;an000; dms; | ||
| 929 | |||
| 930 | IRET ;end of interrupt 67 | ||
| 931 | EMS_INT67 ENDP | ||
| 932 | |||
| 933 | |||
| 934 | |||
| 935 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 936 | ;º Entry point for EMM STATUS Function 1 º | ||
| 937 | ;º º | ||
| 938 | ;º on entry: (AH) = '40'x º | ||
| 939 | ;º º | ||
| 940 | ;º on exit: (AH) = status º | ||
| 941 | ;º all other registers preserved º | ||
| 942 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 943 | EMM_STATUS PROC | ||
| 944 | CMP MANAGER_STATUS,SW_ERROR ;is manager ok? | ||
| 945 | ; $IF E ;if no then | ||
| 946 | JNE $$IF3 | ||
| 947 | MOV AH,EMS_CODE80 ;indicate bad status | ||
| 948 | JMP ST1 ;exit | ||
| 949 | ; $ENDIF | ||
| 950 | $$IF3: | ||
| 951 | CMP CARD_STATUS,HW_ERROR ;is card ok? | ||
| 952 | ; $IF E ;if no then | ||
| 953 | JNE $$IF5 | ||
| 954 | MOV AH,EMS_CODE81 ;indicate bad status | ||
| 955 | JMP ST1 ;exit | ||
| 956 | ; $ENDIF | ||
| 957 | $$IF5: | ||
| 958 | XOR AH,AH ;set good return status | ||
| 959 | ST1: | ||
| 960 | RET ;return to caller | ||
| 961 | EMM_STATUS ENDP | ||
| 962 | |||
| 963 | |||
| 964 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 965 | ;º Entry point for GET PAGE FRAME Function 2 º | ||
| 966 | ;º º | ||
| 967 | ;º on entry: (AH) = '41'x º | ||
| 968 | ;º º | ||
| 969 | ;º on exit: (AH) = status º | ||
| 970 | ;º (BX) = segment address of page frame º | ||
| 971 | ;º all other registers preserved º | ||
| 972 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 973 | Q_PAGE_FRAME PROC | ||
| 974 | push cx ;save regs ;an000; dms; | ||
| 975 | push dx ; ;an000; dms; | ||
| 976 | push si ; ;an000; dms; | ||
| 977 | |||
| 978 | cmp cs:Map_Count,4 ;enough frames? ;an000; dms; | ||
| 979 | jb Q_Page_Frame_Error_Exit ;no - exit with error ;an000; dms; | ||
| 980 | |||
| 981 | mov cx,4h ;loop only 4 times ;an000; dms; | ||
| 982 | xor ax,ax ;page number reference ;an000; dms; | ||
| 983 | mov si,offset cs:Map_Table ;point to map table ;an000; dms; | ||
| 984 | mov bx,cs:[si].Phys_Page_Segment ;set start segment value ;an000; dms; | ||
| 985 | mov dx,bx ;segment reference ;an000; dms; | ||
| 986 | |||
| 987 | Q_Page_Frame_Loop: | ||
| 988 | |||
| 989 | cmp cs:[si].Phys_Page_Number,ax ;page matches reference? ;an000; dms; | ||
| 990 | jne Q_Page_Frame_Error_Exit ;no - exit with error ;an000; dms; | ||
| 991 | |||
| 992 | cmp cs:[si].Phys_Page_Segment,dx ;page frame match reference ;an000; dms; | ||
| 993 | jne Q_Page_Frame_Error_Exit ;no - exit with error ;an000; dms; | ||
| 994 | |||
| 995 | add si,Type Mappable_Phys_Page_Struct;adjust pointer ;an000; dms; | ||
| 996 | add dx,400h ;next page frame ;an000; dms; | ||
| 997 | inc ax ;next page ;an000; dms; | ||
| 998 | loop Q_Page_Frame_Loop ;continue loop ;an000; dms; | ||
| 999 | |||
| 1000 | xor ah,ah ;set good return ;an000; dms; | ||
| 1001 | jmp Q_Page_Exit ;exit the routine ;an000; dms; | ||
| 1002 | |||
| 1003 | Q_Page_Frame_Error_Exit: | ||
| 1004 | |||
| 1005 | mov ah,EMS_Code80 ;signal software error ;an000; dms; | ||
| 1006 | |||
| 1007 | Q_Page_Exit: | ||
| 1008 | |||
| 1009 | pop si ;restore regs ;an000; dms; | ||
| 1010 | pop dx ; ;an000; dms; | ||
| 1011 | pop cx ; ;an000; dms; | ||
| 1012 | |||
| 1013 | RET | ||
| 1014 | Q_PAGE_FRAME ENDP | ||
| 1015 | |||
| 1016 | |||
| 1017 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 1018 | ;º Entry point for QUERY TOTAL & UNALLOCATED PAGES Function 3 º | ||
| 1019 | ;º º | ||
| 1020 | ;º on entry: (AH) = '42'x º | ||
| 1021 | ;º º | ||
| 1022 | ;º on exit: (AH) = status º | ||
| 1023 | ;º (BX) = number of pages available in expanded memory º | ||
| 1024 | ;º (DX) = total number of pages in expanded memory º | ||
| 1025 | ;º all other registers preserved º | ||
| 1026 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 1027 | Q_PAGES PROC | ||
| 1028 | |||
| 1029 | XOR AH,AH ;Init good return status | ||
| 1030 | MOV BX,CS:FREE_PAGES ;bx gets num unalloc pages | ||
| 1031 | MOV DX,CS:TOTAL_EMS_PAGES ;dx gets num total pages | ||
| 1032 | CMP BX,DX ;If unalloc <= total then OK | ||
| 1033 | JNA Q_PAGES_RET ;Otherwise sumptin's rong | ||
| 1034 | MOV AH,EMS_CODE81 ; set that return code | ||
| 1035 | Q_PAGES_RET: | ||
| 1036 | RET | ||
| 1037 | Q_PAGES ENDP | ||
| 1038 | |||
| 1039 | |||
| 1040 | |||
| 1041 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 1042 | ;º Entry point for GET HANDLE AND ALLOCATE Function 4 º | ||
| 1043 | ;º º | ||
| 1044 | ;º on entry: (AH) = '43'x º | ||
| 1045 | ;º (BX) = number of pages to allocate º | ||
| 1046 | ;º º | ||
| 1047 | ;º on exit: (AH) = status º | ||
| 1048 | ;º (DX) = handle º | ||
| 1049 | ;º AX,DX Revised...all other registers preserved º | ||
| 1050 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 1051 | GET_HANDLE PROC | ||
| 1052 | PUSH BX | ||
| 1053 | PUSH CX | ||
| 1054 | PUSH DI | ||
| 1055 | PUSH SI | ||
| 1056 | PUSH DS ;save these registers | ||
| 1057 | |||
| 1058 | PUSH CS ;get cs | ||
| 1059 | POP DS ;into ds | ||
| 1060 | |||
| 1061 | ;Remove test for BX = 0. This is @RH4 | ||
| 1062 | ; valid under LIM 4.0 | ||
| 1063 | |||
| 1064 | cmp bx,0 ;0 page allocate is invalid ;an000; dms; | ||
| 1065 | jne GH_OKCount ;0 pages not requested ;an000; dms; | ||
| 1066 | mov ah,EMS_Code89 ;flag 0 pages requested ;an000; dms; | ||
| 1067 | jmp GH_Exit ;exit routine ;an000; dms; | ||
| 1068 | |||
| 1069 | GH_OKCount: | ||
| 1070 | |||
| 1071 | CMP BX,TOTAL_EMS_PAGES ;Enough total EMS pages? | ||
| 1072 | JNA GH_OKTOTAL | ||
| 1073 | MOV AH,EMS_CODE87 | ||
| 1074 | JMP GH_EXIT | ||
| 1075 | |||
| 1076 | GH_OKTOTAL: | ||
| 1077 | cli ;ints off ;an000; dms; | ||
| 1078 | CMP BX,FREE_PAGES ;Enough unallocated pages? | ||
| 1079 | sti ;ints on ;an000; dms; | ||
| 1080 | JNA GH_OKFREE | ||
| 1081 | MOV AH,EMS_CODE88 | ||
| 1082 | JMP GH_EXIT | ||
| 1083 | ;----------------------------------------------------- | ||
| 1084 | ; Search for a free handle @RH1 º | ||
| 1085 | ;----------------------------------------------------- | ||
| 1086 | GH_OKFREE: | ||
| 1087 | MOV CX,NUM_HANDLES ;loop counter is #handles | ||
| 1088 | DEC CX ;handle 0 reserved for op. sys. @RH1 | ||
| 1089 | MOV DX,1 ;handle assignment set to 1 @RH1 | ||
| 1090 | MOV DI,TYPE H_LOOKUP_STRUC ;init table index to 1st entry @RH1 | ||
| 1091 | ;-------------------------------- | ||
| 1092 | CLI ;interrupts OFF during allocation | ||
| 1093 | ;-------------------------------- | ||
| 1094 | GH_FREEHSRCH: | ||
| 1095 | CMP HANDLE_LOOKUP_TABLE.H_PAGES[DI],REUSABLE_HANDLE | ||
| 1096 | ;Is this handle available? @RH1 | ||
| 1097 | JE GH_HFREE ;yes end search dx=handle id @RH1 | ||
| 1098 | INC DX ;next handle assignment | ||
| 1099 | ADD DI,TYPE H_LOOKUP_STRUC ;next entry in handle lookup @RH1 | ||
| 1100 | ;repeat for all table entries | ||
| 1101 | LOOP GH_FREEHSRCH | ||
| 1102 | MOV AH,EMS_CODE85 ;no available handles | ||
| 1103 | JMP GH_EXIT ;go to exit ;GGA | ||
| 1104 | |||
| 1105 | ;----------------------------------------------------- | ||
| 1106 | ; If here then there's enough pages for request. @RH1 º | ||
| 1107 | ; DX = handle #, DI = ptr to hndl lookup entry @RH1 º | ||
| 1108 | GH_HFREE: | ||
| 1109 | |||
| 1110 | MOV CX,NUM_HANDLES ;loop counter | ||
| 1111 | DEC CX ;handle 0 reserved for op. sys. @RH1 | ||
| 1112 | ;si = index to hndl lookup tbl @RH1 | ||
| 1113 | MOV SI,TYPE H_LOOKUP_STRUC ; for adding pages (skip 0 entry) @RH1 | ||
| 1114 | XOR AX,AX ;clear page counter | ||
| 1115 | CLC ;clear carry for addition | ||
| 1116 | GH_PAGESUM: | ||
| 1117 | CMP HANDLE_LOOKUP_TABLE.H_PAGES[SI],REUSABLE_HANDLE | ||
| 1118 | JE GH_PGSUM_BOT ;If handle is free don't add @RH4 | ||
| 1119 | ADD AX,HANDLE_LOOKUP_TABLE.H_PAGES[SI] | ||
| 1120 | ;add lengths (pages) of PALs @RH1 | ||
| 1121 | ADD SI,TYPE H_LOOKUP_STRUC ; next entry in handle lookup @RH1 | ||
| 1122 | GH_PGSUM_BOT: | ||
| 1123 | LOOP GH_PAGESUM | ||
| 1124 | CMP AX,TOTAL_EMS_PAGES ;pages in handle lookup > total? @RH1 | ||
| 1125 | JNA GH_CALCHLUP ;no OK @RH1 | ||
| 1126 | MOV AH,EMS_CODE80 ;software error..we screwed up @RH1 | ||
| 1127 | JMP GH_EXIT ;go to exit @RH1 ;GGA | ||
| 1128 | |||
| 1129 | GH_CALCHLUP: ;calculate entry in hndl lkup tbl @RH1 | ||
| 1130 | |||
| 1131 | cli ;ints off ;an001; dms; | ||
| 1132 | mov cx,bx ;alloc count ;an000; dms; | ||
| 1133 | call EMS_Page_Contig_Chk ;do we have contig pgs. ;an001; dms; | ||
| 1134 | jnc GH_Alloc ;yes continue process ;an001; dms; | ||
| 1135 | mov ah,EMS_Code88 ;no signal error ;an001; dms; | ||
| 1136 | sti ;ints on ;an001; dms; | ||
| 1137 | jmp GH_Exit ;exit routine ;an001; dms; | ||
| 1138 | |||
| 1139 | GH_Alloc: | ||
| 1140 | |||
| 1141 | call EMS_Link_Set ;set up links ;an001; dms; | ||
| 1142 | |||
| 1143 | |||
| 1144 | sub Free_Pages,bx ;free = free - requested pages | ||
| 1145 | mov Handle_LookUp_Table.H_Pages[di],bx ;page count ;an000; dms; | ||
| 1146 | mov Handle_LookUp_Table.H_Pal_Ptr[di],si ;initialize to ptr for ;ac001; dms; | ||
| 1147 | ; pages | ||
| 1148 | sti ;ints on ;an001; dms; | ||
| 1149 | xor ah,ah ;clear flag ;an000; dms; | ||
| 1150 | |||
| 1151 | |||
| 1152 | GH_EXIT: ;GGA | ||
| 1153 | |||
| 1154 | POP DS | ||
| 1155 | POP SI | ||
| 1156 | POP DI | ||
| 1157 | POP CX | ||
| 1158 | POP BX | ||
| 1159 | |||
| 1160 | RET | ||
| 1161 | GET_HANDLE ENDP | ||
| 1162 | |||
| 1163 | |||
| 1164 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 1165 | ;º Entry point for MAP LOGICAL TO PHYSICAL PAGE Function 5 º | ||
| 1166 | ;º º | ||
| 1167 | ;º on entry: (AH) = '44'x º | ||
| 1168 | ;º (AL) = physical page j º | ||
| 1169 | ;º (BX) = logical page i º | ||
| 1170 | ;º (DX) = handle º | ||
| 1171 | ;º º | ||
| 1172 | ;º on exit: (AH) = status º | ||
| 1173 | ;º all other registers preserved º | ||
| 1174 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 1175 | |||
| 1176 | MAP_L_TO_P PROC | ||
| 1177 | PUSH BX | ||
| 1178 | PUSH CX | ||
| 1179 | PUSH DX | ||
| 1180 | PUSH DI | ||
| 1181 | PUSH SI | ||
| 1182 | PUSH DS ;save these registers | ||
| 1183 | PUSH CS ;get cs | ||
| 1184 | POP DS ;into ds | ||
| 1185 | |||
| 1186 | CMP BX,PAGE_INHIBITTED ;If the log pg = inhibit, ignore @RH4 | ||
| 1187 | JNE MLP_HANDLE_CHK ; checking handle ID. Restore PF @RH4 | ||
| 1188 | MOV SI,BX ; calls this proc, and a saved pg @RH4 | ||
| 1189 | JMP SHORT MLP_GET_SEG ; that has never been mapped will @RH4 | ||
| 1190 | ; have no handle ID @RH4 | ||
| 1191 | |||
| 1192 | MLP_HANDLE_CHK: | ||
| 1193 | CMP DX,NUM_HANDLES-1 ;handle within range ? | ||
| 1194 | JBE MLP_DXINRANGE | ||
| 1195 | MOV AH,EMS_CODE83 ;handle not found | ||
| 1196 | JMP MLP_EXIT ;exit | ||
| 1197 | MLP_DXINRANGE: | ||
| 1198 | push ax ;save affected regs ;an000; dms; | ||
| 1199 | push dx ; ;an000; dms; | ||
| 1200 | MOV AX,DX ; (DX:AX used in MUL @RH1 | ||
| 1201 | MOV DX,TYPE H_LOOKUP_STRUC ;SI = entry's offset into @RH8 | ||
| 1202 | MUL DX ; the handle lookup table @RH8 | ||
| 1203 | MOV SI,AX ; @RH1 | ||
| 1204 | pop dx ;restore affected regs ;an000; dms; | ||
| 1205 | pop ax ; ;an000; dms; | ||
| 1206 | |||
| 1207 | MOV CX,HANDLE_LOOKUP_TABLE.H_PAGES[SI] ;CX = handle's pages @RH8 | ||
| 1208 | CMP CX,REUSABLE_HANDLE ;Handle have pages? | ||
| 1209 | JNE MLP_DXHASPAGES ;Yes next check | ||
| 1210 | MOV AH,EMS_CODE83 ;No handle not used | ||
| 1211 | JMP MLP_EXIT ; set error and exit | ||
| 1212 | MLP_DXHASPAGES: | ||
| 1213 | CMP BX,TOTAL_EMS_PAGES ;Logical pg requested (0 based) @RH1 | ||
| 1214 | JB MLP_BX_LE_TOT ; less than or = to total pages? @RH1 | ||
| 1215 | MOV AH,EMS_CODE8A ;No... logical page out of range | ||
| 1216 | JMP MLP_EXIT ;exit | ||
| 1217 | MLP_BX_LE_TOT: | ||
| 1218 | CMP BX,CX ;Logical page requested <= number @RH1 | ||
| 1219 | JB MLP_LP_OK ; of pages for this handle? | ||
| 1220 | MOV AH,EMS_CODE8A ;No...error log. page out of range @RH1 | ||
| 1221 | JMP MLP_EXIT ;exit | ||
| 1222 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 1223 | ;³ Convert handle's logical page to ³ | ||
| 1224 | ;³ relative page in the EMS pool (SI) ³ | ||
| 1225 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 1226 | MLP_LP_OK: ;Get this handle's @RH8 | ||
| 1227 | MOV DI,HANDLE_LOOKUP_TABLE.H_PAL_PTR[SI] ; head index to PAL @RH8 | ||
| 1228 | CMP BX,0 ;If 1st pg wanted @RH8 | ||
| 1229 | JE MLP_GOT_PHYS_PG ; then we've got it @RH8 | ||
| 1230 | MOV CX,BX ;Else scan linked PAL@RH8 | ||
| 1231 | ; for log pg - 1. @RH8 | ||
| 1232 | MLP_SCAN_PAL: ; (log p is 0 based) @RH8 | ||
| 1233 | SHL DI,1 ;2 bytes per PAL ent | ||
| 1234 | ; mult is slow here | ||
| 1235 | MOV DI,PAGE_ALLOC_LIST[DI] ; This loop will get @RH8 | ||
| 1236 | LOOP MLP_SCAN_PAL ; the index of the @RH8 | ||
| 1237 | MLP_GOT_PHYS_PG: ; desired page @RH8 | ||
| 1238 | MOV SI,DI ;SI = page on card @RH8 | ||
| 1239 | |||
| 1240 | |||
| 1241 | |||
| 1242 | |||
| 1243 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 1244 | ;³ Get seg addr of the phys page (DI) ³ | ||
| 1245 | MLP_GET_SEG: ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 1246 | XOR DI,DI ;Clear offset into mappable phys. @RH4 | ||
| 1247 | MOV CX,MAP_COUNT ; page table. Loop for # entries. @RH4 | ||
| 1248 | MLP_PP_CHECK: | ||
| 1249 | CMP AL,BYTE PTR MAP_TABLE.PHYS_PAGE_NUMBER[DI] ;AX = table pp? @RH4 | ||
| 1250 | JE MLP_PP_OK ;Yes..get seg @RH4 | ||
| 1251 | ADD DI,TYPE MAPPABLE_PHYS_PAGE_STRUCT ;No..check next @RH4 | ||
| 1252 | LOOP MLP_PP_CHECK ; table entry @RH4 | ||
| 1253 | MOV AH,EMS_CODE8B ;If here physical page not found @RH1 | ||
| 1254 | JMP MLP_EXIT ; in mappable phys pg table..Error @RH1 | ||
| 1255 | MLP_PP_OK: | ||
| 1256 | MOV MAP_TABLE.PPM_LOG_PAGE[DI],BX ;Place the logical pg @RH4 | ||
| 1257 | MOV MAP_TABLE.PPM_HANDLE[DI],DX ; the mappable pp table @RH4 | ||
| 1258 | MOV DI,MAP_TABLE.PHYS_PAGE_SEGMENT[DI] ;DI= page's PC seg addr @RH1 | ||
| 1259 | |||
| 1260 | ;------------------------------------- | ||
| 1261 | ; Map L to P depending on memory card º | ||
| 1262 | ;------------------------------------- | ||
| 1263 | MLP_VIRTUAL: | ||
| 1264 | TEST MEMCARD_MODE,WSP_VIRT ;Using either an XMA 1, XMA/A, or @RH2 | ||
| 1265 | JZ MLP_MC_TEST ; XMA Emulator in virtual mode? @RH2 | ||
| 1266 | CALL W_EMSPG_XVIRT ;Yes..Map one logical page to | ||
| 1267 | JMP MLP_GOODRC ; physical page using 310X regs | ||
| 1268 | ;Else not virtual...use real mode | ||
| 1269 | MLP_MC_TEST: ;If system has multiple cards, @RH5 | ||
| 1270 | CMP NUM_MEM_CARDS,1 ; then adjust absolute EMS page to @RH5 | ||
| 1271 | JNA MLP_REAL ; its corresponding page on the @RH5 | ||
| 1272 | CALL MLP_MCARD_SETUP ; card to be used @RH5 | ||
| 1273 | MLP_REAL: | ||
| 1274 | CMP MEMCARD_MODE,XMAA_REAL ;XMA/A card (on PS/2 mod 50 or 60) @RH3 | ||
| 1275 | JNE MLP_HLST ; in real mode (WSP not loaded)? @RH3 | ||
| 1276 | CALL W_EMSPG_XREAL ;Map one logical page to physical @RH2 | ||
| 1277 | JMP MLP_GOODRC | ||
| 1278 | MLP_HLST: ;If not XMA then MXO | ||
| 1279 | CALL W_EMSPG_HLST ;Map one logical page to physical @RH3 | ||
| 1280 | MLP_GOODRC: | ||
| 1281 | XOR AH,AH ;Good return status..mapping | ||
| 1282 | ; should always be successful | ||
| 1283 | MLP_EXIT: | ||
| 1284 | |||
| 1285 | POP DS ;restore these registers | ||
| 1286 | POP SI | ||
| 1287 | POP DI | ||
| 1288 | POP DX | ||
| 1289 | POP CX | ||
| 1290 | POP BX | ||
| 1291 | |||
| 1292 | RET | ||
| 1293 | MAP_L_TO_P ENDP | ||
| 1294 | |||
| 1295 | |||
| 1296 | |||
| 1297 | |||
| 1298 | |||
| 1299 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 1300 | ;³ Subroutine: WRITE TRANSLATE TABLE FOR EMS PAGE ³ | ||
| 1301 | ;³ XMA VIRTUAL MODE ³ | ||
| 1302 | ;³ ³ | ||
| 1303 | ;³ This routine will write the Translate Table so that the ³ | ||
| 1304 | ;³ specified 16K page of 'real' address will be mapped to a ³ | ||
| 1305 | ;³ specified 16K page of XMA physical memory. ³ | ||
| 1306 | ;³ This routine is called if the XMA card is in 'virtual' ³ | ||
| 1307 | ;³ mode - i.e. bank swapping is active. The 16 bit 31AX ports ³ | ||
| 1308 | ;³ are used for setting up the XMA translate table. ³ | ||
| 1309 | ;³ The XMA 1 card and XMA emulator are always in virtual ³ | ||
| 1310 | ;³ mode. The XMA\A card is in virtual mode if bank switching ³ | ||
| 1311 | ;³ is active (used by the 3270 Workstation Program). ³ | ||
| 1312 | ;³ ³ | ||
| 1313 | ;³ On entry: (DI) is starting segment in PC address space. ³ | ||
| 1314 | ;³ Must be on 4K boundary else is rounded ³ | ||
| 1315 | ;³ down to the nearest 4K. ³ | ||
| 1316 | ;³ (SI) absolute EMS page number (not handle relative) RH4³ | ||
| 1317 | ;³ or FFFFh if page is to be inhibitted RH4³ | ||
| 1318 | ;³ ³ | ||
| 1319 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 1320 | |||
| 1321 | W_EMSPG_XVIRT PROC | ||
| 1322 | MOV DX,IDREG ;Save the current bank ID @RH1 | ||
| 1323 | IN AL,DX ; (bank of the requestor). Write @RH1 | ||
| 1324 | MOV BANKID,AL ; to the trans. table for this bank@RH1 | ||
| 1325 | |||
| 1326 | MOV AX,DI ;Get the PC seg. addr of the page @RH1 | ||
| 1327 | XCHG AL,AH ;Div by 256 (Segments per 4K block)@RH1 | ||
| 1328 | MOV AH,BANKID ;Join with the bank ID to get the @RH1 | ||
| 1329 | MOV DX,TTPOINTER ; ptr to the translate table entry @RH1 | ||
| 1330 | OUT DX,AX ;Set TT ptr @RH1 | ||
| 1331 | |||
| 1332 | MOV AX,SI ;Get absolute EMS page number @RH4 | ||
| 1333 | CMP AX,PAGE_INHIBITTED ;Is TT entry to be inhibitted? @RH4 | ||
| 1334 | JE VM_TTDATA_OK ;Yes..write the FFFF in AX @RH4 | ||
| 1335 | MUL BLOCKS_PER_PAGE ;Else convert page to XMA 4K block @RH1 | ||
| 1336 | TEST MEMCARD_MODE,EMUL_VIRT ;If running on the emulator then @RH7 | ||
| 1337 | JZ VM_TTDATA_OK ; turn high order bit of data on @RH7 | ||
| 1338 | OR AX,EMUL_TTDATA_ON ; allowing >8M support on emulator @RH7 | ||
| 1339 | VM_TTDATA_OK: | ||
| 1340 | MOV CX,BLOCKS_PER_PAGE ;Set up one page - loop on blocks @RH1 | ||
| 1341 | MOV DX,AIDATA ; per page using the auto inc reg @RH1 | ||
| 1342 | VM_WRITE: | ||
| 1343 | OUT DX,AX ;Write TT entry, inc TT ptr @RH1 | ||
| 1344 | CMP AX,PAGE_INHIBITTED ;Inhibit TT entry? | ||
| 1345 | JE VM_NEXT_TT ;Yes..don't inc AX | ||
| 1346 | INC AX ;Inc block ptr..contiguous blocks @RH1 | ||
| 1347 | VM_NEXT_TT: | ||
| 1348 | LOOP VM_WRITE ;Loop for all blocks in a page @RH1 | ||
| 1349 | |||
| 1350 | RET | ||
| 1351 | W_EMSPG_XVIRT ENDP | ||
| 1352 | |||
| 1353 | |||
| 1354 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 1355 | ;³ Subroutine: WRITE TRANSLATE TABLE FOR EMS PAGE ³ | ||
| 1356 | ;³ XMA REAL MODE ³ | ||
| 1357 | ;³ ³ | ||
| 1358 | ;³ This routine performs basically the same functions as ³ | ||
| 1359 | ;³ the above routine. It is called if the XMA/A card is in ³ | ||
| 1360 | ;³ 'real' mode (i.e. bank switching not active, planar memory ³ | ||
| 1361 | ;³ is not disabled). The 8 bit 10X ports are used for setting ³ | ||
| 1362 | ;³ up the XMA translate table. ³ | ||
| 1363 | ;³ ³ | ||
| 1364 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 1365 | W_EMSPG_XREAL PROC | ||
| 1366 | |||
| 1367 | MOV AL,WTT_CARD_SLOT ;Put the XMA/A card into setup @RH2 | ||
| 1368 | OR AL,SLOT_SETUP ; mode @RH2 | ||
| 1369 | OUT 96h,AL ; @RH2 | ||
| 1370 | |||
| 1371 | XOR AL,AL ;Set the translate table ptr by @RH2 | ||
| 1372 | MOV DX,RM_TTPTR_HI | ||
| 1373 | OUT DX,AL ; dividing the PC seg. addr in DI @RH2 | ||
| 1374 | MOV AX,DI | ||
| 1375 | XCHG AL,AH ; by 256 (Segments per 4K block). @RH2 | ||
| 1376 | MOV DX,RM_TTPTR_LO | ||
| 1377 | OUT DX,AL ;High byte always 0..no banking @RH2 | ||
| 1378 | |||
| 1379 | MOV AX,SI ;Get absolute EMS page number @RH4 | ||
| 1380 | CMP AX,PAGE_INHIBITTED ;Is TT entry to be inhibitted? @RH4 | ||
| 1381 | JE RM_TTDATA_OK ;Yes..write the FFFF in AX @RH4 | ||
| 1382 | MUL BLOCKS_PER_PAGE ;Else convert page to XMA 4K block @RH1 | ||
| 1383 | RM_TTDATA_OK: | ||
| 1384 | MOV CX,BLOCKS_PER_PAGE ;Set up one page - loop on blocks @RH2 | ||
| 1385 | ; per page using the auto inc regs @RH2 | ||
| 1386 | RM_WRITE: | ||
| 1387 | XCHG AH,AL ;Write TT data high byte first, @RH2 | ||
| 1388 | MOV DX,RM_TTDATA_HI ; then write low byte. This is @RH2 | ||
| 1389 | OUT DX,AL ; not an auto increment port. @RH2 | ||
| 1390 | XCHG AH,AL ; @RH2 | ||
| 1391 | MOV DX,RM_TTDATA_LO ; @RH2 | ||
| 1392 | OUT DX,AL ; @RH1 | ||
| 1393 | CMP AX,PAGE_INHIBITTED ;Inhibit TT entry? | ||
| 1394 | JE RM_NEXT_TT ;Yes..don't inc AX | ||
| 1395 | INC AX ;Inc block ptr..contiguous blocks @RH1 | ||
| 1396 | RM_NEXT_TT: | ||
| 1397 | LOOP RM_WRITE ;Loop for all blocks in a page @RH1 | ||
| 1398 | |||
| 1399 | MOV AL,0 ;Reset the slot ID @RH5 | ||
| 1400 | OUT 96h,AL ; @RH5 | ||
| 1401 | RET | ||
| 1402 | W_EMSPG_XREAL ENDP | ||
| 1403 | |||
| 1404 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 1405 | ;³ Subroutine: WRITE TRANSLATE TABLE FOR EMS PAGE ³ | ||
| 1406 | ;³ Memory Expansion Option (MXO) ³ | ||
| 1407 | ;³ ³ | ||
| 1408 | ;³ This routine is used to map a logical page to a physical ³ | ||
| 1409 | ;³ page off the MXO card. MXO has 16K blocks, as opposed ³ | ||
| 1410 | ;³ to 4K on the XMA. The 8 bit 10X ports are used for setting ³ | ||
| 1411 | ;³ up MXO's translate table. Note that the data in the ³ | ||
| 1412 | ;³ translate table is only 8 bits, and the high order bit is a ³ | ||
| 1413 | ;³ 0 to inhibit translation (where inhibit = 1 on XMA). ³ | ||
| 1414 | ;³ ³ | ||
| 1415 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 1416 | W_EMSPG_HLST PROC | ||
| 1417 | PUSH CX ; @RH3 | ||
| 1418 | |||
| 1419 | MOV AL,WTT_CARD_SLOT ;Put the MXO card into setup @RH3 | ||
| 1420 | OR AL,SLOT_SETUP ; mode @RH3 | ||
| 1421 | OUT 96h,AL ; @RH3 | ||
| 1422 | |||
| 1423 | MOV AX,DI ;Set the MXO translate table @RH3 | ||
| 1424 | MOV CL,10 ; ptr by dividing the PC segment @RH3 | ||
| 1425 | SHR AX,CL ; addr in DI by 1024 @RH3 | ||
| 1426 | MOV DX,H_TTPTR_LO ; (segments per 16K MXO block). @RH3 | ||
| 1427 | OUT DX,AL ; @RH3 | ||
| 1428 | XCHG AL,AH ; @RH3 | ||
| 1429 | MOV DX,H_TTPTR_HI ; @RH3 | ||
| 1430 | OUT DX,AL ; @RH3 | ||
| 1431 | |||
| 1432 | MOV AX,SI ;Get absolute EMS page number @RH4 | ||
| 1433 | CMP AX,PAGE_INHIBITTED ;Is TT entry to be inhibitted? @RH4 | ||
| 1434 | JE HM_TTDATA_INH ;Yes write MXO inhibit pattern @RH4 | ||
| 1435 | ;Else turn on enable and write pg @RH3 | ||
| 1436 | OR AL,H_TT_ENBMASK ; (no need to convert.. 16K EMS @RH3 | ||
| 1437 | JMP SHORT HM_WRITETT ; page = 16K MXO block) @RH3 | ||
| 1438 | HM_TTDATA_INH: ; | ||
| 1439 | MOV AL,H_TT_INHIBIT ;AL = MXO TT inhibit data @RH3 | ||
| 1440 | HM_WRITETT: | ||
| 1441 | MOV DX,H_TTDATA ; Write to the 1 MXO TT entry. @RH3 | ||
| 1442 | OUT DX,AL ; @RH3 | ||
| 1443 | MOV AL,0 ;Reset the slot ID @RH5 | ||
| 1444 | OUT 96h,AL ; @RH5 | ||
| 1445 | |||
| 1446 | POP CX ; @RH3 | ||
| 1447 | RET | ||
| 1448 | W_EMSPG_HLST ENDP | ||
| 1449 | |||
| 1450 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 1451 | ;³ Subroutine: MULTIPLE MEMORY CARD SETUP ³ | ||
| 1452 | ;³ ³ | ||
| 1453 | ;³ This subroutine selects the correct card in a multicard ³ | ||
| 1454 | ;³ system for mapping a physical page. Given the absolute page ³ | ||
| 1455 | ;³ number within the EMS pool (SI), it finds the card to use for ³ | ||
| 1456 | ;³ this page, and converts SI to the offset of the page within ³ | ||
| 1457 | ;³ this card. Before this new page is mapped, it may be necessary ³ | ||
| 1458 | ;³ to disable the translate table entry of the card that's ³ | ||
| 1459 | ;³ currently mapped. ³ | ||
| 1460 | ;³ ³ | ||
| 1461 | ;³ On entry: (DI) is starting segment in PC address space. ³ | ||
| 1462 | ;³ (SI) absolute EMS page number (not handle relative) ³ | ||
| 1463 | ;³ or FFFFh if page is to be inhibitted ³ | ||
| 1464 | ;³ ³ | ||
| 1465 | ;³ On exit: (DI) is unchanged. ³ | ||
| 1466 | ;³ (SI) offset of the page within the selected card ³ | ||
| 1467 | ;³ or FFFFh if page is to be inhibitted ³ | ||
| 1468 | ;³ WTT_CARD_SLOT = Slot # of the new card to map ³ | ||
| 1469 | ;³ MEMCARD_MODE = Flag indicating if XMA/A or MXO ³ | ||
| 1470 | ;³ ³ | ||
| 1471 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 1472 | |||
| 1473 | PG_NEW_CARD_ID DW ? ;Holders for the ID and the slot # @RH5 | ||
| 1474 | PG_NEW_CARD_SLOT DB ? ; of the card that will be used @RH5 | ||
| 1475 | ; in the new mapping @RH5 | ||
| 1476 | MC_TABLE_OFFSET DW ? ;Holder for offset into the @RH5 | ||
| 1477 | ; multicard page mapping table @RH5 | ||
| 1478 | |||
| 1479 | MLP_MCARD_SETUP PROC | ||
| 1480 | PUSH AX | ||
| 1481 | PUSH CX | ||
| 1482 | ;------------------------------------- | ||
| 1483 | ; Get the ID and slot of the card to º | ||
| 1484 | ; make active. Convert SI to be º | ||
| 1485 | ; the correct page within this card. º | ||
| 1486 | ;------------------------------------- | ||
| 1487 | PUSH DI ;Loop through the mem @RH5 | ||
| 1488 | XOR DI,DI ; card table to find @RH5 | ||
| 1489 | MOV CX,NUM_MEM_CARDS ; card used to map the @RH5 | ||
| 1490 | MC_GET_CARD: ; absolute page (SI) @RH5 | ||
| 1491 | CMP MEM_CARD_TABLE.END_PG_NUM[DI],SI ;If the last pg this @RH5 | ||
| 1492 | JAE MC_FOUND_CARD ; card maps <= SI then @RH5 | ||
| 1493 | ADD DI,TYPE MEM_CARD_STRUC ; use this card @RH5 | ||
| 1494 | LOOP MC_GET_CARD ;Else check next card @RH5 | ||
| 1495 | ; Note: if SI = FFFF @RH5 | ||
| 1496 | ; the last card is @RH5 | ||
| 1497 | ; selected. This is @RH5 | ||
| 1498 | ; OK, since it doesn't @RH5 | ||
| 1499 | ; matter which is inh @RH5 | ||
| 1500 | MC_FOUND_CARD: ; @RH5 | ||
| 1501 | MOV AX,MEM_CARD_TABLE.CARD_ID[DI] ;Save the card ID and @RH5 | ||
| 1502 | MOV PG_NEW_CARD_ID,AX ; the slot # of the @RH5 | ||
| 1503 | MOV AL,MEM_CARD_TABLE.CARD_SLOT[DI] ; card used to map @RH5 | ||
| 1504 | MOV PG_NEW_CARD_SLOT,AL ; the new page. @RH5 | ||
| 1505 | MOV AX,MEM_CARD_TABLE.START_PG_NUM[DI] ;If SI is not inhibit, @RH5 | ||
| 1506 | CMP SI,PAGE_INHIBITTED ; convert SI from the @RH5 | ||
| 1507 | JE MC_DEACTIVATE ; absolute pg number @RH5 | ||
| 1508 | SUB SI,AX ; to the offset of the @RH5 | ||
| 1509 | ; page within this card @RH5 | ||
| 1510 | |||
| 1511 | ;------------------------------------- | ||
| 1512 | MC_DEACTIVATE: ; Deactivate (inhibit) the translate º | ||
| 1513 | POP DI ; table entry of the current card. º | ||
| 1514 | ;------------------------------------- | ||
| 1515 | ; Search for the seg addr in the @RH5 | ||
| 1516 | ; map phys pg table to get the @RH5 | ||
| 1517 | ; corresponding entry in the @RH5 | ||
| 1518 | PUSH SI ; multicard page mapping table @RH5 | ||
| 1519 | XOR SI,SI ;SI = offset into map phy pg table @RH5 | ||
| 1520 | XOR AX,AX ;AX = offset into multic pm table @RH5 | ||
| 1521 | MOV CX,MAP_COUNT ;Loop on # phys pgs (incl FE & FF) @RH5 | ||
| 1522 | MC_SRCH_MPP: ; @RH5 | ||
| 1523 | CMP MAP_TABLE.PHYS_PAGE_SEGMENT[SI],DI ;If no segment match @RH5 | ||
| 1524 | JE MC_CHECK_CUR_PG ; then next entry in @RH5 | ||
| 1525 | ADD SI,TYPE MAPPABLE_PHYS_PAGE_STRUCT ; map phys pg tbl & @RH5 | ||
| 1526 | ADD AX,TYPE MULTIC_PM_STRUC ; multicard pm table @RH5 | ||
| 1527 | LOOP MC_SRCH_MPP ; @RH5 | ||
| 1528 | |||
| 1529 | ;Examine the current card ID and @RH5 | ||
| 1530 | ; slot used for this page @RH5 | ||
| 1531 | MC_CHECK_CUR_PG: | ||
| 1532 | MOV MC_TABLE_OFFSET,AX ;Save mc tbl offset @RH5 | ||
| 1533 | MOV SI,AX ; and put it in SI @RH5 | ||
| 1534 | CMP MC_PM_TABLE.PG_CARD[SI],NO_CARD ;If the page is @RH5 | ||
| 1535 | JE MC_MAP_NEW ; inhibitted or if @RH5 | ||
| 1536 | MOV AL,MC_PM_TABLE.PG_SLOT[SI] ; the new page is @RH5 | ||
| 1537 | CMP AL,PG_NEW_CARD_SLOT ; on the same card @RH5 | ||
| 1538 | JE MC_MAP_NEW ; as the old page @RH5 | ||
| 1539 | ; then dont inhibit @RH5 | ||
| 1540 | |||
| 1541 | ;Inhibit TT entry for current card @RH5 | ||
| 1542 | MOV WTT_CARD_SLOT,AL ;Save slot # and ID @RH5 | ||
| 1543 | MOV AX,MC_PM_TABLE.PG_CARD[SI] ; of current card @RH5 | ||
| 1544 | MOV SI,PAGE_INHIBITTED ;Page = inhibitted @RH5 | ||
| 1545 | CMP AX,XMAA_CARD_ID ;If card = XMA/A @RH5 | ||
| 1546 | JNE MC_INH_HLST ; then inh XMA/A TT @RH5 | ||
| 1547 | CALL W_EMSPG_XREAL ; entry for pg via @RH5 | ||
| 1548 | JMP SHORT MC_MAP_NEW ; real mode regs @RH5 | ||
| 1549 | MC_INH_HLST: ;Else inhibit TT @RH5 | ||
| 1550 | CALL W_EMSPG_HLST ; entry for MXO @RH5 | ||
| 1551 | |||
| 1552 | ;------------------------------------- | ||
| 1553 | ; Activate (enable) the translate º | ||
| 1554 | ; table entry of the new card. º | ||
| 1555 | MC_MAP_NEW: ;------------------------------------- | ||
| 1556 | ;Set the multicard page frame @RH5 | ||
| 1557 | ; table for the new card @RH5 | ||
| 1558 | POP SI ;Restore EMS page @RH5 | ||
| 1559 | PUSH DI ; and save pc seg addr. @RH5 | ||
| 1560 | MOV DI,MC_TABLE_OFFSET ; @RH5 | ||
| 1561 | MOV AL,PG_NEW_CARD_SLOT ;Store slot # of new card in @RH5 | ||
| 1562 | MOV MC_PM_TABLE.PG_SLOT[DI],AL ; multc pm tbl and in variable @RH5 | ||
| 1563 | MOV WTT_CARD_SLOT,AL ; used by map log to phys proc @RH5 | ||
| 1564 | CMP SI,PAGE_INHIBITTED ;If new pg is not inhibitted @RH5 | ||
| 1565 | JE MC_NEWID_INH ; then set card ID field in @RH5 | ||
| 1566 | MOV AX,PG_NEW_CARD_ID ; the multicard page mapping @RH5 | ||
| 1567 | MOV MC_PM_TABLE.PG_CARD[DI],AX ; table to new card ID @RH5 | ||
| 1568 | JMP SHORT MC_SET_FLGS ; @RH5 | ||
| 1569 | MC_NEWID_INH: ; @RH5 | ||
| 1570 | MOV AX,NO_CARD ;Else set card ID as no card @RH5 | ||
| 1571 | MOV MC_PM_TABLE.PG_CARD[DI],AX ; @RH5 | ||
| 1572 | ;............................ | ||
| 1573 | ;Set flags so main MLP proc @RH5 | ||
| 1574 | ; can map the new page @RH5 | ||
| 1575 | MC_SET_FLGS: ;............................. @RH5 | ||
| 1576 | POP DI ;Restore PC seg addr | ||
| 1577 | CMP PG_NEW_CARD_ID,XMAA_CARD_ID ;Set the flag that tells @RH5 | ||
| 1578 | JNE MC_MAP_HLST ; the main Map Log to P proc @RH5 | ||
| 1579 | MOV MEMCARD_MODE,XMAA_REAL ; which subroutine to call @RH5 | ||
| 1580 | JMP SHORT MC_END_PROC ;At this point, @RH5 | ||
| 1581 | MC_MAP_HLST: ; DI = PC segment addr of page @RH5 | ||
| 1582 | MOV MEMCARD_MODE,HOLS_REAL ; SI = page's offset into card @RH5 | ||
| 1583 | MC_END_PROC: ; WTT_CARD_SLOT = card slot # @RH5 | ||
| 1584 | POP CX ; MEMCARD_MODE = flag showing @RH5 | ||
| 1585 | POP AX ; if card is XMAA or MXO @RH5 | ||
| 1586 | RET ; @RH5 | ||
| 1587 | MLP_MCARD_SETUP ENDP | ||
| 1588 | |||
| 1589 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 1590 | ;º Entry point for DEALLOCATE PAGES Function 6 º | ||
| 1591 | ;º º | ||
| 1592 | ;º on entry: (AH) = '45'x º | ||
| 1593 | ;º (DX) = handle º | ||
| 1594 | ;º º | ||
| 1595 | ;º on exit: (AH) = status º | ||
| 1596 | ;º AX Revised...all other registers preserved º | ||
| 1597 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 1598 | DE_ALLOCATE PROC | ||
| 1599 | PUSH BX ;save these registers | ||
| 1600 | PUSH CX | ||
| 1601 | PUSH DX | ||
| 1602 | PUSH DI | ||
| 1603 | PUSH SI | ||
| 1604 | PUSH DS | ||
| 1605 | PUSH ES ; @RH1 | ||
| 1606 | |||
| 1607 | PUSH CS ;get this code segment | ||
| 1608 | POP DS ;into ds | ||
| 1609 | PUSH CS ;Set up ES for shifting (MOVSB) @RH1 | ||
| 1610 | POP ES ; the PAL table @RH1 | ||
| 1611 | |||
| 1612 | cmp dx,0 ;handle zero? ;an000; dms; | ||
| 1613 | jne D_Check_Handle ;no continue ;an000; dms; | ||
| 1614 | mov bx,0 ;reallocate to a page count of 0 ;an000; dms; | ||
| 1615 | call Reallocate ; ;an000; dms; | ||
| 1616 | jmp DA_Exit ;exit routine ;an000; dms; | ||
| 1617 | |||
| 1618 | D_Check_Handle: | ||
| 1619 | |||
| 1620 | CMP DX,NUM_HANDLES-1 ;handle within range ? | ||
| 1621 | JBE D_OKRANGE ;if not then... | ||
| 1622 | MOV AH,EMS_CODE83 ;handle not found | ||
| 1623 | JMP DA_EXIT ;exit | ||
| 1624 | D_OKRANGE: ;check if active (valid) handle | ||
| 1625 | PUSH DX ;Save handle id @RH1 | ||
| 1626 | MOV AX,DX ;set up indexing into h lookup @RH1 | ||
| 1627 | MOV DX,TYPE H_LOOKUP_STRUC ; @RH8 | ||
| 1628 | MUL DX ;get handle lookup entry offset @RH8 | ||
| 1629 | POP DX ;Restore handle id @RH1 | ||
| 1630 | MOV DI,AX ;Put offset into index reg @RH1 | ||
| 1631 | |||
| 1632 | CMP HANDLE_LOOKUP_TABLE.H_Pages[DI],REUSABLE_HANDLE | ||
| 1633 | ;Handle has pages? @RH1 | ||
| 1634 | JNE D_OKHNDL ;Yes OK handle | ||
| 1635 | MOV AH,EMS_CODE83 ;No handle not in use. error. | ||
| 1636 | JMP DA_EXIT ;exit | ||
| 1637 | ;----------------------------------------------------- | ||
| 1638 | D_OKHNDL: ; Before deallocation can continue, insure the @RH1 º | ||
| 1639 | ; page frame map is not saved under this handle @RH1 º | ||
| 1640 | ;----------------------------------------------------- | ||
| 1641 | PUSH DX ;Save handle id @RH1 | ||
| 1642 | MOV AX,DX ;Get the correct offset @RH1 | ||
| 1643 | MOV DX,TYPE H_SAVE_STRUC ; into the handle save @RH8 | ||
| 1644 | MUL DX ; area for this handle @RH8 | ||
| 1645 | POP DX ;Restore handle id @RH1 | ||
| 1646 | MOV SI,AX ; @RH1 | ||
| 1647 | D_HSAVECHK: | ||
| 1648 | CMP HANDLE_SAVE_AREA.PG0_LP[SI],REUSABLE_SAVEA | ||
| 1649 | JE D_PAT_UPDATE ;If the 1st entry for this handle @RH1 | ||
| 1650 | MOV AH,EMS_CODE86 ; in the save area is not free | ||
| 1651 | JMP DA_EXIT ; then in use...exit with error | ||
| 1652 | ;----------------------------------------------------- | ||
| 1653 | ; Update Page Allocation List - unallocate | ||
| 1654 | D_PAT_UPDATE: | ||
| 1655 | |||
| 1656 | PUSH DX ;Save handle id @RH1 | ||
| 1657 | |||
| 1658 | |||
| 1659 | |||
| 1660 | MOV CX,HANDLE_LOOKUP_TABLE.H_PAGES[DI] ;Get the # of pages @RH1 | ||
| 1661 | MOV AX,HANDLE_LOOKUP_TABLE.H_PAL_PTR[DI] ;Load si with ptr @RH1 | ||
| 1662 | MOV SI,AX ;pass ptr ;an000; dms; | ||
| 1663 | |||
| 1664 | push cx ;save loop count ;an000; dms; | ||
| 1665 | |||
| 1666 | cmp cx,0 ;handle has 0 pages? ;an001; dms; | ||
| 1667 | je D_Depat_Exit1 ;yes - don't changes ptr;an001; dms; | ||
| 1668 | |||
| 1669 | mov ax,cs:PAL_Free_Ptr ;no - dealloc pages ;an001; dms; | ||
| 1670 | mov cs:PAL_Free_Ptr,si ;set free ptr to root of;an001; dms; | ||
| 1671 | ; handle list | ||
| 1672 | dec cx ;don't loop past last pg;an001; dms; | ||
| 1673 | |||
| 1674 | D_DEPAT: | ||
| 1675 | |||
| 1676 | ;this loop scans to | ||
| 1677 | ;the end of the allocated | ||
| 1678 | ;chain | ||
| 1679 | |||
| 1680 | cmp cx,0 ;end of deallocate? ;an000; dms; | ||
| 1681 | je D_Depat_Exit ;yes - exit ;an000; dms; | ||
| 1682 | shl si,1 ;no - adjust to index ;an001; dms; | ||
| 1683 | mov si,Page_Alloc_List[si] ;get new ptr val ;an001; dms; | ||
| 1684 | dec cx ;dec loop ctr ;an001; dms; | ||
| 1685 | jmp D_DEPAT ;continue ;an000; dms; | ||
| 1686 | |||
| 1687 | D_DEPAT_EXIT: | ||
| 1688 | |||
| 1689 | shl si,1 ;adjust to index value ;an001; dms; | ||
| 1690 | mov Page_Alloc_List[si],ax ;pt. last page to orig. ;an001; dms; | ||
| 1691 | ; free ptr. | ||
| 1692 | |||
| 1693 | D_Depat_Exit1: | ||
| 1694 | |||
| 1695 | pop cx ;restore loop count ;an000; dms; | ||
| 1696 | pop dx ;restore handle ;an000; dms; | ||
| 1697 | |||
| 1698 | push ds ;save regs ;an000; dms; | ||
| 1699 | push si ; ;an000; dms; | ||
| 1700 | |||
| 1701 | mov ax,cs ;swap segs ;an000; dms; | ||
| 1702 | mov ds,ax ; ;an000; dms; | ||
| 1703 | mov si,offset cs:Null_Handle_Name ;point to null handle ;an000; dms; | ||
| 1704 | mov ax,5301h ;set handle name func ;an000; dms; | ||
| 1705 | call Handle_Name ;set the handle name to ;an000; dms; | ||
| 1706 | ; nulls | ||
| 1707 | pop si ;restore regs ;an000; dms; | ||
| 1708 | pop ds ; ;an000; dms; | ||
| 1709 | |||
| 1710 | cli ;ints off ;an000; dms; | ||
| 1711 | add cs:Free_Pages,cx ;free up page ;an000; dms; | ||
| 1712 | mov Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;deallocate ;an000; dms; | ||
| 1713 | ; handle | ||
| 1714 | sti ;ints on ;an000; dms; | ||
| 1715 | |||
| 1716 | xor ah,ah ;clear flag ;an000; dms; | ||
| 1717 | |||
| 1718 | DA_EXIT: | ||
| 1719 | |||
| 1720 | POP ES ; @RH1 | ||
| 1721 | POP DS | ||
| 1722 | POP SI | ||
| 1723 | POP DI | ||
| 1724 | POP DX | ||
| 1725 | POP CX | ||
| 1726 | POP BX | ||
| 1727 | |||
| 1728 | RET | ||
| 1729 | DE_ALLOCATE ENDP | ||
| 1730 | |||
| 1731 | |||
| 1732 | ;==================================================================== | ||
| 1733 | ; Deallocate_Chain - This routine deallocates a page from a | ||
| 1734 | ; handle and links it to the free list | ||
| 1735 | ; | ||
| 1736 | ; Inputs : SI - PTR to entry to deallocate | ||
| 1737 | ; | ||
| 1738 | ; Outputs : SI - PTR to next entry to deallocate | ||
| 1739 | ; | ||
| 1740 | ;==================================================================== | ||
| 1741 | |||
| 1742 | Deallocate_Chain proc ;deallocate page ;an000; dms; | ||
| 1743 | |||
| 1744 | push ax ;save regs ;an000; dms; | ||
| 1745 | push bx ; ;an000; dms; | ||
| 1746 | push cx ; ;an000; dms; | ||
| 1747 | |||
| 1748 | cli ;ints off ;an000; dms; | ||
| 1749 | |||
| 1750 | mov bx,si ;alloc_ptr ;an000; dms; | ||
| 1751 | |||
| 1752 | mov ax,si ;get page_ptr ;an000; dms; | ||
| 1753 | mov dx,Type Page_Alloc_List ;get entry size ;an000; dms; | ||
| 1754 | mul dx ;get pointer val ;an000; dms; | ||
| 1755 | mov si,ax ;page_ptr ;an000; dms; | ||
| 1756 | |||
| 1757 | mov ax,Page_List_Entry ;page_ptr value ;an000; dms; | ||
| 1758 | mov cx,cs:PAL_Free_PTR ;free_ptr ;an000; dms; | ||
| 1759 | |||
| 1760 | |||
| 1761 | mov cs:PAL_Free_PTR,bx ;new free_ptr ;an000; dms; | ||
| 1762 | mov Page_List_Entry,cx ;new free_ptr value ;an000; dms; | ||
| 1763 | mov si,ax ;next page to deallocate;an000; dms; | ||
| 1764 | sti ;ints on ;an000; dms; | ||
| 1765 | |||
| 1766 | pop cx ;restore regs ;an000; dms; | ||
| 1767 | pop bx ; ;an000; dms; | ||
| 1768 | pop ax ; ;an000; dms; | ||
| 1769 | |||
| 1770 | ret ; ;an000; dms; | ||
| 1771 | |||
| 1772 | Deallocate_Chain endp ; ;an000; dms; | ||
| 1773 | |||
| 1774 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 1775 | ;º Entry point for QUERY MEMORY MANAGER VERSION Function 7 º | ||
| 1776 | ;º º | ||
| 1777 | ;º on entry: (AH) = '46'x º | ||
| 1778 | ;º º | ||
| 1779 | ;º on exit: (AH) = status º | ||
| 1780 | ;º all other registers preserved º | ||
| 1781 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 1782 | Q_VERSION PROC | ||
| 1783 | MOV AL,EMM_VERSION ;al get version number | ||
| 1784 | XOR AH,AH ;good return code | ||
| 1785 | RET | ||
| 1786 | Q_VERSION ENDP | ||
| 1787 | |||
| 1788 | |||
| 1789 | |||
| 1790 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 1791 | ;º Entry point for SAVE MAPPING CONTEXT Function 8 º | ||
| 1792 | ;º º | ||
| 1793 | ;º on entry: (AH) = '47'x º | ||
| 1794 | ;º (DX) = handle assigned to the interrupt service º | ||
| 1795 | ;º routine (i.e. save map under this handle). º | ||
| 1796 | ;º º | ||
| 1797 | ;º on exit: (AH) = status º | ||
| 1798 | ;º all other registers preserved º | ||
| 1799 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 1800 | SAVE_MAP PROC | ||
| 1801 | PUSH DX | ||
| 1802 | PUSH DI | ||
| 1803 | PUSH SI | ||
| 1804 | PUSH DS | ||
| 1805 | PUSH ES ;save these registers | ||
| 1806 | |||
| 1807 | PUSH CS ;get cs | ||
| 1808 | POP DS ;into ds | ||
| 1809 | PUSH CS ;Get CS into ES (save area is in | ||
| 1810 | POP ES ; this segment) | ||
| 1811 | |||
| 1812 | CMP DX,NUM_HANDLES-1 ;handle within range ? | ||
| 1813 | JBE SM_DXINRANGE ;if not then... | ||
| 1814 | MOV AH,EMS_CODE83 ;handle not found | ||
| 1815 | JMP SM_EXIT ;exit | ||
| 1816 | SM_DXINRANGE: | ||
| 1817 | PUSH DX ;Handle destroyed by MUL @RH1 | ||
| 1818 | MOV AX,DX ;SI = requested handle's @RH1 | ||
| 1819 | MOV DX,TYPE H_LOOKUP_STRUC ; offset into the handle @RH8 | ||
| 1820 | MUL DX ; lookup table @RH8 | ||
| 1821 | MOV SI,AX ; @RH1 | ||
| 1822 | POP DX ;Restore handle ID @RH1 | ||
| 1823 | |||
| 1824 | CMP HANDLE_LOOKUP_TABLE.H_Pages[SI],REUSABLE_HANDLE | ||
| 1825 | JNE SM_HACTIVE ;If handle is in use (active), ok @RH1 | ||
| 1826 | MOV AH,EMS_CODE83 ;else handle not in use; error | ||
| 1827 | JMP SM_EXIT ;exit | ||
| 1828 | SM_HACTIVE: | ||
| 1829 | MOV AX,DX ;DI = requested handle's @RH1 | ||
| 1830 | MOV DX,TYPE H_SAVE_STRUC ; offset into the handle @RH1 | ||
| 1831 | MUL DX ; save area @RH1 | ||
| 1832 | MOV DI,AX ;Add the table base to @RH1 | ||
| 1833 | ADD DI,OFFSET HANDLE_SAVE_AREA ; make ES:DI a pointer @RH1 | ||
| 1834 | |||
| 1835 | ;------------------------------------- | ||
| 1836 | ; Insure save area free for this hndl º | ||
| 1837 | SM_AREACHECK: ;------------------------------------- | ||
| 1838 | CMP [DI].PG0_LP,REUSABLE_SAVEA | ||
| 1839 | JE SM_SAVE_OK ;If 1st entry free then OK to save @RH1 | ||
| 1840 | MOV AH,EMS_CODE8D ;Else page map already saved for | ||
| 1841 | JMP SM_EXIT ; this handle. Exit with error | ||
| 1842 | SM_SAVE_OK: | ||
| 1843 | CALL SAVE_PGFRM_MAP ;Save to area pointed to by ES:DI @RH1 | ||
| 1844 | XOR AH,AH ;Set good return code | ||
| 1845 | SM_EXIT: | ||
| 1846 | POP ES ;restore these registers | ||
| 1847 | POP DS | ||
| 1848 | POP SI | ||
| 1849 | POP DI | ||
| 1850 | POP DX | ||
| 1851 | RET ;return to caller | ||
| 1852 | SAVE_MAP ENDP | ||
| 1853 | |||
| 1854 | ;-----------------------------------------------------------------------; | ||
| 1855 | ; Subroutine: SAVE PAGE FRAME MAP ; | ||
| 1856 | ; ; | ||
| 1857 | ; purpose: To save the map of the 4 pages within the ; | ||
| 1858 | ; page frame to a save area pointed to by ES:DI. ; | ||
| 1859 | ; The handle ID and logical page active within each ; | ||
| 1860 | ; of the 4 physical pages is saved. Each is a word ; | ||
| 1861 | ; value. ; | ||
| 1862 | ; called by: Save mapping array (Function 8) using a handle ID ; | ||
| 1863 | ; and our save area. ; | ||
| 1864 | ; Get page map (Function 15 subfunction 0) without ; | ||
| 1865 | ; a handle ID using the application's save area. ; | ||
| 1866 | ; ; | ||
| 1867 | ; on entry: ES:DI points to save area ; | ||
| 1868 | ; ; | ||
| 1869 | ; on exit: All registers preserved ; | ||
| 1870 | ;-----------------------------------------------------------------------; | ||
| 1871 | SAVE_PGFRM_MAP PROC | ||
| 1872 | PUSH AX ;save these registers | ||
| 1873 | PUSH CX | ||
| 1874 | PUSH DI | ||
| 1875 | PUSH SI | ||
| 1876 | PUSH DS | ||
| 1877 | |||
| 1878 | PUSH CS ;get this segment into DS | ||
| 1879 | POP DS | ||
| 1880 | ;------------------------------------- | ||
| 1881 | ; Read the current handle ID and log º | ||
| 1882 | ; pg #s in the mappable phys pg tableº | ||
| 1883 | ;------------------------------------- | ||
| 1884 | CLD ;Set direction for STOSW forward @RH5 | ||
| 1885 | XOR SI,SI ;Clear offset into mappable phys. @RH5 | ||
| 1886 | MOV CX,map_count ; page table. Loop for # entries @RH5 | ||
| 1887 | SM_HLP_STORE: ;Store the word for the @RH5 | ||
| 1888 | MOV AX,MAP_TABLE.PPM_HANDLE[SI] ; currently active handle@RH5 | ||
| 1889 | STOSW ; and logical page into @RH5 | ||
| 1890 | MOV AX,MAP_TABLE.PPM_LOG_PAGE[SI] ; the save area at ES:DI @RH5 | ||
| 1891 | STOSW ; STOSW moves AX to ES:DI@RH5 | ||
| 1892 | ADD SI,TYPE MAPPABLE_PHYS_PAGE_STRUCT ;Next entry in mpp table @RH5 | ||
| 1893 | LOOP SM_HLP_STORE ; @RH5 | ||
| 1894 | |||
| 1895 | POP DS ;Recover these registers | ||
| 1896 | POP SI | ||
| 1897 | POP DI | ||
| 1898 | POP CX | ||
| 1899 | POP AX | ||
| 1900 | RET ;return to caller | ||
| 1901 | SAVE_PGFRM_MAP ENDP | ||
| 1902 | |||
| 1903 | |||
| 1904 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 1905 | ;º Entry point for RESTORE MAPPING CONTEXT Function 9 º | ||
| 1906 | ;º º | ||
| 1907 | ;º on entry: (AH) = '48'x º | ||
| 1908 | ;º (DX) = handle assigned to the interrupt service º | ||
| 1909 | ;º routine (i.e. handle map was saved under). º | ||
| 1910 | ;º º | ||
| 1911 | ;º on exit: (AH) = status º | ||
| 1912 | ;º all other registers preserved º | ||
| 1913 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 1914 | RESTORE_MAP PROC | ||
| 1915 | PUSH BX | ||
| 1916 | PUSH CX | ||
| 1917 | PUSH DX | ||
| 1918 | PUSH DI | ||
| 1919 | PUSH SI | ||
| 1920 | PUSH DS ;save these registers | ||
| 1921 | |||
| 1922 | PUSH CS ;Get CS into DS (save area is in | ||
| 1923 | POP DS ; this segment) | ||
| 1924 | |||
| 1925 | CMP DX,NUM_HANDLES-1 ;handle within range ? | ||
| 1926 | JBE RM_DXINRANGE ;if not then... | ||
| 1927 | MOV AH,EMS_CODE83 ;handle not found | ||
| 1928 | JMP RM_EXIT ;exit | ||
| 1929 | RM_DXINRANGE: | ||
| 1930 | PUSH DX ;Handle destroyed by MUL @RH1 | ||
| 1931 | MOV AX,DX ;SI = requested handle's @RH1 | ||
| 1932 | MOV DX,TYPE H_LOOKUP_STRUC ; offset into the handle @RH1 | ||
| 1933 | MUL DX ; lookup table @RH1 | ||
| 1934 | MOV SI,AX ; @RH1 | ||
| 1935 | POP DX ;Restore handle ID @RH1 | ||
| 1936 | |||
| 1937 | CMP HANDLE_LOOKUP_TABLE.H_Pages[SI],REUSABLE_HANDLE | ||
| 1938 | JNE RM_HACTIVE ;If handle is in use (active), ok @RH1 | ||
| 1939 | MOV AH,EMS_CODE83 ;else handle not in use; error | ||
| 1940 | JMP RM_EXIT ;exit | ||
| 1941 | RM_HACTIVE: | ||
| 1942 | MOV AX,DX ;SI = requested handle's @RH1 | ||
| 1943 | MOV DX,TYPE H_SAVE_STRUC ; offset into the handle @RH1 | ||
| 1944 | MUL DX ; save area @RH1 | ||
| 1945 | MOV SI,AX ;Add the table base to @RH1 | ||
| 1946 | ADD SI,OFFSET HANDLE_SAVE_AREA ; make DS:SI a pointer @RH1 | ||
| 1947 | |||
| 1948 | ;------------------------------------- | ||
| 1949 | ; Insure save area used for this hndl º | ||
| 1950 | RM_AREACHECK: ;------------------------------------- | ||
| 1951 | CMP [SI].PG0_LP,REUSABLE_SAVEA ;Unused save table entry? @RH1 | ||
| 1952 | JNE RM_SAVE_OK ;No used..OK check next @RH1 | ||
| 1953 | MOV AH,EMS_CODE8E ;Yes error ..no page map | ||
| 1954 | JMP RM_EXIT ; saved. Exit. | ||
| 1955 | |||
| 1956 | ;------------------------------------- | ||
| 1957 | ; Call RESTORE_PGFRM_MAP º | ||
| 1958 | RM_SAVE_OK: ;------------------------------------- | ||
| 1959 | CALL RESTORE_PGFRM_MAP ;Restore page frame map | ||
| 1960 | CMP AH,0 ;Successful? | ||
| 1961 | JNE RM_EXIT ;No exit | ||
| 1962 | |||
| 1963 | ;------------------------------------- | ||
| 1964 | ; Clear the save area for the handle º | ||
| 1965 | ;------------------------------------- | ||
| 1966 | ;DS:SI still ptr to save area @RH5 | ||
| 1967 | MOV CX,map_count ;Clear all saved entries @RH5 | ||
| 1968 | RM_CLEAR_SA: ;Use an overlay to mark the @RH5 | ||
| 1969 | MOV [SI].HSA_LP,REUSABLE_SAVEA ; save area free - put reusabl @RH5 | ||
| 1970 | ADD SI,TYPE H_SAVEA_ENTRY ; indicator in the log p field @RH5 | ||
| 1971 | LOOP RM_CLEAR_SA ; @RH5 | ||
| 1972 | |||
| 1973 | RM_EXIT: | ||
| 1974 | POP DS ;restore these registers | ||
| 1975 | POP SI | ||
| 1976 | POP DI | ||
| 1977 | POP DX | ||
| 1978 | POP CX | ||
| 1979 | POP BX | ||
| 1980 | RET ;return to caller | ||
| 1981 | RESTORE_MAP ENDP | ||
| 1982 | |||
| 1983 | ;-----------------------------------------------------------------------; | ||
| 1984 | ; Subroutine: RESTORE PAGE FRAME MAP ; | ||
| 1985 | ; ; | ||
| 1986 | ; purpose: To restore the map of the 4 pages within the ; | ||
| 1987 | ; page frame from a save area pointed to by DS:SI. ; | ||
| 1988 | ; The save area consists of a handle ID and logical ; | ||
| 1989 | ; page for each of the 4 physical pages. Each is a ; | ||
| 1990 | ; word value. ; | ||
| 1991 | ; called by: Restore mapping context (Function 9) using a ; | ||
| 1992 | ; handle ID and our save area. ; | ||
| 1993 | ; Set page map (Function 15 subfunction 1) without ; | ||
| 1994 | ; a handle ID using the application's save area. ; | ||
| 1995 | ; ; | ||
| 1996 | ; on entry: DS:SI points to the save area ; | ||
| 1997 | ; ; | ||
| 1998 | ; on exit: (AX) = Status ; | ||
| 1999 | ; All other registers preserved ; | ||
| 2000 | ; ; | ||
| 2001 | ;-----------------------------------------------------------------------; | ||
| 2002 | RESTORE_PGFRM_MAP PROC | ||
| 2003 | PUSH BX | ||
| 2004 | PUSH CX | ||
| 2005 | PUSH DX | ||
| 2006 | PUSH DI | ||
| 2007 | PUSH SI | ||
| 2008 | |||
| 2009 | XOR DI,DI ;Use for mappable phys page table @RH5 | ||
| 2010 | MOV CX,map_count ;Loop for all pages in page frame @RH5 | ||
| 2011 | RP_RSTR_LP: ; @RH5 | ||
| 2012 | PUSH DS ;Get the phys page from @RH5 | ||
| 2013 | MOV AX,MAP_TABLE.PHYS_PAGE_NUMBER[DI] ; the map phys pg tbl @RH5 | ||
| 2014 | POP DS ; (only AL is used) @RH5 | ||
| 2015 | MOV DX,[SI] ;DX = Handle ID..inc SI @RH5 | ||
| 2016 | ADD SI,TYPE PG0_HNDL ; by len needed for hnd @RH5 | ||
| 2017 | MOV BX,[SI] ;BX = Log. page..inc SI @RH5 | ||
| 2018 | ADD SI,TYPE PG0_LP ; by len needed for lp @RH5 | ||
| 2019 | CALL MAP_L_TO_P ;Call main Map module @RH5 | ||
| 2020 | CMP AH,0 ;If an error occurred @RH5 | ||
| 2021 | JE RP_NEXT ; anywhere set software @RH5 | ||
| 2022 | MOV AH,EMS_CODE80 ; error and exit @RH5 | ||
| 2023 | JMP SHORT RP_EXIT ;Else map next page @RH5 | ||
| 2024 | RP_NEXT: ;Advance offset into @RH5 | ||
| 2025 | ADD DI,TYPE MAPPABLE_PHYS_PAGE_STRUCT ; map phys page table @RH5 | ||
| 2026 | LOOP RP_RSTR_LP ;Loop for 4 EMS pages @RH5 | ||
| 2027 | |||
| 2028 | RP_EXIT: | ||
| 2029 | POP SI | ||
| 2030 | POP DI ;Restore entry regs | ||
| 2031 | POP DX | ||
| 2032 | POP CX | ||
| 2033 | POP BX | ||
| 2034 | RET ;return to caller | ||
| 2035 | RESTORE_PGFRM_MAP ENDP | ||
| 2036 | |||
| 2037 | |||
| 2038 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 2039 | ;º Entry point for GET EMM HANDLE COUNT Function 12 º | ||
| 2040 | ;º º | ||
| 2041 | ;º on entry: (AH) = '4B'x º | ||
| 2042 | ;º º | ||
| 2043 | ;º on exit: (AH) = status º | ||
| 2044 | ;º (BX) = number of open (active) EMS handles º | ||
| 2045 | ;º all other registers preserved º | ||
| 2046 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 2047 | Q_OPEN PROC | ||
| 2048 | PUSH CX ;save these registers | ||
| 2049 | PUSH SI | ||
| 2050 | PUSH DS | ||
| 2051 | |||
| 2052 | PUSH CS ;get this segment | ||
| 2053 | POP DS ;into ds | ||
| 2054 | |||
| 2055 | XOR BX,BX ;clear open handle counter | ||
| 2056 | XOR SI,SI ;SI = offset of handle lookup table@RH1 | ||
| 2057 | MOV CX,NUM_HANDLES ;loop counter = number of handles | ||
| 2058 | QH_CHECKALL: | ||
| 2059 | CMP HANDLE_LOOKUP_TABLE.H_Pages[SI],REUSABLE_HANDLE | ||
| 2060 | ;Handle have pages? @RH1 | ||
| 2061 | JE QH_NEXTH ;No..not active..next @RH1 | ||
| 2062 | INC BX ;Else open handle @RH1 | ||
| 2063 | QH_NEXTH: | ||
| 2064 | ADD SI,TYPE H_LOOKUP_STRUC ;Point to next handle lookup entry @RH1 | ||
| 2065 | LOOP QH_CHECKALL ; and check it out @RH1 | ||
| 2066 | XOR AH,AH ;good return status | ||
| 2067 | |||
| 2068 | POP DS ;recover these registers | ||
| 2069 | POP SI | ||
| 2070 | POP CX | ||
| 2071 | RET ;return to caller | ||
| 2072 | Q_OPEN ENDP | ||
| 2073 | |||
| 2074 | |||
| 2075 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 2076 | ;º Entry point for GET EMM HANDLE PAGES Function 13 º | ||
| 2077 | ;º NOTE - CAN HANDLE HANDLE WITH 0 PAGES º | ||
| 2078 | ;º on entry: (AH) = '4C'x º | ||
| 2079 | ;º (DX) = handle id º | ||
| 2080 | ;º º | ||
| 2081 | ;º on exit: (AH) = status º | ||
| 2082 | ;º (BX) = number of pages allocated to this handle º | ||
| 2083 | ;º all other registers preserved º | ||
| 2084 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 2085 | Q_ALLOCATE PROC | ||
| 2086 | PUSH DX ;save these registers | ||
| 2087 | PUSH SI | ||
| 2088 | PUSH DS | ||
| 2089 | |||
| 2090 | PUSH CS ;get this segment | ||
| 2091 | POP DS ;into ds | ||
| 2092 | |||
| 2093 | CMP DX,NUM_HANDLES-1 ;DX <= Number of handles @RH1 | ||
| 2094 | JBE QP_DXINRANGE ;Yes OK @RH1 | ||
| 2095 | MOV AH,EMS_CODE83 ;No out of range..error @RH1 | ||
| 2096 | JMP Q_ALLOC_EXIT ;exit @RH1 | ||
| 2097 | QP_DXINRANGE: | ||
| 2098 | MOV AX,DX ;SI = offset into @RH1 | ||
| 2099 | MOV DX,TYPE H_LOOKUP_STRUC ; handle lookup tbl @RH1 | ||
| 2100 | MUL DX ; for the given @RH1 | ||
| 2101 | MOV SI,AX ; handle @RH1 | ||
| 2102 | MOV BX,HANDLE_LOOKUP_TABLE.H_Pages[SI] ;Return # of pages @RH1 | ||
| 2103 | |||
| 2104 | CMP BX,REUSABLE_HANDLE ; is this one free ;AN004; | ||
| 2105 | JNE QP_GOOD_RC ; no, must be a real number ;AN004; | ||
| 2106 | mov ah,EMS_Code83 ; this page is not allocated currently ;an004; dms; | ||
| 2107 | XOR BX,BX ; yes, zero BX (number of pages) ;AN004; | ||
| 2108 | jmp Q_Alloc_Exit ; exit the routine ;an004; dms; | ||
| 2109 | ;AN004; | ||
| 2110 | QP_GOOD_RC: ;AN004; | ||
| 2111 | XOR AH,AH ;good return status | ||
| 2112 | Q_ALLOC_EXIT: | ||
| 2113 | POP DS ;recover these registers | ||
| 2114 | POP SI | ||
| 2115 | POP DX | ||
| 2116 | RET ;return to caller | ||
| 2117 | Q_ALLOCATE ENDP | ||
| 2118 | |||
| 2119 | |||
| 2120 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 2121 | ;º Entry point for GET ALL OPEN HANDLES AND PAGES Function 14 º | ||
| 2122 | ;º º | ||
| 2123 | ;º on entry: (AH) = '4D'x º | ||
| 2124 | ;º ES:DI = Points to an array. Each entry consists of º | ||
| 2125 | ;º 2 words. The first word is for an active º | ||
| 2126 | ;º EMS handle and the 2nd word for the number º | ||
| 2127 | ;º of pages allocated to that handle. This º | ||
| 2128 | ;º procedure will fill in the table, but the º | ||
| 2129 | ;º requestor must supply a large enough array. º | ||
| 2130 | ;º º | ||
| 2131 | ;º on exit: (AH) = status º | ||
| 2132 | ;º (BX) = Number of active EMS handles º | ||
| 2133 | ;º all other registers preserved º | ||
| 2134 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 2135 | Q_OPEN_ALL PROC | ||
| 2136 | PUSH CX ;save these registers | ||
| 2137 | PUSH DX | ||
| 2138 | PUSH DI | ||
| 2139 | PUSH SI | ||
| 2140 | PUSH DS | ||
| 2141 | |||
| 2142 | PUSH CS ;get this segment | ||
| 2143 | POP DS ;into ds | ||
| 2144 | |||
| 2145 | MOV DI,cs:[bp].IE_Saved_DI_Reg ;restore di to its value on - gga P1501 ;an004; | ||
| 2146 | ;entry | ||
| 2147 | |||
| 2148 | XOR BX,BX ;Init number of active handles @RH1 | ||
| 2149 | XOR DX,DX ; and handle id @RH1 | ||
| 2150 | XOR SI,SI ;SI = offset into handle lup table @RH1 | ||
| 2151 | MOV CX,NUM_HANDLES ;Loop for all entries in h lup tbl @RH1 | ||
| 2152 | QHP_CHECKALL: | ||
| 2153 | MOV AX,HANDLE_LOOKUP_TABLE.H_Pages[SI] ; @RH1 | ||
| 2154 | CMP AX,REUSABLE_HANDLE ;If entry is reusable (free), @RH1 | ||
| 2155 | JE QHP_NEXT ; don't count it. Check next hndl @RH1 | ||
| 2156 | INC BX ;Else active handle. Inc hndl cnt @RH1 | ||
| 2157 | MOV ES: WORD PTR [DI],DX ;Write handle # in the user's area @RH1 | ||
| 2158 | MOV ES: WORD PTR [DI+2],AX ;Write # of pages in the 2nd word @RH1 | ||
| 2159 | ADD DI,4 ;Advance ptr to user's area @RH1 | ||
| 2160 | QHP_NEXT: ;Check next entry in h lup table @RH1 | ||
| 2161 | ADD SI,TYPE H_LOOKUP_STRUC ;Inc offset into handle lup table @RH1 | ||
| 2162 | INC DX ;Next handle ID | ||
| 2163 | LOOP QHP_CHECKALL | ||
| 2164 | |||
| 2165 | XOR AH,AH ;good return status | ||
| 2166 | |||
| 2167 | POP DS ;restore these registers | ||
| 2168 | POP SI | ||
| 2169 | POP DI | ||
| 2170 | POP DX | ||
| 2171 | POP CX | ||
| 2172 | RET ;return to caller | ||
| 2173 | Q_OPEN_ALL ENDP | ||
| 2174 | |||
| 2175 | |||
| 2176 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 2177 | ;º Entry point for GET/SET PAGE MAP SUBFUNCTIONS Function 15 º | ||
| 2178 | ;º º | ||
| 2179 | ;º on entry: (AH) = '4E'x º | ||
| 2180 | ;º (AL) = subfunction number º | ||
| 2181 | ;º ES:DI = destination save area for Get Subfunction º | ||
| 2182 | ;º DS:SI = source save area for Set Subfunction º | ||
| 2183 | ;º º | ||
| 2184 | ;º on exit: (AH) = status º | ||
| 2185 | ;º all other registers preserved º | ||
| 2186 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 2187 | SUBFCN_TABLE LABEL WORD | ||
| 2188 | DW OFFSET GET_SUBFCN ;0 - Put page frame map into ES:DI array | ||
| 2189 | DW OFFSET SET_SUBFCN ;1 - Set page frame map from DS:SI array | ||
| 2190 | DW OFFSET GET_SET_SUBFCN ;2 - Put page frame map into ES:DI array | ||
| 2191 | ;and Set page frame map from DS:SI array | ||
| 2192 | MAX_SUBFCN EQU ($-SUBFCN_TABLE)/2 ;maximum allowable subfunction number | ||
| 2193 | DW OFFSET SIZE_SUBFCN ;3 - Return storage requirements of the | ||
| 2194 | ;Get and Set subfunctions | ||
| 2195 | GET_SET_MAP PROC | ||
| 2196 | MOV DI,cs:[bp].IE_Saved_DI_Reg ;restore di to its value on | ||
| 2197 | PUSH BX ;save bx | ||
| 2198 | CMP AL,MAX_SUBFCN ;is subfunctiion number within range? | ||
| 2199 | ; $IF BE ;do if yes... | ||
| 2200 | JNBE $$IF86 | ||
| 2201 | MOV BX,OFFSET GET_SET_EXIT ;get return address common to all subfcns | ||
| 2202 | PUSH BX ;put it on stack for return | ||
| 2203 | XOR AH,AH ;adjust ax to make it | ||
| 2204 | ADD AX,AX ; offset into jump table | ||
| 2205 | MOV BX,AX ;get it into bx for jump | ||
| 2206 | ;At entry to subfunction handler: | ||
| 2207 | ; CS = INT67 code segment | ||
| 2208 | ; TOP OF STACK is return address, GET_SET_EXIT | ||
| 2209 | |||
| 2210 | JMP CS:SUBFCN_TABLE[BX] ;call subfunction handler | ||
| 2211 | ; $ENDIF | ||
| 2212 | $$IF86: | ||
| 2213 | ;if subfcn # is out of range then do... | ||
| 2214 | MOV AH,EMS_CODE8F ;function call out of range | ||
| 2215 | GET_SET_EXIT: | ||
| 2216 | POP BX ;recover bx | ||
| 2217 | RET ;return to caller | ||
| 2218 | GET_SET_MAP ENDP | ||
| 2219 | |||
| 2220 | |||
| 2221 | page | ||
| 2222 | ;-----------------------------------------------------------------------; | ||
| 2223 | ; Subfunction 0 to GET PAGE MAP Function 15/0 ; | ||
| 2224 | ; ; | ||
| 2225 | ; on entry: (AH) = '43'x ; | ||
| 2226 | ; (AL) = 0 ; | ||
| 2227 | ; ES:DI = Destination save area ; | ||
| 2228 | ; ; | ||
| 2229 | ; on exit: (AH) = status ; | ||
| 2230 | ; all other registers preserved ; | ||
| 2231 | ;-----------------------------------------------------------------------; | ||
| 2232 | GET_SUBFCN PROC | ||
| 2233 | PUSH DI ;save | ||
| 2234 | PUSH ES ;save | ||
| 2235 | |||
| 2236 | |||
| 2237 | CALL SAVE_PGFRM_MAP ;save page frame map to ES:DI | ||
| 2238 | XOR AH,AH ;good return status | ||
| 2239 | POP ES ;restore | ||
| 2240 | POP DI ;restore | ||
| 2241 | RET ;return to caller | ||
| 2242 | GET_SUBFCN ENDP | ||
| 2243 | |||
| 2244 | |||
| 2245 | ;-----------------------------------------------------------------------; | ||
| 2246 | ; Subfunction 1 to SET PAGE MAP Function 15/1 ; | ||
| 2247 | ; ; | ||
| 2248 | ; on entry: (AH) = '43'x ; | ||
| 2249 | ; (AL) = 1 ; | ||
| 2250 | ; DS:SI = Source save area ; | ||
| 2251 | ; ; | ||
| 2252 | ; on exit: (AH) = status ; | ||
| 2253 | ; all other registers preserved ; | ||
| 2254 | ;-----------------------------------------------------------------------; | ||
| 2255 | SET_SUBFCN PROC | ||
| 2256 | PUSH SI ;save | ||
| 2257 | PUSH DS ;save | ||
| 2258 | CALL RESTORE_PGFRM_MAP ;restore page frame map from DS:SI | ||
| 2259 | XOR AH,AH ;good return status | ||
| 2260 | POP DS ;restore | ||
| 2261 | POP SI ;restore | ||
| 2262 | RET ;return to caller | ||
| 2263 | SET_SUBFCN ENDP | ||
| 2264 | |||
| 2265 | |||
| 2266 | ;-----------------------------------------------------------------------; | ||
| 2267 | ; Subfunction 2 to GET and SET PAGE MAP Function 15/2 ; | ||
| 2268 | ; ; | ||
| 2269 | ; on entry: (AH) = '43'x ; | ||
| 2270 | ; (AL) = 2 ; | ||
| 2271 | ; ES:DI = destination save area ; | ||
| 2272 | ; DS:SI = source save area ; | ||
| 2273 | ; ; | ||
| 2274 | ; on exit: (AH) = status ; | ||
| 2275 | ; all other registers preserved ; | ||
| 2276 | ;-----------------------------------------------------------------------; | ||
| 2277 | GET_SET_SUBFCN PROC | ||
| 2278 | PUSH DI | ||
| 2279 | PUSH SI | ||
| 2280 | |||
| 2281 | MOV DI,cs:[bp].IE_Saved_DI_Reg ;restore di to its value on | ||
| 2282 | ;entry into irpt handler | ||
| 2283 | |||
| 2284 | CALL SAVE_PGFRM_MAP ;save page frame map to ES:DI | ||
| 2285 | CALL RESTORE_PGFRM_MAP ;restore page frame map from DS:SI | ||
| 2286 | XOR AH,AH ;good return status | ||
| 2287 | |||
| 2288 | POP SI | ||
| 2289 | POP DI | ||
| 2290 | RET ;return to caller | ||
| 2291 | GET_SET_SUBFCN ENDP | ||
| 2292 | |||
| 2293 | ;-----------------------------------------------------------------------; | ||
| 2294 | ; Subfunction 3 to RETURN SIZE OF SAVE ARRAY Function 15/3 ; | ||
| 2295 | ; ; | ||
| 2296 | ; on entry: (AH) = '43'x ; | ||
| 2297 | ; (AL) = 3 ; | ||
| 2298 | ; ; | ||
| 2299 | ; on exit: (AH) = status ; | ||
| 2300 | ; (AL) = Number of bytes needed for a GET or SET ; | ||
| 2301 | ; all other registers preserved ; | ||
| 2302 | ;-----------------------------------------------------------------------; | ||
| 2303 | SIZE_SUBFCN PROC | ||
| 2304 | MOV AL,TYPE H_SAVE_STRUC ;get size requirements for save area | ||
| 2305 | XOR AH,AH ;good return status | ||
| 2306 | RET ;return to caller | ||
| 2307 | SIZE_SUBFCN ENDP | ||
| 2308 | |||
| 2309 | ;========================================================================= | ||
| 2310 | ; Set_Instance This routine accesses the instance table. | ||
| 2311 | ; | ||
| 2312 | ; Inputs : Instance_Table - Table of instances of reentrancy. | ||
| 2313 | ; | ||
| 2314 | ; Outputs : BP - pointer to instance table entry to use | ||
| 2315 | ; NC - instance table entry found | ||
| 2316 | ; CY - no instance table entry found | ||
| 2317 | ; AH - error code on CY | ||
| 2318 | ;========================================================================= | ||
| 2319 | |||
| 2320 | Set_Instance proc ;set the instance table ;an000; dms; | ||
| 2321 | |||
| 2322 | cli ;disable interrupts ;an000; dms; | ||
| 2323 | push cx ; ;an000; dms; | ||
| 2324 | |||
| 2325 | mov bp,offset cs:Instance_Table ;get pointer to instance table ;an000; dms; | ||
| 2326 | mov cx,Instance_Count ;number of instances ;an000; dms; | ||
| 2327 | |||
| 2328 | Set_Instance_Loop: | ||
| 2329 | |||
| 2330 | cmp cs:[bp].IE_Alloc_Byte,Unallocated;unallocated entry? ;an000; dms; | ||
| 2331 | je Set_Instance_Found ;open entry ;an000; dms; | ||
| 2332 | add bp,Instance_Size ;next instance ;an000; dms; | ||
| 2333 | loop Set_Instance_Loop ;continue ;an000; dms; | ||
| 2334 | |||
| 2335 | mov ah,EMS_Code80 ;not enough instance entries ;an000; dms; | ||
| 2336 | stc ;signal error ;an000; dms; | ||
| 2337 | jmp Set_Instance_Exit ;exit routine ;an000; dms; | ||
| 2338 | |||
| 2339 | Set_Instance_Found: | ||
| 2340 | |||
| 2341 | mov cs:[bp].IE_Alloc_Byte,Allocated ;instance allocated ;an000; dms; | ||
| 2342 | clc ;signal good exit ;an000; dms; | ||
| 2343 | |||
| 2344 | Set_Instance_Exit: | ||
| 2345 | |||
| 2346 | pop cx ;restore regs ;an000; dms; | ||
| 2347 | sti ;turn on interrupts ;an000; dms; | ||
| 2348 | |||
| 2349 | ret ;return ;an000; dms; | ||
| 2350 | |||
| 2351 | Set_Instance endp ; ;an000; dms; | ||
| 2352 | |||
| 2353 | ;========================================================================= | ||
| 2354 | ; Reset_Instance This routine accesses the instance table. | ||
| 2355 | ; | ||
| 2356 | ; Inputs : BP - pointer to currently active instance entry | ||
| 2357 | ; | ||
| 2358 | ; Outputs : Instance_Table - Deactivated instance entry | ||
| 2359 | ;========================================================================= | ||
| 2360 | |||
| 2361 | Reset_Instance proc | ||
| 2362 | |||
| 2363 | cli ;turn off interrupts ;an000; dms; | ||
| 2364 | mov cs:[bp].IE_Alloc_Byte,Unallocated;deallocate instance ;an000; dms; | ||
| 2365 | sti ;set interrupts ;an000; dms; | ||
| 2366 | |||
| 2367 | ret ;return ;an000; dms; | ||
| 2368 | |||
| 2369 | Reset_Instance endp ; ;an000; dms; | ||
| 2370 | |||
| 2371 | |||
| 2372 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 2373 | ;º Entry point for UNSUPPORTED FUNCTION CALLS º | ||
| 2374 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 2375 | UNSUPPORTED PROC | ||
| 2376 | |||
| 2377 | GET_PORT_ARRAY: | ||
| 2378 | GET_L_TO_P: | ||
| 2379 | RET | ||
| 2380 | UNSUPPORTED ENDP | ||
| 2381 | |||
| 2382 | |||
| 2383 | ;========================================================================= | ||
| 2384 | ; EMS_Page_Contig_Chk - This routine will take CX as input, which is | ||
| 2385 | ; the count of pages needed to satisfy the | ||
| 2386 | ; Allocate, Allocate Raw, or Reallocate functions. | ||
| 2387 | ; It will scan the unallocated page list to | ||
| 2388 | ; determine if there are CX number of contiguous | ||
| 2389 | ; pages. When it finds a block of contiguous | ||
| 2390 | ; pages it will return a pointer in SI pointing | ||
| 2391 | ; to the first page in the linked list that contains | ||
| 2392 | ; CX contiguous pages. If CX contiguous pages are | ||
| 2393 | ; not found a CY will be returned. | ||
| 2394 | ; | ||
| 2395 | ; Inputs : CX (Pages needed for request) | ||
| 2396 | ; | ||
| 2397 | ; Outputs : CY (There are no CX contiguous pages) | ||
| 2398 | ; NC (There are CX contiguous pages) | ||
| 2399 | ; SI (Pointer to 1st. page of CX contiguous pages) | ||
| 2400 | ;========================================================================= | ||
| 2401 | |||
| 2402 | EMS_Page_Contig_Chk proc near ;determine contiguity ;an001; dms; | ||
| 2403 | |||
| 2404 | push ax ;save regs ;an001; dms; | ||
| 2405 | push bx ; ;an001; dms; | ||
| 2406 | push cx ; ;an001; dms; | ||
| 2407 | push dx ; ;an001; dms; | ||
| 2408 | push di ; ;an001; dms; | ||
| 2409 | |||
| 2410 | ;;;; mov ax,cs:Free_Pages ;initialize page count ;an001; dms; | ||
| 2411 | mov di,cs:PAL_Free_Ptr ;pointer to free list ;an001; dms; | ||
| 2412 | mov si,di ;initialize ptr val ;an001; dms; | ||
| 2413 | ;;;; mov bx,di ;initialize base val ;an001; dms; | ||
| 2414 | ;;;; mov dx,1 ;initialize count val ;an001; dms; | ||
| 2415 | |||
| 2416 | EMS_Page_Contig_Main_Loop: | ||
| 2417 | |||
| 2418 | ;;;; cmp dx,cx ;at end? ;an001; dms; | ||
| 2419 | ;;;; je EMS_Page_Found_Contig ;yes - found contig ;an001; dms; | ||
| 2420 | |||
| 2421 | ;;;; shl di,1 ;index value ;an001; dms; | ||
| 2422 | ;;;; mov si,Page_Alloc_List[di] ;point to next free ;an001; dms; | ||
| 2423 | ;;;; shr di,1 ;ptr value ;an001; dms; | ||
| 2424 | ;;;; dec di ;see if it is contig ;an001; dms; | ||
| 2425 | ;;;; cmp si,di ; ;an001; dms; | ||
| 2426 | ;;;; je EMS_Page_Contig_Loop ;contig - check next ;an001; dms; | ||
| 2427 | ;;;; jmp EMS_Page_Contig_Init_Loop ;not contig ;an001; dms; | ||
| 2428 | |||
| 2429 | EMS_Page_Contig_Loop: | ||
| 2430 | |||
| 2431 | ;;;; inc dx ;inc loop counter ;an001; dms; | ||
| 2432 | ;;;; jmp EMS_Page_Contig_Main_Loop ;continue ;an001; dms; | ||
| 2433 | |||
| 2434 | EMS_Page_Contig_Init_Loop: | ||
| 2435 | |||
| 2436 | ;;;; sub ax,dx ;adjust pages left cnt ;an001; dms; | ||
| 2437 | ;;;; cmp ax,cx ;enough left? ;an001; dms; | ||
| 2438 | ;;;; jb EMS_Page_Not_Contig ;no contig memory ;an001; dms; | ||
| 2439 | ;;;; mov bx,si ;reinit base val ;an001; dms; | ||
| 2440 | ;;;; mov di,si ;reinit ptr val ;an001; dms; | ||
| 2441 | ;;;; mov dx,1 ;reinit count val ;an001; dms; | ||
| 2442 | ;;;; jmp EMS_Page_Contig_Main_Loop ;continue check ;an001; dms; | ||
| 2443 | |||
| 2444 | EMS_Page_Not_Contig: | ||
| 2445 | |||
| 2446 | ;;;; stc ;signal not contig ;an001; dms; | ||
| 2447 | ;;;; jmp EMS_Page_Contig_Exit ;exit routine ;an001; dms; | ||
| 2448 | |||
| 2449 | EMS_Page_Found_Contig: | ||
| 2450 | |||
| 2451 | clc ;signal contig ;an001; dms; | ||
| 2452 | ;;;; mov si,bx ;pass ptr to 1st. ;an001; dms; | ||
| 2453 | |||
| 2454 | EMS_Page_Contig_Exit: | ||
| 2455 | |||
| 2456 | pop di ;restore regs ;an001; dms; | ||
| 2457 | pop dx ; ;an001; dms; | ||
| 2458 | pop cx ; ;an001; dms; | ||
| 2459 | pop bx ; ;an001; dms; | ||
| 2460 | pop ax ; ;an001; dms; | ||
| 2461 | |||
| 2462 | ret ;return to caller ;an001; dms; | ||
| 2463 | |||
| 2464 | EMS_Page_Contig_Chk endp ;end proc ;an001; dms; | ||
| 2465 | |||
| 2466 | |||
| 2467 | |||
| 2468 | ;========================================================================= | ||
| 2469 | ; EMS_Link_Set - This routine takes the SI returned from | ||
| 2470 | ; EMS_Page_Cont_Chk and removes CX pages from | ||
| 2471 | ; the linked list for the new handle. | ||
| 2472 | ; | ||
| 2473 | ; Inputs : SI - Pointer value to the beginning of pages for handle | ||
| 2474 | ; CX - Count of pages to be allocated | ||
| 2475 | ; | ||
| 2476 | ; Outputs : Adjusted unallocated list | ||
| 2477 | ; SI - Pointer value to beginning of pages for handle | ||
| 2478 | ;========================================================================= | ||
| 2479 | |||
| 2480 | |||
| 2481 | EMS_Link_Set proc near ;set contig links ;an001; dms; | ||
| 2482 | |||
| 2483 | push ax ;save regs ;an001; dms; | ||
| 2484 | push bx ; ;an001; dms; | ||
| 2485 | push cx ; ;an001; dms; | ||
| 2486 | push dx ; ;an001; dms; | ||
| 2487 | push di ; ;an001; dms; | ||
| 2488 | |||
| 2489 | ;;;; cmp si,cs:PAL_Free_Ptr ;at root? ;an001; dms; | ||
| 2490 | ;;;; je EMS_Link_Set_Up_Root ;yes - set up links ;an001; dms; | ||
| 2491 | |||
| 2492 | ;;;; mov di,cs:PAL_Free_Ptr ;get first free link ;an001; dms; | ||
| 2493 | |||
| 2494 | EMS_Link_Set_Up_Search_Loop: | ||
| 2495 | |||
| 2496 | ;;;; shl di,1 ;get index value ;an001; dms; | ||
| 2497 | ;;;; cmp si,Page_Alloc_List[di] ;pointers match? ;an001; dms; | ||
| 2498 | ;;;; je EMS_Link_Set_Up ;yes - set up links ;an001; dms; | ||
| 2499 | ;;;; mov di,Page_Alloc_List[di] ;get next pointer ;an001; dms; | ||
| 2500 | ;;;; jmp EMS_Link_Set_Up_Search_Loop ;continue ;an001; dms; | ||
| 2501 | |||
| 2502 | EMS_Link_Set_Up: | ||
| 2503 | |||
| 2504 | ;;;; mov ax,di ;save index value ;an001; dms; | ||
| 2505 | ;;;; mov di,si ;point to first link ;an001; dms; | ||
| 2506 | ;;;; mov dx,1 ;init loop counter ;an001; dms; | ||
| 2507 | |||
| 2508 | EMS_Link_Set_Up_Loop: | ||
| 2509 | |||
| 2510 | ;;;; cmp dx,cx ;at end? ;an001; dms; | ||
| 2511 | ;;;; je EMS_Link_Set_Up_Loop_Exit ;yes - exit ;an001; dms; | ||
| 2512 | |||
| 2513 | ;;;; shl di,1 ;index value ;an001; dms; | ||
| 2514 | ;;;; mov di,Page_Alloc_List[di] ;next ptr ;an001; dms; | ||
| 2515 | ;;;; inc dx ;inc counter ;an001; dms; | ||
| 2516 | ;;;; jmp EMS_Link_Set_Up_Loop ;continue ;an001; dms; | ||
| 2517 | |||
| 2518 | EMS_Link_Set_Up_Loop_Exit: | ||
| 2519 | |||
| 2520 | ;;;; shl di,1 ;index value ;an001; dms; | ||
| 2521 | ;;;; mov bx,Page_Alloc_List[di] ;get next link ;an001; dms; | ||
| 2522 | ;;;; mov di,ax ;get orig. link ;an001; dms; | ||
| 2523 | ;;;; mov Page_Alloc_List[di],bx ;hook up links ;an001; dms; | ||
| 2524 | ;;;; jmp EMS_Link_Set_Up_Exit | ||
| 2525 | |||
| 2526 | |||
| 2527 | EMS_Link_Set_Up_Root: | ||
| 2528 | |||
| 2529 | mov di,si ;point to first link ;an001; dms; | ||
| 2530 | xor dx,dx ;init loop counter ;an001; dms; | ||
| 2531 | |||
| 2532 | EMS_Link_Set_Up_Root_Loop: | ||
| 2533 | |||
| 2534 | cmp dx,cx ;at end? ;an001; dms; | ||
| 2535 | je EMS_Link_Set_Up_Root_Exit ;yes - exit ;an001; dms; | ||
| 2536 | |||
| 2537 | shl di,1 ;index value ;an001; dms; | ||
| 2538 | mov di,Page_Alloc_List[di] ;next ptr ;an001; dms; | ||
| 2539 | inc dx ;inc counter ;an001; dms; | ||
| 2540 | jmp EMS_Link_Set_Up_Root_Loop ;continue ;an001; dms; | ||
| 2541 | |||
| 2542 | EMS_Link_Set_Up_Root_Exit: | ||
| 2543 | |||
| 2544 | mov cs:PAL_Free_Ptr,di ;new free ptr ;an001; dms; | ||
| 2545 | jmp EMS_Link_Set_Up_Exit ;exit routine ;an001; dms; | ||
| 2546 | |||
| 2547 | EMS_Link_Set_Up_Exit: | ||
| 2548 | |||
| 2549 | pop di ;restore regs ;an001; dms; | ||
| 2550 | pop dx ; ;an001; dms; | ||
| 2551 | pop cx ; ;an001; dms; | ||
| 2552 | pop bx ; ;an001; dms; | ||
| 2553 | pop ax ; ;an001; dms; | ||
| 2554 | |||
| 2555 | ret ;return to caller ;an001; dms; | ||
| 2556 | |||
| 2557 | EMS_Link_Set endp ; ;an001; dms; | ||
| 2558 | |||
| 2559 | |||
| 2560 | |||
| 2561 | |||
| 2562 | ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 2563 | ;³ ³ | ||
| 2564 | ;³ LIM 4.0 functions are kept in a seperate include file, ³ | ||
| 2565 | ;³ LIM40.INC ³ | ||
| 2566 | ;³ ³ | ||
| 2567 | ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 2568 | include lim40.inc | ||
| 2569 | |||
| 2570 | Instance_Table db Instance_Size*Instance_Count dup(Unallocated) ;instance table ;an000; dms; | ||
| 2571 | |||
| 2572 | RESIDENT: ;last address that must stay resident | ||
| 2573 | PAGE | ||
| 2574 | PAGE | ||
| 2575 | |||
| 2576 | INCLUDE EMSINIT.INC ;Main file for throwaway | ||
| 2577 | ; initialization code | ||
| 2578 | INCLUDE XMA1DIAG.INC ;XMA 1 diagnostics and routines | ||
| 2579 | INCLUDE PS2_5060.INC ;Diagnostics for PS/2 models 50 @RH2 | ||
| 2580 | ; and 60. Support for XMA/A and @RH2 | ||
| 2581 | ; MXO cards @RH2 | ||
| 2582 | INCLUDE XMA2EMS.CL1 | ||
| 2583 | |||
| 2584 | |||
| 2585 | TEMP_STACK DB STACK_SIZE DUP(0) ;RESERVE FOR TEMP STACK | ||
| 2586 | TOP_OF_STACK DB ? ;DURING INITIALIZATION | ||
| 2587 | |||
| 2588 | CSEG ENDS | ||
| 2589 | END START | ||
| 2590 | |||
| 2591 | |||
diff --git a/v4.0/src/DEV/XMA2EMS/XMA2EMS.LC b/v4.0/src/DEV/XMA2EMS/XMA2EMS.LC new file mode 100644 index 0000000..bee5cc6 --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/XMA2EMS.LC | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | XMA2EMS.ASM | ||
| 2 | XMA2EMSP.INC | ||
| 3 | DIAGS.ASM | ||
| 4 | LIM40.INC | ||
| 5 | LIM40B.INC | ||
| 6 | PS2_5060.INC | ||
| 7 | PARMPARS.INC | ||
| 8 | EMSINIT.INC | ||
| 9 | XMA1DIAG.INC | ||
| 10 | GENIOCTL.INC | ||
| 11 | \ No newline at end of file | ||
diff --git a/v4.0/src/DEV/XMA2EMS/XMA2EMS.SKL b/v4.0/src/DEV/XMA2EMS/XMA2EMS.SKL new file mode 100644 index 0000000..d2a8169 --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/XMA2EMS.SKL | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | :class 1 | ||
| 2 | |||
| 3 | :use 1 xma2ems CRLF | ||
| 4 | :use 2 xma2ems Welcome_Msg | ||
| 5 | :use 3 xma2ems DGS_Start_Msg | ||
| 6 | :use 4 xma2ems DGS_End_Msg | ||
| 7 | :use 5 xma2ems Page_Frame_Msg | ||
| 8 | :use 6 xma2ems PF_Start | ||
| 9 | :use 7 xma2ems Conv_Pages | ||
| 10 | :use 8 xma2ems Reserve_Msg | ||
| 11 | :use 9 xma2ems Res_Pages | ||
| 12 | :use 10 xma2ems Avail_Msg | ||
| 13 | |||
| 14 | :use 11 xma2ems EMS_Pages | ||
| 15 | :use 12 xma2ems XMA1_Err_Msg | ||
| 16 | :use 13 xma2ems Not_Found_Msg | ||
| 17 | :use 14 xma2ems Parm_Err_Msg | ||
| 18 | :use 15 xma2ems No_Emul_Msg | ||
| 19 | :use 16 xma2ems Wrong_Emul_Msg | ||
| 20 | :use 17 xma2ems Wrong_XMAA_Msg | ||
| 21 | :use 18 xma2ems Req_EMS_Err_Msg | ||
| 22 | :use 19 xma2ems Not_Instl_Msg | ||
| 23 | :use 20 xma2ems Conflict_Msg | ||
| 24 | |||
| 25 | :use 21 xma2ems Confl_Address | ||
| 26 | :use 22 xma2ems Hole_Msg | ||
| 27 | :use 23 xma2ems Hole_Address | ||
| 28 | :use 24 xma2ems Frame_Msg | ||
| 29 | :use 25 xma2ems Frame_Address | ||
| 30 | :use 26 xma2ems No_Pages_Msg | ||
| 31 | :use 27 xma2ems Size_Msg1 | ||
| 32 | :use 28 xma2ems Mem_OK | ||
| 33 | :use 29 xma2ems Next_Line | ||
| 34 | :use 28 common Prompt_Msg | ||
| 35 | :use 30 xma2ems XMA2EMS_Msg_Term | ||
| 36 | :use 16 common No_EMS_Memory | ||
| 37 | :use 30 xma2ems XMA2EMS_Msg_Term1 | ||
| 38 | |||
| 39 | :end | ||
diff --git a/v4.0/src/DEV/XMA2EMS/XMA2EMSP.INC b/v4.0/src/DEV/XMA2EMS/XMA2EMSP.INC new file mode 100644 index 0000000..fa4196f --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/XMA2EMSP.INC | |||
| @@ -0,0 +1,243 @@ | |||
| 1 | |||
| 2 | INCSW EQU 0 ;INCLUDE PSDATA.INC ;AN000; | ||
| 3 | FARSW EQU 0 ;CALL THE PARSER BY NEAR CALL | ||
| 4 | DATESW EQU 1 ; ;SUPPRESS DATE CHECKING ;AN000; | ||
| 5 | TIMESW EQU 1 ; ;SUPPRESS TIME CHECKING ;AN000; | ||
| 6 | FILESW EQU 1 ;SUPPORT CHECKING FILE SPECIFICATION ;AN000; | ||
| 7 | CAPSW EQU 1 ; ;SUPPRESS FILE TABLE CAPS ;AN000; | ||
| 8 | CMPXSW EQU 1 ; ;SUPPRESS CHECKING COMPLEX LIST | ||
| 9 | DRVSW EQU 1 ; ;SUPPRESS SUPPORT OF DRIVE ONLY FORMAT | ||
| 10 | QUSSW EQU 1 ; ;SUPPRESS SUPPORT OF QUOTED STRING FORMAT ;AN000; | ||
| 11 | NUMSW EQU 1 ; ;SUPPRESS CHECKING NUMERIC VALUE | ||
| 12 | KEYSW EQU 1 ;SUPPORT KEYWORDS ;AN000; | ||
| 13 | SWSW EQU 1 ;DO SUPPORT SWITCHES ;AN000; | ||
| 14 | VAL1SW EQU 1 ;SUPPORT VALUE DEFINITION 1 ;AN000; | ||
| 15 | VAL2SW EQU 1 ; ;SUPPRESS SUPPORT OF VALUE DEFINITION 2 ;AN000; | ||
| 16 | VAL3SW EQU 1 ;DO SUPPORT VALUE DEFINITION 3 | ||
| 17 | |||
| 18 | include psdata.inc | ||
| 19 | |||
| 20 | ;*********************************************************************** | ||
| 21 | |||
| 22 | ;------------------------------------------------------------------- | ||
| 23 | ; | ||
| 24 | ; parser stuff for XMA2EMS.SYS | ||
| 25 | ; | ||
| 26 | ;------------------------------------------------------------------- | ||
| 27 | |||
| 28 | p_block: | ||
| 29 | dw offset px_block ; address of extended parms block | ||
| 30 | db 0 ; number of extra stuff | ||
| 31 | |||
| 32 | ;$P_PARMS_Blk <offset px_block, 0, 0> ; parm block | ||
| 33 | |||
| 34 | ;------------------------ | ||
| 35 | ; extended parameter block for APPEND first load | ||
| 36 | |||
| 37 | px_block: | ||
| 38 | db 1 ; min number positional operands | ||
| 39 | db 1 ; max number positional operands | ||
| 40 | dw offset dummy_ctl ; dummy control block | ||
| 41 | |||
| 42 | db 1 ; /X only switch | ||
| 43 | dw offset X_Switch ; control block for /X switch | ||
| 44 | |||
| 45 | db 7 ; max number of keywords | ||
| 46 | dw offset frame_ctl ; offset of FRAME= keyword control block | ||
| 47 | dw offset p0_ctl ; offset of p0 keyword control block | ||
| 48 | dw offset p1_ctl ; offset of p1 keyword control block | ||
| 49 | dw offset p2_ctl ; offset of p2 keyword control block | ||
| 50 | dw offset p3_ctl ; offset of p3 keyword control block | ||
| 51 | dw offset p254_ctl ; offset of p254 keyword control block | ||
| 52 | dw offset p255_ctl ; offset of p255 keyword control block | ||
| 53 | |||
| 54 | ;------------------------ | ||
| 55 | |||
| 56 | dummy_ctl: | ||
| 57 | dw 0200h ; | ||
| 58 | dw 0 ; no caps | ||
| 59 | dw offset dum_result ; pointer to dummy result block | ||
| 60 | dw offset dum_values ; pointer to null values block | ||
| 61 | db 0 ; number of switches and synonyms | ||
| 62 | |||
| 63 | dum_values: | ||
| 64 | dw 0 ; null value list | ||
| 65 | |||
| 66 | X_Switch: | ||
| 67 | dw $P_Num_Val ; /X:64 | ||
| 68 | dw 0002 ; caps | ||
| 69 | dw offset X_Result ; pointer to result block | ||
| 70 | dw offset X_Values ; pointer to values block, none | ||
| 71 | db 1 ; number of switches and synonyms | ||
| 72 | db "/X",0 ; only /X is valid | ||
| 73 | |||
| 74 | X_Values: | ||
| 75 | db 1 ; numeric values | ||
| 76 | db 1 ; 1 ranges | ||
| 77 | db 1 ; = 1 means good range | ||
| 78 | dd 4 ; valid values range from 4 (64Kb)... | ||
| 79 | dd 512 ; 512 (8MB) | ||
| 80 | |||
| 81 | ;------------------------ | ||
| 82 | |||
| 83 | frame_ctl: | ||
| 84 | dw $P_Simple_S ; used for FRAME= and Pxxx= | ||
| 85 | dw 0 ; cap by char table | ||
| 86 | dw offset frame_result ; pointer to result block | ||
| 87 | dw offset address_values ; pointer to values block | ||
| 88 | db 1 ; number of synonyms | ||
| 89 | db "FRAME=",0 | ||
| 90 | |||
| 91 | p0_ctl: | ||
| 92 | dw $P_Simple_S ; used for FRAME= and Pxxx= | ||
| 93 | dw 0 ; cap by char table | ||
| 94 | dw offset p0_result ; pointer to result block | ||
| 95 | dw offset address_values ; pointer to values block | ||
| 96 | db 3 ; number of synonyms | ||
| 97 | db "P0=",0 | ||
| 98 | db "P00=",0 | ||
| 99 | db "P000=",0 | ||
| 100 | |||
| 101 | p1_ctl: | ||
| 102 | dw $P_Simple_S ; used for FRAME= and Pxxx= | ||
| 103 | dw 0 ; cap by char table | ||
| 104 | dw offset p1_result ; pointer to result block | ||
| 105 | dw offset address_values ; pointer to values block | ||
| 106 | db 3 ; number of synonyms | ||
| 107 | db "P1=",0 | ||
| 108 | db "P01=",0 | ||
| 109 | db "P001=",0 | ||
| 110 | |||
| 111 | p2_ctl: | ||
| 112 | dw $P_Simple_S ; used for FRAME= and Pxxx= | ||
| 113 | dw 0 ; cap by char table | ||
| 114 | dw offset p2_result ; pointer to result block | ||
| 115 | dw offset address_values ; pointer to values block | ||
| 116 | db 3 ; number of synonyms | ||
| 117 | db "P2=",0 | ||
| 118 | db "P02=",0 | ||
| 119 | db "P002=",0 | ||
| 120 | |||
| 121 | p3_ctl: | ||
| 122 | dw $P_Simple_S ; used for FRAME= and Pxxx= | ||
| 123 | dw 0 ; cap by char table | ||
| 124 | dw offset p3_result ; pointer to result block | ||
| 125 | dw offset address_values ; pointer to values block | ||
| 126 | db 3 ; number of synonyms | ||
| 127 | db "P3=",0 | ||
| 128 | db "P03=",0 | ||
| 129 | db "P003=",0 | ||
| 130 | |||
| 131 | p254_ctl: | ||
| 132 | dw $P_Simple_S ; used for FRAME= and Pxxx= | ||
| 133 | dw 0 ; cap by char table | ||
| 134 | dw offset p254_result ; pointer to result block | ||
| 135 | dw offset address_values ; pointer to values block | ||
| 136 | db 1 ; number of synonyms | ||
| 137 | db "P254=",0 | ||
| 138 | |||
| 139 | p255_ctl: | ||
| 140 | dw $P_Simple_S ; used for FRAME= and Pxxx= | ||
| 141 | dw 0 ; cap by char table | ||
| 142 | dw offset p255_result ; pointer to result block | ||
| 143 | dw offset address_values ; pointer to values block | ||
| 144 | db 1 ; number of synonyms | ||
| 145 | db "P255=",0 | ||
| 146 | |||
| 147 | ;------------------------ | ||
| 148 | |||
| 149 | address_values: | ||
| 150 | db 3 ; strings | ||
| 151 | db 0 ; zeroes here for ranges | ||
| 152 | db 0 ; and values | ||
| 153 | db 24 ; 24 possible strings | ||
| 154 | db 0A0h | ||
| 155 | dw offset A0_str | ||
| 156 | db 0A4h | ||
| 157 | dw offset A4_str | ||
| 158 | db 0A8h | ||
| 159 | dw offset A8_str | ||
| 160 | db 0ACh | ||
| 161 | dw offset AC_str | ||
| 162 | db 0B0h | ||
| 163 | dw offset B0_str | ||
| 164 | db 0B4h | ||
| 165 | dw offset B4_str | ||
| 166 | db 0B8h | ||
| 167 | dw offset B8_str | ||
| 168 | db 0BCh | ||
| 169 | dw offset BC_str | ||
| 170 | db 0C0h | ||
| 171 | dw offset C0_str | ||
| 172 | db 0C4h | ||
| 173 | dw offset C4_str | ||
| 174 | db 0C8h | ||
| 175 | dw offset C8_str | ||
| 176 | db 0CCh | ||
| 177 | dw offset CC_str | ||
| 178 | db 0D0h | ||
| 179 | dw offset D0_str | ||
| 180 | db 0D4h | ||
| 181 | dw offset D4_str | ||
| 182 | db 0D8h | ||
| 183 | dw offset D8_str | ||
| 184 | db 0DCh | ||
| 185 | dw offset DC_str | ||
| 186 | db 0E0h | ||
| 187 | dw offset E0_str | ||
| 188 | db 0E4h | ||
| 189 | dw offset E4_str | ||
| 190 | db 0E8h | ||
| 191 | dw offset E8_str | ||
| 192 | db 0ECh | ||
| 193 | dw offset EC_str | ||
| 194 | db 0F0h | ||
| 195 | dw offset F0_str | ||
| 196 | db 0F4h | ||
| 197 | dw offset F4_str | ||
| 198 | db 0F8h | ||
| 199 | dw offset F8_str | ||
| 200 | db 0FCh | ||
| 201 | dw offset FC_str | ||
| 202 | |||
| 203 | |||
| 204 | |||
| 205 | A0_str db "A000",0 | ||
| 206 | A4_str db "A400",0 | ||
| 207 | A8_str db "A800",0 | ||
| 208 | AC_str db "AC00",0 | ||
| 209 | B0_str db "B000",0 | ||
| 210 | B4_str db "B400",0 | ||
| 211 | B8_str db "B800",0 | ||
| 212 | BC_str db "BC00",0 | ||
| 213 | C0_str db "C000",0 | ||
| 214 | C4_str db "C400",0 | ||
| 215 | C8_str db "C800",0 | ||
| 216 | CC_str db "CC00",0 | ||
| 217 | D0_str db "D000",0 | ||
| 218 | D4_str db "D400",0 | ||
| 219 | D8_str db "D800",0 | ||
| 220 | DC_str db "DC00",0 | ||
| 221 | E0_str db "E000",0 | ||
| 222 | E4_str db "E400",0 | ||
| 223 | E8_str db "E800",0 | ||
| 224 | EC_str db "EC00",0 | ||
| 225 | F0_str db "F000",0 | ||
| 226 | F4_str db "F400",0 | ||
| 227 | F8_str db "F800",0 | ||
| 228 | FC_str db "FC00",0 | ||
| 229 | |||
| 230 | ;------------------------ | ||
| 231 | |||
| 232 | dum_result $P_Result_Blk <> ; dummy result block | ||
| 233 | X_Result $P_Result_Blk <> ; /X result block | ||
| 234 | frame_result $P_Result_Blk <> ; FRAME= result block | ||
| 235 | p0_result $P_Result_Blk <> ; p0= result block | ||
| 236 | p1_result $P_Result_Blk <> ; p1= result block | ||
| 237 | p2_result $P_Result_Blk <> ; p2= result block | ||
| 238 | p3_result $P_Result_Blk <> ; p3= result block | ||
| 239 | p255_result $P_Result_Blk <> ; p254= result block | ||
| 240 | p254_result $P_Result_Blk <> ; p255= result block | ||
| 241 | |||
| 242 | |||
| 243 | \ No newline at end of file | ||