Giter VIP home page Giter VIP logo

xenia-project / xenia Goto Github PK

View Code? Open in Web Editor NEW
7.7K 431.0 1.1K 47.25 MB

Xbox 360 Emulator Research Project

Home Page: https://xenia.jp

License: Other

C++ 94.37% Assembly 3.23% C 0.14% Batchfile 0.03% Lua 0.44% Python 1.05% Pawn 0.10% C# 0.18% HLSL 0.21% GDB 0.01% Java 0.11% PowerShell 0.01% Starlark 0.13% SourcePawn 0.01%
emulator emulation xenon ppc xbox360 cpp c-plus-plus d3d12 vulkan

xenia's Introduction

Xenia - Xbox 360 Emulator

Xenia is an experimental emulator for the Xbox 360. For more information, see the main Xenia wiki.

Interested in supporting the core contributors? Visit Xenia Project on Patreon.

Come chat with us about emulator-related topics on Discord. For developer chat join #dev but stay on topic. Lurking is not only fine, but encouraged! Please check the FAQ page before asking questions. We've got jobs/lives/etc, so don't expect instant answers.

Discussing illegal activities will get you banned.

Status

Buildbot Status Releases
Windows Build status Latest โ—ฆ All
Linux Build status

Quite a few real games run. Quite a few don't. See the Game compatibility list for currently tracked games, and feel free to contribute your own updates, screenshots, and information there following the existing conventions.

Disclaimer

The goal of this project is to experiment, research, and educate on the topic of emulation of modern devices and operating systems. It is not for enabling illegal activity. All information is obtained via reverse engineering of legally purchased devices and games and information made public on the internet (you'd be surprised what's indexed on Google...).

Quickstart

See the Quickstart page.

Building

See building.md for setup and information about the xb script. When writing code, check the style guide and be sure to run clang-format!

Contributors Wanted!

Have some spare time, know advanced C++, and want to write an emulator? Contribute! There's a ton of work that needs to be done, a lot of which is wide open greenfield fun.

For general rules and guidelines please see CONTRIBUTING.md.

Fixes and optimizations are always welcome (please!), but in addition to that there are some major work areas still untouched:

See more projects good for contributors. It's a good idea to ask on Discord and check the issues page before beginning work on something.

FAQ

See the frequently asked questions page.

xenia's People

Contributors

benvanik avatar bwrsandman avatar chris-hawley avatar cookieplmonster avatar dougvj avatar drchat avatar emoose avatar fraxul avatar gibbed avatar gliniak avatar hlide avatar illusion0001 avatar inolen avatar jgoyvaerts avatar joellinn avatar kriskras99 avatar margen67 avatar maxton avatar parkerlamb avatar prism019 avatar randprint avatar razzile avatar sephiroth99 avatar shuffle2 avatar significantbits avatar triang3l avatar vlad-ivanov-name avatar wildenhaus avatar wunkolo avatar x1nixmzeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xenia's Issues

Implement waits in critical sections.

They don't currently support contention - there's no waiting logic. Need lightweight events.

Note that critical sections are never deleted on the 360, so whatever primitive we use needs to not exhaust itself quickly. Not sure if most games create/delete CS' frequently enough for it to matter. Perhaps we keep a list of allocated CS' and periodically scavenge events from those that haven't been locked in awhile?

Design debugger interface.

In-process to keep the build simpler, allow for arbitrary function calls to anything, and make locking easier.

A hybrid may be possible with a small out-of-process shim to enable capturing exceptions and minidumps. Win32 allows only one debugger at a time, though, so this would prevent VS from attaching.

Current xe::dbg should be cleaned up.

  • xe::debug
    • DebugHost
      • Pause()/Resume()/Step()
      • Quit()
    • Protocol
      • GDBProtocol
      • WSProtocol

??

  • DebugComponent
    • ProcessorDebugComponent
    • GPUDebugComponent
    • APUDebugComponent
    • KernelDebugComponent

Need a tracing channel so that all tracing data can be sent over debug connection. Flush support that the debugger can call would be nice.

Launch --wait-for-debugger.

Alloy should have some debug hooks. Perhaps it owns suspending threads/etc.

Replace gflags with another options parser.

