599a545588867ee3e0f399ab2bb751f41c0d9e54
[qbasicapps.git] / networking / LPT communication driver / lptdrv.asm
1 ; Svjatoslav Agejenko\r
2 ; 2002.08\r
3 ; compile with FASM - Flat Assembler\r
4 \r
5 ;       TSR driver for LPT1 communication.\r
6 ;       Functions by INT 63h:\r
7 \r
8 ;         Deactivate\r
9 ;       AH = 0\r
10 \r
11 ;         Activate\r
12 ;       AH = 1\r
13 \r
14 ;         Get downloaded data\r
15 ;       AH = 2\r
16 ;       ES:DI   - pointer where to place downloaded data\r
17 ;       on return:\r
18 ;       AX = Number of bytes downloaded\r
19 \r
20 ;       copies downloaded data from driver input buffers to\r
21 ;       specified place.        \r
22 \r
23 ;         Upload data\r
24 ;       AH = 3\r
25 ;       DS:SI   - pointer for data to be uploaded\r
26 ;       CX      - amount of bytes to upload \r
27 \r
28 ;       After interrupt, data will be immediately\r
29 ;       moved to communication driver own output buffer,\r
30 ;       and sent when line becomes avaiable.\r
31  \r
32 myint = 63h     ; interrupt to hook\r
33 upbuf = 5000    ; upload buffer size\r
34 downbuf = 5000  ; download buffer size\r
35 InPort = 37ah   ; input port, for Parallel Printer Port Control Register\r
36 defspd = 3      ; Default communication speed\r
37 upbufp = last + downbuf\r
38 \r
39 \r
40 org     100h\r
41 \r
42 ;============================ TSR initialization ====================\r
43 \r
44 mov     dx, InPort      ; reset line\r
45 mov     al, 0\r
46 out     dx, al\r
47 \r
48 mov     ax, 0           ; Saves old interrupt vector\r
49 mov     es, ax\r
50 mov     eax, [es:32]\r
51 mov     [d2], eax       \r
52 \r
53 cli\r
54 mov     ax, cs          ; Set new interrupt vector for IRQ 0\r
55 shl     eax, 16\r
56 mov     ax, custom\r
57 mov     [es:32], eax\r
58 mov     ax, int63       ; Set new interrupt vector for INT 63\r
59 mov     [es:4 * myint], eax\r
60 sti\r
61 \r
62 \r
63 mov     ax, last        ; Calculate needed memory size, begin TSR\r
64 add     ax, upbuf + downbuf + 1000\r
65 mov     dx, 0\r
66 mov     bx, 16\r
67 div     bx\r
68 mov     dx, ax\r
69 mov     ax, 3100h\r
70 int     21h\r
71 d2      dd 0\r
72 \r
73 ;============================ IRQ 0 handler =========================\r
74 \r
75 custom:\r
76 pushf                   ; Execute default code in old int vector\r
77 call    dword [cs:d2]\r
78 \r
79 ;pusha                   ; Write 1 character, for debugging\r
80 ;mov     ax, 0e01h\r
81 ;mov     bx, 0\r
82 ;int     10h\r
83 ;popa\r
84 \r
85 inc     byte [cs:tmr]   ; Update timer\r
86 \r
87 cmp     [cs:progress], 0 ; Check if custom routine is already active\r
88 jne     EndOfRoutine\r
89 cmp     [cs:enabled], 0 ; Check if driver is enabled\r
90 je      EndOfRoutine\r
91 \r
92 mov     [cs:progress], 1 ; Set active flag\r
93 pusha\r
94 push    ds\r
95 push    es\r
96 \r
97 mov     dx, InPort\r
98 in      al, dx\r
99 shl     al, 4\r
100 cmp     al, 128\r
101 jb      checkdone\r
102 \r
103 ;============================ download data from LPT ================\r
104 \r
105 mov     ax, cs\r
106 mov     es, ax\r
107 mov     ds, ax\r
108 mov     di, last\r
109 add     di, [dbufsiz]\r
110 mov     bh, 0\r
111 \r
112 SkipHeader:\r
113 in      al, dx\r
114 shl     al, 6\r
115 cmp     al, 128\r
116 jae     SkipHeader\r
117 mov     ah, 255\r
118 mov     cx, 0\r
119 \r
120 SkipBit:\r
121 inc     cx\r
122 cmp     cx, 30\r
123 je      MkHeader\r
124 in      al, dx\r
125 cmp     al, ah\r
126 je      SkipBit\r
127 in      al, dx\r
128 \r
129 mov     cx, 0\r
130 mov     ah, al\r
131 shr     al, 3\r
132 or      al, 254\r
133 sub     al, 254\r
134 \r
135 shl     bl, 1\r
136 add     bl, al\r
137 inc     bh\r
138 cmp     bh, 8\r
139 jb      SkipBit\r
140 \r
141 mov     al, bl\r
142 stosb\r
143 mov     bh, 0\r
144 mov     bl, bh\r
145 jmp     SkipBit\r
146 \r
147 MkHeader:\r
148 mov     ax, di\r
149 sub     ax, last\r
150 sub     ax, [dbufsiz]\r
151 stosw\r
152 mov     ax, di\r
153 sub     ax, last\r
154 mov     [dbufsiz], ax\r
155 \r
156 checkdone:\r
157 cmp     word [cs:ubufsiz], 0\r
158 je      alldone\r
159 \r
160 ; =========================== send data to LPT ======================\r
161 \r
162 mov     ax, cs\r
163 mov     ds, ax\r
164 mov     byte [tmr], 0\r
165 \r
166 mov     dx, InPort\r
167 mov     al, 255\r
168 out     dx, al\r
169 mov     si, upbufp\r
170 mov     cx, [ubufsiz]\r
171 \r
172 sti\r
173 SendHeader:\r
174 cmp     byte [tmr], 2\r
175 jb      SendHeader\r
176 cli\r
177 \r
178 SendByte:\r
179 cmp     cx, 0\r
180 je      sent\r
181 \r
182 mov     bl, 0\r
183 lodsb\r
184 \r
185 SendBit:\r
186 push    ax\r
187 push    cx\r
188 shr     al, 4\r
189 or      al, 247\r
190 sub     al, 247\r
191 mov     bh, bl\r
192 or      bh, 254\r
193 sub     bh, 254\r
194 shl     bh, 1\r
195 add     al, bh\r
196 \r
197 mov     ch, 0\r
198 mov     cl, [spd]\r
199 WaitForBit:\r
200 out     dx, al\r
201 loop    WaitForBit\r
202 pop     cx\r
203 pop     ax\r
204 inc     bl\r
205 shl     al, 1\r
206 cmp     bl, 8\r
207 jb      SendBit\r
208 \r
209 dec     cx\r
210 jmp     SendByte\r
211 sent:\r
212 \r
213 mov     al, 0\r
214 out     dx, al\r
215 mov word [ubufsiz], 0\r
216 \r
217 \r
218 alldone:\r
219 pop     es\r
220 pop     ds\r
221 popa\r
222 mov     [cs:progress], 0 ; Terminate active flag\r
223 EndOfRoutine:\r
224 iret\r
225 \r
226 progress db 0\r
227 enabled db 0\r
228 dbufsiz dw 0\r
229 ubufsiz dw 0\r
230 tmr     db 0\r
231 spd     db defspd\r
232 \r
233 ;============================ INT 63h handler =======================\r
234 \r
235 int63:\r
236 cmp     ah, 0\r
237 je      set_unactive\r
238 cmp     ah, 1\r
239 je      set_active\r
240 cmp     ah, 2\r
241 je      get_data\r
242 cmp     ah, 3\r
243 je      send_data\r
244 jmp     EndOfRoutine\r
245 \r
246 set_active:\r
247 mov     dx, InPort      ; reset line\r
248 mov     al, 0\r
249 out     dx, al\r
250 mov     [cs:enabled], 1\r
251 jmp     EndOfRoutine\r
252 \r
253 set_unactive:\r
254 mov     [cs:enabled], 0\r
255 jmp     EndOfRoutine\r
256 \r
257 get_data:\r
258 push    ds\r
259 mov     ax, cs\r
260 mov     ds, ax\r
261 mov     si, last\r
262 mov     cx, [dbufsiz]\r
263 rep     movsb\r
264 pop     ds\r
265 mov     ax, [cs:dbufsiz]\r
266 mov     [cs:dbufsiz], 0\r
267 jmp     EndOfRoutine\r
268 \r
269 send_data:\r
270 push    es\r
271 mov     dx, cx\r
272 mov     bx, cs\r
273 mov     es, bx\r
274 mov     di, upbufp\r
275 add     di, [cs:ubufsiz]\r
276 rep     movsb\r
277 add     [cs:ubufsiz], dx\r
278 pop     es\r
279 jmp     EndOfRoutine\r
280 \r
281 last:\r