This commit is contained in:
Pavel 2024-10-29 13:29:52 +03:00
parent 795d3b8578
commit e2574eba4f
9 changed files with 281 additions and 192 deletions

View File

@ -375,27 +375,24 @@ end;
procedure ttyconsdev_init();
begin
tty_init( @std_tty[ 0],'[Input ]:',nil);
tty_init( @std_tty[ 1],'[Output]:',nil);
tty_init( @std_tty[ 2],'[Error ]:',nil);
tty_init( @std_tty[ 0],'[Input ]:',nil,TF_THD_NAME_PREFIX);
tty_init( @std_tty[ 1],'[Output]:',nil,TF_THD_NAME_PREFIX);
tty_init( @std_tty[ 2],'[Error ]:',nil,TF_THD_NAME_PREFIX);
//
tty_init(@deci_tty[ 0],'[stdin ]:',nil);
tty_init(@deci_tty[ 1],'[stdout]:',nil);
tty_init(@deci_tty[ 2],'[stderr]:',nil);
tty_init(@deci_tty[ 3],'[tty2 ]:',nil);
tty_init(@deci_tty[ 4],'[tty3 ]:',nil);
tty_init(@deci_tty[ 5],'[tty4 ]:',nil);
tty_init(@deci_tty[ 6],'[tty5 ]:',nil);
tty_init(@deci_tty[ 7],'[tty6 ]:',nil);
tty_init(@deci_tty[ 8],'[tty7 ]:',nil);
tty_init(@deci_tty[ 9],'[ttya0 ]:',nil);
tty_init(@deci_tty[10],'[ttyb0 ]:',nil);
tty_init(@deci_tty[11],'[ttyc0 ]:',nil);
tty_init(@deci_tty[ 0],'[stdin ]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[ 1],'[stdout]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[ 2],'[stderr]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[ 3],'[tty2 ]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[ 4],'[tty3 ]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[ 5],'[tty4 ]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[ 6],'[tty5 ]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[ 7],'[tty6 ]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[ 8],'[tty7 ]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[ 9],'[ttya0 ]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[10],'[ttyb0 ]:',nil,TF_THD_NAME_PREFIX);
tty_init(@deci_tty[11],'[ttyc0 ]:',nil,TF_THD_NAME_PREFIX);
//
tty_init(@debug_tty ,'[Debug ]:',nil);
//
std_tty[0].t_flags:=TF_NOWRITEPREFIX;
std_tty[1].t_flags:=TF_NOWRITEPREFIX;
tty_init(@debug_tty ,'[Debug ]:',nil,TF_THD_NAME_PREFIX);
//
dev_console:=make_dev_credf(MAKEDEV_ETERNAL, @ttyconsdev_cdevsw, 0, UID_ROOT, GID_WHEEL, &600, 'console',[]);
dev_console^.si_drv1:=@debug_tty;

View File