gflags is full of warnings and weirdness. It'd be nice to have a better/simpler/more modern parser that had some of the same behaviors. For example, being able to register flags inside of any .cc file is nice, as is being able to load flags from files.

Optimize conditional branches.

Sequences with some ALU op (or compare) with Rc=1 and a conditional branch are common.

It'd be nice to optimize these to not store the condition value (if we know that it won't be used in the following instruction? maybe msvc doesn't do this).

82012FBC: 70C00003 andi    r0, r6, 0x0003
82012FC0: 4002FFF0 bc      0x00, 0x02

It may be interesting to store a lookaside of cr0 that is sourced from the EFLAGS of the cmp. Then with SAHF to load the EFLAGS any of the normal conditional jumps could be used.

Drop SymbolTable and use a single SymbolDatabase.

In the LLVM world each module had its own SymbolDatabase. Now that doesn't make much sense, and the extra indirections are slowing things down. Keeping the SDB as the single true source of all symbols would also remove some of the model breaking behavior around processor/jit/etc.

Build a kernel type system.

Need to mock out something for having ref-counted handles (that live as 32-bit IDs that can be mapped to values).

Each object type, such as events/files/threads/etc, should have some basic metadata (type name/dealloc function/etc). No need for type chains - can use composition if needed.

Add virtual filesystem manager.

Basic file API, pluggable file systems, and registration.
Support both sync and async. Perhaps only async and provide wrappers?
Need to match the Nt/Zw kernel APIs: ZwCreateFile/ZwOpenFile/ZwReadFile/ZwCloseFile.

When resolving a path each filesystem gets called to see if it handles it. Once the right filesystem is picked it can have the create/open calls issued on it with the path.

  • file system table (registration, resolving, symlinks?)
  • file system API (create/open/read/[write]/close)
  • local file system (single file path or directory mapped to path)
  • gdfs file system (iso)

GPR0 optimizations.

MSVC doesn't seem to ever try writing to r0, but it's legal and some games may do it. Have the function analyzer walk instructions and see if r0 is written - if not, allow the function to treat r0 as constant 0.

Investigate save state feasibility.

Would be great to support. Seems difficult.

CPU

For saving need to be able to suspend all threads and capture all thread state. This is difficult in a deep JIT, as if PPC registers are kept in host registers and single PPC instructions can be many IR ops that cannot be divided.

Having synchronization points that check for save state markers and suspend the threads could make it work. A 'save state pending' check on function calls could work in most cases, though all branches may need it too. Yuck.

GPU

A state manager would need to retain all objects (textures/buffers/etc) so that they can be read back, saved, and later recreated.

Kernel

All thread primitives (wait/etc) would need to support alerting so that they could be woken and later waited. Any kernel state (object table/etc) would need to be fully serializable. Any host pointers stored in guest code would need to be rewritten (like locks/etc).

Explore kernel abstraction layering.

Right now there are some things PAL'ed out but most of the kernel just makes Win32 calls. Building a WINE-like compat layer sounds painful. It may be possible to link against winelib or something, but that sounds like a massive nightmare when it comes to porting to various systems/compilers that wine doesn't support.

A solid PAL implementing the subset of Win32 used with tight argument validation would likely be the best option for most things. Very few APIs are radically different between posix/win32.

Getting a list of the core feature areas used and the functionality used would be step 1.

Implement indirect branches via function table.

  • Function pointer table as a global object, built at codegen end
  • Add Execute to xethunk for jumping through the table as a tail call
  • Change Processor::Execute/etc to jump through into xethunk

Setup GPU skeleton.

GPU shared code:

xe::gpu::Device: d3d::D3D11Device, gl::GL4Device
xe::gpu::RingBuffer

Shows the ringbuffer having lazy flushes on drawprimitive. GPU_CONTROLPACKET.
'Batches'. 32K ringbuffer with indirection to 2M buffer.
Predication (32bit mask or value?)
Textures/VBs/etc are all just views onto the same memory. Could be a problem if a buffer is both a texture and a VB.
Predicated tiling can likely be ignored. Shaders may reference a tile offset, can just be screen offset (maybe).
Tessellation can be supported in D3D11/GL4, it seems, though the shader rewriting will be tricky. Shader stages don't quite line up, but 11/4 are a superset of 360 functionality.
Runtime patching of shaders based on current vertex declaration used in a draw. Need an efficient cache.

