00001
00002 #include "struct.h"
00003 #include <sys/stat.h>
00004 #include <conio.h>
00005 #include <i86.h>
00006
00007
00008
00009
00010 int __far Kick(struct output_buffer __far *obuf);
00011 int __far Stty(struct termios __far *tios);
00012 int __far Ctrl(union ioctl_entry __far *ioc);
00013
00014 #pragma aux (_dev_call) Kick;
00015 #pragma aux (_dev_call) Stty;
00016 #pragma aux (_dev_call) Ctrl;
00017
00018 #pragma off (check_stack);
00019
00020 extern struct dev_entry dev_table[];
00021 extern struct driver_ctrl drv_ctrl;
00022 extern int num_asyncs;
00023
00024 int idle[MAX_ASYNCS] = {1};
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 pid_t tto(struct dev_entry *dev, struct output_buffer far *obuf) {
00036 char far *p;
00037 unsigned c, i, n;
00038 int sig = 0;
00039
00040 if(obuf->mode & OUTPUT_XOFF) {
00041 obuf->mode &= ~OUTPUT_XOFF;
00042 outp(dev->iobase, 0x13);
00043 return(0);
00044 }
00045
00046 if(obuf->mode & OUTPUT_XON) {
00047 obuf->mode &= ~OUTPUT_XON;
00048 outp(dev->iobase, 0x11);
00049 return(0);
00050 }
00051
00052 if(obuf->mode & OUTPUT_STOPPED) {
00053 dev->busy = 0;
00054 return(0);
00055 }
00056
00057 if(obuf->mode & OUTPUT_STOPPED_HW) {
00058 dev->busy = 0;
00059 return(0);
00060 }
00061
00062 if(obuf->discard) {
00063
00064
00065
00066 n = obuf->discard;
00067 obuf->discard -= n;
00068 obuf->size -= n;
00069 i = &obuf->buffer[obuf->length] - obuf->tail;
00070 if(i > n)
00071 obuf->tail += n;
00072 else
00073 obuf->tail = &obuf->buffer[n-i];
00074 }
00075
00076 if(dev->state || obuf->size > 0) {
00077 if(dev->state) {
00078 c = dev->state;
00079 dev->state = 0;
00080 }
00081 else {
00082
00083
00084
00085
00086 p = obuf->tail;
00087 if(p >= &obuf->buffer[obuf->length-1])
00088 obuf->tail = &obuf->buffer[0];
00089 else
00090 ++obuf->tail;
00091 --obuf->size;
00092 c = *p;
00093 }
00094
00095 if(obuf->mode & OUTPUT_XNL) {
00096 if(c == '\l')
00097 dev->state = '\r';
00098 }
00099
00100
00101
00102
00103 _disable();
00104 dev->tx_pending = 10;
00105 outp(dev->iobase, c);
00106 _enable();
00107 }
00108 else
00109 dev->busy = 0;
00110
00111
00112
00113
00114
00115 if(obuf->size < obuf->bcount) {
00116 obuf->bcount = 0;
00117 obuf->action |= ACT_OUTPUT_READY;
00118 sig = drv_ctrl.hw_pid;
00119 }
00120
00121 return(sig);
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 int far Kick(struct output_buffer far *obuf)
00138 {
00139 register struct dev_entry *dev;
00140
00141 dev = &dev_table[obuf->handle];
00142
00143 if(obuf->mode & OUTPUT_HFLOW_OFF) {
00144 obuf->mode &= ~OUTPUT_HFLOW_OFF;
00145
00146
00147
00148 dev->modem_control &= ~0x02;
00149 outp(dev->iobase+4, dev->modem_control);
00150 }
00151
00152 if(obuf->mode & OUTPUT_HFLOW_ON) {
00153 obuf->mode &= ~OUTPUT_HFLOW_ON;
00154
00155
00156
00157 dev->modem_control |= 0x02;
00158 outp(dev->iobase+4, dev->modem_control);
00159 }
00160
00161 if(dev->busy)
00162 return(0);
00163
00164 if((obuf->mode & (OUTPUT_XON|OUTPUT_XOFF)) != 0
00165 || obuf->size > 0 && (obuf->mode & OUTPUT_STOPPED) == 0) {
00166 dev->busy = 1;
00167 tto(dev, obuf);
00168 }
00169 return(1);
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 int far Stty(struct termios far *tios) {
00184 register struct dev_entry *dev;
00185 int index;
00186 unsigned short cflag;
00187 int status;
00188
00189 cflag = tios->c_cflag;
00190 index = tios->handle;
00191 dev = &dev_table[index];
00192 dev->baud = tios->c_ospeed;
00193
00194
00195
00196
00197
00198
00199
00200
00201 dev->parity = (((~cflag) & PARODD) >> 8)
00202 | ((cflag & PARENB) >> 8)
00203 | ((cflag & PARSTK) >> 0);
00204 dev->stop_bits = ((cflag & CSTOPB) >> 6) + 1;
00205 dev->data_bits = ((cflag & CSIZE) >> 4) + 5;
00206 status = reset_async(index, 0);
00207 return(status);
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 int far Ctrl(union ioctl_entry far *ioc) {
00222 int type;
00223 unsigned unit;
00224 struct dev_entry *dev;
00225
00226 type = ioc->type;
00227 ioc->status = IOCTL_ERROR;
00228
00229 if(type == IOCTL_OPEN) {
00230 ioc->status = IOCTL_OK;
00231 return(0);
00232 }
00233 else if(type == IOCTL_CLOSE) {
00234
00235
00236
00237 ioc->close.obuf->rows = 0;
00238 ioc->close.obuf->cols = 0;
00239 ioc->close_return.status = IOCTL_OK;
00240 return(0);
00241 }
00242 else if(type == IOCTL_CTL) {
00243 unsigned char bits, mask, oldbits;
00244
00245 unit = ioc->close.unit;
00246 if(unit > num_asyncs || unit <= 0) {
00247 ioc->status = IOCTL_BAD_UNIT;
00248 return(0);
00249 }
00250 dev = &dev_table[unit-1];
00251
00252 mask = ioc->user.data[4] & 0x03;
00253 bits = ioc->user.data[0];
00254 _disable();
00255 oldbits = inp( dev->iobase + 4 );
00256 dev->modem_control = (oldbits & ~mask & 0xE7) | (bits & mask) | 0x08;
00257 outp( dev->iobase + 4, dev->modem_control);
00258 _enable();
00259 ioc->user_return.data[0] = oldbits;
00260
00261 mask = ioc->user.data[5] & 0x40;
00262 bits = ioc->user.data[1];
00263 _disable();
00264 oldbits = inp( dev->iobase + 3 );
00265 outp( dev->iobase + 3, (oldbits & ~mask) | (bits & mask));
00266 _enable();
00267 ioc->user_return.data[1] = oldbits;
00268
00269 ioc->user_return.data[2] = dev->modem_status & 0xF0;
00270
00271 ioc->user_return.data[3] = 0;
00272 ioc->user_return.nbytes = 4;
00273 ioc->user_return.status = IOCTL_OK;
00274 return(0);
00275 }
00276 else if(type == IOCTL_STARTBREAK) {
00277 unit = ioc->startbreak.unit;
00278 if(unit > num_asyncs || unit <= 0) {
00279 ioc->status = IOCTL_BAD_UNIT;
00280 return(0);
00281 }
00282 dev = &dev_table[unit-1];
00283 outp( dev->iobase + 3, inp( dev->iobase + 3 ) | 0x40);
00284 ioc->status = IOCTL_OK;
00285 return(0);
00286 }
00287 else if(type == IOCTL_STOPBREAK) {
00288 unit = ioc->stopbreak.unit;
00289 if(unit > num_asyncs || unit <= 0) {
00290 ioc->status = IOCTL_BAD_UNIT;
00291 return(0);
00292 }
00293 dev = &dev_table[unit-1];
00294 outp( dev->iobase + 3, inp( dev->iobase + 3 ) & ~0x40);
00295 ioc->status = IOCTL_OK;
00296 return(0);
00297 }
00298 else if(type == IOCTL_STARTDROP) {
00299 unit = ioc->startdrop.unit;
00300 if(unit > num_asyncs || unit <= 0) {
00301 ioc->status = IOCTL_BAD_UNIT;
00302 return(0);
00303 }
00304 dev = &dev_table[unit-1];
00305 dev->modem_control &= ~0x01;
00306 outp(dev->iobase+4, dev->modem_control);
00307 ioc->status = IOCTL_OK;
00308 return(0);
00309 }
00310 else if(type == IOCTL_STOPDROP) {
00311 unit = ioc->stopdrop.unit;
00312 if(unit > num_asyncs || unit <= 0) {
00313 ioc->status = IOCTL_BAD_UNIT;
00314 return(0);
00315 }
00316 dev = &dev_table[unit-1];
00317 dev->modem_control |= 0x01;
00318 outp(dev->iobase+4, dev->modem_control);
00319 ioc->status = IOCTL_OK;
00320 return(0);
00321 }
00322 return(-1);
00323 }
00324
00325 #pragma on (check_stack);