mirror of https://github.com/red-prig/fpPS4.git
261 lines
5.1 KiB
Plaintext
261 lines
5.1 KiB
Plaintext
unit md_tty;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
uses
|
|
windows,
|
|
ntapi,
|
|
vuio,
|
|
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;
|
|
|
|
implementation
|
|
|
|
uses
|
|
kern_thr;
|
|
|
|
function ttydisc_read_poll(tp:p_tty):QWORD;
|
|
var
|
|
N:DWORD;
|
|
begin
|
|
N:=0;
|
|
|
|
case GetFileType(tp^.t_rd_handle) of
|
|
FILE_TYPE_DISK:
|
|
begin
|
|
N:=1;
|
|
end;
|
|
FILE_TYPE_CHAR:
|
|
begin
|
|
GetNumberOfConsoleInputEvents(tp^.t_rd_handle,@N);
|
|
end;
|
|
FILE_TYPE_PIPE:
|
|
begin
|
|
PeekNamedPipe(tp^.t_rd_handle,
|
|
nil,
|
|
0,
|
|
nil,
|
|
@N,
|
|
nil);
|
|
end;
|
|
else;
|
|
end;
|
|
|
|
Result:=N;
|
|
end;
|
|
|
|
function ttydisc_write_poll(tp:p_tty):QWORD;
|
|
begin
|
|
Result:=1;
|
|
end;
|
|
|
|
function _ttydisc_read(tp:THandle;uio:p_uio;buf_addr:Pointer):Integer;
|
|
var
|
|
BLK :IO_STATUS_BLOCK;
|
|
OFFSET:Int64;
|
|
begin
|
|
//init
|
|
BLK :=Default(IO_STATUS_BLOCK);
|
|
OFFSET:=Int64(FILE_USE_FILE_POINTER_POSITION_L);
|
|
//
|
|
NtReadFile(tp,0,nil,nil,@BLK,buf_addr,uio^.uio_resid,@OFFSET,nil);
|
|
//
|
|
Result:=uiomove(buf_addr, BLK.Information, uio);
|
|
end;
|
|
|
|
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;
|
|
|
|
begin
|
|
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 _ttydisc_write0(tp:p_tty;uio:p_uio):Integer; inline;
|
|
var
|
|
BUF:array[0..TTY_STACKBUF-1] of AnsiChar;
|
|
begin
|
|
Result:=_ttydisc_write(tp,uio,@BUF);
|
|
end;
|
|
|
|
function ttydisc_write(tp:p_tty;uio:p_uio;ioflag:Integer):Integer;
|
|
var
|
|
size:QWORD;
|
|
begin
|
|
uio^.uio_td:=curkthread;
|
|
size:=tty_get_full_size(tp,uio);
|
|
if (uio^.uio_td=nil) then
|
|
begin
|
|
if (size<=TTY_STACKBUF) then
|
|
begin
|
|
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;
|
|
end else
|
|
begin
|
|
Result:=_ttydisc_write(tp,uio,thread_get_local_buffer(uio^.uio_td,size));
|
|
end;
|
|
end;
|
|
|
|
procedure md_init_tty; register;
|
|
var
|
|
i:Integer;
|
|
begin
|
|
For i:=0 to High(std_tty) do
|
|
begin
|
|
std_tty[i].t_rd_handle:=GetStdHandle(STD_INPUT_HANDLE);
|
|
std_tty[i].t_wr_handle:=GetStdHandle(STD_OUTPUT_HANDLE);
|
|
end;
|
|
|
|
For i:=0 to High(deci_tty) do
|
|
begin
|
|
deci_tty[i].t_rd_handle:=GetStdHandle(STD_INPUT_HANDLE);
|
|
deci_tty[i].t_wr_handle:=GetStdHandle(STD_OUTPUT_HANDLE);
|
|
end;
|
|
|
|
std_tty [2].t_wr_handle:=GetStdHandle(STD_ERROR_HANDLE);
|
|
deci_tty[2].t_wr_handle:=GetStdHandle(STD_ERROR_HANDLE);
|
|
|
|
debug_tty.t_rd_handle:=GetStdHandle(STD_INPUT_HANDLE);
|
|
debug_tty.t_wr_handle:=GetStdHandle(STD_OUTPUT_HANDLE);
|
|
end;
|
|
|
|
initialization
|
|
init_tty:=@md_init_tty;
|
|
|
|
end.
|
|
|
|
|
|
|