home *** CD-ROM | disk | FTP | other *** search
- page 58,132
- ;/*
- ;** parint.asm
- ;** contains: PrBufC(), stopprt(), strtprt(), testprt()
- ;*/
-
- include model.h
- include prologue.h
-
- DOSCALL equ 21h ;Dos: call software interrupt number
- DOSGETVECTOR equ 35h ;Dos: Get Interrupt vector function number
- DOSSETVECTOR equ 25h ;Dos: Set Interrupt vector
-
-
- ;==>-- PARINT is the structure that holds the state information for
- ; a parallel port.
- ;
- PARINT struc
- StatusBits dw ? ;Status of channel
- BaseIOPAR dw ? ;Base I/O Address for LPT
- IntNum dw ? ;Interrupt Number
- PrevVector dd ? ;Previous value for interrupt vector
- PrevBase2 dw ? ;Previous value for interrupt enable port
- Irq8259 dw ? ;Interrupt # in 8259
- Prev8259 dw ? ;Previous 8259 bit
- IOAdd8259 dw ? ;I/O address of 8259
- pBufSize dw ? ;Size of buffer
- pBufCount dw ? ;Number of characters currently in buffer
- pBufHead dw ? ;Offset into buffer for head
- pBufTail dw ? ;Offset into buffer for tail
- pBuffer dw ptrsize dup(?) ;points to actual buffer
- PARINT ends
-
- PARBUFFERFULL equ -800 ;buffer is full error
-
- ifdef LATTICE
- ;==>-- Define bits in the StatusBits member (Lattice)
- ;
- BUFFEREMPTY equ 1000000000000000b ;Buffer is empty
- BUFFERFULL equ 0100000000000000b ;Buffer is full
- INTSRUNNING equ 0010000000000000b ;Interrupts are running
- INTSENABLED equ 0001000000000000b ;Interrupts enabled
- else
- ;==>-- Define bits in the StatusBits member (non-Lattice)
- ;
- BUFFEREMPTY equ 0000000000000001b ;Buffer is empty
- BUFFERFULL equ 0000000000000010b ;Buffer is full
- INTSRUNNING equ 0000000000000100b ;Interrupts are running
- INTSENABLED equ 0000000000001000b ;Interrupts enabled
- endif
-
- ;==>-- Bits for the parallel control port
- ;
- PARSTROBE equ 00000001b ;Parallel strobe bit (active low)
- PARAUTOFEED equ 00000010b ;Auto feed bit (active low)
- PARINITPRINTER equ 00000100b ;Initialize printer bit
- PARSELECTINPUT equ 00001000b ;Select bit (active low)
- PARIRQENABLE equ 00010000b ;Interrupt enable bit
-
-
- dseg dparint
-
- if _LDATA
- printerstruct dd 0 ;32 bit pointer to PARINT
- else
- printerstruct dw 0 ;16 bit pointer to PARINT
- endif
-
- endds
-
- pseg cparint
-
- ;==>-- The StrobePrinter macro creates the strobe signal for the printer.
- ; The assumption is made that upon entry the DX register contains the
- ; address of the parallel control port.
- ;
- StrobePrinter macro
- mov al,PARIRQENABLE+PARSELECTINPUT+PARINITPRINTER+PARSTROBE
- out dx,al
- jmp short $+2 ;delay
- jmp short $+2 ; "
- jmp short $+2 ;
- xor al,PARSTROBE
- out dx,al
- endm
-
-
-
- ;/*
- ;** int
- ;** PrBufC(PARINT *p,unsigned char character)
- ;**
- ;** ARGUMENT(s)
- ;** p - Points to PARINT structure returned from
- ;** OpenPrinter().
- ;**
- ;** character - Character to be put in the printer buffer.
- ;**
- ;**
- ;** DESCRIPTION
- ;** Puts a character in the printer buffer.
- ;**
- ;**
- ;** RETURNS
- ;** 0 if successful, else:
- ;**
- ;** PARBUFFERFULL
- ;**
- ;** AUTHOR
- ;** "" Thu 17-Nov-1988 11:50:48
- ;** Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
- ;**
- ;** MODIFICATIONS
- ;**
- ;*/
- cproc PrBufC
- push es
- if _LDATA
- push ds
- lds si,parm1_ ;DS:SI points to PARINT
- mov al,parm3_ ;AL = character
- else
- mov si,parm1_ ;DS:SI points to PARINT
- mov al,parm2_ ;AL = character
- endif
- test [si+StatusBits],BUFFERFULL
- jz bufnotfull
- mov ax,PARBUFFERFULL
- jmp short prbufcex
- bufnotfull: lea di,[si+pBufSize]
- cli
- call insert ;insert character in buffer
- jnz notful2 ;if buffer did not go full jump
- or [si+StatusBits],BUFFERFULL ;set bit that says buffer is full
- notful2: sti
- xor ax,ax ;assume success
- test [si+StatusBits],BUFFEREMPTY ;did we put character in empty buffer?
- jz prbufcex ;if not jump out
- and [si+StatusBits],not BUFFEREMPTY ;else say buffer not now empty
- test [si+StatusBits],INTSENABLED
- jz prbufcex ;if ints not enabled get out
- test [si+StatusBits],INTSRUNNING
- jnz prbufcex
- mov dx,[si+BaseIOPAR] ;see if printer is ready
- inc dx
- in al,dx
- test al,80h ;is printer ready for character
- jz prbufcex
- lea di,[si+pBufSize]
- cli
- call remove ;remove character from buffer
- jnz notempt1 ;see if it went empty
- or [si+StatusBits],BUFFEREMPTY
- notempt1: or [si+StatusBits],INTSRUNNING
- sti
- mov dx,[si+BaseIOPAR] ;DX = base address of Parallel port
- out dx,al ;output character to port
- inc dx
- inc dx
- jmp short $+2
- jmp short $+2
- StrobePrinter
- xor ax,ax ;indicate success
- prbufcex:
- if _LDATA
- pop ds
- endif
- pop es
- cproce
-
- ;/*
- ;** void
- ;** stopprt(PARINT *p)
- ;**
- ;** ARGUMENT(s)
- ;** p - points to PARINT structure to stop
- ;**
- ;**
- ;** DESCRIPTION
- ;** Halts printer output, does not remove characters from buffer,
- ;** does not disable interrupt system.
- ;**
- ;** RETURNS
- ;** void
- ;**
- ;** AUTHOR
- ;** "" Fri 18-Nov-1988 11:11:41
- ;** Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
- ;**
- ;** MODIFICATIONS
- ;**
- ;*/
- cproc stopprt
- if _LDATA
- push ds
- lds si,parm1_
- else
- mov si,parm1_
- endif
- and [si+StatusBits],not INTSRUNNING+INTSENABLED
- if _LDATA
- pop ds
- endif
- cproce
-
- ;/*
- ;** void
- ;** _closepar(PARINT *p)
- ;**
- ;** ARGUMENT(s)
- ;** p - points to PARINT structure to close
- ;**
- ;** DESCRIPTION
- ;** Restores modes set in parallel port and 8259 and interrupt
- ;** vectors to their pre-opened condition. This function should
- ;** only be called by the ClosePrinter() function.
- ;**
- ;** RETURNS
- ;** void
- ;**
- ;** AUTHOR
- ;** "" Thu 17-Nov-1988 11:11:06
- ;** Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
- ;**
- ;** MODIFICATIONS
- ;**
- ;*/
- cproc _closepar,,_closepa
- push es
- push ds
- if _LDATA
- lds si,parm1_
- else
- mov si,parm1_
- endif
- mov dx,[si+BaseIOPAR] ;CX = base I/O address for port
- add dx,2 ;DX = IRQ enable port
- mov al,byte ptr [si+PrevBase2] ;Restore parallel port
- out dx,al ;to it's pre-open setting
- mov cx,[si+Irq8259]
- mov ax,1
- shl al,cl
- mov cx,ax
- mov dx,[si+IOAdd8259] ;DX=Base I/O Address of 8259
- inc dx
- in al,dx
- jmp short $+2
- or al,cl ;assume previously disabled
- test [si+Prev8259],cx ;check assumption
- jnz rs8259 ;if assumption correct
- xor al,cl ;else reverse assumption
- rs8259: out dx,al ;restore to previous state
- push ds ;now restore the interrupt vector
- mov al,byte ptr [si+IntNum] ;Interrupt Vector #
- lds dx,[si+PrevVector] ;DS:DX = old value
- mov ah,DOSSETVECTOR
- int DOSCALL
- pop ds
- pop ds
- pop es
- cproce
-
-
- ;/*
- ;** void
- ;** strtprt(PARINT *p)
- ;**
- ;** ARGUMENT(s)
- ;** p - points to PARINT structure to start
- ;**
- ;**
- ;** DESCRIPTION
- ;** Re-starts printer output, assume printer has been halted with
- ;** StopPrinter().
- ;**
- ;** RETURNS
- ;** void
- ;**
- ;** AUTHOR
- ;** "" Fri 18-Nov-1988 11:11:41
- ;** Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
- ;**
- ;** MODIFICATIONS
- ;**
- ;*/
- cproc strtprt
- if _LDATA
- push ds
- lds si,parm1_
- else
- mov si,parm1_
- endif
- or [si+StatusBits],INTSENABLED
- test [si+StatusBits],INTSRUNNING ;are they running
- jnz startexit ;if so leave
- mov dx,[si+BaseIOPAR] ;see if printer is ready
- inc dx
- in al,dx
- test al,80h ;is printer ready for character
- jz startexit
- lea di,[si+pBufSize]
- cli
- call remove ;remove character from buffer
- jnz stnotempt1 ;see if it went empty
- or [si+StatusBits],BUFFEREMPTY
- stnotempt1: or [si+StatusBits],INTSRUNNING
- sti
- mov dx,[si+BaseIOPAR] ;DX = base address of Parallel port
- out dx,al ;output character to port
- inc dx
- stloop1: in al,dx
- test al,80h
- jz stloop1
- inc dx
- StrobePrinter
- startexit:
- if _LDATA
- pop ds
- endif
- cproce
-
-
-
- ;/*
- ;** void
- ;** _setpari(PARINT *p)
- ;**
- ;** ARGUMENT(s)
- ;** p - points to PARINT structure to setup
- ;**
- ;** DESCRIPTION
- ;** Enables interrupt mode operation for a parallel device as described
- ;** in a PARINT structure. This function should only be called by the
- ;** OpenPrinter() function.
- ;**
- ;** RETURNS
- ;** void
- ;**
- ;** AUTHOR
- ;** "" Wed 16-Nov-1988 09:42:30
- ;** Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
- ;**
- ;** MODIFICATIONS
- ;**
- ;*/
- cproc _setpari
- push es
- push ds
- if _LDATA
- les si,parm1_
- mov word ptr printerstruct,si
- mov word ptr printerstruct+2,es
- mov ax,es
- mov ds,ax ;DS:SI points to structure
- else
- mov si,parm1_
- mov printerstruct,si ;DS:SI points to structure
- endif
- mov ah,DOSGETVECTOR
- mov al,byte ptr [si+IntNum] ;Get current value of vector
- int DOSCALL ;to ES:BX
- mov word ptr [si+PrevVector],bx
- mov word ptr [si+PrevVector+2],es
- push ds ;now set the vector of our handler
- mov ah,DOSSETVECTOR
- mov al,byte ptr [si+IntNum]
- mov bx,cs
- mov ds,bx
- mov dx,offset IRQ7Routine ;set new vector to DS:DX
- int DOSCALL
- pop ds ;Get DS back
- mov dx,[si+BaseIOPAR] ;CX = base I/O address for port
- add dx,2 ;DX = IRQ enable port
- in al,dx ;read current value
- mov byte ptr [si+PrevBase2],al ;and save in structure
- mov al,PARIRQENABLE+PARSELECTINPUT+PARINITPRINTER
- jmp short _fpf
- _fpf: out dx,al ;enable interrupts on parallel port
- mov cx,[si+Irq8259] ;get 8259 enable bit
- mov al,1
- shl al,cl ;shift 1 bit into position
- not al ;ones complement it
- mov cl,al ;save in cl
- mov dx,[si+IOAdd8259] ;dx=8259 base
- inc dx
- in al,dx
- jmp short _fpf2
- _fpf2: xor ah,ah
- mov [si+Prev8259],ax
- and al,cl ;enable correct bit
- out dx,al ;in 8259
- pop ds
- pop es
- cproce
-
-
- ;/*
- ;** unsigned char
- ;** testprt(PARINT *p)
- ;**
- ;** ARGUMENT(s)
- ;** p - points to PARINT structure
- ;**
- ;** DESCRIPTION
- ;** Gets the hardware status of the printer.
- ;**
- ;**
- ;** RETURNS
- ;**
- ;** Bit Meaning
- ;** 7 Busy
- ;** 6 Ack
- ;** 5 Out of paper
- ;** 4 Select
- ;** 3 Error
- ;**
- ;** AUTHOR
- ;** "" Fri 18-Nov-1988 12:07:30
- ;** Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
- ;**
- ;** MODIFICATIONS
- ;**
- ;*/
- cproc testprt
- if _LDATA
- push ds
- lds si,parm1_
- else
- mov si,parm1_
- endif
- mov dx,[si+BaseIOPAR] ;get port # to DX
- inc dx
- in al,dx
- and al,0f8h ;mask unused bits
- xor ah,ah
- if _LDATA
- pop ds
- endif
- cproce
-
- ;/*
- ;** DESCRIPTION
- ;** Interrupt routine for IRQ #7 (printer). Saves all registers and
- ;** points DS:SI to the PARINT data structure which contains state
- ;** information for the parallel port using IRQ 7.
- ;**
- ;** AUTHOR
- ;** "" Wed 16-Nov-1988 09:55:13
- ;** Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
- ;**
- ;** MODIFICATIONS
- ;**
- ;*/
- IRQ7Routine proc far
- sti
- push ax
- push dx
- push es
- push ds
- push bx
- push cx
- push si
- push di
- ifdef TURBOC
- if _HUGE
- mov ax,_dparint_DATA
- else
- mov ax,DGROUP
- endif
- else
- ifndef AZTEC
- mov ax,DGROUP
- else
- mov ax,dataseg
- endif
- endif
- mov ds,ax
- if _LDATA
- lds si,printerstruct
- else
- mov si,printerstruct
- endif
- cld
- call ProcessIRQ
- mov dx,[si+IOAdd8259] ;Load registers for 8259 EOI
- mov al,20h
- pop di
- pop si
- pop cx
- pop bx
- pop ds
- pop es
- cli
- out dx,al ;re-enable 8259
- pop dx
- pop ax
- iret
- IRQ7Routine endp
-
-
- ;==>-- Arrive here with DS:SI pointing to a PARINT data structure
- ;
- ProcessIRQ proc near
- mov dx,[si+BaseIOPAR] ;read status port to clear
- inc dx ;interrupt condition
- in al,dx
- test [si+StatusBits],INTSENABLED
- jz stopirq
- test [si+StatusBits],BUFFEREMPTY
- jz IRQbufnotempty ;if buffer not empty continue
- stopirq: and [si+StatusBits],not INTSRUNNING
- jmp short IRQExit
- IRQbufnotempty: lea di,[si+pBufSize]
- call remove ;remove character from buffer
- jnz didnotgoempty ;if buffer did not go empty take jump
- or [si+StatusBits],BUFFEREMPTY
- didnotgoempty: and [si+StatusBits],not BUFFERFULL ;cannot be full now
- mov dx,[si+BaseIOPAR] ;get base of parallel port
- out dx,al ;send character to printer
- jmp short $+2
- jmp short $+2
- inc dx
- inc dx
- StrobePrinter
- IRQExit: ret
- ProcessIRQ endp
-
-
- ;==>-- Offsets for the insert & remove routines
- ;
- BSIZE equ 0
- COUNT equ 2
- HEAD equ 4
- TAIL equ 6
- BUFFER equ 8
-
- ;==>-- insert character is to be called with ds:di pointing to the
- ; size variable, upon return the Zero flag being set indicates
- ; that the buffer is NOW FULL. When the buffer is full do not call
- ; this routine again, until there is space for another character.
- ; Call with character in AL. This routine does not test for a
- ; full buffer before inserting, only after inserting.
- ;
- insert proc near ;DS:DX points to beginning
- push si
- if _LDATA
- push es
- les si,[di+BUFFER] ;es:si points to base of array
- else
- mov si,[di+BUFFER] ;ds:si points to base of array
- endif
- inc word ptr [di+COUNT] ;bump counter
- mov bx,[di+TAIL] ;read the tail
- mov dx,bx
- inc dx ;advance the tail for next
- mov cx,[di+BSIZE] ;get size of buffer to cx
- cmp dx,cx ;check for wrap
- jb inwrap ;if no wrap take jump
- xor dx,dx ;reset subscript to 0
- inwrap: mov [di+TAIL],dx ;save updated tail
- if _LDATA
- mov es:[si+bx],al ;save character via ES:SI
- else
- mov [si+bx],al ;save character via DS:SI
- endif
- jmp short inend
- inend: cmp dx,[di+HEAD] ;see if buffer full
- if _LDATA
- pop es
- endif
- pop si
- ret
- insert endp
-
- ;==>-- remove character is to be called with ds:di pointing to the
- ; size variable, upon return the Zero flag being set indicates
- ; that the buffer is NOW EMPTY. When the buffer is empty DO NOT call
- ; this routine again, until there is another character to remove.
- ; Returns with character in AL. This routine does not test for an
- ; empty buffer before removing, only after removing.
- ;
- remove proc near
- push si
- if _LDATA
- push es
- les si,[di+BUFFER] ;es:si=base of buffer
- else
- mov si,[di+BUFFER] ;ds:si=base of buffer
- endif
- dec word ptr [di+COUNT] ;decrement counter
- mov bx,[di+HEAD] ;read the head
- mov dx,bx
- inc dx
- mov cx,[di+BSIZE] ;get size of buffer to cx
- cmp dx,cx ;check for wrap
- jb rewrap ;if no wrap take jump
- xor dx,dx ;reset subscript to 0
- rewrap: mov [di+HEAD],dx ;save updated head
- xor ah,ah
- if _LDATA
- mov al,es:[si+bx] ;remove character via ES:SI
- else
- mov al,[si+bx] ;remove character via DS:SI
- endif
- jmp short reend
- reend: cmp dx,[di+TAIL] ;see if buffer empty
- if _LDATA
- pop es
- endif
- pop si
- ret
- remove endp
-
- endps
- end
-