Gamepad
This commit is contained in:
parent
22cf48e712
commit
ea9f0217a1
3 changed files with 229 additions and 4 deletions
|
|
@ -137,6 +137,7 @@ A RISC-V RV64GCV/RVA23 emulator written in Object Pascal. It simulates processor
|
|||
- Filesystem (virtio-fs, FUSE-based host directory sharing)
|
||||
- Keyboard
|
||||
- Mouse
|
||||
- Gamepad
|
||||
- Sound
|
||||
- VirtIO Sound (default)
|
||||
- FM801 (Ensoniq PCI sound card, with PCM and OPL3 support, if SoundMode=FM801, but currently with some timing dropout issues, so CMI8738 is recommended instead if OPL3 is needed, otherwise just use VirtIO Sound which works fine and has better performance and lower latency than all hardware-emulated sound options)
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ are required. The VirtIO devices are used to provide a standard interface for de
|
|||
| VIRTIO FS | $1005b000 | $1000 | $1b | VirtIO filesystem device |
|
||||
| VIRTIO CRYPTO | $1005c000 | $1000 | $1c | VirtIO crypto device |
|
||||
| VIRTIO BALLOON | $1005d000 | $1000 | $1d | VirtIO balloon device |
|
||||
| VIRTIO INPUT GAMEPAD | $1005e000 | $1000 | $1e | VirtIO gamepad input (evdev: BTN_GAMEPAD + dual sticks/triggers/D-pad) |
|
||||
|
||||
For each VirtIO device, the MMIO region size is $1000. For the VirtIO GPU device, the guest OS allocates its own frame buffer memory ranges, so $1000 as MMIO region size remains valid for the device registers in this case.
|
||||
|
||||
|
|
|
|||
231
src/PasRISCV.pas
231
src/PasRISCV.pas
|
|
@ -1,7 +1,7 @@
|
|||
(******************************************************************************
|
||||
* PasRISCV *
|
||||
******************************************************************************
|
||||
* Version 2026-05-13-03-23-0000 *
|
||||
* Version 2026-06-04-04-25-0000 *
|
||||
******************************************************************************
|
||||
* zlib license *
|
||||
*============================================================================*
|
||||
|
|
@ -6452,14 +6452,42 @@ type PPPasRISCVInt8=^PPasRISCVInt8;
|
|||
ABS_X=$00;
|
||||
ABS_Y=$01;
|
||||
ABS_Z=$02;
|
||||
ABS_RX=$03;
|
||||
ABS_RY=$04;
|
||||
ABS_RZ=$05;
|
||||
ABS_HAT0X=$10;
|
||||
ABS_HAT0Y=$11;
|
||||
BTN_SOUTH=$130; // A
|
||||
BTN_EAST=$131; // B
|
||||
BTN_NORTH=$133; // X
|
||||
BTN_WEST=$134; // Y
|
||||
BTN_TL=$136; // Left shoulder
|
||||
BTN_TR=$137; // Right shoulder
|
||||
BTN_TL2=$138; // Left trigger (digital)
|
||||
BTN_TR2=$139; // Right trigger (digital)
|
||||
BTN_SELECT=$13a;
|
||||
BTN_START=$13b;
|
||||
BTN_MODE=$13c; // Guide/Home
|
||||
BTN_THUMBL=$13d; // Left stick press
|
||||
BTN_THUMBR=$13e; // Right stick press
|
||||
GAMEPAD_ABS_MIN=-32767;
|
||||
GAMEPAD_ABS_MAX=32767;
|
||||
GAMEPAD_TRIGGER_MAX=32767;
|
||||
ButtonList:array[0..2] of TPasRISCVUInt16=(BTN_LEFT,BTN_RIGHT,BTN_MIDDLE);
|
||||
GamepadButtonList:array[0..12] of TPasRISCVUInt16=
|
||||
(
|
||||
BTN_SOUTH,BTN_EAST,BTN_NORTH,BTN_WEST,BTN_TL,BTN_TR,BTN_TL2,BTN_TR2,
|
||||
BTN_SELECT,BTN_START,BTN_MODE,BTN_THUMBL,BTN_THUMBR
|
||||
);
|
||||
GamepadAxisList:array[0..7] of TPasRISCVUInt16=(ABS_X,ABS_Y,ABS_RX,ABS_RY,ABS_Z,ABS_RZ,ABS_HAT0X,ABS_HAT0Y);
|
||||
Vendor=$ffff;
|
||||
DeviceID=$12;
|
||||
type TInputKind=
|
||||
(
|
||||
Keyboard,
|
||||
Mouse,
|
||||
Tablet
|
||||
Tablet,
|
||||
Gamepad
|
||||
);
|
||||
TKind=TInputKind;
|
||||
PKind=^TKind;
|
||||
|
|
@ -6471,6 +6499,7 @@ type PPPasRISCVInt8=^PPasRISCVInt8;
|
|||
destructor Destroy; override;
|
||||
function HandleKeyboard(const aKeyCode:TPasRISCVUInt16;const aDown:Boolean):Boolean;
|
||||
function HandleMouse(const aDX,aDY,aDZ:TPasRISCVInt32;const aButtons:TPasRISCVUInt32):Boolean;
|
||||
function HandleGamepad(const aLeftX,aLeftY,aRightX,aRightY,aLeftTrigger,aRightTrigger,aHatX,aHatY:TPasRISCVInt32;const aButtons:TPasRISCVUInt32):Boolean;
|
||||
procedure DeviceReset; override;
|
||||
function DeviceRecv(const aQueueIndex,aDescriptorIndex,aReadSize,aWriteSize:TPasRISCVUInt64):Boolean; override;
|
||||
function QueueEvent(const aType,aCode:TPasRISCVUInt16;const aValue:TPasRISCVUInt32):Boolean;
|
||||
|
|
@ -6511,6 +6540,17 @@ type PPPasRISCVInt8=^PPasRISCVInt8;
|
|||
procedure LoadSnapshot(const aNode:TSnapshot.TNode); override;
|
||||
procedure SaveSnapshot(const aNode:TSnapshot.TNode); override;
|
||||
end;
|
||||
TVirtIOInputGamepadDevice=class(TVirtIOInputDevice)
|
||||
public
|
||||
const DefaultBaseAddress=TPasRISCVUInt64($1005e000);
|
||||
DefaultSize=TPasRISCVUInt64($1000);
|
||||
DefaultIRQ=TPasRISCVUInt64($1e);
|
||||
public
|
||||
constructor Create(const aMachine:TPasRISCV); reintroduce;
|
||||
procedure DeviceInitialize; override;
|
||||
procedure LoadSnapshot(const aNode:TSnapshot.TNode); override;
|
||||
procedure SaveSnapshot(const aNode:TSnapshot.TNode); override;
|
||||
end;
|
||||
{ TVirtIOSoundDevice }
|
||||
TVirtIOSoundDevice=class(TVirtIODevice)
|
||||
public
|
||||
|
|
@ -13392,6 +13432,10 @@ type PPPasRISCVInt8=^PPasRISCVInt8;
|
|||
fVirtIOInputTabletSize:TPasRISCVUInt64;
|
||||
fVirtIOInputTabletIRQ:TPasRISCVUInt64;
|
||||
|
||||
fVirtIOInputGamepadBase:TPasRISCVUInt64;
|
||||
fVirtIOInputGamepadSize:TPasRISCVUInt64;
|
||||
fVirtIOInputGamepadIRQ:TPasRISCVUInt64;
|
||||
|
||||
fVirtIOSoundBase:TPasRISCVUInt64;
|
||||
fVirtIOSoundSize:TPasRISCVUInt64;
|
||||
fVirtIOSoundIRQ:TPasRISCVUInt64;
|
||||
|
|
@ -13611,6 +13655,10 @@ type PPPasRISCVInt8=^PPasRISCVInt8;
|
|||
property VirtIOInputTabletSize:TPasRISCVUInt64 read fVirtIOInputTabletSize write fVirtIOInputTabletSize;
|
||||
property VirtIOInputTabletIRQ:TPasRISCVUInt64 read fVirtIOInputTabletIRQ write fVirtIOInputTabletIRQ;
|
||||
|
||||
property VirtIOInputGamepadBase:TPasRISCVUInt64 read fVirtIOInputGamepadBase write fVirtIOInputGamepadBase;
|
||||
property VirtIOInputGamepadSize:TPasRISCVUInt64 read fVirtIOInputGamepadSize write fVirtIOInputGamepadSize;
|
||||
property VirtIOInputGamepadIRQ:TPasRISCVUInt64 read fVirtIOInputGamepadIRQ write fVirtIOInputGamepadIRQ;
|
||||
|
||||
property VirtIOSoundBase:TPasRISCVUInt64 read fVirtIOSoundBase write fVirtIOSoundBase;
|
||||
property VirtIOSoundSize:TPasRISCVUInt64 read fVirtIOSoundSize write fVirtIOSoundSize;
|
||||
property VirtIOSoundIRQ:TPasRISCVUInt64 read fVirtIOSoundIRQ write fVirtIOSoundIRQ;
|
||||
|
|
@ -13813,6 +13861,8 @@ type PPPasRISCVInt8=^PPasRISCVInt8;
|
|||
|
||||
fVirtIOInputTabletDevice:TVirtIOInputTabletDevice;
|
||||
|
||||
fVirtIOInputGamepadDevice:TVirtIOInputGamepadDevice;
|
||||
|
||||
fVirtIOSoundDevice:TVirtIOSoundDevice;
|
||||
|
||||
fVirtIO9PDevice:TVirtIO9PDevice;
|
||||
|
|
@ -14063,6 +14113,8 @@ type PPPasRISCVInt8=^PPasRISCVInt8;
|
|||
|
||||
property VirtIOInputTabletDevice:TVirtIOInputTabletDevice read fVirtIOInputTabletDevice;
|
||||
|
||||
property VirtIOInputGamepadDevice:TVirtIOInputGamepadDevice read fVirtIOInputGamepadDevice;
|
||||
|
||||
property VirtIOSoundDevice:TVirtIOSoundDevice read fVirtIOSoundDevice;
|
||||
|
||||
property VirtIO9PDevice:TVirtIO9PDevice read fVirtIO9PDevice;
|
||||
|
|
@ -55805,9 +55857,54 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function TPasRISCV.TVirtIOInputDevice.HandleGamepad(const aLeftX,aLeftY,aRightX,aRightY,aLeftTrigger,aRightTrigger,aHatX,aHatY:TPasRISCVInt32;const aButtons:TPasRISCVUInt32):Boolean;
|
||||
var Index:TPasRISCVSizeInt;
|
||||
Button,LastButton:Boolean;
|
||||
Axes:array[0..7] of TPasRISCVInt32;
|
||||
begin
|
||||
if fKind=TPasRISCV.TVirtIOInputDevice.TKind.Gamepad then begin
|
||||
Axes[0]:=aLeftX;
|
||||
Axes[1]:=aLeftY;
|
||||
Axes[2]:=aRightX;
|
||||
Axes[3]:=aRightY;
|
||||
Axes[4]:=aLeftTrigger;
|
||||
Axes[5]:=aRightTrigger;
|
||||
Axes[6]:=aHatX;
|
||||
Axes[7]:=aHatY;
|
||||
result:=true;
|
||||
// Emit absolute axis state (evdev filters out unchanged ABS values on the guest side)
|
||||
for Index:=0 to length(GamepadAxisList)-1 do begin
|
||||
result:=QueueEvent(VIRTIO_INPUT_EV_ABS,GamepadAxisList[Index],TPasRISCVUInt32(Axes[Index]));
|
||||
if not result then begin
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
// Emit only the buttons that changed since the last report
|
||||
if result and (aButtons<>fButtonState) then begin
|
||||
for Index:=0 to length(GamepadButtonList)-1 do begin
|
||||
Button:=(aButtons and (TPasRISCVUInt32(1) shl Index))<>0;
|
||||
LastButton:=(fButtonState and (TPasRISCVUInt32(1) shl Index))<>0;
|
||||
if Button<>LastButton then begin
|
||||
result:=QueueEvent(VIRTIO_INPUT_EV_KEY,GamepadButtonList[Index],ord(Button) and 1);
|
||||
if not result then begin
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
fButtonState:=aButtons;
|
||||
end;
|
||||
if result then begin
|
||||
result:=QueueEvent(VIRTIO_INPUT_EV_SYN,0,0);
|
||||
end;
|
||||
end else begin
|
||||
result:=false;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPasRISCV.TVirtIOInputDevice.DeviceConfigWrite;
|
||||
var Name:TPasRISCVRawByteString;
|
||||
Index,Len:TPasRISCVSizeInt;
|
||||
AbsMin,AbsMax,AbsFuzz,AbsFlat,AbsRes:TPasRISCVInt32;
|
||||
begin
|
||||
case fConfigSpace[0] of
|
||||
VIRTIO_INPUT_CFG_UNSET:begin
|
||||
|
|
@ -55823,6 +55920,9 @@ begin
|
|||
TPasRISCV.TVirtIOInputDevice.TKind.Tablet:begin
|
||||
Name:='virtio_tablet';
|
||||
end;
|
||||
TPasRISCV.TVirtIOInputDevice.TKind.Gamepad:begin
|
||||
Name:='virtio_gamepad';
|
||||
end;
|
||||
else begin
|
||||
Name:='';
|
||||
end;
|
||||
|
|
@ -55899,6 +55999,28 @@ begin
|
|||
end;
|
||||
end;
|
||||
end;
|
||||
TPasRISCV.TVirtIOInputDevice.TKind.Gamepad:begin
|
||||
case fConfigSpace[1] of
|
||||
VIRTIO_INPUT_EV_KEY:begin
|
||||
fConfigSpace[2]:=768 div 8;
|
||||
FillChar(fConfigSpace[8],768 div 8,#0);
|
||||
for Index:=0 to length(GamepadButtonList)-1 do begin
|
||||
fConfigSpace[8+(GamepadButtonList[Index] shr 3)]:=fConfigSpace[8+(GamepadButtonList[Index] shr 3)] or (1 shl (GamepadButtonList[Index] and 7));
|
||||
end;
|
||||
end;
|
||||
VIRTIO_INPUT_EV_ABS:begin
|
||||
// Bits up to ABS_HAT0Y ($11) must be representable, so report 4 bytes
|
||||
fConfigSpace[2]:=4;
|
||||
PPasRISCVUInt32(Pointer(@fConfigSpace[8]))^:=(1 shl ABS_X) or (1 shl ABS_Y) or
|
||||
(1 shl ABS_RX) or (1 shl ABS_RY) or
|
||||
(1 shl ABS_Z) or (1 shl ABS_RZ) or
|
||||
(1 shl ABS_HAT0X) or (1 shl ABS_HAT0Y);
|
||||
end;
|
||||
else begin
|
||||
fConfigSpace[2]:=0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
else begin
|
||||
fConfigSpace[2]:=0;
|
||||
end;
|
||||
|
|
@ -55912,6 +56034,41 @@ begin
|
|||
PPasRISCVUInt32(Pointer(@fConfigSpace[16]))^:=0; // fuzz
|
||||
PPasRISCVUInt32(Pointer(@fConfigSpace[20]))^:=0; // flat
|
||||
PPasRISCVUInt32(Pointer(@fConfigSpace[24]))^:=0; // res
|
||||
end else if fKind=TPasRISCV.TVirtIOInputDevice.TKind.Gamepad then begin
|
||||
AbsMin:=0;
|
||||
AbsMax:=0;
|
||||
AbsFuzz:=0;
|
||||
AbsFlat:=0;
|
||||
AbsRes:=0;
|
||||
case fConfigSpace[1] of
|
||||
ABS_X,ABS_Y,ABS_RX,ABS_RY:begin // Analog sticks, centered signed range
|
||||
AbsMin:=GAMEPAD_ABS_MIN;
|
||||
AbsMax:=GAMEPAD_ABS_MAX;
|
||||
AbsFuzz:=16;
|
||||
AbsFlat:=128;
|
||||
end;
|
||||
ABS_Z,ABS_RZ:begin // Triggers, unsigned range
|
||||
AbsMin:=0;
|
||||
AbsMax:=GAMEPAD_TRIGGER_MAX;
|
||||
end;
|
||||
ABS_HAT0X,ABS_HAT0Y:begin // D-pad, three-state
|
||||
AbsMin:=-1;
|
||||
AbsMax:=1;
|
||||
end;
|
||||
else begin
|
||||
AbsMax:=-1; // Mark as unsupported axis below
|
||||
end;
|
||||
end;
|
||||
if AbsMax<>-1 then begin
|
||||
fConfigSpace[2]:=5*4;
|
||||
PPasRISCVUInt32(Pointer(@fConfigSpace[8]))^:=TPasRISCVUInt32(AbsMin);
|
||||
PPasRISCVUInt32(Pointer(@fConfigSpace[12]))^:=TPasRISCVUInt32(AbsMax);
|
||||
PPasRISCVUInt32(Pointer(@fConfigSpace[16]))^:=TPasRISCVUInt32(AbsFuzz);
|
||||
PPasRISCVUInt32(Pointer(@fConfigSpace[20]))^:=TPasRISCVUInt32(AbsFlat);
|
||||
PPasRISCVUInt32(Pointer(@fConfigSpace[24]))^:=TPasRISCVUInt32(AbsRes);
|
||||
end else begin
|
||||
fConfigSpace[2]:=0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
else begin
|
||||
|
|
@ -55920,7 +56077,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TPasRISCV.TVirtIOInputDevice.LoadSnapshot(const aNode:TSnapshot.TNode);
|
||||
begin
|
||||
inherited LoadSnapshot(aNode);
|
||||
|
|
@ -56011,6 +56167,28 @@ begin
|
|||
inherited SaveSnapshot(aNode);
|
||||
end;
|
||||
|
||||
{ TPasRISCV.TVirtIOInputGamepadDevice }
|
||||
|
||||
constructor TPasRISCV.TVirtIOInputGamepadDevice.Create(const aMachine:TPasRISCV);
|
||||
begin
|
||||
inherited Create(aMachine,aMachine.fConfiguration.fVirtIOInputGamepadBase,aMachine.fConfiguration.fVirtIOInputGamepadSize,TVirtIOInputDevice.TKind.Gamepad);
|
||||
fIRQ:=aMachine.fConfiguration.fVirtIOInputGamepadIRQ;
|
||||
end;
|
||||
|
||||
procedure TPasRISCV.TVirtIOInputGamepadDevice.DeviceInitialize;
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure TPasRISCV.TVirtIOInputGamepadDevice.LoadSnapshot(const aNode:TSnapshot.TNode);
|
||||
begin
|
||||
inherited LoadSnapshot(aNode);
|
||||
end;
|
||||
|
||||
procedure TPasRISCV.TVirtIOInputGamepadDevice.SaveSnapshot(const aNode:TSnapshot.TNode);
|
||||
begin
|
||||
inherited SaveSnapshot(aNode);
|
||||
end;
|
||||
|
||||
{ TPasRISCV.TVirtIOSoundDevice.TPCMBuffer }
|
||||
|
||||
constructor TPasRISCV.TVirtIOSoundDevice.TPCMBuffer.Create(const aDevice:TVirtIOSoundDevice);
|
||||
|
|
@ -138263,6 +138441,10 @@ begin
|
|||
fVirtIOInputTabletSize:=TPasRISCV.TVirtIOInputTabletDevice.DefaultSize;
|
||||
fVirtIOInputTabletIRQ:=TPasRISCV.TVirtIOInputTabletDevice.DefaultIRQ;
|
||||
|
||||
fVirtIOInputGamepadBase:=TPasRISCV.TVirtIOInputGamepadDevice.DefaultBaseAddress;
|
||||
fVirtIOInputGamepadSize:=TPasRISCV.TVirtIOInputGamepadDevice.DefaultSize;
|
||||
fVirtIOInputGamepadIRQ:=TPasRISCV.TVirtIOInputGamepadDevice.DefaultIRQ;
|
||||
|
||||
fVirtIOSoundBase:=TPasRISCV.TVirtIOSoundDevice.DefaultBaseAddress;
|
||||
fVirtIOSoundSize:=TPasRISCV.TVirtIOSoundDevice.DefaultSize;
|
||||
fVirtIOSoundIRQ:=TPasRISCV.TVirtIOSoundDevice.DefaultIRQ;
|
||||
|
|
@ -138477,6 +138659,10 @@ begin
|
|||
fVirtIOInputTabletSize:=aConfiguration.fVirtIOInputTabletSize;
|
||||
fVirtIOInputTabletIRQ:=aConfiguration.fVirtIOInputTabletIRQ;
|
||||
|
||||
fVirtIOInputGamepadBase:=aConfiguration.fVirtIOInputGamepadBase;
|
||||
fVirtIOInputGamepadSize:=aConfiguration.fVirtIOInputGamepadSize;
|
||||
fVirtIOInputGamepadIRQ:=aConfiguration.fVirtIOInputGamepadIRQ;
|
||||
|
||||
fVirtIOSoundBase:=aConfiguration.fVirtIOSoundBase;
|
||||
fVirtIOSoundSize:=aConfiguration.fVirtIOSoundSize;
|
||||
fVirtIOSoundIRQ:=aConfiguration.fVirtIOSoundIRQ;
|
||||
|
|
@ -138760,6 +138946,9 @@ begin
|
|||
fVirtIOInputTabletBase:=aNode.GetUInt64('VirtIOInputTabletBase',fVirtIOInputTabletBase);
|
||||
fVirtIOInputTabletSize:=aNode.GetUInt64('VirtIOInputTabletSize',fVirtIOInputTabletSize);
|
||||
fVirtIOInputTabletIRQ:=aNode.GetUInt64('VirtIOInputTabletIRQ',fVirtIOInputTabletIRQ);
|
||||
fVirtIOInputGamepadBase:=aNode.GetUInt64('VirtIOInputGamepadBase',fVirtIOInputGamepadBase);
|
||||
fVirtIOInputGamepadSize:=aNode.GetUInt64('VirtIOInputGamepadSize',fVirtIOInputGamepadSize);
|
||||
fVirtIOInputGamepadIRQ:=aNode.GetUInt64('VirtIOInputGamepadIRQ',fVirtIOInputGamepadIRQ);
|
||||
|
||||
// VirtIO Sound
|
||||
fVirtIOSoundBase:=aNode.GetUInt64('VirtIOSoundBase',fVirtIOSoundBase);
|
||||
|
|
@ -138981,6 +139170,9 @@ begin
|
|||
aNode.SetUInt64('VirtIOInputTabletBase',fVirtIOInputTabletBase);
|
||||
aNode.SetUInt64('VirtIOInputTabletSize',fVirtIOInputTabletSize);
|
||||
aNode.SetUInt64('VirtIOInputTabletIRQ',fVirtIOInputTabletIRQ);
|
||||
aNode.SetUInt64('VirtIOInputGamepadBase',fVirtIOInputGamepadBase);
|
||||
aNode.SetUInt64('VirtIOInputGamepadSize',fVirtIOInputGamepadSize);
|
||||
aNode.SetUInt64('VirtIOInputGamepadIRQ',fVirtIOInputGamepadIRQ);
|
||||
|
||||
// VirtIO Sound
|
||||
aNode.SetUInt64('VirtIOSoundBase',fVirtIOSoundBase);
|
||||
|
|
@ -139410,6 +139602,8 @@ begin
|
|||
|
||||
fVirtIOInputTabletDevice:=TVirtIOInputTabletDevice.Create(self);
|
||||
|
||||
fVirtIOInputGamepadDevice:=TVirtIOInputGamepadDevice.Create(self);
|
||||
|
||||
fVirtIO9PDevice:=TVirtIO9PDevice.Create(self);
|
||||
|
||||
fVirtIONetDevice:=TVirtIONetDevice.Create(self);
|
||||
|
|
@ -139560,6 +139754,7 @@ begin
|
|||
fBus.AddBusDevice(fVirtIOInputKeyboardDevice);
|
||||
fBus.AddBusDevice(fVirtIOInputMouseDevice);
|
||||
fBus.AddBusDevice(fVirtIOInputTabletDevice);
|
||||
fBus.AddBusDevice(fVirtIOInputGamepadDevice);
|
||||
if assigned(fVirtIOSoundDevice) then begin
|
||||
fBus.AddBusDevice(fVirtIOSoundDevice);
|
||||
end;
|
||||
|
|
@ -139790,6 +139985,7 @@ begin
|
|||
FreeAndNil(fVirtIOInputKeyboardDevice);
|
||||
FreeAndNil(fVirtIOInputMouseDevice);
|
||||
FreeAndNil(fVirtIOInputTabletDevice);
|
||||
FreeAndNil(fVirtIOInputGamepadDevice);
|
||||
FreeAndNil(fVirtIOSoundDevice);
|
||||
FreeAndNil(fVirtIO9PDevice);
|
||||
if assigned(fEthernetDevice) then begin
|
||||
|
|
@ -139921,7 +140117,7 @@ var Index,DeviceID,IRQPin:TPasRISCVSizeInt;
|
|||
I2CClockNode,I2CNode,I2CHIDKeyboardNode,I2CDS1307Node,
|
||||
PS2KeyboardNode,PS2MouseNode,
|
||||
VirtIOBlockNode,
|
||||
VirtIOInputKeyboardNode,VirtIOInputMouseNode,VirtIOInputTabletNode,VirtIOSoundNode,
|
||||
VirtIOInputKeyboardNode,VirtIOInputMouseNode,VirtIOInputTabletNode,VirtIOInputGamepadNode,VirtIOSoundNode,
|
||||
VirtIO9PNode,VirtIONetNode,
|
||||
VirtIORandomGeneratorNode,
|
||||
VirtIOGPUNode,
|
||||
|
|
@ -140915,6 +141111,26 @@ begin
|
|||
SoCNode.AddChild(VirtIOInputTabletNode);
|
||||
end;
|
||||
|
||||
VirtIOInputGamepadNode:=TPasRISCV.TFDT.TFDTNode.Create(fFDT,'virtio',fConfiguration.fVirtIOInputGamepadBase);
|
||||
try
|
||||
VirtIOInputGamepadNode.AddPropertyString('compatible','virtio,mmio');
|
||||
Cells[0]:=0;
|
||||
Cells[1]:=fConfiguration.fVirtIOInputGamepadBase;
|
||||
Cells[2]:=0;
|
||||
Cells[3]:=fConfiguration.fVirtIOInputGamepadSize;
|
||||
VirtIOInputGamepadNode.AddPropertyCells('reg',@Cells,4);
|
||||
Cells[0]:=INTC0.GetPHandle;
|
||||
Cells[1]:=TPasRISCVUInt32(fConfiguration.fVirtIOInputGamepadIRQ);
|
||||
if fAIA then begin
|
||||
Cells[2]:=4; // IRQ_TYPE_LEVEL_HIGH
|
||||
VirtIOInputGamepadNode.AddPropertyCells('interrupts-extended',@Cells,3);
|
||||
end else begin
|
||||
VirtIOInputGamepadNode.AddPropertyCells('interrupts-extended',@Cells,2);
|
||||
end;
|
||||
finally
|
||||
SoCNode.AddChild(VirtIOInputGamepadNode);
|
||||
end;
|
||||
|
||||
if fConfiguration.fSoundMode=TSoundMode.VirtIO then begin
|
||||
VirtIOSoundNode:=TPasRISCV.TFDT.TFDTNode.Create(fFDT,'virtio',fConfiguration.fVirtIOSoundBase);
|
||||
try
|
||||
|
|
@ -141815,6 +142031,7 @@ begin
|
|||
fVirtIOInputKeyboardDevice.Reset;
|
||||
fVirtIOInputMouseDevice.Reset;
|
||||
fVirtIOInputTabletDevice.Reset;
|
||||
fVirtIOInputGamepadDevice.Reset;
|
||||
if assigned(fVirtIOSoundDevice) then begin
|
||||
fVirtIOSoundDevice.Reset;
|
||||
end;
|
||||
|
|
@ -142830,6 +143047,9 @@ begin
|
|||
if assigned(fVirtIOInputTabletDevice) then begin
|
||||
fVirtIOInputTabletDevice.LoadSnapshot(Snapshot.Root.FindNode('VirtIOInputTablet'));
|
||||
end;
|
||||
if assigned(fVirtIOInputGamepadDevice) then begin
|
||||
fVirtIOInputGamepadDevice.LoadSnapshot(Snapshot.Root.FindNode('VirtIOInputGamepad'));
|
||||
end;
|
||||
if assigned(fVirtIOSoundDevice) then begin
|
||||
fVirtIOSoundDevice.LoadSnapshot(Snapshot.Root.FindNode('VirtIOSound'));
|
||||
end;
|
||||
|
|
@ -143015,6 +143235,9 @@ begin
|
|||
if assigned(fVirtIOInputTabletDevice) then begin
|
||||
fVirtIOInputTabletDevice.SaveSnapshot(Snapshot.Root.AddObject('VirtIOInputTablet'));
|
||||
end;
|
||||
if assigned(fVirtIOInputGamepadDevice) then begin
|
||||
fVirtIOInputGamepadDevice.SaveSnapshot(Snapshot.Root.AddObject('VirtIOInputGamepad'));
|
||||
end;
|
||||
if assigned(fVirtIOSoundDevice) then begin
|
||||
fVirtIOSoundDevice.SaveSnapshot(Snapshot.Root.AddObject('VirtIOSound'));
|
||||
end;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue