home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / comm / ykh121.zip / YKHSRC.ZIP / GOLD.ASM < prev    next >
Assembly Source File  |  1992-10-10  |  22KB  |  567 lines

  1.     PAGE    64,132
  2.     TITLE   GOLD key from NUMLOCK
  3.     NAME    GOLD
  4. ;
  5. ; This program maps the NUM LOCK key (scan code 45H) to F1 (scan code 3BH)
  6. ; for use with Kermit emulating a DEC VT100.
  7. ;
  8. ; Version 2.0 - March 1991
  9. ;       Additions:
  10. ;               SHIFT and NUM LOCK acts as normal NUM LOCK
  11. ;               ALT and NUM LOCK inverts current GOLD status
  12. ;               Fix for problem with some clone BIOSes
  13. ;               Fix non-detection of BIOS intercept support
  14. ;               Use INT 09H if interrupt intercept not available
  15. ;
  16. ; Bob Eager
  17. ;       rde@ukc.ac.uk           USENET
  18. ;       100016,2770             CompuServe
  19. ;       +44 227 367270          Telephone
  20. ;
  21. ; You may distribute this program freely as long as all of the files that
  22. ; make up the package (see the documentation file) are kept with it (including
  23. ; this source file) and you don't try to make money from it either by selling
  24. ; it directly or incorporating it into a product you sell.
  25. ;
  26. ; Values for exit status:
  27. ;
  28. ;       0       - success
  29. ;       1       - could not install program
  30. ;       2       - no BIOS support present
  31. ;       3       - unsupported DOS version (< 3.0)
  32. ;       4       - invalid parameter
  33. ;
  34. ; Constants
  35. ; ---------
  36. ;
  37.     CR      = 0DH                   ; Carriage return
  38.     LF      = 0AH                   ; Linefeed
  39.     TAB     = 09H                   ; Tab
  40. ;
  41.     ID      = 0DCH                  ; Multiplex ID
  42. ;
  43.     CSEG    SEGMENT BYTE PUBLIC 'CODE'
  44. ;
  45.     $BEGIN  EQU     $
  46. ;
  47.     ORG     0100H
  48. ;
  49.     ASSUME  CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG
  50. ;
  51.     SUBTTL  Data areas
  52.     PAGE+
  53. ;
  54. ; The following jump to the initialisation code also provides three bytes
  55. ; of storage, two of which are used later by the resident part of the code.
  56. ;
  57. BEGIN:  JMP     INIT                    ; jump to initialisation code
  58. ;
  59. ; Redefine storage for the above jump
  60. ;
  61.     ORG     BEGIN
  62. MBIT    EQU     THIS BYTE               ; Make/Break bit
  63.     ORG     BEGIN+1
  64. ONOFF   EQU     THIS BYTE               ; On/Off flag (0=off, initially on)
  65. ;
  66. ; Back to normal storage allocation
  67. ;
  68.     ORG     BEGIN+3
  69. ;
  70. ; The following three values may be changed if required. MPID is the multiplex
  71. ; ID, and will only need alteration if some other TSR is using the same value.
  72. ; Choose another at random until it works! NEWKEY is the scan code value for
  73. ; the key to replace NUM LOCK. MODE is used to force a particular operation
  74. ; mode; it is particularly useful when a BIOS says that it supports the
  75. ; keyboard intercept function, but doesn't.
  76. ;
  77. XXX     DW      0
  78. MPID    DB      0DCH                    ; 102H Multiplex ID ** DO NOT MOVE **
  79. NEWKEY  DB      03BH                    ; 103H Replacement key ** DO NOT MOVE **
  80. MODE    DB      0                       ; 104H Mode selector ** DO NOT MOVE **
  81.                     ;       00H = auto
  82.                     ;       01H = use INT 15H
  83.                     ;       02H = use INT 09H
  84. ;
  85. INTOFF  DW      ?                       ; Old interrupt vector offset
  86. INTSEG  DW      ?                       ; Old interrupt vector segment
  87. I2FOFF  DW      ?                       ; Old INT 2FH offset
  88. I2FSEG  DW      ?                       ; Old INT 2FH segment
  89. ;
  90.     SUBTTL  INT 2FH (multiplex) handler
  91.     PAGE+
  92. ;
  93. ; This INT 2FH handler is hooked into the MS-DOS multiplex interrupt.
  94. ;
  95. ;       Input parameters:
  96. ;
  97. ;               AH      = handler ID (MPID for this program)
  98. ;                         Calls with unrecognised handler IDs are passed on
  99. ;               AL      = function code
  100. ;                               00      - get installation status
  101. ;                               01      - get GOLD status
  102. ;                               02      - set GOLD status
  103. ;
  104. ;       Output parameters:
  105. ;
  106. ;               AL      = result
  107. ;                               Get installation status:
  108. ;                                       FFH     - Already installed
  109. ;                               Get GOLD status:
  110. ;                                       00H     - OFF
  111. ;                                       01H     - ON
  112. ;                               Set GOLD status:
  113. ;                                       00H     - OK
  114. ;
  115. I2FHAN  PROC    FAR
  116. ;
  117.     ASSUME  CS:CSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
  118. ;
  119.     CMP     AH,MPID                 ; for this program?
  120.     JE      I2FH10                  ; j if so
  121.     JMP     DWORD PTR I2FOFF        ; else use old handler
  122. ;
  123. I2FH10: OR      AL,AL                   ; AL=0, get installation status?
  124.     JNE     I2FH20                  ; j if not
  125.     MOV     AL,0FFH                 ; indicate already installed
  126.     IRET                            ; and return
  127. ;
  128. I2FH20: DEC     AL                      ; AL=1, get GOLD status?
  129.     JNE     I2FH30                  ; j if not
  130.     MOV     AL,ONOFF                ; get value
  131.     IRET                            ; and return
  132. ;
  133. I2FH30: DEC     AL                      ; AL=2, set GOLD status?
  134.     JNE     I2FH40                  ; j if not
  135.     MOV     ONOFF,DL                ; set new value, drop through
  136. ;
  137. I2FH40: IRET                            ; and return
  138. ;
  139. I2FHAN  ENDP
  140. ;
  141.     SUBTTL  INT 15H (system services) handler
  142.     PAGE+
  143. ;
  144. ; This INT 15H handler is hooked into the BIOS system services interrupt.
  145. ; It is used only if the keyboard interrupt intercept capability is available
  146. ; in the BIOS.
  147. ;
  148. ;       Input parameters:
  149. ;               AH      - function. Only 4FH (keyboard intercept) is handled;
  150. ;                         other values cause the action to be passed to the
  151. ;                         previous handler.
  152. ;               AL      - scan code for key just pressed
  153. ;
  154. ;       Output parameters:
  155. ;               AL      - input scan code, or mapped version of it.
  156. ;               CY      - set to indicate that keystroke is to be processed.
  157. ;               All other register contents are preserved.
  158. ;
  159.     ASSUME  CS:CSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
  160. ;
  161. I15HAN  PROC    FAR
  162. ;
  163.     CMP     AH,4FH                  ; keyboard intercept function?
  164.     JE      I15H10                  ; j if so
  165.     JMP     DWORD PTR INTOFF        ; else call old handler
  166. ;
  167. I15H10: PUSH ES
  168.         PUSH DI
  169.         PUSH AX
  170.  
  171.         MOV AH,AL
  172.         SHR AL,1
  173.         SHR AL,1
  174.         SHR AL,1
  175.         SHR AL,1
  176.         AND AH,0FH
  177.         ADD AL,'0'
  178.         ADD AH,'0'
  179.         CMP AL,'9'
  180.         JBE FOO1
  181.         ADD AL,7
  182. FOO1:
  183.         CMP AH,'9'
  184.         JBE FOO2
  185.         ADD AH,7
  186. FOO2:
  187.         MOV DI,0B800H
  188.         MOV ES,DI
  189.         XOR DI,DI
  190.         ADD DI,CS:XXX
  191.         ADD CS:XXX,4
  192.                 AND CS:XXX,127
  193.         MOV BYTE PTR ES:[DI  ],AL
  194.         MOV BYTE PTR ES:[DI+1],15
  195.         MOV BYTE PTR ES:[DI+2],AH
  196.         MOV BYTE PTR ES:[DI+3],15
  197.  
  198.         POP AX
  199.         POP DI
  200.         POP ES
  201. ;
  202. I15H60: STC                             ; make sure keystroke processed
  203.         RETF    2                       ; return, preserving flags
  204. ;
  205. I15HAN  ENDP
  206. ;
  207. I15LEN  =       $ - I15HAN              ; length of INT 15H handler
  208. ;
  209.     SUBTTL  INT 09H (keyboard interrupt) handler
  210.     PAGE+
  211. ;
  212. ; This INT 09H handler is hooked into the keyboard interrupt vector.
  213. ; It is used only if the keyboard interrupt intercept facility is not
  214. ; available in the BIOS, and is moved in memory so that the space occupied
  215. ; by the INT 15H handler is not wasted.
  216. ;
  217. ;       Input parameters:
  218. ;               No explicit inputs. Implicit input from the keyboard
  219. ;               hardware.
  220. ;
  221. ;       Output parameters:
  222. ;               No explicit outputs. Control is passed to the normal keyboard
  223. ;               interrupt handler unless the keystroke is to be modified or
  224. ;               absorbed. Modified keystrokes are placed into the BIOS input
  225. ;               buffer.
  226. ;               All registers are preserved.
  227. ;
  228. I09HAN  PROC    FAR
  229. ;
  230.     PUSH    AX                      ; save register
  231.     IN      AL,60H                  ; get next character from hardware
  232.     MOV     AH,AL                   ; copy scan code
  233.     AND     AH,80H                  ; isolate make/break bit
  234.     MOV     MBIT,AH                 ; save it
  235.     AND     AL,7FH                  ; mask out make/break bit
  236.     CMP     AL,45H                  ; NUM LOCK?
  237.     JE      I09H10                  ; j if so
  238.     JMP     I09H80                  ; else just pass on to original handler
  239. ;
  240. ; NUM LOCK has been pressed. Check for SHIFT (retain normal action).
  241. ;
  242. I09H10: PUSH    DS                      ; save segment
  243.     MOV     AX,40H                  ; BIOS data segment
  244.     MOV     DS,AX                   ; address BIOS data segment
  245.     MOV     AL,DS:[17H]             ; get keyboard flags
  246.     POP     DS                      ; recover segment
  247.     AND     AL,0FH                  ; mask out lock status
  248.     MOV     AH,AL                   ; take copy for later comparison
  249.     CMP     ONOFF,0                 ; is GOLD on?
  250.     JE      I09H20                  ; j if not - do nothing here
  251.     AND     AL,03H                  ; mask out ALT and CTRL status
  252.     JE      I09H20                  ; j if not shifted
  253.     CMP     AH,AL                   ; see if just SHIFT
  254.     JE      I09H80                  ; if so, treat as normal NUM LOCK call
  255. ;
  256. ; Check for ALT (invert GOLD status). This needs to work whether GOLD is
  257. ; ON or OFF.
  258. ;
  259. I09H20: MOV     AL,AH                   ; recover shift status bits
  260.     AND     AL,08H                  ; mask out CTRL and SHIFT status
  261.     JE      I09H30                  ; j if not ALT - pass through
  262.     CMP     AH,AL                   ; see if just ALT
  263.     JNE     I09H30                  ; j if not - pass through
  264.     TEST    MBIT,80H                ; make operation?
  265.     JNE     I09H70                  ; j if not - ignore
  266.     XOR     ONOFF,1                 ; flip GOLD ON/OFF flag
  267.     JMP     SHORT I09H70            ; absorb keystroke and exit
  268. ;
  269. I09H30: CMP     ONOFF,0                 ; is GOLD on?
  270.     JE      I09H80                  ; j if not - pass through
  271. ;
  272. I09H40: TEST    MBIT,80H                ; break code?
  273.     JNZ     I09H70                  ; j if so - ignore
  274.     PUSH    DS                      ; save segment
  275.     PUSH    SI                      ; save register
  276.     PUSH    BX                      ; save register
  277.     MOV     AX,40H                  ; BIOS data segment
  278.     MOV     DS,AX                   ; address it
  279.     MOV     BX,DS:[1CH]             ; get offset of next slot in buffer
  280.     MOV     SI,BX                   ; save for later
  281.     ADD     BX,2                    ; advance pointer
  282.     CMP     BX,DS:[82H]             ; time to wrap?
  283.     JNZ     I09H50                  ; j if not
  284.     MOV     BX,DS:[80H]             ; else do it
  285. ;
  286. I09H50: CMP     BX,DS:[1AH]             ; buffer is full?
  287.     JZ      I09H60                  ; j if so - discard character
  288.     MOV     AH,NEWKEY               ; set replacement scan code
  289.     XOR     AL,AL                   ; extended code
  290.     MOV     WORD PTR [SI],AX        ; set into buffer
  291.     MOV     DS:[1CH],BX             ; save updated buffer pointer
  292. ;
  293. I09H60: POP     BX                      ; recover register
  294.     POP     SI                      ; recover register
  295.     POP     DS                      ; recover segment
  296. ;
  297. ; Clear the keyboard port, acknowledging the character.
  298. ;
  299. I09H70: IN      AL,61H                  ; get control port
  300.     MOV     AH,AL                   ; copy for later reset
  301.     OR      AL,80H                  ; set bit to acknowledge
  302.     JMP     SHORT $+2               ; wait for settle
  303.     OUT     61H,AL                  ; do the acknowledge
  304.     JMP     SHORT $+2               ; wait for settle
  305.     MOV     AL,AH                   ; get original setting
  306.     OUT     61H,AL                  ; put it back
  307.     JMP     SHORT $+2               ; wait for settle
  308.     MOV     AL,20H                  ; End-Of-Interrupt
  309.     OUT     20H,AL                  ; send to interrupt controller
  310.     POP     AX                      ; recover register
  311.     IRET                            ; return without calling original
  312. ;
  313. I09H80: POP     AX                      ; recover register
  314.     JMP     DWORD PTR INTOFF        ; jump to original interrupt handler
  315. ;
  316. I09HAN  ENDP
  317. ;
  318. I09LEN  =       $ - I09HAN              ; length of INT 09H handler
  319. ;
  320.     SUBTTL  Initialisation code
  321.     PAGE+
  322. ;
  323. ; This is the program initialisation code. It is not present in the resident
  324. ; copy of the program.
  325. ;
  326.     ASSUME  CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG
  327. ;
  328. INIT:   MOV     ONOFF,1                 ; set initial value
  329. ;
  330. ; Select the operating mode
  331. ;
  332.     CMP     MODE,2                  ; force INT 09H to be used?
  333.     JE      INIT50                  ; j if so
  334.     PUSH    ES                      ; save ES
  335.     MOV     AH,0C0H                 ; see if keyboard intercept supported
  336.     INT     15H                     ; get system configuration parameters
  337.     JNC     INIT10                  ; j if configuration call supported
  338.     POP     ES                      ; recover ES
  339.     JMP     SHORT INIT20            ; try for INT 09H mode
  340. ;
  341. INIT10: TEST    BYTE PTR ES:[BX+5],10H  ; see if intercept flag set
  342.     POP     ES                      ; recover ES
  343.     JNE     INIT30                  ; j if intercept supported - use it
  344. ;
  345. INIT20: CMP     MODE,1                  ; force INT 15H mode?
  346.     JNE     INIT40                  ; j if not - use INT 09H mode
  347.     LEA     DX,MES0                 ; 'Sorry - this machine does not...'
  348.     MOV     AH,9                    ; output message
  349.     INT     21H                     ; do it
  350.     MOV     AX,4C02H                ; exit with error status
  351.     INT     21H
  352. ;
  353. INIT30: MOV     MODE,1                  ; select INT 15H mode
  354.     JMP     SHORT INIT50            ; check DOS version now
  355. ;
  356. INIT40: MOV     MODE,2                  ; select INT 09H mode
  357. ;
  358. ; The INT 2FH code will work only on DOS 3.0 and above. See if it is OK
  359. ; to use it.
  360. ;
  361. INIT50: MOV     AX,3000H                ; get DOS version
  362.     INT     21H                     ; returns minor in AH, major in AL
  363.     CMP     AL,3                    ; see if 3 or greater
  364.     JGE     INIT60                  ; j if so - OK
  365.     LEA     DX,MES1                 ; 'Sorry - DOS 3.0 or above is...'
  366.     MOV     AH,9                    ; output message
  367.     INT     21H                     ; do it
  368.     MOV     AX,4C03H                ; exit with error status
  369.     INT     21H
  370. ;
  371. ; See if already installed
  372. ;
  373. INIT60: MOV     AH,MPID                 ; multiplex ID
  374.     XOR     AL,AL                   ; function 00H
  375.     INT     2FH                     ; call multiplex
  376.     OR      AL,AL                   ; see if OK to install (AL unchanged)
  377.     JZ      INIT70                  ; j if so
  378.     CMP     AL,0FFH                 ; already installed?
  379.     JE      INIT100                 ; j if so - skip installation
  380.     LEA     DX,MES2                 ; 'Cannot install program'
  381.     MOV     AH,9                    ; output message
  382.     INT     21H                     ; do it
  383.     MOV     AX,4C01H                ; exit with error status
  384.     INT     21H
  385. ;
  386. ; Program is not installed; install it now.
  387. ;
  388. INIT70: PUSH    ES                      ; save segment
  389.     MOV     AX,352FH                ; get old INT 2FH handler
  390.     INT     21H                     ; returns value in ES:BX
  391.     MOV     I2FOFF,BX               ; save offset
  392.     MOV     I2FSEG,ES               ; save segment
  393.     LEA     DX,I2FHAN               ; point to new INT 2FH handler
  394.     MOV     AX,252FH                ; set INT 2FH vector
  395.     INT     21H                     ; from DS:DX
  396. ;
  397. ; Perform installation conditional on the selected mode
  398. ;
  399.     CMP     MODE,1                  ; use INT 15H mode?
  400.     JNE     INIT80                  ; j if not - set up for INT 09H
  401. ;
  402. ; Use the INT 15H code, which uses the BIOS keyboard interrupt intercept
  403. ;
  404.     MOV     AX,3515H                ; get old INT 15H handler
  405.     INT     21H                     ; returns value in ES:BX
  406.     MOV     INTOFF,BX               ; save offset
  407.     MOV     INTSEG,ES               ; save segment
  408.     LEA     DX,I15HAN               ; point to new INT 15H handler
  409.     MOV     AX,2515H                ; set INT 15H vector
  410.     INT     21H                     ; from DS:DX
  411.     POP     ES                      ; recover segment
  412.     MOV     WORD PTR INTLEN,I15LEN  ; save interrupt routine length
  413.     JMP     SHORT INIT90            ; rejoin common code
  414. ;
  415. ; Use the INT 09H code, which uses the keyboard hardware interrupt
  416. ;
  417. INIT80: MOV     AX,3509H                ; get old INT 09H handler
  418.     INT     21H                     ; returns value in ES:BX
  419.     MOV     INTOFF,BX               ; save offset
  420.     MOV     INTSEG,ES               ; save segment
  421.     LEA     DX,I15HAN               ; point to new INT 09H handler
  422.                     ; (where it WILL be)
  423.     MOV     AX,2509H                ; set INT 09H vector
  424.     INT     21H                     ; from DS:DX
  425.     POP     ES                      ; recover segment
  426.     MOV     CX,I09LEN               ; get interrupt routine length
  427.     MOV     INTLEN,CX               ; save it
  428.     CLD                             ; autoincrement
  429.     MOV     SI,OFFSET I09HAN        ; get address of interrupt routine
  430.     MOV     DI,OFFSET I15HAN        ; where to move it
  431.     REP     MOVSB                   ; do so
  432. ;
  433. ; Complete installation
  434. ;
  435. INIT90: INC     BYTE PTR RESFLAG        ; remember to stay resident
  436. ;
  437. ; The program is now installed. Handle parameters.
  438. ;
  439. INIT100:CLD                             ; autoincrement
  440.     MOV     SI,81H                  ; offset of command tail
  441.     MOV     DI,81H                  ; put characters back in same place
  442. ;
  443. INIT110:LODSB                           ; get next command character
  444.     CMP     AL,CR                   ; end of command?
  445.     JE      INIT130                 ; j if so
  446.     CMP     AL,'a'                  ; check if lower case alphabetic
  447.     JL      INIT120                 ; j if not
  448.     CMP     AL,'z'                  ; check range
  449.     JG      INIT120                 ; j if not in range
  450.     SUB     AL,'a'-'A'              ; convert to upper case
  451. ;
  452. INIT120:STOSB                           ; return possibly modified character
  453.     JMP     INIT110                 ; keep scanning
  454. ;
  455. INIT130:MOV     SI,81H                  ; back to start of command tail
  456. ;
  457. INIT140:LODSB                           ; get next character
  458.     CMP     AL,' '                  ; space?
  459.     JE      INIT140                 ; j if so - ignore
  460.     CMP     AL,TAB                  ; tab?
  461.     JE      INIT140                 ; j if so - ignore
  462.     CMP     AL,CR                   ; end of parameters?
  463.     JE      INIT150                 ; j if so
  464.     DEC     SI                      ; point back to first non-space
  465.     MOV     BX,SI                   ; save pointer
  466.     MOV     CX,2                    ; check for ON
  467.     LEA     DI,ON                   ; 'ON'
  468.     REP     CMPSB                   ; matched?
  469.     JE      INIT190                 ; j if so
  470.     MOV     SI,BX                   ; recover pointer
  471.     MOV     CX,3                    ; check for OFF
  472.     LEA     DI,OFF                  ; 'OFF'
  473.     REP     CMPSB                   ; matched?
  474.     JE      INIT180                 ; j if so
  475.     LEA     DX,MES4                 ; 'Parameter must be ON or OFF'
  476.     MOV     AH,9                    ; output message
  477.     INT     21H                     ; do it
  478.     MOV     AX,4C01H                ; indicate error
  479.     INT     21H                     ; and exit
  480. ;
  481. ; No parameter given - just report status unless initial installation
  482. ;
  483. INIT150:LEA     DX,MES3                 ; 'GOLD is '
  484.     MOV     AH,9                    ; output message
  485.     INT     21H                     ; do it
  486.     MOV     AH,MPID                 ; multiplex ID
  487.     MOV     AL,1                    ; request status
  488.     INT     2FH                     ; returns AL=0 for OFF, AL=1 for ON
  489.     OR      AL,AL                   ; test value
  490.     JNZ     INIT160                 ; j if ON
  491.     LEA     DX,OFF                  ; 'OFF'
  492.     JMP     SHORT INIT170           ; join common code
  493. ;
  494. INIT160:LEA     DX,ON                   ; 'ON'
  495. ;
  496. INIT170:MOV     AH,9                    ; output message
  497.     INT     21H                     ; do it
  498.     JMP     SHORT INIT220           ; use common code
  499. ;
  500. INIT180:XOR     DL,DL                   ; clear flag
  501.     JMP     SHORT INIT200           ; jump to setting code
  502. ;
  503. INIT190:MOV     DL,1                    ; set flag
  504. ;
  505. ; AL now contains the required GOLD setting flag. Check that the rest of
  506. ; the command line is blank, then if all is OK set the flag appropriately.
  507. ;
  508. INIT200:LODSB                           ; get next character
  509.     CMP     AL,' '                  ; space?
  510.     JE      INIT200                 ; j if so - ignore
  511.     CMP     AL,TAB                  ; tab?
  512.     JE      INIT200                 ; j if so - ignore
  513.     CMP     AL,CR                   ; end of parameters?
  514.     JE      INIT210                 ; j if so
  515.     LEA     DX,MES5                 ; 'Invalid parameter'
  516.     MOV     AH,9                    ; output message
  517.     INT     21H                     ; do it
  518.     MOV     AX,4C04H                ; indicate error
  519.     INT     21H                     ; and exit
  520. ;
  521. ; The command line is OK. Set the GOLD flag.
  522. ;
  523. INIT210:MOV     AH,MPID                 ; multiplex ID
  524.     MOV     AL,2                    ; set flag from DL
  525.     INT     2FH                     ; set new flag value in resident copy
  526. ;
  527. ; If this is not the first load of GOLD, just exit.
  528. ;
  529. INIT220:TEST    BYTE PTR RESFLAG,1      ; make resident?
  530.     JNE     INIT230                 ; j if so
  531.     MOV     AX,4C00H                ; else just exit with success
  532.     INT     21H
  533. ;
  534. ; This is the first load of GOLD; terminate and stay resident
  535. ;
  536. INIT230:MOV     ES,ES:[2CH]             ; get environment segment
  537.     MOV     AH,49H                  ; free memory for it
  538.     INT     21H                     ; do it
  539.     MOV     DX,OFFSET I15HAN        ; size of common part
  540.     ADD     DX,INTLEN               ; add size of interrupt routine
  541.     ADD     DX,15                   ; round to next paragraph
  542.     MOV     CL,4                    ; amount to shift
  543.     SHR     DX,CL                   ; convert to paragraphs
  544.     MOV     AX,3100H                ; exit with success status
  545.     INT     21H                     ; and stay resident
  546. ;
  547. INTLEN  DW      ?                       ; Size of selected interrupt handler
  548. RESFLAG DB      0                       ; Set to 1 if to stay resident
  549. ;
  550. ON      DB      'ON',CR,LF,'$'
  551. OFF     DB      'OFF',CR,LF,'$'
  552. MES0    DB      'Sorry - this machine does not support the GOLD utility',CR,LF
  553.     DB      'if the interrupt intercept mode is selected'
  554.     DB      CR,LF,'$'
  555. MES1    DB      'Sorry - DOS 3.0 or above is required for the GOLD utility'
  556.     DB      CR,LF,'$'
  557. MES2    DB      'Sorry - cannot install the GOLD utility',CR,LF,'$'
  558. MES3    DB      'GOLD is $'
  559. MES4    DB      'Parameter must be ON or OFF',CR,LF,'$'
  560. MES5    DB      'Invalid parameter',CR,LF,'$'
  561. ;
  562. INFO    DB      '====GOLD version 2.0===='
  563. ;
  564. CSEG    ENDS
  565. ;
  566.     END     BEGIN
  567.