1 /*
2 * msdos.cxx
3 *
4 * General class implementation for MS-DOS
5 *
6 * Portable Windows Library
7 *
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9 *
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
14 *
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * The Original Code is Portable Windows Library.
21 *
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23 *
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
26 *
27 * Contributor(s): ______________________________________.
28 *
29 * $Revision: 20385 $
30 * $Author: rjongbloed $
31 * $Date: 2008-06-04 05:40:38 -0500 (Wed, 04 Jun 2008) $
32 */
33
34 #include "ptlib.h"
35
36 #include <bios.h>
37 #include <fcntl.h>
38
39
40 ///////////////////////////////////////////////////////////////////////////////
41 // PTime
42
GetTimeSeparator()43 PString PTime::GetTimeSeparator()
44 {
45 return "";
46 }
47
48
GetTimeAMPM()49 PBoolean PTime::GetTimeAMPM()
50 {
51 return PFalse;
52 }
53
54
GetTimeAM()55 PString PTime::GetTimeAM()
56 {
57 return "am";
58 }
59
60
GetTimePM()61 PString PTime::GetTimePM()
62 {
63 return "pm";
64 }
65
66
GetDayName(Weekdays dayOfWeek,NameType type)67 PString PTime::GetDayName(Weekdays dayOfWeek, NameType type)
68 {
69 static const char * const weekdays[] = {
70 "Sunday", "Monday", "Tuesday", "Wednesday",
71 "Thursday", "Friday", "Saturday"
72 };
73 static const char * const abbrev_weekdays[] = {
74 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
75 };
76 return (type != FullName ? abbrev_weekdays : weekdays)[dayOfWeek];
77 }
78
79
GetDateSeparator()80 PString PTime::GetDateSeparator()
81 {
82 return "-";
83 }
84
85
GetMonthName(Months month,NameType type)86 PString PTime::GetMonthName(Months month, NameType type)
87 {
88 static const char * const months[] = { "",
89 "January", "February", "March", "April", "May", "June",
90 "July", "August", "September", "October", "November", "December"
91 };
92 static const char * const abbrev_months[] = {
93 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
94 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
95 };
96 return (type != FullName ? abbrev_months : months)[month];
97 }
98
99
GetDateOrder()100 PTime::DateOrder PTime::GetDateOrder()
101 {
102 return DayMonthYear;
103 }
104
105
GetTimeZone() const106 long PTime::GetTimeZone() const
107 {
108 return 0;
109 }
110
111
GetTimeZoneString(TimeZoneType type) const112 PString PTime::GetTimeZoneString(TimeZoneType type) const
113 {
114 return "";
115 }
116
117
118
119 ///////////////////////////////////////////////////////////////////////////////
120 // PSerialChannel
121
Construct()122 void PSerialChannel::Construct()
123 {
124 biosParm = 0xe3; // 9600 baud, no parity, 1 stop bit, 8 data bits
125 }
126
127
GetName() const128 PString PSerialChannel::GetName() const
129 {
130 if (IsOpen())
131 return psprintf("COM%i", os_handle+1);
132
133 return PString();
134 }
135
136
Read(void * buf,PINDEX len)137 PBoolean PSerialChannel::Read(void * buf, PINDEX len)
138 {
139 char * b = (char *)buf;
140 while (len > 0) {
141 int c = ReadChar();
142 if (c >= 0) {
143 *b++ = (char)c;
144 len--;
145 }
146 }
147 return len == 0;
148 }
149
150
Write(const void * buf,PINDEX len)151 PBoolean PSerialChannel::Write(const void * buf, PINDEX len)
152 {
153 const char * b = (const char *)buf;
154 while (len-- > 0) {
155 if (!WriteChar(*b++))
156 return PFalse;
157 }
158 return PTrue;
159 }
160
161
Close()162 PBoolean PSerialChannel::Close()
163 {
164 if (!IsOpen())
165 return PFalse;
166
167 os_handle = -1;
168 return PTrue;
169 }
170
171
SetCommsParam(DWORD speed,BYTE data,Parity parity,BYTE stop,FlowControl inputFlow,FlowControl outputFlow)172 PBoolean PSerialChannel::SetCommsParam(DWORD speed, BYTE data, Parity parity,
173 BYTE stop, FlowControl inputFlow, FlowControl outputFlow)
174 {
175 switch (speed) {
176 case 0 :
177 break;
178 case 110 :
179 biosParm &= 0x1f;
180 break;
181 case 150 :
182 biosParm &= 0x1f;
183 biosParm |= 0x20;
184 break;
185 case 300 :
186 biosParm &= 0x1f;
187 biosParm |= 0x40;
188 break;
189 case 600 :
190 biosParm &= 0x1f;
191 biosParm |= 0x60;
192 break;
193 case 1200 :
194 biosParm &= 0x1f;
195 biosParm |= 0x80;
196 break;
197 case 2400 :
198 biosParm &= 0x1f;
199 biosParm |= 0xa0;
200 break;
201 case 4800 :
202 biosParm &= 0x1f;
203 biosParm |= 0xc0;
204 break;
205 case 9600 :
206 biosParm &= 0x1f;
207 biosParm |= 0xe0;
208 break;
209 default :
210 return PFalse;
211 }
212
213 switch (data) {
214 case 0 :
215 break;
216 case 5 :
217 biosParm &= 0xfc;
218 break;
219 case 6 :
220 biosParm &= 0xfc;
221 biosParm |= 1;
222 break;
223 case 7 :
224 biosParm &= 0xfc;
225 biosParm |= 2;
226 break;
227 case 8 :
228 biosParm &= 0xfc;
229 biosParm |= 3;
230 break;
231 default :
232 return PFalse;
233 }
234
235 switch (parity) {
236 case DefaultParity :
237 break;
238 case NoParity :
239 biosParm &= 0xe7;
240 break;
241 case OddParity :
242 biosParm &= 0xe7;
243 biosParm |= 8;
244 break;
245 case EvenParity :
246 biosParm &= 0xe7;
247 biosParm |= 0x10;
248 break;
249 default :
250 return PFalse;
251 }
252
253 switch (stop) {
254 case 0 :
255 break;
256 case 1 :
257 biosParm &= ~4;
258 break;
259 case 2 :
260 biosParm |= 4;
261 break;
262 default :
263 return PFalse;
264 }
265
266 if (outputFlow != DefaultFlowControl || inputFlow != DefaultFlowControl)
267 return PFalse;
268
269 _bios_serialcom(_COM_INIT, os_handle, biosParm);
270 return PTrue;
271 }
272
Open(const PString & port,DWORD speed,BYTE data,Parity parity,BYTE stop,FlowControl inputFlow,FlowControl outputFlow)273 PBoolean PSerialChannel::Open(const PString & port, DWORD speed, BYTE data,
274 Parity parity, BYTE stop, FlowControl inputFlow, FlowControl outputFlow)
275 {
276 Close();
277
278 os_handle = -1;
279 if (PCaselessString("COM") != port.Left(3) &&
280 port[3] >= '1' && port[3] <= '4')
281 return PFalse;
282 os_handle = port[3] - '1';
283 return SetCommsParam(speed, data, parity, stop, inputFlow, outputFlow);
284 }
285
286
SetSpeed(DWORD speed)287 PBoolean PSerialChannel::SetSpeed(DWORD speed)
288 {
289 return SetCommsParam(speed,
290 0, DefaultParity, 0, DefaultFlowControl, DefaultFlowControl);
291 }
292
293
GetSpeed() const294 DWORD PSerialChannel::GetSpeed() const
295 {
296 static int speed[8] = { 110, 150, 300, 600, 1200, 2400, 4800, 9600 };
297 return speed[biosParm>>5];
298 }
299
300
SetDataBits(BYTE data)301 PBoolean PSerialChannel::SetDataBits(BYTE data)
302 {
303 return SetCommsParam(0,
304 data, DefaultParity, 0, DefaultFlowControl, DefaultFlowControl);
305 }
306
307
GetDataBits() const308 BYTE PSerialChannel::GetDataBits() const
309 {
310 return (BYTE)((biosParm&3)+5);
311 }
312
313
SetParity(Parity parity)314 PBoolean PSerialChannel::SetParity(Parity parity)
315 {
316 return SetCommsParam(0,0, parity, 0, DefaultFlowControl, DefaultFlowControl);
317 }
318
319
GetParity() const320 PSerialChannel::Parity PSerialChannel::GetParity() const
321 {
322 return (biosParm&8) == 0 ? NoParity :
323 (biosParm&0x10) == 0 ? OddParity : EvenParity;
324 }
325
326
SetStopBits(BYTE stop)327 PBoolean PSerialChannel::SetStopBits(BYTE stop)
328 {
329 return SetCommsParam(0,
330 0, DefaultParity, stop, DefaultFlowControl, DefaultFlowControl);
331 }
332
333
GetStopBits() const334 BYTE PSerialChannel::GetStopBits() const
335 {
336 return (BYTE)(((biosParm&4)>>3)+1);
337 }
338
339
SetInputFlowControl(FlowControl flowControl)340 PBoolean PSerialChannel::SetInputFlowControl(FlowControl flowControl)
341 {
342 return SetCommsParam(0,0, DefaultParity, 0, flowControl, DefaultFlowControl);
343 }
344
345
GetInputFlowControl() const346 PSerialChannel::FlowControl PSerialChannel::GetInputFlowControl() const
347 {
348 return RtsCts;
349 }
350
351
SetOutputFlowControl(FlowControl flowControl)352 PBoolean PSerialChannel::SetOutputFlowControl(FlowControl flowControl)
353 {
354 return SetCommsParam(0,0, DefaultParity, 0, DefaultFlowControl, flowControl);
355 }
356
357
GetOutputFlowControl() const358 PSerialChannel::FlowControl PSerialChannel::GetOutputFlowControl() const
359 {
360 return RtsCts;
361 }
362
363
SetDTR(PBoolean state)364 void PSerialChannel::SetDTR(PBoolean state)
365 {
366 if (!IsOpen())
367 return;
368
369 }
370
371
SetRTS(PBoolean state)372 void PSerialChannel::SetRTS(PBoolean state)
373 {
374 if (!IsOpen())
375 return;
376
377 }
378
379
SetBreak(PBoolean state)380 void PSerialChannel::SetBreak(PBoolean state)
381 {
382 if (!IsOpen())
383 return;
384
385 int s = state;
386 }
387
388
GetCTS()389 PBoolean PSerialChannel::GetCTS()
390 {
391 if (!IsOpen())
392 return PFalse;
393
394 return (_bios_serialcom(_COM_STATUS, os_handle, 0)&0x8010) == 0x10;
395 }
396
397
GetDSR()398 PBoolean PSerialChannel::GetDSR()
399 {
400 if (!IsOpen())
401 return PFalse;
402
403 return (_bios_serialcom(_COM_STATUS, os_handle, 0)&0x8020) == 0x20;
404 }
405
406
GetDCD()407 PBoolean PSerialChannel::GetDCD()
408 {
409 if (!IsOpen())
410 return PFalse;
411
412 return (_bios_serialcom(_COM_STATUS, os_handle, 0)&0x8080) == 0x80;
413 }
414
415
GetRing()416 PBoolean PSerialChannel::GetRing()
417 {
418 if (!IsOpen())
419 return PFalse;
420
421 return (_bios_serialcom(_COM_STATUS, os_handle, 0)&0x8040) == 0x40;
422 }
423
424
GetPortNames()425 PStringList PSerialChannel::GetPortNames()
426 {
427 static char buf[] = "COM ";
428 PStringList ports;
429 for (char p = '1'; p <= '4'; p++) {
430 if (*(WORD *)(0x00400000+p-'1') != 0) {
431 buf[3] = p;
432 ports.Append(new PString(buf));
433 }
434 }
435 return ports;
436 }
437
438
439 ///////////////////////////////////////////////////////////////////////////////
440 // PPipeChannel
441
Execute()442 PBoolean PPipeChannel::Execute()
443 {
444 if (hasRun)
445 return PFalse;
446
447 flush();
448 if (os_handle >= 0) {
449 _close(os_handle);
450 os_handle = -1;
451 }
452
453 if (!ConvertOSError(system(subProgName)))
454 return PFalse;
455
456 if (!fromChild.IsEmpty()) {
457 os_handle = _open(fromChild, _O_RDONLY);
458 if (!ConvertOSError(os_handle))
459 return PFalse;
460 }
461
462 return PTrue;
463 }
464
465
466 ///////////////////////////////////////////////////////////////////////////////
467 // Configuration files
468
Construct(Source src)469 void PConfig::Construct(Source src)
470 {
471 switch (src) {
472 case Application :
473 PFilePath appFile = PProcess::Current()->GetFile();
474 location = appFile.GetVolume() +
475 appFile.GetPath() + appFile.GetTitle() + ".INI";
476 }
477 }
478
479
Construct(const PFilePath & file)480 void PConfig::Construct(const PFilePath & file)
481 {
482 location = file;
483 }
484
485
GetSections()486 PStringList PConfig::GetSections()
487 {
488 PStringList sections;
489
490 if (!location.IsEmpty()) {
491 PAssertAlways(PUnimplementedFunction);
492 }
493
494 return sections;
495 }
496
497
GetKeys(const PString &) const498 PStringList PConfig::GetKeys(const PString &) const
499 {
500 PStringList keys;
501
502 if (location.IsEmpty()) {
503 char ** ptr = _environ;
504 while (*ptr != NULL) {
505 PString buf = *ptr++;
506 keys.AppendString(buf.Left(buf.Find('=')));
507 }
508 }
509 else {
510 PAssertAlways(PUnimplementedFunction);
511 }
512
513 return keys;
514 }
515
516
DeleteSection(const PString &)517 void PConfig::DeleteSection(const PString &)
518 {
519 if (location.IsEmpty())
520 return;
521
522 PAssertAlways(PUnimplementedFunction);
523 }
524
525
DeleteKey(const PString &,const PString & key)526 void PConfig::DeleteKey(const PString &, const PString & key)
527 {
528 if (location.IsEmpty()) {
529 PAssert(key.Find('=') == P_MAX_INDEX, PInvalidParameter);
530 _putenv(key + "=");
531 }
532 else
533 PAssertAlways(PUnimplementedFunction);
534 }
535
536
GetString(const PString &,const PString & key,const PString & dflt)537 PString PConfig::GetString(const PString &,
538 const PString & key, const PString & dflt)
539 {
540 PString str;
541
542 if (location.IsEmpty()) {
543 PAssert(key.Find('=') == P_MAX_INDEX, PInvalidParameter);
544 char * env = getenv(key);
545 if (env != NULL)
546 str = env;
547 else
548 str = dflt;
549 }
550 else {
551 PAssertAlways(PUnimplementedFunction);
552 }
553 return str;
554 }
555
556
SetString(const PString &,const PString & key,const PString & value)557 void PConfig::SetString(const PString &, const PString & key, const PString & value)
558 {
559 if (location.IsEmpty()) {
560 PAssert(key.Find('=') == P_MAX_INDEX, PInvalidParameter);
561 _putenv(key + "=" + value);
562 }
563 else
564 PAssertAlways(PUnimplementedFunction);
565 }
566
567
568
569 ///////////////////////////////////////////////////////////////////////////////
570 // Threads
571
SwitchContext(PThread * from)572 void PThread::SwitchContext(PThread * from)
573 {
574 if (setjmp(from->context) != 0) // Are being reactivated from previous yield
575 return;
576
577 if (status == Starting) {
578 if (setjmp(context) != 0) {
579 status = Running;
580 Main();
581 Terminate(); // Never returns from here
582 }
583 context[7] = (int)stackTop-16; // Change the stack pointer in jmp_buf
584 }
585
586 longjmp(context, PTrue);
587 PAssertAlways("longjmp failed"); // Should never get here
588 }
589
590
591
592 ///////////////////////////////////////////////////////////////////////////////
593 // PDynaLink
594
PDynaLink()595 PDynaLink::PDynaLink()
596 {
597 PAssertAlways(PUnimplementedFunction);
598 }
599
600
PDynaLink(const PString &)601 PDynaLink::PDynaLink(const PString &)
602 {
603 PAssertAlways(PUnimplementedFunction);
604 }
605
606
~PDynaLink()607 PDynaLink::~PDynaLink()
608 {
609 }
610
611
Open(const PString & name)612 PBoolean PDynaLink::Open(const PString & name)
613 {
614 PAssertAlways(PUnimplementedFunction);
615 return PFalse;
616 }
617
618
Close()619 void PDynaLink::Close()
620 {
621 }
622
623
IsLoaded() const624 PBoolean PDynaLink::IsLoaded() const
625 {
626 return PFalse;
627 }
628
629
GetFunction(PINDEX index,Function & func)630 PBoolean PDynaLink::GetFunction(PINDEX index, Function & func)
631 {
632 return PFalse;
633 }
634
635
GetFunction(const PString & name,Function & func)636 PBoolean PDynaLink::GetFunction(const PString & name, Function & func)
637 {
638 return PFalse;
639 }
640
641
642
643 // End Of File ///////////////////////////////////////////////////////////////
644