Search     or:     and:
Последние статьи :
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
  SQL 30.07   
  JFS 10.06   
  B-trees 01.06   
TOP 20
 Robbins 6...522 
 Go Web ...280 
 CPAN-> FAQ...210 
 Secure Programming for Li...133 
 Kernel Notes...126 
 Linux Inline Assembly...111 
 C++ Templates 2...94 
 Httpd-> История Ap...82 
 Stewens -> IPC 6...81 
 M.Pilgrim->Часть 2...78 
 Cluster 4...76 
 Intel 386...75 
 Mod_perl 2...74 
 M.Pilgrim->Часть 3...74 
 Robbins 5...72 
  01.10.2019 : 2795711 посещений
 *	rs_io.s
 * This module implements the rs232 io interrupts.

.globl _rs1_interrupt,_rs2_interrupt

size	= 1024				/* must be power of two !
					   and must match the value
					   in tty_io.c!!! */

/* these are the offsets into the read/write buffer structures */
rs_addr = 0
head = 4
tail = 8
proc_list = 12
buf = 16

startup	= 256		/* chars left in write queue when we restart it */

 * These are the actual interrupt routines. They look where
 * the interrupt is coming from, and take appropriate action.
.align 2
	pushl $_table_list+8
	jmp rs_int
.align 2
	pushl $_table_list+16
	pushl %edx
	pushl %ecx
	pushl %ebx
	pushl %eax
	push %es
	push %ds		/* as this is an interrupt, we cannot */
	pushl $0x10		/* know that bs is ok. Load it */
	pop %ds
	pushl $0x10
	pop %es
	movl 24(%esp),%edx
	movl (%edx),%edx
	movl rs_addr(%edx),%edx
	addl $2,%edx		/* interrupt ident. reg */
	xorl %eax,%eax
	inb %dx,%al
	testb $1,%al
	jne end
	cmpb $6,%al		/* this shouldn't happen, but ... */
	ja end
	movl 24(%esp),%ecx
	pushl %edx
	subl $2,%edx
	call jmp_table(,%eax,2)		/* NOTE! not *4, bit0 is 0 already */
	popl %edx
	jmp rep_int
end:	movb $0x20,%al
	outb %al,$0x20		/* EOI */
	pop %ds
	pop %es
	popl %eax
	popl %ebx
	popl %ecx
	popl %edx
	addl $4,%esp		# jump over _table_list entry

	.long modem_status,write_char,read_char,line_status

.align 2
	addl $6,%edx		/* clear intr by reading modem status reg */
	inb %dx,%al

.align 2
	addl $5,%edx		/* clear intr by reading line status reg. */
	inb %dx,%al

.align 2
	inb %dx,%al
	movl %ecx,%edx
	subl $_table_list,%edx
	shrl $3,%edx
	movl (%ecx),%ecx		# read-queue
	movl head(%ecx),%ebx
	movb %al,buf(%ecx,%ebx)
	incl %ebx
	andl $size-1,%ebx
	cmpl tail(%ecx),%ebx
	je 1f
	movl %ebx,head(%ecx)
	pushl %edx
	call _do_tty_interrupt
	addl $4,%esp
1:	ret

.align 2
	movl 4(%ecx),%ecx		# write-queue
	movl head(%ecx),%ebx
	subl tail(%ecx),%ebx
	andl $size-1,%ebx		# nr chars in queue
	je write_buffer_empty
	cmpl $startup,%ebx
	ja 1f
	movl proc_list(%ecx),%ebx	# wake up sleeping process
	testl %ebx,%ebx			# is there any?
	je 1f
	movl $0,(%ebx)
1:	movl tail(%ecx),%ebx
	movb buf(%ecx,%ebx),%al
	outb %al,%dx
	incl %ebx
	andl $size-1,%ebx
	movl %ebx,tail(%ecx)
	cmpl head(%ecx),%ebx
	je write_buffer_empty
.align 2
	movl proc_list(%ecx),%ebx	# wake up sleeping process
	testl %ebx,%ebx			# is there any?
	je 1f
	movl $0,(%ebx)
1:	incl %edx
	inb %dx,%al
	jmp 1f
1:	jmp 1f
1:	andb $0xd,%al		/* disable transmit interrupt */
	outb %al,%dx