summaryrefslogtreecommitdiff
path: root/v4.0/src/SELECT/ROUTINES.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/SELECT/ROUTINES.ASM')
-rw-r--r--v4.0/src/SELECT/ROUTINES.ASM1626
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;
10INCLUDE MAC_EQU.INC ;AN000;
11INCLUDE PAN-LIST.INC ;AN000;
12INCLUDE PANEL.MAC ;AN000;
13
14;**********************************************************************
15DATA SEGMENT BYTE PUBLIC 'DATA' ;AN000;
16
17
18NULl_DEVICE DB 'nul',0 ;AN000;
19CON_DEVICE DB 'con',0 ;AN000;
20
21SUB_PROGRAM DB 0 ;AN000;
22 PUBLIC EXEC_ERR ;AN000;
23EXEC_ERR DB 0 ;AN000;
24FIRST_TRY DB 0 ;AN000;DT
25INT24_STATUS DB 0 ;AN000;
26UNHOOKED EQU 0 ;AN000;
27HOOKED EQU 1 ;AN000;
28 PUBLIC EXEC_DEALLOC,EXEC_FDISK ;AN000;
29EXEC_DEALLOC DB 0 ;AN000;DT
30EXEC_FDISK DB 0 ;AN000;DT
31EXEC_DEHELP DB 0 ;AN000;DT
32
33DATA 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;**********************************************************************
57CODE_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;****************************************************************************
76PUBLIC APPEND_STRING_ROUTINE ;AN000;
77APPEND_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
103APPEND_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;****************************************************************************
120PUBLIC COPY_ROUTINE ;AN000;
121COPY_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.
137REP 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
145COPY_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;******************************************************************************
162PUBLIC PUSH_ROUTINE ;AN000;
163PUSH_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;
172PUSH_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;******************************************************************************
189PUBLIC POP_ROUTINE ;AN000;
190POP_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
202POP_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;****************************************************************************
224PUBLIC MAKE_DIR_PATHS_ROUTINE ;AN000;
225MAKE_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
243PROCESS_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;
249DELETING_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
254LENGTH_NOT_ZERO: ;AN000;
255REPNZ 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 '\'
262STRING_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;
266DELETING_DIR_2: ;AN000;
267 INC DI ;AN000; Adjust DI to point to the '\'
268 MOV WORD PTR [BX], CX ;AN000; Length left in string
269ADJUST_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;
292MAKE_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;
308CANNOT_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;
315DELETING_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;
330DIR_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;
339DELETING_DIR_4: ;AN000;
340 DEC DI ;AN000;
341 JMP PROCESS_NEXT_DIR ;AN000;
342
343ERROR_POP_EXIT: ;AN000;
344 POP CX ;AN000; Pop the extra value off the stack.
345ERROR_EXIT: ;AN000;
346 POP AX ;AN000; Pop the error message number
347 STC ;AN000;
348 JMP PATHS_DONE ;AN000;
349NORMAL_EXIT: ;AN000;
350 CLC ;AN000;
351
352PATHS_DONE: ;AN000;
353 MOV WORD PTR [BX], DX ;AN000; Restore the original path length
354
355 POP ES ;AN000;
356
357 RET ;AN000;
358
359MAKE_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;****************************************************************************
374PUBLIC POS_ZERO ;AN000;
375POS_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
390POS_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;****************************************************************************
406PUBLIC BEEP_ROUTINE ;AN000;
407BEEP_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;
421B_WAIT: MOV CX,2801 ;AN000; wait 10 milliseconds
422SPKR_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
429BEEP_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;****************************************************************************
446PUBLIC BIN_TO_CHAR_ROUTINE ;AN000;
447BIN_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
474BIN_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;**************************************************************************
494PUBLIC PREPARE_FILE_ROUTINE ;AN000;
495PREPARE_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 ;
533END_PREPARE_FILE: ;AN000;
534 ;
535 RET ;AN000;
536 ;
537PREPARE_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;**************************************************************************
554PUBLIC WRITE_LINE_ROUTINE ;AN000;
555WRITE_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 ;
579WRITE_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;**************************************************************************
599PUBLIC SAVE_FILE_ROUTINE ;AN000;
600SAVE_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 ;
629SAVE_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
662PUBLIC EXEC_PROGRAM_ROUTINE ;AN000;
663EXEC_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.
805EXEC_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;****************************************************************************
835PUBLIC GET_CNTY_DEF_ROUTINE ;AN000;
836GET_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
863GET_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;************************************************************************
883PUBLIC GET_CNTY_INDEX_ROUTINE ;AN000;
884GET_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;
913GET_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;************************************************************************
936PUBLIC GET_KYBD_INDEX_ROUTINE ;AN000;
937GET_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 ;
969GET_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;****************************************************************************
993PUBLIC GET_KYBD_ROUTINE ;AN000;
994GET_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 ;
1011GET_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;;************************************************************************
1045SLOT_SETUP EQU 08h ;AN000;Mask to put the desired adapter @RH2
1046CARD_ID_LO EQU 100H ;AN000;PS/2 Adapter card id low and @RH2
1047CARD_ID_HI EQU 101H ;AN000; high bytes - read only @RH2
1048 ;Card IDs read from port 100,101 @RH2
1049XMAA_CARD_ID EQU 0FEF7h ;AN000; XMA/A Card ID @RH2
1050HLST_CARD_ID EQU 0FEFEh ;AN000; HOLSTER card id JW
1051MODE_REG EQU 31A7H ;AN000; Mode register
1052TTPOINTER EQU 31A0H ;AN000; Translate Table Pointer (word)
1053 ;
1054NUM_OF_SLOTS EQU 8 ;AN000;
1055 ;
1056PUBLIC CHK_EX_MEM_ROUTINE ;AN000;
1057CHK_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;
1146CHK_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;****************************************************************************
1187PUBLIC GET_PRINTER_PARAMS_ROUTINE ;AN000;
1188GET_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;
1211RETURN_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
1223COPY_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
1242EXIT_GET_PARAMS: ;AN000;
1243 RET ;AN000;
1244 ;
1245GET_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;****************************************************************************
1273PUBLIC SAVE_PRINTER_PARAMS_ROUTINE ;AN000;
1274SAVE_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
1313SAVE_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;****************************************************************************
1328PUBLIC DISPLAY_MESSAGE_ROUTINE ;AN000;
1329DISPLAY_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;
1338DISPLAY_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;****************************************************************************
1347PUBLIC HOOK_INT_23 ;AN074;SEH
1348HOOK_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
1380HOOK_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;****************************************************************************
1389PUBLIC RESTORE_INT_23 ;AN074;SEH
1390RESTORE_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
1410RESTORE_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;****************************************************************************
1418PUBLIC HOOK_INT_24 ;AN000;
1419HOOK_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;
1456HOOK_INT_24 ENDP ;AN000;
1457
1458;****************************************************************************
1459; Procedure for restoring the old interrupt 24h vector.
1460; INPUT:
1461; None.
1462; OUTPUT:
1463; None.
1464;****************************************************************************
1465PUBLIC RESTORE_INT_24 ;AN000;
1466RESTORE_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;
1491RESTORE_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;****************************************************************************
1499PUBLIC HOOK_INT_2F ;AN000;
1500PUBLIC RESTORE_INT_2F ;AN000;
1501HOOK_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
1528HOOK_INT_2F ENDP ;AN000;
1529;****************************************************************************
1530; Procedure for restoring the old interrupt 2Fh vector.
1531; INPUT:
1532; None.
1533; OUTPUT:
1534; None.
1535;****************************************************************************
1536RESTORE_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;
1550RESTORE_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;****************************************************************************
1558PUBLIC HOOK_INT_2F_256KB ;AN000;
1559HOOK_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
1586HOOK_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;****************************************************************************
1594PUBLIC HOOK_INT_2F_FORMAT ;AN111;JW
1595HOOK_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 ;
1622HOOK_INT_2F_FORMAT ENDP ;AN111;JW
1623;****************************************************************************
1624
1625CODE_FAR ENDS ;AN000;
1626 END ;AN000;