Initial revision
[AROS-Contrib.git] / development / compilers / freepascal / rtl / aros / crt.pp
blobeac05609e86a01472c2e0daf4e5cdbbac8fb5e69
2 $Id$
3 This file is part of the Free Pascal run time library.
4 Copyright (c) 1999-2000 by Nils Sjoholm and Carl Eric Codere
6 See the file COPYING.FPC, included in this distribution,
7 for details about the copyright.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 **********************************************************************}
16 unit Crt;
18 {--------------------------------------------------------------------}
19 { LEFT TO DO: }
20 {--------------------------------------------------------------------}
21 { o Write special characters are not recognized }
22 { o Write does not take care of window coordinates yet. }
23 { o Read does not recognize the special editing characters }
24 { o Read does not take care of window coordinates yet. }
25 { o Readkey extended scancode is not correct yet }
26 { o Color mapping only works for 4 colours }
27 { o ClrScr, DeleteLine, InsLine do not work with window coordinates }
28 {--------------------------------------------------------------------}
32 Interface
34 Const
35 { Controlling consts }
36 Flushing=false; {if true then don't buffer output}
37 ScreenWidth = 80;
38 ScreenHeight = 25;
40 { CRT modes }
41 BW40 = 0; { 40x25 B/W on Color Adapter }
42 CO40 = 1; { 40x25 Color on Color Adapter }
43 BW80 = 2; { 80x25 B/W on Color Adapter }
44 CO80 = 3; { 80x25 Color on Color Adapter }
45 Mono = 7; { 80x25 on Monochrome Adapter }
46 Font8x8 = 256; { Add-in for ROM font }
48 { Mode constants for 3.0 compatibility }
49 C40 = CO40;
50 C80 = CO80;
53 When using this color constants on the Amiga
54 you can bet that they don't work as expected.
55 You never know what color the user has on
56 his Amiga. Perhaps we should do a check of
57 the number of bitplanes (for number of colors)
59 The normal 4 first pens for an Amiga are
61 0 LightGrey
62 1 Black
63 2 White
64 3 Blue
68 { Foreground and background color constants }
69 Black = 1; { normal pen for amiga }
70 Blue = 3; { windowborder color }
71 Green = 15;
72 Cyan = 7;
73 Red = 4;
74 Magenta = 5;
75 Brown = 6;
76 LightGray = 0; { canvas color }
78 { Foreground color constants }
79 DarkGray = 8;
80 LightBlue = 9;
81 LightGreen = 10;
82 LightCyan = 11;
83 LightRed = 12;
84 LightMagenta = 13;
85 Yellow = 14;
86 White = 2; { third color on amiga }
88 { Add-in for blinking }
89 Blink = 128;
91 {Other Defaults}
92 LastMode : Word = 3;
93 WindMin : Word = $0;
94 WindMax : Word = $184f;
95 { These don't change anything if they are modified }
96 CheckSnow : Boolean = FALSE;
97 DirectVideo: Boolean = FALSE;
98 var
99 TextAttr : BYTE;
100 { CheckBreak have to make this one to a function for Amiga }
101 CheckEOF : Boolean;
103 Procedure AssignCrt(Var F: Text);
104 Function KeyPressed: Boolean;
105 Function ReadKey: Char;
106 Procedure TextMode(Mode: Integer);
107 Procedure Window(X1, Y1, X2, Y2: BYTE);
108 Procedure GoToXy(X: byte; Y: byte);
109 Function WhereX: Byte;
110 Function WhereY: Byte;
111 Procedure ClrScr;
112 Procedure ClrEol;
113 Procedure InsLine;
114 Procedure DelLine;
115 Procedure TextColor(Color: Byte);
116 Procedure TextBackground(Color: Byte);
117 Procedure LowVideo;
118 Procedure HighVideo;
119 Procedure NormVideo;
120 Procedure Delay(DTime: Word);
121 Procedure Sound(Hz: Word);
122 Procedure NoSound;
124 { Extra functions }
126 Procedure CursorOn;
127 Procedure CursorOff;
128 Function CheckBreak: Boolean;
130 Implementation
133 The definitions of TextRec and FileRec are in separate files.
135 {$i textrec.inc}
136 {$i filerec.inc}
139 maxcols,maxrows : longint;
141 CONST
142 { This is used to make sure that readkey returns immediately }
143 { if keypressed was used beforehand. }
144 KeyPress : char = #0;
145 _LVODisplayBeep = -96;
148 Type
150 pInfoData = ^tInfoData;
151 tInfoData = packed record
152 id_NumSoftErrors : Longint; { number of soft errors on disk }
153 id_UnitNumber : Longint; { Which unit disk is (was) mounted on }
154 id_DiskState : Longint; { See defines below }
155 id_NumBlocks : Longint; { Number of blocks on disk }
156 id_NumBlocksUsed : Longint; { Number of block in use }
157 id_BytesPerBlock : Longint;
158 id_DiskType : Longint; { Disk Type code }
159 id_VolumeNode : Longint; { BCPL pointer to volume node }
160 id_InUse : Longint; { Flag, zero if not in use }
161 end;
163 { * List Node Structure. Each member in a list starts with a Node * }
165 pNode = ^tNode;
166 tNode = packed Record
167 ln_Succ, { * Pointer to next (successor) * }
168 ln_Pred : pNode; { * Pointer to previous (predecessor) * }
169 ln_Type : Byte;
170 ln_Pri : Shortint; { * Priority, for sorting * }
171 ln_Name : PChar; { * ID string, null terminated * }
172 End; { * Note: Integer aligned * }
174 { normal, full featured list }
176 pList = ^tList;
177 tList = packed record
178 lh_Head : pNode;
179 lh_Tail : pNode;
180 lh_TailPred : pNode;
181 lh_Type : Byte;
182 l_pad : Byte;
183 end;
185 pMsgPort = ^tMsgPort;
186 tMsgPort = packed record
187 mp_Node : tNode;
188 mp_Flags : Byte;
189 mp_SigBit : Byte; { signal bit number }
190 mp_SigTask : Pointer; { task to be signalled (TaskPtr) }
191 mp_MsgList : tList; { message linked list }
192 end;
194 pMessage = ^tMessage;
195 tMessage = packed record
196 mn_Node : tNode;
197 mn_ReplyPort : pMsgPort; { message reply port }
198 mn_Length : Word; { message len in bytes }
199 end;
201 pIOStdReq = ^tIOStdReq;
202 tIOStdReq = packed record
203 io_Message : tMessage;
204 io_Device : Pointer; { device node pointer }
205 io_Unit : Pointer; { unit (driver private)}
206 io_Command : Word; { device command }
207 io_Flags : Byte;
208 io_Error : Shortint; { error or warning num }
209 io_Actual : Longint; { actual number of bytes transferred }
210 io_Length : Longint; { requested number bytes transferred}
211 io_Data : Pointer; { points to data area }
212 io_Offset : Longint; { offset for block structured devices }
213 end;
215 pIntuiMessage = ^tIntuiMessage;
216 tIntuiMessage = packed record
217 ExecMessage : tMessage;
218 IClass : Longint;
219 Code : Word;
220 Qualifier : Word;
221 IAddress : Pointer;
222 MouseX,
223 MouseY : Word;
224 Seconds,
225 Micros : Longint;
226 IDCMPWindow : Pointer;
227 SpecialLink : pIntuiMessage;
228 end;
230 pWindow = ^tWindow;
231 tWindow = packed record
232 NextWindow : pWindow; { for the linked list in a screen }
233 LeftEdge,
234 TopEdge : Integer; { screen dimensions of window }
235 Width,
236 Height : Integer; { screen dimensions of window }
237 MouseY,
238 MouseX : Integer; { relative to upper-left of window }
239 MinWidth,
240 MinHeight : Integer; { minimum sizes }
241 MaxWidth,
242 MaxHeight : Word; { maximum sizes }
243 Flags : Longint; { see below for defines }
244 MenuStrip : Pointer; { the strip of Menu headers }
245 Title : PChar; { the title text for this window }
246 FirstRequest : Pointer; { all active Requesters }
247 DMRequest : Pointer; { double-click Requester }
248 ReqCount : Integer; { count of reqs blocking Window }
249 WScreen : Pointer; { this Window's Screen }
250 RPort : Pointer; { this Window's very own RastPort }
251 BorderLeft,
252 BorderTop,
253 BorderRight,
254 BorderBottom : Shortint;
255 BorderRPort : Pointer;
256 FirstGadget : Pointer;
257 Parent,
258 Descendant : pWindow;
259 Pointer_ : Pointer; { sprite data }
260 PtrHeight : Shortint; { sprite height (not including sprite padding) }
261 PtrWidth : Shortint; { sprite width (must be less than or equal to 16) }
262 XOffset,
263 YOffset : Shortint; { sprite offsets }
264 IDCMPFlags : Longint; { User-selected flags }
265 UserPort,
266 WindowPort : pMsgPort;
267 MessageKey : pIntuiMessage;
268 DetailPen,
269 BlockPen : Byte; { for bar/border/gadget rendering }
270 CheckMark : Pointer;
271 ScreenTitle : PChar; { if non-null, Screen title when Window is active }
272 GZZMouseX : Integer;
273 GZZMouseY : Integer;
274 GZZWidth : Integer;
275 GZZHeight : Word;
276 ExtData : Pointer;
277 UserData : Pointer; { general-purpose pointer to User data extension }
278 WLayer : Pointer;
279 IFont : Pointer;
280 MoreFlags : Longint;
281 end;
283 const
285 M_LNM = 20; { linefeed newline mode }
286 PMB_ASM = M_LNM + 1; { internal storage bit for AS flag }
287 PMB_AWM = PMB_ASM + 1; { internal storage bit for AW flag }
288 MAXTABS = 80;
289 IECLASS_MAX = $15;
291 type
293 pKeyMap = ^tKeyMap;
294 tKeyMap = packed record
295 km_LoKeyMapTypes : Pointer;
296 km_LoKeyMap : Pointer;
297 km_LoCapsable : Pointer;
298 km_LoRepeatable : Pointer;
299 km_HiKeyMapTypes : Pointer;
300 km_HiKeyMap : Pointer;
301 km_HiCapsable : Pointer;
302 km_HiRepeatable : Pointer;
303 end;
307 pConUnit = ^tConUnit;
308 tConUnit = packed record
309 cu_MP : tMsgPort;
310 { ---- read only variables }
311 cu_Window : Pointer; { (WindowPtr) intuition window bound to this unit }
312 cu_XCP : Integer; { character position }
313 cu_YCP : Integer;
314 cu_XMax : Integer; { max character position }
315 cu_YMax : Integer;
316 cu_XRSize : Integer; { character raster size }
317 cu_YRSize : Integer;
318 cu_XROrigin : Integer; { raster origin }
319 cu_YROrigin : Integer;
320 cu_XRExtant : Integer; { raster maxima }
321 cu_YRExtant : Integer;
322 cu_XMinShrink : Integer; { smallest area intact from resize process }
323 cu_YMinShrink : Integer;
324 cu_XCCP : Integer; { cursor position }
325 cu_YCCP : Integer;
327 { ---- read/write variables (writes must must be protected) }
328 { ---- storage for AskKeyMap and SetKeyMap }
330 cu_KeyMapStruct : tKeyMap;
332 { ---- tab stops }
334 cu_TabStops : Array [0..MAXTABS-1] of Word;
335 { 0 at start, -1 at end of list }
337 { ---- console rastport attributes }
339 cu_Mask : Shortint;
340 cu_FgPen : Shortint;
341 cu_BgPen : Shortint;
342 cu_AOLPen : Shortint;
343 cu_DrawMode : Shortint;
344 cu_AreaPtSz : Shortint;
345 cu_AreaPtrn : Pointer; { cursor area pattern }
346 cu_Minterms : Array [0..7] of Byte; { console minterms }
347 cu_Font : Pointer; { (TextFontPtr) }
348 cu_AlgoStyle : Byte;
349 cu_TxFlags : Byte;
350 cu_TxHeight : Word;
351 cu_TxWidth : Word;
352 cu_TxBaseline : Word;
353 cu_TxSpacing : Word;
355 { ---- console MODES and RAW EVENTS switches }
357 cu_Modes : Array [0..(PMB_AWM+7) div 8 - 1] of Byte;
358 { one bit per mode }
359 cu_RawEvents : Array [0..(IECLASS_MAX+7) div 8 - 1] of Byte;
360 end;
362 const
365 CD_CURRX = 1;
366 CD_CURRY = 2;
367 CD_MAXX = 3;
368 CD_MAXY = 4;
370 CSI = chr($9b);
372 SIGBREAKF_CTRL_C = 4096;
374 function AllocVec( size, reqm : Longint ): Pointer;
375 begin
377 MOVE.L A6,-(A7)
378 MOVE.L size,d0
379 MOVE.L reqm,d1
380 MOVE.L _ExecBase, A6
381 JSR -684(A6)
382 MOVE.L (A7)+,A6
383 MOVE.L d0,@RESULT
384 end;
385 end;
388 function DoPkt(ID : pMsgPort;
389 Action, Param1, Param2,
390 Param3, Param4, Param5 : Longint) : Longint;
391 begin
393 MOVEM.L d2/d3/d4/d5/d6/d7/a6,-(A7)
394 MOVE.L ID,d1
395 MOVE.L Action,d2
396 MOVE.L Param1,d3
397 MOVE.L Param2,d4
398 MOVE.L Param3,d5
399 MOVE.L Param4,d6
400 MOVE.L Param5,d7
401 MOVE.L _DOSBase,A6
402 JSR -240(A6)
403 MOVEM.L (A7)+,d2/d3/d4/d5/d6/d7/a6
404 MOVE.L d0,@RESULT
405 end;
406 end;
408 procedure FreeVec( memory : Pointer );
409 begin
411 MOVE.L A6,-(A7)
412 MOVE.L memory,a1
413 MOVE.L _ExecBase,A6
414 JSR -690(A6)
415 MOVE.L (A7)+,A6
416 end;
417 end;
420 function GetConsoleTask : pMsgPort;
421 begin
423 MOVE.L A6,-(A7)
424 MOVE.L _DOSBase,A6
425 JSR -510(A6)
426 MOVE.L (A7)+,A6
427 MOVE.L d0,@RESULT
428 end;
429 end;
432 function GetMsg(port : pMsgPort): pMessage;
433 begin
435 MOVE.L A6,-(A7)
436 MOVE.L port,a0
437 MOVE.L _ExecBase,A6
438 JSR -372(A6)
439 MOVE.L (A7)+,A6
440 MOVE.L d0,@RESULT
441 end;
442 end;
444 function ModifyIDCMP(window : pWindow;
445 IDCMPFlags : Longint) : Boolean;
446 begin
448 MOVE.L A6,-(A7)
449 MOVE.L window,a0
450 MOVE.L IDCMPFlags,d0
451 MOVE.L _IntuitionBase,A6
452 JSR -150(A6)
453 MOVE.L (A7)+,A6
454 TST.L d0
455 bne @success
456 bra @end
457 @success:
458 move.b #1,d0
459 @end:
460 move.b d0,@RESULT
461 end;
462 end;
464 procedure ReplyMsg(mess : pMessage);
465 begin
467 MOVE.L A6,-(A7)
468 MOVE.L mess,a1
469 MOVE.L _ExecBase,A6
470 JSR -378(A6)
471 MOVE.L (A7)+,A6
472 end;
473 end;
476 function WaitPort(port : pMsgPort): pMessage;
477 begin
479 MOVE.L A6,-(A7)
480 MOVE.L port,a0
481 MOVE.L _ExecBase,A6
482 JSR -384(A6)
483 MOVE.L (A7)+,A6
484 MOVE.L d0,@RESULT
485 end;
486 end;
488 procedure Delay_(ticks : Longint);
489 begin
491 MOVE.L A6,-(A7)
492 MOVE.L ticks,d1
493 MOVE.L _DOSBase,A6
494 JSR -198(A6)
495 MOVE.L (A7)+,A6
496 end;
497 end;
499 function SetSignal(newSignals, signalMask : Longint) : Longint;
500 begin
502 MOVE.L A6,-(A7)
503 MOVE.L newSignals,d0
504 MOVE.L signalMask,d1
505 MOVE.L _ExecBase,A6
506 JSR -306(A6)
507 MOVE.L (A7)+,A6
508 MOVE.L d0,@RESULT
509 end;
510 end;
512 function OpenInfo : pInfoData;
514 port : pMsgPort;
515 info : pInfoData;
516 bptr, d4, d5, d6, d7 : Longint;
517 begin
518 info := pInfoData(AllocVec(SizeOf(tInfoData), 1));
520 if info <> nil then begin
521 port := GetConsoleTask;
522 bptr := Longint(info) shr 2;
524 if port <> nil then begin
525 if DoPkt(port, $19, bptr, d4, d5, d6, d7) <> 0 then info := pInfoData(bptr shl 2)
526 else port := nil;
527 end;
529 if port = nil then begin
530 FreeVec(info);
531 info := nil;
532 end;
533 end;
535 OpenInfo := info;
536 end;
538 procedure CloseInfo(var info : pInfoData);
539 begin
540 if info <> nil then begin
541 FreeVec(info);
542 info := nil;
543 end;
544 end;
546 function ConData(modus : byte) : integer;
548 info : pInfoData;
549 theunit : pConUnit;
550 pos : Longint;
551 begin
552 pos := 1;
553 info := OpenInfo;
555 if info <> nil then begin
556 theunit := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit);
558 case modus of
559 CD_CURRX : pos := theunit^.cu_XCP;
560 CD_CURRY : pos := theunit^.cu_YCP;
561 CD_MAXX : pos := theunit^.cu_XMax;
562 CD_MAXY : pos := theunit^.cu_YMax;
563 end;
565 CloseInfo(info);
566 end;
568 ConData := pos + 1;
569 end;
571 function WhereX : Byte;
572 begin
573 WhereX := Byte(ConData(CD_CURRX))-lo(windmin);
574 end;
576 function realx: byte;
577 begin
578 RealX := Byte(ConData(CD_CURRX));
579 end;
581 function realy: byte;
582 begin
583 RealY := Byte(ConData(CD_CURRY));
584 end;
586 function WhereY : Byte;
587 begin
588 WhereY := Byte(ConData(CD_CURRY))-hi(windmin);
589 end;
591 function screencols : integer;
592 begin
593 screencols := ConData(CD_MAXX);
594 end;
596 function screenrows : integer;
597 begin
598 screenrows := ConData(CD_MAXY);
599 end;
602 procedure Realgotoxy(x,y : integer);
603 begin
604 Write(CSI, y, ';', x, 'H');
605 end;
608 procedure gotoxy(x,y : byte);
609 begin
610 if (x<1) then
611 x:=1;
612 if (y<1) then
613 y:=1;
614 if y+hi(windmin)-2>=hi(windmax) then
615 y:=hi(windmax)-hi(windmin)+1;
616 if x+lo(windmin)-2>=lo(windmax) then
617 x:=lo(windmax)-lo(windmin)+1;
618 Write(CSI, y+hi(windmin), ';', x+lo(windmin), 'H');
619 end;
622 procedure CursorOff;
623 begin
624 Write(CSI,'0 p');
625 end;
627 procedure CursorOn;
628 begin
629 Write(CSI,'1 p');
630 end;
632 procedure ClrScr;
633 begin
634 Write(Chr($0c));
635 end;
637 function ReadKey : char;
638 const
639 IDCMP_VANILLAKEY = $00200000;
640 IDCMP_RAWKEY = $00000400;
642 info : pInfoData;
643 win : pWindow;
644 imsg : pIntuiMessage;
645 msg : pMessage;
646 key : char;
647 idcmp, vanil : Longint;
648 begin
649 key := #0;
650 if KeyPress <> #0 then
651 Begin
652 ReadKey:=KeyPress;
653 KeyPress:=#0;
654 exit;
655 end;
656 info := OpenInfo;
658 if info <> nil then begin
659 win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
660 idcmp := win^.IDCMPFlags;
661 vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
663 ModifyIDCMP(win, (idcmp or vanil));
665 repeat
666 msg := WaitPort(win^.UserPort);
667 imsg := pIntuiMessage(GetMsg(win^.UserPort));
669 if (imsg^.IClass = IDCMP_VANILLAKEY) then
670 key := char(imsg^.Code)
671 else
672 if (imsg^.IClass = IDCMP_RAWKEY) then
673 key := char(imsg^.Code);
675 ReplyMsg(pMessage(imsg));
676 until key <> #0;
678 repeat
679 msg := GetMsg(win^.UserPort);
681 if msg <> nil then ReplyMsg(msg);
682 until msg = nil;
684 ModifyIDCMP(win, idcmp);
686 CloseInfo(info);
687 end;
689 ReadKey := key;
690 end;
692 function KeyPressed : Boolean;
693 const
694 IDCMP_VANILLAKEY = $00200000;
695 IDCMP_RAWKEY = $00000400;
697 info : pInfoData;
698 win : pWindow;
699 imsg : pIntuiMessage;
700 msg : pMessage;
701 idcmp, vanil : Longint;
702 ispressed : Boolean;
703 begin
704 KeyPress := #0;
705 ispressed := False;
706 info := OpenInfo;
708 if info <> nil then begin
709 win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
710 idcmp := win^.IDCMPFlags;
711 vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
713 ModifyIDCMP(win, (idcmp or vanil));
715 msg := WaitPort(win^.UserPort);
716 imsg := pIntuiMessage(GetMsg(win^.UserPort));
718 if (imsg^.IClass = IDCMP_VANILLAKEY) or (imsg^.IClass = IDCMP_RAWKEY) then
719 Begin
720 ispressed := true;
721 KeyPress := char(imsg^.Code)
722 end;
724 ReplyMsg(pMessage(imsg));
726 repeat
727 msg := GetMsg(win^.UserPort);
729 if msg <> nil then ReplyMsg(msg);
730 until msg = nil;
732 ModifyIDCMP(win, idcmp);
734 CloseInfo(info);
735 end;
737 KeyPressed := ispressed;
738 end;
740 procedure TextColor(color : byte);
741 begin
742 TextAttr := (TextAttr and $70) or color;
743 Write(CSI, '3', color, 'm');
744 end;
746 procedure TextBackground(color : byte);
747 begin
748 Textattr:=(textattr and $8f) or ((color and $7) shl 4);
749 Write(CSI, '4', color, 'm');
750 end;
752 procedure Window(X1,Y1,X2,Y2: Byte);
753 begin
754 if (x1<1) or (x2>screencols) or (y2>screenrows) or
755 (x1>x2) or (y1>y2) then
756 exit;
757 windmin:=(x1-1) or ((y1-1) shl 8);
758 windmax:=(x2-1) or ((y2-1) shl 8);
759 gotoxy(1,1);
760 end;
766 procedure DelLine;
767 begin
768 Write(CSI,'X');
769 end;
771 procedure ClrEol;
772 begin
773 Write(CSI,'K');
774 end;
776 procedure InsLine;
777 begin
778 Write(CSI,'1 L');
779 end;
781 procedure cursorbig;
782 begin
783 end;
785 procedure lowvideo;
786 begin
787 end;
789 procedure highvideo;
790 begin
791 end;
793 procedure nosound;
794 begin
795 end;
797 procedure sound(hz : word);
798 begin
799 end;
801 procedure delay(DTime : Word);
803 dummy : Longint;
804 begin
805 dummy := trunc((real(DTime) / 1000.0) * 50.0);
806 Delay_(dummy);
807 end;
809 function CheckBreak : boolean;
810 begin
811 if (SetSignal(0, 0) and SIGBREAKF_CTRL_C) = SIGBREAKF_CTRL_C then
812 CheckBreak := true
813 else
814 CheckBreak := false;
815 end;
817 procedure textmode(mode : integer);
818 begin
819 lastmode:=mode;
820 mode:=mode and $ff;
821 windmin:=0;
822 windmax:=(screencols-1) or ((screenrows-1) shl 8);
823 maxcols:=screencols;
824 maxrows:=screenrows;
825 end;
827 procedure normvideo;
828 begin
829 end;
831 function GetTextBackground : byte;
833 info : pInfoData;
834 pen : byte;
835 begin
836 pen := 1;
837 info := OpenInfo;
839 if info <> nil then begin
840 pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_BgPen;
842 CloseInfo(info);
843 end;
845 GetTextBackground := pen;
846 end;
848 function GetTextColor : byte;
850 info : pInfoData;
851 pen : byte;
852 begin
853 pen := 1;
854 info := OpenInfo;
856 if info <> nil then begin
857 pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_FgPen;
859 CloseInfo(info);
860 end;
862 GetTextColor := pen;
863 end;
866 {*****************************************************************************
867 Read and Write routines
868 *****************************************************************************}
869 { Problem here: Currently all these routines are not implemented because of how }
870 { the console device works. Because w low level write is required to change the }
871 { position of the cursor, and since the CrtWrite is assigned as the standard }
872 { write routine, a recursive call will occur }
874 { How to fix this: }
875 { At startup make a copy of the Output handle, and then use this copy to make }
876 { low level positioning calls. This does not seem to work yet. }
880 Function CrtWrite(var f : textrec):integer;
883 i,col,row : longint;
884 c : char;
885 buf: array[0..1] of char;
887 begin
888 col:=realx;
889 row:=realy;
890 inc(row);
891 inc(col);
892 for i:=0 to f.bufpos-1 do
893 begin
894 c:=f.buffer[i];
895 case ord(c) of
896 10 : begin
897 inc(row);
898 end;
899 13 : begin
900 col:=lo(windmin)+1;
901 end;
902 8 : if col>lo(windmin)+1 then
903 begin
904 dec(col);
905 end;
906 7 : begin
907 { beep }
909 move.l a6,d6 { save base pointer }
910 move.l _IntuitionBase,a6 { set library base }
911 sub.l a0,a0
912 jsr _LVODisplayBeep(a6)
913 move.l d6,a6 { restore base pointer }
914 end;
915 end;
916 else
917 begin
918 buf[0]:=c;
919 realgotoxy(row,col);
920 do_write(f.handle,longint(@buf[0]),1);
921 inc(col);
922 end;
923 end;
924 if col>lo(windmax)+1 then
925 begin
926 col:=lo(windmin)+1;
927 inc(row);
928 end;
929 while row>hi(windmax)+1 do
930 begin
931 delline;
932 dec(row);
933 end;
934 end;
935 f.bufpos:=0;
936 realgotoxy(row-1,col-1);
937 CrtWrite:=0;
938 end;
940 Function CrtClose(Var F: TextRec): Integer;
941 Begin
942 F.Mode:=fmClosed;
943 CrtClose:=0;
944 End;
946 Function CrtOpen(Var F: TextRec): Integer;
947 Begin
948 If F.Mode = fmOutput Then
949 CrtOpen:=0
950 Else
951 CrtOpen:=5;
952 End;
954 Function CrtRead(Var F: TextRec): Integer;
955 Begin
956 f.bufend:=do_read(f.handle,longint(f.bufptr),f.bufsize);
957 f.bufpos:=0;
958 CrtRead:=0;
959 End;
961 Function CrtInOut(Var F: TextRec): Integer;
962 Begin
963 Case F.Mode of
964 fmInput: CrtInOut:=CrtRead(F);
965 fmOutput: CrtInOut:=CrtWrite(F);
966 End;
967 End;
969 procedure assigncrt(var f : text);
970 begin
971 { TextRec(F).Mode:=fmClosed;
972 TextRec(F).BufSize:=SizeOf(TextBuf);
973 TextRec(F).BufPtr:=@TextRec(F).Buffer;
974 TextRec(F).BufPos:=0;
975 TextRec(F).OpenFunc:=@CrtOpen;
976 TextRec(F).InOutFunc:=@CrtInOut;
977 TextRec(F).FlushFunc:=@CrtInOut;
978 TextRec(F).CloseFunc:=@CrtClose;
979 TextRec(F).Name[0]:='.';
980 TextRec(F).Name[1]:=#0;}
981 end;
985 old_exit : pointer;
987 procedure crt_exit;
988 begin
989 { Restore default colors }
990 write(CSI,'0m');
991 exitproc:=old_exit;
992 end;
995 Begin
996 old_exit:=exitproc;
997 exitproc:=@crt_exit;
998 { load system variables to temporary variables to save time }
999 maxcols:=screencols;
1000 maxrows:=screenrows;
1001 { Set the initial text attributes }
1002 { Text background }
1003 Textattr:=(textattr and $8f) or ((GetTextBackGround and $7) shl 4);
1004 { Text foreground }
1005 TextAttr := (TextAttr and $70) or GetTextColor;
1006 { set output window }
1007 windmax:=(maxcols-1) or (( maxrows-1) shl 8);
1010 { Get a copy of the standard }
1011 { output handle, and when using }
1012 { direct console calls, use this }
1013 { handle instead. }
1014 { assigncrt(Output);
1015 TextRec(Output).mode:=fmOutput;}
1016 end.