1
2
3
4
5
6
7
8
9
10
11
12
13 .text
14 .globl _rs1_interrupt,_rs2_interrupt
15
16 size = 2048
17
18
19
20
21 rs_addr = 0
22 head = 4
23 tail = 8
24 proc_list = 12
25 buf = 16
26
27 startup = 256
28
29
30
31
32
33
34
35
36 .align 2
37 _rs1_interrupt:
38 pushl $_table_list+8
39 pushl $_table_list+24
40 jmp rs_int
41
42 .align 2
43 _rs2_interrupt:
44 pushl $_table_list+16
45 pushl $_table_list+32
46 rs_int: cld
47 pushl %edx
48 pushl %ecx
49 pushl %ebx
50 pushl %eax
51 push %es
52 push %ds
53 pushl $0x10
54 pop %ds
55 pushl $0x10
56 pop %es
57 movl 24(%esp),%edx
58 call do_rs_intr
59 movl 28(%esp),%edx
60 call do_rs_intr
61 movb $0x20,%al
62 outb %al,$0x20
63 pop %ds
64 pop %es
65 popl %eax
66 popl %ebx
67 popl %ecx
68 popl %edx
69 addl $8,%esp # jump over the _table_list entries
70 iret
71
72 do_rs_intr:
73 pushl %edx
74 movl (%edx),%edx
75 movl rs_addr(%edx),%edx
76 addl $2,%edx
77 1: xorl %eax,%eax
78 inb %dx,%al
79 testb $1,%al
80 jne 2f
81 cmpb $6,%al
82 ja 2f
83 movl (%esp),%ecx
84 pushl %edx
85 subl $2,%edx
86 call jmp_table(,%eax,2)
87 popl %edx
88 jmp 1b
89 2: popl %edx
90 ret
91
92 jmp_table:
93 .long modem_status,write_char,read_char,line_status
94
95 .align 2
96 modem_status:
97 addl $6,%edx
98 inb %dx,%al
99 ret
100
101 .align 2
102 line_status:
103 addl $5,%edx
104 inb %dx,%al
105 ret
106
107 .align 2
108 read_char:
109 inb %dx,%al
110 movl %ecx,%edx
111 subl $_table_list,%edx
112 shrl $3,%edx
113 movl (%ecx),%ecx # read-queue
114 movl head(%ecx),%ebx
115 movb %al,buf(%ecx,%ebx)
116 incl %ebx
117 andl $size-1,%ebx
118 cmpl tail(%ecx),%ebx
119 je 1f
120 movl %ebx,head(%ecx)
121 1: movl mask_table(,%edx,4),%edx
122 orl %edx,_timer_active
123 ret
124
125 .align 2
126 mask_table:
127 .long 0,4,8,16,32
128
129 .align 2
130 write_char:
131 movl 4(%ecx),%ecx # write-queue
132 movl head(%ecx),%ebx
133 subl tail(%ecx),%ebx
134 andl $size-1,%ebx # nr chars in queue
135 je write_buffer_empty
136 cmpl $startup,%ebx
137 ja 1f
138 movl proc_list(%ecx),%ebx # wake up sleeping process
139 testl %ebx,%ebx # is there any?
140 je 1f
141 movl $0,(%ebx)
142 1: movl tail(%ecx),%ebx
143 movb buf(%ecx,%ebx),%al
144 outb %al,%dx
145 incl %ebx
146 andl $size-1,%ebx
147 movl %ebx,tail(%ecx)
148 cmpl head(%ecx),%ebx
149 je write_buffer_empty
150 ret
151
152 .align 2
153 write_buffer_empty:
154 movl proc_list(%ecx),%ebx # wake up sleeping process
155 testl %ebx,%ebx # is there any?
156 je 1f
157 movl $0,(%ebx)
158 1: incl %edx
159 inb %dx,%al
160 jmp 1f
161 1: jmp 1f
162 1: andb $0xd,%al # disable transmit interrupt
163 outb %al,%dx
164 ret