.286
code segment
assume cs:code,ds:code
org 100h

start:
  jmp main                      ;jump to main program

;resident procedures:

print proc near                 ;outputs ASCIIZ string to Pos ds:si on LPT1
print_loop:
  xor ah,ah                     ;function 0
  lodsb                         ;get characters
  or al,al                      ;finished, if 0 as conclusion
  je finished
  xor dx,dx                     ;output on LPT1
  int 17h
  jmp print_loop                ;next character
finished:
  ret
print endp

handler5 proc far               ;handler for interrupt 5
  push es                       ;store all used registers
  push ds
  pusha

  mov ax,cs                     ;load es with PSP segment
  mov es,ax
  mov ds,ax                     ;data segment in code segment also

  mov di,80h                    ;parameter block as buffer
  mov ah,1bh                    ;function 1bh
  xor bx,bx
  int 10h                       ;get video status

  cli

  mov al,byte ptr cs:[80h+22h]  ;get number screen lines
  cmp al,25d
  jbe normal                    ;if 25 screen lines, normal routine

  lea si,small_font          ;switch to 6 point font
  call print                    ;code to printer
  jmp output

normal:
  lea si,big_font           ;switch to 12 point font
  call print                    ;code to printer

output:
  sti
  pushf
  call dword ptr [oldint5]      ;enable normal output

  popa
  pop ds
  pop es
  iret
handler5 endp

oldint5: dd 0                   ;original vector
small_font:  db 1bh,'(s6V'   ;6 point height
                db 1bh,'&l12D'  ;12 lines per inch
                db 1bh,'(s12H'  ;12 characters per inch
                db 0
big_font:    db 1bh,'(s12V' ;12 point height
                db 1bh,'&l6D'   ;6 lines per inch
                db 1bh,'(s10H'  ;10 characters per inch
                db 0

last:

main proc near
  mov ax,3505h                  ;read out interrupt 5
  int 21h
  mov di,bx                     ;es:di points to installed handler
  mov si,bx                     ;ds:si points to handler of this program
  mov cx,4                      ;compare 8 bytes
  repe cmpsw
  jcxz uninstall           ;same ?, then uninstall

install:
  mov word ptr oldint5,bx       ;store old vector
  mov word ptr oldint5 + 2,es

  mov ax,2505h                  ;redirect interrupt 5
  lea dx,handler5               ;load offset, segment already in ds
  int 21h

  mov ax,ds:[2ch]               ;load environment segment
  mov es,ax                     ;to es
  mov ah,49h                    ;and release
  int 21h

  mov ah,9                      ;output installation message
  lea dx,installed
  int 21h
  lea dx,last                 ;remain resident until label last
  inc dx
  int 27h

uninstall:
  mov ah,9                      ;output uninstall message
  lea dx,uninstalled
  int 21h

  push ds
  lds dx,dword ptr es:[oldint5] ;load ds:dx with old vector
  mov ax,2505h                  ;set this
  int 21h
  pop ds

  mov ah,49h                    ;release resident memory
  int 21h
  int 20h                       ;and exit
main endp


installed:    db 'New Print Screen function installed',0dh,0ah,'$'
uninstalled:  db 'Print Screen uninstalled',0dh,0ah,'$'

code ends
end start
