home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
printer
/
spool.arc
/
BUFFERP.ASM
next >
Wrap
Assembly Source File
|
1985-08-09
|
15KB
|
730 lines
; PRINT control program
page 60,132
;Routines
public begin,s1,baddevice,b1,do_menu,b2,b23,test_end,exit8
public clear_the_buffer,b245,b25,change_priority,b26,b265,b27
public change_port,b3,b35,b4,exit9,lpt1,b5,lpt2,b6,lpt3,com1,com2
public this_prn_not_avaliable,termin_ate,set_pause,get_query,no_pause
public printbxcxdx,p1,p2,p3,p4,p5,bin2dec,repeat3,ioctl,ioctl_ret
public get_port_address,g1,print_port,com,lpt,com_one,com_two,lpt_one
public lpt_two,lpt_three,error3,ascbin,ab1,ab2
public ab25,ab3,ab4,ab5,ab6
;Variables
public header,not_installed,not_valid_port,pause_on,line1,line2,line3
public line4,menu,number,port_menu,not_avaliable,pause_on_q
public pause_off_q,buffer_cleared,new_port,lpt1_mess,lpt2_mess
public lpt3_mess,com1_mess,com2_mess,new_priority,nothing_done
public you_sure,crlf,space,not_valid_number,port_number,port_type
public buffer_size,characters_in_buffer,priority,pause_flag
public scratch,ioctl_buff,handle
code segment
assume cs:code, ds:code, es:code, ss:code
keyboard_no_echo equ 8 ; msdos function call equates
display_char equ 2
display_string equ 9
terminate equ 4ch
cr equ 0dh
lf equ 0ah
; Version 2.1 : By Craig Derouen. Change communications input from
; 3/20/85 : software interrupt to ioctl calls to make better
; : compatability with other programs.
; Version 2.2 : By Craig Derouen. Add printer pause feature
; 4/4/85
org 100h
begin:
jmp s1
; data
header db "BUFFER PRINT control program. Version 2.2",cr,lf,lf,"$"
not_installed db "FLASH PRINT is not installed.",cr,lf,"$"
not_valid_port db "The output port does not exist",cr,lf,"$"
pause_on db cr,lf,"The printer output is paused right now",cr,lf,"$"
line1 db "The number of characters in the buffer: $"
line2 db "The size of the buffer in characters: $"
line3 db "The port being used with the printer: $"
line4 db "The priority of the printer (1 lowest, 200 highest): $"
menu db cr,lf,"Choose the number of one of the following command options.",cr,lf
db "1.) Clear the buffer",cr,lf
db "2.) Change the port to use with the printer",cr,lf
db "3.) Change the priority",cr,lf
db "4.) Pause printer output",cr,lf
db "5.) Reprint the current page",cr,lf
db "6.) Exit the program",cr,lf,"$"
number db "Number: ","$"
port_menu db cr,lf,lf,"Choose the port to use with the printer.",cr,lf
db "1.) LPT1",cr,lf
db "2.) LPT2",cr,lf
db "3.) LPT3",cr,lf
db "4.) COM1",cr,lf
db "5.) COM2",cr,lf
db "6.) Exit the program",cr,lf,"$"
not_avaliable db "The port chosen is not in the system",cr,lf,"$"
pause_on_q db cr,lf,"Do you want to pause printer output (y=yes) ? $"
pause_off_q db cr,lf,"Do you want printer output on again (y=yes) ? $"
buffer_cleared db "The buffer is empty",cr,lf,"$"
new_port db "The new port to use with the printer is $"
lpt1_mess db "LPT1",cr,lf,"$"
lpt2_mess db "LPT2",cr,lf,"$"
lpt3_mess db "LPT3",cr,lf,"$"
com1_mess db "COM1",cr,lf,"$"
com2_mess db "COM2",cr,lf,"$"
new_priority db "Input the new priority: $"
nothing_done db "Nothing was done",cr,lf,"$"
you_sure db "You sure you what to clear the buffer? (y=yes) $"
crlf db cr,lf,"$"
space db " $"
not_valid_number db cr,lf,"invalid number",cr,lf,"$"
port_number db ?
port_type db ?
buffer_size dw ?
characters_in_buffer dw ?
priority dw ?
pause_flag db ?
; end of data
; macros
print macro message
mov ah, display_string
mov dx, offset message
int 21h
endm
buffer_input macro size_of_buffer
local i2, buffer, num_of_chars, buffer2
; This macro inputs characters from the keyboard with echo and stores them in memory.
; The string of characters is terminated with two bytes of 0.
; enter: ds = cs
; exit: al = # of characters typed not including the CR
; ds:si -> first char. of the string typed
jmp i2
buffer db size_of_buffer + 1
num_of_chars db ?
buffer2 db size_of_buffer dup(?)
dw ?
i2:
mov ah, 0ah ; buffer keyboard input
mov dx, offset buffer
int 21h
mov al, [num_of_chars] ; end the string with 0,0
mov ah, 0
mov si, offset buffer2
add si, ax
mov [si], word ptr 0
sub si, ax
endm
; end of macros
s1:
print header ; print "BUFFER PRINT program ..."
mov ax,7
call ioctl ; call driver
push bx
mov ax,8
xor bx,bx ; do nothing
call ioctl
mov pause_flag,bl
pop bx
jc baddevice
cmp bx, 55aah ; check test pattern
je b1
baddevice:
print not_installed ; print "BUFFER PRINT is not installed."
jmp termin_ate
b1:
mov ax, cs ; restore es = cs
mov es, ax
mov ax, 1 ; get port # and type
call ioctl
mov [port_number], bl
mov [port_type], bh
mov ax, 3 ; get buffer size
call ioctl
mov [buffer_size], bx
mov ax, 4 ; get # of char. in the buffer
call ioctl
mov [characters_in_buffer], bx
mov ax, 6 ; get the priority
call ioctl
mov [priority], bx
print line1 ; print "The number of characters in the buffer:"
mov ax, [characters_in_buffer]
call bin2dec
call printbxcxdx
print crlf
print line2 ; print "The size of the buffer in characters:"
mov ax, [buffer_size]
call bin2dec
call printbxcxdx
print crlf
print line3 ; print "The port being used with the printer:"
mov ah, [port_type]
mov al, [port_number]
call print_port
print line4 ; print "The priority of the printer (1 lowest, 65536 highest):"
mov ax, [priority]
call bin2dec
call printbxcxdx
print crlf
cmp pause_flag,-1 ; is printer paused ?
jne do_menu
print pause_on
do_menu:
print menu ; print the menu
b2:
print number ; print "Number: "
mov ah, keyboard_no_echo ; wait for a number to be typed
int 21h
cmp al, cr
je exit8
push ax ; echo every thing except cr
mov ah, display_char
mov dl, al
int 21h
print space ; print two spaces
pop ax
cmp al, "1" ; jump to the correct command
je clear_the_buffer
cmp al, "2"
jne b23
jmp change_port
b23:
cmp al, "3"
je change_priority
cmp al, "4"
jne test_end
jmp set_pause ; Handle pause status
test_end:
cmp al, "5" ; reprint current page
je print_cur_page
cmp al, "6"
je exit8
jmp b2
exit8:
print crlf
jmp termin_ate
print_cur_page:
mov ax,9 ; current page function
xor bx,bx
call ioctl
jmp termin_ate
clear_the_buffer:
print you_sure ; print "Are you sure you want to clear the buffer? (y=yes) "
mov ah, keyboard_no_echo ; wait for something to be typed
int 21h
cmp al, cr
je b245
push ax ; echo everything except cr
mov ah, display_char
mov dl, al
int 21h
print space ; print two spaces
pop ax
and al, 0dfh ; convert the something to upper case
cmp al, "Y"
je b25
b245:
print nothing_done ; print "Nothing was done"
jmp termin_ate
b25:
mov ax, 0 ; flush the buffer
call ioctl
print buffer_cleared ; print "The buffer is empty"
jmp termin_ate
change_priority:
print new_priority ; print "Input the new priority"
buffer_input 5 ; input max. of 5 character from the keyboard with echo
cmp al, 0 ; if no characters were typed exit
jnz b26
jmp termin_ate
b26:
call ascbin ; conver the ascii characters to binary
push ax
print crlf
lodsb ; if the first non convertable character is a 0, then it was a good #.
cmp al, 0
pop ax
jnz b265
cmp ax, 0 ; the priority must be between 1 and 200
je b265
cmp ax, 200
ja b265
jmp b27
b265:
print not_valid_number
jmp change_priority
b27:
mov bx, ax ; set the new priority
mov ax, 5
call ioctl
print crlf
jmp termin_ate
change_port:
print port_menu ; print the port menu
b3:
print number ; print "Number: "
mov ah, keyboard_no_echo ; wait for a number to be typed
int 21h
cmp al, cr
je exit9
push ax ; echo every thing except cr
mov ah, display_char
mov dl, al
int 21h
print space ; print two spaces
pop ax
cmp al, "1" ; jump to the correct command
je lpt1
cmp al, "2"
je lpt2
cmp al, "3"
je lpt3
cmp al, "4"
jne b35
jmp com1
b35:
cmp al, "5"
jne b4
jmp com2
b4:
cmp al, "6"
je exit9
jmp b3
exit9:
print crlf
jmp termin_ate
lpt1:
mov bx, 0000h
call get_port_address ; determine if this port is in the system
cmp dx, 0
jnz b5
jmp this_prn_not_avaliable
b5:
print new_port ; print "The new port to use with the printer is "
print lpt1_mess ; print "LPT1."
mov ax, 2 ; use lpt1 for the output port
mov bl, 0 ; port number
mov bh, 1 ; port type = parallel
call ioctl
jmp termin_ate
lpt2:
mov bx, 0001
call get_port_address ; determine if this port is in the system
cmp dx, 0
jnz b6
jmp this_prn_not_avaliable
b6:
print new_port ; print "The new port to use with the printer is "
print lpt2_mess ; print "LPT2."
mov ax, 2
mov bl, 1 ; port number
mov bh, 1 ; port type = parallel
call ioctl
jmp termin_ate
lpt3:
mov bx, 0002
call get_port_address ; determine if this port is in the system
cmp dx, 0
jz this_prn_not_avaliable
print new_port ; print "The new port to use with the printer is "
print lpt3_mess ; print "LPT3."
mov ax, 2
mov bl, 2 ; port number (0,1,2)
mov bh, 1 ; port type = parallel
call ioctl
jmp termin_ate
com1:
mov bx, 0100h
call get_port_address ; determine if this port is in the system
cmp dx, 0
jz this_prn_not_avaliable
print new_port ; print "The new port to use with the printer is "
print com1_mess ; print "COM1."
mov ax, 2
mov bl, 0 ; port number
mov bh, 0 ; port type = serial
call ioctl
jmp termin_ate
com2:
mov bx, 0101h
call get_port_address ; determine if this port is in the system
cmp dx, 0
jz this_prn_not_avaliable
print new_port ; print "The new port to use with the printer is "
print com2_mess ; print "COM2."
mov ax, 2
mov bl, 1 ; port number
mov bh, 0 ; port type = serial
call ioctl
jmp termin_ate
this_prn_not_avaliable:
print not_avaliable
jmp b3
termin_ate:
mov ah, terminate ; return to msdos
int 21h
set_pause:
; Get current pause status and determine if user wishes to toggle it.
mov ax,8 ; function call
mov bx,1 ; assume we want to turn on pause
mov dx,offset pause_on_q
cmp pause_flag,-1 ; is pause on?
jne get_query
mov bx,2 ; we want to turn it off
mov dx,offset pause_off_q
get_query:
push ax
push bx
mov ah,9
int 21h ; show message
mov ah,1
int 21h ; get response
or al,20h ; to lower case
cmp al,'y'
jne no_pause
pop bx
pop ax
call ioctl
jmp termin_ate
no_pause:
pop bx
pop ax
jmp termin_ate
;--------------------------------------------------------------------
printbxcxdx proc
; print registers bx, cx, dx if they are not spaces
push dx
push dx
cmp bh, " "
je p1
mov ah, display_char
mov dl, bh
int 21h
p1:
cmp bl, " "
je p2
mov ah, display_char
mov dl, bl
int 21h
p2:
cmp ch, " "
je p3
mov ah, display_char
mov dl, ch
int 21h
p3:
cmp cl, " "
je p4
mov ah, display_char
mov dl, cl
int 21h
p4:
mov ah, display_char
pop dx
cmp dh, " "
je p5
mov dl, dh
int 21h
p5:
mov ah, display_char
pop dx
int 21h
ret
printbxcxdx endp
;--------------------------------------------------------------------
bin2dec proc
; Convert a two byte binary number to a six byte ascii decimal number.
; call: ax = binary number
; es = cs = ds
; return: bxcxdx = ascii decimal number
; registers changed: bx cx dx
; algorithm used:
; REPEAT digit = (x mod 10) + '0'; x = x DIV 10 UNTIL x = 0
pushf
push ax
push si
push di
cld ; auto increment
mov di, offset scratch ; work space
mov si, di
push ax
mov ax, 2020h
stosw
stosw
stosw
pop ax
mov di, si
mov bx, 10
repeat3:
xor dx, dx ; get the first digit
div bx ; dxax/bx = ax R dx
add dx, "0"
push ax
mov al, dl
stosb ; mov es:[di], al
pop ax
or ax, ax
jnz repeat3
lodsw
mov dx, ax
lodsw
mov cx, ax
lodsw
mov bx, ax
pop di
pop si
pop ax
popf
ret
scratch db 6 dup(9)
bin2dec endp
;--------------------------------------------------------------------
; Put function into IOCTL buffer and call the device
ioctl proc near
mov [ioctl_buff],ax ; put in functions
mov [ioctl_buff+2],bx
mov bx,[handle] ; get printer handle
mov ax,4403h ; read/write ioctl
mov cx,4 ; just 2 words
mov dx,offset ioctl_buff
int 21h
xor bx,bx
jc ioctl_ret ; oops an error
mov bx,[ioctl_buff+2] ; get response
ioctl_ret:
ret
ioctl endp
ioctl_buff dw ?
dw ?
handle dw 4 ; Standard PRN handle
;--------------------------------------------------------------------
get_port_address proc
; call: bh = port type (0 com, 1 if parallel)
; bl = port_number (0, 1, 2)
; return: dx = port address
push ax
push es
push si
mov ax,0040h ; use es:si to get the port address
mov es,ax ; the com and parallel ports are at 40:0 to 40:0010
mov si,8
cmp bh, 0
jnz g1
mov si, 0
g1:
mov al, bl
cbw
add si,ax
add si,ax
mov dx,es:[si]
pop si
pop es
pop ax
ret
get_port_address endp
;--------------------------------------------------------------------
print_port proc
; print the port type (LPT1, LPT2, LPT3, COM1, COM2) on the screen
; call: ah = port type (0 = com, 1 = parallel)
; al = port number (0, 1, 2)
; return: carry set if al or ah are out of range
cmp ah, 0
jz com
cmp ah, 1
jz lpt
jmp error3
com:
cmp al, 0
jz com_one
cmp al, 1
jz com_two
jmp error3
lpt:
cmp al, 0
jz lpt_one
cmp al, 1
jz lpt_two
cmp al, 2
jz lpt_three
jmp error3
com_one:
print com1_mess
ret
com_two:
print com2_mess
ret
lpt_one:
print lpt1_mess
ret
lpt_two:
print lpt2_mess
ret
lpt_three:
print lpt3_mess
ret
error3:
stc
ret
print_port endp
;--------------------------------------------------------------------
ascbin proc
cld
push dx
push bx
xor bx,bx
mov cx,-1
ab1:
cmp byte ptr [si],' '
jnz ab2
inc si
jmp ab1
ab2:
push si
cmp byte ptr [si],'+'
jz ab25
cmp byte ptr [si],'-'
jnz ab3
ab25:
inc si
ab3:
lodsb
cmp al,'.'
jnz ab4
xor cx,cx
jmp ab3
ab4:
cmp al,'0'
jb ab5
cmp al,'9'
ja ab5
and ax,0fh
xchg ax,bx
mov dx,10
mul dx
add bx,ax
or cx,cx
js ab3
inc cx
jmp ab3
ab5:
dec si
mov ax,bx
pop bx
cmp byte ptr [bx],'-'
jnz ab6
neg ax
ab6:
pop bx
pop dx
ret
ascbin endp
;--------------------------------------------------------------------
code ends
end begin