@ -993,7 +993,7 @@ begin
//debug
end;
procedure op_jit2native(var ctx:t_jit_context2;pcb:Boolean);
procedure op_jit2native(var ctx:t_jit_context2;pcb,stack:Boolean);
begin
with ctx.builder do
begin
@ -1004,28 +1004,33 @@ begin
ori([r13-jit_frame_offset+Integer(@p_kthread(nil)^.pcb_flags),os8],Byte(PCB_IS_HLE));
end;
////save internal stack
//movq([r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_jctx.rsp)],rsp);
//movq([r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_jctx.rbp)],rbp);
//
////load guest stack
//movq(r14,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_ustack.stack)]);
//movq(r15,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_ustack.sttop)]);
//
////set teb
//movq([GS+teb_stack],r14);
//movq([GS+teb_sttop],r15);
if stack then
begin
//save internal stack
movq([r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_jctx.rsp)],rsp);
movq([r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_jctx.rbp)],rbp);
//load rsp,rbp,r14,r15,r13
//movq(rsp,[r13+Integer(@p_jit_frame(nil)^.tf_rsp)]);
//movq(rbp,[r13+Integer(@p_jit_frame(nil)^.tf_rbp)]);
//load guest stack
movq(r14,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_ustack.stack)]);
movq(r15,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_ustack.sttop)]);
//set teb
movq([GS+teb_stack],r14);
movq([GS+teb_sttop],r15);
//load rsp,rbp
movq(rsp,[r13+Integer(@p_jit_frame(nil)^.tf_rsp)]);
movq(rbp,[r13+Integer(@p_jit_frame(nil)^.tf_rbp)]);
end;
//load r14,r15,r13
movq(r14,[r13+Integer(@p_jit_frame(nil)^.tf_r14)]);
movq(r15,[r13+Integer(@p_jit_frame(nil)^.tf_r15)]);
movq(r13,[r13+Integer(@p_jit_frame(nil)^.tf_r13)]);
end;
end;
procedure op_native2jit(var ctx:t_jit_context2;pcb:Boolean);
procedure op_native2jit(var ctx:t_jit_context2;pcb,stack:Boolean);
begin
with ctx.builder do
begin
@ -1033,7 +1038,7 @@ begin
//save r13
movq([GS+Integer(teb_jitcall)],r13);
//load curkthread,jit ctx
//load curkthread,jit_ctx
movq(r13,[GS +Integer(teb_thread)]);
leaq(r13,[r13+jit_frame_offset ]);
@ -1045,21 +1050,24 @@ begin
movq(r14,[GS+Integer(teb_jitcall)]);
movq([r13+Integer(@p_jit_frame(nil)^.tf_r13)],r14);
//load rsp,rbp
//movq([r13+Integer(@p_jit_frame(nil)^.tf_rsp)],rsp);
//movq([r13+Integer(@p_jit_frame(nil)^.tf_rbp)],rbp);
if stack then
begin
//load rsp,rbp
movq([r13+Integer(@p_jit_frame(nil)^.tf_rsp)],rsp);
movq([r13+Integer(@p_jit_frame(nil)^.tf_rbp)],rbp);
//load host stack
//movq(r14,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_kstack.stack)]);
//movq(r15,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_kstack.sttop)]);
//load host stack
movq(r14,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_kstack.stack)]);
movq(r15,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_kstack.sttop)]);
//set teb
//movq([GS+teb_stack],r14);
//movq([GS+teb_sttop],r15);
//set teb
movq([GS+teb_stack],r14);
movq([GS+teb_sttop],r15);
//load internal stack
//movq(rsp,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_jctx.rsp)]);
//movq(rbp,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_jctx.rbp)]);
//load internal stack
movq(rsp,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_jctx.rsp)]);
movq(rbp,[r13-jit_frame_offset+Integer(@p_kthread(nil)^.td_jctx.rbp)]);
end;
//reset PCB_IS_HLE
if pcb then
@ -1131,11 +1139,11 @@ begin
Exit(True);
end;
op_jit2native(ctx,false);
op_jit2native(ctx,false,true);
add_orig(ctx);
op_native2jit(ctx,false);
op_native2jit(ctx,false,true);
Result:=True;
end;
@ -1412,7 +1420,7 @@ begin
link_curr:=ctx.builder.get_curr_label.after;
//
op_jit2native(ctx,true);
op_jit2native(ctx,true,false);
//[JIT->HLE]
ctx.builder.call_far(node^.native);
@ -1420,7 +1428,7 @@ begin
op_debug_info_addr(ctx,node^.native);
//[HLE->JIT]
op_native2jit(ctx,true);
op_native2jit(ctx,true,false);
//
op_pop_rip_part0(ctx,0); //out:r14
ctx.imm:=0;

View File

