source: anotherchoice/tags/jsp-1.4.4-full-UTF8/config/windows/hw_serial.c@ 26

Last change on this file since 26 was 26, checked in by ykominami, 12 years ago

initial

File size: 21.4 KB
Line 
1/*
2 * TOPPERS/JSP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 *
9 * 上記著作権者
10は,以下の (1)〜(4) の条件か,Free Software Foundation
11 * によってå…
12¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
13 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
14 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
16 * 利用と呼ぶ)することを無償で許諾する.
17 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
18 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
19 * スコード中に含まれていること.
20 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
21 * 用できる形で再é…
22å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
23å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
24 * 者
25マニュアルなど)に,上記の著作権表示,この利用条件および下記
26 * の無保証規定を掲載すること.
27 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
28 * 用できない形で再é…
29å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
30 * と.
31 * (a) 再é…
32å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
33マニュアルなど)に,上記の著
34 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
35 * (b) 再é…
36å¸ƒã®å½¢æ…
37‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
38 * 報告すること.
39 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
40 * 害からも,上記著作権者
41およびTOPPERSプロジェクトをå…
42è²¬ã™ã‚‹ã“と.
43 *
44 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
45お
46 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
47 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
48 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
49 *
50 * @(#) $Id: hw_serial.c,v 1.13 2003/12/15 07:19:22 takayuki Exp $
51 */
52
53
54
55#include <hw_serial.h>
56#include <hal_msg.h>
57#include <t_services.h>
58
59#include <resource.h>
60#include <debugout.h>
61
62#define BUFSZ_UPPERBOUND 24*1024 /* コンソールバッファの巻戻し基準サイズ (これを超
63えると巻き戻し) (どうやら30000を超
64えられないらしい)*/
65#define BUFSZ_LOWERBOUND 8*1024 /* 巻き戻したときにどのくらい巻き戻すか (UPPERBOUNDよりも小さい数)*/
66
67#define ID_PORT(x) ((x) + 1)
68#define INDEX_PORT(x) ((x) - 1)
69#define GET_SIOPCB(x) (&siopcb_table[INDEX_PORT(x)])
70
71#define BITTEST(x,y) ( ( (x) & (y) ) != 0)
72#define BITSET(x,y) InterlockedExchange( &(x), (x) | (y) )
73#define BITCLEAR(x,y) InterlockedExchange( &(x), (x) & ~(y) )
74
75extern HINSTANCE ProcessInstance;
76extern HANDLE PrimaryThreadHandle;
77
78 /* シリアル制御ブロック */
79SIOPCB siopcb_table[TNUM_PORT];
80
81
82 /* 致命的なエラー発生時用アサート */
83extern void FatalAssertion(int exp, LPCSTR format, ... );
84
85
86/*
87 * シリアルI/Oå…
88±é€šéƒ¨ã‚¤ãƒ³ã‚¿ãƒ•ã‚§ãƒ¼ã‚¹
89 */
90
91/*===========================================================================*/
92
93/*
94 * コンソール型シリアル
95 */
96
97#define MAX_CONSOLE_BUFSZ 2048
98#define SERMSG_CREATE WM_APP
99#define SERMSG_UPDATE (WM_APP+1)
100
101struct tagSerialConsoleParameters
102{
103 CRITICAL_SECTION cs;
104 unsigned int position;
105 char buffer[MAX_CONSOLE_BUFSZ];
106};
107
108
109static LRESULT CALLBACK KeyEventTrapper(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
110{
111 SIOPCB * scope;
112
113 /* WM_CHARをフックする */
114 if(Msg == WM_CHAR)
115 {
116 scope = (SIOPCB *)GetWindowLong(GetParent(hWnd),GWL_USERDATA);
117 PostMessage(scope->Handle,WM_CHAR,wParam,lParam);
118 return TRUE;
119 }
120
121 /* もともとのWndProcを呼びなおす */
122 return CallWindowProc((void *)GetWindowLong(hWnd,GWL_USERDATA),hWnd,Msg,wParam,lParam);
123}
124
125static void SelectConsoleFont(HWND console, UINT pixel)
126{
127 HANDLE oldfont;
128 HANDLE newfont;
129 LOGFONT logfont;
130 HDC hDC;
131
132 /* DC取得 */
133 hDC = GetDC(console);
134
135 /* 今のフォント情
136報を取得する */
137 oldfont = (HANDLE) SendMessage(console, WM_GETFONT, 0, 0);
138 GetObject(oldfont, sizeof(LOGFONT), &logfont);
139
140 /* ポイントを変更 */
141 logfont.lfHeight = -MulDiv(pixel, GetDeviceCaps(hDC, LOGPIXELSY), 72);
142
143 /* 更新したフォント情
144報をå…
145ƒã«ã€æ–°ã—いフォントを生成して選択 */
146 newfont = CreateFontIndirect(&logfont);
147 SendMessage(console, WM_SETFONT, (WPARAM)newfont, MAKELPARAM(TRUE,0));
148
149 /* 前のフォントを破棄 */
150 DeleteObject(oldfont);
151
152 /* DC解放 */
153 ReleaseDC(console, hDC);
154}
155
156static LRESULT ConsoleCommandHandler(HWND hDlg, UINT wID, UINT wNotifyCode, LPARAM lParam)
157{
158 BOOL result;
159 HANDLE console;
160
161 result = TRUE;
162 console = GetDlgItem(hDlg, IDC_CONSOLE);
163
164 switch(wID)
165 {
166 /*
167 * フォントの大きさを変更する
168 */
169 case ID_FONT_BIG:
170 SelectConsoleFont(console, 16);
171 break;
172 case ID_FONT_NORMAL:
173 SelectConsoleFont(console, 9);
174 break;
175 case ID_FONT_SMALL:
176 SelectConsoleFont(console, 4);
177 break;
178
179 default:
180 result = FALSE;
181 }
182
183 return result;
184}
185
186static BOOL CALLBACK ConsoleProc(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam)
187{
188 switch(Msg)
189 {
190 case SERMSG_CREATE:
191 {
192 SIOPCB * work;
193 void * DefWndProc;
194 HWND hConsole;
195
196 hConsole = GetDlgItem(hDlg, IDC_CONSOLE);
197
198 /* テキストボックスのWndProcにフックをかける */
199 DefWndProc = (void *)GetWindowLong(hConsole,GWL_WNDPROC);
200 SetWindowLong(hConsole, GWL_USERDATA, (LONG) DefWndProc);
201
202 work = (SIOPCB *)lParam;
203 SetWindowLong(hDlg,GWL_USERDATA,lParam);
204 SetWindowLong(hConsole, GWL_WNDPROC, (long)KeyEventTrapper);
205
206 SetTimer(hDlg, 100, 300, NULL);
207
208 ShowWindow(hDlg,SW_SHOWNA);
209 break;
210 }
211
212 case WM_DESTROY:
213 {
214 SIOPCB * scope;
215 KillTimer(hDlg, 100);
216 scope = (SIOPCB *)GetWindowLong(hDlg,GWL_USERDATA);
217 if(scope != 0)
218 scope->Handle = NULL;
219 break;
220 }
221
222 case WM_CLOSE: /* ユーザによるウィンドウクローズを抑止 */
223 break;
224
225 case WM_CHAR:
226 {
227 SIOPCB * scope;
228 scope = (SIOPCB *)GetWindowLong(hDlg,GWL_USERDATA);
229 if(scope != 0)
230 {
231 scope->ReceiveBuffer = (char)wParam;
232 BITSET(scope->Flag, SIO_STA_INTRCV);
233 HALInterruptRequest(INHNO_SERIAL);
234 }
235 break;
236 }
237
238 case WM_SETFONT:
239 return TRUE;
240
241 case WM_INITDIALOG:
242 case WM_SIZE:
243 {
244 RECT client;
245 GetClientRect(hDlg,&client);
246 MoveWindow(GetDlgItem(hDlg,IDC_CONSOLE),0,0,client.right,client.bottom,TRUE);
247 break;
248 }
249
250 case WM_COMMAND:
251 return ConsoleCommandHandler(hDlg, LOWORD(wParam), HIWORD(wParam), lParam);
252
253 //一定時間たったら改行がこなくても出力する
254 case WM_TIMER:
255 if(wParam == 100)
256 {
257 SIOPCB * scope;
258 struct tagSerialConsoleParameters * param;
259
260 scope = (SIOPCB *)GetWindowLong(hDlg, GWL_USERDATA);
261 if(scope != 0) {
262 param = (struct tagSerialConsoleParameters *)scope->versatile;
263 if(param->position == 0)
264 break;
265
266 lParam = TRUE;
267 }
268 else
269 break; //まだ初期化が終わってないので何もしない
270 }
271
272 //lParam : 送信が終わった後に割込みをかけるかどうか (FALSE:かけない TRUE:かける)
273 case SERMSG_UPDATE:
274 {
275 LRESULT result;
276 int textlength;
277 HANDLE console;
278 SIOPCB * scope;
279 struct tagSerialConsoleParameters * param;
280
281 scope = (SIOPCB *)GetWindowLong(hDlg, GWL_USERDATA);
282 if(scope != 0) {
283 param = (struct tagSerialConsoleParameters *)scope->versatile;
284
285 console = GetDlgItem(hDlg, IDC_CONSOLE);
286
287 textlength = GetWindowTextLength(console);
288 if(textlength > BUFSZ_UPPERBOUND)
289 {
290 /* 古い情
291報を消す */
292 SendMessage(console,EM_SETSEL,0,textlength - BUFSZ_LOWERBOUND);
293 SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)"");
294 textlength = GetWindowTextLength(console);
295 }
296 /* 末尾に文字を置く */
297 result = SendMessage(console,EM_SETSEL,textlength,textlength);
298
299 EnterCriticalSection(&param->cs);
300 param->buffer[param->position] = '\x0';
301 result = SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)param->buffer);
302 param->position = 0;
303 LeaveCriticalSection(&param->cs);
304
305 if(lParam == TRUE)
306 {
307 BITSET(scope->Flag, SIO_STA_INTSND);
308 HALInterruptRequest(INHNO_SERIAL);
309 }
310 }
311 else
312 PostMessage(hDlg, Msg, wParam, lParam); //まだ初期化が終わってないので末尾につけなおす
313
314 break;
315 }
316
317 default:
318 return FALSE;
319 }
320
321 return TRUE;
322}
323
324static void SerialConsole_FinalRelease(void * param)
325{
326 SIOPCB * cb = (SIOPCB *)param;
327 struct tagSerialConsoleParameters * versatile;
328
329 if(cb->Handle != 0l && cb->Handle != NULL)
330 DestroyWindow(cb->Handle);
331 cb->Handle = NULL;
332
333 versatile = cb->versatile;
334 DeleteCriticalSection(&versatile->cs);
335 GlobalFree((HGLOBAL)versatile);
336}
337
338static void CreateSerialConsole(SIOPCB * cb)
339{
340 struct tagSerialConsoleParameters * param;
341
342 param = GlobalAlloc(GMEM_FIXED, sizeof(struct tagSerialConsoleParameters));
343 FatalAssertion(param != NULL, "CreateSerialConsole: GlobalAlloc reported NULL.");
344 param->position = 0;
345 InitializeCriticalSection(&param->cs);
346 cb->versatile = param;
347
348 cb->Handle = CreateDialog(ProcessInstance, MAKEINTRESOURCE(CONSOLEDIALOG), 0, ConsoleProc);
349 FatalAssertion(cb->Handle != 0, "CreateSerialConsole could not create its dialog.");
350 PostMessage(cb->Handle,SERMSG_CREATE,0,(LPARAM)cb);
351 UpdateWindow(cb->Handle);
352 HALAddDestructionProcedure(SerialConsole_FinalRelease,cb);
353}
354
355static BOOL SerialConsole_PutChar(SIOPCB * cb, INT chr, BOOL rasint)
356{
357 char buffer[2];
358 int textlength;
359 HANDLE console;
360
361 assert(cb != NULL);
362 assert(BITTEST(cb->Flag, SIO_TYP_CONSOLE));
363 assert(cb->Handle != NULL);
364
365 console = GetDlgItem(cb->Handle, IDC_CONSOLE);
366 buffer[0] = (char) chr;
367 buffer[1] = '\x0';
368
369 textlength = GetWindowTextLength(console);
370 if(textlength > BUFSZ_UPPERBOUND)
371 {
372 /* 古い情
373報を消す */
374 SendMessage(console,EM_SETSEL,0,textlength - BUFSZ_LOWERBOUND);
375 SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)"");
376 textlength = GetWindowTextLength(console);
377 }
378 /* 末尾に文字を置く */
379 SendMessage(console,EM_SETSEL,textlength,textlength);
380 SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)buffer);
381
382 if(rasint == TRUE)
383 {
384 BITSET(cb->Flag, SIO_STA_INTSND);
385 HALInterruptRequest(INHNO_SERIAL);
386 }
387
388 return TRUE;
389}
390
391static BOOL SerialConsole_PushChar(SIOPCB * cb, INT chr)
392{
393 BOOL success;
394 BOOL update;
395 struct tagSerialConsoleParameters * param;
396
397 param = (struct tagSerialConsoleParameters *)cb->versatile;
398
399 do {
400 success = FALSE;
401 update = FALSE;
402
403 EnterCriticalSection(&param->cs);
404
405 if(param->position < MAX_CONSOLE_BUFSZ)
406 {
407 param->buffer[param->position] = (char)chr;
408 param->position ++;
409
410 if(chr == '\n')
411 update = TRUE;
412 }else
413 update = TRUE;
414
415 LeaveCriticalSection(&param->cs);
416
417 if(update == TRUE)
418 SendMessage(cb->Handle, SERMSG_UPDATE, 0, 1);
419 } while(success == TRUE);
420
421 return TRUE;
422}
423
424/*===========================================================================*/
425
426/*
427 * Windowsのコンソールを使用したシリアルå…
428¥å‡ºåŠ›
429 */
430
431static DWORD WINAPI WinConsole_ReceiverThread(LPVOID param)
432{
433 SIOPCB * cb = (SIOPCB *)param;
434 DWORD work;
435 HANDLE stdin;
436 INPUT_RECORD input_record;
437
438 assert(cb != NULL);
439 assert(cb->Handle != NULL && cb->Handle != 0);
440
441 stdin = GetStdHandle(STD_INPUT_HANDLE);
442 FatalAssertion(stdin != 0, "WinConsole_ReceiverThread failed to acquire the handle of standard input.");
443
444 while((work = WaitForSingleObject(cb->Handle, INFINITE)) != WAIT_FAILED)
445 {
446 assert(work == WAIT_OBJECT_0); /* オブジェクトはシグナル状æ…
447‹ã«ãªã£ãŸ */
448
449 ReadConsoleInput(stdin, &input_record, 1, &work);
450
451 if(input_record.EventType == KEY_EVENT && input_record.Event.KeyEvent.bKeyDown == TRUE)
452 {
453 cb->ReceiveBuffer = (char)input_record.Event.KeyEvent.uChar.AsciiChar;
454
455 BITSET(cb->Flag, SIO_STA_INTRCV);
456 HALInterruptRequest(INHNO_SERIAL);
457 }
458 }
459
460 return 0;
461}
462
463static void WinConsole_CreatePort(SIOPCB * cb)
464{
465 BOOL result;
466 result = AllocConsole();
467 FatalAssertion(result != 0, "WinConsole_CreatePort failed to allocate its own console.");
468 cb->Handle = GetStdHandle(STD_OUTPUT_HANDLE);
469 SetConsoleTitle("TOPPERS/JSP SerialConsole");
470
471 /* 受信バッファ監視用スレッドを作成 */
472 CreateThread(NULL,0,WinConsole_ReceiverThread,(LPVOID)cb,0,NULL);
473}
474
475static BOOL WinConsole_PutChar(SIOPCB * cb, INT chr, BOOL rasint)
476{
477 BOOL result;
478 DWORD written;
479 char word;
480
481 assert(cb != NULL);
482 assert(BITTEST(cb->Flag, SIO_TYP_TTY));
483 assert(cb->Handle != NULL && cb->Handle != 0);
484
485 /* 標準出力に一文字送信 */
486 word = (char)chr;
487 result = WriteFile(cb->Handle, &word, 1, &written, NULL);
488
489 /* 割込み発生フラグが立っていたら、送信完了割込み要求を起こす */
490 if(result != 0 && rasint == TRUE)
491 {
492 BITSET(cb->Flag, SIO_STA_INTSND);
493 HALInterruptRequest(INHNO_SERIAL);
494 }
495
496 return result != 0 ? TRUE : FALSE;
497}
498
499static void WinConsole_ClosePort(SIOPCB * cb)
500{
501 assert(cb != NULL);
502 assert(BITTEST(cb->Flag, SIO_TYP_TTY));
503
504 if(cb->Handle != NULL && cb->Handle != 0)
505 {
506 FreeConsole();
507 cb->Handle = NULL;
508 }
509}
510
511/*===========================================================================*/
512
513/*
514 * Windowsのコンソールを使用したシリアルå…
515¥å‡ºåŠ›
516 */
517
518/* 注 : CreateConsoleScreenBufferは失敗時にINVALID_HANDLE_VALUEを返すが、
519 他のシリアルå…
520¥å‡ºåŠ›éƒ¨ã¨å…
521±é€šã‹ã™ã‚‹ãŸã‚ã«NULLを用いる。 */
522
523static DWORD WINAPI ScreenBuffer_ReceiverThread(LPVOID param)
524{
525 SIOPCB * cb = (SIOPCB *)param;
526 DWORD work;
527 INPUT_RECORD input_record;
528
529 assert(cb != NULL);
530 assert(cb->Handle != NULL && cb->Handle != 0);
531
532 while((work = WaitForSingleObject(cb->Handle, INFINITE)) != WAIT_FAILED)
533 {
534 assert(work == WAIT_OBJECT_0); /* オブジェクトはシグナル状æ…
535‹ã«ãªã£ãŸ */
536
537 ReadConsoleInput(cb->Handle, &input_record, 1, &work);
538
539 if(input_record.EventType == KEY_EVENT && input_record.Event.KeyEvent.bKeyDown == TRUE)
540 {
541 cb->ReceiveBuffer = (char)input_record.Event.KeyEvent.uChar.AsciiChar;
542
543 BITSET(cb->Flag, SIO_STA_INTRCV);
544 HALInterruptRequest(INHNO_SERIAL);
545 }
546 }
547
548 return 0;
549}
550
551static void ScreenBuffer_CreatePort(SIOPCB * cb)
552{
553 cb->Handle = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
554
555 /* cb->Handle should not be compared with NULL because CreateConsoleScreenBuffer returns INVALID_HANDLE_VALUE if it failed */
556 FatalAssertion(cb->Handle != INVALID_HANDLE_VALUE && cb->Handle != NULL,
557 "ScreenBuffer_CreatePort failed to allocate its own console.");
558
559 SetConsoleActiveScreenBuffer(cb->Handle);
560 SetConsoleTitle("TOPPERS/JSP SerialConsole");
561
562 /* 受信バッファ監視用スレッドを作成 */
563 CreateThread(NULL,0,ScreenBuffer_ReceiverThread,(LPVOID)cb,0,NULL);
564}
565
566static BOOL ScreenBuffer_PutChar(SIOPCB * cb, INT chr, BOOL rasint)
567{
568 BOOL result;
569 DWORD written;
570 char word;
571
572 assert(cb != NULL);
573 assert(BITTEST(cb->Flag, SIO_TYP_SCRBUF));
574 assert(cb->Handle != NULL && cb->Handle != 0);
575
576 /* 標準出力に一文字送信 */
577 word = (char)chr;
578 result = WriteFile(cb->Handle, &word, 1, &written, NULL);
579
580 /* 割込み発生フラグが立っていたら、送信完了割込み要求を起こす */
581 if(result != 0 && rasint == TRUE)
582 {
583 BITSET(cb->Flag, SIO_STA_INTSND);
584 HALInterruptRequest(INHNO_SERIAL);
585 }
586
587 return result != 0 ? TRUE : FALSE;
588}
589
590static void ScreenBuffer_ClosePort(SIOPCB * cb)
591{
592 assert(cb != NULL);
593 assert(BITTEST(cb->Flag, SIO_TYP_SCRBUF));
594
595 if(cb->Handle != NULL && cb->Handle != 0)
596 {
597 CloseHandle(cb->Handle);
598 cb->Handle = NULL;
599 }
600}
601
602/*===========================================================================*/
603
604/*
605 * ほんとにシリアル出力
606 */
607
608static DWORD WINAPI RawSerial_ReceiverThread(LPVOID param)
609{
610 SIOPCB * cb = (SIOPCB *)param;
611 DWORD work;
612 char buffer;
613
614 assert(cb != NULL);
615 assert(cb->Handle != NULL && cb->Handle != 0);
616
617 while((work = WaitForSingleObject(cb->Handle, INFINITE)) != WAIT_FAILED)
618 {
619 assert(work == WAIT_OBJECT_0); /* オブジェクトはシグナル状æ…
620‹ã«ãªã£ãŸ */
621
622 ReadFile(cb->Handle, &buffer, 1, &work, NULL);
623
624 cb->ReceiveBuffer = (char)buffer;
625 BITSET(cb->Flag, SIO_STA_INTRCV);
626 HALInterruptRequest(INHNO_SERIAL);
627 }
628
629 return 0;
630}
631
632static void RawSerial_CreatePort(SIOPCB * cb)
633{
634 cb->Handle = CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
635 FatalAssertion( cb->Handle != INVALID_HANDLE_VALUE && cb->Handle != NULL,
636 "RawSerial_CreatePort failed to open the port 'COM1'.");
637
638 /* 受信バッファ監視用スレッドを作成 */
639 CreateThread(NULL, 0, RawSerial_ReceiverThread, (LPVOID)cb, 0, NULL);
640}
641
642static BOOL RawSerial_PutChar(SIOPCB * cb, INT chr, BOOL rasint)
643{
644 BOOL result;
645 DWORD written;
646 char word;
647
648 assert(cb != NULL);
649 assert(BITTEST(cb->Flag, SIO_TYP_RAWSIO));
650 assert(cb->Handle != NULL && cb->Handle != 0);
651
652 /* 標準出力に一文字送信 */
653 word = (char)chr;
654 result = WriteFile(cb->Handle, &word, 1, &written, NULL);
655
656 /* 割込み発生フラグが立っていたら、送信完了割込み要求を起こす */
657 if(result != 0 && rasint == TRUE)
658 {
659 BITSET(cb->Flag, SIO_STA_INTSND);
660 HALInterruptRequest(INHNO_SERIAL);
661 }
662
663 return result != 0 ? TRUE : FALSE;
664}
665
666static void RawSerial_ClosePort(SIOPCB * cb)
667{
668 assert(cb != NULL);
669 assert(BITTEST(cb->Flag, SIO_TYP_RAWSIO));
670
671 if(cb->Handle != NULL && cb->Handle != 0)
672 {
673 CloseHandle(cb->Handle);
674 cb->Handle = NULL;
675 }
676}
677
678
679/*
680 * SIOドライバの初期化ルーチン
681 */
682void sio_initialize(void)
683{
684 int i;
685
686 for(i=0; i<TNUM_PORT; ++i)
687 {
688 siopcb_table[i].Flag = SIO_TYP_CONSOLE;
689 siopcb_table[i].Handle = NULL;
690 siopcb_table[i].ReceiveBuffer = -1;
691 siopcb_table[i].versatile = NULL;
692 }
693}
694
695/*
696 * シリアルI/Oポートのオープン
697 */
698SIOPCB * sio_opn_por(ID siopid, VP_INT exinf)
699{
700 BOOL success;
701 SIOPCB * siopcb = GET_SIOPCB(siopid);
702
703 assert(siopcb != NULL);
704
705 siopcb->exinf = exinf;
706
707 success = TRUE;
708 switch(SIO_TYP(siopcb->Flag))
709 {
710 case SIO_TYP_CONSOLE:
711 HALExecuteProcedure(CreateSerialConsole,siopcb);
712 break;
713 case SIO_TYP_TTY:
714 WinConsole_CreatePort(siopcb);
715 break;
716 case SIO_TYP_SCRBUF:
717 HALExecuteProcedure(ScreenBuffer_CreatePort,siopcb);
718 break;
719 case SIO_TYP_RAWSIO:
720 HALExecuteProcedure(RawSerial_CreatePort,siopcb);
721 break;
722 default:
723 success = FALSE;
724 }
725
726 if(success == TRUE)
727 BITSET(siopcb->Flag, SIO_STA_OPEN);
728
729 return siopcb;
730}
731
732/*
733 * シリアルI/Oポートのクローズ
734 */
735void sio_cls_por(SIOPCB *siopcb)
736{
737 assert(siopcb != NULL);
738
739 switch(SIO_TYP(siopcb->Flag))
740 {
741 case SIO_TYP_CONSOLE:
742 HALExecuteProcedure(SerialConsole_FinalRelease,siopcb);
743 break;
744 case SIO_TYP_TTY:
745 WinConsole_ClosePort(siopcb);
746 break;
747 case SIO_TYP_SCRBUF:
748 HALExecuteProcedure(ScreenBuffer_ClosePort,siopcb);
749 break;
750 case SIO_TYP_RAWSIO:
751 HALExecuteProcedure(RawSerial_ClosePort,siopcb);
752 break;
753 }
754}
755
756/*
757 * シリアルI/Oポートへの文字送信
758 */
759BOOL sio_snd_chr(SIOPCB *siopcb, INT chr)
760{
761 BOOL result;
762
763 assert(siopcb != NULL);
764
765 switch(SIO_TYP(siopcb->Flag))
766 {
767 case SIO_TYP_CONSOLE:
768 result = SerialConsole_PushChar(siopcb, chr);
769 break;
770 case SIO_TYP_TTY:
771 result = WinConsole_PutChar(siopcb, chr, TRUE);
772 break;
773 case SIO_TYP_SCRBUF:
774 result = ScreenBuffer_PutChar(siopcb, chr, TRUE);
775 break;
776 case SIO_TYP_RAWSIO:
777 result = RawSerial_PutChar(siopcb, chr, TRUE);
778 break;
779 }
780
781 return result;
782}
783
784/*
785 * シリアルI/Oポートからの文字受信
786 */
787INT sio_rcv_chr(SIOPCB * siopcb)
788{
789 INT result;
790
791 result = siopcb->ReceiveBuffer;
792 siopcb->ReceiveBuffer = -1;
793
794 return result;
795}
796
797
798/*
799 * シリアルI/Oポートからのコールバック許可
800 */
801void sio_ena_cbr(SIOPCB * siopcb, UINT cbrtn)
802{}
803
804/*
805 * シリアルI/Oポートからのコールバック禁止
806 */
807void sio_dis_cbr(SIOPCB * siopcb, UINT cbrtn)
808{}
809
810
811/*
812 * シリアルI/Oポート割込みハンドラ
813 */
814void sio_handler(void)
815{
816 int port;
817
818 for(port = 0; port < TNUM_PORT; ++ port)
819 {
820 if(BITTEST(siopcb_table[port].Flag, SIO_STA_OPEN))
821 {
822 /* 受信完了割込み */
823 if(BITTEST(siopcb_table[port].Flag, SIO_STA_INTRCV))
824 {
825 /* 受信した文字を取り出し */
826 BITCLEAR(siopcb_table[port].Flag, SIO_STA_INTRCV);
827 sio_ierdy_rcv(GET_SIOPCB(ID_PORT(port))->exinf);
828
829 }
830
831 /* 送信完了割込み */
832 if(BITTEST(siopcb_table[port].Flag, SIO_STA_INTSND))
833 {
834 BITCLEAR(siopcb_table[port].Flag, SIO_STA_INTSND);
835 sio_ierdy_snd(GET_SIOPCB(ID_PORT(port))->exinf);
836 }
837 }
838 }
839}
840
841/*
842 * コンソールポートへの強制一文字出力 (割込みなし)
843 */
844void SerialRawPutc(INT chr)
845{
846 SIOPCB * siopcb = &siopcb_table[CONSOLE_PORTID - 1];
847
848 assert(siopcb != NULL);
849
850 if(!BITTEST(siopcb->Flag, SIO_STA_OPEN))
851 return;
852
853 switch(SIO_TYP(siopcb->Flag))
854 {
855 case SIO_TYP_CONSOLE:
856 SerialConsole_PutChar(siopcb, chr, FALSE);
857 break;
858 case SIO_TYP_TTY:
859 WinConsole_PutChar(siopcb, chr, FALSE);
860 break;
861 case SIO_TYP_SCRBUF:
862 ScreenBuffer_PutChar(siopcb, chr, FALSE);
863 break;
864 case SIO_TYP_RAWSIO:
865 RawSerial_PutChar(siopcb, chr, FALSE);
866 break;
867 }
868}
Note: See TracBrowser for help on using the repository browser.