|
|
1.1 root 1: /*
2: * rs_io.s
3: *
4: * This module implements the rs232 io interrupts.
5: */
6:
7: .text
8: .globl _rs1_interrupt,_rs2_interrupt
9:
10: size = 1024 /* must be power of two !
11: and must match the value
12: in tty_io.c!!! */
13:
14: /* these are the offsets into the read/write buffer structures */
15: rs_addr = 0
16: head = 4
17: tail = 8
18: proc_list = 12
19: buf = 16
20:
21: startup = 256 /* chars left in write queue when we restart it */
22:
23: /*
24: * These are the actual interrupt routines. They look where
25: * the interrupt is coming from, and take appropriate action.
26: */
27: .align 2
28: _rs1_interrupt:
29: pushl $_table_list+8
30: jmp rs_int
31: .align 2
32: _rs2_interrupt:
33: pushl $_table_list+16
34: rs_int:
35: pushl %edx
36: pushl %ecx
37: pushl %ebx
38: pushl %eax
39: push %es
40: push %ds /* as this is an interrupt, we cannot */
41: pushl $0x10 /* know that bs is ok. Load it */
42: pop %ds
43: pushl $0x10
44: pop %es
45: movl 24(%esp),%edx
46: movl (%edx),%edx
47: movl rs_addr(%edx),%edx
48: addl $2,%edx /* interrupt ident. reg */
49: rep_int:
50: xorl %eax,%eax
51: inb %dx,%al
52: testb $1,%al
53: jne end
54: cmpb $6,%al /* this shouldn't happen, but ... */
55: ja end
56: movl 24(%esp),%ecx
57: pushl %edx
58: subl $2,%edx
59: call jmp_table(,%eax,2) /* NOTE! not *4, bit0 is 0 already */
60: popl %edx
61: jmp rep_int
62: end: movb $0x20,%al
63: outb %al,$0x20 /* EOI */
64: pop %ds
65: pop %es
66: popl %eax
67: popl %ebx
68: popl %ecx
69: popl %edx
70: addl $4,%esp # jump over _table_list entry
71: iret
72:
73: jmp_table:
74: .long modem_status,write_char,read_char,line_status
75:
76: .align 2
77: modem_status:
78: addl $6,%edx /* clear intr by reading modem status reg */
79: inb %dx,%al
80: ret
81:
82: .align 2
83: line_status:
84: addl $5,%edx /* clear intr by reading line status reg. */
85: inb %dx,%al
86: ret
87:
88: .align 2
89: read_char:
90: inb %dx,%al
91: movl %ecx,%edx
92: subl $_table_list,%edx
93: shrl $3,%edx
94: movl (%ecx),%ecx # read-queue
95: movl head(%ecx),%ebx
96: movb %al,buf(%ecx,%ebx)
97: incl %ebx
98: andl $size-1,%ebx
99: cmpl tail(%ecx),%ebx
100: je 1f
101: movl %ebx,head(%ecx)
102: pushl %edx
103: call _do_tty_interrupt
104: addl $4,%esp
105: 1: ret
106:
107: .align 2
108: write_char:
109: movl 4(%ecx),%ecx # write-queue
110: movl head(%ecx),%ebx
111: subl tail(%ecx),%ebx
112: andl $size-1,%ebx # nr chars in queue
113: je write_buffer_empty
114: cmpl $startup,%ebx
115: ja 1f
116: movl proc_list(%ecx),%ebx # wake up sleeping process
117: testl %ebx,%ebx # is there any?
118: je 1f
119: movl $0,(%ebx)
120: 1: movl tail(%ecx),%ebx
121: movb buf(%ecx,%ebx),%al
122: outb %al,%dx
123: incl %ebx
124: andl $size-1,%ebx
125: movl %ebx,tail(%ecx)
126: cmpl head(%ecx),%ebx
127: je write_buffer_empty
128: ret
129: .align 2
130: write_buffer_empty:
131: movl proc_list(%ecx),%ebx # wake up sleeping process
132: testl %ebx,%ebx # is there any?
133: je 1f
134: movl $0,(%ebx)
135: 1: incl %edx
136: inb %dx,%al
137: jmp 1f
138: 1: jmp 1f
139: 1: andb $0xd,%al /* disable transmit interrupt */
140: outb %al,%dx
141: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.