home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
comm
/
mskerm30.zip
/
EPSON.ZIP
/
EPSON.ASM
next >
Wrap
Assembly Source File
|
1990-01-18
|
19KB
|
525 lines
page 60,132
title Graphics Module for Print Screen with EGA and Epson Printer
; Revised 17 Nov 1989 by Joe Doupnik
; Add initial jump label start: and identify it for the DOS loader.
; Relabel "Out" to be "Out1" to avoid assembler keyword.
;
; Revised 6 Dec 1989 by Frank da Cruz
; Change Epson initialization and restore strings:
; Disable perforation skip and paper-out detect during graphics print.
; Restore string is now ESC @ (initialize) rather than ESC 0 (1/8"/line)
Epson segment para public 'code'
assume cs:Epson,ds:Epson,es:Epson
comment #
This routine is for public domain for those of you who bought an
EGA and enhanced monitor and determined that you could no longer
do a Shf_Prt_Scn in mode 10h (16). If you have an IBM compatible
and an Epson FX series printer then this routine will replace the
GRAPHICS.COM routine. I also have routines for Radio Shack DMP
printers with 8 pins (but only 7 usable for graphics) and for HP
LaserJet printers when used with an EGA. Enjoy...
Dr. R. Brooks Van Horn, Jr.
701 Fall Place
Herndon, VA. 22070
#
org 100h
start: jmp Setup
Mlen db 'EGA Graphics Ver 1.0'
Cmp_Str dw $-mlen
; normal int 5 entry point
Begin: pushf ; enable further interrupts
push ax
push bx
push bp
push di
push si
mov ah,15 ; setup a function call to dos to
int 10h ; get the video mode
and ax,007fh ; mask off unwanted data
mov cs:[Mode],ax ; and save it for future use
cmp al,7 ; is this a mono card?
jz Out1 ; yes, exit - when in text mode
cmp al,3 ; see if we are in the graphics mode?
jg cont ; yes, go around using dos
Out1: pop si ; restore the registers saved
pop di
pop bp
pop bx
pop ax
popf
;----- jump far to Dos
db 0EAh ; jump far segment to Print
dos dw 0 ; offset of jump
dos2 dw 0 ; segment of jump
Cont: push cx ; and save all the registers
push dx
push ds
push es
push cs ; now put code seg register into
pop es ; the extra segment register
xor ax,ax
mov ds,ax
inc al ; see if we are already being done
mov al,Byte Ptr ds:[500h] ; get the current mode and also set it
or al,al
jnz Getout ; if 550h was not zero then exit
push cs
pop ds
xchg al,Byte Ptr cs:switch
or al,al
jnz GetOut
sti
mov cs:[sp_save],sp
jmp Process
Return: mov si,Offset Restore
mov cl,cs:[si] ; get number of bytes to print
xor ch,ch
inc si
call Tabptr ; restore printer to original state
Exit: mov sp,cs:[sp_save]
xor ax,ax
mov Byte Ptr cs:switch,al ; set value to zero
Getout: pop es ; restore registers and exit
pop ds
pop dx
pop cx
pop si
pop di
pop bp
pop bx
pop ax
popf
sti
iret ; bye...............
;--------------------------------------------------------------------
; Epson FX Printer with IBM-PC
;--------------------------------------------------------------------
Line_Sp db 7,27,51,24,27,79,27,56 ; Control Codes for 24/216" line spacing
; Also disable perforation skip (ESC O) and
; disable paper-out detect (ESC 8) (fdc)
Set_Graf db 4,27,76 ; Cntrl Code for each graphics line printed
Col_2_Do dw 0 ; last column number to be printed
Restore db 2,27,64,12 ; change count to 3 if you want a form feed
; changed from ESC 0 to ESC @ (fdc)
Line_Buf db 960 dup (?) ; line buffer
Eight dw 8
Four dw 4
Switch db 0
Sp_Save dw 0
Mode dw 0 ; Current Video Mode
Rows dw 0 ; Number of rows for this mode
Cols dw 0 ; Number of columns for this mode
; Modes = 4 5 6 7 8 9 A B C D E F 10
Col_Mode dw 320,320,640, 0, 0,320,640, 0,720,320,640,640,640
Row_Mode dw 200,200,200, 0, 0,200,200, 0,348,200,200,350,350
;--------------------------------------------------------------------
; Print a Table of Control Values
; ===============================
;
Tabptr: mov al,cs:[si]
call Printer
inc si
loop Tabptr
nop
ret
;
; Send an alarm bell sound
; ========================
;
Bell: mov al,7
mov ah,14
int 10h
ret
; Send the character in AL to the printer
; =======================================
;
Printer: push dx
sub dx,dx
xor ah,ah
int 17h
pop dx
test ah,25h
jnz Error
ret
;
; Error returns on printer commands
; =================================
;
Error: call Bell
call Bell
jmp Exit
;
; Send a form feed to the Printer
; ===============================
;
Cr_Lf: push dx
sub dx,dx
mov ax,0dh
int 17h
mov ax,0ah
int 17h
pop dx
test ah,25h
jnz Error
ret
;---------------------------------------------------------------------
; l
; Graphics Processing Section l
; l
;---------------------------------------------------------------------
Process: mov bp,cs:[Mode]
sub bp,4
sal bp,1
mov ax,cs:Row_Mode[bp] ; save rows-1 and cols-1
dec ax
mov cs:Rows,ax
mov ax,cs:Col_Mode[bp]
dec ax
mov cs:Cols,ax
mov ah,1 ; initialize the printer
xor dx,dx
int 17h
mov si,Offset cs:Line_Sp ; setup for correct interline spacing
mov cl,cs:[si] ; get length
xor ch,ch
inc si
call TabPtr
mov ax,cs:[Cols] ; decide to do graphics by row or column mode
cmp ax,320
jg By_Rows
jmp By_Cols
;--------------------------------------------------------------------
; for By_Rows calls we have usually 640 x 200 type, so do 200
; across and 640 down the page. This means that we can only
; single dot to get lines to connect on the printer paper.
;--------------------------------------------------------------------
By_Rows: mov cx,0 ; start the column index at zero
Br_Strt: push cx ; save the current column index
mov dx,cs:[Rows] ; initialize the row count to max
mov bh,Byte Ptr cs:[Eight]
xor si,si ; max characters to print
mov cs:[Col_2_Do],si
mov di,Offset cs:Line_Buf
xor bl,bl
; do for a count of 'Eight'
Br_Cont: call Read ; read the next dot at (row,col)
and al,07fh ; check if any thing is there
jz Br_Fill ; and skip if nothing there
mov al,1 ; else fill the byte
Br_Fill: shl bl,1 ; move reg left one bit
or bl,al ; and or in the next value
inc cx ; increment the column count
dec bh ; and the loop index
jnz Br_Cont ; continue loop for 8 times
; undo
add si,2 ; add two to the column counter
mov Byte Ptr cs:[di],bl ; save filled byte
mov Byte Ptr cs:[di+1],bl ; twice for filling
cmp cs:[Rows],199 ; check for less than 200 rows
jg Br_Two
mov Byte Ptr cs:[di+2],bl ; and 3 times for low resolution
inc di
inc si
Br_Two: add di,2 ; up the buffer ptr
or bl,bl ; do we have anything to print?
jz Br_Skp ; no, skip
mov cs:[Col_2_Do],si ; save index
Br_Skp: mov bh,Byte Ptr cs:[Eight] ; set loop for 8 more cols per row
dec dx ; delete one from the row index
pop cx ; restore the column count
push cx ; and save it again for this row
cmp dx,0 ; and test to see if we are finished
jge Br_Cont ; loop
mov cx,cs:[Col_2_Do] ; get the number of bytes to print
or cx,cx
jz Br_NoP ; skip if didn't get anything
push cx ; save number to do
mov si,Offset cs:Set_Graf ; setup for graphics
mov cl,cs:[si] ; get length
xor ch,ch
inc si ; point past length field
call TabPtr ; perform the setup
pop cx ; now get the real characters to do
mov si,Offset cs:Line_Buf ; get print line pointer
call TabPtr ; and print the line
Br_NoP: call Cr_Lf ; do carriage return and line feed at end
pop cx
add cx,cs:[Eight] ; add 8 to column count
cmp cx,cs:[Cols] ; compare to max to do
jg Br_Ret
jmp Br_Strt ; continue until fini
Br_Ret: jmp Return ; restore printer and exit
;--------------------------------------------------------------------
; for By_Cols calls we have usually 320 x 200 type, so do 320
; across and 200 down the page. This means that we must double
; dot to get lines to connect on the printer paper.
;--------------------------------------------------------------------
By_Cols: mov dx,0 ; start the row index at zero
; for each row do all the columns
Bc_Strt: push dx ; save the current row index
mov cx,0 ; initialize the col count to start
mov bh,Byte Ptr cs:[Four]
xor si,si ; max characters to print
mov cs:[Col_2_Do],si
mov di,Offset cs:Line_Buf
; for each column in the row, do
Bc_Cont: call Read ; read the next dot at (row,col)
and al,07fh ; check if any thing is there
jz Bc_Fill ; and skip if nothing there
mov al,3 ; else fill the byte from the bottom
Bc_Fill: shl bl,1 ; move reg left one bit
shl bl,1 ; and repeat
or bl,al ; and 'or' in the next value
inc dx ; increment the row count
dec bh ; and the loop index
jnz Bc_Cont ; continue loop for 4 times
add si,3 ; add three to the column counter
mov Byte Ptr cs:[di],bl ; save filled byte
mov Byte Ptr cs:[di+1],bl ; twice for filling
mov Byte Ptr cs:[di+2],bl ; and three times for a lady
add di,3 ; up the buffer ptr
or bl,bl ; see if anything is there
jz Bc_Skp ; skip if we have nothing to plot
mov cs:[Col_2_Do],si ; save index
Bc_Skp: mov bh,Byte Ptr cs:[Four] ; set loop for 8 more cols per row
inc cx ; add one to the col index
pop dx ; restore the row count
push dx ; and save it again for this row
cmp cx,cs:[Cols] ; and test to see if we are finished
jle Bc_Cont ; loop
mov cx,cs:[Col_2_Do] ; get the number of bytes to print
or cx,cx
jz Bc_NoP ; skip if didn't get anything
push cx ; save number to do
mov si,Offset cs:Set_Graf ; setup for graphics
mov cl,cs:[si] ; get length
xor ch,ch
inc si ; point past length field
call TabPtr ; perform the setup
pop cx ; now get the real characters to do
mov si,Offset cs:Line_Buf ; get print line pointer
call TabPtr ; print the line
Bc_NoP: call Cr_Lf
pop dx
add dx,cs:[Four] ; add to column count
cmp dx,cs:[Rows] ; compare to max to do
jg Bc_Ret ; if fini then exit
jmp Bc_Strt ; else go do next row
Bc_Ret: jmp Return ; restore printer and exit
;--------------------------------------------------------------------
;
; Read Dot Routine Using DOS/BIOS or VDI interface for int 10h
;
;-------------------------------------------------------------------
Read: xor al,al
cmp dx,0 ; see if all is ok
jl Read_Ret
cmp cx,cs:[Cols] ; also check on overdoing it
jg Read_Ret
cmp cs:[Mode],10h
je Read_Dot ; if mode = 10 then do special I/O
mov ah,13
push bx
push cx
push dx
int 10h
pop dx
pop cx
pop bx
xor ah,ah ; clear the high byte for testing
Read_Ret: ret
;---------------------------------------------------------------
;
; Read a Pixel (Dot) from the EGA using Read Mode 0
;
;----------------------------------------------------------------
Read_Dot: push bx
push cx
push dx
mov ax,dx ; save column value
mov bx,cx ; and row value
mov dx,0a000h ; Video ram address
mov ds,dx ; into segment register
mov dx,80
mul dx ; column * 80
shr bx,1
shr bx,1
shr bx,1 ; row / 8
add bx,ax ; actual data byte address
and cl,7 ; row mod 8
xor cl,7 ; bit mask 7 - (row mod 8)
mov ch,1
shl ch,cl ; 2^mask
mov ah,3 ; initialize bit plane number
Plane_Loop:
mov dx,03CEh ; EGA Controller
mov al,4 ; map select register
out dx,al
mov dx,03CFh ; data register
mov al,ah ; select bit planes 3,2,1,0
out dx,al
mov al,ds:[bx] ; read bit plane
shl cl,1
and al,ch
jz Not_On
or cl,1
Not_On: dec ah
jge Plane_Loop
and cl,0fh
mov al,cl
pop dx
pop cx
pop bx
ret
dw -1 ; fense
;--------------------------------------------------------------------
;
; Initialization Routine for EPSON.COM
;
;--------------------------------------------------------------------
Setup: xor ax,ax
mov es,ax ; setup to address segment zero
mov cx,es:[0016h] ; get current segment
mov bx,es:[0014h] ; and offset
mov ds,cx ; make that the data segment
mov cx,cs:[Cmp_Str] ; setup to check bytes for same
mov si,Offset cs:mlen ; data field "Graphic..."
mov bx,si
Check: mov ax,cs:[si] ; get a byte in accum
cmp ax,ds:[bx] ; is it the same
jne Ok ; no, then we are ok
inc si ; otherwise, increment pointers
inc bx ; to both fields
loop Check ; and loop for 7 checks
mov ax,cs
mov ds,ax
mov ah,09h
mov dx,Offset Message1
int 21h
int 20h ; if same then dont overlay but exit
Ok: mov bx,es:[0014h] ; get the current offset in int vector
mov ax,cs ; now setup to display a message
mov ds,ax
mov Word Ptr dos,bx ; and save it locally
mov bx,es:[0016h] ; get the segment location of item too
mov Word Ptr dos2,bx ; and save it also
mov ax,cs ; save our entry at int vector
mov es:[0016h],ax ; segment
mov bx,Offset cs:Begin ; define entry point to routine
mov es:[0014h],bx ; offset
mov di,Offset Field1
call Convert ; convert starting address
mov di,Offset Field2
mov bx,Offset Setup
add bx,15 ; convert to next paragraph addr
mov cl,4
shr bx,cl
add ax,bx
call Convert ; and the new ending address
mov ah,09h ; now do our message
mov dx,Offset Message2
int 21h
mov dx,Offset cs:Setup
int 27h ; terminate but stay resident
Convert proc near
;
; ax = number to be converted
; di = address of field in which to put the hex characters
;
push ax
push bx
push cx
push dx
lea bx,Ascii
mov cl,4
mov dx,ax
mov al,ah
shr al,cl
xlat Ascii
mov Byte Ptr cs:[di],al
mov al,dh
and al,0fh
xlat Ascii
mov Byte Ptr cs:[di+1],al
mov al,dl
shr al,cl
xlat Ascii
mov Byte Ptr cs:[di+2],al
mov al,dl
and al,0fh
xlat Ascii
mov Byte Ptr cs:[di+3],al
pop dx
pop cx
pop bx
pop ax
ret
Convert endp
Message1 db 'EGA Graphics routine is already resident',13,10,'$'
Message2 db 'EGA Graphics routine is now resident ('
Field1 db '0000-'
Field2 db '0000)',13,10,'$'
Ascii db '0123456789abcdef'
Epson ends
end start