home *** CD-ROM | disk | FTP | other *** search
/ RBBS in a Box Volume 1 #2 / RBBS_vol1_no2.iso / 015n / canjetdl.asm < prev    next >
Assembly Source File  |  1986-12-07  |  12KB  |  374 lines

  1. PAGE ,132
  2.         TITLE   CANJETDL - Print Screen Utility
  3.  
  4. ;***    CANJETDL - Print Screen Utility
  5. ;
  6. ;       CANJETDL is a print screen utility. It intercepts INT 5 from
  7. ;       the BIOS (generated when <Print Screen> is struck), and prints
  8. ;       the contents of the screen onto the PRN device.
  9. ;
  10. ;       To execute:
  11. ;
  12. ;       CANJETDL
  13. ;
  14. ;       To activate:
  15. ;
  16. ;       Press <Print Screen>
  17. ;
  18. ;       OR, if using Mouse Systems' PC PAINT, execute CANJETDL before PC PAINT
  19. ;       then, use the normal program procedures for printing a picture.
  20. ;
  21. ;       Once CANJETDL has been executed, it remains permanently in RAM and
  22. ;       does not need to be executed again.
  23. ;
  24. ;-      Modified Aug 86 by SRN  - Text dump to graphics.
  25. ;    Modified again by Wayne D. Markel for IBM EGA
  26. ;-      Canon PJ-1080A Inkjet graphics dump.
  27. ;-      Code has been taken from various sources and been modified to suit.
  28. ;    
  29. ;       I wrote numerous versions of this program.
  30. ;    This version was written specifically for use with IBM Drawing 
  31. ;    Assistant.  It can only be invoked by using the PRINT SCREEN key,
  32. ;    and therefore reads only the portion of the screen that contains the
  33. ;    picture, not the border and icons.
  34. ;
  35. ;    This version also rotates the picture 90 degrees and doubles up on
  36. ;    the pixels in order to get a larger picture.
  37.  
  38. ;       NOTE: This is my first ever attempt at assembler programming so
  39. ;       any comments for improvement would be appreciated.
  40. ;       Wayne D. Markel
  41. ;       655 Carnathan Ct.
  42. ;       Ft. Walton Beach, Florida   32548
  43. ;       904-862-5417
  44. ;       Compuserve ID 71330,552 
  45.           
  46.  
  47. FALSE   =       0
  48. TRUE    =       NOT FALSE
  49.  
  50. ;       The next 2 switches should be set to TRUE and TRUE for:
  51. COLUMNS =       80              ; Characters/line
  52.  
  53.         page
  54.  
  55.  
  56.  
  57. CODE    SEGMENT BYTE PUBLIC 'CODE'
  58.         ASSUME  CS:CODE,DS:CODE,ES:CODE,SS:CODE
  59.  
  60.         ORG     100H
  61.  
  62. ;*      Entry point
  63. ;
  64.  
  65. BEGIN:
  66.         JMP     NEAR PTR START
  67.  
  68.  
  69. ;*      INT 5 handler
  70. ;
  71.  
  72. INT_5:
  73.         PUSH    DS                      ; Save his data segment
  74.         PUSH    AX
  75.  
  76.         MOV     CS:INT_SP,SP
  77.         MOV     CS:INT_SS,SS            ; Save his stack
  78.  
  79.         MOV     AX,CS
  80.         MOV     SS,AX                   ; Set local stack
  81.         MOV     SP,OFFSET INT_STACK
  82.  
  83.         STI                             ; Now allow interrupts to come in
  84.  
  85.         PUSH    ES
  86.         PUSH    BX
  87.         PUSH    CX
  88.         PUSH    DX
  89.         PUSH    SI
  90.         PUSH    DI
  91.  
  92.         MOV     DS,AX
  93.         MOV     ES,AX                   ; Set up my segments
  94.  
  95.         CALL    CANJET
  96.  
  97.  
  98.         POP     DI
  99.         POP     SI
  100.         POP     DX
  101.         POP     CX
  102.         POP     BX
  103.         POP     ES
  104.  
  105.         CLI                             ; INTs off while messing around
  106.         MOV     AX,CS:INT_SP
  107.         MOV     SP,AX
  108.         MOV     AX,CS:INT_SS            ; Restore his stack
  109.         MOV     SS,AX
  110.  
  111.         POP     AX
  112.         POP     DS
  113.         IRET                            ; Back to BIOS
  114. INT_SS  DW      0                       ; Saved stack values
  115. INT_SP  DW      0
  116.  
  117. INT_CX  DW      0                       ; Current X location
  118. INT_CY  DW      0                       ; Current Y location
  119. MYCHR   DW      0                       ; Character at position
  120. MYLINE  DB      82 DUP (?)              ; Line buffer
  121. LINES   DW      0                       ; Number of lines valid on screen
  122. BLUE_BUFFER    DB    80 DUP(?)
  123. GREEN_BUFFER    DB    80 DUP(?)
  124. RED_BUFFER    DB    80 DUP(?)
  125. DosVersMsg    db    "ATTR: Needs DOS 2.0 +$"
  126. LOAD_BUFFER    DB    ?
  127. ROW        DW    ?
  128. COLUMN        DW    ?
  129. NO_OF_BYTES    EQU    50H
  130.             DW      128 DUP (?)
  131. INT_STACK LABEL NEAR                    ; Internal stack
  132.  
  133.  
  134. CANJET        PROC    NEAR
  135. ;------------------------------------------------------------------------------
  136. ;   PROCEDURE TO READ AN EGA MODE 16 SCREEN, ROTATE IT 90 DEGREES CLOCKWISE, 
  137. ;   DOUBLE THE DOT OUTPUT FROM 640X350 TO 1280X700 AND PRINT IT ON A CANON 
  138. ;   PJ1080A
  139. ;------------------------------------------------------------------------------
  140.  
  141. ;This code for checking DOS version came from PC Magazine
  142.  
  143.     Mov    AH, 30h            ; Check for DOS Version
  144.     Int    21h            ;   through DOS call
  145.     Cmp    AL, 2            ; See if it's 2.0 or above
  146.     Jae    DosVersOK        ; If so, continue
  147.  
  148.     Mov    DX, Offset DosVersMsg    ; Error message
  149. ErrorExit:
  150.     Mov    AH, 9            ; Print String function call
  151.     Int    21h            ; Do it
  152.     Int    20h            ; And exit prematurely
  153.  
  154. DosVersOK:
  155.         
  156. ;-------------------------------------------------------------------------------
  157. ;     READ A WINDOW, ONE DOT AT A TIME, RETURNING THE VALUE IN AL
  158. ;-------------------------------------------------------------------------------
  159.  
  160.     MOV    COLUMN,92D        ;INITIALIZE COLUMN COUNTER
  161.  
  162. NEWCOLUMN:
  163.  
  164.     MOV    LOAD_BUFFER,80H        ;INITIALIZE THIS VARIABLE WHICH IS USED 
  165.     MOV    ROW,337D        ;SET ROW POINTER TO BOTTOM OF WINDOW    
  166.     
  167. ;------------------------------------------------------------------------------
  168. ;  ZERO OUT BUFFERS AT BEGINNING OF EACH ROW
  169. ;------------------------------------------------------------------------------
  170.     MOV    CX,240D
  171.     
  172.     MOV    BX,00            ;SET OFFSET POINTER TO ZERO
  173. ZERO:    MOV    [BLUE_BUFFER+BX],00    ;PUT ZERO IN BYTE OF RED_BUFFER
  174.     INC    BX
  175.     LOOP    ZERO
  176. ;------------------------------------------------------------------------------
  177. ;       READ A DOT AT COLUMN=CX ROW=DX
  178. ;       RETURN VALUE OF PIXEL IN AL
  179. ;------------------------------------------------------------------------------
  180.     MOV    BX,0            ;INITIALIZE POINTER FOR BUFFERS
  181. LINE:    MOV     CX,COLUMN        ;SET CX TO CURRENT COLUMN
  182.     MOV     DX,ROW            ;SET DX TO CURRENT ROW
  183.     MOV     AH,0DH            ;READ DOT FUNCTION
  184.     INT     10H
  185.  
  186.     MOV    DH,LOAD_BUFFER        ;SETUP DH TO TURN ON CORRECT BIT WHEN
  187.                     ; ORed WITH A BYTE IN ONE OF THE BUFFERS
  188. ;------------------------------------------------------------------------------
  189. ;     In order to get a picture 8.25X15.0 inches on the CANON, it is necessary
  190. ;     to write each pixel FOUR times.  The EGA operates in 640X350 pixel
  191. ;     mode. So the program will load the value of the pixel into a buffer
  192. ;     TWICE and print each buffer TWICE.  This will
  193. ;     produce a picture on paper 1280 by 700 pixels in size.
  194. ;------------------------------------------------------------------------------
  195.             
  196.     CALL    LOAD_BUFFERS    
  197.  
  198.     CALL    LOAD_BUFFERS        
  199.  
  200. ;------------------------------------------------------------------------------
  201. ;     Ok, that doubled up on the pixels, now it's time to DEC the ROW
  202. ;     counter to read the next pixel
  203. ;------------------------------------------------------------------------------
  204.  
  205.  
  206.     DEC    WORD PTR [ROW]        ;DECREMENT THE ROW COUNTER
  207.  
  208. ;------------------------------------------------------------------------------
  209. ;       CHECK TO SEE IF AT TOP OF THE WINDOW
  210. ;------------------------------------------------------------------------------
  211.  
  212.     CMP     WORD PTR [ROW],18D    ;TEST IF ABOVE TOP OF WINDOW
  213.     JGE      LINE            ;NO...READ ANOTHER DOT            
  214.  
  215.  
  216.     CALL    OUTPUT_BUFFERS        ;YES, OUTPUT ONE LINE TO CANONJET    
  217.  
  218.     CALL    OUTPUT_BUFFERS        ;OUTPUT SECOND LINE
  219.  
  220.  
  221.     INC    WORD PTR [COLUMN]    ;INCREMENT COLUMN NUMBER
  222.  
  223.     CMP     WORD PTR [COLUMN],548D    ;AT RIGHT EDGE OF WINDOW?
  224.     JL      NEWCOLUMN        ;NO, READ ANOTHER COLUMN OF DOTS    
  225.  
  226.     RET                ;YES..HAVE READ ALL OF WINDOW, SO EXIT
  227. ;-------------------------------------------------------------------------------
  228. ;   SUBROUTINE TO LOAD BUFFERS
  229. ;-------------------------------------------------------------------------------
  230.  
  231. LOAD_BUFFERS    PROC    NEAR
  232.  
  233.     MOV    AH,AL            ;PUT THE VALUE FROM THE READ_DOT BIOS
  234.                     ; CALL INTO AH FOR FURTHER MANIPULATION
  235.     SHR    AH,1            ;PUSH THE LSB INTO THE BIT BUCKET
  236. ;------------------------------------------------------------------------------
  237. ;                   IF IT'S A "1", THEN TURN ON THE
  238. ;                   CORRESPONDING BIT IN THE CURRENT
  239. ;                   BYTE OF THE BLUE BUFFER 
  240. ;------------------------------------------------------------------------------
  241.  
  242.     JNC    GREEN            ;IF IT'S A 0 CHECK THE GREEN BIT
  243. LOAD_BLUE_BUFFER:
  244.     OR    BYTE PTR [BLUE_BUFFER+BX],DH    ;TURN ON A BIT IN BUFFER
  245.              
  246. GREEN:    SHR    AH,1            ;SHIFT RIGHT ONE MORE TIME
  247.                     ; TO SEE IF THE 2 BIT IS ON
  248.                     ;IF YES, PUT A BIT IN THE GREEN BUFFER
  249.     JNC    RED            ;IF NO, CHECK THE RED BIT
  250. LOAD_GREEN_BUFFER:
  251.     OR    BYTE PTR [GREEN_BUFFER+BX],DH
  252.  
  253. RED:    SHR    AH,1            ;SHIFT ONE MORE TIME TO CHECK THE 4 BIT
  254.                                         
  255.     JNC    END_LOAD_BUFFER        ;IF NOT SET JUMP TO END_LOAD_BUFFER
  256. LOAD_RED_BUFFER:
  257.     OR    BYTE PTR[RED_BUFFER+BX],DH    ;SINCE THE 4 BIT IS SET, LOAD...
  258.                             ; TO THE BUFFER
  259.  
  260. END_LOAD_BUFFER:
  261.     SHR    DX,1
  262.     MOV    LOAD_BUFFER,DH        ;SHR THE VARIABLE, "LOAD_BUFFER"    
  263.     CMP    DH,00            ;HAVE WE READ 8 DOTS YET?
  264.     JNZ    SAME_BYTE        ;NO, READ NEXT DOT
  265.     MOV    LOAD_BUFFER,80H        ;RESET MSB OF LOAD_BUFFER
  266.     MOV    DH,LOAD_BUFFER        ;SAME FOR DH
  267. ;-------------------------------------------------------------------------------
  268. ;  AFTER STUFFING 8 DOTS INTO THE BUFFER, INCREMENT THE BUFFER OFFSET POINTER
  269. ;-------------------------------------------------------------------------------
  270.     INC    BX            ;BUMP POINTER FOR BUFFERS
  271.  
  272. SAME_BYTE:
  273.  
  274.     RET
  275.  
  276.  
  277. LOAD_BUFFERS        ENDP
  278. ;------------------------------------------------------------------------------
  279.  
  280. OUTPUT_BUFFERS  PROC       NEAR
  281.  
  282. ;-------------------------------------------------------------------------------
  283. ;  SET CANONJET TO GRAPHICS MODE...
  284. ; ...THEN OUTPUT ONE ROW OF DOTS TO THE CANONJET.
  285. ; NOTE: TWO ROWS OF DOTS MUST BE SENT BEFORE ANY PRINTER ACTION OCCURS
  286. ;
  287. ;-------------------------------------------------------------------------------
  288.  
  289.  
  290.  
  291.         MOV    AH,5            ;SET DOS FUNCTION TO 5 FOR PRINT 
  292.                         ;TER OUTPUT
  293.         MOV    DL,01BH            ;SEND        
  294.         INT    21H            ;ESCAPE CHARACTER
  295.         MOV    DL,058H            ;THEN "X" CHARACTER
  296.         INT    21H
  297.         MOV    DL,NO_OF_BYTES            ;GET READY FOR 10 BYTES OF DATA
  298.         INT    21H
  299.  
  300. ;------------------------------------------------------------------------------
  301. ;     OUTPUT (NO_OF_BYTES) FROM THE RED_BUFFER                                 
  302. ;------------------------------------------------------------------------------
  303.  
  304.         MOV    BX,0            ;SET OFFSET IN BUFFER TO ZERO    
  305. RED_OUT:    MOV    DL,[RED_BUFFER+BX]    ;PUT BYTE IN DL FOR OUTPUT TO 
  306.                         ;PRINTER
  307.         INT    21H            ;DO IT.
  308.         INC    BX            ;MOVE OVER TO NEXT BYTE IN
  309.                         ; BUFFER
  310.         CMP    BX,NO_OF_BYTES
  311.         JL    RED_OUT            ;READ ANOTHER BYTE UNTIL 80
  312.                         ; HAVE BEEN READ.
  313.         
  314. ;------------------------------------------------------------------------------
  315. ;  OUTPUT (N0_OF_BYTES) FROM THE GREEN_BUFFER
  316. ;------------------------------------------------------------------------------
  317.         MOV    BX,0    
  318. GREEN_OUT:    MOV    DL,[GREEN_BUFFER+BX]
  319.         INT    21H
  320.         INC    BX
  321.         CMP     BX,NO_OF_BYTES        
  322.         JL    GREEN_OUT            
  323. ;------------------------------------------------------------------------------
  324. ;  OUTPUT  (NO_OF_BYTES) FROM THE BLUE_BUFFER
  325. ;------------------------------------------------------------------------------
  326.         MOV    BX,0
  327. BLUE_OUT:    MOV    DL,[BLUE_BUFFER+BX]
  328.         INT    21H
  329.         INC    BX
  330.         CMP    BX,NO_OF_BYTES
  331.         JL    BLUE_OUT
  332. ;------------------------------------------------------------------------------
  333. ;  ONE LINE OF DOTS HAVE BEEN OUTPUT TO THE CANONJET PRINT BUFFER
  334. ;------------------------------------------------------------------------------
  335.         RET    
  336. OUTPUT_BUFFERS        ENDP
  337. ;-------------------------------------------------------------------------------
  338.         
  339.  
  340.     RET                ;NEAR RETURN TO DOS
  341. CANJET    ENDP
  342.  
  343.  
  344. INT_END LABEL   NEAR
  345.  
  346. ;*      Main entry point
  347. ;
  348.  
  349. START:
  350.         MOV     SP,OFFSET INT_STACK             ; Good place for it
  351.         PUSH    DS
  352.  
  353.         XOR     AX,AX
  354.         MOV     DS,AX                           ; Clear DS
  355.  
  356.         MOV     SI,5*4                          ; SI points to interrupt
  357.         CLI
  358.  
  359.         MOV     WORD PTR [SI],OFFSET INT_5
  360.         MOV     WORD PTR [SI+2],CS              ; Set my interrupt vector
  361.  
  362.         STI
  363.         POP     DS
  364.  
  365.         MOV     DX,OFFSET INT_END               ; LWA of resident portion
  366.         
  367. ;    MOV    AH,31H                ;FUNCTION FOR STAY RESIDENT
  368. ;    MOV    AL,1                ;RETURN CODE FOR COMMAND
  369. ;    MOV    DX,5D                ;RESERVE 1.5K MEMORY
  370. ;       INT     21H
  371.     INT    27H
  372. CODE    ENDS
  373.         END     BEGIN
  374.