home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / utils / kylock.zip / KYLOCK.ASM next >
Assembly Source File  |  1987-06-16  |  30KB  |  564 lines

  1. ;
  2.                  page 66,132
  3. ;
  4. ;KYLOCK.ASM for the IBM PC/XT & PCJR - 1987 by Ocean
  5. ;
  6. ;This is part 2 of a 2 part utilities set consisting of -----------------------
  7. ;SCRNOFF3.ASM & KYLOCK.ASM. -----------------------THEY MUST BE USED TOGETHER!
  8. ;                                                       -----------------------
  9. ;
  10. kb_data             equ 60h                     ;keyboard data port
  11. kb_ctrl             equ 61h                     ;keyboard control port
  12. k_key               equ 37                      ;scan code of k key
  13. o_key               equ 24                      ;scan code of o key
  14. del_key             equ 83                      ;scan code of Del key
  15. ins_key             equ 82                      ;scan code of Ins key
  16. alt_key             equ 8                       ;shift code for Alt key
  17. ctrl_key            equ 4                       ;shift code for Ctrl key
  18. eoi                 equ 20h                     ;end-of-interrupt signal
  19. int_ctrl_port       equ 20h                     ;8259 interrupt controller port
  20. ;
  21. code             segment para public 'code'
  22.                  assume cs:code
  23.                  org 0
  24. seg_org             equ $
  25. ;
  26. bios_data        segment at 40h                 ;bios data area
  27.                  org 063h
  28. addr_6845        dw ?                           ;define location that holds
  29.                                                 ;word address of active display
  30.                  org 065h
  31. crt_mode_set     db ?                           ;define location that holds
  32.                                                 ;byte loaded into pc active
  33.                                                 ;display port or pcjr's vga
  34. bios_data        ends
  35. ;
  36.                  org 0100h
  37. begin:           jmp initialize                 ;goto initialization routine
  38. ;
  39. adapter          db 0                           ;0 = EGA, 1 = CGA or MDA, and
  40.                                                 ;2 = PCJR
  41. pcjr_mode        db ?                           ;current setting of PCJR video
  42. pc_mode          db ?                           ;current setting of 6845 mode
  43.                                                 ;control register of the pc
  44. kylock_status    db 0                           ;interrupt routine status flag
  45. char_count       dw ?                           ;length of password
  46. hotky_val        db 00h,44h,2fh,2eh,2dh         ;hotkey make scan code table -
  47.                  db 20h,1eh,16h,11h             ;filler,F10,v,c,x,d,a,u, and w
  48. msr_address      dw ?                           ;address of mode select register
  49. pcjr_signature   db 0fdh                        ;PCJR BIOS signature
  50. ibm_signature    db 'IBM'                       ;EGA BIOS signature
  51. errmsg           db 13,10,'KYLOCK ALREADY LOADED!',13,10,'$'
  52. ;
  53. old_int_9h       label dword                    ;holding area for INT 9h vector
  54. int_9h_ptr       dw 2 dup (?)
  55. old_int_16h      label dword                    ;holding area for INT 16h vector
  56. int_16h_ptr      dw 2 dup (?)
  57. old_int_5h       label dword                    ;holding area, INT 5h vector
  58. int_5h_ptr       dw 2 dup (?)
  59. ;
  60. ;------------------------------------------------------------------------------
  61. ;All calls to INT 5 will henceforth be routed thru here.  On the PCJR, the
  62. ;Print Screen Function is processed by INT 48h (This interrupt translates the
  63. ;PCJR 62 key keyboard scan codes to be compatible with the 83 key keyboard of
  64. ;the PC and then INT 9 occurs.) which activates INT 5 before INT 9 is called.
  65. ;To insure that a copy of the screen cannot be printed out on the PCJR while
  66. ;the keyboard is supposedly locked, therefore, requires that the bios print
  67. ;screen service be intercepted and nulled while KYLOCK is active.
  68. ;------------------------------------------------------------------------------
  69. ;
  70. new_int_5h       proc near
  71.                  test kylock_status,01          ;kylock routine active?
  72.                  jnz print_not                  ;yes, block PRTSCR function
  73.                  jmp old_int_5h                 ;no, goto normal INT 5h handler
  74. print_not:       iret                           ;exit, nulling INT 5h
  75. new_int_5h       endp
  76. ;
  77. ;------------------------------------------------------------------------------
  78. ;All calls to INT 16h will henceforth be routed thru here.  If ah = 255 on
  79. ;entry, bh is set to 255 to signal the caller that this routine was indeed
  80. ;invoked.
  81. ;------------------------------------------------------------------------------
  82. new_int_16h      proc near
  83.                  cmp ah,255                     ;ah = 255?
  84.                  jne newint1                    ;no, then jump
  85.                  mov bh,ah                      ;yes, set bh to 255 and exit
  86.                  iret
  87. newint1:         jmp old_int_16h                ;goto normal 16h handler
  88. new_int_16h      endp
  89. ;
  90. ;------------------------------------------------------------------------------
  91. ;Execution comes here every time an interrupt 9 is generated from the keyboard.
  92. ;------------------------------------------------------------------------------
  93. ;
  94. kylock           proc near
  95.                  sti                            ;restore interrupts
  96.                  push ax                        ;save registers
  97.                  push bx
  98.                  push cx
  99.                  push dx
  100.                  push si
  101.                  push di
  102.                  push ds
  103.                  push es
  104.                  in al,kb_data                  ;read keypress (or break)
  105.                  cmp kylock_status,0            ;kylock routine active?
  106.                  je kylock0                     ;no, then check for Alt-O/Alt-K
  107. ;
  108. ;The kylock routine is already in progress.  Check for a press of one of the
  109. ;POPUP DESKSET "hot-keys" and block it out if it just occured.  (This routine
  110. ; may be omitted if this program is not used with POPUP DESKSET.)
  111. ;
  112.                  and al,7fh                     ;strip the break bit
  113.                  mov dl,al                      ;load keypress make scan code
  114.                  mov cx,8                       ;number of hotkeys to check
  115.                  lea bx,hotky_val               ;address of table of hotkeys
  116. next1:           mov ax,cx                      ;sequential pointer to hotkey
  117.                  xlat hotky_val                 ;load value of hotkey to al
  118.                  cmp dl,al                      ;keypress match this "hotkey"?
  119.                  jne loop                       ;no, how about next one?
  120.                  mov ah,2                       ;yes, get shift status
  121.                  int 16h                        ;
  122.                  cmp al,alt_key                 ;alt pressed?
  123.                  jne exit1                      ;no, goto old int 9 routine
  124.                  call kb_reset                  ;alt-"hotkey" pressed; reset kb
  125.                  jmp unlck1                     ;exit
  126. loop:            loop next1                     ;get next value from table
  127.                  mov al,dl                      ;no match - continue
  128. ;
  129. ;The kylock routine is already in progress.  Check for a press of Ctrl-Alt-Del
  130. ;or Ctrl-Alt-Ins (On the PCJR, this combination invokes diagnostic routines
  131. ;from which a Ctrl-Alt-Del can reset the machine.) and block it out if it just
  132. ;occurred.
  133. ;
  134.                  cmp al,ins_key                 ;was Ins Key pressed?
  135.                  je sh_stat                     ;get shift status
  136.                  cmp al,del_key                 ;was the Del key pressed?
  137.                  jne exit1                      ;no, goto old INT 9 routine
  138. sh_stat:         mov ah,2                       ;Int 16h - get shift status
  139.                  int 16h                        ;get status of shift keys
  140.                  and al,alt_key+ctrl_key        ;ctrl-alt pressed?
  141.                  cmp al,alt_key+ctrl_key
  142.                  jne exit1                      ;no, goto old int 9 routine
  143.                  call kb_reset                  ;ctrl-alt-del press - reset kb
  144.                  jmp unlck1                     ;exit
  145. ;                
  146. ;The kylock routine is not already active.  If Alt-O was pressed, toggle timer
  147. ;on/off, then block it out.
  148. ;
  149. kylock0:         cmp al,o_key                   ;o key pressed?
  150.                  jne strp_brk                   ;no, jump
  151.                  mov ah,2                       ;yes, get shift status
  152.                  int 16h
  153.                  test al,alt_key                ;Alt pressed when o key press?
  154.                  jnz toggle                     ;Alt-o key press --- toggle
  155.                  jmp strp_brk                   ;Alt-o key not pressed --- jump
  156. ;
  157. ;Int 16h is called here with ah set to 158.  Int 16h is a chained interrupt
  158. ;hooked into by SCRNOFF3.  When it is SCRNOFF3's turn in the chain, it tests
  159. ;the value of the register AH.  If it has been set to 158, then it toggles its
  160. ;timer on/off.
  161. ;
  162. toggle:          mov ah,158                     ;Place 158 into AH
  163.                  int 16h                        ;Call INT with AH set to 158
  164.                  call kb_reset                  ;reset kybrd, throw away alt-o
  165.                  jmp unlck1                     ;exit, skip normal kybrd route
  166. strp_brk:        and al,7fh                     ;strip the break bit
  167. ;
  168. ;The kylock routine is not already active.  See if Alt-K was pressed.
  169. ;
  170.                  cmp al,k_key                   ;is it the k key?
  171.                  jne exit                       ;no, goto old int 9 routine
  172.                  mov ah,2                       ;int 16h - get shift status
  173.                  int 16h
  174.                  test al,alt_key                ;is the alt key pressed?
  175.                  jne kylock2                    ;yes, goto kylock routine
  176. ;
  177. ;Exit routine restores registers and, if screen is blanked, enables the video
  178. ;& resets count before exiting thru normal keyboard interrupt handler.
  179. ;
  180. exit:            pop es                         ;pop registers off stack
  181.                  pop ds
  182.                  pop di
  183.                  pop si
  184.                  pop dx
  185.                  pop cx
  186.                  pop bx
  187.                  pop ax
  188. ;
  189. ;Call user interrupt 4dh (created by scrnoff3.com) to unblank screen if the
  190. ;timer within scrnoff3.com is 0.
  191. ;
  192.                  int 4dh                        ;user interrupt 4dh
  193.                  jmp old_int_9h                 ;exit to normal interrupt
  194.                                                 ;handler
  195. ;
  196. ;Exit1 routine restores registers before exiting thru normal keyboard interrupt
  197. ;handler and bypasses video enable and count reset routines since kylock is in
  198. ;progress.
  199. ;
  200. exit1:           pop es                         ;pop registers off stack
  201.                  pop ds
  202.                  pop di
  203.                  pop si
  204.                  pop dx
  205.                  pop cx
  206.                  pop bx
  207.                  pop ax
  208.                  jmp old_int_9h                 ;exit to normal interrupt
  209.                                                 ;handler
  210. ;
  211. ;Trigger keys are pressed.  Reset the keyboard, send an EOI signal to the 8259,
  212. ;and execute our kylock routine.
  213. ;
  214. kylock2:         call kb_reset                  ;reset keyboard and issue EOI
  215.                  mov kylock_status,1            ;set status byte
  216.                  push cs                        ;set ds and es to the code
  217.                                                 ;segment
  218.                  pop ds
  219.                  push cs
  220.                  pop es
  221.                  assume ds:code
  222. ;
  223. ;Begin kylock routine by disabling video and getting a password from the user.
  224. ;
  225.                  call video_disable             ;disable video display
  226.                  xor di,di                      ;point DI to start of PSP
  227.                  call get_password              ;get the password
  228.                  or cx,cx                       ;any characters input?
  229.                  je unlock                      ;no, exit this interrupt
  230.                  cmp al,27                      ;was input terminated with ESC
  231.                  je unlock                      ;yes, then exit
  232.                  mov char_count,cx              ;save length of password
  233. ;
  234. ;The password is now entered and the keyboard 'locked', awaiting input of a 
  235. ;matching password.  Accept input from the keyboard but continue to loop until
  236. ;the password is correctly re-entered.
  237. ;
  238. kylock3:         mov di,80h                     ;point DI to upper storage
  239.                  call get_password              ;get password
  240.                  cmp cx,char_count              ;same number of characters?
  241.                  jne kylock3                    ;no, then paswords don't match
  242.                  cmp al,27                      ;was input ended with ESC key?
  243.                  je kylock3                     ;yes, start input loop over
  244.                  xor si,si                      ;point SI to first password
  245.                  mov di,80h                     ;point DI to second password
  246.                  cld                            ;clear DF for string operations
  247.                  repe cmpsw                     ;compare the two passwords
  248.                  jne kylock3                    ;not equal, continue looping
  249. ;
  250. ;Exit kylock routine by clearing the status flag, enabling the video display,
  251. ;and executing an IRET instruction.
  252. ;
  253. unlock:          mov kylock_status,0            ;reset status byte
  254.                  push ax                        ;save ax & dx
  255.                  push dx
  256.                  call video_enable              ;re-enable video display
  257.                  pop dx                         ;restore dx & ax
  258.                  pop ax
  259. unlck1:          pop es                         ;restore register values
  260.                  pop ds
  261.                  pop di
  262.                  pop si
  263.                  pop dx
  264.                  pop cx
  265.                  pop bx
  266.                  pop ax
  267.                  iret                           ;exit kylock routine
  268. kylock           endp
  269. ;
  270. ;------------------------------------------------------------------------------
  271. ;VIDEO ENABLE and VIDEO DISABLE enable and disable the VIDEO output to the
  272. ;screen of the PCJR
  273. ;------------------------------------------------------------------------------
  274. ;
  275. video_disable    proc near                      ;disable the video display
  276.                  cmp adapter,0                  ;is video adapter an EGA?
  277.                  je ega_disable                 ;yes, then jump
  278.                  test adapter,2                 ;is computer a PCJR?
  279.                  jnz jr_disable                 ;yes, then jump
  280. ;
  281. ;Disable video of PC with CGA or MDA adapter.
  282. ;
  283.                  push ds                        ;save ds
  284.                  mov ax,bios_data               ;set es to bios data area
  285.                  mov ds,ax
  286.                  assume ds:bios_data
  287.                  mov al,crt_mode_set            ;get current value (dynamic) of
  288.                                                 ;6845 mode control register
  289.                  mov pc_mode,al                 ;save it
  290.                  mov ax,addr_6845               ;get active display address
  291.                  add ax,4                       ;add 4 to get MSR address
  292.                  mov msr_address,ax             ;save address
  293.                  mov al,0ah                     ;out 6845 index register...
  294.                  mov dx,03b4h                   ;points to 6845 data reg. 10
  295.                  out dx,al
  296.                  mov al,2bh                     ;value to turn off cursor
  297.                  mov dx,03b5h                   ;6845 data registers port
  298.                  out dx,al                      ;disable cursor
  299.                  mov dx,msr_address             ;6845 mode control register
  300.                  mov al,pc_mode                 ;get current value of 6845 mode
  301.                  and al,37h                     ;strip enable bit
  302.                  out dx,al                      ;disable video display
  303.                  pop ds                         ;restore ds
  304.                  ret
  305. ;
  306. ;Disable video of PC with an EGA card.
  307. ;
  308. ega_disable:     xor al,al                      ;zero al (clear bit 5)
  309.                  call set_ega                   ;disable EGA
  310.                  ret
  311. ;
  312. ;Disable video of PCJR.
  313. ;
  314. jr_disable:      push ds                        ;save ds register
  315.                  mov ax,bios_data               ;set es to bios data area
  316.                  mov ds,ax                      ;                              
  317.                  assume ds:bios_data            ;                              
  318.                  mov al,crt_mode_set            ;get current value (dynamic) of
  319.                                                 ;PCJR VGA mode control register
  320.                  mov pcjr_mode,al               ;store current value, VGA mode
  321.                  mov dx,03dah                   ;PCJR VGA I/O port
  322.                  in  al,dx                      ;addr/data f/f to proper state
  323.                  mov al,02h                     ;VGA border color register
  324.                  out dx,al                      ;set VGA to border color cont.
  325.                  mov al,00h                     ;color black
  326.                  out dx,al                      ;set border color black
  327.                  mov al,00                      ;VGA mode control 1 register
  328.                  out dx,al                      ;set VGA to mode control 1
  329.                  mov al,pcjr_mode               ;get current value of VGA mode
  330.                  and al,0f7h                    ;toggle enable/disable bit
  331.                  out dx,al                      ;disable video display
  332.                  pop ds                         ;restore ds register
  333.                  ret
  334. video_disable    endp
  335. ;
  336. video_enable     proc near                      ;enable the video display
  337.                  cmp adapter,0                  ;is video adapter an EGA?
  338.                  je ega_enable                  ;yes,then jump
  339.                  test adapter,2                 ;is the computer a PCJR?
  340.                  jnz jr_enable                  ;yes, then jump
  341. ;
  342. ;Enable video of PC with CGA or MDA adapter card.
  343. ;
  344.                  mov al,0ah                     ;out to 6845 index register...
  345.                  mov dx,03b4h                   ;points to 6845 data reg. 10
  346.                  out dx,al
  347.                  mov al,0bh                     ;value to turn cursor on
  348.                  mov dx,03b5h                   ;6845 data registers port
  349.                  out dx,al                      ;enable cursor
  350.                  mov dx,msr_address             ;6845 mode control register
  351.                  mov al,pc_mode                 ;get stored value 6845 mode
  352.                  out dx,al                      ;enable pc display
  353.                  ret
  354. ;
  355. ;Enable video of PC with an EGA adapter card.
  356. ;
  357. ega_enable:      mov al,20h                     ;set bit 5 of al
  358.                  call set_ega                   ;enable EGA video
  359.                  ret
  360. ;
  361. ;Enable video of PCJR.
  362. ;
  363. jr_enable:       mov dx,03dah                   ;set PCJR VGA address
  364.                  in al,dx                       ;addr/data f/f to proper state
  365.                  mov al,00h                     ;VGA mode control 1 register
  366.                  out dx,al                      ;set VGA to mode control 1
  367.                  mov al,pcjr_mode               ;get stored value VGA mode
  368.                  out dx,al                      ;enable PCJR video display ...
  369.                                                 ;border remains black
  370.                  ret
  371. video_enable     endp
  372. ;
  373. ;-----------------------------------------------------------------------------
  374. ;SET_EGA is called by VIDEO_ENABLE and VIDEO_DISABLE routines to selectively
  375. ;set or clear bit 5 of the EGA Attribute Address Register.
  376. ;Entry:  AL - value to OUT to Attribute Address Register
  377. ;-----------------------------------------------------------------------------
  378. ;
  379. set_ega          proc near
  380.                  push ax                        ;save AL
  381.                  mov dx,3bah                    ;reset monochrome flip-flop...
  382.                  in al,dx                       ;for write to Address Register
  383.                  mov dx,3dah                    ;reset color flip-flop
  384.                  in al,dx
  385.                  mov dx,3c0h                    ;set DX to Attr Addr Register
  386.                  pop ax                         ;retrieve entry value of AL
  387.                  out dx,al                      ;write value to register
  388.                  ret
  389. set_ega          endp
  390. ;
  391. ;------------------------------------------------------------------------------
  392. ;KB RESET subroutine resets the keyboard and issues an EOI to the 8259 PIC.
  393. ;------------------------------------------------------------------------------
  394. ;
  395. kb_reset         proc near
  396.                  test adapter,2                 ;Is this computer a PCJR?
  397.                  jnz jr_kbd                     ;yes,then jump
  398. ;
  399. ;Reset standard PC keyboard.
  400. ;
  401. std_kbd:         in al,kb_ctrl                  ;get current control port value
  402.                  mov ah,al                      ;save it
  403.                  or al,80h                      ;set the keyboard clear bit
  404.                  out kb_ctrl,al                 ;send reset value to port
  405.                  mov al,ah                      ;get the original value
  406.                  out kb_ctrl,al                 ;enable the keyboard
  407.                  jmp kbd1                       ;jump to disable interrupts
  408.                                                 ;and send EOI signal to 8259
  409. ;
  410. ;Reset PCJR keyboard.
  411. ;
  412. jr_kbd:          in al,0a0h                     ;yes, then read NMI mask
  413.                                                 ;register to clear PCJR
  414.                                                 ;keyboard NMI latch
  415. kbd1:            cli                            ;disable interrupts
  416.                  mov al,eoi                     ;get eoi value
  417.                  out int_ctrl_port,al           ;send eoi signal to the 8259
  418.                  sti                            ;enable interrupts
  419.                  ret                            ;return to caller
  420. kb_reset         endp
  421. ;
  422. ;------------------------------------------------------------------------------
  423. ;GET PASSWORD subroutine reads up to 50 characters entered from the keyboard
  424. ;and stores them in the designated buffer.  Backspace key is active as an
  425. ;editing key.
  426. ;Entry:  ES:DI - buffer address        | EXIT:  CX - character count
  427. ;------------------------------------------------------------------------------
  428. ;
  429. get_password     proc near
  430.                  cld                            ;clear DF for string operations
  431.                  xor cx,cx                      ;zero CX - initial char count
  432. getpas1:         mov ah,0                       ;INT 16h funct. - get keypress
  433.                  int 16h                        ;get character from keyboard
  434.                  cmp al,13                      ;ENTER key?
  435.                  je done                        ;yes, then exit
  436.                  cmp al,27                      ;ESC key?
  437.                  je done                        ;yes, then exit
  438.                  cmp al,8                       ;BACKSPACE key?
  439.                  je backspace                   ;yes,goto backspace routine
  440.                  cmp cx,40h                     ;is the buffer full?
  441.                  je buffer_full                 ;yes, then don't accept entry
  442.                  inc cx                         ;char entered - increment count
  443.                  stosw                          ;deposit character in buffer
  444.                  jmp getpas1                    ;return for more input
  445. backspace:       or cx,cx                       ;any characters to delete?
  446.                  je getpas1                     ;no,then goto input loop
  447.                  sub di,2                       ;decrement buffer pointer
  448.                  dec cx                         ;decrement character count
  449.                  jmp getpas1                    ;return to input loop
  450. buffer_full:     mov ah,14                      ;INT 10h function - Write TTY
  451.                  mov al,7                       ;ASCII code for beep
  452.                  int 10h                        ;sound the beep
  453.                  jmp getpas1                    ;and return for more input
  454. done:            ret                            ;return to calling routine
  455. get_password     endp
  456. ;
  457. ;------------------------------------------------------------------------------
  458. ;INITIALIZE routine checks to see if KYLOCK has already been loaded.  If so,
  459. ;execution aborts with an error message.  If it hasn't, then the value of 
  460. ;ADAPTER is set according to the type of display adapter present in the system
  461. ;and the vectors in low memory pointing to the INT 9h and 16h routines are set
  462. ;to point to our own newly installed code.
  463. ;------------------------------------------------------------------------------
  464. ;
  465. initialize       proc near
  466. ;
  467. ;See if KYLOCK has been previously loaded by calling INT 16h with AH set to
  468. ;255 and BH set to 0.  If BH comes back unchanged, then KYLOCK is NOT
  469. ;currently resident in memory; if BH = 255, then KYLOCK has been loaded.
  470. ;
  471.                  mov ah,255                     ;set AH and BH
  472.                  xor bh,bh
  473.                  int 16h                        ;call interrupt routine
  474.                  or bh,bh                       ;is BH = 0?
  475.                  je init1                       ;yes, then continue
  476.                  lea dx,errmsg                  ;no, print error message & exit
  477.                  mov ah,09h
  478.                  int 21h
  479.                  ret
  480. ;
  481. ;Check the computer's ID to see if its a PC or PCJR.
  482. ;
  483. init1:           mov ax,0f000h                  ;es to BIOS segment holding
  484.                  mov es,ax                      ;computer ID value
  485.                  mov al,byte ptr es:[0fffeh]    ;offset address and load to al
  486.                  sub al,0fch                    ;
  487.                  or al,al                       ;al = 0?
  488.                  jz pc                          ;AT, try the pc routine...
  489.                  dec al                         ;al = 1?
  490.                  jz pcjr                        ;yes, then computer is a PCJR
  491.                  dec al                         ;al = 2?
  492.                  jz pc                          ;XT, try the pc routine...
  493.                  dec al                         ;al = 3?
  494.                  jz pc                          ;PC
  495.                  jnz pc                         ;unidentified computer, try PC
  496.                  ret
  497. ;
  498. ;The computer is a PCJR.
  499. ;
  500. pcjr:            mov adapter,2                  ;set adapter to PCJR
  501.                  jmp init2                      ;jump to install program
  502. ;
  503. ;The computer is a PC.  Check for the presence of an Enhanced Graphics Adapter
  504. ;by looking for an 'IBM'signature in the EGA Bios area.
  505. ;
  506. pc:              mov ax,0c000h                  ;set ES to EGA BIOS segment
  507.                  mov es,ax
  508.                  mov di,1eh                     ;starting address of signature
  509.                  lea si,ibm_signature           ;point si to 'IBM' text
  510.                  mov cx,3                       ;three characters to check
  511.                  cld                            ;clear df
  512.                  repe cmpsb                     ;compare the three bytes
  513.                  je init2                       ;signature found - EGA present
  514. ;
  515. ;The computer is a PC, but the display adapter is not an EGA.  It must be
  516. ;either a CGA or an MDA.
  517. ;
  518.                  mov adapter,1                  ;set ADAPTER for CGA or MDA
  519. ;
  520. ;Save the current interrupt 16h vector and replace it with our own.
  521. ;
  522. init2:           mov ah,35h                     ;DOS function - get vector
  523.                  mov al,16h                     ;interrupt 16h
  524.                  int 21h                        ;get the vector
  525.                  mov int_16h_ptr,bx             ;save offset of vector
  526.                  mov int_16h_ptr[2],es          ;save segment of vector
  527.                  mov ah,25h                     ;DOS function - set vector
  528.                  mov al,16h                     ;interrupt 16h
  529.                  lea dx,new_int_16h             ;pointer to new routine
  530.                  int 21h                        ;set vector
  531. ;
  532. ;Now save the old interrupt 9 vector, replace it with the new one, and exit.
  533. ;
  534.                  mov ah,35h                     ;DOS function - get vector
  535.                  mov al,9h                      ;interrupt 9
  536.                  int 21h                        ;get vector
  537.                  mov int_9h_ptr,bx              ;save offset
  538.                  mov int_9h_ptr[2],es           ;save segment
  539.                  mov ah,25h                     ;DOS function - set vector
  540.                  mov al,9h                      ;interrupt 9
  541.                  lea dx,kylock                  ;point to our freeze routine
  542.                  int 21h                        ;set vector
  543. ;
  544. ;Save the current interrupt 5h vector and replace it with a new routine.
  545. ;
  546.                  mov ah,35h                     ;DOS function - get vector
  547.                  mov al,5h                      ;interrupt 5h
  548.                  int 21h                        ;get the vector
  549.                  mov int_5h_ptr,bx              ;save offset of vector
  550.                  mov int_5h_ptr[2],es           ;save segment of vector
  551.                  mov ah,25h                     ;DOS function - set vector
  552.                  mov al,5h                      ;interrupt 5h
  553.                  lea dx,new_int_5h              ;pointer to new routine
  554.                  int 21h                        ;set vector
  555.                  mov dx,(offset initialize - seg_org + 15) shr 4     ;...
  556.                                                 ;prepare DX for exit
  557.                  mov ah,31h                     ;terminate-but-stay-resident
  558.                  int 21h                        ;dos function call
  559. initialize       endp
  560. ;
  561. code             ends
  562.                  end begin
  563.                             
  564.