@ -180,6 +180,11 @@ type
sttop:Pointer;
end;
t_td_buffer=packed record
addr:Pointer;
size:QWORD;
end;
p_td_jctx=^t_td_jctx;
t_td_jctx=packed record
block:Pointer;
@ -255,6 +260,8 @@ type
pcb_fsbase :Pointer;
pcb_gsbase :Pointer;
pcb_onfault :Pointer;
td_temp :t_td_buffer;
td_padding :t_td_buffer;
end;
const
@ -355,6 +362,9 @@ procedure thread_resume_all (exclude:p_kthread); external;
function kthread_add(func,arg:Pointer;newtdp:pp_kthread;pages:Word;name:PChar):Integer; external;
procedure kthread_exit(); external;
function thread_get_local_buffer(td:p_kthread;size:QWORD):Pointer;
procedure thread_free_local_buffer(td:p_kthread);
implementation
function curkthread:p_kthread; assembler; nostackframe;
@ -593,6 +603,42 @@ begin
td^.pcb_onfault:=v;
end;
//
function thread_get_local_buffer(td:p_kthread;size:QWORD):Pointer;
begin
if (td=nil) then Exit(nil);
if (size<=td^.td_padding.size) then
begin
Result:=td^.td_padding.addr;
end else
if (size<=td^.td_temp.size) then
begin
Result:=td^.td_temp.addr;
end else
begin
if (td^.td_temp.addr<>nil) then
begin
FreeMem(td^.td_temp.addr);
end;
Result:=GetMem(size);
td^.td_temp.addr:=Result;
td^.td_temp.size:=MemSize(Result);
end;
end;
procedure thread_free_local_buffer(td:p_kthread);
begin
if (td=nil) then Exit;
if (td^.td_temp.addr<>nil) then
begin
FreeMem(td^.td_temp.addr);
end;
td^.td_temp:=Default(t_td_buffer);
end;
end.

View File

@ -214,6 +214,7 @@ procedure thread_dec_ref(td:p_kthread); public;
begin
if (System.InterlockedDecrement(td^.td_ref)=0) then
begin
thread_free_local_buffer(td);
thread_zombie(td);
end;
end;

View File

@ -562,7 +562,11 @@ begin
if (SPtr>td^.td_kstack.sttop) and (SPtr<=td^.td_kstack.stack) then
begin
if ((Result+size)>=SPtr) then Exit(nil);
if ((Result+size)>=SPtr) then
begin
Result:=thread_get_local_buffer(td,size+align-1);
Result:=System.Align(Result,align);
end;
end;
end;

View File

@ -69,6 +69,7 @@ var
td:p_kthread;
stack_size:ULONG_PTR;
headr_size:ULONG_PTR;
padding :ULONG_PTR;
data:Pointer;
size:ULONG_PTR;
R:DWORD;
@ -82,7 +83,9 @@ begin
end;
headr_size:=SizeOf(kthread)+size_of_umtx_q;
headr_size:=System.Align(headr_size,4*1024);
size :=System.Align(headr_size,4*1024);
padding :=size-headr_size;
headr_size:=size;
size:=headr_size+SYS_GUARD_SIZE+stack_size;
size:=System.Align(size,64*1024);
@ -131,6 +134,9 @@ begin
td^.td_kstack.sttop:=data;
td^.td_kstack.stack:=data+stack_size;
td^.td_padding.addr:=Pointer(td)+(headr_size-padding);
td^.td_padding.size:=padding;
Result:=td;
end;

View File

