Skip to content

Latest commit

 

History

History
318 lines (266 loc) · 7.77 KB

tmpcommm.pas

File metadata and controls

318 lines (266 loc) · 7.77 KB
 
Nov 18, 2000
Nov 18, 2000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
{$A+,B+,D-,E+,F+,I+,L+,N-,O-,R-,S+,V-}
unit tmpcom;
interface
uses crt,dos;
var
tmpcom_BIOS_port_table:array[1..2] of integer absolute $0040:0000;
const
I8088_IMR=$21;
tmpcom_buffer_max=5120;
type
tmpcom_portrec=
record
RTB, { receive / transmit buffers }
IER, { interrupt enable register }
IIR, { interrupt identification register }
LCR, { line control register }
MCR, { modem control register }
LSR, { line status register }
MSR:integer; { modem status register }
end;
var
tmpcom_saveoldvec:pointer;
tmpcom_ports:tmpcom_portrec;
tmpcom_base:integer;
tmpcom_irq,
tmpcom_port:byte;
tmpcom_open_flag:boolean;
tmpcom_buffer:array[0..tmpcom_buffer_max] of byte;
tmpcom_buffer_head,
tmpcom_buffer_tail,
tmpcom_buffer_used:integer;
tmpcom_outcharacter:char;
tmpcom_outgoingnow:boolean;
mpcoder:boolean;
mpcode:array[1..6] of byte;
procedure tmpcom_clear_errors;
procedure tmpcom_setdtr(b:boolean);
procedure tmpcom_closeport(ddtr:boolean);
procedure tmpcom_resetport(comport:byte; baudrate:longint; parity:char;
wordsize,stopbits:byte);
procedure tmpcom_openport(comport:byte; baudrate:longint; parity:char;
wordsize,stopbits:byte);
procedure tmpcom_initvars;
function tmpcom_receive(var c:char):boolean;
procedure tmpcom_sendno(c:char);
procedure tmpcom_send(c:char);
implementation
procedure tmpcom_clear_errors;
var i,j:integer;
begin
inline($FA); { cli }
{ disable baud rate bs... }
i:=port[tmpcom_ports.LCR] and $7F;
port[tmpcom_ports.LCR]:=i;
i:=port[tmpcom_ports.LSR]; { read LSR to reset errors }
i:=port[tmpcom_ports.RTB]; { read RTB in case it contains a chr }
{ enable the IRQ line (3/4) on the 8259 controller }
i:=((port[I8088_IMR]) and ((1 shl tmpcom_irq) xor $00FF));
port[I8088_IMR]:=i;
{ enable data-available interrupt --
transmit-register-empty interrupt is set by tmpcom_send(. }
port[tmpcom_ports.IER]:=$01;
{ enable OUT2, RTS, and DTR }
port[tmpcom_ports.MCR]:=$0B;
inline($FB); { sti }
end;
procedure tmpcom_setdtr(b:boolean);
var bb:byte;
begin
bb:=port[tmpcom_ports.MCR] and $FE;
if (b) then inc(bb);
port[tmpcom_ports.MCR]:=bb;
end;
procedure tmpcom_closeport(ddtr:boolean);
var i,j:integer;
begin
if (tmpcom_open_flag) then begin
inline($FA); { cli }
{ disable the IRQ line (3/4) on the 8259 controller }
i:=((port[I8088_IMR]) or (1 shl tmpcom_irq));
port[I8088_IMR]:=i;
{ disable data-available interrupt (along with all other interrupts) }
port[tmpcom_ports.IER]:=$00;
{ disable OUT2, and DTR if ddtr=TRUE }
i:=((port[tmpcom_ports.MCR]) and ($F7));
port[tmpcom_ports.MCR]:=i;
inline($FB); { sti }
{ reset interrupt vector to original setting }
setintvec(tmpcom_irq+8,tmpcom_saveoldvec);
tmpcom_open_flag:=FALSE;
end;
end;
function iii(i:integer):byte;
var j:integer;
begin
j:=tmpcom_buffer_tail-i;
if (j<0) then inc(j,tmpcom_buffer_max+1);
iii:=tmpcom_buffer[j];
end;
procedure checkmpcode;
var i:integer;
begin
inline($FA);
if ((iii(1)=254) and (iii(2)=253)) then
if ((iii(9)=1) and (iii(10)=2) and (iii(11)=1)) then begin
mpcoder:=TRUE;
for i:=1 to 6 do mpcode[7-i]:=iii(i+2);
tmpcom_buffer_head:=0;
tmpcom_buffer_tail:=tmpcom_buffer_head;
end;
inline($FB);
end;
procedure tmpcom_isr(flags,cs,ip,ax,bx,cx,dx,si,di,ds,es,bp:word); interrupt;
var dxx,i:integer;
bb:byte;
label iisr1,iisr2;
begin
inline($FB);
iisr1:
dxx:=port[tmpcom_ports.IIR];
if (dxx and $01<>$00) then goto iisr2;
case (dxx and $06) of
0:;
2:begin
if (tmpcom_outgoingnow) then begin
i:=port[tmpcom_ports.MSR];
port[tmpcom_ports.RTB]:=ord(tmpcom_outcharacter);
tmpcom_outgoingnow:=FALSE;
end;
port[tmpcom_ports.IER]:=port[tmpcom_ports.IER] and $FD;{ turn off TRE }
end;
4:begin
bb:=port[tmpcom_ports.RTB];
tmpcom_buffer[tmpcom_buffer_head]:=bb;
inc(tmpcom_buffer_head);
if (tmpcom_buffer_head>tmpcom_buffer_max) then
tmpcom_buffer_head:=0;
if (bb=255) then checkmpcode;
end;
6:;
end;
goto iisr1;
iisr2:
port[$20]:=$20;
end;
procedure tmpcom_resetport(comport:byte; baudrate:longint; parity:char;
wordsize,stopbits:byte);
const
tmpcom_num_bauds=10;
tmpcom_baud_table:
array[1..tmpcom_num_bauds] of record baud,bits:word; end
= ((baud:110; bits:$00), (baud:150; bits:$20),
(baud:300; bits:$40), (baud:600; bits:$60),
(baud:1200; bits:$80), (baud:2400; bits:$A0),
(baud:4800; bits:$C0), (baud:9600; bits:$E0),
(baud:19200; bits:$E0), (baud:38400; bits:$E0));
var regs:registers;
comparm,i:integer;
begin
tmpcom_buffer_head:=0;
tmpcom_buffer_tail:=0;
{ set up baud rate bits }
i:=0;
repeat inc(i)
until ((tmpcom_baud_table[i].baud=baudrate) or (i=tmpcom_num_bauds));
comparm:=tmpcom_baud_table[i].bits;
case upcase(parity) of
'E':comparm:=comparm or $18;
'O':comparm:=comparm or $08;
end;
if (wordsize=7) then comparm:=comparm or $02 else comparm:=comparm or $03;
if (stopbits=2) then comparm:=comparm or $04;
regs.ax:=comparm and $00FF;
regs.dx:=tmpcom_port-1; { comport }
intr($14,regs);
end;
procedure tmpcom_openport(comport:byte; baudrate:longint; parity:char;
wordsize,stopbits:byte);
begin
if (tmpcom_open_flag) then tmpcom_closeport(FALSE);
if ((comport=2) and (tmpcom_BIOS_port_table[2]<>0)) then begin
tmpcom_base:=$2f8;
tmpcom_port:=2; tmpcom_irq:=3;
end else begin
tmpcom_base:=$3f8;
tmpcom_port:=1; tmpcom_irq:=4;
end;
with tmpcom_ports do begin
RTB:=tmpcom_base;
IER:=tmpcom_base+$01;
IIR:=tmpcom_base+$02;
LCR:=tmpcom_base+$03;
MCR:=tmpcom_base+$04;
LSR:=tmpcom_base+$05;
MSR:=tmpcom_base+$06;
end;
(* { if the impossible has happened, get the heck outta here... }
if (port[tmpcom_ports.IIR] and $F8<>0) then exit;*)
tmpcom_resetport(comport,baudrate,parity,wordsize,stopbits);
getintvec(tmpcom_irq+8,tmpcom_saveoldvec);
setintvec(tmpcom_irq+8,@tmpcom_isr);
tmpcom_resetport(comport,baudrate,parity,wordsize,stopbits);
tmpcom_clear_errors;
tmpcom_open_flag:=TRUE;
end;
procedure tmpcom_initvars;
begin
tmpcom_base:=$3f8;
tmpcom_irq:=4;
tmpcom_port:=1;
tmpcom_open_flag:=FALSE;
tmpcom_buffer_head:=0;
tmpcom_buffer_tail:=0;
tmpcom_buffer_used:=0;
tmpcom_outcharacter:=#0;
tmpcom_outgoingnow:=FALSE;
end;
function tmpcom_receive(var c:char):boolean;
begin
c:=#0;
if (tmpcom_buffer_head<>tmpcom_buffer_tail) then begin
inline($FA);
c:=chr(tmpcom_buffer[tmpcom_buffer_tail]);
tmpcom_buffer_tail:=(tmpcom_buffer_tail+1) mod (tmpcom_buffer_max+1);
inline($FB);
tmpcom_receive:=TRUE;
end else
tmpcom_receive:=FALSE;
end;
procedure tmpcom_sendno(c:char);
var i:integer;
begin
i:=port[tmpcom_ports.MSR];
while (port[tmpcom_ports.LSR] and $20=0) do ;
port[tmpcom_ports.RTB]:=ord(c);
end;
procedure tmpcom_send(c:char);
var lng:longint;
i:integer;
begin
inline($FB);
lng:=0; while ((tmpcom_outgoingnow) and (lng<500000)) do inc(lng);
if (lng>=500000) then begin
inline($FA); tmpcom_outgoingnow:=FALSE;
{ tmpcom_clear_errors;}
inline($FA); delay(100); inline($FB);
end;
{ enable transmit-register-empty interrupt }
inline($FA);
tmpcom_outcharacter:=c;
tmpcom_outgoingnow:=TRUE;
i:=port[tmpcom_ports.IER];
if (i and $02<>$02) then begin
i:=i or $02;
port[tmpcom_ports.IER]:=i;
end;
inline($FB);
(* inline($FA);
tmpcom_obuffer[tmpcom_obuffer_tail]:=c;
tmpcom_obuffer_tail:=(tmpcom_obuffer_tail+1) mod (tmpcom_obuffer_max+1);
inline($FB);*)
end;
begin
mpcoder:=FALSE;
tmpcom_open_flag:=FALSE;
end.