home *** CD-ROM | disk | FTP | other *** search
- Comment |
- First module in the replacement PrintScreen program. This module
- contains the code which intercepts Shift-PrtScr from the keyboard,
- determines the current video mode, printer address, and calls the
- appropriate routine in Listing 2. It also contains the installation
- code.
- Save as PRTSCR1.ASM
- Compile: MASM /Ml PRTSCR;
- or
- TASM /Ml PRTSCR
- |
-
- ;Remove the comment mark from the next line if you are using TASM
- ;TASM equ 1
-
- Ifdef TASM
- QUIRKS
- MASM51
- Endif
-
- .MODEL SMALL,C
-
- extrn textmode:near, lo_res:near, med_res:near, hi_res:near
- extrn cga_4:near, cga_6:near, ega_clr:near, ega_mono:near
-
- .STACK 100h
-
- .DATA
- db 200h dup (?)
- newstk equ $ ;Start of ISR stack
- base_port dw ?
-
- public vidmode, vidcols, vidrows, vidseg, vidoff, vidpage
- vidmode dw ? ;Variables describing
- vidcols dw ? ; current video state
- vidrows dw ?
- vidseg dw ?
- vidoff dw ?
- vidpage dw ?
-
- ; Call table for print-screen routines
- vidroutine dw offset textmode, offset textmode ;Modes 0,1
- dw offset textmode, offset textmode ;Modes 2,3
- dw offset lo_res, offset lo_res ;Modes 4,5
- dw offset med_res, offset textmode ;Modes 6,7
- dw 5 dup (offset none) ;Modes 8-0C
- dw offset lo_res, offset med_res ;Modes 0D,0E
- dw offset hi_res, offset hi_res ;Modes 0F,10
-
- Ifndef TASM
- public _acrtused
- _acrtused dw ? ;Keep MSC/QC from loading startup
- ;code.
- Endif
-
- signon db 13,10,"PC Resource's PrintScreen Program is installed."
- db 13,10,"You can now print graphics and text."
- db 13,10,"$"
-
- .CODE
- ;----------
- ; CS-based data locations
- ;----------
-
- old_sp dw ?
- old_ss dw ?
- start_flag db 0
-
- ;------------
- ; This becomes the new Int 05h
- ; and intercepts Shift-Prtscr keypresses.
- ; It must change to our local stack, save
- ; registers, and restore everything when
- ; we're done.
- ;------------
- new_int5 proc
- test cs:start_flag,-1 ;Already here?
- jnz int5_exit ;Yes -- just leave
- mov cs:start_flag,1 ;Show we've started
- push ax ;Save AX register for return
- cli ;No interrupts
- mov cs:[old_ss],ss ;Save the stack
- mov cs:[old_sp],sp
- mov ax,@data ;Move to our stack
- mov ss,ax
- mov sp,offset newstk
- sti ;Allow interrupts
-
- push bx ;Save all registers
- push cx
- push dx
- push bp
- push di
- push si
- push ds
- push es
-
- mov ax,@data ;Set DS to our data
- mov ds,ax
- call setup ;And start to work
-
- pop es ;Recover registers
- pop ds
- pop si
- pop di
- pop bp
- pop dx
- pop cx
- pop bx
-
- cli ;No interrupts during
- mov ss,cs:[old_ss] ; stack switch
- mov sp,cs:[old_sp]
- sti ;Allow interrupts
- pop ax ;Get original AX
- mov start_flag,0 ;Show that we're leaving
- int5_exit:
- iret ;We're done
- new_int5 endp
-
- ;------------
- ; Read video and printer info from BIOS RAM,
- ; then call the correct PrtScr routine.
- ;------------
- setup proc
- mov ax,40h ;ES ==> ROM BIOS data
- mov es,ax
- mov dx,es:[8] ;Get printer port addr.
- mov base_port,dx ;Save it
- or dx,dx ;Is a printer attached?
- jz exit ;No -- forget it
- inc dx ;DX ==> status port
- in al,dx ;Read status
- and al,1000B ;Test bit 3
- jz exit ;Error -- skip everything
- mov al,es:[49h] ;Get video mode
- cbw ;Change byte to word
- mov vidmode,ax ;Save mode
- cmp ax,10h ;Is it okay?
- ja exit ;VGA/MCGA special: exit
- mov ax,es:[4ah] ;Get display columns
- mov vidcols,ax ; and save
- mov al,es:[84h] ;Get display rows
- or al,al ;Is it 0?
- jnz @F ;No -- go
- mov al,24 ;Else assume default
- @@: cbw ;Make into word
- mov vidrows,ax ; and save it
- cmp vidmode,7 ;Monochrome mode?
- jne @F ;No -- go
- mov vidseg,0b000h ;Yes -- video base at B000
- jmp short setup_1 ;Skip other tests
- @@: jg @F ;Go if EGA graphics
- mov vidseg,0b800h ;Video base for CGA & color text
- jmp short setup_1
- @@: mov vidseg,0a000h ;Video base for EGA/VGA graphics
- setup_1:
- mov ax,es:[4eh] ;Video offset address
- mov vidoff,ax ; and save it
- mov bx,vidmode ;Get mode back
- add bx,bx ;* 2 for table offset
- add bx,offset vidroutine ;Add table address
- call [bx] ;Call routine
- exit: ret ;We're done
- setup endp
-
- ;------------
- ; Dummy routine if a PCjr/Tandy 1000
- ; or illegal video mode appears to be
- ; active
- ;------------
- none proc
- ret
- none endp
-
- ;------------
- ; Send a byte to the printer
- ; If the printer signals an error,
- ; simply return with the byte unsent.
- ; If the printer is busy, wait for it.
- ;------------
- prt_out proc near uses dx, char:word
- mov dx,base_port
- inc dx ;DX ==> status port
- @@: in al,dx ;Get status
- test al,1000b ;Error?
- jz exit ;Yes -- forget it
- test al,80h ;Busy?
- jz @B ;Yes -- wait til ready
- mov ax,char ;Get char to print
- dec dx ;DX ==> data port
- out dx,al ;Send character
- inc dx
- inc dx ;DX ==> output control port
- mov al,1101b ;Bit 0 is strobe bit
- out dx,al ;Turn strobe on
- dec al ;(now it's 1100b)
- out dx,al ;Turn strobe off
- exit: ret
- prt_out endp
-
- ;------------
- ; Send a value to a specific port
- ; on the EGA Graphics Controller chip
- ;------------
- gc_out proc near index:word, value:word
- mov dx,3ceh ;Graphics controller port
- mov ax,index ;Index in AL
- mov bx,value ;Value in BL
- mov ah,bl ;Value in AH
- out dx,ax ;Send it out
- ret
- gc_out endp
-
- ;------------
- ; Install the Print-Screen program in
- ; memory and exit. Note that this does
- ; not check to see if it is already installed.
- ; (You may want to add that).
- ;------------
-
- install proc near
- mov ax,@code ;Get code segment
- mov ds,ax ; into DS
- mov dx,offset new_int5 ;Get new Int 5 address
- mov ax,2505h ;Set as new Int 5
- int 21h
- mov ax,@data ;Now get data segment
- mov ds,ax ; into DS
- mov dx,offset signon ;DS:DX ==> sign-on message
- mov ah,9 ;Print a string
- int 21h ;Tell the world
- mov dx,0abh ;Paragraphs to keep (from MAP file)
- mov ax,3100h ;Terminate & stay resident
- int 21h
- install endp
- end install
-