@ -12,14 +12,15 @@ uses
subr_uio,
sys_tty;
const
TTY_STACKBUF=256;
function ttydisc_read_poll (tp:p_tty):QWORD;
function ttydisc_write_poll(tp:p_tty):QWORD;
function ttydisc_read (tp:p_tty;uio:p_uio;ioflag:Integer):Integer;
function ttydisc_write(tp:p_tty;uio:p_uio;ioflag:Integer):Integer;
function ttycrt_write(tp:p_tty;iov_base:Pointer;iov_len:qword):Integer;
implementation
uses
@ -60,160 +61,170 @@ begin
Result:=1;
end;
function ttydisc_read(tp:p_tty;uio:p_uio;ioflag:Integer):Integer;
function _ttydisc_read(tp:THandle;uio:p_uio;buf_addr:Pointer):Integer;
var
LEN:QWORD;
BLK:IO_STATUS_BLOCK;
BLK :IO_STATUS_BLOCK;
OFFSET:Int64;
BUF:array[0..1023] of AnsiChar;
begin
//init
BLK:=Default(IO_STATUS_BLOCK);
BLK :=Default(IO_STATUS_BLOCK);
OFFSET:=Int64(FILE_USE_FILE_POINTER_POSITION_L);
//
LEN:=uio^.uio_resid;
if (len>Length(BUF)) then len:=Length(BUF);
NtReadFile(tp,0,nil,nil,@BLK,buf_addr,uio^.uio_resid,@OFFSET,nil);
//
NtReadFile(tp^.t_rd_handle,0,nil,nil,@BLK,@BUF,LEN,@OFFSET,nil);
//
Result:=uiomove(@BUF, BLK.Information, uio);
Result:=uiomove(buf_addr, BLK.Information, uio);
end;
type
TWRITE_BUF=object
MAX,LEN:QWORD;
PTR:Pointer;
BUF:array[0..1023] of AnsiChar;
Procedure INIT ();
function WRITE(N:Pointer;L:QWORD):QWORD;
function UP (L:QWORD):QWORD;
function _ttydisc_read0(tp:THandle;uio:p_uio):Integer; inline;
var
BUF:array[0..TTY_STACKBUF-1] of AnsiChar;
begin
Result:=_ttydisc_read(tp,uio,@BUF);
end;
function ttydisc_read(tp:p_tty;uio:p_uio;ioflag:Integer):Integer;
begin
uio^.uio_td:=curkthread;
if (uio^.uio_td=nil) then
begin
if (uio^.uio_resid<=TTY_STACKBUF) then
begin
Result:=_ttydisc_read0(tp^.t_rd_handle,uio);
end else
begin
uio^.uio_td:=GetMem(uio^.uio_resid);
Result:=_ttydisc_read(tp^.t_rd_handle,uio,uio^.uio_td);
FreeMem(uio^.uio_td);
uio^.uio_td:=nil;
end;
end else
begin
Result:=_ttydisc_read(tp^.t_rd_handle,uio,thread_get_local_buffer(uio^.uio_td,uio^.uio_resid));
end;
end;
function tty_get_full_size(tp:p_tty;uio:p_uio):QWORD; inline;
begin
Result:=0;
//
if (tp^.t_newline<>0) then
begin
if ((tp^.t_flags and TF_TTY_NAME_PREFIX)<>0) then
begin
Result:=Result+tp^.t_nlen;
end;
//
if (uio^.uio_td<>nil) and
((tp^.t_flags and TF_THD_NAME_PREFIX)<>0) then
begin
Result:=Result+strlen(@p_kthread(uio^.uio_td)^.td_name)+3;
end;
end;
//
Result:=Result+uio^.uio_resid;
end;
// if (td^.td_name='SceVideoOutServiceThread') then exit;
function _ttydisc_write(tp:p_tty;uio:p_uio;buf_addr:Pointer):Integer;
var
CURR :Pointer;
BLK :IO_STATUS_BLOCK;
OFFSET:Int64;
LEN :QWORD;
procedure WRITE(ch:AnsiChar); inline;
begin
PAnsiChar(CURR)[0]:=ch;
Inc(CURR,1);
Inc(LEN ,1);
end;
procedure WRITE(N:Pointer;L:QWORD); inline;
begin
Move(N^,CURR^,L);
Inc(CURR,L);
Inc(LEN ,L);
end;
Procedure TWRITE_BUF.INIT();
begin
PTR:=@BUF[0];
MAX:=Length(BUF);
LEN:=0;
Result:=0;
//init
BLK :=Default(IO_STATUS_BLOCK);
OFFSET:=Int64(FILE_USE_FILE_POINTER_POSITION_L);
CURR :=buf_addr;
LEN :=0;
//
if (tp^.t_newline<>0) then
begin
//tty name
if ((tp^.t_flags and TF_TTY_NAME_PREFIX)<>0) then
begin
WRITE(tp^.t_name,tp^.t_nlen);
end;
//thread name
if (uio^.uio_td<>nil) and
((tp^.t_flags and TF_THD_NAME_PREFIX)<>0) then
begin
WRITE('(');
WRITE(@p_kthread(uio^.uio_td)^.td_name,strlen(@p_kthread(uio^.uio_td)^.td_name));
WRITE(pchar('):'),2);
end;
end;
//text
LEN:=LEN+uio^.uio_resid;
Result:=uiomove(CURR, uio^.uio_resid, uio);
CURR:=buf_addr+LEN-1;
//
tp^.t_newline:=ord((PAnsiChar(CURR)^=#13) or (PAnsiChar(CURR)^=#10));
//
Result:=NtWriteFile(tp^.t_wr_handle,0,nil,nil,@BLK,buf_addr,LEN,@OFFSET,nil);
//
if (Result=STATUS_PENDING) then
begin
Result:=NtWaitForSingleObject(tp^.t_wr_handle,False,nil);
if (Result=0) then
begin
Result:=BLK.Status;
end;
end;
//
Result:=0; //ignore errors
//
if (tp^.t_update<>nil) then
begin
tp^.t_update();
end;
end;
function TWRITE_BUF.WRITE(N:Pointer;L:QWORD):QWORD;
function _ttydisc_write0(tp:p_tty;uio:p_uio):Integer; inline;
var
BUF:array[0..TTY_STACKBUF-1] of AnsiChar;
begin
if (L>MAX) then L:=MAX;
Move(N^,PTR^,L);
Inc(PTR,L);
Dec(MAX,L);
Inc(LEN,L);
Result:=L;
end;
function TWRITE_BUF.UP(L:QWORD):QWORD;
begin
if (L>MAX) then L:=MAX;
Inc(PTR,L);
Dec(MAX,L);
Inc(LEN,L);
Result:=L;
Result:=_ttydisc_write(tp,uio,@BUF);
end;
function ttydisc_write(tp:p_tty;uio:p_uio;ioflag:Integer):Integer;
var
BLK:IO_STATUS_BLOCK;
OFFSET:Int64;
BUF:TWRITE_BUF;
i:QWORD;
td:p_kthread;
size:QWORD;
begin
Result:=0;
//init
BLK:=Default(IO_STATUS_BLOCK);
OFFSET:=Int64(FILE_WRITE_TO_END_OF_FILE_L);
//
BUF.INIT();
//tty name
if ((tp^.t_flags and TF_NOWRITEPREFIX)=0) then
uio^.uio_td:=curkthread;
size:=tty_get_full_size(tp,uio);
if (uio^.uio_td=nil) then
begin
BUF.WRITE(tp^.t_name,tp^.t_nlen);
end;
//thread
td:=curkthread;
if (td<>nil) then
begin
BUF.WRITE(pchar('('),1);
BUF.WRITE(@td^.td_name,strlen(@td^.td_name));
BUF.WRITE(pchar('):'),2);
end;
//text
while (uio^.uio_resid<>0) do
begin
i:=uio^.uio_resid;
Result:=uiomove(BUF.PTR, BUF.MAX, uio);
if (Result<>0) then Break;
i:=i-uio^.uio_resid;
BUF.UP(i);
//
NtWriteFile(tp^.t_wr_handle,0,nil,nil,@BLK,@BUF.BUF,BUF.LEN,@OFFSET,nil);
//
BUF.INIT();
end;
//
if (tp^.t_update<>nil) then
begin
tp^.t_update();
end;
end;
function ttycrt_write(tp:p_tty;iov_base:Pointer;iov_len:qword):Integer;
var
BLK:IO_STATUS_BLOCK;
OFFSET:Int64;
BUF:TWRITE_BUF;
i:QWORD;
td:p_kthread;
R:DWORD;
begin
Result:=0;
//init
BLK:=Default(IO_STATUS_BLOCK);
OFFSET:=Int64(FILE_WRITE_TO_END_OF_FILE_L);
//
BUF.INIT();
//tty name
if ((tp^.t_flags and TF_NOWRITEPREFIX)=0) then
begin
BUF.WRITE(tp^.t_name,tp^.t_nlen);
end;
//thread
td:=curkthread;
if (td<>nil) then
begin
BUF.WRITE(pchar('('),1);
BUF.WRITE(@td^.td_name,strlen(@td^.td_name));
BUF.WRITE(pchar('):'),2);
end;
//text
while (iov_len<>0) do
begin
i:=BUF.WRITE(iov_base,iov_len);
Inc(iov_base,i);
Dec(iov_len ,i);
//
R:=NtWriteFile(tp^.t_wr_handle,0,nil,nil,@BLK,@BUF.BUF,BUF.LEN,@OFFSET,nil);
//
if (R=STATUS_PENDING) then
if (size<=TTY_STACKBUF) then
begin
R:=NtWaitForSingleObject(tp^.t_wr_handle,False,nil);
if (R=0) then
begin
R:=BLK.Status;
end;
Result:=_ttydisc_write0(tp,uio);
end else
begin
uio^.uio_td:=GetMem(size);
Result:=_ttydisc_write(tp,uio,uio^.uio_td);
FreeMem(uio^.uio_td);
uio^.uio_td:=nil;
end;
//
BUF.INIT();
end;
//
if (tp^.t_update<>nil) then
end else
begin
tp^.t_update();
Result:=_ttydisc_write(tp,uio,thread_get_local_buffer(uio^.uio_td,size));
end;
end;

View File

@ -12,19 +12,31 @@ Procedure sys_tty_init;
implementation
uses
vuio,
md_tty,
kern_thread;
Procedure CrtOutWrite(var t:TextRec);
var
tp:p_tty;
aiov:iovec;
auio:t_uio;
Begin
if (t.BufPos=0) then Exit;
tp:=PPointer(@t.UserData)^;
if (tp=nil) then Exit;
ttycrt_write(tp,t.Bufptr,t.BufPos);
aiov.iov_base :=t.Bufptr;
aiov.iov_len :=t.BufPos;
auio.uio_iov :=@aiov;
auio.uio_iovcnt:=1;
auio.uio_offset:=0;
auio.uio_resid :=t.BufPos;
auio.uio_segflg:=UIO_SYSSPACE;
auio.uio_rw :=UIO_WRITE;
ttydisc_write(tp,@auio,0);
t.BufPos:=0;
end;

View File

@ -12,15 +12,17 @@ uses
kern_mtx;
const
TF_NOWRITEPREFIX=$00001;
TF_TTY_NAME_PREFIX=$00001;
TF_THD_NAME_PREFIX=$00002;
type
p_tty=^t_tty;
t_tty=record
t_name :PChar;
t_nlen :QWORD;
t_nlen :DWORD;
t_flags :QWORD;
t_flags :WORD;
t_newline:WORD;
t_mtx :p_mtx; // TTY lock.
t_mtxobj :mtx; // Per-TTY lock (when not borrowing).
@ -37,7 +39,7 @@ type
procedure tty_lock (tp:p_tty);
procedure tty_unlock(tp:p_tty);
procedure tty_init(tp:p_tty;name:PChar;mutex:p_mtx);
procedure tty_init(tp:p_tty;name:PChar;mutex:p_mtx;flags:WORD);
procedure tty_fini(tp:p_tty);
var
@ -63,7 +65,7 @@ begin
mtx_unlock(tp^.t_mtx^)
end;
procedure tty_init(tp:p_tty;name:PChar;mutex:p_mtx);
procedure tty_init(tp:p_tty;name:PChar;mutex:p_mtx;flags:WORD);
begin
if (tp=nil) then Exit;
@ -86,6 +88,8 @@ begin
knlist_init_mtx(@tp^.t_inpoll .si_note, tp^.t_mtx);
knlist_init_mtx(@tp^.t_outpoll.si_note, tp^.t_mtx);
tp^.t_flags :=flags;
tp^.t_newline:=1;
end;
procedure tty_fini(tp:p_tty);