http://msdn.microsoft.com/en-us/aa937791.aspx

http://www.microsoft.com/en-us/download/details.aspx?id=5313

https://docs.google.com/viewer?a=v&q=cache:i8cYxwESI1QJ:download.microsoft.com/download/d/3/0/d30d58cd-87a2-41d5-bb53-baf560aa2373/next_generation_graphics_programming_on_xbox_360.ppt+&hl=en&gl=us&pid=bl&srcid=ADGEEShzQeK3ItDPkPiqxZm9UL2AvQDaSNDpAoJawDuOrg2lSuriNBwyyGBDQsUb0LAp0sNYo76-HoLH28362dTgwUOwswApa2s8LYLTpa-1xxPjOrL3exnmGpHSltW9oybT4o6PBDhN&sig=AHIEtbSSGtigqSuFsGf-g_zPLLXVPtioyg

PPC disasm is slow.

Currently using vectors and strings - this is causing tons of allocs. Make it a static buffer.

libjit x64 encoding enhancements.

Use MOVBE to store to/from memory with swapping. Perhaps a new load_swapped/store_swapped opcode?

Small negative nints are very wasteful in encoding:
mov rsi, 0xFFFFFFFFFFFFFFF0
add rax, rsi
The encoders for various methods could be smart enough to identify these small negative numbers and generate a movsx or something:
[reg, imm, if("$2 >> 32 == 0xFFFFFFFF")] -> { use movsx to avoid encoding 4 0xFF bytes }

Optimize compare/branch pairs with context use tracking.

Need some form of intra-block use tracking on context. Some simple in/out context slot lists on each block would help identify redundant stores.

  • Start at bottom, recurse up, set incoming context locs
  • Epilog needs all read, so that final stores are done
    • (except compares?)
  • f.e. block, if successors don't need a context loc, kill store
  • Run dce to kill compares

Ideally:

  ; 8202FB84 2C030000 cmpi         0x00, 0x00, r3, 0
  v38.i8 = compare_slt v36.i32, 0
  v39.i8 = compare_sgt v36.i32, 0
  v40.i8 = compare_eq v36.i32, 0
  store_context +276, v38.i8
  store_context +277, v39.i8
  store_context +278, v40.i8
  ; 8202FB88 4182000C bc           0x0C, 0x02, 0x8202FB94
  branch_true v40.i8, loc_8202FB94

Becomes:

    v40.i8 = compare_eq v36.i32, 0
    branch_true v40.i8, loc_8202FB94

With can be coded by a sequence:

    cmp gpr32.35, 0
    je loc_8202FB94

libjit may be storing useless local variables.

00000000000F1167 48 89 45 E0 mov qword ptr [rbp-20h],rax
00000000000F116B 0F C8 bswap eax

The stored value is never used again. Something is making libjit think it needs to keep it around in a local.

Identify simple static indirect branches.

lis r11,-32229
addi r11,r11,7680
mtctr r11
bctr // 0x821B1E00

This seems to be used a lot.
Can either try to recognize this exact sequence or do some more advanced constant detection.

Identify jump tables and optimize (or at least analyze).

0x820FC260 in VP. Loads from the address block and jumps there. Should at least analyze this by reading the data values and adding basic blocks/functions for them. Fancy would be to rebuild the table as an LLVM select.

Looks like a lot of games have this construct (look for mtspr CTR, r0).

Explore using machine code linker.

