diff --git a/fpPS4.lpi b/fpPS4.lpi
index e769282e..a1642674 100644
--- a/fpPS4.lpi
+++ b/fpPS4.lpi
@@ -842,6 +842,10 @@
+
+
+
+
diff --git a/sys/dev/dev_dce.pas b/sys/dev/dev_dce.pas
index 618c0653..24579f7b 100644
--- a/sys/dev/dev_dce.pas
+++ b/sys/dev/dev_dce.pas
@@ -6,15 +6,24 @@ unit dev_dce;
interface
uses
+ sysutils,
vm,
vmparam,
kern_conf,
sys_event,
- time;
+ time,
+ kern_mtx,
+ display_interface;
procedure dce_initialize();
var
+ dce_interface:TAbstractDisplay=TDisplayInterface;
+
+ dce_handle:TDisplayHandle;
+
+ dce_mtx:mtx;
+
dce_page:Pointer;
g_video_out_event_flip:t_knlist;
@@ -29,14 +38,19 @@ uses
sys_vm_object,
vm_pager,
kern_event,
- kern_mtx,
md_time,
kern_proc,
kern_timeout;
const
- EVENTID_FLIP =$0006;
- EVENTID_VBLANK=$0007;
+ EVENTID_FLIP =$0006;
+ EVENTID_VBLANK =$0007;
+ EVENTID_SETMODE =$0051;
+ EVENTID_POSITION =$0058;
+ EVENTID_PREVBLANK=$0059;
+
+ //$0062 wZI4fmUJMlw / vXMpe7Murfc
+ //$0063 sys_vblank
procedure knote_eventid(event_id:WORD;flipArg:QWORD;lockflags:Integer);
begin
@@ -139,7 +153,7 @@ type
flipPendingNum0:DWORD;
gcQueueNum :DWORD;
flipPendingNum1:DWORD;
- submitTsc :DWORD;
+ submitTsc :QWORD;
f_0x40 :QWORD;
end;
@@ -291,8 +305,11 @@ var
poff:PQWORD;
plen:PQWORD;
len:QWORD;
- resl_status:t_resolution_status;
- flip_status:t_flip_status;
+ u:record
+ case byte of
+ 0:(r_status:t_resolution_status);
+ 1:(f_status:t_flip_status);
+ end;
begin
Result:=0;
@@ -304,10 +321,37 @@ begin
if (data^.arg6=0) and (data^.arg2=0) then
begin
+ //arg3 [0..1]
+ case Integer(data^.arg3) of
+ 0:;
+ 1:begin
+ //sceSblACMgrIsSystemUcred
+ Exit(EPERM);
+ end;
+ else
+ begin
+ Exit(EINVAL);
+ end;
+ end;
+
+ mtx_lock(dce_mtx);
+
+ if (dce_handle=nil) then
+ begin
+ dce_handle:=dce_interface.Open;
+ end else
+ begin
+ Result:=EBUSY;
+ end;
+
+ mtx_unlock(dce_mtx);
+
+ if (Result<>0) then Exit;
+
Writeln('dce_video_open');
ptr:=Pointer(data^.arg5);
- len:=111; //canary
+ len:=$a5a5; //canary
copyout(@len,ptr,SizeOf(QWORD));
open_vblank;
@@ -324,6 +368,22 @@ begin
begin
//arg2 -> canary
+ if (data^.arg2<>$a5a5) then Exit(EINVAL);
+
+ mtx_lock(dce_mtx);
+
+ if (dce_handle=nil) then
+ begin
+ Result:=EINVAL;
+ end else
+ begin
+ FreeAndNil(dce_handle);
+ end;
+
+ mtx_unlock(dce_mtx);
+
+ if (Result<>0) then Exit;
+
Writeln('dce_video_close:',data^.arg2);
close_vblank;
@@ -340,6 +400,24 @@ begin
//arg2 -> canary
//arg3 -> fid
+ if (data^.arg2<>$a5a5) then Exit(EINVAL);
+
+ if (Integer(data^.arg3)>15) then Exit(EINVAL);
+
+ mtx_lock(dce_mtx);
+
+ if (dce_handle=nil) then
+ begin
+ Result:=EINVAL;
+ end else
+ begin
+ Result:=dce_handle.UnregisterBuffer(Integer(data^.arg3));
+ end;
+
+ mtx_unlock(dce_mtx);
+
+ if (Result<>0) then Exit;
+
Writeln('UnregisterBufferAttribute:',data^.arg2,' ',data^.arg3);
Exit(0);
@@ -354,6 +432,22 @@ begin
//arg2 -> canary
//arg3 -> rate
+ if (data^.arg2<>$a5a5) then Exit(EINVAL);
+
+ mtx_lock(dce_mtx);
+
+ if (dce_handle=nil) then
+ begin
+ Result:=EINVAL;
+ end else
+ begin
+ Result:=dce_handle.SetFlipRate(Integer(data^.arg3));
+ end;
+
+ mtx_unlock(dce_mtx);
+
+ if (Result<>0) then Exit;
+
Writeln('SetFlipRate:',data^.arg2,' ',data^.arg3);
Exit(0);
@@ -367,6 +461,8 @@ begin
begin
//arg2 -> canary
+ if (data^.arg2<>$a5a5) then Exit(EINVAL);
+
poff:=Pointer(data^.arg3); //output offset //4000..3FFC000
plen:=Pointer(data^.arg4); //output len //4000
@@ -392,20 +488,42 @@ begin
//arg3 = &result;
//arg4 = 72
+ if (data^.arg2<>$a5a5) then Exit(EINVAL);
+
ptr:=Pointer(data^.arg3);
- flip_status:=Default(t_flip_status);
- flip_status.flipArg :=flipArg;
- flip_status.count :=0;
- flip_status.processTime :=0;
- flip_status.tsc :=0;
- flip_status.currentBuffer :=0;
- flip_status.flipPendingNum0:=0;
- flip_status.gcQueueNum :=0;
- flip_status.flipPendingNum1:=0;
- flip_status.submitTsc :=0;
+ len:=Integer(data^.arg4);
+ if (len>SizeOf(t_flip_status)) then
+ begin
+ len:=SizeOf(t_flip_status);
+ end;
- Result:=copyout(@flip_status,ptr,data^.arg4);
+ u.f_status:=Default(t_flip_status);
+ u.f_status.flipArg :=flipArg;
+ u.f_status.count :=0;
+ u.f_status.processTime :=0;
+ u.f_status.tsc :=0;
+ u.f_status.currentBuffer :=0;
+ u.f_status.flipPendingNum0:=0;
+ u.f_status.gcQueueNum :=0;
+ u.f_status.flipPendingNum1:=0;
+ u.f_status.submitTsc :=0;
+
+ mtx_lock(dce_mtx);
+
+ if (dce_handle=nil) then
+ begin
+ Result:=EINVAL;
+ end else
+ begin
+ Result:=dce_handle.GetFlipStatus(@u.f_status);
+ end;
+
+ mtx_unlock(dce_mtx);
+
+ if (Result<>0) then Exit;
+
+ Result:=copyout(@u.f_status,ptr,len);
Exit;
end;
@@ -423,6 +541,8 @@ begin
//arg3 -> ptr
//arg4 -> 64
+ if (data^.arg2<>$a5a5) then Exit(EINVAL);
+
ptr:=Pointer(data^.arg3);
len:=0;
@@ -446,17 +566,39 @@ begin
//arg3 = &result;
//arg4 = 44;
+ if (data^.arg2<>$a5a5) then Exit(EINVAL);
+
ptr:=Pointer(data^.arg3);
- resl_status:=Default(t_resolution_status);
- resl_status.width :=1920;
- resl_status.heigth :=1080;
- resl_status.paneWidth :=1920;
- resl_status.paneHeight :=1080;
- resl_status.refreshHz :=$426fc28f;
- resl_status.screenSizeInInch:=32;
+ len:=Integer(data^.arg4);
+ if (len>SizeOf(t_resolution_status)) then
+ begin
+ len:=SizeOf(t_resolution_status);
+ end;
- Result:=copyout(@resl_status,ptr,data^.arg4);
+ u.r_status:=Default(t_resolution_status);
+ u.r_status.width :=1920;
+ u.r_status.heigth :=1080;
+ u.r_status.paneWidth :=1920;
+ u.r_status.paneHeight :=1080;
+ u.r_status.refreshHz :=$426fc28f;
+ u.r_status.screenSizeInInch:=32;
+
+ mtx_lock(dce_mtx);
+
+ if (dce_handle=nil) then
+ begin
+ Result:=EINVAL;
+ end else
+ begin
+ Result:=dce_handle.GetResolutionStatus(@u.r_status);
+ end;
+
+ mtx_unlock(dce_mtx);
+
+ if (Result<>0) then Exit;
+
+ Result:=copyout(@u.r_status,ptr,len);
Exit;
end;
@@ -469,17 +611,22 @@ begin
begin
//arg2 -> canary
//arg4 = 80;
+
+ if (data^.arg2<>$a5a5) then Exit(EINVAL);
+
Result:=dce_set_cursor_info(dev,data^.arg2,data^.arg5,Pointer(data^.arg3));
Exit;
end;
Exit(EINVAL);
end;
- 31: //set vaddr
+ 31: //sys
begin
//arg2 -> canary
//arg3 <- subtype 0..13
+ if (data^.arg2<>$a5a5) then Exit(EINVAL);
+
if (data^.arg3>13) then Exit(EINVAL);
Writeln('dce_flip_control(',data^.id,'):',data^.arg3,' 0x',HexStr(data^.arg4,16));
@@ -500,7 +647,7 @@ type
p_register_buffer_attr_args=^t_register_buffer_attr_args;
t_register_buffer_attr_args=packed record
canary :QWORD; //arg5 data in dce_flip_control:0:pointer(arg5)^
- vid :Byte; //video output port id ?
+ attrid :Byte; //attribute id [0..3]
submit :Byte; //0 = RegisterBuffers ; 1 = SubmitChangeBufferAttribute
f_0xa :WORD;
pixelFormat:DWORD;
@@ -519,7 +666,28 @@ Function dce_register_buffer_attr(dev:p_cdev;data:p_register_buffer_attr_args):I
begin
Result:=0;
- Writeln('register_buffer_attr:',data^.vid,' ',
+ if (data^.canary<>$a5a5) then Exit(EINVAL);
+
+ if (data^.attrid>3) then Exit(EINVAL);
+ if (data^.submit>1) then Exit(EINVAL);
+
+ mtx_lock(dce_mtx);
+
+ if (dce_handle=nil) then
+ begin
+ Result:=EINVAL;
+ end else
+ begin
+ case data^.submit of
+ 0:Result:=dce_handle.RegisterBufferAttribute(data^.attrid,@data^.pixelFormat);
+ 1:Result:=dce_handle.SubmitBufferAttribute (data^.attrid,@data^.pixelFormat);
+ else;
+ end;
+ end;
+
+ mtx_unlock(dce_mtx);
+
+ Writeln('register_buffer_attr:',data^.attrid,' ',
data^.submit,' ',
'0x',HexStr(data^.pixelFormat,8),' ',
data^.tilingMode,' ',
@@ -534,17 +702,35 @@ type
p_register_buffer_ptrs=^t_register_buffer_ptrs;
t_register_buffer_ptrs=packed record
canary:QWORD; //arg5 data in dce_flip_control:0:pointer(arg5)^
- index :DWORD; //buffer index
- vid :DWORD; //video output port id ?
+ index :DWORD; //buffer index [0..15]
+ attrid:DWORD; //attribute id [0..3]
left :Pointer; //buffer ptr
right :Pointer; //Stereo ptr
+ unk :Integer;
end;
Function dce_register_buffer_ptrs(dev:p_cdev;data:p_register_buffer_ptrs):Integer;
begin
Result:=0;
- Writeln('register_buffer_ptrs:',data^.vid,' ',
+ if (data^.canary<>$a5a5) then Exit(EINVAL);
+
+ if (data^.index>15) then Exit(EINVAL);
+ if (data^.attrid>3) then Exit(EINVAL);
+
+ mtx_lock(dce_mtx);
+
+ if (dce_handle=nil) then
+ begin
+ Result:=EINVAL;
+ end else
+ begin
+ Result:=dce_handle.RegisterBuffer(@data^.index);
+ end;
+
+ mtx_unlock(dce_mtx);
+
+ Writeln('register_buffer_ptrs:',data^.attrid,' ',
data^.index,' ',
'0x',HexStr(data^.left),' ',
'0x',HexStr(data^.right));
@@ -553,8 +739,8 @@ end;
type
- p_submit_flip=^t_submit_flip;
- t_submit_flip=packed record
+ p_submit_flip_args=^t_submit_flip_args;
+ t_submit_flip_args=packed record
canary :QWORD; //arg5 data in dce_flip_control:0:pointer(arg5)^
bufferIndex:QWORD;
flipMode :DWORD;
@@ -563,22 +749,53 @@ type
flipArg2 :QWORD;
eop_nz :DWORD;
f_0x2c :DWORD;
- eop_val :DWORD;
- f_0x34 :DWORD;
+ eop_val :PQWORD;
f_0x38 :QWORD;
rout :PQWORD; //extraout of result
end;
-Function dce_submit_flip(dev:p_cdev;data:p_submit_flip):Integer;
+Function dce_submit_flip(dev:p_cdev;data:p_submit_flip_args):Integer;
var
+ submit:t_submit_flip;
+ eop_val:PQWORD;
ures:QWORD;
begin
Result:=0;
+ if (data^.canary<>$a5a5) then Exit(EINVAL);
+
+ if (data^.bufferIndex>15) then Exit(EINVAL);
+ if (data^.eop_nz>1) then Exit(EINVAL);
+
+ submit.bufferIndex:=data^.bufferIndex;
+ submit.flipMode :=data^.flipMode;
+ submit.flipArg :=data^.flipArg;
+ submit.flipArg2 :=data^.flipArg2;
+
+ if (data^.eop_nz=1) then
+ begin
+ eop_val:=data^.eop_val;
+ end else
+ begin
+ eop_val:=nil;
+ end;
+
+ mtx_lock(dce_mtx);
+
+ if (dce_handle=nil) then
+ begin
+ Result:=EINVAL;
+ end else
+ begin
+ Result:=dce_handle.SubmitFlip(@submit,eop_val);
+ end;
+
+ mtx_unlock(dce_mtx);
+
Writeln('submit_flip:',data^.bufferIndex,' ',
data^.flipMode,' ',
'0x',HexStr(data^.flipArg,16),' ',
- data^.eop_val);
+ '0x',HexStr(data^.eop_val));
knote_eventid(EVENTID_FLIP, data^.flipArg, 0); //SCE_VIDEO_OUT_EVENT_FLIP
@@ -734,20 +951,22 @@ begin
event_id:=kn^.kn_kevent.ident shr 48;
case event_id of
- EVENTID_FLIP: //SCE_VIDEO_OUT_EVENT_FLIP
+ EVENTID_FLIP, //SCE_VIDEO_OUT_EVENT_FLIP
+ EVENTID_VBLANK, //SCE_VIDEO_OUT_EVENT_VBLANK
+ EVENTID_SETMODE, //8
+ EVENTID_POSITION, //12
+ EVENTID_PREVBLANK, //SCE_VIDEO_OUT_EVENT_PRE_VBLANK_START
+ $0060,
+ $0061,
+ $0062,
+ $0063:
begin
knlist_add(@g_video_out_event_flip,kn,0);
end;
- EVENTID_VBLANK: //SCE_VIDEO_OUT_EVENT_VBLANK
- begin
- knlist_add(@g_video_out_event_flip,kn,0);
- end;
- // $0051:Result:=8;
- // $0058:Result:=12;
else
begin
- Writeln(stderr,'filt_display_attach:',event_id);
- Assert(false,'filt_display_attach');
+ //Writeln(stderr,'filt_display_attach:',event_id);
+ //Assert(false,'filt_display_attach');
Result:=EINVAL;
end;
end;
@@ -762,16 +981,18 @@ begin
event_id:=kn^.kn_kevent.ident shr 48;
case event_id of
- EVENTID_FLIP: //SCE_VIDEO_OUT_EVENT_FLIP
+ EVENTID_FLIP, //SCE_VIDEO_OUT_EVENT_FLIP
+ EVENTID_VBLANK, //SCE_VIDEO_OUT_EVENT_VBLANK
+ EVENTID_SETMODE, //8
+ EVENTID_POSITION, //12
+ EVENTID_PREVBLANK, //SCE_VIDEO_OUT_EVENT_PRE_VBLANK_START
+ $0060,
+ $0061,
+ $0062,
+ $0063:
begin
knlist_remove(@g_video_out_event_flip,kn,0)
end;
- EVENTID_VBLANK: //SCE_VIDEO_OUT_EVENT_VBLANK
- begin
- knlist_remove(@g_video_out_event_flip,kn,0)
- end;
- // $0051:Result:=8;
- // $0058:Result:=12;
else;
end;
@@ -834,6 +1055,7 @@ var
procedure dce_initialize();
begin
mtx_init(knlist_lock_flip,'knlist_lock_flip');
+ mtx_init(dce_mtx,'dce');
knlist_init_mtx(@g_video_out_event_flip,@knlist_lock_flip);
diff --git a/sys/dev/display_interface.pas b/sys/dev/display_interface.pas
new file mode 100644
index 00000000..f1f0c408
--- /dev/null
+++ b/sys/dev/display_interface.pas
@@ -0,0 +1,128 @@
+unit display_interface;
+
+{$mode ObjFPC}{$H+}
+
+interface
+
+type
+ p_flip_status=^t_flip_status;
+ t_flip_status=packed record
+ flipArg :QWORD;
+ flipArg2 :QWORD;
+ count :QWORD;
+ processTime :QWORD;
+ tsc :QWORD;
+ currentBuffer :DWORD;
+ flipPendingNum0:DWORD;
+ gcQueueNum :DWORD;
+ flipPendingNum1:DWORD;
+ submitTsc :QWORD;
+ end;
+
+ p_resolution_status=^t_resolution_status;
+ t_resolution_status=packed record
+ width :DWORD;
+ heigth :DWORD;
+ paneWidth :DWORD;
+ paneHeight :DWORD;
+ refreshHz :DWORD; //Single
+ screenSizeInInch:DWORD;
+ end;
+
+ p_register_buffer_attr=^t_register_buffer_attr;
+ t_register_buffer_attr=packed record
+ pixelFormat:DWORD;
+ tilingMode :DWORD;
+ pitchPixel :DWORD;
+ width :DWORD;
+ height :DWORD;
+ f_0x20 :Byte;
+ f_0x21 :Byte;
+ options :WORD;
+ end;
+
+ p_register_buffer=^t_register_buffer;
+ t_register_buffer=packed record
+ index :DWORD; //buffer index [0..15]
+ attrid:DWORD; //attribute id [0..3]
+ left :Pointer; //buffer ptr
+ right :Pointer; //Stereo ptr
+ end;
+
+ p_submit_flip=^t_submit_flip;
+ t_submit_flip=packed record
+ bufferIndex:DWORD;
+ flipMode :DWORD;
+ flipArg :QWORD;
+ flipArg2 :QWORD;
+ end;
+
+ TDisplayHandle=class
+ function GetFlipStatus (status:p_flip_status):Integer; virtual;
+ function GetResolutionStatus (status:p_resolution_status):Integer; virtual;
+ function SetFlipRate (rate:Integer):Integer; virtual;
+ function RegisterBufferAttribute(attrid:Byte;attr:p_register_buffer_attr):Integer; virtual;
+ function SubmitBufferAttribute (attrid:Byte;attr:p_register_buffer_attr):Integer; virtual;
+ function RegisterBuffer (buf:p_register_buffer):Integer; virtual;
+ function UnregisterBuffer (index:Integer):Integer; virtual;
+ function SubmitFlip (submit:p_submit_flip;eop_val:PQWORD):Integer; virtual;
+ end;
+
+ TDisplayInterface=class
+ class Function Open:TDisplayHandle; virtual;
+ end;
+
+ TAbstractDisplay=class of TDisplayInterface;
+
+implementation
+
+class Function TDisplayInterface.Open:TDisplayHandle;
+begin
+ Result:=TDisplayHandle.Create;
+end;
+
+//
+
+function TDisplayHandle.GetFlipStatus(status:p_flip_status):Integer;
+begin
+ Result:=0;
+end;
+
+function TDisplayHandle.GetResolutionStatus(status:p_resolution_status):Integer;
+begin
+ Result:=0;
+end;
+
+function TDisplayHandle.SetFlipRate(rate:Integer):Integer;
+begin
+ Result:=0;
+end;
+
+function TDisplayHandle.RegisterBufferAttribute(attrid:Byte;attr:p_register_buffer_attr):Integer;
+begin
+ Result:=0;
+end;
+
+function TDisplayHandle.SubmitBufferAttribute(attrid:Byte;attr:p_register_buffer_attr):Integer;
+begin
+ Result:=0;
+end;
+
+function TDisplayHandle.RegisterBuffer(buf:p_register_buffer):Integer;
+begin
+ Result:=0;
+end;
+
+function TDisplayHandle.UnregisterBuffer(index:Integer):Integer;
+begin
+ Result:=0;
+end;
+
+function TDisplayHandle.SubmitFlip(submit:p_submit_flip;eop_val:PQWORD):Integer;
+begin
+ Result:=0;
+end;
+
+
+end.
+
diff --git a/sys/kern/kern_dlsym.pas b/sys/kern/kern_dlsym.pas
index b02bfb2b..e5ceccb5 100644
--- a/sys/kern/kern_dlsym.pas
+++ b/sys/kern/kern_dlsym.pas
@@ -395,19 +395,30 @@ end;
type
p_jmpq64_trampoline=^t_jmpq64_trampoline;
t_jmpq64_trampoline=packed record
- lea:array[0..6] of Byte;
+ lea :array[0..6] of Byte; //48 8D 3D F9 FF FF FF
+ nop1 :Byte; //90
//
and_rsp:DWORD; //48 83 E4 F0
//
inst :Word; //FF 15
- offset :DWORD; //00
+ offset :DWORD; //02
+ ret :Byte; //C3
+ nop2 :Byte; //90
addr :QWORD;
nid :QWORD;
libname:PChar;
end;
const
- c_jmpq64_trampoline:t_jmpq64_trampoline=(lea:($48,$8D,$3D,$F9,$FF,$FF,$FF);and_rsp:($F0E48348);inst:$15FF;offset:0;addr:0);
+ c_jmpq64_trampoline:t_jmpq64_trampoline=(lea :($48,$8D,$3D,$F9,$FF,$FF,$FF);
+ nop1 :$90;
+ and_rsp:($F0E48348);
+ inst :$15FF;offset:$02;
+ ret :$C3;
+ nop2 :$90;
+ addr :0;
+ nid :0;
+ libname:nil);
procedure _unresolve_symbol(data:p_jmpq64_trampoline);
var
diff --git a/sys/vm/vm_nt_map.pas b/sys/vm/vm_nt_map.pas
index b9b2c466..66633501 100644
--- a/sys/vm/vm_nt_map.pas
+++ b/sys/vm/vm_nt_map.pas
@@ -23,7 +23,7 @@ type
vm_nt_file_obj=packed record
hfile:THandle;
refs :QWORD;
- flags:QWORD;
+ flags:Byte;
maxp :Byte;
end;