home *** CD-ROM | disk | FTP | other *** search
- ; File......: ISPRINT.ASM
- ; Author....: Ted Means
- ; CIS ID....: 73067,3332
- ;
- ; This function is an original work by Ted Means and is placed in the
- ; public domain. I got the idea from Norm Mongeau, but the code is
- ; all mine.
- ;
- ; Modification history:
- ; ---------------------
- ;
- ; Rev 1.3 16 Jul 1993 00:00:18 GLENN
- ; Modified for compatibility in protected mode under ExoSpace. Should
- ; work in real mode as well.
- ;
- ; Rev 1.2 15 Aug 1991 23:07:56 GLENN
- ; Forest Belt proofread/edited/cleaned up doc
- ;
- ; Rev 1.1 14 Jun 1991 19:54:38 GLENN
- ; Minor edit to file header
- ;
- ; Rev 1.0 01 Apr 1991 01:03:26 GLENN
- ; Nanforum Toolkit
- ;
- ;
-
-
- ; $DOC$
- ; $FUNCNAME$
- ; FT_ISPRINT()
- ; $CATEGORY$
- ; DOS/BIOS
- ; $ONELINER$
- ; Check printer status
- ; $SYNTAX$
- ; FT_ISPRINT( [ <cDevice> ] ) -> lResult
- ; $ARGUMENTS$
- ; <cDevice> is optional and is the device to test (LPT2, COM1, etc.).
- ; If omitted, the function will default to the PRN device.
- ; $RETURNS$
- ; .T. if device is ready for output.
- ; .F. if one of the following conditions occurs:
- ; 1) The device is not ready.
- ; 2) The device does not exist.
- ; 3) DOS couldn't open the device for some reason
- ; (such as no file handles available).
- ; $DESCRIPTION$
- ; The Clipper IsPrinter() function is somewhat limited because it only
- ; works with LPT1. Furthermore, it talks directly to the hardware, so
- ; if you have redirected LPT1 via the DOS MODE command, the IsPrinter()
- ; function will return erroneous results.
- ;
- ; This function offers a better alternative. Instead of talking to the
- ; hardware, it issues a DOS call that checks to see if the device is
- ; ready or not. That gives DOS an opportunity to deal with any
- ; redirections, and since you pass the device name as a parameter, you
- ; can test any device, not just LPT1 (note that the function defaults
- ; to PRN if you fail to pass a valid parameter).
- ;
- ; The function also temporarily traps the DOS critical error handler so
- ; you don't get any nasty error messages if the device isn't ready. It
- ; restores the old critical error handler before exiting.
- ;
- ; Note that although this function is mainly designed for testing
- ; printers, you can also check to see if a drive is ready. Since DOS
- ; thinks the NUL device exists on every drive, you can pass a drive
- ; letter followed by NUL as a parameter. If DOS is able to open the
- ; NUL device, then the drive is ready, otherwise the door is open or
- ; something else is wrong.
- ;
- ; The source code is written to adhere to Turbo Assembler's IDEAL mode.
- ; To use another assembler, you will need to rearrange the PROC and
- ; SEGMENT directives, and also the ENDP and ENDS directives (a very
- ; minor task).
- ; $EXAMPLES$
- ; IF ! FT_ISPRINT()
- ; Qout( "PRN is not ready!" )
- ; ENDIF
- ;
- ; IF ! FT_ISPRINT( "COM2" )
- ; Qout( "Check the device on COM2. Something is wrong." )
- ; ENDIF
- ;
- ; IF ! FT_ISPRINT( "A:\NUL" )
- ; Qout( "Oops, better check drive A!" )
- ; ENDIF
- ; $END$
- ;
-
- IDEAL
- P286
-
- Public FT_ISPRINT
-
- Handle EQU Word Ptr BP - 2
- OpenFlag EQU Byte Ptr BP - 4
-
- Extrn __ParInfo:Far
- Extrn __ParC:Far
- Extrn __RetL:Far
- Extrn __bcopy:Far ; Internal!!!
-
- Extrn cpmiIsProtected:Far
- Extrn cpmiFarCallReal:Far
- Extrn cpmiAllocateDOSMem:Far
- Extrn cpmiFreeDOSMem:Far
- Extrn cpmiRealPtr:Far
-
- Struc CPUREGS
- AX DW ?
- BX DW ?
- CX DW ?
- DX DW ?
- SI DW ?
- DI DW ?
- BP DW ?
- DS DW ?
- ES DW ?
- Flags DW ?
- Ends CPUREGS
-
- Segment _NanFor Word Public "CODE"
- Assume CS:_NanFor
-
- Proc FT_IsPrint Far
-
- Push BP ; Save BP
- Mov BP,SP ; Set up stack reference
- Sub SP,4 ; Allocate room for locals
- Mov [OpenFlag],0 ; Initialize flag
-
- Mov AX,1 ; Specify first param
- Push AX ; Put param # on stack
- Call __ParInfo ; Get data type
- Inc SP ; Realign stack
- Inc SP ; Realign stack
- Test AX,1 ; Check for character
- JNZ @@Get ; If so, continue
- Mov BX,4 ; Default to PRN
- Jmp Short @@Status ; Bypass param retrieval
-
- @@Get: Mov AX,1 ; Specify first param
- Push AX ; Put param # on stack
- Call __ParC ; Retrieve parameter
- Inc SP ; Realign stack
- Inc SP ; Realign stack
-
- Push DS ; Save DS
- Mov DS,DX ; Get segment of device name
- Mov DX,AX ; Get offset of device name
- Mov AX,3D01h ; DOS service--open file or device
- Int 21h ; Call DOS
- Pop DS ; Restore DS
- Mov BX,AX ; Move handle to BX
- Mov AX,0 ; Default to FALSE
- CMC ; Toggle carry flag
- ADC [OpenFlag],0 ; Set open flag
- JNZ @@Status
- Jmp @@Done ; Bail if open failed
-
- @@Status: Mov [Handle],BX ; Store device's handle
-
- Call cpmiIsProtected ; Check CPU mode
- Or AX,AX ; AX clear?
- JZ @@Real ; If so, it's real mode
-
- Push DOSBytes ; Put seg size on stack
- Call cpmiAllocateDOSMem ; Allocate DOS memory
- Or AX,AX ; See if allocate failed
- JZ @@Done ; Return .F. if so
-
- Push DOSBytes ; Put byte count on stack
- Push Seg __ftIsPrint ; Put source ptr on stack
- Push Offset __ftIsPrint
- Push AX ; Put target ptr on stack
- Push 0
- Call __bcopy ; Copy proc to low memory
- Inc SP
- Inc SP
- Pop AX
- Add SP,6 ; Realign stack
-
- Push AX ; Save selector
-
- Mov ES,AX
- Mov [Word Ptr ES:ModCode1],Int24Ofs
- Mov [Word Ptr ES:ModCode2],ReadyOfs
- Mov [Word Ptr ES:ModCode3],ReadyOfs
- Mov [Word Ptr ES:ModCode4],ReadyOfs
-
- Push ES ; Put pointer on stack
- Push 0
- Call cpmiRealPtr ; Get real mode address
-
- Mov BX,[Handle] ; Get handle
-
- RegPtr EQU ( CPUREGS Ptr BP - Size CPUREGS )
-
- Enter Size CPUREGS,0 ; Allocate CPUREGS
- Mov [RegPtr.AX],BX ; Supply handle
- Push DX ; Supply function pointer
- Push AX
- LEA AX,[BP - Size CPUREGS] ; Get offset of CPUREGS
- Push SS
- Push AX
- Push SS
- Push AX
- Call cpmiFarCallReal ; Check printer status
- Mov AX,[RegPtr.AX]
- Leave ; Deallocate CPUREGS
-
- Pop BX ; Get selector back
- Push AX ; Save return value
- Push BX ; Put selector on stack
- Call cpmiFreeDOSMem ; Free low DOS memory
- Pop AX ; Get return value back
- Jmp Short @@Done
-
- @@Real: Mov AX,[Handle] ; Get handle
- Call __ftIsPrint ; Call status checker
-
- @@Done: Push AX ; Put status on stack
- Call __RetL ; Return status to Clipper app
-
- Cmp [OpenFlag],1 ; Need to close device?
- JNE @@Exit ; No, so go ahead and exit
- Mov AH,3Eh ; DOS service--close handle
- Mov BX,[Handle] ; Supply file handle
- Int 21h ; Call DOS
-
- @@Exit: Mov SP,BP ; Realign stack
- Pop BP ; Restore BP
- RetF ; Far return to Clipper app
- Endp FT_IsPrint
- Ends _NanFor
-
-
-
- Segment _NanForInternal Word "CODE"
- Assume CS:_NanforInternal
- Org 0
-
- Old24Vec EQU DWord Ptr BP - 6
- Old24Ofs EQU Word Ptr BP - 6
- Old24Seg EQU Word Ptr BP - 4
-
- Proc __ftIsPrint Far
-
- Push BP
- Mov BP,SP
- Sub SP,6
-
- Mov [Handle],AX ; Retrieve handle & store
-
- Mov AX,3524h ; Get INT 24h vector
- Int 21h ; Call DOS
- Mov [Old24Ofs],BX ; Save offset
- Mov [Old24Seg],ES ; Save segment value
-
- Push DS ; Save DS
- Push CS ; Move CS . . .
- Pop DS ; . . . to DS
-
- ModCode1 = $ - __ftIsPrint + 1
-
- Mov DX,Offset Int_24 ; Get offset of handler
- Mov AX,2524h ; Set INT 24h vector
- Int 21h ; Call DOS
- Pop DS ; Restore DS
-
- ModCode2 = $ - __ftIsPrint + 3
-
- Mov [CS:IsReady],1 ; Assume printer ready
- Mov AX,4407h ; Get output status
- Mov BX,[Handle] ; Choose print device
- Int 21h ; Call DOS
-
- ModCode3 = $ - __ftIsPrint + 3
-
- And AL,[CS:IsReady] ; Combine error reports
- CBW ; Clear high byte
- Push AX ; Save status for later
-
- Push DS ; Save DS
- Mov AX,2524h ; Set INT 24h vector
- LDS DX,[Old24Vec] ; Get address of original handler
- Int 21h ; Call DOS
- Pop DS
-
- Pop AX ; Return status in AX
- Mov SP,BP ; Realign stack
- Pop BP ; Restore BP
- RetF ; Far return
- Endp __ftIsPrint
-
-
-
- Proc Int_24 Far
-
- Int24Ofs = $ - __ftIsPrint
-
- ModCode4 = $ - __ftIsPrint + 3
-
- Mov [CS:IsReady],0 ; Indicate not ready
- Xor AX,AX ; Tell DOS to ignore error
- IRet
-
- @@1: ReadyOfs = $ - __ftIsPrint
-
- IsReady DB ?
-
- Endp Int_24
-
- DOSBytes = $ - __ftIsPrint
-
- Ends _NanForInternal
- End