Generate many llvm::Module in memory and write as finished to .o files using LLVMTargetMachine::addPassesToEmitFile (keep memory use low, multithreaded, etc.

Link together using the system linker into a dll/dylib/etc:

  • g++ -dynamiclib -undefined suppress -flat_namespace *.o -o foo.dylib
  • link.exe ??
  • lld in the future, when ready (ELF only right now)

Load dylib/dll at runtime; resolve imports (kernel shims/etc), execute using the function table in xethunk.
Add via ExecModule subclasses for JIT/Library/etc. Processor::Execute can have a code section map or just linear search the loaded modules.

Refactor shared GPU code.

Would be nice to get anything currently in D3D that could be shared into shared code.
This may mean building out a base GPU implementation that is extended by D3D/GL. Making the nop GPU a trivial subclass of this would help ensure it keeps working and supports debugging features. Mantle would be a different class tree.

Create xex info tracker web service.

xenia-info --upload some.xex

POST a JSON blob to an appspot service that would track the info like kernel imports/etc. Would allow for prioritization and compatibility queries.

Properly implement lwarx and stwcx.

They currently don't do the right thing w.r.t. memory. I'm not sure what I'm doing (acquire/release) does what I think it does, and it's slightly different than the PPC.

Instruction test suite.

Create a bunch of instruction tests and a simple test runner that allows compiling them into PPC code.

.globl  _main
.align  4
_main:
        #li r3, 4
        mulld r3, r4, r5
        #blr
./gas/as-new -a64 -be -mregnames -mpower7 -maltivec -mvsx -R -o test.o test.s
./binutils/objdump --adjust-vma=0x8001000 -Mpower7 -sD -EB test.o

Optimize ALU ops for more efficient encoding.

Certain operations could be encoded much more efficiently. For example, add reg, reg, 1/-1 could be translated to an inc/dec.

Avoiding large negative number loads for simple operations would be nice.

Refactor ModuleGenerator for threaded AOT and demand generation.

ModuleGenerator:
  - llvm::Module main_module_
  - Prepare()
    - BuildImports()
    - BuildExports()
    - LinkXeThunk()
    - LinkInternal() (add Xe* functions)
  - AcquireTask()/ReleaseTask() (for JITing)
  - Load()
  - CompileAndLink()
     - create threads, each steals functions for generation via tasks
     - when tasks full, write out, create new
     - when complete, link with system linker/etc
  - ModuleGeneratorTask
      - llvm::Module task_module_
      - BuildFunction()
      - DeclareFunction() (private)
      - Write()

Add CPU tracing for execution.

Trace all functions, branches, instructions, loads, stores, register read/writes, etc.

These could be added to HIR as trace points (based on disasm info). For example:

  ; 82000000 addi r1, r2, 123
  trace INSTRUCTION, 8200000
  v0 = load_context +2
  trace REGISTER_LOAD, 2, v0
  v1 = add v0, 123
  store_context +1, v1
  trace REGISTER_STORE, 1, v1

Could have CALL/RETURN/BRANCH/INSTRUCTION/REGISTER/MEMORY_LOAD/_STORE, etc.

Implement GL4 GPU driver.

May need many extensions not available everywhere. Would be nice not to depend on third party libraries for extension loading/etc, as they all pretty much suck to build/ship cross-platform.

Cleanup codegen interface.

Prepare for splitting modes into lazy JIT and AOT via linker.
There will always be a SDB and LLVM EE for cases where static analysis misses things, but the Prepare process will differ greatly.

  • Make ExecModule the only interface into code.
  • Move the Xe* methods to a shared class and expose via fn pointer table.

Create window menu system.

  • Window
    • main_menu() -> MenuItem
  • MenuItem
    • hotkey
    • name
    • icon
    • AddChildItem() -> MenuItem
    • AddChildSeparator() -> MenuItem
    • selected

x64_jit - CheckProcessor SSE4 support

The CheckProcessor function only support SSE4.1 or 4.2 from Intel, AMD processors are unsupported because it use SSE4a, its this a "check function" bug or the emulator needs all the SSE4.1 instructions and AMD processors are really unsupported?
cmd

Add x64 disassembler.

Would be nice to have good disassembly of the generated x64 code.

Beaengine seems decent and easy enough to link in. It's LGPL and has no official git mirror, but a github repo could be setup easy enough.

Add Windows build support.

  • valid gyp projects for VS2010
  • ninja builds
  • figure out how to get headers included in vs project (maybe include in sources list?)
  • gflags parsing (string narrow? wchar to mbcs?)
  • replace openssl for base64 and sha1
  • pal for sockets

Switch to using mongoose for the debug server.

mongoose is a nice small C web server that runs everywhere and supports both file serving and web sockets. This can remove a lot of the PAL code for socket handling and other weird threading issues, as it's mostly taken care of by mongoose itself.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.