diff options
Diffstat (limited to 'v4.0/src/SELECT/ROUTINES.ASM')
| -rw-r--r-- | v4.0/src/SELECT/ROUTINES.ASM | 1626 |
1 files changed, 1626 insertions, 0 deletions
diff --git a/v4.0/src/SELECT/ROUTINES.ASM b/v4.0/src/SELECT/ROUTINES.ASM new file mode 100644 index 0000000..cd4fc0d --- /dev/null +++ b/v4.0/src/SELECT/ROUTINES.ASM | |||
| @@ -0,0 +1,1626 @@ | |||
| 1 | ;*************************************************************************** | ||
| 2 | ; Subroutines which are called by the macros in MACROS.INC. | ||
| 3 | ; File: ROUTINES.ASM | ||
| 4 | ; | ||
| 5 | ; This is a stand alone module and is meant to be linked with the calling | ||
| 6 | ; program. | ||
| 7 | ; | ||
| 8 | ;*************************************************************************** | ||
| 9 | .ALPHA ;AN000; | ||
| 10 | INCLUDE MAC_EQU.INC ;AN000; | ||
| 11 | INCLUDE PAN-LIST.INC ;AN000; | ||
| 12 | INCLUDE PANEL.MAC ;AN000; | ||
| 13 | |||
| 14 | ;********************************************************************** | ||
| 15 | DATA SEGMENT BYTE PUBLIC 'DATA' ;AN000; | ||
| 16 | |||
| 17 | |||
| 18 | NULl_DEVICE DB 'nul',0 ;AN000; | ||
| 19 | CON_DEVICE DB 'con',0 ;AN000; | ||
| 20 | |||
| 21 | SUB_PROGRAM DB 0 ;AN000; | ||
| 22 | PUBLIC EXEC_ERR ;AN000; | ||
| 23 | EXEC_ERR DB 0 ;AN000; | ||
| 24 | FIRST_TRY DB 0 ;AN000;DT | ||
| 25 | INT24_STATUS DB 0 ;AN000; | ||
| 26 | UNHOOKED EQU 0 ;AN000; | ||
| 27 | HOOKED EQU 1 ;AN000; | ||
| 28 | PUBLIC EXEC_DEALLOC,EXEC_FDISK ;AN000; | ||
| 29 | EXEC_DEALLOC DB 0 ;AN000;DT | ||
| 30 | EXEC_FDISK DB 0 ;AN000;DT | ||
| 31 | EXEC_DEHELP DB 0 ;AN000;DT | ||
| 32 | |||
| 33 | DATA ENDS ;AN000; DATA | ||
| 34 | ;********************************************************************** | ||
| 35 | |||
| 36 | .XLIST ;AN000; | ||
| 37 | INCLUDE STRUC.INC ;AN000; | ||
| 38 | INCLUDE MACROS.INC ;AN000; | ||
| 39 | INCLUDE VARSTRUC.INC ;AN000; | ||
| 40 | INCLUDE EXT.INC ;AN000; | ||
| 41 | EXTRN EXIT_DOS:FAR ;AN000; | ||
| 42 | EXTRN SYSDISPMSG:FAR ;AN000; | ||
| 43 | EXTRN HANDLE_ERROR_CALL:FAR ;AN000; | ||
| 44 | EXTRN ALLOCATE_MEMORY_CALL:FAR ;AN000; | ||
| 45 | EXTRN DEALLOCATE_MEMORY_CALL:FAR ;AN000; | ||
| 46 | |||
| 47 | EXTRN INT_23_VECTOR:NEAR ;AN074;SEH ctrl-break | ||
| 48 | EXTRN INT_24_VECTOR:NEAR ;AN000; | ||
| 49 | EXTRN INT_2F_VECTOR:NEAR ;AN000; | ||
| 50 | EXTRN INT_2F_256KB:NEAR ;AN000; | ||
| 51 | EXTRN INT_2F_FORMAT:NEAR ;AN111;JW | ||
| 52 | EXTRN ALLOCATE_HELP:FAR ;AN000; | ||
| 53 | EXTRN DEALLOCATE_HELP:FAR ;AN000; | ||
| 54 | .LIST ;AN000; | ||
| 55 | |||
| 56 | ;********************************************************************** | ||
| 57 | CODE_FAR SEGMENT PARA PUBLIC 'CODE' ;AN000; Segment for far routine | ||
| 58 | ASSUME CS:CODE_FAR,DS:DATA ;AN000; | ||
| 59 | ; | ||
| 60 | ;************************************************************************ | ||
| 61 | ; | ||
| 62 | ; APPEND_STRING: Append an ASCII-N string to the specified string. | ||
| 63 | ; | ||
| 64 | ; INPUT: | ||
| 65 | ; SI - OFFSET NAME_SRC | ||
| 66 | ; CX - IMMED_MAX | ||
| 67 | ; DI - OFFSET NAME_DEST | ||
| 68 | ; | ||
| 69 | ; OUTPUT: | ||
| 70 | ; None. | ||
| 71 | ; | ||
| 72 | ; OPERATION: | ||
| 73 | ; | ||
| 74 | ; | ||
| 75 | ;**************************************************************************** | ||
| 76 | PUBLIC APPEND_STRING_ROUTINE ;AN000; | ||
| 77 | APPEND_STRING_ROUTINE PROC FAR ;AN000; | ||
| 78 | |||
| 79 | PUSH ES ;AN000; | ||
| 80 | PUSH DS ;AN000; | ||
| 81 | POP ES ;AN000; ES and DS point to the data segment | ||
| 82 | |||
| 83 | .IF < CX LT <WORD PTR [DI]> > ;AN000; | ||
| 84 | MOV [DI], CX ;AN000; | ||
| 85 | .ELSE ;AN000; | ||
| 86 | SUB CX, [DI] ;AN000; Calculate space for the other string | ||
| 87 | .IF < CX GE <WORD PTR [SI]>> ;AN000; | ||
| 88 | MOV CX, [SI] ;AN000; Move the entire string | ||
| 89 | .ENDIF ;AN000; | ||
| 90 | MOV AX, [DI] ;AN000; Current size of destination string | ||
| 91 | ADD [DI], CX ;AN000; Add in the length of the new string | ||
| 92 | ADD DI, AX ;AN000; Add length of string to pointer | ||
| 93 | ADD DI, 2 ;AN000; Increment to pass first word and last byte | ||
| 94 | ADD SI, 2 ;AN000; Point source to start of the string | ||
| 95 | CLD ;AN000; | ||
| 96 | REP MOVSB ;AN000; | ||
| 97 | .ENDIF ;AN000; | ||
| 98 | |||
| 99 | POP ES ;AN000; | ||
| 100 | |||
| 101 | RET ;AN000; | ||
| 102 | |||
| 103 | APPEND_STRING_ROUTINE ENDP ;AN000; | ||
| 104 | ;************************************************************************ | ||
| 105 | ; | ||
| 106 | ; COPY_ROUTINE - Subroutine to perform the copy string operation. | ||
| 107 | ; | ||
| 108 | ; INPUT: | ||
| 109 | ; SI - OFFSET NAME_SRC | ||
| 110 | ; AX - IMMED_MAX | ||
| 111 | ; DI - OFFSET NAME_DEST | ||
| 112 | ; | ||
| 113 | ; OUTPUT: | ||
| 114 | ; None. | ||
| 115 | ; | ||
| 116 | ; OPERATION: Copies NAME_SRC1 to NAME_DEST. If NAME_SRC1 is longer then | ||
| 117 | ; IMMED_MAX, then only IMMED_MAX bytes are copied. | ||
| 118 | ; | ||
| 119 | ;**************************************************************************** | ||
| 120 | PUBLIC COPY_ROUTINE ;AN000; | ||
| 121 | COPY_ROUTINE PROC FAR ;AN000; | ||
| 122 | |||
| 123 | PUSH ES ;AN000; | ||
| 124 | PUSH DS ;AN000; | ||
| 125 | POP ES ;AN000; ES and DS point to the data segment | ||
| 126 | |||
| 127 | PUSH DI ;AN000; Save OFFSET NAME_DEST | ||
| 128 | MOV DX, AX ;AN000; Save IMMED_MAX | ||
| 129 | CLD ;AN000; Move strings in the forward direction | ||
| 130 | MOV CX,WORD PTR [SI] ;AN000; Get length of source string | ||
| 131 | ADD SI,2 ;AN000; Point SI to start of string | ||
| 132 | ADD DI,2 ;AN000; Point DI to start of destination. | ||
| 133 | .IF < CX GT AX > ;AN000; | ||
| 134 | MOV CX,AX ;AN000; Will not fit so adjust length | ||
| 135 | .ENDIF ;AN000; | ||
| 136 | SUB AX,CX ;AN000; Amount of room left. | ||
| 137 | REP MOVSB ;AN000; Move the string | ||
| 138 | SUB DX,AX ;AN000; Subtract the amount left over | ||
| 139 | POP SI ;AN000; | ||
| 140 | MOV WORD PTR [SI],DX ;AN000; Store the length of the string | ||
| 141 | |||
| 142 | POP ES ;AN000; | ||
| 143 | RET ;AN000; | ||
| 144 | |||
| 145 | COPY_ROUTINE ENDP ;AN000; | ||
| 146 | ;****************************************************************************** | ||
| 147 | ; | ||
| 148 | ; PUSH_ROUTINE: Routine to do the actual pushing of the screen label | ||
| 149 | ; | ||
| 150 | ; INPUT: | ||
| 151 | ; AX - Contains the address of the code for this screen | ||
| 152 | ; | ||
| 153 | ; OUTPUT: | ||
| 154 | ; None. | ||
| 155 | ; | ||
| 156 | ; OPERATION: The screen label address is pushed onto the SELECT stack | ||
| 157 | ; provided the numher of entries on the stack will not exceed the | ||
| 158 | ; maximum. Error will NOT be generated if the function was not | ||
| 159 | ; successful. | ||
| 160 | ; | ||
| 161 | ;****************************************************************************** | ||
| 162 | PUBLIC PUSH_ROUTINE ;AN000; | ||
| 163 | PUSH_ROUTINE PROC FAR ;AN000; | ||
| 164 | |||
| 165 | .IF < STACK_INDEX B STACK_SIZE > ;AN000; Is there any room? | ||
| 166 | MOV BL,STACK_INDEX ;AN000; Get the index | ||
| 167 | MOV BH, 0 ;AN000; | ||
| 168 | MOV SELECT_STACK[BX],AX ;AN000; Store the label | ||
| 169 | ADD STACK_INDEX,2 ;AN000; Point to next free space | ||
| 170 | .ENDIF ;AN000; | ||
| 171 | RET ;AN000; | ||
| 172 | PUSH_ROUTINE ENDP ;AN000; | ||
| 173 | ;****************************************************************************** | ||
| 174 | ; | ||
| 175 | ; POP_ROUTINE: Routine to do the actual poping of the screen label | ||
| 176 | ; | ||
| 177 | ; INPUT: | ||
| 178 | ; None. | ||
| 179 | ; | ||
| 180 | ; OUTPUT: | ||
| 181 | ; SI contains the address of the screen code. | ||
| 182 | ; | ||
| 183 | ; OPERATION: The screen label address is poped from the SELECT stack | ||
| 184 | ; provided there are entries on the stack. If there are no values | ||
| 185 | ; on the stack then the address of the EXIT_DOS screen will be | ||
| 186 | ; returned. | ||
| 187 | ; | ||
| 188 | ;****************************************************************************** | ||
| 189 | PUBLIC POP_ROUTINE ;AN000; | ||
| 190 | POP_ROUTINE PROC FAR ;AN000; | ||
| 191 | |||
| 192 | .IF < STACK_INDEX A 0 > ;AN000; Is there anything on the stack? | ||
| 193 | SUB STACK_INDEX,2 ;AN000; Point to last item on the stack | ||
| 194 | MOV BL,STACK_INDEX ;AN000; Get the index | ||
| 195 | MOV BH, 0 ;AN000; | ||
| 196 | MOV SI,SELECT_STACK[BX] ;AN000; Get the label | ||
| 197 | .ELSE ;AN000; | ||
| 198 | MOV SI,OFFSET EXIT_DOS ;AN000; EXIT_DOS screen | ||
| 199 | .ENDIF ;AN000; | ||
| 200 | RET ;AN000; | ||
| 201 | |||
| 202 | POP_ROUTINE ENDP ;AN000; | ||
| 203 | ;************************************************************************ | ||
| 204 | ; | ||
| 205 | ; MAKE_DIR_PATHS_ROUTINE: Create the specified directory including all | ||
| 206 | ; the specified sub-directories if they do not exist. | ||
| 207 | ; | ||
| 208 | ; INPUT: | ||
| 209 | ; BX - Points to an ASCII-N string containing the path to create | ||
| 210 | ; | ||
| 211 | ; OUTPUT: | ||
| 212 | ; CY = 0 Success | ||
| 213 | ; CY = 1 Error - AX will contain an error code. | ||
| 214 | ; | ||
| 215 | ; OPERATION: The directory pathname is created. | ||
| 216 | ; If the drive letter and colon are not followed by a '\', then the | ||
| 217 | ; macro will start creating the directories from the default directory. | ||
| 218 | ; If they are followed by a '\', then the macro will start at the root. | ||
| 219 | ; If an error occures, then sub-directories which have been created will | ||
| 220 | ; be removed. | ||
| 221 | ; | ||
| 222 | ; | ||
| 223 | ;**************************************************************************** | ||
| 224 | PUBLIC MAKE_DIR_PATHS_ROUTINE ;AN000; | ||
| 225 | MAKE_DIR_PATHS_ROUTINE PROC FAR ;AN000; | ||
| 226 | |||
| 227 | PUSH ES ;AN000; | ||
| 228 | PUSH DS ;AN000; | ||
| 229 | POP ES ;AN000; | ||
| 230 | |||
| 231 | |||
| 232 | MOV AH, 1 ;AN000; Flag indicating adding or deleting dirs | ||
| 233 | MOV SI, 0 ;AN000; End of the first path created | ||
| 234 | MOV DI, BX ;AN000; Offset of the ASCII-N string | ||
| 235 | ADD DI, 5 ;AN000; Point to the beginning of the path | ||
| 236 | MOV DX, WORD PTR [BX] ;AN000; Get the length of the string | ||
| 237 | MOV CX, DX ;AN000; Store in another variable as well | ||
| 238 | SUB CX, 3 ;AN000; Skip the first 3 characters 'C:\' | ||
| 239 | MOV AL, '\' ;AN000; Delimiter to search for | ||
| 240 | CLD ;AN000; Start searching in the forward direction | ||
| 241 | |||
| 242 | |||
| 243 | PROCESS_NEXT_DIR: ;AN000; | ||
| 244 | CMP AH, 1 ;AN000; Adding or deleting directories? | ||
| 245 | JNE DELETING_DIR_1 ;AN000; If adding, then jump | ||
| 246 | CMP CX,0 ;AN000; Is the string length zero? | ||
| 247 | JNE LENGTH_NOT_ZERO ;AN000; | ||
| 248 | JMP NORMAL_EXIT ;AN000; | ||
| 249 | DELETING_DIR_1: ;AN000; | ||
| 250 | CMP SI, DI ;AN000; Was this the first DIR created? | ||
| 251 | JNE LENGTH_NOT_ZERO ;AN000; | ||
| 252 | JMP ERROR_EXIT ;AN000; | ||
| 253 | |||
| 254 | LENGTH_NOT_ZERO: ;AN000; | ||
| 255 | REPNZ SCASB ;AN000; | ||
| 256 | JNZ STRING_END ;AN000; If not zero, we reached the string end | ||
| 257 | |||
| 258 | INC CX ;AN000; By adjusting DI, more bytes to the strings end | ||
| 259 | CMP AH,1 ;AN000; Adding or deleting | ||
| 260 | JNE DELETING_DIR_2 ;AN000; | ||
| 261 | DEC DI ;AN000; Back DI up to point to the '\' | ||
| 262 | STRING_END: ;AN000; | ||
| 263 | MOV WORD PTR [BX], DX ;AN000; Length of entire string | ||
| 264 | SUB WORD PTR [BX], CX ;AN000; Subtract the amount left in string | ||
| 265 | JMP ADJUST_DONE ;AN000; | ||
| 266 | DELETING_DIR_2: ;AN000; | ||
| 267 | INC DI ;AN000; Adjust DI to point to the '\' | ||
| 268 | MOV WORD PTR [BX], CX ;AN000; Length left in string | ||
| 269 | ADJUST_DONE: ;AN000; | ||
| 270 | |||
| 271 | CMP AH, 1 ;AN000; Adding or deleting directories | ||
| 272 | JNE DELETING_DIR_3 ;AN000; | ||
| 273 | CMP SI, 0 ;AN000; Created a DIR yet? | ||
| 274 | JNE MAKE_START ;AN000; | ||
| 275 | PUSH AX ;AN000; | ||
| 276 | ;********************************************************************** | ||
| 277 | PUSHH <DX,DI> ;AN000; | ||
| 278 | |||
| 279 | MOV DI,BX ;AN000; Get the offset of the string | ||
| 280 | CALL FAR PTR POS_ZERO ;AN000; Make into an ASCII-Z string | ||
| 281 | MOV INT_24_ERROR, 0 ;AN000; Zero the number of critical errors | ||
| 282 | MOV DX,BX ;AN000; Get the start of the string | ||
| 283 | ADD DX, 2 ;AN000; | ||
| 284 | MOV AH,3BH ;AN000; DOS function call number | ||
| 285 | DOSCALL ;AN000; | ||
| 286 | |||
| 287 | POPP <DI,DX> ;AN000; | ||
| 288 | ;********************************************************************** | ||
| 289 | POP AX ;AN000; | ||
| 290 | JNC DIR_DONE ;AN000; | ||
| 291 | MOV SI, DI ;AN000; | ||
| 292 | MAKE_START: ;AN000; | ||
| 293 | PUSH AX ;AN000; | ||
| 294 | ;********************************************************************** | ||
| 295 | PUSHH <DX,DI> ;AN000; | ||
| 296 | MOV DI,BX ;AN000; | ||
| 297 | CALL FAR PTR POS_ZERO ;AN000; position the '0' at the end of the path | ||
| 298 | MOV INT_24_ERROR, 0 ;AN000; Zero the number of critical errors | ||
| 299 | MOV DX,BX ;AN000; advance pointer to beginning of path | ||
| 300 | ADD DX, 2 ;AN000; | ||
| 301 | MOV AH,39H ;AN000; make directory interrupt | ||
| 302 | DOSCALL ;AN000; call to DOS interrupt 21 | ||
| 303 | POPP <DI,DX> ;AN000; | ||
| 304 | ;********************************************************************** | ||
| 305 | JC CANNOT_MAKE ;AN000; | ||
| 306 | POP AX ;AN000; | ||
| 307 | JMP DIR_DONE ;AN000; | ||
| 308 | CANNOT_MAKE: ;AN000; | ||
| 309 | POP CX ;AN000; Pop the previously saved AX value | ||
| 310 | PUSH AX ;AN000; Push the make dir error message | ||
| 311 | MOV AX, '\' ;AN000; | ||
| 312 | STD ;AN000; Now search in the backward direction | ||
| 313 | MOV CX, WORD PTR [BX] ;AN000; | ||
| 314 | JMP DIR_DONE ;AN000; | ||
| 315 | DELETING_DIR_3: ;AN000; | ||
| 316 | PUSH AX ;AN000; | ||
| 317 | ;********************************************************************** | ||
| 318 | PUSHH <DX,DI> ;AN000; | ||
| 319 | MOV DI,BX ;AN000; | ||
| 320 | CALL FAR PTR POS_ZERO ;AN000; position the '0' at the end of the path | ||
| 321 | MOV INT_24_ERROR, 0 ;AN000; Zero the number of critical errors | ||
| 322 | MOV DX,BX ;AN000; advance pointer to beginning of path | ||
| 323 | ADD DX, 2 ;AN000; | ||
| 324 | MOV AH,3AH ;AN000; remove the specified directory | ||
| 325 | DOSCALL ;AN000; call to DOS interrupt 21 | ||
| 326 | POPP <DI,DX> ;AN000; | ||
| 327 | ;********************************************************************** | ||
| 328 | JC ERROR_POP_EXIT ;AN000; | ||
| 329 | POP AX ;AN000; | ||
| 330 | DIR_DONE: ;AN000; | ||
| 331 | MOV BYTE PTR [DI], '\' ;AN000; Put the delimiter back | ||
| 332 | CMP CX,0 ;AN000; | ||
| 333 | JE NORMAL_EXIT ;AN000; If CX = 0, string ends | ||
| 334 | DEC CX ;AN000; | ||
| 335 | CMP AH,1 ;AN000; | ||
| 336 | JNE DELETING_DIR_4 ;AN000; | ||
| 337 | INC DI ;AN000; | ||
| 338 | JMP PROCESS_NEXT_DIR ;AN000; | ||
| 339 | DELETING_DIR_4: ;AN000; | ||
| 340 | DEC DI ;AN000; | ||
| 341 | JMP PROCESS_NEXT_DIR ;AN000; | ||
| 342 | |||
| 343 | ERROR_POP_EXIT: ;AN000; | ||
| 344 | POP CX ;AN000; Pop the extra value off the stack. | ||
| 345 | ERROR_EXIT: ;AN000; | ||
| 346 | POP AX ;AN000; Pop the error message number | ||
| 347 | STC ;AN000; | ||
| 348 | JMP PATHS_DONE ;AN000; | ||
| 349 | NORMAL_EXIT: ;AN000; | ||
| 350 | CLC ;AN000; | ||
| 351 | |||
| 352 | PATHS_DONE: ;AN000; | ||
| 353 | MOV WORD PTR [BX], DX ;AN000; Restore the original path length | ||
| 354 | |||
| 355 | POP ES ;AN000; | ||
| 356 | |||
| 357 | RET ;AN000; | ||
| 358 | |||
| 359 | MAKE_DIR_PATHS_ROUTINE ENDP ;AN000; | ||
| 360 | ;************************************************************************ | ||
| 361 | ; | ||
| 362 | ; POS_ZERO - Position a zero at the end of an ASCII-N string, making it | ||
| 363 | ; into an ASCII-Z string. | ||
| 364 | ; | ||
| 365 | ; INPUT: | ||
| 366 | ; DI - Points to the string to covert. | ||
| 367 | ; | ||
| 368 | ; OUTPUT: | ||
| 369 | ; None. | ||
| 370 | ; | ||
| 371 | ; OPERATION: An ASCII-N string is converted to an ASCII-Z string. | ||
| 372 | ; | ||
| 373 | ;**************************************************************************** | ||
| 374 | PUBLIC POS_ZERO ;AN000; | ||
| 375 | POS_ZERO PROC FAR ;AN000; | ||
| 376 | |||
| 377 | PUSH AX ;AN000; | ||
| 378 | PUSH DI ;AN000; | ||
| 379 | |||
| 380 | MOV AX,[DI] ;AN000; Get the length of the string | ||
| 381 | ADD DI,AX ;AN000; Add the length to the offset | ||
| 382 | ADD DI,2 ;AN000; Adjust for the length word | ||
| 383 | MOV BYTE PTR [DI],0 ;AN000; Position the zero after the end. | ||
| 384 | |||
| 385 | POP DI ;AN000; | ||
| 386 | POP AX ;AN000; | ||
| 387 | |||
| 388 | RET ;AN000; | ||
| 389 | |||
| 390 | POS_ZERO ENDP ;AN000; | ||
| 391 | ;************************************************************************ | ||
| 392 | ; | ||
| 393 | ; BEEP_ROUTINE - Cause the speaker to create a tone of a given frequency | ||
| 394 | ; and duration. | ||
| 395 | ; | ||
| 396 | ; INPUT: | ||
| 397 | ; DI - The frequency of the tone to create. | ||
| 398 | ; BX - The duration of the tone. | ||
| 399 | ; | ||
| 400 | ; OUTPUT: | ||
| 401 | ; None. | ||
| 402 | ; | ||
| 403 | ; OPERATION: Causes the speaker to produce a tone. | ||
| 404 | ; | ||
| 405 | ;**************************************************************************** | ||
| 406 | PUBLIC BEEP_ROUTINE ;AN000; | ||
| 407 | BEEP_ROUTINE PROC FAR ;AN000; | ||
| 408 | |||
| 409 | MOV AL,0B6H ;AN000; write timer mode register | ||
| 410 | OUT 43H,AL ;AN000; | ||
| 411 | MOV DX,14H ;AN000; timer divisor= | ||
| 412 | MOV AX,4F38H ;AN000; 1331000/frequency | ||
| 413 | DIV DI ;AN000; | ||
| 414 | OUT 42H,AL ;AN000; write timer 2 count low byte | ||
| 415 | MOV AL,AH ;AN000; | ||
| 416 | OUT 42H,AL ;AN000; write timer 2 count high byte | ||
| 417 | IN AL,61H ;AN000; get current PORT B setting | ||
| 418 | MOV AH,AL ;AN000; and save it in AH | ||
| 419 | OR AL,3 ;AN000; turn on speaker | ||
| 420 | OUT 61H,AL ;AN000; | ||
| 421 | B_WAIT: MOV CX,2801 ;AN000; wait 10 milliseconds | ||
| 422 | SPKR_ON:LOOP SPKR_ON ;AN000; | ||
| 423 | DEC BX ;AN000; | ||
| 424 | JNZ B_WAIT ;AN000; beep until finished | ||
| 425 | MOV AL,AH ;AN000; recover value of port | ||
| 426 | OUT 61H,AL ;AN000; | ||
| 427 | RET ;AN000; | ||
| 428 | |||
| 429 | BEEP_ROUTINE ENDP ;AN000; | ||
| 430 | ;************************************************************************ | ||
| 431 | ; | ||
| 432 | ; BIN_TO_CHAR_ROUTINE: Convert a binary number to ASCII format. | ||
| 433 | ; | ||
| 434 | ; INPUT: | ||
| 435 | ; AX - The binary number to convert. | ||
| 436 | ; DI - Pointer to the ASCII-N string to store the result. | ||
| 437 | ; | ||
| 438 | ; OUTPUT: | ||
| 439 | ; None. | ||
| 440 | ; | ||
| 441 | ; OPERATION: The specified 16 bit numeric variable contents are | ||
| 442 | ; converted to ASCII and stored in ASCII-N format. Leading zeros | ||
| 443 | ; will not be stored. | ||
| 444 | ; | ||
| 445 | ;**************************************************************************** | ||
| 446 | PUBLIC BIN_TO_CHAR_ROUTINE ;AN000; | ||
| 447 | BIN_TO_CHAR_ROUTINE PROC FAR ;AN000; | ||
| 448 | |||
| 449 | MOV SI, DI ;AN000; Copy the string pointer | ||
| 450 | ADD SI, 6 ;AN000; Point to the string END | ||
| 451 | MOV CX, 10 ;AN000; Number to divide AX by | ||
| 452 | |||
| 453 | .WHILE < NONZERO AX> ;AN000; | ||
| 454 | MOV DX, 0 ;AN000; Zero the high order word | ||
| 455 | DIV CX ;AN000; Divide the binary number | ||
| 456 | ADD DL, 48 ;AN000; Convert to ASCII | ||
| 457 | MOV [SI], DL ;AN000; Store in the string. | ||
| 458 | DEC SI ;AN000; Point to the next free string space | ||
| 459 | .ENDWHILE ;AN000; | ||
| 460 | SUB SI, DI ;AN000; Get the difference in the pointers | ||
| 461 | DEC SI ;AN000; Adjust for the lenght word | ||
| 462 | MOV WORD PTR [DI], 5 ;AN000; Store the number of characters | ||
| 463 | SUB WORD PTR [DI], SI ;AN000; Subtract the number of extra digits | ||
| 464 | MOV CX, WORD PTR [DI] ;AN000; | ||
| 465 | MOV BX, DI ;AN000; | ||
| 466 | ADD BX, 2 ;AN000; | ||
| 467 | .WHILE < NONZERO CX > ;AN000; | ||
| 468 | COPY_BYTE [BX],[BX+SI] ;AN000; | ||
| 469 | DEC CX ;AN000; | ||
| 470 | INC BX ;AN000; | ||
| 471 | .ENDWHILE ;AN000; | ||
| 472 | RET ;AN000; | ||
| 473 | |||
| 474 | BIN_TO_CHAR_ROUTINE ENDP ;AN000; | ||
| 475 | ;************************************************************************** | ||
| 476 | ; | ||
| 477 | ; PREPARE_FILE_ROUTINE: Prepare a file and a buffer for the construction | ||
| 478 | ; of that file line by line. | ||
| 479 | ; | ||
| 480 | ; INPUT: | ||
| 481 | ; BX = The address of an ASCII-N string containing the name of the file | ||
| 482 | ; to create. | ||
| 483 | ; | ||
| 484 | ; OUTPUT: CY = 0: No error was encountered. | ||
| 485 | ; CY = 1: There was an error encountered. | ||
| 486 | ; | ||
| 487 | ; OPERATION: A attempt is made to create the file. If it fails because | ||
| 488 | ; the file already exists, then the file is opened for writing. | ||
| 489 | ; The user will then write to the file be calling WRITE_LINE macro. The | ||
| 490 | ; data will be temperarily stored in a buffer to limit the actual number | ||
| 491 | ; of writes to the file. | ||
| 492 | ; | ||
| 493 | ;************************************************************************** | ||
| 494 | PUBLIC PREPARE_FILE_ROUTINE ;AN000; | ||
| 495 | PREPARE_FILE_ROUTINE PROC FAR ;AN000; | ||
| 496 | ; | ||
| 497 | ;********************************************************************** | ||
| 498 | ; Try to create the file | ||
| 499 | ;********************************************************************** | ||
| 500 | MOV DI, BX ;AN000; Get the address of the file name string | ||
| 501 | CALL POS_ZERO ;AN000; Make the ASCII-N string into an ASCII-Z | ||
| 502 | MOV DX, DI ;AN000; Get the address again | ||
| 503 | ADD DX, 2 ;AN000; Pass the length word and point to string | ||
| 504 | MOV N_WRITE_ERR_CODE, 0 ;AN000; Indicate there have been no errors yet | ||
| 505 | MOV INT_24_ERROR, 0 ;AN000; Zero the number of critical errors | ||
| 506 | MOV CX, 0 ;AN000; Attributes to give the file | ||
| 507 | MOV AH, 3CH ;AN000; Function for creating a file | ||
| 508 | DOSCALL ;AN000; Create the file | ||
| 509 | ;********************************************************************** | ||
| 510 | ; See if an error has occured. | ||
| 511 | ;********************************************************************** | ||
| 512 | .IF < C > ;AN000; Did the DOS fn. return an error? | ||
| 513 | .IF < AX EQ 5 > ;AN000; Was the error ACCESS DENIED? | ||
| 514 | MOV DX, BX ;AN000; Get the address of the string | ||
| 515 | MOV INT_24_ERROR, 0 ;AN000; Zero the number of critical errors | ||
| 516 | MOV AX, 3D01H ;AN000; DOS Fn. for opening a file | ||
| 517 | DOSCALL ;AN000; | ||
| 518 | .IF < C > ;AN000; Was there an error? | ||
| 519 | MOV N_WRITE_ERR_CODE, AX ;AN000; Save this error code | ||
| 520 | .ENDIF ;AN000; | ||
| 521 | .ELSE ;AN000; | ||
| 522 | MOV N_WRITE_ERR_CODE, AX ;AN000; | ||
| 523 | .ENDIF ;AN000; | ||
| 524 | .ENDIF ;AN000; | ||
| 525 | ; | ||
| 526 | .IF < N_WRITE_ERR_CODE NE 0 > ;AN000; | ||
| 527 | STC ;AN000; | ||
| 528 | .ELSE ;AN000; | ||
| 529 | MOV N_WRITE_HANDLE, AX ;AN000; | ||
| 530 | CLC ;AN000; | ||
| 531 | .ENDIF ;AN000; | ||
| 532 | ; | ||
| 533 | END_PREPARE_FILE: ;AN000; | ||
| 534 | ; | ||
| 535 | RET ;AN000; | ||
| 536 | ; | ||
| 537 | PREPARE_FILE_ROUTINE ENDP ;AN000; | ||
| 538 | ;************************************************************************** | ||
| 539 | ; | ||
| 540 | ; WRITE_LINE_ROUTINE: Write a line to the file being constructed. | ||
| 541 | ; | ||
| 542 | ; INPUT: | ||
| 543 | ; BX = The address of an ASCII-N string containing the line to write | ||
| 544 | ; to the file. | ||
| 545 | ; | ||
| 546 | ; OUTPUT: CY = 0: No error was encountered. | ||
| 547 | ; CY = 1: An error was encountered. | ||
| 548 | ; | ||
| 549 | ; OPERATION: The line that is passed, has a CR and a LF appended to the | ||
| 550 | ; end of the line. The data is then stored in a buffer. When the | ||
| 551 | ; buffer is full, the data is written to the disk. | ||
| 552 | ; | ||
| 553 | ;************************************************************************** | ||
| 554 | PUBLIC WRITE_LINE_ROUTINE ;AN000; | ||
| 555 | WRITE_LINE_ROUTINE PROC FAR ;AN000; | ||
| 556 | |||
| 557 | |||
| 558 | ; See if there has been an error so far ; | ||
| 559 | .IF < N_WRITE_ERR_CODE EQ 0 > ;AN000; Has there been an error? | ||
| 560 | MOV SI, BX ;AN000; No! Get the string address | ||
| 561 | ADD SI, WORD PTR [BX] ;AN000; Get the end of string address | ||
| 562 | ADD SI, 2 ;AN000; Adjust for the length word | ||
| 563 | MOV BYTE PTR [SI], E_CR ;AN000; Append a carrage return to the string | ||
| 564 | MOV BYTE PTR [SI+1], E_LF ;AN000; Append a line feed to the string | ||
| 565 | MOV CX, WORD PTR [BX] ;AN000; Get the length of the string | ||
| 566 | ADD CX, 2 ;AN000; Increase the string length by two | ||
| 567 | MOV DX, BX ;AN000; Get the address of the string | ||
| 568 | ADD DX, 2 ;AN000; Adjust pointer for length word | ||
| 569 | MOV BX, N_WRITE_HANDLE ;AN000; Handle for the already opened file | ||
| 570 | MOV INT_24_ERROR, 0 ;AN000; Zero the number of critical errors | ||
| 571 | MOV AH, 40H ;AN000; Function call for writing to a file | ||
| 572 | DOSCALL ;AN000; Write the line | ||
| 573 | .IF < C > ;AN000; Was there an error? | ||
| 574 | MOV N_WRITE_ERR_CODE, AX ;AN000; Yes! Save the error code | ||
| 575 | .ENDIF ;AN000; | ||
| 576 | .ENDIF ;AN000; | ||
| 577 | RET ;AN000; | ||
| 578 | ; | ||
| 579 | WRITE_LINE_ROUTINE ENDP ;AN000; | ||
| 580 | ;************************************************************************** | ||
| 581 | ; | ||
| 582 | ; SAVE_FILE_ROUTINE: Empty the data in the buffer being used to create | ||
| 583 | ; the file and then close the file. | ||
| 584 | ; | ||
| 585 | ; INPUT: | ||
| 586 | ; BX - The address of the string containing the file name. | ||
| 587 | ; | ||
| 588 | ; OUTPUT: CY = 0: No error was encountered. | ||
| 589 | ; CY = 1: An error was encountered. | ||
| 590 | ; AX will contain the code of the error which occured. | ||
| 591 | ; | ||
| 592 | ; OPERATION: The routine will check to see if there is any data left in | ||
| 593 | ; the buffer. If there is, the data is written to the file being | ||
| 594 | ; created. The file is then closed. If errors were encountered at | ||
| 595 | ; anytime during the create process, then the carry flag will be set | ||
| 596 | ; and the error code will be returned in AX. | ||
| 597 | ; | ||
| 598 | ;************************************************************************** | ||
| 599 | PUBLIC SAVE_FILE_ROUTINE ;AN000; | ||
| 600 | SAVE_FILE_ROUTINE PROC FAR ;AN000; | ||
| 601 | ; | ||
| 602 | .IF < N_WRITE_ERR_CODE NE 0 > ;AN000; Has an error been encountered? | ||
| 603 | MOV DI, BX ;AN000; Yes! Erase the file. | ||
| 604 | CALL POS_ZERO ;AN000; Make string into an ASCII-Z string | ||
| 605 | MOV INT_24_ERROR, 0 ;AN000; Zero the number of critical errors | ||
| 606 | MOV DX, DI ;AN000; Get the address of the string | ||
| 607 | ADD DX, 2 ;AN000; Advance pointer past length word | ||
| 608 | MOV AH, 41H ;AN000; DOS function for erasing a file | ||
| 609 | DOSCALL ;AN000; Erase the file | ||
| 610 | .ELSE ;AN000; Otherwise, if no error. | ||
| 611 | MOV BX, N_WRITE_HANDLE ;AN000; Get the file handle | ||
| 612 | MOV INT_24_ERROR, 0 ;AN000; Zero the number of critical errors | ||
| 613 | MOV AH, 3EH ;AN000; DOS function for closing a file | ||
| 614 | DOSCALL ;AN000; Close the file | ||
| 615 | .IF < C > ;AN000; Error closing the file? | ||
| 616 | MOV N_WRITE_ERR_CODE, AX ;AN000; Yes! Save the error code | ||
| 617 | .ENDIF ;AN000; | ||
| 618 | .ENDIF ;AN000; | ||
| 619 | ; | ||
| 620 | MOV AX, N_WRITE_ERR_CODE ;AN000; Return the error code | ||
| 621 | .IF < N_WRITE_ERR_CODE NE 0 > ;AN000; Have errors been encountered? | ||
| 622 | STC ;AN000; Yes! Set the carry flag | ||
| 623 | .ELSE ;AN000; No! | ||
| 624 | CLC ;AN000; Clear the carry flag | ||
| 625 | .ENDIF ;AN000; | ||
| 626 | ; | ||
| 627 | RET ;AN000; | ||
| 628 | ; | ||
| 629 | SAVE_FILE_ROUTINE ENDP ;AN000; | ||
| 630 | ;**************************************************************************** | ||
| 631 | ; | ||
| 632 | ; EXEC_PROGRAM_ROUTINE: Loads another program into memory and begins | ||
| 633 | ; execution. | ||
| 634 | ; | ||
| 635 | ; INPUT: child = Name of the program to execute (ASCII-N format) | ||
| 636 | ; name_com = The command line to be passed to parm_block | ||
| 637 | ; parm_block = Parameter block for child program. | ||
| 638 | ; re_dir = Flag indicating whether to redirect the output or not. | ||
| 639 | ; = 1: Redirect the output. | ||
| 640 | ; = 0: Don't redirect the output. | ||
| 641 | ; | ||
| 642 | ; OUTPUT: CY = 0: Successful | ||
| 643 | ; CY = 1: Error - AX has the error code. | ||
| 644 | ; | ||
| 645 | ; OPERATION: The command line to be passed to the parameter block is | ||
| 646 | ; copied to the command buffer specified for the parameter block and | ||
| 647 | ; a carrage return is appended to the end of the buffer. (The | ||
| 648 | ; command line length can be zero. | ||
| 649 | ; | ||
| 650 | ; The segment offsets in the parameter block are defined and DOS | ||
| 651 | ; function call 29H is performed to set up the default FCB's. | ||
| 652 | ; | ||
| 653 | ; DOS function call 4Bh is performed to load and execute the | ||
| 654 | ; specified child program. The contents of SS and SP are destroyed | ||
| 655 | ; during the call, so they must be save and restored later. When the | ||
| 656 | ; parent program (SELECT) gets control, all available memory is | ||
| 657 | ; allocated to it. It is assumed that memory has been freed (Function | ||
| 658 | ; call 4Ah - FREE_MEM) before invoking this function. | ||
| 659 | ; | ||
| 660 | ;************************************************************************ | ||
| 661 | |||
| 662 | PUBLIC EXEC_PROGRAM_ROUTINE ;AN000; | ||
| 663 | EXEC_PROGRAM_ROUTINE PROC FAR ;AN000; | ||
| 664 | ; | ||
| 665 | ; | ||
| 666 | EX_CHILD EQU [BP]+12 ;AN000; Equates for temporary variables | ||
| 667 | EX_NAME_COM EQU [BP]+10 ;AN000; | ||
| 668 | EX_PARM_BLOCK EQU [BP]+8 ;AN000; | ||
| 669 | EX_RE_DIR EQU [BP]+6 ;AN000; | ||
| 670 | ; | ||
| 671 | MOV SUB_PROGRAM, TRUE ;AN000; | ||
| 672 | ; | ||
| 673 | PUSH BP ;AN000; Save base pointer | ||
| 674 | MOV BP, SP ;AN000; Set up pointer for temp. variables | ||
| 675 | ; | ||
| 676 | PUSH DS ;AN000; Save the segment registers | ||
| 677 | PUSH ES ;AN000; | ||
| 678 | ; | ||
| 679 | MOV AH,2FH ;AC000;JW | ||
| 680 | DOSCALL ;AC000;JW get DTA address | ||
| 681 | PUSH ES ;AC000;JW save DTA seg | ||
| 682 | PUSH BX ;AC000;JW save DTA off | ||
| 683 | ; | ||
| 684 | PUSH DS ;AN000; | ||
| 685 | POP ES ;AN000; Point ES to the current data segment | ||
| 686 | ; | ||
| 687 | .IF < <WORD PTR EX_RE_DIR> EQ EXEC_DIR > ;AN000; | ||
| 688 | MOV AH, 3EH ;AN000; Close Stdout | ||
| 689 | MOV BX, STDOUT ;AN000; | ||
| 690 | DOSCALL ;AN000; | ||
| 691 | MOV DX, OFFSET NULL_DEVICE ;AN000; Open the NULL device | ||
| 692 | MOV AX, 3D01H ;AN000; | ||
| 693 | DOSCALL ;AN000; | ||
| 694 | MOV AH, 3EH ;AN000; Close Stderr | ||
| 695 | MOV BX, STDERR ;AN000; | ||
| 696 | DOSCALL ;AN000; | ||
| 697 | MOV DX, OFFSET NULL_DEVICE ;AN000; Open the NULL device | ||
| 698 | MOV AX, 3D01H ;AN000; | ||
| 699 | DOSCALL ;AN000; | ||
| 700 | .ENDIF ;AN000; | ||
| 701 | ; | ||
| 702 | ; | ||
| 703 | MOV SI, EX_NAME_COM ;AN000; Get the address of the command line | ||
| 704 | MOV CX, WORD PTR [SI] ;AN000; Get the length of the command line | ||
| 705 | MOV BYTE PTR CMD_BUFF, CL ;AN000; Store the lenth of the string | ||
| 706 | MOV DI, OFFSET CMD_BUFF+1 ;AN000; Location to place the string | ||
| 707 | ADD SI, 2 ;AN000; Adjust pointer for length word | ||
| 708 | CLD ;AN000; Move in the forward direction | ||
| 709 | REP MOVSB ;AN000; Copy the string | ||
| 710 | MOV BYTE PTR [DI], 0DH ;AN000; Place a carriage return at the end. | ||
| 711 | ; | ||
| 712 | MOV DI, EX_CHILD ;AN000; Get the address of the program name string | ||
| 713 | CALL POS_ZERO ;AN000; Turn into an ASCII-Z string | ||
| 714 | MOV SI,EX_PARM_BLOCK ;AN000; Address of the parameters | ||
| 715 | MOV AH,62H ;AN000; DOS Function number for getting the PSP segment | ||
| 716 | DOSCALL ;AN000; Get the current PSP segment | ||
| 717 | ; | ||
| 718 | MOV [SI]+8, BX ;AN000; Store PSP segment in the parm block | ||
| 719 | MOV [SI]+12, BX ;AN000; These are the FCB segments | ||
| 720 | MOV AX, DATA ;AN000; Get the address of the data segment | ||
| 721 | MOV [SI]+4, AX ;AN000; Segment of the command line | ||
| 722 | ; | ||
| 723 | MOV ES, BX ;AN000; ES:DI points to the FCB to load | ||
| 724 | MOV DI, 5CH ;AN000; First FCB to load | ||
| 725 | MOV BX, SI ;AN000; Move the address of the parm block | ||
| 726 | MOV SI, [BX]+2 ;AN000; Get the address of the command line | ||
| 727 | INC SI ;AN000; Skip the length byte | ||
| 728 | MOV AX, 2900H ;AN000; DOS Function for parsing a command line | ||
| 729 | DOSCALL ;AN000; Parse the command line | ||
| 730 | MOV AX, 2900H ;AN000; | ||
| 731 | MOV DI, 6CH ;AN000; ES:DI points to the second FCB | ||
| 732 | DOSCALL ;AN000; Parse the second filename | ||
| 733 | ; | ||
| 734 | ;INT 4BH DESTROYS SS,SP ; | ||
| 735 | MOV WORD PTR SAVE_AREA, SP ;AN000; Save the stack segment and pointer | ||
| 736 | MOV WORD PTR SAVE_AREA[2], SS ;AN000; | ||
| 737 | ; | ||
| 738 | MOV FIRST_TRY,TRUE ;AN000;DT initialize variables | ||
| 739 | MOV EXEC_DEALLOC,FALSE ;AN000;DT | ||
| 740 | MOV EXEC_DEHELP,FALSE ;AN000;DT | ||
| 741 | ; | ||
| 742 | MOV INT_24_ERROR, 0 ;AN000; Zero the number of critical errors | ||
| 743 | PUSH DS ;AN000; Save the current data segment | ||
| 744 | POP ES ;AN000; Point ES to the current data segment | ||
| 745 | MOV DX, EX_CHILD ;AN000; Get the string with the name of the sub-program | ||
| 746 | ADD DX, 2 ;AN000; Adjust pointer passed length word | ||
| 747 | MOV AX,4B00H ;AN000; DOS Function number of executing a sub-program | ||
| 748 | PUSH BX ;AN000;DT | ||
| 749 | DOSCALL ;AN000; Fork to the sub-process | ||
| 750 | POP BX ;AN000;DT | ||
| 751 | .IF < c > ;AN000;DT | ||
| 752 | MOV EXEC_ERR,TRUE ;AN000;DT | ||
| 753 | .ELSE ;AN000;DT | ||
| 754 | MOV EXEC_ERR,FALSE ;AN000;DT | ||
| 755 | .ENDIF ;AN000;DT | ||
| 756 | ;RESTORE REGISTERS ; | ||
| 757 | MOV AX,DATA ;AN000; Restore the data register first | ||
| 758 | MOV DS,AX ;AN000; Load the data segment register | ||
| 759 | MOV ES,AX ;AN000; | ||
| 760 | CLI ;AN000; Turn off interrupts while setting SS | ||
| 761 | MOV SS,WORD PTR SAVE_AREA[2] ;AN000; Restore the stack segment and pointer | ||
| 762 | MOV SP,WORD PTR SAVE_AREA ;AN000; | ||
| 763 | STI ;AN000; Turn interrupts on again. | ||
| 764 | CALL FAR PTR HOOK_INT_24 ;AN000; | ||
| 765 | ; | ||
| 766 | .IF < <WORD PTR EX_RE_DIR> EQ EXEC_DIR > ;AN000; Redirect Stdout? | ||
| 767 | MOV AH, 3EH ;AN000; Close Stdout. | ||
| 768 | MOV BX, 1 ;AN000; | ||
| 769 | DOSCALL ;AN000; | ||
| 770 | MOV DX, OFFSET CON_DEVICE ;AN000; Open CON as stdout. | ||
| 771 | MOV AX, 3D01H ;AN000; | ||
| 772 | DOSCALL ;AN000; | ||
| 773 | MOV AH, 3EH ;AN000; Close Stderr. | ||
| 774 | MOV BX, 2 ;AN000; | ||
| 775 | DOSCALL ;AN000; | ||
| 776 | MOV DX, OFFSET CON_DEVICE ;AN000; Open CON as stdout. | ||
| 777 | MOV AX, 3D01H ;AN000; | ||
| 778 | DOSCALL ;AN000; | ||
| 779 | .ENDIF ;AN000; | ||
| 780 | ; | ||
| 781 | MOV AH,1AH ;AN000;JW | ||
| 782 | POP DX ;AN000;JW get old DTA off | ||
| 783 | POP DS ;AN000;JW get old DTA seg | ||
| 784 | DOSCALL ;AN000;JW restore the DTA address | ||
| 785 | ; | ||
| 786 | POP ES ;AN000; Restore all the registers. | ||
| 787 | POP DS ;AN000; | ||
| 788 | POP BP ;AN000; Restore the base pointer | ||
| 789 | ; | ||
| 790 | MOV AH, 4DH ;AN000; Get the return code from the sub-process | ||
| 791 | DOSCALL ;AN000; | ||
| 792 | .IF < AX NE 0 > or ;AN000; SAR;If not zero... | ||
| 793 | .IF < EXEC_ERR eq TRUE > ;AN000; SAR | ||
| 794 | .THEN ;AN000; SAR | ||
| 795 | MOV SUB_ERROR,AL ;AN000; | ||
| 796 | STC ;AN000; Indicate there was an error | ||
| 797 | .ELSE ;AN000; Otherwise... | ||
| 798 | MOV SUB_ERROR,0 ;AN000; | ||
| 799 | CLC ;AN000; No error. | ||
| 800 | .ENDIF ;AN000; | ||
| 801 | MOV SUB_PROGRAM, FALSE ;AN000; | ||
| 802 | MOV EXEC_FDISK, FALSE ;AN000;DT reset FDISK flag | ||
| 803 | ; | ||
| 804 | RET 8 ;AN000; Return, popping the parameters. | ||
| 805 | EXEC_PROGRAM_ROUTINE ENDP ;AN000; | ||
| 806 | ;************************************************************************ | ||
| 807 | ; | ||
| 808 | ; GET_CNTY_DEF_ROUTINE: Get country, keyboard and codepage for the | ||
| 809 | ; specified entry from the CTY_TABLE. | ||
| 810 | ; | ||
| 811 | ; INPUT: | ||
| 812 | ; BX = 1: Use CTY_TAB_A | ||
| 813 | ; = 2: Use CTY_TAB_B | ||
| 814 | ; AX = index into country list table | ||
| 815 | ; | ||
| 816 | ; OUTPUT: | ||
| 817 | ; N_COUNTRY = Country code | ||
| 818 | ; N_KYBD_VAL = 0: Keyboard code is not valid | ||
| 819 | ; = 1: Keyboard code is valid | ||
| 820 | ; S_KEYBOARD = Keyboard code (ASCII-N format) | ||
| 821 | ; N_CP_PRI = Primary code page | ||
| 822 | ; N_CP_SEC = Secondary code page | ||
| 823 | ; N_DESIGNATES = Number of disignates | ||
| 824 | ; N_CPSW = Cpsw status | ||
| 825 | ; N_CTY_RES = Reserved | ||
| 826 | ; | ||
| 827 | ; | ||
| 828 | ; OPERATION: The country code, keyboard, primary codepage and the | ||
| 829 | ; seondary codepage from the CTY_TABLE for the specified index is | ||
| 830 | ; returned as spedified above. | ||
| 831 | ; | ||
| 832 | ; Note: Index of the first item is the table is 1. | ||
| 833 | ; | ||
| 834 | ;**************************************************************************** | ||
| 835 | PUBLIC GET_CNTY_DEF_ROUTINE ;AN000; | ||
| 836 | GET_CNTY_DEF_ROUTINE PROC FAR ;AN000; | ||
| 837 | ; AX contains the search's start index | ||
| 838 | SUB AX, 1 ;AN000; Make the first index 0 | ||
| 839 | MOV DX, TYPE CTY_DEF ;AN000; There are 9 bytes per entry | ||
| 840 | MUL DX ;AN000; Calculate the starting offset | ||
| 841 | MOV SI, AX ;AN000; Move the address into an index reg | ||
| 842 | ; | ||
| 843 | .IF < BX EQ 1 > ;AN000; BX contains which table to search | ||
| 844 | ADD SI, OFFSET CTY_TAB_A_1 ;AN000; Use the first table | ||
| 845 | .ELSE ;AN000; | ||
| 846 | ADD SI, OFFSET CTY_TAB_B_1 ;AN000; Use the second table | ||
| 847 | .ENDIF ;AN000; | ||
| 848 | ; | ||
| 849 | COPY_WORD N_COUNTRY, [SI+0] ;AN000; Get the counrty code | ||
| 850 | COPY_BYTE N_KYBD_VAL, [SI+2] ;AN000; See if the keyboard is valid | ||
| 851 | MOV S_KEYBOARD, 2 ;AN000; Length of the keyboard code string | ||
| 852 | COPY_WORD S_KEYBOARD[2], [SI+3] ;AN000; Get the keyboard code string | ||
| 853 | COPY_WORD N_CP_PRI, [SI+5] ;AN000; Get the primary code page | ||
| 854 | COPY_WORD N_CP_SEC, [SI+7] ;AN000; Get the secondary code page | ||
| 855 | COPY_WORD N_DESIGNATES, [SI+9] ;AN000; Get the number of designates | ||
| 856 | COPY_WORD N_CPSW, [SI+11] ;AN000; Get the code page switching status | ||
| 857 | COPY_BYTE ALT_KYB_ID, [SI+13] ;AN000; Get default alternate keyboard | ||
| 858 | COPY_BYTE N_CTY_RES, [SI+14] ;AN000; A reserved byte | ||
| 859 | |||
| 860 | COPY_WORD I_KYBD_ALT,2 ;AC090;JW | ||
| 861 | RET ;AN000; | ||
| 862 | |||
| 863 | GET_CNTY_DEF_ROUTINE ENDP ;AN000; | ||
| 864 | ;**************************************************************************** | ||
| 865 | ; | ||
| 866 | ; GET_CNTY_INDEX_ROUTINE: Scan CTY_TABLE for the specified country code and | ||
| 867 | ; return index of country code into the table. | ||
| 868 | ; | ||
| 869 | ; INPUT: | ||
| 870 | ; CX = The country code | ||
| 871 | ; | ||
| 872 | ; OUTPUT: | ||
| 873 | ; DX = 1: Country code is in table CTY_TAB_A | ||
| 874 | ; = 2: Country code is in table CTY_TAB_B | ||
| 875 | ; BX = The index into the country list. | ||
| 876 | ; | ||
| 877 | ; OPERATION: The CTY_TABLE is scanned for the specified country code and | ||
| 878 | ; the index into the table is returned. | ||
| 879 | ; | ||
| 880 | ; Note: The index of the first item in the table is 1. | ||
| 881 | ; | ||
| 882 | ;************************************************************************ | ||
| 883 | PUBLIC GET_CNTY_INDEX_ROUTINE ;AN000; | ||
| 884 | GET_CNTY_INDEX_ROUTINE PROC FAR ;AN000; | ||
| 885 | ; | ||
| 886 | MOV DX, 1 ;AN000; Which table to search | ||
| 887 | MOV AH, 0 ;AN000; Clear the high byte | ||
| 888 | .WHILE < DX LE 2 > ;AN000; Search the TWO tables | ||
| 889 | .IF < DX EQ 1 > ;AN000; Are we searching the first table? | ||
| 890 | MOV SI, OFFSET CTY_TAB_A_1 ;AN000; Yes! Get the offset of the table | ||
| 891 | MOV AL, CTY_TAB_A ;AN000; Get the number of entries | ||
| 892 | .ELSE ;AN000; Otherwise... | ||
| 893 | MOV SI, OFFSET CTY_TAB_B_1 ;AN000; Get the offset of the second table | ||
| 894 | MOV AL, CTY_TAB_B ;AN000; Get the number of entries in this table | ||
| 895 | .ENDIF ;AN000; | ||
| 896 | MOV BX, 1 ;AN000; Index currently being scaned | ||
| 897 | ; | ||
| 898 | ; CX contains the country code. | ||
| 899 | .WHILE < <WORD PTR [SI]> NE CX> AND ;AN000; Search until this code is found | ||
| 900 | .WHILE < BX LE AX > ;AN000; And while there are still table entries | ||
| 901 | INC BX ;AN000; Increment the index into the table | ||
| 902 | ADD SI, TYPE CTY_DEF ;AN000; Point to the next table record | ||
| 903 | .ENDWHILE ;AN000; | ||
| 904 | ; | ||
| 905 | .IF < BX GT AX > ;AN000; Index is finished for this table | ||
| 906 | INC DX ;AN000; Examine the next table | ||
| 907 | .ELSE ;AN000; | ||
| 908 | .LEAVE ;AN000; Exit the while loop | ||
| 909 | .ENDIF ;AN000; | ||
| 910 | ; | ||
| 911 | .ENDWHILE ;AN000; | ||
| 912 | RET ;AN000; | ||
| 913 | GET_CNTY_INDEX_ROUTINE ENDP ;AN000; | ||
| 914 | ;**************************************************************************** | ||
| 915 | ; | ||
| 916 | ; GET_KYBD_INDEX_ROUTINE: Scan KYBD_TABLE for the specified keyboard code and | ||
| 917 | ; return index of keyboard code in the table and the | ||
| 918 | ; alternate keyboard indicator. | ||
| 919 | ; | ||
| 920 | ; INPUT: | ||
| 921 | ; DI = The offset of an ASCII-N string containing the keyboard code. | ||
| 922 | ; | ||
| 923 | ; OUTPUT: | ||
| 924 | ; DX = 1: Keyboard is in table KYBD_TAB_A | ||
| 925 | ; = 2: Keyboard is in table KYBD_TAB_B | ||
| 926 | ; BX = The index into keyboard table. | ||
| 927 | ; AL = 0: No alternate keyboard | ||
| 928 | ; = 1: Alternate keyboard present | ||
| 929 | ; | ||
| 930 | ; OPERATION: The KYBD_TABLE is scanned for the specifies keyboard code and | ||
| 931 | ; the index into the table is returned. | ||
| 932 | ; | ||
| 933 | ; Note: The index of the first item in the table is 1. | ||
| 934 | ; | ||
| 935 | ;************************************************************************ | ||
| 936 | PUBLIC GET_KYBD_INDEX_ROUTINE ;AN000; | ||
| 937 | GET_KYBD_INDEX_ROUTINE PROC FAR ;AN000; | ||
| 938 | ; | ||
| 939 | MOV BX, 0 ;AN000; Zero the table index | ||
| 940 | MOV DX, 1 ;AN000; Which table to search | ||
| 941 | MOV AH, 0 ;AN000; Clear high byte to use 16-bit value | ||
| 942 | .WHILE < DX LE 2 > ;AN000; | ||
| 943 | .IF < DX EQ 1 > ;AN000; | ||
| 944 | MOV SI, OFFSET KYBD_TAB_A_1 ;AN000; Get the offset of the table | ||
| 945 | MOV AL, KYBD_TAB_A ;AN000; Get the number of entries | ||
| 946 | .ELSE ;AN000; | ||
| 947 | MOV SI, OFFSET KYBD_TAB_B_1 ;AN000; Get the offset of the second table | ||
| 948 | MOV AL, KYBD_TAB_B ;AN000; Get the number of entries in this table | ||
| 949 | .ENDIF ;AN000; | ||
| 950 | MOV BX, 1 ;AN000; Index currently being scaned | ||
| 951 | ; | ||
| 952 | MOV CX, WORD PTR [DI+2] ;AN000; Get the keyboard code | ||
| 953 | .WHILE < <WORD PTR [SI]> NE CX> AND ;AN000; | ||
| 954 | .WHILE < BX LE AX > ;AN000; | ||
| 955 | INC BX ;AN000; | ||
| 956 | ADD SI, TYPE KYB_DEF ;AN000; | ||
| 957 | .ENDWHILE ;AN000; | ||
| 958 | ; | ||
| 959 | .IF < BX GT AX > ;AN000; Index is finished for this table | ||
| 960 | INC DX ;AN000; Examine the next table | ||
| 961 | .ELSE ;AN000; | ||
| 962 | MOV AL, BYTE PTR [SI+2] ;AN000; Get the alternate keyboard flag | ||
| 963 | .LEAVE ;AN000; Exit the while loop | ||
| 964 | .ENDIF ;AN000; | ||
| 965 | ; | ||
| 966 | .ENDWHILE ;AN000; | ||
| 967 | RET ;AN000; | ||
| 968 | ; | ||
| 969 | GET_KYBD_INDEX_ROUTINE ENDP ;AN000; | ||
| 970 | ;************************************************************************; | ||
| 971 | ; | ||
| 972 | ; GET_KYBD_ROUTINE: Get the keyboard code and the alternate keyboard | ||
| 973 | ; indicator from the KYBD_TABLE for the item specified by the index | ||
| 974 | ; into the keyboard table. | ||
| 975 | ; | ||
| 976 | ; INPUT: | ||
| 977 | ; CX = 1: Keyboard code is in table KYBD_TAB_A | ||
| 978 | ; = 2: Keyboard code is is table KYBD_TAB_B | ||
| 979 | ; AX = index into the keyboard table. | ||
| 980 | ; DI = Address of the keyboard code. (ASCII-N format) | ||
| 981 | ; | ||
| 982 | ; OUTPUT: | ||
| 983 | ; AL = 0: No alternate keyboard | ||
| 984 | ; = 1: Alternate keyboard present | ||
| 985 | ; | ||
| 986 | ; OPERATION: The keyboard code from the KYBD_TABLE for the specified | ||
| 987 | ; index item is returned. Also, the alternate keyboard present | ||
| 988 | ; variable is updated. | ||
| 989 | ; | ||
| 990 | ; Note: Index of the first item in the table is 1. | ||
| 991 | ; | ||
| 992 | ;**************************************************************************** | ||
| 993 | PUBLIC GET_KYBD_ROUTINE ;AN000; | ||
| 994 | GET_KYBD_ROUTINE PROC FAR ;AN000; | ||
| 995 | ; AX contins the search's start index | ||
| 996 | SUB AX, 1 ;AN000; Make the first index 0 | ||
| 997 | MOV DX, TYPE KYB_DEF ;AN000; There are 3 bytes per entry | ||
| 998 | MUL DX ;AN000; Calculate the offset into the table | ||
| 999 | MOV SI, AX ;AN000; Move the address into an index reg | ||
| 1000 | .IF < CX EQ 1> ;AN000; CX Contains which table to search | ||
| 1001 | ADD SI, OFFSET KYBD_TAB_A_1 ;AN000; | ||
| 1002 | .ELSE ;AN000; | ||
| 1003 | ADD SI, OFFSET KYBD_TAB_B_1 ;AN000; | ||
| 1004 | .ENDIF ;AN000; | ||
| 1005 | ; | ||
| 1006 | MOV WORD PTR [DI], 2 ;AN000; Length of the string | ||
| 1007 | COPY_WORD [DI+2], [SI] ;AN000; Get the keyboard name | ||
| 1008 | MOV AL, [SI+2] ;AN000; See if there is an alternate keyboard | ||
| 1009 | RET ;AN000; | ||
| 1010 | ; | ||
| 1011 | GET_KYBD_ROUTINE ENDP ;AN000; | ||
| 1012 | ;;************************************************************************ | ||
| 1013 | ;; | ||
| 1014 | ;; CHK_EX_MEM_ROUTINE: Check if the system supports expanded memory. | ||
| 1015 | ;; | ||
| 1016 | ;; INPUT: | ||
| 1017 | ;; None. | ||
| 1018 | ;; | ||
| 1019 | ;; OUTPUT: | ||
| 1020 | ;; SI = 0: Expanded memory is NOT supported. | ||
| 1021 | ;; = 1: Expanded memory is supported. | ||
| 1022 | ;; BX = 0: XMA card | ||
| 1023 | ;; = 1: MODEL 80 | ||
| 1024 | ;; | ||
| 1025 | ;; OPERATION: A call to the system services (INT 15H, AH = C0H) is performed | ||
| 1026 | ;; to get the system configuration parameters. (model byte). | ||
| 1027 | ;; | ||
| 1028 | ;; The Personal System/2 Model 80 (model byte = 0F8h) always support | ||
| 1029 | ;; expanded memory. | ||
| 1030 | ;; | ||
| 1031 | ;; The Personal System/2 Models 50 and 60 (model byte = 0FCh) support | ||
| 1032 | ;; expanded memory if the CATSKILL 2 is present. The CATSKILL 2 card has | ||
| 1033 | ;; the identity number of F7FEh. F7H is read through the port address | ||
| 1034 | ;; 101h and FEH is read through port 100H | ||
| 1035 | ;; | ||
| 1036 | ;; The PS2 50/60 also support expanded memory if the HOLSTER card is | ||
| 1037 | ;; is present (id = FEFEh). | ||
| 1038 | ;; | ||
| 1039 | ;; AT's (and some XT's ?) support expanded memory if the CATSKILL 1 | ||
| 1040 | ;; (XMA) card is present. | ||
| 1041 | ;; | ||
| 1042 | ;; All other models do not support expanded memory. | ||
| 1043 | ;; | ||
| 1044 | ;;************************************************************************ | ||
| 1045 | SLOT_SETUP EQU 08h ;AN000;Mask to put the desired adapter @RH2 | ||
| 1046 | CARD_ID_LO EQU 100H ;AN000;PS/2 Adapter card id low and @RH2 | ||
| 1047 | CARD_ID_HI EQU 101H ;AN000; high bytes - read only @RH2 | ||
| 1048 | ;Card IDs read from port 100,101 @RH2 | ||
| 1049 | XMAA_CARD_ID EQU 0FEF7h ;AN000; XMA/A Card ID @RH2 | ||
| 1050 | HLST_CARD_ID EQU 0FEFEh ;AN000; HOLSTER card id JW | ||
| 1051 | MODE_REG EQU 31A7H ;AN000; Mode register | ||
| 1052 | TTPOINTER EQU 31A0H ;AN000; Translate Table Pointer (word) | ||
| 1053 | ; | ||
| 1054 | NUM_OF_SLOTS EQU 8 ;AN000; | ||
| 1055 | ; | ||
| 1056 | PUBLIC CHK_EX_MEM_ROUTINE ;AN000; | ||
| 1057 | CHK_EX_MEM_ROUTINE PROC FAR ;AN000; | ||
| 1058 | ; | ||
| 1059 | PUSH ES ;AN000; | ||
| 1060 | MOV AH, 0C0H ;AN000; Function number to get the model byte | ||
| 1061 | INT 15H ;AN000; | ||
| 1062 | .IF < AH eq 80H > ;AN000;IF AH = 80H | ||
| 1063 | MOV SI, 0 ;AN000;then this is a PC or PCjr. No Expanded memory | ||
| 1064 | MOV BX, 0 ;AN000;JW not a model 80 | ||
| 1065 | .ELSE near ;AN000; | ||
| 1066 | .IF < AH ne 086H > ;AN000;If not an old XT or AT | ||
| 1067 | MOV AH, BYTE PTR ES:[BX]+2 ;AN000; Get the model byte | ||
| 1068 | MOV AL, BYTE PTR ES:[BX]+3 ;AN000; Get the sub-model byte | ||
| 1069 | .ENDIF ;AN000; | ||
| 1070 | .IF < AH eq 0F8H> ;AN000; Is this a model 80? | ||
| 1071 | MOV SI, 1 ;AN000; Yes! Expanded memory supported | ||
| 1072 | MOV BX, 1 ;AN000;JW | ||
| 1073 | .ELSEIF < AH eq 0FCH > and ;AN000; Is this a model 50 or 60? | ||
| 1074 | .IF < AL eq 04 > or ;AN000; | ||
| 1075 | .IF < AL eq 05 > ;AN000; | ||
| 1076 | ;------------------------------------- | ||
| 1077 | ; Search for XMA/A cards � | ||
| 1078 | ;------------------------------------- | ||
| 1079 | XOR CX,CX ;AN000;Check all slots starting at 0 @RH2 | ||
| 1080 | MOV BX,0 ;AN000;JW say not a model 80 | ||
| 1081 | .REPEAT ;AN000; | ||
| 1082 | ; | ||
| 1083 | MOV AL,CL ;AN000;Enable the specific slot by ORing @RH2 | ||
| 1084 | OR AL,SLOT_SETUP ;AN000; the slot (bits 0-2) with the @RH2 | ||
| 1085 | OUT 96H,AL ;AN000; setup flag (bit 3). @RH2 | ||
| 1086 | ; | ||
| 1087 | MOV DX,CARD_ID_LO ;AN000;Read the signature ID of the card @RH2 | ||
| 1088 | IN AL,DX ;AN000; @RH2 | ||
| 1089 | XCHG AL,AH ;AN000; @RH2 | ||
| 1090 | MOV DX,CARD_ID_HI ;AN000; @RH2 | ||
| 1091 | IN AL,DX ;AN000; @RH2 | ||
| 1092 | ; | ||
| 1093 | .IF < AX eq XMAA_CARD_ID > or ;AN000; | ||
| 1094 | .IF < AX eq HLST_CARD_ID > ;AN000;JW | ||
| 1095 | MOV SI, 1 ;AN000; Yes! Expanded memory supported | ||
| 1096 | .LEAVE ;AN000; | ||
| 1097 | .ENDIF ;AN000; | ||
| 1098 | ; | ||
| 1099 | .IF < CL eq NUM_OF_SLOTS > ;AN000; | ||
| 1100 | MOV SI, 0 ;AN000; No! Expanded memoory isn't supported | ||
| 1101 | .LEAVE ;AN000; | ||
| 1102 | .ENDIF ;AN000; | ||
| 1103 | ; | ||
| 1104 | INC CL ;AN000;Check next adapter slot @RH2 | ||
| 1105 | ; | ||
| 1106 | .UNTIL ;AN000; | ||
| 1107 | XOR AX,AX ;AN000;JW | ||
| 1108 | OUT 96H,AL ;AN000;JW Reset port to neutral state | ||
| 1109 | ; | ||
| 1110 | .ELSE ;AN000; AT or XT | ||
| 1111 | ;------------------------------------- | ||
| 1112 | ; Search for XMA cards � | ||
| 1113 | ;------------------------------------- | ||
| 1114 | MOV DX,MODE_REG ;AN000;SAVE CONTENTS OF MODE REG | ||
| 1115 | IN AL,DX ;AN000; | ||
| 1116 | PUSH AX ;AN000; | ||
| 1117 | ; | ||
| 1118 | MOV AX,0AA55H ;AN000;DATA PATTERN (IN REAL MODE) | ||
| 1119 | ;BE CERTAIN MODE REG GETS | ||
| 1120 | ;REAL MODE | ||
| 1121 | MOV DX,MODE_REG ;AN000;I/O TO MODE REG | ||
| 1122 | OUT DX,AL ;AN000;WRITE PATTERN | ||
| 1123 | MOV DX,TTPOINTER + 1 ;AN000;I/O TO TT POINTER (ODD ADDR) | ||
| 1124 | XCHG AL,AH ;AN000;CHRG BUS WITH INVERSE PATTERN | ||
| 1125 | OUT DX,AL ;AN000;WRITE IT | ||
| 1126 | MOV DX,MODE_REG ;AN000; | ||
| 1127 | IN AL,DX ;AN000;READ BACK MODE REG | ||
| 1128 | XOR AL,AH ;AN000; | ||
| 1129 | AND AL,0FH ;AN000;MASK OFF UNUSED BITS | ||
| 1130 | ;ZERO FLAG = 0 IF ERROR | ||
| 1131 | POP AX ;AN000; | ||
| 1132 | PUSHF ;AN000;SAVE FLAGS | ||
| 1133 | MOV DX,MODE_REG ;AN000; | ||
| 1134 | OUT DX,AL ;AN000;RESTORE MODE REG TO INITIAL STATE | ||
| 1135 | POPF ;AN000;RESTORE FLAGS | ||
| 1136 | .IF < z > ;AN000; | ||
| 1137 | MOV SI,1 ;AN000;XMA card present | ||
| 1138 | .ELSE ;AN000; | ||
| 1139 | MOV SI,0 ;AN000;no XMA card present | ||
| 1140 | .ENDIF ;AN000; | ||
| 1141 | MOV BX,0 ;AN000;not a model 80 | ||
| 1142 | .ENDIF ;AN000; | ||
| 1143 | .ENDIF ;AN000; | ||
| 1144 | POP ES ;AN000; | ||
| 1145 | RET ;AN000; | ||
| 1146 | CHK_EX_MEM_ROUTINE ENDP ;AN000; | ||
| 1147 | ;**************************************************************************** | ||
| 1148 | ; | ||
| 1149 | ; GET_PRINTER_PARAMS_ROUTINE: Get parameters for specified printer. | ||
| 1150 | ; | ||
| 1151 | ; INPUT: | ||
| 1152 | ; AX = The printer number. | ||
| 1153 | ; BX = The number of the port to retrieve the information on. | ||
| 1154 | ; If var_port = 0, the information that is returned is | ||
| 1155 | ; that which corresponds to var_prt. | ||
| 1156 | ; BX = 0 : Get the information on printer number VAR_PRT | ||
| 1157 | ; = 1 : Get the information for the printer attached to LPT1 | ||
| 1158 | ; = 2 : Get the information for the printer attached to LPT2 | ||
| 1159 | ; = 3 : Get the information for the printer attached to LPT3 | ||
| 1160 | ; = 4 : Get the information for the printer attached to COM1 | ||
| 1161 | ; = 5 : Get the information for the printer attached to COM2 | ||
| 1162 | ; = 6 : Get the information for the printer attached to COM3 | ||
| 1163 | ; = 7 : Get the information for the printer attached to COM4 | ||
| 1164 | ; | ||
| 1165 | ; OUTPUT: | ||
| 1166 | ; AX = 1: Printer information is valid | ||
| 1167 | ; = 0: Printer not valid: default values returned | ||
| 1168 | ; | ||
| 1169 | ; OPERATION: Printer information for the specified printer is returned. | ||
| 1170 | ; If the specified printer is not defined, default values will be | ||
| 1171 | ; returned. | ||
| 1172 | ; I_PRINTER = Index into printer list (16 bit variable) : default 1 | ||
| 1173 | ; N_PRINTER_TYPE = P: Parallel printer | ||
| 1174 | ; = S: Serial printer | ||
| 1175 | ; I_PORT = Port number (16 bit variable) : default 1 | ||
| 1176 | ; I_REDIRECT = Redirection port number (16 bit variable) : default 1 | ||
| 1177 | ; S_MODE_PARM = Mode parameters - ASCII-N format | ||
| 1178 | ; S_CP_DRIVER = Code page driver parameters - ASCII-N format | ||
| 1179 | ; S_CP_PREPARE = Code prepare parameters - ASCII-N format | ||
| 1180 | ; S_GRAPH_PARM = Graphics parameters - ASCII-N format | ||
| 1181 | ; | ||
| 1182 | ; The structures of printer information are searched for the one with | ||
| 1183 | ; the same number as specified by AX. If found, the information | ||
| 1184 | ; in that structure is returned in the variables listed above. | ||
| 1185 | ; | ||
| 1186 | ;**************************************************************************** | ||
| 1187 | PUBLIC GET_PRINTER_PARAMS_ROUTINE ;AN000; | ||
| 1188 | GET_PRINTER_PARAMS_ROUTINE PROC FAR ;AN000; | ||
| 1189 | |||
| 1190 | .IF < BX NE 0 > ;AN000; | ||
| 1191 | DEC BX ;AN000; | ||
| 1192 | MOV AX, TYPE PRINTER_DEF ;AN000; | ||
| 1193 | MUL BX ;AN000; | ||
| 1194 | MOV SI, AX ;AN000; | ||
| 1195 | .IF < PRINTER_TABLES[SI].PRINTER_DATA_VALID EQ 1 > ;AN000; | ||
| 1196 | JMP COPY_INFO ;AN000; | ||
| 1197 | .ELSE ;AN000; | ||
| 1198 | JMP RETURN_DEFAULTS ;AN000; | ||
| 1199 | .ENDIF ;AN000; | ||
| 1200 | .ELSE ;AN000; | ||
| 1201 | MOV SI, 0 ;AN000; Index into the printer table | ||
| 1202 | MOV BX, 1 ;AN000; Which structure is being searched | ||
| 1203 | .WHILE < BX BE 7 > ;AN000; Search the seven structures | ||
| 1204 | .IF < PRINTER_TABLES[SI].PRINTER_TAB_NUM EQ AX > AND ;AN000; Does the printer number match? | ||
| 1205 | .IF < PRINTER_TABLES[SI].PRINTER_DATA_VALID EQ 1 > ;AN000; And is this data valid? | ||
| 1206 | JMP COPY_INFO ;AN000; | ||
| 1207 | .ENDIF ;AN000; | ||
| 1208 | ADD SI, TYPE PRINTER_DEF ;AN000; Search the next structure | ||
| 1209 | INC BX ;AN000; | ||
| 1210 | .ENDWHILE ;AN000; | ||
| 1211 | RETURN_DEFAULTS: ;AN000; | ||
| 1212 | MOV I_PRINTER, 1 ;AN000; Yes! Return the default information | ||
| 1213 | MOV I_PORT, 1 ;AN000; | ||
| 1214 | MOV I_REDIRECT, 1 ;AN000; | ||
| 1215 | MOV S_MODE_PARM, 0 ;AN000; | ||
| 1216 | MOV S_CP_DRIVER, 0 ;AN000; | ||
| 1217 | MOV S_CP_PREPARE, 0 ;AN000; | ||
| 1218 | MOV S_GRAPH_PARM, 0 ;AN000; | ||
| 1219 | MOV AX, 0 ;AN000; Indicate that the default values are being returned | ||
| 1220 | JMP EXIT_GET_PARAMS ;AN000; | ||
| 1221 | .ENDIF ;AN000; | ||
| 1222 | |||
| 1223 | COPY_INFO: ;AN000; | ||
| 1224 | COPY_WORD I_PRINTER, PRINTER_TABLES[SI].PRINTER_INDEX ;AN000; Copy the data out of the structure | ||
| 1225 | COPY_BYTE N_PRINTER_TYPE, PRINTER_TABLES[SI].PRINTER_TYPE ;AN000; | ||
| 1226 | COPY_WORD I_PORT, PRINTER_TABLES[SI].PORT_NUMBER ;AN000; | ||
| 1227 | COPY_WORD I_REDIRECT, PRINTER_TABLES[SI].REDIRECTION_PORT ;AN000; | ||
| 1228 | PUSH SI ;AN000; | ||
| 1229 | COPY_STRING S_MODE_PARM, 40, PRINTER_TABLES[SI].MODE_PARMS ;AN000; | ||
| 1230 | POP SI ;AN000; | ||
| 1231 | PUSH SI ;AN000; | ||
| 1232 | COPY_STRING S_CP_DRIVER, 22, PRINTER_TABLES[SI].CODE_DRIVER ;AN000; | ||
| 1233 | POP SI ;AN000; | ||
| 1234 | PUSH SI ;AN000; | ||
| 1235 | COPY_STRING S_CP_PREPARE, 12, PRINTER_TABLES[SI].CODE_PREPARE ;AN000; | ||
| 1236 | POP SI ;AN000; | ||
| 1237 | PUSH SI ;AN000; | ||
| 1238 | COPY_STRING S_GRAPH_PARM, 20, PRINTER_TABLES[SI].GRAPHICS_PARMS ;AN000; | ||
| 1239 | POP SI ;AN000; | ||
| 1240 | MOV AX, 1 ;AN000; Return that the data is valid | ||
| 1241 | |||
| 1242 | EXIT_GET_PARAMS: ;AN000; | ||
| 1243 | RET ;AN000; | ||
| 1244 | ; | ||
| 1245 | GET_PRINTER_PARAMS_ROUTINE ENDP ;AN000; | ||
| 1246 | ;**************************************************************************** | ||
| 1247 | ; | ||
| 1248 | ; SAVE_PRINTER_PARAMS_ROUTINE: Save the printer information in the printer | ||
| 1249 | ; structures. | ||
| 1250 | ; | ||
| 1251 | ; INPUT: | ||
| 1252 | ; AX = The printer number. | ||
| 1253 | ; | ||
| 1254 | ; OUTPUT: | ||
| 1255 | ; None. | ||
| 1256 | ; | ||
| 1257 | ; OPERATION: Printer information for the specified printer is stored. | ||
| 1258 | ; I_PRINTER = Index into printer list (16 bit variable) : default 1 | ||
| 1259 | ; N_PRINTER_TYPE = P: Parallel printer | ||
| 1260 | ; = S: Serial printer | ||
| 1261 | ; I_PORT = Port number (16 bit variable) : default 1 | ||
| 1262 | ; I_REDIRECT = Redirection port number (16 bit variable) : default 1 | ||
| 1263 | ; S_MODE_PARM = Mode parameters - ASCII-N format | ||
| 1264 | ; S_CP_DRIVER = Code page driver parameters - ASCII-N format | ||
| 1265 | ; S_CP_PREPARE = Code prepare parameters - ASCII-N format | ||
| 1266 | ; S_GRAPH_PARM = Graphics parameters - ASCII-N format | ||
| 1267 | ; | ||
| 1268 | ; The information is stored in the structures according to the type | ||
| 1269 | ; and port number of this printer. The first three structures are for | ||
| 1270 | ; LPT1 - LPT3, while the next four are for COM1 - COM2. | ||
| 1271 | ; | ||
| 1272 | ;**************************************************************************** | ||
| 1273 | PUBLIC SAVE_PRINTER_PARAMS_ROUTINE ;AN000; | ||
| 1274 | SAVE_PRINTER_PARAMS_ROUTINE PROC FAR ;AN000; | ||
| 1275 | |||
| 1276 | PUSH AX ;AN000; Save the printer number | ||
| 1277 | MOV AX, TYPE PRINTER_DEF ;AN000; Get the size of each structure | ||
| 1278 | MOV SI, I_PORT ;AN000; Get the port number | ||
| 1279 | .IF < N_PRINTER_TYPE EQ 'S'> ;AN000; Is this a serial port? | ||
| 1280 | ADD SI, 3 ;AN000; Yes! Store in the later 4 structures | ||
| 1281 | .ENDIF ;AN000; | ||
| 1282 | DEC SI ;AN000; Make the first index a 0 | ||
| 1283 | MUL SI ;AN000; Calculate the address of the structure | ||
| 1284 | MOV BX, AX ;AN000; Put address into an index register | ||
| 1285 | COPY_WORD PRINTER_TABLES[BX].PRINTER_INDEX, I_PRINTER ;AN000; Copy the data into the structure | ||
| 1286 | COPY_BYTE PRINTER_TABLES[BX].PRINTER_TYPE, N_PRINTER_TYPE;AN000; | ||
| 1287 | COPY_WORD PRINTER_TABLES[BX].PORT_NUMBER, I_PORT ;AN000; | ||
| 1288 | COPY_WORD PRINTER_TABLES[BX].REDIRECTION_PORT, I_REDIRECT ;AN000; | ||
| 1289 | COPY_STRING PRINTER_TABLES[BX].MODE_PARMS, 40, S_MODE_PARM ;AC000;JW | ||
| 1290 | COPY_STRING PRINTER_TABLES[BX].CODE_DRIVER, 22, S_CP_DRIVER ;AN000; | ||
| 1291 | COPY_STRING PRINTER_TABLES[BX].CODE_PREPARE, 12, S_CP_PREPARE ;AN000; | ||
| 1292 | COPY_STRING PRINTER_TABLES[BX].GRAPHICS_PARMS, 20, S_GRAPH_PARM ;AN000; | ||
| 1293 | .IF <I_PORT EQ 1 > ;AN029; | ||
| 1294 | COPY_STRING S_GRAPHICS,M_GRAPHICS,S_GRAPH_PARM ;AN029; | ||
| 1295 | .ENDIF ;AN029; | ||
| 1296 | POP AX ;AN000; Restore the printer number | ||
| 1297 | MOV PRINTER_TABLES[BX].PRINTER_TAB_NUM, AX ;AN000; Save the number | ||
| 1298 | MOV PRINTER_TABLES[BX].PRINTER_DATA_VALID, 1 ;AN000; Indicate that the data is valid | ||
| 1299 | |||
| 1300 | MOV SI, 0 ;AN000; | ||
| 1301 | MOV CX, 1 ;AN000; | ||
| 1302 | .WHILE < CX BE 7 > ;AN000; | ||
| 1303 | .IF < PRINTER_TABLES[SI].PRINTER_TAB_NUM EQ AX > AND ;AN000; | ||
| 1304 | .IF < SI NE BX > ;AN000; | ||
| 1305 | MOV PRINTER_TABLES[SI].PRINTER_DATA_VALID, 0 ;AN000; | ||
| 1306 | .ENDIF ;AN000; | ||
| 1307 | ADD SI, TYPE PRINTER_DEF ;AN000; | ||
| 1308 | INC CX ;AN000; | ||
| 1309 | .ENDWHILE ;AN000; | ||
| 1310 | |||
| 1311 | RET ;AN000; | ||
| 1312 | |||
| 1313 | SAVE_PRINTER_PARAMS_ROUTINE ENDP ;AN000; | ||
| 1314 | ;**************************************************************************** | ||
| 1315 | ; | ||
| 1316 | ; DISPLAY_MESSAGE_ROUTINE: Call the message retriever to display a message. | ||
| 1317 | ; | ||
| 1318 | ; INPUT: | ||
| 1319 | ; AX = The number of the message to be displayed. (16 bit value) | ||
| 1320 | ; | ||
| 1321 | ; OUTPUT: | ||
| 1322 | ; If CY = 1, there was an error displaying the message. | ||
| 1323 | ; If CY = 0, there were no errors. | ||
| 1324 | ; | ||
| 1325 | ; OPERATION: | ||
| 1326 | ; | ||
| 1327 | ;**************************************************************************** | ||
| 1328 | PUBLIC DISPLAY_MESSAGE_ROUTINE ;AN000; | ||
| 1329 | DISPLAY_MESSAGE_ROUTINE PROC FAR ;AN000; AX already contains the message number | ||
| 1330 | MOV BX, -1 ;AN000; HANDLE -1 ==> USE ONLY DOS FUNCTION 1-12 | ||
| 1331 | MOV SI, 0 ;AN000; SUBSTITUTION LIST | ||
| 1332 | MOV CX, 0 ;AN000; SUBSTITUTION COUNT | ||
| 1333 | MOV DL, 00 ;AN000; DOS INT21H FUNCTION FOR INPUT 0==> NO INPUT | ||
| 1334 | MOV DI, 0 ;AN000; INPUT BUFFER IF DL = 0AH | ||
| 1335 | MOV DH, -1 ;AN000; MESSAGE CALL -1==> UTILITY MESSAGE | ||
| 1336 | CALL SYSDISPMSG ;AN000; | ||
| 1337 | RET ;AN000; | ||
| 1338 | DISPLAY_MESSAGE_ROUTINE ENDP ;AN000; | ||
| 1339 | |||
| 1340 | ;**************************************************************************** | ||
| 1341 | ; Procedure for hooking the INT_23_VECTOR into vector table | ||
| 1342 | ; INPUT: | ||
| 1343 | ; None. | ||
| 1344 | ; OUTPUT: | ||
| 1345 | ; None. | ||
| 1346 | ;**************************************************************************** | ||
| 1347 | PUBLIC HOOK_INT_23 ;AN074;SEH | ||
| 1348 | HOOK_INT_23 PROC FAR ;AN074;SEH | ||
| 1349 | |||
| 1350 | PUSH AX ;AN074;SEH | ||
| 1351 | PUSH BX ;AN074;SEH | ||
| 1352 | PUSH DX ;AN074;SEH | ||
| 1353 | PUSH ES ;AN074;SEH Save the segment registers. | ||
| 1354 | PUSH DS ;AN074;SEH | ||
| 1355 | PUSHF ;AN074;SEH | ||
| 1356 | ; | ||
| 1357 | MOV AL, 23H ;AN074;SEH Interrupt number to get the vector of | ||
| 1358 | MOV AH, 35H ;AN074;SEH DOS Function number for getting a vector | ||
| 1359 | DOSCALL ;AN074;SEH Get the interrupt vector | ||
| 1360 | MOV WORD PTR OLD_INT_23, BX ;AN074;SEH Save the old vactor offset | ||
| 1361 | MOV AX, ES ;AN074;SEH Get the old vector segment | ||
| 1362 | MOV WORD PTR OLD_INT_23[2], AX ;AN074;SEH Save the old vector segment | ||
| 1363 | PUSH DS ;AN074;SEH Save DS | ||
| 1364 | PUSH CS ;AN074;SEH Point DS to the current code segment | ||
| 1365 | POP DS ;AN074;SEH | ||
| 1366 | MOV DX, OFFSET INT_23_VECTOR ;AN074;SEH Load offset of the new vector | ||
| 1367 | MOV AL, 23H ;AN074;SEH Interrupt number to set | ||
| 1368 | MOV AH, 25H ;AN074;SEH DOS Fn. number for setting a vector | ||
| 1369 | DOSCALL ;AN074;SEH Set the vector | ||
| 1370 | POP DS ;AN074;SEH Restore data segment | ||
| 1371 | ; | ||
| 1372 | POPF ;AN074;SEH | ||
| 1373 | POP DS ;AN074;SEH Restore the registers | ||
| 1374 | POP ES ;AN074;SEH | ||
| 1375 | POP DX ;AN074;SEH | ||
| 1376 | POP BX ;AN074;SEH | ||
| 1377 | POP AX ;AN074;SEH | ||
| 1378 | ; | ||
| 1379 | RET ;AN074;SEH | ||
| 1380 | HOOK_INT_23 ENDP ;AN074;SEH | ||
| 1381 | |||
| 1382 | ;**************************************************************************** | ||
| 1383 | ; Procedure for restoring the old interrupt 23h vector. | ||
| 1384 | ; INPUT: | ||
| 1385 | ; None. | ||
| 1386 | ; OUTPUT: | ||
| 1387 | ; None. | ||
| 1388 | ;**************************************************************************** | ||
| 1389 | PUBLIC RESTORE_INT_23 ;AN074;SEH | ||
| 1390 | RESTORE_INT_23 PROC FAR ;AN074;SEH | ||
| 1391 | ; | ||
| 1392 | PUSHF ;AN074;SEH | ||
| 1393 | PUSH AX ;AN074;SEH | ||
| 1394 | PUSH DX ;AN074;SEH | ||
| 1395 | PUSH DS ;AN074;SEH Save the data segment | ||
| 1396 | ; | ||
| 1397 | PUSH DS ;AN074;SEH Save DS | ||
| 1398 | LDS DX, OLD_INT_23 ;AN074;SEH Load the address of the old vector | ||
| 1399 | MOV AH, 25H ;AN074;SEH DOS Fn. number for setting an interrupt vector | ||
| 1400 | MOV AL, 23H ;AN074;SEH Interrupt vector to set | ||
| 1401 | DOSCALL ;AN074;SEH Set the vector | ||
| 1402 | POP DS ;AN074;SEH Restore data segment | ||
| 1403 | ; | ||
| 1404 | POP DS ;AN074;SEH Restore the data segment | ||
| 1405 | POP DX ;AN074;SEH | ||
| 1406 | POP AX ;AN074;SEH | ||
| 1407 | POPF ;AN074;SEH | ||
| 1408 | ; | ||
| 1409 | RET ;AN074;SEH | ||
| 1410 | RESTORE_INT_23 ENDP ;AN074;SEH | ||
| 1411 | ;**************************************************************************** | ||
| 1412 | ; Procedure for hooking the INT_24_VECTOR into vector table | ||
| 1413 | ; INPUT: | ||
| 1414 | ; None. | ||
| 1415 | ; OUTPUT: | ||
| 1416 | ; None. | ||
| 1417 | ;**************************************************************************** | ||
| 1418 | PUBLIC HOOK_INT_24 ;AN000; | ||
| 1419 | HOOK_INT_24 PROC FAR ;AN000; | ||
| 1420 | |||
| 1421 | PUSH AX ;AN000; | ||
| 1422 | PUSH BX ;AN000; | ||
| 1423 | PUSH DX ;AN000; | ||
| 1424 | PUSH ES ;AN000; Save the segment registers. | ||
| 1425 | PUSH DS ;AN000; | ||
| 1426 | PUSHF ;AN000; | ||
| 1427 | |||
| 1428 | .IF < INT24_STATUS eq UNHOOKED > ;AN000; | ||
| 1429 | |||
| 1430 | MOV AL, 24H ;AN000; Interrupt number to get the vector of | ||
| 1431 | MOV AH, 35H ;AN000; DOS Function number for getting a vector | ||
| 1432 | DOSCALL ;AN000; Get the interrupt vector | ||
| 1433 | MOV WORD PTR OLD_INT_24, BX ;AN000; Save the old vactor offset | ||
| 1434 | MOV AX, ES ;AN000; Get the old vector segment | ||
| 1435 | MOV WORD PTR OLD_INT_24[2], AX ;AN000; Save the old vector segment | ||
| 1436 | PUSH DS ;AN000; Save DS | ||
| 1437 | PUSH CS ;AN000; Point DS to the current code segment | ||
| 1438 | POP DS ;AN000; | ||
| 1439 | MOV DX, OFFSET INT_24_VECTOR ;AN000; Load offset of the new vector | ||
| 1440 | MOV AL, 24H ;AN000; Interrupt number to set | ||
| 1441 | MOV AH, 25H ;AN000; DOS Fn. number for setting a vector | ||
| 1442 | DOSCALL ;AN000; Set the vector | ||
| 1443 | POP DS ;AN000; Restore data segment | ||
| 1444 | MOV INT24_STATUS,HOOKED ;AN000; | ||
| 1445 | |||
| 1446 | .ENDIF ;AN000; | ||
| 1447 | |||
| 1448 | POPF ;AN000; | ||
| 1449 | POP DS ;AN000; Restore the registers | ||
| 1450 | POP ES ;AN000; | ||
| 1451 | POP DX ;AN000; | ||
| 1452 | POP BX ;AN000; | ||
| 1453 | POP AX ;AN000; | ||
| 1454 | |||
| 1455 | RET ;AN000; | ||
| 1456 | HOOK_INT_24 ENDP ;AN000; | ||
| 1457 | |||
| 1458 | ;**************************************************************************** | ||
| 1459 | ; Procedure for restoring the old interrupt 24h vector. | ||
| 1460 | ; INPUT: | ||
| 1461 | ; None. | ||
| 1462 | ; OUTPUT: | ||
| 1463 | ; None. | ||
| 1464 | ;**************************************************************************** | ||
| 1465 | PUBLIC RESTORE_INT_24 ;AN000; | ||
| 1466 | RESTORE_INT_24 PROC FAR ;AN000; | ||
| 1467 | |||
| 1468 | PUSHF ;AN000; | ||
| 1469 | PUSH AX ;AN000; | ||
| 1470 | PUSH DX ;AN000; | ||
| 1471 | PUSH DS ;AN000; Save the data segment | ||
| 1472 | |||
| 1473 | .IF < INT24_STATUS eq HOOKED > ;AN000; | ||
| 1474 | |||
| 1475 | PUSH DS ;AN000; Save DS | ||
| 1476 | LDS DX, OLD_INT_24 ;AN000; Load the address of the old vector | ||
| 1477 | MOV AH, 25H ;AN000; DOS Fn. number for setting an interrupt vector | ||
| 1478 | MOV AL, 24H ;AN000; Interrupt vector to set | ||
| 1479 | DOSCALL ;AN000; Set the vector | ||
| 1480 | POP DS ;AN000; Restore data segment | ||
| 1481 | MOV INT24_STATUS,UNHOOKED ;AN000; | ||
| 1482 | |||
| 1483 | .ENDIF ;AN000; | ||
| 1484 | |||
| 1485 | POP DS ;AN000; Restore the data segment | ||
| 1486 | POP DX ;AN000; | ||
| 1487 | POP AX ;AN000; | ||
| 1488 | POPF ;AN000; | ||
| 1489 | |||
| 1490 | RET ;AN000; | ||
| 1491 | RESTORE_INT_24 ENDP ;AN000; | ||
| 1492 | ;**************************************************************************** | ||
| 1493 | ; Procedure for hooking the INT_2F_VECTOR into vector table | ||
| 1494 | ; INPUT: | ||
| 1495 | ; None. | ||
| 1496 | ; OUTPUT: | ||
| 1497 | ; None. | ||
| 1498 | ;**************************************************************************** | ||
| 1499 | PUBLIC HOOK_INT_2F ;AN000; | ||
| 1500 | PUBLIC RESTORE_INT_2F ;AN000; | ||
| 1501 | HOOK_INT_2F PROC FAR ;AN000; | ||
| 1502 | |||
| 1503 | PUSH AX ;AN000; | ||
| 1504 | PUSH BX ;AN000; | ||
| 1505 | PUSH DX ;AN000; | ||
| 1506 | PUSH ES ;AN000; Save the segment registers. | ||
| 1507 | PUSH DS ;AN000; | ||
| 1508 | MOV AL, 2FH ;AN000; Interrupt number to get the vector of | ||
| 1509 | MOV AH, 35H ;AN000; DOS Function number for getting a vector | ||
| 1510 | DOSCALL ;AN000; Get the interrupt vector | ||
| 1511 | MOV WORD PTR OLD_INT_2F, BX ;AN000; Save the old vactor offset | ||
| 1512 | MOV AX, ES ;AN000; Get the old vector segment | ||
| 1513 | MOV WORD PTR OLD_INT_2F[2], AX ;AN000; Save the old vector segment | ||
| 1514 | PUSH CS ;AN000; Point DS to the current code segment | ||
| 1515 | POP DS ;AN000; | ||
| 1516 | MOV DX, OFFSET INT_2F_VECTOR ;AN000; Load offset of the new vector | ||
| 1517 | MOV AL, 2FH ;AN000; Interrupt number to set | ||
| 1518 | MOV AH, 25H ;AN000; DOS Fn. number for setting a vector | ||
| 1519 | DOSCALL ;AN000; Set the vector | ||
| 1520 | POP DS ;AN000; Restore the registers | ||
| 1521 | POP ES ;AN000; | ||
| 1522 | POP DX ;AN000; | ||
| 1523 | POP BX ;AN000; | ||
| 1524 | POP AX ;AN000; | ||
| 1525 | |||
| 1526 | RET ;AN000; | ||
| 1527 | |||
| 1528 | HOOK_INT_2F ENDP ;AN000; | ||
| 1529 | ;**************************************************************************** | ||
| 1530 | ; Procedure for restoring the old interrupt 2Fh vector. | ||
| 1531 | ; INPUT: | ||
| 1532 | ; None. | ||
| 1533 | ; OUTPUT: | ||
| 1534 | ; None. | ||
| 1535 | ;**************************************************************************** | ||
| 1536 | RESTORE_INT_2F PROC FAR ;AN000; | ||
| 1537 | PUSHF ;AN000; | ||
| 1538 | PUSH AX ;AN000; | ||
| 1539 | PUSH DX ;AN000; | ||
| 1540 | PUSH DS ;AN000; Save the data segment | ||
| 1541 | LDS DX, OLD_INT_2F ;AN000; Load the address of the old vector | ||
| 1542 | MOV AH, 25H ;AN000; DOS Fn. number for setting an interrupt vector | ||
| 1543 | MOV AL, 2FH ;AN000; Interrupt vector to set | ||
| 1544 | DOSCALL ;AN000; Set the vector | ||
| 1545 | POP DS ;AN000; Restore the data segment | ||
| 1546 | POP DX ;AN000; | ||
| 1547 | POP AX ;AN000; | ||
| 1548 | POPF ;AN000; | ||
| 1549 | RET ;AN000; | ||
| 1550 | RESTORE_INT_2F ENDP ;AN000; | ||
| 1551 | ;**************************************************************************** | ||
| 1552 | ; Procedure for hooking the INT_2F_256KB into vector table | ||
| 1553 | ; INPUT: | ||
| 1554 | ; None. | ||
| 1555 | ; OUTPUT: | ||
| 1556 | ; None. | ||
| 1557 | ;**************************************************************************** | ||
| 1558 | PUBLIC HOOK_INT_2F_256KB ;AN000; | ||
| 1559 | HOOK_INT_2F_256KB PROC FAR ;AN000; | ||
| 1560 | |||
| 1561 | PUSH AX ;AN000; | ||
| 1562 | PUSH BX ;AN000; | ||
| 1563 | PUSH DX ;AN000; | ||
| 1564 | PUSH ES ;AN000; Save the segment registers. | ||
| 1565 | PUSH DS ;AN000; | ||
| 1566 | MOV AL, 2FH ;AN000; Interrupt number to get the vector of | ||
| 1567 | MOV AH, 35H ;AN000; DOS Function number for getting a vector | ||
| 1568 | DOSCALL ;AN000; Get the interrupt vector | ||
| 1569 | MOV WORD PTR OLD_INT_2F, BX ;AN000; Save the old vactor offset | ||
| 1570 | MOV AX, ES ;AN000; Get the old vector segment | ||
| 1571 | MOV WORD PTR OLD_INT_2F[2], AX ;AN000; Save the old vector segment | ||
| 1572 | PUSH CS ;AN000; Point DS to the current code segment | ||
| 1573 | POP DS ;AN000; | ||
| 1574 | MOV DX, OFFSET INT_2F_256KB ;AN000; Load offset of the new vector | ||
| 1575 | MOV AL, 2FH ;AN000; Interrupt number to set | ||
| 1576 | MOV AH, 25H ;AN000; DOS Fn. number for setting a vector | ||
| 1577 | DOSCALL ;AN000; Set the vector | ||
| 1578 | POP DS ;AN000; Restore the registers | ||
| 1579 | POP ES ;AN000; | ||
| 1580 | POP DX ;AN000; | ||
| 1581 | POP BX ;AN000; | ||
| 1582 | POP AX ;AN000; | ||
| 1583 | |||
| 1584 | RET ;AN000; | ||
| 1585 | |||
| 1586 | HOOK_INT_2F_256KB ENDP ;AN000; | ||
| 1587 | ;**************************************************************************** | ||
| 1588 | ; Procedure for hooking the INT_2F_FORMAT into vector table | ||
| 1589 | ; INPUT: | ||
| 1590 | ; None. | ||
| 1591 | ; OUTPUT: | ||
| 1592 | ; None. | ||
| 1593 | ;**************************************************************************** | ||
| 1594 | PUBLIC HOOK_INT_2F_FORMAT ;AN111;JW | ||
| 1595 | HOOK_INT_2F_FORMAT PROC FAR ;AN111;JW | ||
| 1596 | |||
| 1597 | PUSH AX ;AN111;JW | ||
| 1598 | PUSH BX ;AN111;JW | ||
| 1599 | PUSH DX ;AN111;JW | ||
| 1600 | PUSH ES ;AN111; Save the segment registers. JW | ||
| 1601 | PUSH DS ;AN111;JW | ||
| 1602 | MOV AL, 2FH ;AN111; Interrupt number to get the vector of JW | ||
| 1603 | MOV AH, 35H ;AN111; DOS Function number for getting a vector JW | ||
| 1604 | DOSCALL ;AN111; Get the interrupt vector JW | ||
| 1605 | MOV WORD PTR OLD_INT_2F, BX ;AN111; Save the old vactor offset JW | ||
| 1606 | MOV AX, ES ;AN111; Get the old vector segment JW | ||
| 1607 | MOV WORD PTR OLD_INT_2F[2], AX ;AN111; Save the old vector segment JW | ||
| 1608 | PUSH CS ;AN111; Point DS to the current code segment JW | ||
| 1609 | POP DS ; ;AN111;JW | ||
| 1610 | MOV DX, OFFSET INT_2F_FORMAT ;AN111; Load offset of the new vector JW | ||
| 1611 | MOV AL, 2FH ;AN111; Interrupt number to set JW | ||
| 1612 | MOV AH, 25H ;AN111; DOS Fn. number for setting a vector JW | ||
| 1613 | DOSCALL ;AN111; Set the vector JW | ||
| 1614 | POP DS ;AN111; Restore the registers JW | ||
| 1615 | POP ES ;AN111;JW | ||
| 1616 | POP DX ;AN111;JW | ||
| 1617 | POP BX ;AN111;JW | ||
| 1618 | POP AX ;AN111;JW | ||
| 1619 | ; | ||
| 1620 | RET ;AN111;JW | ||
| 1621 | ; | ||
| 1622 | HOOK_INT_2F_FORMAT ENDP ;AN111;JW | ||
| 1623 | ;**************************************************************************** | ||
| 1624 | |||
| 1625 | CODE_FAR ENDS ;AN000; | ||
| 1626 | END ;AN000; | ||