├── VERSION ├── vi ├── render.c ├── window.h ├── registers.md └── render.h ├── assets ├── logo.png └── logo-small.png ├── vr4300 ├── docs │ └── vr43xx.pdf ├── TODO.txt ├── opcodes.c ├── registers.md ├── fault.md ├── segment.h ├── opcodes.h ├── icache.h ├── debug.h └── decoder.h ├── debugger ├── README ├── main.cpp ├── rdp_window.cpp ├── rdp_window.h ├── network_handle.h ├── register_model.h ├── disassembly_view.h ├── register_model.cpp ├── memory_window.cpp ├── memory_window.h ├── main_window.ui ├── memory_view.h ├── toggle_window.h ├── rsp_window.h ├── vr4300_window.h ├── register_view.h ├── cen64d.pro ├── disassembly_view.cpp ├── main_window.h └── toggle_window.cpp ├── arch ├── arm │ ├── fpu │ │ ├── abs_32.h │ │ ├── abs_64.h │ │ ├── neg_32.h │ │ ├── neg_64.h │ │ ├── sqrt_32.h │ │ ├── sqrt_64.h │ │ ├── cvt_f32_f64.h │ │ ├── cvt_f32_i32.h │ │ ├── cvt_f32_i64.h │ │ ├── cvt_f64_f32.h │ │ ├── cvt_f64_i32.h │ │ ├── cvt_f64_i64.h │ │ ├── cvt_i32_f32.h │ │ ├── cvt_i32_f64.h │ │ ├── cvt_i64_f32.h │ │ ├── cvt_i64_f64.h │ │ ├── trunc_i32_f32.h │ │ ├── trunc_i32_f64.h │ │ ├── trunc_i64_f32.h │ │ ├── trunc_i64_f64.h │ │ ├── add_32.h │ │ ├── add_64.h │ │ ├── div_32.h │ │ ├── div_64.h │ │ ├── mul_32.h │ │ ├── mul_64.h │ │ ├── sub_32.h │ │ ├── sub_64.h │ │ ├── cmp_f_32.h │ │ ├── cmp_f_64.h │ │ ├── cmp_clt_32.h │ │ ├── cmp_clt_64.h │ │ ├── cmp_eq_32.h │ │ ├── cmp_eq_64.h │ │ ├── cmp_ole_32.h │ │ ├── cmp_ole_64.h │ │ ├── cmp_olt_32.h │ │ ├── cmp_olt_64.h │ │ ├── cmp_ueq_32.h │ │ ├── cmp_ueq_64.h │ │ ├── cmp_ule_32.h │ │ ├── cmp_ule_64.h │ │ ├── cmp_ult_32.h │ │ ├── cmp_ult_64.h │ │ ├── cmp_un_32.h │ │ └── cmp_un_64.h │ └── rsp │ │ ├── vand.h │ │ ├── vor.h │ │ ├── vxor.h │ │ ├── vnand.h │ │ ├── vnor.h │ │ └── vnxor.h └── x86_64 │ ├── rsp │ ├── transpose.h │ ├── vor.h │ ├── vand.h │ ├── vxor.h │ ├── vmudh.h │ ├── vmrg.h │ ├── gcc │ │ ├── defs.h │ │ ├── vor.s │ │ ├── vand.s │ │ ├── vxor.s │ │ ├── vnor.s │ │ ├── vnand.s │ │ ├── vnxor.s │ │ ├── vabs.s │ │ ├── vmrg.s │ │ └── vlt.s │ ├── vaddc.h │ ├── vdivh.c │ ├── vsubc.h │ ├── vmov.c │ ├── vabs.h │ ├── vadd.h │ ├── vsub.h │ ├── transpose.c │ ├── vmulh.h │ ├── vmul.h │ ├── vcr.h │ └── vcmp.h │ ├── fpu │ ├── cvt_i32_f32.h │ ├── cvt_i64_f32.h │ ├── cvt_i32_f64.h │ ├── cvt_i64_f64.h │ ├── trunc_i32_f32.h │ ├── trunc_i64_f32.h │ ├── trunc_i32_f64.h │ ├── trunc_i64_f64.h │ ├── ceil_i32_f32.h │ ├── ceil_i64_f32.h │ ├── cvt_f32_i32.h │ ├── cvt_f32_i64.h │ ├── ceil_i32_f64.h │ ├── ceil_i64_f64.h │ ├── cvt_f64_i32.h │ ├── cvt_f64_i64.h │ ├── floor_i32_f32.h │ ├── floor_i64_f32.h │ ├── floor_i32_f64.h │ ├── floor_i64_f64.h │ ├── round_i32_f32.h │ ├── round_i64_f32.h │ ├── round_i32_f64.h │ ├── round_i64_f64.h │ ├── cmp_ueq_32.h │ ├── cmp_ule_32.h │ ├── cmp_ult_32.h │ ├── sqrt_32.h │ ├── cmp_ueq_64.h │ ├── cmp_ule_64.h │ ├── cmp_ult_64.h │ ├── neg_32.h │ ├── abs_32.h │ ├── sqrt_64.h │ ├── neg_64.h │ ├── abs_64.h │ ├── cvt_f32_f64.h │ ├── cvt_f64_f32.h │ ├── add_32.h │ ├── div_32.h │ ├── mul_32.h │ ├── sub_32.h │ ├── add_64.h │ ├── div_64.h │ ├── mul_64.h │ └── sub_64.h │ ├── context.h │ └── tlb │ └── tlb.h ├── cmake ├── Toolchains │ ├── osxcross-x86_64.cmake │ ├── mingw64-i686.cmake │ └── mingw64-x86_64.cmake └── Modules │ ├── FindOpenGLXQuartz.cmake │ └── FindIconv.cmake ├── os ├── windows │ ├── x86_64 │ │ └── fpu │ │ │ ├── fpu_cmp_f_32.asm │ │ │ ├── fpu_cmp_f_64.asm │ │ │ ├── fpu_cmp_un_32.asm │ │ │ ├── fpu_cmp_un_64.asm │ │ │ ├── fpu_cmp_eq_32.asm │ │ │ ├── fpu_cmp_eq_64.asm │ │ │ ├── fpu_cmp_ole_32.asm │ │ │ ├── fpu_cmp_ole_64.asm │ │ │ ├── fpu_cmp_olt_32.asm │ │ │ ├── fpu_cmp_olt_64.asm │ │ │ └── fpu.h │ ├── dynarec.c │ └── winapi_window.h ├── main.h ├── keycodes.h ├── posix │ ├── main.c │ ├── cpuid.c │ ├── timer.h │ ├── timer.c │ └── rom_file.c ├── winapi │ ├── console.h │ ├── timer.h │ ├── timer.c │ ├── main.c │ ├── gl_common.h │ ├── alloc.c │ ├── gl_display.h │ ├── console.c │ ├── gl_screen.h │ ├── cpuid.c │ └── gl_context.h ├── cpuid.h ├── dynarec.h ├── common │ ├── input.h │ ├── alloc.h │ ├── rom_file.h │ ├── gl_hints.c │ ├── save_file.h │ ├── gl_hints.h │ ├── local_time.h │ └── local_time.c ├── unix │ ├── arm │ │ └── fpu │ │ │ └── fpu.h │ └── x86_64 │ │ └── fpu │ │ ├── fpu_cmp_f_32.h │ │ ├── fpu_cmp_f_64.h │ │ ├── fpu_cmp_un_32.h │ │ ├── fpu_cmp_un_64.h │ │ ├── fpu.h │ │ ├── fpu_cmp_eq_32.h │ │ ├── fpu_cmp_ole_32.h │ │ ├── fpu_cmp_olt_32.h │ │ ├── fpu_cmp_eq_64.h │ │ ├── fpu_cmp_ole_64.h │ │ └── fpu_cmp_olt_64.h ├── sdl │ ├── gl_common.h │ ├── gl_display.h │ ├── gl_context.h │ └── gl_screen.h └── x11 │ ├── gl_common.h │ ├── gl_screen.h │ ├── gl_display.h │ └── gl_context.h ├── .gitattributes ├── cen64.h ├── si ├── cic.h ├── registers.md ├── pak_transfer.h ├── rtc.h └── gb.h ├── common ├── debug.h ├── reciprocal.h ├── debug.c └── hash_table.h ├── ai ├── registers.md └── context.h ├── rdp ├── interface.h ├── registers.md ├── cpu.h └── cpu.c ├── ri ├── registers.md └── rdram_registers.md ├── gdb ├── protocol.h └── gdb.h ├── .github └── workflows │ └── debian-linux.yml ├── rsp ├── opcodes.c ├── registers.md ├── vector_opcodes.md ├── interface.h ├── opcodes.md ├── decoder.h ├── cp2.h └── opcodes.h ├── .travis.yml ├── pi ├── registers.md └── is_viewer.h ├── dd └── registers.md ├── device ├── netapi.h ├── cart_db.h └── options.h └── .appveyor.yml /VERSION: -------------------------------------------------------------------------------- 1 | 0.3 2 | -------------------------------------------------------------------------------- /vi/render.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/cen64/HEAD/vi/render.c -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/cen64/HEAD/assets/logo.png -------------------------------------------------------------------------------- /assets/logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/cen64/HEAD/assets/logo-small.png -------------------------------------------------------------------------------- /vr4300/docs/vr43xx.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n64dev/cen64/HEAD/vr4300/docs/vr43xx.pdf -------------------------------------------------------------------------------- /debugger/README: -------------------------------------------------------------------------------- 1 | This is CEN64's Qt-based debugger. 2 | 3 | It is inspired by Presence's Qt frontend for CEN64: 4 | https://github.com/dh4/cen64-qt 5 | 6 | -------------------------------------------------------------------------------- /vr4300/TODO.txt: -------------------------------------------------------------------------------- 1 | - Fix/verify killed stages during exceptions. If debugging mode is enabled, 2 | there are a lot of spurious bus_read_word messages that are concerning to 3 | say the least. 4 | 5 | -------------------------------------------------------------------------------- /arch/arm/fpu/abs_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/abs_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_abs_32(const uint32_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/abs_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/abs_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_abs_64(const uint64_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/neg_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/neg_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_neg_32(const uint32_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/neg_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/neg_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_neg_64(const uint64_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/sqrt_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/sqrt_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_sqrt_32(const uint32_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/sqrt_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/sqrt_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_sqrt_64(const uint64_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_f32_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_f32_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_f32_f64(const uint64_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_f32_i32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_f32_i32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_f32_i32(const uint32_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_f32_i64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_f32_i64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_f32_i64(const uint64_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_f64_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_f64_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_f64_f32(const uint32_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_f64_i32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_f64_i32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_f64_i32(const uint32_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_f64_i64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_f64_i64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_f64_i64(const uint64_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_i32_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_i32_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_i32_f32(const uint32_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_i32_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_i32_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_i32_f64(const uint64_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_i64_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_i64_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_i64_f32(const uint32_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/cvt_i64_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cvt_i64_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_cvt_i64_f64(const uint64_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/trunc_i32_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/trunc_i32_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_trunc_i32_f32(const uint32_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/trunc_i32_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/trunc_i32_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_trunc_i32_f64(const uint64_t *fs, uint32_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/trunc_i64_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/trunc_i64_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_trunc_i64_f32(const uint32_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/trunc_i64_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/trunc_i64_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_trunc_i64_f64(const uint64_t *fs, uint64_t *fd) { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /arch/arm/fpu/add_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/add_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_add_32( 9 | const uint32_t *fs, const uint32_t *ft, uint32_t *fd) { 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/arm/fpu/add_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/add_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_add_64( 9 | const uint64_t *fs, const uint64_t *ft, uint64_t *fd) { 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/arm/fpu/div_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/div_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_div_32( 9 | const uint32_t *fs, const uint32_t *ft, uint32_t *fd) { 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/arm/fpu/div_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/div_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_div_64( 9 | const uint64_t *fs, const uint64_t *ft, uint64_t *fd) { 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/arm/fpu/mul_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/mul_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_mul_32( 9 | const uint32_t *fs, const uint32_t *ft, uint32_t *fd) { 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/arm/fpu/mul_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/mul_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_mul_64( 9 | const uint64_t *fs, const uint64_t *ft, uint64_t *fd) { 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/arm/fpu/sub_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/sub_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_sub_32( 9 | const uint32_t *fs, const uint32_t *ft, uint32_t *fd) { 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/arm/fpu/sub_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/sub_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline void fpu_sub_64( 9 | const uint64_t *fs, const uint64_t *ft, uint64_t *fd) { 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_f_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_f_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_f_32( 9 | const uint32_t *fs, const uint32_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_f_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_f_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_f_64( 9 | const uint64_t *fs, const uint64_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_clt_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_clt_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_clt_32( 9 | const uint32_t *fs, const uint32_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_clt_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_clt_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_clt_64( 9 | const uint64_t *fs, const uint64_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_eq_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_eq_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_eq_32( 9 | const uint32_t *fs, const uint32_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_eq_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_eq_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_eq_64( 9 | const uint64_t *fs, const uint64_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_ole_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_ole_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_ole_32( 9 | const uint32_t *fs, const uint32_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_ole_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_ole_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_ole_64( 9 | const uint64_t *fs, const uint64_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_olt_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_olt_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_olt_32( 9 | const uint32_t *fs, const uint32_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_olt_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_olt_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_olt_64( 9 | const uint64_t *fs, const uint64_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_ueq_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_ueq_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_ueq_32( 9 | const uint32_t *fs, const uint32_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_ueq_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_ueq_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_ueq_64( 9 | const uint64_t *fs, const uint64_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_ule_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_ule_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_ule_32( 9 | const uint32_t *fs, const uint32_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_ule_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_ule_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_ule_64( 9 | const uint64_t *fs, const uint64_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_ult_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_ult_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_ult_32( 9 | const uint32_t *fs, const uint32_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_ult_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_ult_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_ult_64( 9 | const uint64_t *fs, const uint64_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_un_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_un_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_un_32( 9 | const uint32_t *fs, const uint32_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/fpu/cmp_un_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/fpu/cmp_un_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline uint8_t fpu_cmp_un_64( 9 | const uint64_t *fs, const uint64_t *ft) { 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /arch/arm/rsp/vand.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/rsp/vand.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | 11 | static inline uint16x8_t rsp_vand(uint16x8_t vs, uint16x8_t vt) { 12 | return vandq_u16(vs, vt); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /arch/arm/rsp/vor.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/rsp/vor.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | 11 | static inline uint16x8_t rsp_vor(uint16x8_t vs, uint16x8_t vt) { 12 | return vorrq_u16(vs, vt); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /arch/arm/rsp/vxor.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/rsp/vxor.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | 11 | static inline uint16x8_t rsp_vxor(uint16x8_t vs, uint16x8_t vt) { 12 | return veorq_u16(vs, vt); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /cmake/Toolchains/osxcross-x86_64.cmake: -------------------------------------------------------------------------------- 1 | # For cross-compiling CEN64 with osxcross (x86_64). 2 | 3 | set(CMAKE_SYSTEM_NAME Darwin) 4 | 5 | set(CMAKE_C_COMPILER o64-clang) 6 | set(CMAKE_CXX_COMPILER o64-clang++) 7 | 8 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 9 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 10 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 11 | 12 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/transpose.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/transpose.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | void rsp_ltv(struct rsp *rsp, uint32_t addr, unsigned vt, unsigned element); 9 | 10 | void rsp_stv(struct rsp *rsp, uint32_t addr, unsigned vt, unsigned element); 11 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_f_32.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_f_32.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_f_32 proc 10 | movss xmm0, DWORD PTR [rdx] 11 | movss xmm1, DWORD PTR [rdx] 12 | comiss xmm1, xmm0 13 | ret 14 | fpu_cmp_f_32 endp 15 | end 16 | 17 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_f_64.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_f_64.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_f_64 proc 10 | movsd xmm0, QWORD PTR [rcx] 11 | movsd xmm1, QWORD PTR [rdx] 12 | comisd xmm1, xmm0 13 | ret 14 | fpu_cmp_f_64 endp 15 | end 16 | 17 | -------------------------------------------------------------------------------- /arch/arm/rsp/vnand.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/rsp/vnand.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | 11 | static inline uint16x8_t rsp_vnand( 12 | uint16x8_t vs, uint16x8_t vt, uint16x8_t zero) { 13 | return vmvnq_u16(vandq_u16(vs, vt)); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /arch/arm/rsp/vnor.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/rsp/vnor.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | 11 | static inline uint16x8_t rsp_vnor( 12 | uint16x8_t vs, uint16x8_t vt, uint16x8_t zero) { 13 | return vmvnq_u16(vorrq_u16(vs, vt)); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /arch/arm/rsp/vnxor.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/arm/rsp/vnxor.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | 11 | static inline uint16x8_t rsp_vnxor( 12 | uint16x8_t vs, uint16x8_t vt, uint16x8_t zero) { 13 | return vmvnq_u16(veorq_u16(vs, vt)); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_un_32.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_un_32.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_un_32 proc 10 | movss xmm0, DWORD PTR [rcx] 11 | movss xmm1, DWORD PTR [rdx] 12 | comiss xmm1, xmm0 13 | setp al 14 | ret 15 | fpu_cmp_un_32 endp 16 | end 17 | 18 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_un_64.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_un_64.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_un_64 proc 10 | movsd xmm0, QWORD PTR [rcx] 11 | movsd xmm1, QWORD PTR [rdx] 12 | comisd xmm1, xmm0 13 | setp al 14 | ret 15 | fpu_cmp_un_64 endp 16 | end 17 | 18 | -------------------------------------------------------------------------------- /cmake/Toolchains/mingw64-i686.cmake: -------------------------------------------------------------------------------- 1 | # For cross-compiling CEN64 with mingw64-i686. 2 | 3 | set(CMAKE_SYSTEM_NAME Windows) 4 | 5 | set(CMAKE_C_COMPILER i686-w64-mingw32-gcc) 6 | set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) 7 | set(CMAKE_RC_COMPILER i686-w64-mingw32-windres) 8 | 9 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 10 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 11 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 12 | 13 | -------------------------------------------------------------------------------- /os/main.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/main.h 3 | // 4 | // Convenience functions for managing rendering windows. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_main_h__ 11 | #define __os_main_h__ 12 | #include "device/device.h" 13 | #include "device/options.h" 14 | #include "os/gl_window.h" 15 | #include "rom_file.h" 16 | 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior for files 2 | * text=lf 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout 6 | *.md text 7 | *.txt text 8 | *.c text 9 | *.h text 10 | *.s text 11 | *.cmake text 12 | *.pro text 13 | *.ui text 14 | *.asm text 15 | *.in text 16 | 17 | # Denote all files that are truly binary and should not be modified 18 | *.pdf binary 19 | *.png binary 20 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_eq_32.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_eq_32.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_eq_32 proc 10 | movss xmm0, DWORD PTR [rcx] 11 | movss xmm1, DWORD PTR [rdx] 12 | comiss xmm1, xmm0 13 | sete dl 14 | setnp al 15 | and al, dl 16 | ret 17 | fpu_cmp_eq_32 endp 18 | end 19 | 20 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_eq_64.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_eq_64.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_eq_64 proc 10 | movsd xmm0, QWORD PTR [rcx] 11 | movsd xmm1, QWORD PTR [rdx] 12 | comisd xmm1, xmm0 13 | sete dl 14 | setnp al 15 | and al, dl 16 | ret 17 | fpu_cmp_eq_64 endp 18 | end 19 | 20 | -------------------------------------------------------------------------------- /cen64.h: -------------------------------------------------------------------------------- 1 | // 2 | // cen64.h: CEN64 entry point. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __cen64_h__ 12 | #define __cen64_h__ 13 | #include "common.h" 14 | 15 | cen64_cold int cen64_main(int argc, const char **argv); 16 | 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_ole_32.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_ole_32.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_ole_32 proc 10 | movss xmm0, DWORD PTR [rcx] 11 | movss xmm1, DWORD PTR [rdx] 12 | comiss xmm1, xmm0 13 | setae dl 14 | setnp al 15 | and al, dl 16 | ret 17 | fpu_cmp_ole_32 endp 18 | end 19 | 20 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_ole_64.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_ole_64.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_ole_64 proc 10 | movsd xmm0, QWORD PTR [rcx] 11 | movsd xmm1, QWORD PTR [rdx] 12 | comisd xmm1, xmm0 13 | setae dl 14 | setnp al 15 | and al, dl 16 | ret 17 | fpu_cmp_ole_64 endp 18 | end 19 | 20 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_olt_32.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_olt_32.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_olt_32 proc 10 | movss xmm0, DWORD PTR [rcx] 11 | movss xmm1, DWORD PTR [rdx] 12 | comiss xmm1, xmm0 13 | seta dl 14 | setnp al 15 | and al, dl 16 | ret 17 | fpu_cmp_olt_32 endp 18 | end 19 | 20 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu_cmp_olt_64.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; os/windows/x86_64/fpu/fpu_cmp_olt_64.asm 3 | ; 4 | ; This file is subject to the terms and conditions defined in 5 | ; 'LICENSE', which is part of this source code package. 6 | ; 7 | 8 | .code 9 | fpu_cmp_olt_64 proc 10 | movsd xmm0, QWORD PTR [rcx] 11 | movsd xmm1, QWORD PTR [rdx] 12 | comisd xmm1, xmm0 13 | seta dl 14 | setnp al 15 | and al, dl 16 | ret 17 | fpu_cmp_olt_64 endp 18 | end 19 | 20 | -------------------------------------------------------------------------------- /si/cic.h: -------------------------------------------------------------------------------- 1 | // 2 | // si/cic.h: PIF CIC security/lock out algorithms. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __si_cic_h__ 12 | #define __si_cic_h__ 13 | 14 | int get_cic_seed(const uint8_t *rom_data, uint32_t *cic_seed); 15 | 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vor.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vor.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vor_vnor(uint32_t iw, __m128i vs, __m128i vt) { 11 | __m128i vmask = _mm_load_si128((__m128i *) rsp_vlogic_mask[iw & 0x1]); 12 | 13 | __m128i vd = _mm_or_si128(vs, vt); 14 | return _mm_xor_si128(vd, vmask); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vand.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vand.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vand_vnand(uint32_t iw, __m128i vs, __m128i vt) { 11 | __m128i vmask = _mm_load_si128((__m128i *) rsp_vlogic_mask[iw & 0x1]); 12 | 13 | __m128i vd = _mm_and_si128(vs, vt); 14 | return _mm_xor_si128(vd, vmask); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vxor.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vxor.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vxor_vnxor(uint32_t iw, __m128i vs, __m128i vt) { 11 | __m128i vmask = _mm_load_si128((__m128i *) rsp_vlogic_mask[iw & 0x1]); 12 | 13 | __m128i vd = _mm_xor_si128(vs, vt); 14 | return _mm_xor_si128(vd, vmask); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /os/keycodes.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/keycodes.h 3 | // 4 | // Definitions for keycodes. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_keycodes_h__ 11 | #define __os_keycodes_h__ 12 | 13 | #ifdef _WIN32 14 | #include "os/windows/keycodes.h" 15 | #elif defined(__APPLE__) 16 | #include "os/sdl/keycodes.h" 17 | #else 18 | #include "os/x11/keycodes.h" 19 | #endif 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /os/posix/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/posix/main.c: Entry point for POSIX backend. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "cen64.h" 12 | 13 | // Unix application entry point. 14 | int main(int argc, const char *argv[]) { 15 | return cen64_main(argc, argv); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vmudh.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmudh.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vmudh(__m128i vs, __m128i vt, 11 | __m128i *acc_md, __m128i *acc_hi) { 12 | *acc_md = _mm_mullo_epi16(vs, vt); 13 | *acc_hi = _mm_mulhi_epi16(vs, vt); 14 | 15 | return rsp_sclamp_acc_tomd(*acc_md, *acc_hi); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /common/debug.h: -------------------------------------------------------------------------------- 1 | // 2 | // common/debug.h 3 | // 4 | // Verbose debugging functions (read: "fancy print wrappers"). 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __common_debug_h__ 11 | #define __common_debug_h__ 12 | #include "common.h" 13 | 14 | #ifndef NDEBUG 15 | cen64_cold int debug(const char *fmt, ...); 16 | #else 17 | #define debug(...) do {} while (0) 18 | #endif 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /common/reciprocal.h: -------------------------------------------------------------------------------- 1 | // 2 | // common/reciprocal.h: RSP reciprocal ROM contents. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __common_reciprocal_h__ 12 | #define __common_reciprocal_h__ 13 | #include "common.h" 14 | 15 | extern const uint16_t rsp_reciprocal_rom[1024]; 16 | 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vmrg.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmrg.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vmrg(__m128i vs, __m128i vt, __m128i le) { 11 | #ifdef __SSE4_1__ 12 | return _mm_blendv_epi8(vt, vs, le); 13 | #else 14 | vs = _mm_and_si128(le, vs); 15 | vt = _mm_andnot_si128(le, vt); 16 | return _mm_or_si128(vs, vt); 17 | #endif 18 | } 19 | 20 | -------------------------------------------------------------------------------- /vr4300/opcodes.c: -------------------------------------------------------------------------------- 1 | // 2 | // vr4300/opcodes.c: VR4300 opcode types and info. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "vr4300/opcodes.h" 12 | 13 | const char *vr4300_opcode_mnemonics[NUM_VR4300_OPCODES] = { 14 | #define X(op) #op, 15 | #include "vr4300/opcodes.md" 16 | #undef X 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/defs.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/defs.h 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .set acc_lo, %xmm8 12 | .set acc_md, %xmm9 13 | .set acc_hi, %xmm10 14 | 15 | .set vcc_lo, %xmm11 16 | .set vcc_hi, %xmm12 17 | .set vco_lo, %xmm13 18 | .set vco_hi, %xmm14 19 | .set vce , %xmm15 20 | 21 | -------------------------------------------------------------------------------- /debugger/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp: CEN64D entry point. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "main_window.h" 12 | #include 13 | 14 | int main(int argc, char *argv[]) { 15 | QApplication a(argc, argv); 16 | MainWindow w; 17 | w.show(); 18 | 19 | return a.exec(); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /vr4300/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // vr4300/registers.md: MI register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef MI_REGISTER_LIST 12 | #define MI_REGISTER_LIST \ 13 | X(MI_INIT_MODE_REG) \ 14 | X(MI_VERSION_REG) \ 15 | X(MI_INTR_REG) \ 16 | X(MI_INTR_MASK_REG) 17 | #endif 18 | 19 | MI_REGISTER_LIST 20 | 21 | -------------------------------------------------------------------------------- /cmake/Toolchains/mingw64-x86_64.cmake: -------------------------------------------------------------------------------- 1 | # For cross-compiling CEN64 with mingw64-x86_64. 2 | 3 | set(CMAKE_SYSTEM_NAME Windows) 4 | 5 | SET(PREFIX x86_64-w64-mingw32) 6 | SET(CMAKE_C_COMPILER ${PREFIX}-gcc) 7 | SET(CMAKE_CXX_COMPILER ${PREFIX}-g++) 8 | SET(CMAKE_AR ${PREFIX}-gcc-ar) 9 | SET(CMAKE_NM ${PREFIX}-gcc-nm) 10 | SET(CMAKE_RC_COMPILER ${PREFIX}-windres) 11 | 12 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 13 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 14 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 15 | 16 | -------------------------------------------------------------------------------- /debugger/rdp_window.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // rdp_window.cpp: RDP view window. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "rdp_window.h" 12 | 13 | RDPWindow::RDPWindow(QAction *toggleAction, bool initiallyVisible) 14 | : ToggleWindow(tr("CEN64D: RDP"), toggleAction, initiallyVisible) { 15 | } 16 | 17 | RDPWindow::~RDPWindow() { 18 | } 19 | 20 | -------------------------------------------------------------------------------- /os/winapi/console.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/console.h: Console manipulation functions 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | #ifndef CEN64_OS_WINAPI_CONSOLE 11 | #define CEN64_OS_WINAPI_CONSOLE 12 | 13 | void show_console(void); 14 | void hide_console(void); 15 | bool has_console(void); 16 | void check_start_from_explorer(void); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /ai/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // ai/registers.md: AI register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef AI_REGISTER_LIST 12 | #define AI_REGISTER_LIST \ 13 | X(AI_DRAM_ADDR_REG) \ 14 | X(AI_LEN_REG) \ 15 | X(AI_CONTROL_REG) \ 16 | X(AI_STATUS_REG) \ 17 | X(AI_DACRATE_REG) \ 18 | X(AI_BITRATE_REG) 19 | #endif 20 | 21 | AI_REGISTER_LIST 22 | 23 | -------------------------------------------------------------------------------- /rdp/interface.h: -------------------------------------------------------------------------------- 1 | // 2 | // rdp/interface.h: RDP interface. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __rdp_interface_h__ 12 | #define __rdp_interface_h__ 13 | #include "common.h" 14 | 15 | int read_dp_regs(void *opaque, uint32_t address, uint32_t *word); 16 | int write_dp_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm); 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_i32_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_i32_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_i32_f32(const uint32_t *fs, uint32_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | *fd = _mm_cvtss_si32(fs_reg); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_i64_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_i64_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_i64_f32(const uint32_t *fs, uint64_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | *fd = _mm_cvtss_si64(fs_reg); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vaddc.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vaddc.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vaddc(__m128i vs, __m128i vt, 11 | __m128i zero, __m128i *sn) { 12 | __m128i sat_sum, unsat_sum; 13 | 14 | sat_sum = _mm_adds_epu16(vs, vt); 15 | unsat_sum = _mm_add_epi16(vs, vt); 16 | 17 | *sn = _mm_cmpeq_epi16(sat_sum, unsat_sum); 18 | *sn = _mm_cmpeq_epi16(*sn, zero); 19 | 20 | return unsat_sum; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /os/cpuid.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/cpuid.h 3 | // 4 | // Functions for calling cpuid on x86. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_cpuid_h__ 11 | #define __os_cpuid_h__ 12 | #include "common.h" 13 | 14 | struct cen64_cpuid_t { 15 | uint32_t eax; 16 | uint32_t ebx; 17 | uint32_t ecx; 18 | uint32_t edx; 19 | }; 20 | 21 | void cen64_cpuid(uint32_t eax, uint32_t ecx, struct cen64_cpuid_t *cpuid); 22 | void cen64_cpuid_get_vendor(char vendor[13]); 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_i32_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_i32_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_i32_f64(const uint64_t *fs, uint32_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | *fd = _mm_cvtsd_si32(fs_reg); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_i64_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_i64_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_i64_f64(const uint64_t *fs, uint64_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | *fd = _mm_cvtsd_si64(fs_reg); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/trunc_i32_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/trunc_i32_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_trunc_i32_f32(const uint32_t *fs, uint32_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | *fd = _mm_cvttss_si32(fs_reg); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/trunc_i64_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/trunc_i64_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_trunc_i64_f32(const uint32_t *fs, uint64_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | *fd = _mm_cvttss_si64(fs_reg); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/trunc_i32_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/trunc_i32_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_trunc_i32_f64(const uint64_t *fs, uint32_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | *fd = _mm_cvttsd_si32(fs_reg); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/trunc_i64_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/trunc_i64_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_trunc_i64_f64(const uint64_t *fs, uint64_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | *fd = _mm_cvttsd_si64(fs_reg); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /vi/window.h: -------------------------------------------------------------------------------- 1 | // 2 | // vi/window.h: Video interface host window/GUI routines. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_VI_WINDOW_H 12 | #define CEN64_VI_WINDOW_H 13 | 14 | #include "common.h" 15 | #include "vi/controller.h" 16 | 17 | cen64_cold int vi_create_window(struct vi_controller *vi); 18 | cen64_cold void vi_destroy_window(struct vi_controller *vi); 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /debugger/rdp_window.h: -------------------------------------------------------------------------------- 1 | // 2 | // rdp_window.h: RDP view window. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef RDP_WINDOW_H 12 | #define RDP_WINDOW_H 13 | 14 | #include "toggle_window.h" 15 | 16 | class RDPWindow : public ToggleWindow { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit RDPWindow(QAction *toggleAction, bool initiallyVisible); 21 | ~RDPWindow(); 22 | }; 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /os/dynarec.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/dynarec.h 3 | // 4 | // Functions for allocating executable code buffers. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_dynarec_h__ 11 | #define __os_dynarec_h__ 12 | #include "common.h" 13 | #include 14 | 15 | struct dynarec_slab { 16 | size_t size; 17 | uint8_t *ptr; 18 | }; 19 | 20 | cen64_cold void *alloc_dynarec_slab(struct dynarec_slab *slab, size_t size); 21 | cen64_cold void free_dynarec_slab(struct dynarec_slab *slab); 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/ceil_i32_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/ceil_i32_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_ceil_i32_f32(const uint32_t *fs, uint32_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | fs_reg = _mm_ceil_ss(fs_reg, fs_reg); 21 | *fd = _mm_cvtss_si32(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/ceil_i64_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/ceil_i64_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_ceil_i64_f32(const uint32_t *fs, uint64_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | fs_reg = _mm_ceil_ss(fs_reg, fs_reg); 21 | *fd = _mm_cvtss_si64(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_f32_i32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_f32_i32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_f32_i32(const uint32_t *fs, uint32_t *fd) { 13 | float fd_float; 14 | __m128 fd_reg; 15 | 16 | fd_reg = _mm_setzero_ps(); 17 | fd_reg = _mm_cvtsi32_ss(fd_reg, *fs); 18 | fd_float = _mm_cvtss_f32(fd_reg); 19 | 20 | // Prevent aliasing. 21 | memcpy(fd, &fd_float, sizeof(fd_float)); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_f32_i64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_f32_i64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_f32_i64(const uint64_t *fs, uint32_t *fd) { 13 | float fd_float; 14 | __m128 fd_reg; 15 | 16 | fd_reg = _mm_setzero_ps(); 17 | fd_reg = _mm_cvtsi64_ss(fd_reg, *fs); 18 | fd_float = _mm_cvtss_f32(fd_reg); 19 | 20 | // Prevent aliasing. 21 | memcpy(fd, &fd_float, sizeof(fd_float)); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /rdp/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // rdp/registers.md: RDP register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef DP_REGISTER_LIST 12 | #define DP_REGISTER_LIST \ 13 | X(DPC_START_REG) \ 14 | X(DPC_END_REG) \ 15 | X(DPC_CURRENT_REG) \ 16 | X(DPC_STATUS_REG) \ 17 | X(DPC_CLOCK_REG) \ 18 | X(DPC_BUFBUSY_REG) \ 19 | X(DPC_PIPEBUSY_REG) \ 20 | X(DPC_TMEM_REG) 21 | #endif 22 | 23 | DP_REGISTER_LIST 24 | 25 | -------------------------------------------------------------------------------- /ri/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // ri/registers.md: RI register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef RI_REGISTER_LIST 12 | #define RI_REGISTER_LIST \ 13 | X(RI_MODE_REG) \ 14 | X(RI_CONFIG_REG) \ 15 | X(RI_CURRENT_LOAD_REG) \ 16 | X(RI_SELECT_REG) \ 17 | X(RI_REFRESH_REG) \ 18 | X(RI_LATENCY_REG) \ 19 | X(RI_RERROR_REG) \ 20 | X(RI_WERROR_REG) 21 | #endif 22 | 23 | RI_REGISTER_LIST 24 | 25 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/ceil_i32_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/ceil_i32_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_ceil_i32_f64(const uint64_t *fs, uint32_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | fs_reg = _mm_ceil_sd(fs_reg, fs_reg); 21 | *fd = _mm_cvtsd_si32(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/ceil_i64_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/ceil_i64_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_ceil_i64_f64(const uint64_t *fs, uint64_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | fs_reg = _mm_ceil_sd(fs_reg, fs_reg); 21 | *fd = _mm_cvtsd_si64(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_f64_i32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_f64_i32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_f64_i32(const uint32_t *fs, uint64_t *fd) { 13 | double fd_double; 14 | __m128d fd_reg; 15 | 16 | fd_reg = _mm_setzero_pd(); 17 | fd_reg = _mm_cvtsi32_sd(fd_reg, *fs); 18 | fd_double = _mm_cvtsd_f64(fd_reg); 19 | 20 | // Prevent aliasing. 21 | memcpy(fd, &fd_double, sizeof(fd_double)); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_f64_i64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_f64_i64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_f64_i64(const uint64_t *fs, uint64_t *fd) { 13 | double fd_double; 14 | __m128d fd_reg; 15 | 16 | fd_reg = _mm_setzero_pd(); 17 | fd_reg = _mm_cvtsi64_sd(fd_reg, *fs); 18 | fd_double = _mm_cvtsd_f64(fd_reg); 19 | 20 | // Prevent aliasing. 21 | memcpy(fd, &fd_double, sizeof(fd_double)); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/floor_i32_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/floor_i32_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_floor_i32_f32(const uint32_t *fs, uint32_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | fs_reg = _mm_floor_ss(fs_reg, fs_reg); 21 | *fd = _mm_cvtss_si32(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/floor_i64_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/floor_i64_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_floor_i64_f32(const uint32_t *fs, uint64_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | fs_reg = _mm_floor_ss(fs_reg, fs_reg); 21 | *fd = _mm_cvtss_si64(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /si/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // si/registers.md: SI register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef SI_REGISTER_LIST 12 | #define SI_REGISTER_LIST \ 13 | X(SI_DRAM_ADDR_REG) \ 14 | X(SI_PIF_ADDR_RD64B_REG) \ 15 | X(SI_RESERVED_1_REG) \ 16 | X(SI_RESERVED_2_REG) \ 17 | X(SI_PIF_ADDR_WR64B_REG) \ 18 | X(SI_RESERVED_3_REG) \ 19 | X(SI_STATUS_REG) 20 | #endif 21 | 22 | SI_REGISTER_LIST 23 | 24 | 25 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/floor_i32_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/floor_i32_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_floor_i32_f64(const uint64_t *fs, uint32_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | fs_reg = _mm_floor_sd(fs_reg, fs_reg); 21 | *fd = _mm_cvtsd_si32(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/floor_i64_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/floor_i64_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_floor_i64_f64(const uint64_t *fs, uint64_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | fs_reg = _mm_floor_sd(fs_reg, fs_reg); 21 | *fd = _mm_cvtsd_si64(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /gdb/protocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // protocol.h: gdb message parsing and responding 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef _gdb_protocol_h__ 12 | #define _gdb_protocol_h__ 13 | #include "common.h" 14 | 15 | struct gdb; 16 | 17 | cen64_cold void gdb_send_stop_reply(struct gdb* gdb, bool is_breakpoint); 18 | cen64_cold void gdb_handle_packet(struct gdb* gdb, const char* command_start, const char* command_end); 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vdivh.c: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vrcp.c 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include "rsp/cpu.h" 10 | 11 | __m128i rsp_vdivh(struct rsp *rsp, 12 | unsigned src, unsigned e, unsigned dest, unsigned de) { 13 | 14 | // Get the element from VT. 15 | rsp->cp2.div_in = rsp->cp2.regs[src].e[e & 0x7]; 16 | 17 | // Write out the upper part of the result. 18 | rsp->cp2.regs[dest].e[de & 0x7] = rsp->cp2.div_out; 19 | return rsp_vect_load_unshuffled_operand(rsp->cp2.regs[dest].e); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /.github/workflows/debian-linux.yml: -------------------------------------------------------------------------------- 1 | name: debian-linux 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Installing Dependencies 13 | run: | 14 | sudo apt-get update 15 | sudo apt-get install -y freeglut3 freeglut3-dev libglew1.5 libglew1.5-dev libglu1-mesa libglu1-mesa-dev libgl1-mesa-glx libgl1-mesa-dev libpulse-dev libalut-dev mesa-common-dev libopenal-dev 16 | 17 | - name: Build 18 | run: | 19 | mkdir build && cd build 20 | cmake -DCMAKE_BUILD_TYPE=Release .. 21 | make VERBOSE=1 -j4 -------------------------------------------------------------------------------- /os/common/input.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/common/input.h: Input device handling functions. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_COMMON_INPUT 12 | #define CEN64_OS_COMMON_INPUT 13 | #include "common.h" 14 | 15 | struct bus_controller; 16 | 17 | cen64_cold void keyboard_press_callback(struct bus_controller *bus, unsigned key); 18 | cen64_cold void keyboard_release_callback(struct bus_controller *bus, unsigned key); 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /rsp/opcodes.c: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/opcodes.c: RSP opcode types and info. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "rsp/opcodes.h" 12 | 13 | const char *rsp_opcode_mnemonics[NUM_RSP_OPCODES] = { 14 | #define X(op) #op, 15 | #include "rsp/opcodes.md" 16 | #undef X 17 | }; 18 | 19 | const char *rsp_vector_opcode_mnemonics[NUM_RSP_VECTOR_OPCODES] = { 20 | #define X(op) #op, 21 | #include "rsp/vector_opcodes.md" 22 | #undef X 23 | }; 24 | 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/round_i32_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/round_i32_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_round_i32_f32(const uint32_t *fs, uint32_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | fs_reg = _mm_round_ss(fs_reg, fs_reg, _MM_FROUND_TO_NEAREST_INT); 21 | *fd = _mm_cvtss_si32(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/round_i64_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/round_i64_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_round_i64_f32(const uint32_t *fs, uint64_t *fd) { 13 | float fs_float; 14 | __m128 fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | fs_reg = _mm_round_ss(fs_reg, fs_reg, _MM_FROUND_TO_NEAREST_INT); 21 | *fd = _mm_cvtss_si64(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /common/debug.c: -------------------------------------------------------------------------------- 1 | // 2 | // common/debug.c 3 | // 4 | // Verbose debugging functions (read: "fancy print wrappers"). 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #include "common/debug.h" 11 | #include 12 | #include 13 | #include 14 | 15 | #ifndef NDEBUG 16 | 17 | // Writes a formatted string to standard output. 18 | int debug(const char *fmt, ...) { 19 | va_list ap; 20 | int ret; 21 | 22 | va_start(ap, fmt); 23 | ret = vfprintf(stdout, fmt, ap); 24 | va_end(ap); 25 | 26 | return ret; 27 | } 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /vr4300/fault.md: -------------------------------------------------------------------------------- 1 | // 2 | // vr4300/fault.md: VR4300 fault management. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef VR4300_FAULT_LIST 12 | #define VR4300_FAULT_LIST \ 13 | X(NONE) X(CP0I) X(RST) X(NMI) X(OVFL) X(TRAP) X(FPE) X(DADE) \ 14 | X(DTLB) X(WAT) X(INTR) X(DCM) X(DCB) X(COP) X(DBE) X(SYSC) X(BRPT) \ 15 | X(CPU) X(RSVD) X(LDI) X(MCI) X(IADE) X(ITM) X(ICB) X(UNC) X(ITLB) \ 16 | X(IBE) X(RI) 17 | #endif 18 | 19 | VR4300_FAULT_LIST 20 | 21 | -------------------------------------------------------------------------------- /debugger/network_handle.h: -------------------------------------------------------------------------------- 1 | // 2 | // network_handle.h: CEN64D network handle. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef NETWORK_HANDLE_H 12 | #define NETWORK_HANDLE_H 13 | #include 14 | 15 | class NetworkHandle { 16 | QTcpSocket socket; 17 | 18 | public: 19 | explicit NetworkHandle(QWidget *parent); 20 | ~NetworkHandle(); 21 | 22 | int getProtocolVersion(); 23 | int getRemoteProtocolVersion(); 24 | }; 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/round_i32_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/round_i32_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_round_i32_f64(const uint64_t *fs, uint32_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | fs_reg = _mm_round_sd(fs_reg, fs_reg, _MM_FROUND_TO_NEAREST_INT); 21 | *fd = _mm_cvtsd_si32(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/round_i64_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/round_i64_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_round_i64_f64(const uint64_t *fs, uint64_t *fd) { 13 | double fs_double; 14 | __m128d fs_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | fs_reg = _mm_round_sd(fs_reg, fs_reg, _MM_FROUND_TO_NEAREST_INT); 21 | *fd = _mm_cvtsd_si64(fs_reg); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vsubc.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vsubc.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vsubc(__m128i vs, __m128i vt, 11 | __m128i zero, __m128i *eq, __m128i *sn) { 12 | __m128i equal, sat_udiff, sat_udiff_zero; 13 | 14 | sat_udiff = _mm_subs_epu16(vs, vt); 15 | equal = _mm_cmpeq_epi16(vs, vt); 16 | sat_udiff_zero = _mm_cmpeq_epi16(sat_udiff, zero); 17 | 18 | *eq = _mm_cmpeq_epi16(equal, zero); 19 | *sn = _mm_andnot_si128(equal, sat_udiff_zero); 20 | 21 | return _mm_sub_epi16(vs, vt); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /debugger/register_model.h: -------------------------------------------------------------------------------- 1 | // 2 | // register_model.h: CEN64D register model (MVC). 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef REGISTER_MODEL_H 12 | #define REGISTER_MODEL_H 13 | #include 14 | 15 | class RegisterModel { 16 | quint64 *data; 17 | 18 | public: 19 | explicit RegisterModel(unsigned num_regs); 20 | virtual ~RegisterModel(); 21 | 22 | quint64 getIndex(unsigned i); 23 | void setIndex(unsigned i, quint64); 24 | }; 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /arch/x86_64/context.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/context.h 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_ARCH_X86_64_CONTEXT_H 12 | #define CEN64_ARCH_X86_64_CONTEXT_H 13 | #include "common.h" 14 | #include 15 | 16 | struct cen64_context { 17 | __m128i regs[8]; 18 | uint32_t mxcsr; 19 | }; 20 | 21 | cen64_cold void cen64_context_restore(struct cen64_context *context); 22 | cen64_cold void cen64_context_save(struct cen64_context *context); 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vmov.c: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmov.c 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include "rsp/cpu.h" 10 | #include "rsp/rsp.h" 11 | 12 | __m128i rsp_vmov(struct rsp *rsp, 13 | unsigned src, unsigned e, unsigned dest, rsp_vect_t vt_shuffle) { 14 | uint16_t data; 15 | 16 | // Copy element into data 17 | memcpy(&data, (e & 0x7) + (uint16_t *)&vt_shuffle, sizeof(uint16_t)); 18 | 19 | // Write out the upper part of the result. 20 | rsp->cp2.regs[dest].e[e & 0x7] = data; 21 | return rsp_vect_load_unshuffled_operand(rsp->cp2.regs[dest].e); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cmp_ueq_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cmp_ueq_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline uint8_t fpu_cmp_ueq_32( 13 | const uint32_t *fs, const uint32_t *ft) { 14 | float fs_float, ft_float; 15 | __m128 fs_reg, ft_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | return _mm_comieq_ss(fs_reg, ft_reg); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cmp_ule_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cmp_ule_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline uint8_t fpu_cmp_ule_32( 13 | const uint32_t *fs, const uint32_t *ft) { 14 | float fs_float, ft_float; 15 | __m128 fs_reg, ft_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | return _mm_comile_ss(fs_reg, ft_reg); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cmp_ult_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cmp_ult_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline uint8_t fpu_cmp_ult_32( 13 | const uint32_t *fs, const uint32_t *ft) { 14 | float fs_float, ft_float; 15 | __m128 fs_reg, ft_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | return _mm_comilt_ss(fs_reg, ft_reg); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/sqrt_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/sqrt_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_sqrt_32(const uint32_t *fs, uint32_t *fd) { 13 | float fs_float, fd_float; 14 | __m128 fs_reg, fd_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | fd_reg = _mm_sqrt_ss(fs_reg); 21 | fd_float = _mm_cvtss_f32(fd_reg); 22 | 23 | // Prevent aliasing. 24 | memcpy(fd, &fd_float, sizeof(fd_float)); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | notifications: 2 | email: false 3 | 4 | language: c 5 | dist: bionic 6 | osx_image: xcode10.1 7 | 8 | branches: 9 | only: 10 | - master 11 | 12 | compiler: 13 | - gcc 14 | - clang 15 | os: 16 | - linux 17 | - osx 18 | 19 | matrix: 20 | exclude: 21 | - os: osx 22 | compiler: gcc 23 | 24 | addons: 25 | apt: 26 | packages: 27 | - freeglut3 28 | - freeglut3-dev 29 | - libglew1.5 30 | - libglew1.5-dev 31 | - libglu1-mesa 32 | - libglu1-mesa-dev 33 | - libgl1-mesa-glx 34 | - libgl1-mesa-dev 35 | - libpulse-dev 36 | - libalut-dev 37 | 38 | before_script: 39 | - mkdir release && cd release 40 | 41 | script: 42 | - cmake .. 43 | - make 44 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cmp_ueq_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cmp_ueq_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline uint8_t fpu_cmp_ueq_64( 13 | const uint64_t *fs, const uint64_t *ft) { 14 | double fs_double, ft_double; 15 | __m128d fs_reg, ft_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | return _mm_comieq_sd(fs_reg, ft_reg); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cmp_ule_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cmp_ule_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline uint8_t fpu_cmp_ule_64( 13 | const uint64_t *fs, const uint64_t *ft) { 14 | double fs_double, ft_double; 15 | __m128d fs_reg, ft_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | return _mm_comile_sd(fs_reg, ft_reg); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cmp_ult_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cmp_ult_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline uint8_t fpu_cmp_ult_64( 13 | const uint64_t *fs, const uint64_t *ft) { 14 | double fs_double, ft_double; 15 | __m128d fs_reg, ft_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | return _mm_comilt_sd(fs_reg, ft_reg); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/neg_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/neg_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_neg_32(const uint32_t *fs, uint32_t *fd) { 13 | float fs_float, fd_float; 14 | __m128 fs_reg, fd_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | fd_reg = _mm_xor_ps(_mm_set_ss(-0.0f), fs_reg); 21 | fd_float = _mm_cvtss_f32(fd_reg); 22 | 23 | // Prevent aliasing. 24 | memcpy(fd, &fd_float, sizeof(fd_float)); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vabs.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vabs.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vabs(__m128i vs, __m128i vt, 11 | __m128i zero, __m128i *acc_lo) { 12 | __m128i vs_zero = _mm_cmpeq_epi16(vs, zero); 13 | __m128i sign_lt = _mm_srai_epi16(vs, 15); 14 | __m128i vd = _mm_andnot_si128(vs_zero, vt); 15 | 16 | // Careful: if VT = 0x8000 and VS is negative, 17 | // acc_lo will be 0x8000 but vd will be 0x7FFF. 18 | vd = _mm_xor_si128(vd, sign_lt); 19 | *acc_lo = _mm_sub_epi16(vd, sign_lt); 20 | return _mm_subs_epi16(vd, sign_lt); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /debugger/disassembly_view.h: -------------------------------------------------------------------------------- 1 | // 2 | // disassembly_view.h: CEN64D disassembly view (MVC). 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef DISASSEMBLY_VIEW_H 12 | #define DISASSEMBLY_VIEW_H 13 | #include 14 | 15 | class DisassemblyView : public QAbstractScrollArea { 16 | Q_OBJECT 17 | 18 | unsigned fontWidth, fontHeight; 19 | 20 | public: 21 | explicit DisassemblyView(); 22 | virtual ~DisassemblyView(); 23 | 24 | void paintEvent(QPaintEvent* event); 25 | }; 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /debugger/register_model.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // register_model.cpp: CEN64D register model (MVC). 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "register_model.h" 12 | 13 | RegisterModel::RegisterModel(unsigned num_regs) { 14 | data = new quint64[num_regs]; 15 | } 16 | 17 | RegisterModel::~RegisterModel() { 18 | delete[] data; 19 | } 20 | 21 | quint64 RegisterModel::getIndex(unsigned i) { 22 | return data[i]; 23 | } 24 | 25 | void RegisterModel::setIndex(unsigned i, quint64 d) { 26 | data[i] = d; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /ri/rdram_registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // ri/rdram_registers.md: RDRAM register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef RDRAM_REGISTER_LIST 12 | #define RDRAM_REGISTER_LIST \ 13 | X(RDRAM_CONFIG_REG) \ 14 | X(RDRAM_DEVICE_ID_REG) \ 15 | X(RDRAM_DELAY_REG) \ 16 | X(RDRAM_MODE_REG) \ 17 | X(RDRAM_REF_INTERVAL_REG) \ 18 | X(RDRAM_REF_ROW_REG) \ 19 | X(RDRAM_RAS_INTERVAL_REG) \ 20 | X(RDRAM_MIN_INTERVAL_REG) \ 21 | X(RDRAM_ADDR_SELECT_REG) 22 | #endif 23 | 24 | RDRAM_REGISTER_LIST 25 | 26 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/abs_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/abs_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_abs_32(const uint32_t *fs, uint32_t *fd) { 13 | float fs_float, fd_float; 14 | __m128 fs_reg, fd_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | 19 | fs_reg = _mm_set_ss(fs_float); 20 | fd_reg = _mm_andnot_ps(_mm_set_ss(-0.0f), fs_reg); 21 | fd_float = _mm_cvtss_f32(fd_reg); 22 | 23 | // Prevent aliasing. 24 | memcpy(fd, &fd_float, sizeof(fd_float)); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/sqrt_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/sqrt_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_sqrt_64(const uint64_t *fs, uint64_t *fd) { 13 | double fs_double, fd_double; 14 | __m128d fs_reg, fd_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | fd_reg = _mm_sqrt_sd(fs_reg, fs_reg); 21 | fd_double = _mm_cvtsd_f64(fd_reg); 22 | 23 | // Prevent aliasing. 24 | memcpy(fd, &fd_double, sizeof(fd_double)); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /si/pak_transfer.h: -------------------------------------------------------------------------------- 1 | // 2 | // si/pak_transfer.h: Transfer pak handling 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2016, Mike Ryan. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __si_pak_transfer_h__ 12 | #define __si_pak_transfer_h__ 13 | #include "common.h" 14 | 15 | void transfer_pak_read(struct controller *controller, 16 | uint8_t *send_buf, uint8_t send_bytes, 17 | uint8_t *recv_buf, uint8_t recv_bytes); 18 | void transfer_pak_write(struct controller *controller, 19 | uint8_t *send_buf, uint8_t send_bytes, 20 | uint8_t *recv_buf, uint8_t recv_bytes); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/neg_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/neg_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_neg_64(const uint64_t *fs, uint64_t *fd) { 13 | double fs_double, fd_double; 14 | __m128d fs_reg, fd_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | fd_reg = _mm_xor_pd(_mm_set_sd(-0.0), fs_reg); 21 | fd_double = _mm_cvtsd_f64(fd_reg); 22 | 23 | // Prevent aliasing. 24 | memcpy(fd, &fd_double, sizeof(fd_double)); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /os/unix/arm/fpu/fpu.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/arm/fpu/fpu.h 3 | // 4 | // Extern declarations for host FPU functions. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_fpu_h__ 11 | #define __os_fpu_h__ 12 | #include "common.h" 13 | 14 | #include "arch/arm/fpu/fpu.h" 15 | 16 | static inline fpu_state_t fpu_get_state(void) { 17 | fpu_state_t state; 18 | 19 | __asm__ __volatile__("mrc p10, 7, %0, cr1, cr0, 0\n\t" : "=r"(state)); 20 | return state; 21 | } 22 | 23 | static inline void fpu_set_state(fpu_state_t state) { 24 | __asm__ __volatile__("mcr p10, 7, %0, cr1, cr0, 0\n\t" :: "r"(state)); 25 | } 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /os/winapi/timer.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/timer.h: Functions for obtaining the system clock time. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_WINAPI_TIMER 12 | #define CEN64_OS_WINAPI_TIMER 13 | #include "common.h" 14 | #include 15 | 16 | #define NS_PER_SEC 1000000000ULL 17 | 18 | typedef DWORD cen64_time; 19 | 20 | cen64_cold unsigned long long compute_time_difference( 21 | const cen64_time *now, const cen64_time *before); 22 | 23 | cen64_cold void get_time(cen64_time *t); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/abs_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/abs_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_abs_64(const uint64_t *fs, uint64_t *fd) { 13 | double fs_double, fd_double; 14 | __m128d fs_reg, fd_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | 19 | fs_reg = _mm_set_sd(fs_double); 20 | fd_reg = _mm_andnot_pd(_mm_set_sd(-0.0), fs_reg); 21 | fd_double = _mm_cvtsd_f64(fd_reg); 22 | 23 | // Prevent aliasing. 24 | memcpy(fd, &fd_double, sizeof(fd_double)); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /os/common/alloc.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/common/alloc.h: Low-level allocators. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_COMMON_ALLOC 12 | #define CEN64_OS_COMMON_ALLOC 13 | #include "common.h" 14 | 15 | struct cen64_mem { 16 | size_t size; 17 | void *ptr; 18 | }; 19 | 20 | cen64_cold void cen64_alloc_cleanup(void); 21 | cen64_cold int cen64_alloc_init(void); 22 | 23 | cen64_cold void *cen64_alloc(struct cen64_mem *m, size_t size, bool exec); 24 | cen64_cold void cen64_free(struct cen64_mem *m); 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /vr4300/segment.h: -------------------------------------------------------------------------------- 1 | // 2 | // vr4300/segment.h: VR4300 MMU segment manager. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __vr4300_segment_h__ 12 | #define __vr4300_segment_h__ 13 | #include "common.h" 14 | 15 | struct segment { 16 | uint64_t start; 17 | uint64_t length; 18 | uint64_t offset; 19 | 20 | uint8_t xmode_mask; 21 | bool mapped; 22 | bool cached; 23 | }; 24 | 25 | const struct segment* get_default_segment(void); 26 | const struct segment* get_segment(uint64_t address, uint32_t cp0_status); 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /vi/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // vi/registers.md: VI register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef VI_REGISTER_LIST 12 | #define VI_REGISTER_LIST \ 13 | X(VI_STATUS_REG) \ 14 | X(VI_ORIGIN_REG) \ 15 | X(VI_WIDTH_REG) \ 16 | X(VI_INTR_REG) \ 17 | X(VI_CURRENT_REG) \ 18 | X(VI_BURST_REG) \ 19 | X(VI_V_SYNC_REG) \ 20 | X(VI_H_SYNC_REG) \ 21 | X(VI_LEAP_REG) \ 22 | X(VI_H_START_REG) \ 23 | X(VI_V_START_REG) \ 24 | X(VI_V_BURST_REG) \ 25 | X(VI_X_SCALE_REG) \ 26 | X(VI_Y_SCALE_REG) 27 | #endif 28 | 29 | VI_REGISTER_LIST 30 | 31 | -------------------------------------------------------------------------------- /vi/render.h: -------------------------------------------------------------------------------- 1 | // 2 | // vi/render.h: Rendering functions. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_VI_RENDER_H 12 | #define CEN64_VI_RENDER_H 13 | 14 | #include "common.h" 15 | #include "vi/controller.h" 16 | 17 | cen64_cold void gl_window_init(struct vi_controller *vi); 18 | cen64_cold void gl_window_render_frame(struct vi_controller *vi, 19 | const uint8_t *buffer, unsigned hres, unsigned vres, 20 | unsigned hskip, unsigned type); 21 | 22 | // Render callbacks. 23 | cen64_cold void gl_window_resize_cb(int width, int height); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_f32_f64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_f32_f64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_f32_f64(const uint64_t *fs, uint32_t *fd) { 13 | double fs_double; 14 | float fd_float; 15 | __m128d fs_reg; 16 | __m128 fd_reg; 17 | 18 | // Prevent aliasing. 19 | memcpy(&fs_double, fs, sizeof(fs_double)); 20 | fd_reg = _mm_setzero_ps(); 21 | 22 | fs_reg = _mm_set_sd(fs_double); 23 | fd_reg = _mm_cvtsd_ss(fd_reg, fs_reg); 24 | fd_float = _mm_cvtss_f32(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_float, sizeof(fd_float)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/cvt_f64_f32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/cvt_f64_f32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_cvt_f64_f32(const uint32_t *fs, uint64_t *fd) { 13 | double fd_double; 14 | float fs_float; 15 | __m128d fd_reg; 16 | __m128 fs_reg; 17 | 18 | // Prevent aliasing. 19 | memcpy(&fs_float, fs, sizeof(fs_float)); 20 | fd_reg = _mm_setzero_pd(); 21 | 22 | fs_reg = _mm_set_ss(fs_float); 23 | fd_reg = _mm_cvtss_sd(fd_reg, fs_reg); 24 | fd_double = _mm_cvtsd_f64(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_double, sizeof(fd_double)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /pi/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // pi/registers.md: PI register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef PI_REGISTER_LIST 12 | #define PI_REGISTER_LIST \ 13 | X(PI_DRAM_ADDR_REG) \ 14 | X(PI_CART_ADDR_REG) \ 15 | X(PI_RD_LEN_REG) \ 16 | X(PI_WR_LEN_REG) \ 17 | X(PI_STATUS_REG) \ 18 | X(PI_BSD_DOM1_LAT_REG) \ 19 | X(PI_BSD_DOM1_PWD_REG) \ 20 | X(PI_BSD_DOM1_PGS_REG) \ 21 | X(PI_BSD_DOM1_RLS_REG) \ 22 | X(PI_BSD_DOM2_LAT_REG) \ 23 | X(PI_BSD_DOM2_PWD_REG) \ 24 | X(PI_BSD_DOM2_PGS_REG) \ 25 | X(PI_BSD_DOM2_RLS_REG) 26 | #endif 27 | 28 | PI_REGISTER_LIST 29 | 30 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_f_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_f_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_f_32( 12 | const uint32_t *fs, const uint32_t *ft) { 13 | float fs_float, ft_float; 14 | __m128 fs_reg, ft_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_float, fs, sizeof(fs_float)); 18 | memcpy(&ft_float, ft, sizeof(ft_float)); 19 | 20 | fs_reg = _mm_set_ss(fs_float); 21 | ft_reg = _mm_set_ss(ft_float); 22 | 23 | __asm__ __volatile__( 24 | "comiss %0, %1\n\t" 25 | :: "x" (fs_reg), 26 | "x" (ft_reg) 27 | : "cc" 28 | ); 29 | 30 | return 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /os/common/rom_file.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/rom_file.h 3 | // 4 | // Functions for mapping ROM images into the address space. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_rom_file_h__ 11 | #define __os_rom_file_h__ 12 | #include "common.h" 13 | #include 14 | 15 | #ifdef _WIN32 16 | #include 17 | 18 | struct rom_file { 19 | void *ptr; 20 | size_t size; 21 | HANDLE mapping; 22 | HANDLE file; 23 | }; 24 | 25 | #else 26 | struct rom_file { 27 | void *ptr; 28 | size_t size; 29 | int fd; 30 | }; 31 | #endif 32 | 33 | cen64_cold int close_rom_file(const struct rom_file *file); 34 | cen64_cold int open_rom_file(const char *path, struct rom_file *file); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_f_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_f_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_f_64( 12 | const uint64_t *fs, const uint64_t *ft) { 13 | double fs_double, ft_double; 14 | __m128d fs_reg, ft_reg; 15 | 16 | // Prevent aliasing. 17 | memcpy(&fs_double, fs, sizeof(fs_double)); 18 | memcpy(&ft_double, ft, sizeof(ft_double)); 19 | 20 | fs_reg = _mm_set_sd(fs_double); 21 | ft_reg = _mm_set_sd(ft_double); 22 | 23 | __asm__ __volatile__( 24 | "comisd %0, %1\n\t" 25 | :: "x" (fs_reg), 26 | "x" (ft_reg) 27 | : "cc" 28 | ); 29 | 30 | return 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vadd.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vadd.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vadd(__m128i vs, __m128i vt, 11 | __m128i carry, __m128i *acc_lo) { 12 | __m128i vd, minimum, maximum; 13 | 14 | // VCC uses unsaturated arithmetic. 15 | vd = _mm_add_epi16(vs, vt); 16 | *acc_lo = _mm_sub_epi16(vd, carry); 17 | 18 | // VD is the signed sum of the two sources and the carry. Since we 19 | // have to saturate the sum of all three, we have to be clever. 20 | minimum = _mm_min_epi16(vs, vt); 21 | maximum = _mm_max_epi16(vs, vt); 22 | minimum = _mm_subs_epi16(minimum, carry); 23 | return _mm_adds_epi16(minimum, maximum); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /debugger/memory_window.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // memory_window.cpp: Memory view window. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "memory_window.h" 12 | 13 | MemoryWindow::MemoryWindow(QAction *toggleAction, bool initiallyVisible) 14 | : ToggleWindow(tr("CEN64D: Memory"), toggleAction, initiallyVisible), 15 | memoryView(8) { 16 | 17 | addressLabel.setText("Address: "); 18 | 19 | layout.addWidget(&memoryView, 0, 1, 1, 2); 20 | layout.addWidget(&addressLabel, 1, 1); 21 | layout.addWidget(&addressLine, 1, 2); 22 | 23 | setLayout(&layout); 24 | } 25 | 26 | MemoryWindow::~MemoryWindow() { 27 | } 28 | 29 | -------------------------------------------------------------------------------- /os/sdl/gl_common.h: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 4 | // Copyright (C) 2015, Tyler J. Stachecki. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef CEN64_OS_SDL_GL_COMMON 11 | #define CEN64_OS_SDL_GL_COMMON 12 | #include "common.h" 13 | 14 | 15 | enum cen64_gl_context_type { 16 | CEN64_GL_CONTEXT_TYPE_RGBA, 17 | CEN64_GL_CONTEXT_TYPE_COLOR_INDEX 18 | }; 19 | 20 | enum cen64_gl_drawable_type { 21 | CEN64_GL_DRAWABLE_TYPE_WINDOW, 22 | CEN64_GL_DRAWABLE_TYPE_BITMAP 23 | }; 24 | 25 | enum cen64_gl_layer_type { 26 | CEN64_GL_LAYER_TYPE_DEFAULT = 0, 27 | CEN64_GL_LAYER_TYPE_OVERLAY = 1, 28 | CEN64_GL_LAYER_TYPE_UNDERLAY = 2 29 | }; 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /os/windows/dynarec.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/windows/dynarec.c 3 | // 4 | // Functions for allocating executable code buffers. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #include "common.h" 11 | #include "os/dynarec.h" 12 | #include 13 | 14 | extern HANDLE dynarec_heap; 15 | 16 | // Allocates memory with execute permissions set. 17 | void *alloc_dynarec_slab(struct dynarec_slab *slab, size_t size) { 18 | if ((slab->ptr = HeapAlloc(dynarec_heap, HEAP_ZERO_MEMORY, size)) == NULL) 19 | return NULL; 20 | 21 | slab->size = size; 22 | return slab->ptr; 23 | } 24 | 25 | // Frees memory acquired for a dynarec buffer. 26 | void free_dynarec_slab(struct dynarec_slab *slab) { 27 | HeapFree(dynarec_heap, 0, slab->ptr); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /pi/is_viewer.h: -------------------------------------------------------------------------------- 1 | #ifndef __IS_VIEWER_H__ 2 | #define __IS_VIEWER_H__ 3 | 4 | #include 5 | 6 | // IS Viewer 7 | #define IS_VIEWER_BASE_ADDRESS 0x13FF0000 8 | #define IS_VIEWER_ADDRESS_LEN 0x00001000 9 | 10 | struct is_viewer { 11 | uint32_t base_address; 12 | uint32_t len; 13 | 14 | uint8_t *buffer; 15 | uint8_t *output_buffer; 16 | size_t output_buffer_pos; 17 | uint8_t *output_buffer_conv; 18 | int show_output; 19 | int output_warning; 20 | 21 | iconv_t cd; 22 | }; 23 | 24 | int is_viewer_init(struct is_viewer *is, int show_output); 25 | int is_viewer_map(struct is_viewer *is, uint32_t address); 26 | int read_is_viewer(struct is_viewer *is, uint32_t address, uint32_t *word); 27 | int write_is_viewer(struct is_viewer *is, uint32_t address, uint32_t word, uint32_t dqm); 28 | 29 | #endif /* __IS_VIEWER_H__ */ 30 | -------------------------------------------------------------------------------- /rdp/cpu.h: -------------------------------------------------------------------------------- 1 | // 2 | // rdp/cpu.h: RDP processor container. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __rdp_cpu_h__ 12 | #define __rdp_cpu_h__ 13 | #include "common.h" 14 | 15 | enum dp_register { 16 | #define X(reg) reg, 17 | #include "rdp/registers.md" 18 | #undef X 19 | NUM_DP_REGISTERS 20 | }; 21 | 22 | #ifdef DEBUG_MMIO_REGISTER_ACCESS 23 | extern const char *dp_register_mnemonics[NUM_DP_REGISTERS]; 24 | #endif 25 | 26 | struct rdp { 27 | uint32_t regs[NUM_DP_REGISTERS]; 28 | struct bus_controller *bus; 29 | }; 30 | 31 | cen64_cold int rdp_init(struct rdp *rdp, struct bus_controller *bus); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/add_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/add_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_add_32( 13 | const uint32_t *fs, const uint32_t *ft, uint32_t *fd) { 14 | float fs_float, ft_float, fd_float; 15 | __m128 fs_reg, ft_reg, fd_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | fd_reg = _mm_add_ss(fs_reg, ft_reg); 24 | fd_float = _mm_cvtss_f32(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_float, sizeof(fd_float)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/div_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/div_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_div_32( 13 | const uint32_t *fs, const uint32_t *ft, uint32_t *fd) { 14 | float fs_float, ft_float, fd_float; 15 | __m128 fs_reg, ft_reg, fd_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | fd_reg = _mm_div_ss(fs_reg, ft_reg); 24 | fd_float = _mm_cvtss_f32(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_float, sizeof(fd_float)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/mul_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/mul_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_mul_32( 13 | const uint32_t *fs, const uint32_t *ft, uint32_t *fd) { 14 | float fs_float, ft_float, fd_float; 15 | __m128 fs_reg, ft_reg, fd_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | fd_reg = _mm_mul_ss(fs_reg, ft_reg); 24 | fd_float = _mm_cvtss_f32(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_float, sizeof(fd_float)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/sub_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/sub_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_sub_32( 13 | const uint32_t *fs, const uint32_t *ft, uint32_t *fd) { 14 | float fs_float, ft_float, fd_float; 15 | __m128 fs_reg, ft_reg, fd_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | fd_reg = _mm_sub_ss(fs_reg, ft_reg); 24 | fd_float = _mm_cvtss_f32(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_float, sizeof(fd_float)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /si/rtc.h: -------------------------------------------------------------------------------- 1 | // 2 | // si/rtc.h: RTC routines 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2016, Mike Ryan. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __si_rtc_h__ 12 | #define __si_rtc_h__ 13 | #include "common.h" 14 | #include "si/controller.h" 15 | 16 | void rtc_init(struct rtc * rtc); 17 | int rtc_status(struct rtc * rtc, 18 | uint8_t *send_buf, uint8_t send_bytes, 19 | uint8_t *recv_buf, uint8_t recv_bytes); 20 | int rtc_read(struct rtc * rtc, 21 | uint8_t *send_buf, uint8_t send_bytes, 22 | uint8_t *recv_buf, uint8_t recv_bytes); 23 | int rtc_write(struct rtc * rtc, 24 | uint8_t *send_buf, uint8_t send_bytes, 25 | uint8_t *recv_buf, uint8_t recv_bytes); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /debugger/memory_window.h: -------------------------------------------------------------------------------- 1 | // 2 | // memory_window.h: Memory view window. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef MEMORY_WINDOW_H 12 | #define MEMORY_WINDOW_H 13 | 14 | #include "memory_view.h" 15 | #include "toggle_window.h" 16 | #include 17 | #include 18 | #include 19 | 20 | class MemoryWindow : public ToggleWindow { 21 | Q_OBJECT 22 | QGridLayout layout; 23 | 24 | MemoryView memoryView; 25 | QLabel addressLabel; 26 | QLineEdit addressLine; 27 | 28 | public: 29 | explicit MemoryWindow(QAction *toggleAction, bool initiallyVisible); 30 | ~MemoryWindow(); 31 | }; 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/add_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/add_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_add_64( 13 | const uint64_t *fs, const uint64_t *ft, uint64_t *fd) { 14 | double fs_double, ft_double, fd_double; 15 | __m128d fs_reg, ft_reg, fd_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | fd_reg = _mm_add_sd(fs_reg, ft_reg); 24 | fd_double = _mm_cvtsd_f64(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_double, sizeof(fd_double)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/div_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/div_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_div_64( 13 | const uint64_t *fs, const uint64_t *ft, uint64_t *fd) { 14 | double fs_double, ft_double, fd_double; 15 | __m128d fs_reg, ft_reg, fd_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | fd_reg = _mm_div_sd(fs_reg, ft_reg); 24 | fd_double = _mm_cvtsd_f64(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_double, sizeof(fd_double)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/mul_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/mul_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_mul_64( 13 | const uint64_t *fs, const uint64_t *ft, uint64_t *fd) { 14 | double fs_double, ft_double, fd_double; 15 | __m128d fs_reg, ft_reg, fd_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | fd_reg = _mm_mul_sd(fs_reg, ft_reg); 24 | fd_double = _mm_cvtsd_f64(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_double, sizeof(fd_double)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /arch/x86_64/fpu/sub_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/fpu/sub_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include 10 | #include 11 | 12 | static inline void fpu_sub_64( 13 | const uint64_t *fs, const uint64_t *ft, uint64_t *fd) { 14 | double fs_double, ft_double, fd_double; 15 | __m128d fs_reg, ft_reg, fd_reg; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | fd_reg = _mm_sub_sd(fs_reg, ft_reg); 24 | fd_double = _mm_cvtsd_f64(fd_reg); 25 | 26 | // Prevent aliasing. 27 | memcpy(fd, &fd_double, sizeof(fd_double)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/vor.s: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/vor.s 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .include "rsp/gcc/defs.h" 12 | 13 | .text 14 | 15 | .ifdef __MINGW__ 16 | .globl RSP_VOR 17 | .def RSP_VOR; .scl 2; .type 32; .endef 18 | .seh_proc RSP_VOR 19 | .ifndef __VECTORCALL__ 20 | RSP_VOR: 21 | movdqa (%r8), %xmm0 22 | movdqa (%r9), %xmm1 23 | #pxor %xmm2, %xmm2 24 | .endif 25 | .else 26 | .global RSP_VOR 27 | .type RSP_VOR, @function 28 | RSP_VOR: 29 | .endif 30 | 31 | por %xmm1, %xmm0 32 | movdqa %xmm0, acc_lo 33 | retq 34 | 35 | .ifdef __MINGW__ 36 | .seh_endproc 37 | .else 38 | .size RSP_VOR,.-RSP_VOR 39 | .endif 40 | 41 | -------------------------------------------------------------------------------- /rsp/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/registers.md: RSP register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef SP_REGISTER_LIST 12 | #define SP_REGISTER_LIST \ 13 | X(SP_MEM_ADDR_REG) \ 14 | X(SP_DRAM_ADDR_REG) \ 15 | X(SP_RD_LEN_REG) \ 16 | X(SP_WR_LEN_REG) \ 17 | X(SP_STATUS_REG) \ 18 | X(SP_DMA_FULL_REG) \ 19 | X(SP_DMA_BUSY_REG) \ 20 | X(SP_SEMAPHORE_REG) \ 21 | X(CMD_START) \ 22 | X(CMD_END) \ 23 | X(CMD_CURRENT) \ 24 | X(CMD_STATUS) \ 25 | X(CMD_CLOCK) \ 26 | X(CMD_BUSY) \ 27 | X(CMD_PIPE_BUSY) \ 28 | X(CMD_TMEM_BUSY) \ 29 | X(SP_PC_REG) \ 30 | X(SP_IBIST_REG) 31 | #endif 32 | 33 | SP_REGISTER_LIST 34 | 35 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/vand.s: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/vand.s 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .include "rsp/gcc/defs.h" 12 | 13 | .text 14 | 15 | .ifdef __MINGW__ 16 | .globl RSP_VAND 17 | .def RSP_VAND; .scl 2; .type 32; .endef 18 | .seh_proc RSP_VAND 19 | .ifndef __VECTORCALL__ 20 | RSP_VAND: 21 | movdqa (%r8), %xmm0 22 | movdqa (%r9), %xmm1 23 | #pxor %xmm2, %xmm2 24 | .endif 25 | .else 26 | .global RSP_VAND 27 | .type RSP_VAND, @function 28 | RSP_VAND: 29 | .endif 30 | 31 | pand %xmm1, %xmm0 32 | movdqa %xmm0, acc_lo 33 | retq 34 | 35 | .ifdef __MINGW__ 36 | .seh_endproc 37 | .else 38 | .size RSP_VAND,.-RSP_VAND 39 | .endif 40 | 41 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/vxor.s: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/vxor.s 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .include "rsp/gcc/defs.h" 12 | 13 | .text 14 | 15 | .ifdef __MINGW__ 16 | .globl RSP_VXOR 17 | .def RSP_VXOR; .scl 2; .type 32; .endef 18 | .seh_proc RSP_VXOR 19 | .ifndef __VECTORCALL__ 20 | RSP_VXOR: 21 | movdqa (%r8), %xmm0 22 | movdqa (%r9), %xmm1 23 | #pxor %xmm2, %xmm2 24 | .endif 25 | .else 26 | .global RSP_VXOR 27 | .type RSP_VXOR, @function 28 | RSP_VXOR: 29 | .endif 30 | 31 | pxor %xmm1, %xmm0 32 | movdqa %xmm0, acc_lo 33 | retq 34 | 35 | .ifdef __MINGW__ 36 | .seh_endproc 37 | .else 38 | .size RSP_VXOR,.-RSP_VXOR 39 | .endif 40 | 41 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vsub.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vsub.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vsub(__m128i vs, __m128i vt, 11 | __m128i carry, __m128i *acc_lo) { 12 | __m128i unsat_diff, sat_diff, overflow, vd; 13 | 14 | // acc_lo uses saturated arithmetic. 15 | unsat_diff = _mm_sub_epi16(vt, carry); 16 | sat_diff = _mm_subs_epi16(vt, carry); 17 | 18 | *acc_lo = _mm_sub_epi16(vs, unsat_diff); 19 | vd = _mm_subs_epi16(vs, sat_diff); 20 | 21 | // VD is the signed diff of the two sources and the carry. Since we 22 | // have to saturate the diff of all three, we have to be clever. 23 | overflow = _mm_cmpgt_epi16(sat_diff, unsat_diff); 24 | return _mm_adds_epi16(vd, overflow); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /debugger/main_window.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | CEN64D 15 | 16 | 17 | 18 | 19 | 20 | 0 21 | 0 22 | 400 23 | 26 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_un_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_un_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_un_32( 12 | const uint32_t *fs, const uint32_t *ft) { 13 | float fs_float, ft_float; 14 | __m128 fs_reg, ft_reg; 15 | uint8_t condition; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | 24 | __asm__ __volatile__( 25 | "comiss %1, %2\n\t" 26 | "setp %%al\n\t" 27 | : "=a" (condition) 28 | : "x" (fs_reg), 29 | "x" (ft_reg) 30 | : "cc" 31 | ); 32 | 33 | return condition; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /rdp/cpu.c: -------------------------------------------------------------------------------- 1 | // 2 | // rdp/cpu.c: RDP processor container. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "common.h" 12 | #include "rdp/cpu.h" 13 | 14 | #ifdef DEBUG_MMIO_REGISTER_ACCESS 15 | const char *dp_register_mnemonics[NUM_DP_REGISTERS] = { 16 | #define X(reg) #reg, 17 | #include "rdp/registers.md" 18 | #undef X 19 | }; 20 | #endif 21 | 22 | // Sets the opaque pointer used for external accesses. 23 | static void rdp_connect_bus(struct rdp *rdp, struct bus_controller *bus) { 24 | rdp->bus = bus; 25 | } 26 | 27 | // Initializes the RDP component. 28 | int rdp_init(struct rdp *rdp, struct bus_controller *bus) { 29 | rdp_connect_bus(rdp, bus); 30 | 31 | return 0; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /rsp/vector_opcodes.md: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/vector_opcodes.md: RSP vector opcode types and info. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef RSP_VECTOR_OPCODE_TABLE 12 | #define RSP_VECTOR_OPCODE_TABLE X(VINVALID) \ 13 | X(VABS) X(VADD) X(VADDC) X(VAND) X(VCH) X(VCL) X(VCR) X(VEQ) X(VGE) \ 14 | X(VLT) X(VMACF) X(VMACQ) X(VMACU) X(VMADH) X(VMADL) X(VMADM) X(VMADN) \ 15 | X(VMOV) X(VMRG) X(VMUDH) X(VMUDL) X(VMUDM) X(VMUDN) X(VMULF) X(VMULQ) \ 16 | X(VMULU) X(VNAND) X(VNE) X(VNOP) X(VNOR) X(VNULL) X(VNXOR) X(VOR) X(VRCP) \ 17 | X(VRCPH) X(VRCPL) X(VRNDN) X(VRNDP) X(VRSQ) X(VRSQH) X(VRSQL) X(VSAR) \ 18 | X(VSUB) X(VSUBC) X(VXOR) 19 | #endif 20 | 21 | RSP_VECTOR_OPCODE_TABLE 22 | 23 | -------------------------------------------------------------------------------- /os/common/gl_hints.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/common/gl_hints.c: OpenGL configuration hints. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "gl_common.h" 12 | #include "gl_hints.h" 13 | 14 | const cen64_gl_hints cen64_default_gl_hints = { 15 | CEN64_GL_CONTEXT_TYPE_RGBA, 16 | CEN64_GL_DRAWABLE_TYPE_WINDOW, 17 | 18 | 1, // double_buffered 19 | -1, // stereoscopic 20 | 21 | -1, // rgb_color_depth 22 | -1, // alpha_color_depth 23 | -1, // depth_buffer_size 24 | -1, // num_aux_buffers 25 | -1, // stencil_buffer_size 26 | 27 | -1, // accum_buffer_red_bits 28 | -1, // accum_buffer_green_bits 29 | -1, // accum_buffer_blue_bits 30 | -1, // accum_buffer_alpha_bits 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /os/posix/cpuid.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/posix/cpuid.c 3 | // 4 | // Functions for calling cpuid on x86. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #include "os/cpuid.h" 11 | 12 | void cen64_cpuid(uint32_t eax, uint32_t ecx, struct cen64_cpuid_t *cpuid) { 13 | __asm__ __volatile__( 14 | "cpuid\n\t" 15 | 16 | : "=a"(cpuid->eax), "=b"(cpuid->ebx), "=c"(cpuid->ecx), "=d"(cpuid->edx) 17 | : "0"(eax), "2"(ecx) 18 | ); 19 | } 20 | 21 | void cen64_cpuid_get_vendor(char vendor[13]) { 22 | struct cen64_cpuid_t my_cpuid; 23 | 24 | cen64_cpuid(0, 0, &my_cpuid); 25 | 26 | memcpy(vendor + 0, &my_cpuid.ebx, sizeof(my_cpuid.ebx)); 27 | memcpy(vendor + 4, &my_cpuid.edx, sizeof(my_cpuid.edx)); 28 | memcpy(vendor + 8, &my_cpuid.ecx, sizeof(my_cpuid.ecx)); 29 | vendor[12] = '\0'; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /debugger/memory_view.h: -------------------------------------------------------------------------------- 1 | // 2 | // memory_view.h: CEN64D memory view (MVC). 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef MEMORY_VIEW_H 12 | #define MEMORY_VIEW_H 13 | #include 14 | #include 15 | #include 16 | 17 | class MemoryView : public QAbstractScrollArea { 18 | Q_OBJECT 19 | 20 | unsigned fontWidth, fontHeight; 21 | unsigned addressOctets; 22 | int byteStart, bytesPerRow; 23 | 24 | char formatstr[16]; 25 | 26 | public: 27 | explicit MemoryView(unsigned addressOctets); 28 | virtual ~MemoryView(); 29 | 30 | void resizeEvent(QResizeEvent *event); 31 | void paintEvent(QPaintEvent* event); 32 | }; 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_un_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_un_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_un_64( 12 | const uint64_t *fs, const uint64_t *ft) { 13 | double fs_double, ft_double; 14 | __m128d fs_reg, ft_reg; 15 | uint8_t condition; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | 24 | __asm__ __volatile__( 25 | "comisd %1, %2\n\t" 26 | "setp %%al\n\t" 27 | : "=a" (condition) 28 | : "x" (fs_reg), 29 | "x" (ft_reg) 30 | : "cc" 31 | ); 32 | 33 | return condition; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /os/winapi/timer.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/timer.c: Functions for obtaining the system clock time. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "common.h" 12 | #include "os/winapi/timer.h" 13 | #include 14 | 15 | // Computes the difference, in ns, between two times. 16 | unsigned long long compute_time_difference( 17 | const cen64_time *now, const cen64_time *before) { 18 | return (*now - *before) * 1000000ULL; 19 | } 20 | 21 | // Gets the time from the most monotonic source possible. 22 | // 23 | // XXX: Do NOT use QueryPerformanceCounter! It was never 24 | // meant to be a good source of time, and never will be. 25 | void get_time(cen64_time *t) { 26 | *t = timeGetTime(); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/vnor.s: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/vnor.s 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .include "rsp/gcc/defs.h" 12 | 13 | .text 14 | 15 | .ifdef __MINGW__ 16 | .globl RSP_VNOR 17 | .def RSP_VNOR; .scl 2; .type 32; .endef 18 | .seh_proc RSP_VNOR 19 | .ifndef __VECTORCALL__ 20 | RSP_VNOR: 21 | movdqa (%r8), %xmm0 22 | movdqa (%r9), %xmm1 23 | pxor %xmm2, %xmm2 24 | .endif 25 | .else 26 | .global RSP_VNOR 27 | .type RSP_VNOR, @function 28 | RSP_VNOR: 29 | .endif 30 | 31 | pcmpeqd %xmm2, %xmm2 32 | por %xmm1, %xmm0 33 | pxor %xmm2, %xmm0 34 | movdqa %xmm0, acc_lo 35 | retq 36 | 37 | .ifdef __MINGW__ 38 | .seh_endproc 39 | .else 40 | .size RSP_VNOR,.-RSP_VNOR 41 | .endif 42 | 43 | -------------------------------------------------------------------------------- /os/common/save_file.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/save_file.h 3 | // 4 | // Functions for mapping save files into the address space. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_save_file_h__ 11 | #define __os_save_file_h__ 12 | #include "common.h" 13 | #include 14 | 15 | #ifdef _WIN32 16 | #include 17 | 18 | struct save_file { 19 | void *ptr; 20 | size_t size; 21 | HANDLE mapping; 22 | HANDLE file; 23 | }; 24 | 25 | #else 26 | struct save_file { 27 | void *ptr; 28 | size_t size; 29 | int fd; 30 | }; 31 | #endif 32 | 33 | cen64_cold int close_save_file(const struct save_file *file); 34 | cen64_cold int open_save_file(const char *path, size_t size, struct save_file *file, int *created); 35 | cen64_cold int open_gb_save(const char *path, struct save_file *file); 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /os/sdl/gl_display.h: -------------------------------------------------------------------------------- 1 | #ifndef CEN64_OS_SDL_GL_DISPLAY 2 | #define CEN64_OS_SDL_GL_DISPLAY 3 | #include "gl_common.h" 4 | #include 5 | #include 6 | 7 | 8 | #define CEN64_GL_DISPLAY_BAD (NULL) 9 | typedef int cen64_gl_display; 10 | 11 | // 12 | // Creates a cen64_gl_display (where 'source' selects the display to use). 13 | // 14 | // If source is NULL, it is treated as a don't care. 15 | // 16 | static inline cen64_gl_display cen64_gl_display_create(const char *source) { 17 | SDL_Init(SDL_INIT_VIDEO); 18 | return 1; 19 | } 20 | 21 | // Releases resources allocated by cen64_gl_display_create. 22 | static inline void cen64_gl_display_destroy(cen64_gl_display display) { 23 | SDL_Quit(); 24 | } 25 | 26 | // Returns the number of screens present on a given cen64_gl_display. 27 | static inline int cen64_gl_display_get_num_screens(cen64_gl_display display) { 28 | return 1; 29 | } 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /ai/context.h: -------------------------------------------------------------------------------- 1 | // 2 | // ai/context.h: Sound card context management. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_AI_CONTEXT_H 12 | #define CEN64_AI_CONTEXT_H 13 | #include "common.h" 14 | #include 15 | #include 16 | 17 | struct cen64_ai_context { 18 | ALuint buffers[3]; 19 | ALuint unqueued_buffers; 20 | ALuint cur_frequency; 21 | ALuint frequency; 22 | ALuint source; 23 | 24 | ALCdevice *dev; 25 | ALCcontext *ctx; 26 | }; 27 | 28 | cen64_cold int ai_context_create(struct cen64_ai_context *context); 29 | cen64_cold void ai_context_destroy(struct cen64_ai_context *context); 30 | 31 | int ai_switch_frequency(struct cen64_ai_context *context, ALint frequency); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/vnand.s: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/vnand.s 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .include "rsp/gcc/defs.h" 12 | 13 | .text 14 | 15 | .ifdef __MINGW__ 16 | .globl RSP_VNAND 17 | .def RSP_VNAND; .scl 2; .type 32; .endef 18 | .seh_proc RSP_VNAND 19 | .ifndef __VECTORCALL__ 20 | RSP_VNAND: 21 | movdqa (%r8), %xmm0 22 | movdqa (%r9), %xmm1 23 | pxor %xmm2, %xmm2 24 | .endif 25 | .else 26 | .global RSP_VNAND 27 | .type RSP_VMRG, @function 28 | RSP_VNAND: 29 | .endif 30 | 31 | pcmpeqd %xmm2, %xmm2 32 | pand %xmm1, %xmm0 33 | pxor %xmm2, %xmm0 34 | movdqa %xmm0, acc_lo 35 | retq 36 | 37 | .ifdef __MINGW__ 38 | .seh_endproc 39 | .else 40 | .size RSP_VNAND,.-RSP_VNAND 41 | .endif 42 | 43 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/vnxor.s: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/vnxor.s 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .include "rsp/gcc/defs.h" 12 | 13 | .text 14 | 15 | .ifdef __MINGW__ 16 | .globl RSP_VNXOR 17 | .def RSP_VNXOR; .scl 2; .type 32; .endef 18 | .seh_proc RSP_VNXOR 19 | .ifndef __VECTORCALL__ 20 | RSP_VNXOR: 21 | movdqa (%r8), %xmm0 22 | movdqa (%r9), %xmm1 23 | pxor %xmm2, %xmm2 24 | .endif 25 | .else 26 | .global RSP_VNXOR 27 | .type RSP_VNXOR, @function 28 | RSP_VNXOR: 29 | .endif 30 | 31 | pcmpeqd %xmm2, %xmm2 32 | pxor %xmm1, %xmm0 33 | pxor %xmm2, %xmm0 34 | movdqa %xmm0, acc_lo 35 | retq 36 | 37 | .ifdef __MINGW__ 38 | .seh_endproc 39 | .else 40 | .size RSP_VNXOR,.-RSP_VNXOR 41 | .endif 42 | 43 | -------------------------------------------------------------------------------- /os/winapi/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/posix/main.c: Entry point for WinAPI backend. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "cen64.h" 12 | #include 13 | #include 14 | 15 | // Windows application entry point. 16 | int WINAPI WinMain(HINSTANCE hInstance, 17 | HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { 18 | WSADATA wsa_data = {0}; 19 | WPARAM status = 255; 20 | 21 | if (WSAStartup(MAKEWORD(2, 2), &wsa_data)) { 22 | MessageBox(NULL, "Failed to initialize Winsock.", "CEN64", 23 | MB_OK | MB_ICONEXCLAMATION); 24 | 25 | return status; 26 | } 27 | 28 | status = cen64_main(__argc, (const char **) __argv); 29 | WSACleanup(); 30 | 31 | return status; 32 | } 33 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu.h 3 | // 4 | // Extern declarations for host FPU functions. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_fpu_h__ 11 | #define __os_fpu_h__ 12 | #include "common.h" 13 | #include 14 | 15 | #include "arch/x86_64/fpu/fpu.h" 16 | 17 | #include "os/unix/x86_64/fpu/fpu_cmp_eq_32.h" 18 | #include "os/unix/x86_64/fpu/fpu_cmp_eq_64.h" 19 | #include "os/unix/x86_64/fpu/fpu_cmp_f_32.h" 20 | #include "os/unix/x86_64/fpu/fpu_cmp_f_64.h" 21 | #include "os/unix/x86_64/fpu/fpu_cmp_ole_32.h" 22 | #include "os/unix/x86_64/fpu/fpu_cmp_ole_64.h" 23 | #include "os/unix/x86_64/fpu/fpu_cmp_olt_32.h" 24 | #include "os/unix/x86_64/fpu/fpu_cmp_olt_64.h" 25 | #include "os/unix/x86_64/fpu/fpu_cmp_un_32.h" 26 | #include "os/unix/x86_64/fpu/fpu_cmp_un_64.h" 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/transpose.c: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/transpose.c 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | #include "rsp/cpu.h" 10 | #include "rsp/rsp.h" 11 | 12 | void rsp_ltv(struct rsp *rsp, uint32_t addr, unsigned element, unsigned vt) { 13 | for(int i = 0; i < 8; i++){ 14 | uint16_t slice; 15 | 16 | memcpy(&slice, rsp->mem + addr + (i << 1), sizeof(slice)); 17 | slice = byteswap_16(slice); 18 | 19 | rsp->cp2.regs[vt + i].e[(i - element) & 7] = slice; 20 | } 21 | } 22 | 23 | void rsp_stv(struct rsp *rsp, uint32_t addr, unsigned element, unsigned vt) { 24 | for(int i = 0; i < 8; i++){ 25 | uint16_t slice = rsp->cp2.regs[vt + ((i + element) & 7)].e[i]; 26 | slice = byteswap_16(slice); 27 | 28 | memcpy(rsp->mem + addr + (i << 1), &slice, sizeof(slice)); 29 | } 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /vr4300/opcodes.h: -------------------------------------------------------------------------------- 1 | // 2 | // vr4300/opcodes.h: VR4300 opcode types and info. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __vr4300_opcodes_h__ 12 | #define __vr4300_opcodes_h__ 13 | #include "common.h" 14 | 15 | enum vr4300_opcode_id { 16 | #define X(op) VR4300_OPCODE_##op, 17 | #include "vr4300/opcodes.md" 18 | NUM_VR4300_OPCODES 19 | #undef X 20 | }; 21 | 22 | struct vr4300; 23 | typedef int (*vr4300_function)(struct vr4300 *, 24 | uint32_t, uint64_t, uint64_t); 25 | 26 | extern const vr4300_function vr4300_function_table[NUM_VR4300_OPCODES]; 27 | extern const char *vr4300_opcode_mnemonics[NUM_VR4300_OPCODES]; 28 | 29 | cen64_cold int VR4300_INVALID(struct vr4300 *, 30 | uint32_t, uint64_t, uint64_t); 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /debugger/toggle_window.h: -------------------------------------------------------------------------------- 1 | // 2 | // toggle_window.h: Toggle-able window. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef TOGGLE_WINDOW_H 12 | #define TOGGLE_WINDOW_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | class ToggleWindow : public QWidget { 21 | Q_OBJECT 22 | 23 | QAction *toggleAction; 24 | 25 | QStateMachine windowMachine; 26 | QState windowHiddenState; 27 | QState windowExposedState; 28 | 29 | virtual void closeEvent(QCloseEvent *event); 30 | 31 | public: 32 | explicit ToggleWindow(const QString &windowTitle, 33 | QAction *toggleAction, bool initiallyVisible); 34 | 35 | ~ToggleWindow(); 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_eq_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_eq_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_eq_32( 12 | const uint32_t *fs, const uint32_t *ft) { 13 | float fs_float, ft_float; 14 | __m128 fs_reg, ft_reg; 15 | uint8_t condition; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | 24 | __asm__ __volatile__( 25 | "comiss %1, %2\n\t" 26 | "sete %%dl\n\t" 27 | "setnp %%al\n\t" 28 | "and %%dl, %%al\n\t" 29 | : "=a" (condition) 30 | : "x" (fs_reg), 31 | "x" (ft_reg) 32 | : "dl", "cc" 33 | ); 34 | 35 | return condition; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_ole_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_ole_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_ole_32( 12 | const uint32_t *fs, const uint32_t *ft) { 13 | float fs_float, ft_float; 14 | __m128 fs_reg, ft_reg; 15 | uint8_t condition; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | 24 | __asm__ __volatile__( 25 | "comiss %1, %2\n\t" 26 | "setae %%dl\n\t" 27 | "setnp %%al\n\t" 28 | "and %%dl, %%al\n\t" 29 | : "=a" (condition) 30 | : "x" (fs_reg), 31 | "x" (ft_reg) 32 | : "dl", "cc" 33 | ); 34 | 35 | return condition; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_olt_32.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_olt_32.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_olt_32( 12 | const uint32_t *fs, const uint32_t *ft) { 13 | float fs_float, ft_float; 14 | __m128 fs_reg, ft_reg; 15 | uint8_t condition; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_float, fs, sizeof(fs_float)); 19 | memcpy(&ft_float, ft, sizeof(ft_float)); 20 | 21 | fs_reg = _mm_set_ss(fs_float); 22 | ft_reg = _mm_set_ss(ft_float); 23 | 24 | __asm__ __volatile__( 25 | "comiss %1, %2\n\t" 26 | "seta %%dl\n\t" 27 | "setnp %%al\n\t" 28 | "and %%dl, %%al\n\t" 29 | : "=a" (condition) 30 | : "x" (fs_reg), 31 | "x" (ft_reg) 32 | : "dl", "cc" 33 | ); 34 | 35 | return condition; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /dd/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // dd/registers.md: DD register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef DD_REGISTER_LIST 12 | #define DD_REGISTER_LIST \ 13 | X(DD_ASIC_DATA) \ 14 | X(DD_ASIC_MISC_REG) \ 15 | X(DD_ASIC_CMD_STATUS) \ 16 | X(DD_ASIC_CUR_TK) \ 17 | X(DD_ASIC_BM_STATUS_CTL) \ 18 | X(DD_ASIC_ERR_SECTOR) \ 19 | X(DD_ASIC_SEQ_STATUS) \ 20 | X(DD_ASIC_CUR_SECTOR) \ 21 | X(DD_ASIC_HARD_RESET) \ 22 | X(DD_ASIC_C1_S0) \ 23 | X(DD_ASIC_HOST_SECBYTE) \ 24 | X(DD_ASIC_C1_S2) \ 25 | X(DD_ASIC_SEC_BYTE) \ 26 | X(DD_ASIC_C1_S4) \ 27 | X(DD_ASIC_C1_S6) \ 28 | X(DD_ASIC_CUR_ADDR) \ 29 | X(DD_ASIC_ID_REG) \ 30 | X(DD_ASIC_TEST_REG) \ 31 | X(DD_ASIC_TEST_PIN_SEL) 32 | #endif 33 | 34 | DD_REGISTER_LIST 35 | 36 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_eq_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_eq_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_eq_64( 12 | const uint64_t *fs, const uint64_t *ft) { 13 | double fs_double, ft_double; 14 | __m128d fs_reg, ft_reg; 15 | uint8_t condition; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | 24 | __asm__ __volatile__( 25 | "comisd %1, %2\n\t" 26 | "sete %%dl\n\t" 27 | "setnp %%al\n\t" 28 | "and %%dl, %%al\n\t" 29 | : "=a" (condition) 30 | : "x" (fs_reg), 31 | "x" (ft_reg) 32 | : "dl", "cc" 33 | ); 34 | 35 | return condition; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_ole_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_ole_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_ole_64( 12 | const uint64_t *fs, const uint64_t *ft) { 13 | double fs_double, ft_double; 14 | __m128d fs_reg, ft_reg; 15 | uint8_t condition; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | 24 | __asm__ __volatile__( 25 | "comisd %1, %2\n\t" 26 | "setae %%dl\n\t" 27 | "setnp %%al\n\t" 28 | "and %%dl, %%al\n\t" 29 | : "=a" (condition) 30 | : "x" (fs_reg), 31 | "x" (ft_reg) 32 | : "dl", "cc" 33 | ); 34 | 35 | return condition; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /os/unix/x86_64/fpu/fpu_cmp_olt_64.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/x86_64/fpu/fpu_cmp_olt_64.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | static inline uint8_t fpu_cmp_olt_64( 12 | const uint64_t *fs, const uint64_t *ft) { 13 | double fs_double, ft_double; 14 | __m128d fs_reg, ft_reg; 15 | uint8_t condition; 16 | 17 | // Prevent aliasing. 18 | memcpy(&fs_double, fs, sizeof(fs_double)); 19 | memcpy(&ft_double, ft, sizeof(ft_double)); 20 | 21 | fs_reg = _mm_set_sd(fs_double); 22 | ft_reg = _mm_set_sd(ft_double); 23 | 24 | __asm__ __volatile__( 25 | "comisd %1, %2\n\t" 26 | "seta %%dl\n\t" 27 | "setnp %%al\n\t" 28 | "and %%dl, %%al\n\t" 29 | : "=a" (condition) 30 | : "x" (fs_reg), 31 | "x" (ft_reg) 32 | : "dl", "cc" 33 | ); 34 | 35 | return condition; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /rsp/interface.h: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/interface.h: RSP interface. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __rsp_interface_h__ 12 | #define __rsp_interface_h__ 13 | #include "common.h" 14 | 15 | void rsp_dma_read(struct rsp *rsp); 16 | void rsp_dma_write(struct rsp *rsp); 17 | 18 | int read_sp_mem(void *opaque, uint32_t address, uint32_t *word); 19 | int read_sp_regs(void *opaque, uint32_t address, uint32_t *word); 20 | int read_sp_regs2(void *opaque, uint32_t address, uint32_t *word); 21 | int write_sp_mem(void *opaque, uint32_t address, uint32_t word, uint32_t dqm); 22 | int write_sp_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm); 23 | int write_sp_regs2(void *opaque, uint32_t address, uint32_t word, uint32_t dqm); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /device/netapi.h: -------------------------------------------------------------------------------- 1 | // 2 | // device/netapi.h: CEN64 device network API. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __device_netapi_h__ 12 | #define __device_netapi_h__ 13 | #include "common.h" 14 | 15 | struct device; 16 | 17 | enum netapi_debug_request_type { 18 | NETAPI_DEBUG_ERROR, 19 | NETAPI_DEBUG_GET_PROTOCOL_VERSION, 20 | NETAPI_DEBUG_GET_VR4300_REGS, 21 | }; 22 | 23 | struct netapi_debug_request { 24 | uint32_t magic; 25 | uint32_t seq_id; 26 | uint32_t length; 27 | 28 | enum netapi_debug_request_type type; 29 | uint8_t data[]; 30 | }; 31 | 32 | cen64_cold void netapi_close_connection(int csfd); 33 | cen64_cold int netapi_open_connection(void); 34 | 35 | cen64_cold int netapi_debug_wait(int sfd, struct cen64_device *device); 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /device/cart_db.h: -------------------------------------------------------------------------------- 1 | // 2 | // device/cart_db.h: Cart database. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __device_cart_db_h__ 12 | #define __device_cart_db_h__ 13 | 14 | enum cart_db_save_type { 15 | CART_DB_SAVE_TYPE_NONE, 16 | CART_DB_SAVE_TYPE_EEPROM_4KBIT, 17 | CART_DB_SAVE_TYPE_EEPROM_16KBIT, 18 | CART_DB_SAVE_TYPE_FLASH_1MBIT, 19 | CART_DB_SAVE_TYPE_SRAM_256KBIT, 20 | CART_DB_SAVE_TYPE_SRAM_768KBIT, 21 | CART_DB_SAVE_TYPE_SRAM_1MBIT, 22 | }; 23 | 24 | struct cart_db_entry { 25 | const char *rom_id; 26 | const char *regions; 27 | enum cart_db_save_type save_type; 28 | const char *description; 29 | }; 30 | 31 | cen64_cold const struct cart_db_entry *cart_db_get_entry(const uint8_t *rom); 32 | cen64_cold bool cart_db_is_well_formed(void); 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /os/posix/timer.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/posix/timer.h: Functions for obtaining the system clock time. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_POSIX_TIMER 12 | #define CEN64_OS_POSIX_TIMER 13 | #include "common.h" 14 | 15 | #define NS_PER_SEC 1000000000ULL 16 | 17 | #if defined(CLOCK_MONOTONIC_PRECISE) 18 | #define GETTIME_SOURCE CLOCK_MONOTONIC_PRECISE 19 | #else 20 | #define GETTIME_SOURCE CLOCK_MONOTONIC_RAW 21 | #endif 22 | 23 | #ifdef __APPLE__ 24 | #include 25 | typedef struct timeval cen64_time; 26 | 27 | #else 28 | #include 29 | typedef struct timespec cen64_time; 30 | #endif 31 | 32 | cen64_cold unsigned long long compute_time_difference( 33 | const cen64_time *now, const cen64_time *before); 34 | 35 | cen64_cold void get_time(cen64_time *t); 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /os/x11/gl_common.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/x11/gl_common.h: Common X11/OpenGL header. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_X11_GL_COMMON 12 | #define CEN64_OS_X11_GL_COMMON 13 | #include "common.h" 14 | #include 15 | #include 16 | 17 | enum cen64_gl_context_type { 18 | CEN64_GL_CONTEXT_TYPE_RGBA = GLX_RGBA_BIT, 19 | CEN64_GL_CONTEXT_TYPE_COLOR_INDEX = GLX_COLOR_INDEX_BIT 20 | }; 21 | 22 | enum cen64_gl_drawable_type { 23 | CEN64_GL_DRAWABLE_TYPE_WINDOW = GLX_WINDOW_BIT, 24 | CEN64_GL_DRAWABLE_TYPE_BITMAP = GLX_PIXMAP_BIT 25 | }; 26 | 27 | enum cen64_gl_layer_type { 28 | CEN64_GL_LAYER_TYPE_DEFAULT = 0, 29 | CEN64_GL_LAYER_TYPE_OVERLAY = 1, 30 | CEN64_GL_LAYER_TYPE_UNDERLAY = 2 31 | }; 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /rsp/opcodes.md: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/opcodes.md: RSP opcode types and info. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef RSP_OPCODE_TABLE 12 | #define RSP_OPCODE_TABLE X(INVALID) \ 13 | X(ADDU) X(ADDIU) X(AND) X(ANDI) X(BEQ) X(BGEZ) X(BGEZAL) X(BGTZ) \ 14 | X(BLEZ) X(BLTZ) X(BLTZAL) X(BNE) X(BREAK) X(CFC2) X(CTC2) X(J) X(JAL) \ 15 | X(JALR) X(JR) X(LB) X(LBU) X(LBV) X(LDV) X(LFV) X(LH) X(LHU) X(LHV) \ 16 | X(LLV) X(LPV) X(LQV) X(LRV) X(LSV) X(LTV) X(LUI) X(LUV) X(LW) X(MFC0) \ 17 | X(MFC2) X(MTC0) X(MTC2) X(NOP) X(NOR) X(OR) X(ORI) X(SB) X(SBV) X(SDV) \ 18 | X(SFV) X(SH) X(SHV) X(SLL) X(SLLV) X(SLT) X(SLTI) X(SLTIU) X(SLTU) \ 19 | X(SLV) X(SPV) X(SQV) X(SRA) X(SRAV) X(SRL) X(SRLV) X(SRV) X(SSV) X(STV) \ 20 | X(SUBU) X(SUV) X(SW) X(SWV) X(XOR) X(XORI) 21 | #endif 22 | 23 | RSP_OPCODE_TABLE 24 | 25 | -------------------------------------------------------------------------------- /debugger/rsp_window.h: -------------------------------------------------------------------------------- 1 | // 2 | // rsp_window.h: RSP view window. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef RSP_WINDOW_H 12 | #define RSP_WINDOW_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include "disassembly_view.h" 18 | #include "memory_view.h" 19 | #include "register_view.h" 20 | #include "toggle_window.h" 21 | 22 | class RSPWindow : public ToggleWindow { 23 | Q_OBJECT 24 | QGridLayout layout; 25 | QGridLayout addressLayout; 26 | 27 | DisassemblyView disassemblyView; 28 | MemoryView memoryView; 29 | RegisterView registerView; 30 | 31 | QWidget addressWidget; 32 | QLabel addressLabel; 33 | QLineEdit addressLine; 34 | 35 | public: 36 | explicit RSPWindow(QAction *toggleAction, bool initiallyVisible); 37 | ~RSPWindow(); 38 | }; 39 | 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /os/sdl/gl_context.h: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 4 | // Copyright (C) 2015, Tyler J. Stachecki. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef CEN64_OS_SDL_GL_CONTEXT 11 | #define CEN64_OS_SDL_GL_CONTEXT 12 | #include "gl_common.h" 13 | #include "gl_display.h" 14 | #include "gl_screen.h" 15 | #include "gl_window.h" 16 | #include 17 | 18 | #define CEN64_GL_CONTEXT_BAD (NULL) 19 | typedef SDL_GLContext cen64_gl_context; 20 | 21 | // Creates a cen64_gl_context and binds it to the cen64_gl_window. 22 | static inline cen64_gl_context cen64_gl_context_create(cen64_gl_window window) 23 | { 24 | return SDL_GL_CreateContext(window->window); 25 | } 26 | 27 | // Unbinds the cen64_gl_context from the window and releases the context. 28 | static inline void cen64_gl_context_destroy( 29 | cen64_gl_context context, cen64_gl_window window) 30 | { 31 | SDL_GL_DeleteContext(window->window); 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /common/hash_table.h: -------------------------------------------------------------------------------- 1 | // 2 | // common/hash_table.h 3 | // 4 | // Simple hash table implementation 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __common_hastable_h__ 11 | #define __common_hastable_h__ 12 | #include "common.h" 13 | 14 | struct hash_table_entry { 15 | bool used; 16 | unsigned long key; 17 | unsigned long value; 18 | }; 19 | 20 | struct hash_table { 21 | struct hash_table_entry* entries; 22 | int capacity; 23 | int size; 24 | }; 25 | 26 | 27 | void hash_table_init(struct hash_table* table, int capacity); 28 | void hash_table_free(struct hash_table* table); 29 | int hash_table_size(struct hash_table* table); 30 | int hash_table_capacity(struct hash_table* table); 31 | 32 | bool hash_table_get(struct hash_table* table, unsigned long key, unsigned long *value); 33 | void hash_table_set(struct hash_table* table, unsigned long key, unsigned long value); 34 | void hash_table_delete(struct hash_table* table, unsigned long key); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /os/winapi/gl_common.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/gl_common.h: Common WinAPI/OpenGL header. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_WINAPI_GL_COMMON 12 | #define CEN64_OS_WINAPI_GL_COMMON 13 | #include "common.h" 14 | #include 15 | #include 16 | #include 17 | 18 | enum cen64_gl_context_type { 19 | CEN64_GL_CONTEXT_TYPE_RGBA = PFD_TYPE_RGBA, 20 | CEN64_GL_CONTEXT_TYPE_COLOR_INDEX = PFD_TYPE_COLORINDEX 21 | }; 22 | 23 | enum cen64_gl_drawable_type { 24 | CEN64_GL_DRAWABLE_TYPE_WINDOW = PFD_DRAW_TO_WINDOW, 25 | CEN64_GL_DRAWABLE_TYPE_BITMAP = PFD_DRAW_TO_BITMAP 26 | }; 27 | 28 | enum cen64_gl_layer_type { 29 | CEN64_GL_LAYER_TYPE_DEFAULT = PFD_MAIN_PLANE, 30 | CEN64_GL_LAYER_TYPE_OVERLAY = PFD_OVERLAY_PLANE, 31 | CEN64_GL_LAYER_TYPE_UNDERLAY = PFD_UNDERLAY_PLANE 32 | }; 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /os/windows/x86_64/fpu/fpu.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/windows/x86_64/fpu/fpu.h 3 | // 4 | // Extern declarations for host FPU functions. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_fpu_h__ 11 | #define __os_fpu_h__ 12 | #include "common.h" 13 | #include 14 | 15 | #include "arch/x86_64/fpu/fpu.h" 16 | 17 | uint8_t fpu_cmp_eq_32(const uint32_t *fs, const uint32_t *ft); 18 | uint8_t fpu_cmp_eq_64(const uint64_t *fs, const uint64_t *ft); 19 | uint8_t fpu_cmp_f_32(const uint32_t *fs, const uint32_t *ft); 20 | uint8_t fpu_cmp_f_64(const uint64_t *fs, const uint64_t *ft); 21 | uint8_t fpu_cmp_ole_32(const uint32_t *fs, const uint32_t *ft); 22 | uint8_t fpu_cmp_ole_64(const uint64_t *fs, const uint64_t *ft); 23 | uint8_t fpu_cmp_olt_32(const uint32_t *fs, const uint32_t *ft); 24 | uint8_t fpu_cmp_olt_64(const uint64_t *fs, const uint64_t *ft); 25 | uint8_t fpu_cmp_un_32(const uint32_t *fs, const uint32_t *ft); 26 | uint8_t fpu_cmp_un_64(const uint64_t *fs, const uint64_t *ft); 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /debugger/vr4300_window.h: -------------------------------------------------------------------------------- 1 | // 2 | // vr4300_window.h: VR4300 view window. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef VR4300_WINDOW_H 12 | #define VR4300_WINDOW_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include "disassembly_view.h" 18 | #include "memory_view.h" 19 | #include "register_view.h" 20 | #include "toggle_window.h" 21 | 22 | class VR4300Window : public ToggleWindow { 23 | Q_OBJECT 24 | QGridLayout layout; 25 | QGridLayout addressLayout; 26 | 27 | DisassemblyView disassemblyView; 28 | MemoryView memoryView; 29 | RegisterView registerView; 30 | 31 | QWidget addressWidget; 32 | QLabel vaddressLabel; 33 | QLabel paddressLabel; 34 | QLineEdit vaddressLine; 35 | QLineEdit paddressLine; 36 | 37 | public: 38 | explicit VR4300Window(QAction *toggleAction, bool initiallyVisible); 39 | ~VR4300Window(); 40 | }; 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /os/common/gl_hints.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/common/gl_hints.h: OpenGL configuration hints. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_COMMON_GL_HINTS 12 | #define CEN64_OS_COMMON_GL_HINTS 13 | #include "gl_common.h" 14 | 15 | struct cen64_gl_hints { 16 | enum cen64_gl_context_type context_type; 17 | enum cen64_gl_drawable_type drawable_type; 18 | int double_buffered; 19 | int stereoscopic; 20 | 21 | // Color depths. 22 | int rgb_color_depth; 23 | int alpha_color_depth; 24 | 25 | // Buffer sizes, counts. 26 | int depth_buffer_size; 27 | int num_aux_buffers; 28 | int stencil_buffer_size; 29 | 30 | // Accumulation buffer bits. 31 | int accum_buffer_red_bits; 32 | int accum_buffer_green_bits; 33 | int accum_buffer_blue_bits; 34 | int accum_buffer_alpha_bits; 35 | }; 36 | 37 | typedef struct cen64_gl_hints cen64_gl_hints; 38 | extern const cen64_gl_hints cen64_default_gl_hints; 39 | 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /arch/x86_64/tlb/tlb.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/tlb/tlb.h: Translation lookaside buffer. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __arch_tlb_h__ 12 | #define __arch_tlb_h__ 13 | #include "common.h" 14 | #include 15 | 16 | union aligned_tlb_data { 17 | __m128i __align[8]; 18 | uint32_t data[32]; 19 | }; 20 | 21 | struct cen64_tlb { 22 | union aligned_tlb_data page_mask; 23 | union aligned_tlb_data vpn2; 24 | uint8_t global[32]; 25 | uint8_t asid[32]; 26 | uint8_t valid[32]; 27 | }; 28 | 29 | cen64_cold void tlb_init(struct cen64_tlb *tlb); 30 | 31 | cen64_hot unsigned tlb_probe(const struct cen64_tlb *tlb, uint64_t vpn2, 32 | uint8_t vasid, unsigned *index); 33 | 34 | int tlb_read(const struct cen64_tlb *tlb, unsigned index, uint64_t *entry_hi); 35 | int tlb_write(struct cen64_tlb *tlb, unsigned index, uint64_t entry_hi, 36 | uint64_t entry_lo_0, uint64_t entry_lo_1, uint32_t page_mask); 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /debugger/register_view.h: -------------------------------------------------------------------------------- 1 | // 2 | // register_view.h: CEN64D register view (MVC). 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef REGISTER_VIEW_H 12 | #define REGISTER_VIEW_H 13 | #include "register_model.h" 14 | #include 15 | #include 16 | #include 17 | 18 | class RegisterView : public QAbstractScrollArea { 19 | Q_OBJECT 20 | 21 | RegisterModel model; 22 | const char **registers; 23 | unsigned numRegisters; 24 | 25 | unsigned fontWidth, fontHeight; 26 | unsigned longestMnemonic, octets; 27 | char formatstr[16]; 28 | 29 | public: 30 | explicit RegisterView(const char **regs, unsigned num_regs, unsigned octets); 31 | virtual ~RegisterView(); 32 | 33 | unsigned getMaximumHeight() const; 34 | unsigned getMaximumWidth() const; 35 | 36 | RegisterModel& getModel(); 37 | void paintEvent(QPaintEvent* event); 38 | void resizeEvent(QResizeEvent *event); 39 | }; 40 | 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /os/sdl/gl_screen.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/sdl/gl_screen.h: SDL screen definitions. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_SDL_GL_SCREEN 12 | #define CEN64_OS_SDL_GL_SCREEN 13 | #include "gl_common.h" 14 | #include 15 | 16 | #define CEN64_GL_SCREEN_BAD (-1) 17 | typedef int cen64_gl_screen; 18 | 19 | // 20 | // Creates a cen64_gl_screen object on a given cen64_gl_display. 21 | // 22 | // 'which' specifies which screen on a display to use (from 0 to 23 | // num_screens - 1). If 'which' is less than zero, it is treated as 24 | // a don't care. 25 | // 26 | // On error, CEN64_GL_SCREEN_BAD is returned. 27 | // 28 | static inline cen64_gl_screen cen64_gl_screen_create( 29 | cen64_gl_display display, int which) { 30 | // Not used with SDL 31 | return 0; 32 | } 33 | 34 | // 35 | // Releases resources allocated by cen64_screen_create. 36 | // 37 | static inline void cen64_gl_screen_destroy(cen64_gl_screen screen) {} 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /os/winapi/alloc.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/alloc.h: Low-level WinAPI-based allocators. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "common.h" 12 | #include "os/common/alloc.h" 13 | #include 14 | #include 15 | 16 | // Allocates a block of (R/W/X) memory. 17 | void *cen64_alloc(struct cen64_mem *m, size_t size, bool exec) { 18 | int access = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 19 | 20 | if ((m->ptr = VirtualAlloc(NULL, size, 21 | MEM_COMMIT | MEM_RESERVE, access)) == NULL) 22 | return NULL; 23 | 24 | m->size = size; 25 | return m->ptr; 26 | } 27 | 28 | // Releases resources acquired by cen64_alloc_init. 29 | void cen64_alloc_cleanup(void) { 30 | } 31 | 32 | // Initializes CEN64's low-level allocator. 33 | int cen64_alloc_init(void) { 34 | return 0; 35 | } 36 | 37 | // Releases resources acquired by cen64_alloc. 38 | void cen64_free(struct cen64_mem *m) { 39 | VirtualFree(m->ptr, 0, MEM_RELEASE); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vmulh.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmulh.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vmadh_vmudh(uint32_t iw, __m128i vs, __m128i vt, 11 | __m128i zero, __m128i *acc_lo, __m128i *acc_md, __m128i *acc_hi) { 12 | __m128i lo, hi, overflow_mask; 13 | 14 | lo = _mm_mullo_epi16(vs, vt); 15 | hi = _mm_mulhi_epi16(vs, vt); 16 | 17 | // VMADH 18 | if (iw & 0x8) { 19 | // Tricky part: start accumulate everything. 20 | // Get/keep the carry as we'll add it in later. 21 | overflow_mask = _mm_adds_epu16(*acc_md, lo); 22 | *acc_md = _mm_add_epi16(*acc_md, lo); 23 | 24 | overflow_mask = _mm_cmpeq_epi16(*acc_md, overflow_mask); 25 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 26 | 27 | hi = _mm_sub_epi16(hi, overflow_mask); 28 | *acc_hi = _mm_add_epi16(*acc_hi, hi); 29 | } 30 | 31 | // VMUDH 32 | else { 33 | *acc_lo = zero; 34 | *acc_md = lo; 35 | *acc_hi = hi; 36 | } 37 | 38 | return rsp_sclamp_acc_tomd(*acc_md, *acc_hi); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /gdb/gdb.h: -------------------------------------------------------------------------------- 1 | // 2 | // gdb.h: gdb remote debugger implementation 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef _gdb_h__ 12 | #define _gdb_h__ 13 | #include "common.h" 14 | #include "vr4300/interface.h" 15 | #include "device/device.h" 16 | 17 | #define MAX_GDB_PACKET_SIZE 0x4000 18 | 19 | enum gdb_flags { 20 | GDB_FLAGS_INITIAL = 0x1, 21 | GDB_FLAGS_CONNECTED = 0x2, 22 | GDB_FLAGS_PAUSED = 0x4, 23 | }; 24 | 25 | struct gdb { 26 | int socket; 27 | int client; 28 | struct cen64_device* device; 29 | int pending_data; 30 | char packet_buffer[MAX_GDB_PACKET_SIZE*2]; 31 | char output_buffer[MAX_GDB_PACKET_SIZE]; 32 | int flags; 33 | cen64_thread thread; 34 | cen64_mutex client_mutex; 35 | cen64_cv client_semaphore; 36 | }; 37 | 38 | cen64_cold struct gdb* gdb_alloc(); 39 | cen64_cold bool gdb_init(struct gdb* gdb, struct cen64_device* device, const char* host); 40 | cen64_cold void gdb_destroy(struct gdb* gdb); 41 | 42 | #endif -------------------------------------------------------------------------------- /os/winapi/gl_display.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/gl_display.h: WinAPI display definitions. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_WINAPI_GL_DISPLAY 12 | #define CEN64_OS_WINAPI_GL_DISPLAY 13 | #include "gl_common.h" 14 | 15 | #define CEN64_GL_DISPLAY_BAD (-1) 16 | typedef int cen64_gl_display; 17 | 18 | // 19 | // Creates a cen64_gl_display (where 'source' selects the display to use). 20 | // 21 | // If source is NULL, it is treated as a don't care. 22 | // 23 | static inline cen64_gl_display cen64_gl_display_create(const char *source) { 24 | return 0; // TODO 25 | } 26 | 27 | // 28 | // Releases resources allocated by cen64_gl_display_create. 29 | // 30 | static inline void cen64_gl_display_destroy(cen64_gl_display display) { 31 | } 32 | 33 | // 34 | // Returns the number of screens present on a given cen64_gl_display. 35 | // 36 | static inline int cen64_gl_display_get_num_screens(cen64_gl_display display) { 37 | return 1; // TODO 38 | } 39 | 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /device/options.h: -------------------------------------------------------------------------------- 1 | // 2 | // options.h: Common CEN64 simulation options. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __options_h__ 12 | #define __options_h__ 13 | #include "common.h" 14 | 15 | struct cen64_options { 16 | const char *ddipl_path; 17 | const char *ddrom_path; 18 | const char *pifrom_path; 19 | const char *cart_path; 20 | const char *debugger_addr; 21 | 22 | const char *eeprom_path; 23 | size_t eeprom_size; 24 | const char *sram_path; 25 | size_t sram_size; 26 | const char *flashram_path; 27 | int is_viewer_output; 28 | 29 | struct controller *controller; 30 | 31 | bool enable_debugger; 32 | bool enable_profiling; 33 | bool multithread; 34 | bool no_audio; 35 | bool no_video; 36 | }; 37 | 38 | extern const struct cen64_options default_cen64_options; 39 | 40 | cen64_cold int parse_options(struct cen64_options *, int argc, const char *argv[]); 41 | cen64_cold void print_command_line_usage(const char *invokation_string); 42 | 43 | #endif 44 | 45 | -------------------------------------------------------------------------------- /cmake/Modules/FindOpenGLXQuartz.cmake: -------------------------------------------------------------------------------- 1 | # Finds OpenGL for XQuartz on OSX. Sets the same flags as the default 2 | # FindOpenGL.cmake module. Necessary because the default module will 3 | # only find the system OpenGL framework, which does not work with 4 | # XQuartz. 5 | 6 | find_library(OPENGL_gl_LIBRARY 7 | NAMES GL 8 | PATHS /opt/X11/lib 9 | DOC "OpenGL lib for XQuartz on OSX" 10 | ) 11 | find_library(OPENGL_glu_LIBRARY 12 | NAMES GLU 13 | PATHS /opt/X11/lib 14 | DOC "GLU lib for XQuartz on OSX" 15 | ) 16 | find_path(OPENGL_INCLUDE_DIR 17 | NAMES GL/gl.h 18 | PATHS /opt/X11/include 19 | DOC "Include for OpenGL for XQuartz on OSX" 20 | ) 21 | 22 | if(OPENGL_gl_LIBRARY) 23 | set(OPENGL_FOUND TRUE) 24 | endif(OPENGL_gl_LIBRARY) 25 | 26 | if(OPENGL_glu_LIBRARY) 27 | set(OPENGL_GLU_FOUND TRUE) 28 | endif(OPENGL_glu_LIBRARY) 29 | 30 | set(OPENGL_LIBRARIES ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) 31 | set(_OpenGL_REQUIRED_VARS OPENGL_gl_LIBRARY OPENGL_INCLUDE_DIR) 32 | 33 | include(FindPackageHandleStandardArgs) 34 | find_package_handle_standard_args(OpenGLXQuartz REQUIRED_VARS ${_OpenGL_REQUIRED_VARS}) 35 | 36 | mark_as_advanced( 37 | OPENGL_INCLUDE_DIR 38 | OPENGL_glu_LIBRARY 39 | OPENGL_gl_LIBRARY 40 | ) 41 | -------------------------------------------------------------------------------- /os/posix/timer.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/posix/timer.c: Functions for obtaining the system clock time. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "common.h" 12 | #include "os/posix/timer.h" 13 | #include 14 | #include 15 | 16 | // NS_PER_USEC is not defined on OS X 17 | #ifndef NS_PER_USEC 18 | #define NS_PER_USEC 1000 19 | #endif 20 | 21 | // Computes the difference, in ns, between two times. 22 | unsigned long long compute_time_difference( 23 | const cen64_time *now, const cen64_time *before) { 24 | #if defined(__APPLE__) 25 | return (now->tv_sec - before->tv_sec) * NS_PER_SEC + 26 | (now->tv_usec - before->tv_usec) * NS_PER_USEC; 27 | #else 28 | return (now->tv_sec - before->tv_sec) * NS_PER_SEC + 29 | (now->tv_nsec - before->tv_nsec); 30 | #endif 31 | } 32 | 33 | // Gets the time from the most monotonic source possible. 34 | void get_time(cen64_time *t) { 35 | #if defined(__APPLE__) 36 | gettimeofday(t, NULL); 37 | #else 38 | clock_gettime(GETTIME_SOURCE, t); 39 | #endif 40 | } 41 | 42 | -------------------------------------------------------------------------------- /os/winapi/console.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/console.c 3 | // 4 | // Functions for manipulating the console. 5 | // 6 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 7 | // Copyright (C) 2015, Tyler J. Stachecki. 8 | // 9 | // This file is subject to the terms and conditions defined in 10 | // 'LICENSE', which is part of this source code package. 11 | // 12 | 13 | #include "cen64.h" 14 | #include 15 | 16 | bool has_console(void) { 17 | DWORD procId; 18 | DWORD count = GetConsoleProcessList(&procId, 1); 19 | return (count >= 2); 20 | } 21 | 22 | void check_start_from_explorer(void) { 23 | if (has_console()) return; 24 | system("cmd /S /K \"echo cen64 is a command-line application, don't double-click on it! & echo: & echo Type ^\"cen64.exe^\" from this prompt to get the usage.\""); 25 | exit(0); 26 | } 27 | 28 | 29 | // "Hides" the console window (after waiting for input). 30 | void hide_console(void) { 31 | printf("\n"); 32 | system("PAUSE"); 33 | 34 | FreeConsole(); 35 | } 36 | 37 | // "Unhides" the console window. 38 | void show_console(void) { 39 | if (AttachConsole(ATTACH_PARENT_PROCESS) == 0) 40 | AllocConsole(); 41 | 42 | freopen("CONOUT$", "wb", stdout); 43 | freopen("CONOUT$", "wb", stderr); 44 | } 45 | -------------------------------------------------------------------------------- /os/x11/gl_screen.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/x11/gl_screen.h: X11 screen definitions. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_X11_GL_SCREEN 12 | #define CEN64_OS_X11_GL_SCREEN 13 | #include "gl_common.h" 14 | #include 15 | 16 | #define CEN64_GL_SCREEN_BAD (-1) 17 | typedef int cen64_gl_screen; 18 | 19 | // 20 | // Creates a cen64_gl_screen object on a given cen64_gl_display. 21 | // 22 | // 'which' specifies which screen on a display to use (from 0 to 23 | // num_screens - 1). If 'which' is less than zero, it is treated as 24 | // a don't care. 25 | // 26 | // On error, CEN64_GL_SCREEN_BAD is returned. 27 | // 28 | static inline cen64_gl_screen cen64_gl_screen_create( 29 | cen64_gl_display display, int which) { 30 | if (which >= 0) 31 | return XScreenCount(display) > which ? which : CEN64_GL_SCREEN_BAD; 32 | 33 | return XDefaultScreen(display); 34 | } 35 | 36 | // Releases resources allocated by cen64_screen_create. 37 | static inline void cen64_gl_screen_destroy(cen64_gl_screen screen) {} 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /os/winapi/gl_screen.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/gl_screen.h: WinAPI screen definitions. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_WINAPI_GL_SCREEN 12 | #define CEN64_OS_WINAPI_GL_SCREEN 13 | #include "gl_common.h" 14 | #include 15 | #include 16 | 17 | #define CEN64_GL_SCREEN_BAD (NULL) 18 | typedef HWND cen64_gl_screen; 19 | 20 | // 21 | // Creates a cen64_gl_screen object on a given cen64_gl_display. 22 | // 23 | // 'which' specifies which screen on a display to use (from 0 to 24 | // num_screens - 1). If 'which' is less than zero, it is treated as 25 | // a don't care. 26 | // 27 | // On error, CEN64_GL_SCREEN_BAD is returned. 28 | // 29 | static inline cen64_gl_screen cen64_gl_screen_create( 30 | cen64_gl_display display, int which) { 31 | if (which >= 0) 32 | return NULL; // TODO 33 | 34 | return GetDesktopWindow(); 35 | } 36 | 37 | // 38 | // Releases resources allocated by cen64_screen_create. 39 | // 40 | static inline void cen64_gl_screen_destroy(cen64_gl_screen screen) {} 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /os/x11/gl_display.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/x11/gl_display.h: X11 display definitions. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_X11_GL_DISPLAY 12 | #define CEN64_OS_X11_GL_DISPLAY 13 | #include "gl_common.h" 14 | #include 15 | #include 16 | 17 | #define CEN64_GL_DISPLAY_BAD (NULL) 18 | typedef Display *cen64_gl_display; 19 | 20 | // 21 | // Creates a cen64_gl_display (where 'source' selects the display to use). 22 | // 23 | // If source is NULL, it is treated as a don't care. 24 | // 25 | static inline cen64_gl_display cen64_gl_display_create(const char *source) { 26 | return XOpenDisplay(source); 27 | } 28 | 29 | // Releases resources allocated by cen64_gl_display_create. 30 | static inline void cen64_gl_display_destroy(cen64_gl_display display) { 31 | XCloseDisplay(display); 32 | } 33 | 34 | // Returns the number of screens present on a given cen64_gl_display. 35 | static inline int cen64_gl_display_get_num_screens(cen64_gl_display display) { 36 | return XScreenCount(display); 37 | } 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /os/posix/rom_file.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/unix/rom_file.c 3 | // 4 | // Functions for mapping ROM images into the address space. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #include "rom_file.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | // Unmaps a ROM image from the host address space. 19 | int close_rom_file(const struct rom_file *file) { 20 | return munmap(file->ptr, file->size); 21 | } 22 | 23 | // Maps a ROM into the host address space, returns a pointer. 24 | int open_rom_file(const char *path, struct rom_file *file) { 25 | struct stat sb; 26 | void *ptr; 27 | int fd; 28 | 29 | // Open the file for read only. 30 | if ((fd = open(path, O_RDONLY)) == -1) 31 | return -1; 32 | 33 | // Get the file's size, map it into the address space. 34 | if (fstat(fd, &sb) == -1 || (ptr = mmap(NULL, 35 | sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) { 36 | close(fd); 37 | 38 | return -1; 39 | } 40 | 41 | file->ptr = ptr; 42 | file->size = sb.st_size; 43 | file->fd = fd; 44 | 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /os/windows/winapi_window.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/windows/winapi_window.h 3 | // 4 | // Convenience functions for managing rendering windows. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __windows_winapi_window_h__ 11 | #define __windows_winapi_window_h__ 12 | 13 | #include "common.h" 14 | #include "os/gl_window.h" 15 | #include 16 | #include 17 | 18 | struct winapi_window { 19 | HINSTANCE h_instance; 20 | HWND h_wnd; 21 | 22 | HDC h_dc; 23 | HGLRC h_glrc; 24 | 25 | // Locks and whatnot for events. 26 | CRITICAL_SECTION event_lock; 27 | 28 | bool went_fullscreen; 29 | bool exit_requested; 30 | 31 | // Locks and whatnot for rendering. 32 | CRITICAL_SECTION render_lock; 33 | HANDLE render_semaphore; 34 | 35 | unsigned frame_xres, frame_yres, frame_xskip, frame_type; 36 | uint8_t *frame_data; //[MAX_FRAME_DATA_SIZE]; 37 | bool frame_pending; 38 | }; 39 | 40 | cen64_cold bool winapi_window_exit_requested(struct winapi_window *window); 41 | cen64_cold void winapi_window_render_frame(struct winapi_window *window, const void *data, 42 | unsigned xres, unsigned yres, unsigned xskip, unsigned type); 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /debugger/cen64d.pro: -------------------------------------------------------------------------------- 1 | # 2 | # cen64d.pro: CEN64 qmake file. 3 | # 4 | # CEN64D: Cycle-Accurate Nintendo 64 Debugger. 5 | # Copyright (C) 2015, Tyler J. Stachecki. 6 | # 7 | # This file is subject to the terms and conditions defined in 8 | # 'LICENSE', which is part of this source code package. 9 | # 10 | 11 | QT += core gui network 12 | 13 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 14 | 15 | TARGET = cen64d 16 | TEMPLATE = app 17 | 18 | SOURCES += disassembly_view.cpp \ 19 | main.cpp\ 20 | main_window.cpp \ 21 | memory_view.cpp \ 22 | memory_window.cpp \ 23 | network_handle.cpp \ 24 | rdp_window.cpp \ 25 | register_model.cpp \ 26 | register_view.cpp \ 27 | rsp_window.cpp \ 28 | toggle_window.cpp \ 29 | vr4300_window.cpp 30 | 31 | HEADERS += disassembly_view.h \ 32 | main_window.h \ 33 | memory_view.h \ 34 | memory_window.h \ 35 | network_handle.h \ 36 | rdp_window.h \ 37 | register_model.cpp \ 38 | register_view.h \ 39 | rsp_window.h \ 40 | toggle_window.h \ 41 | vr4300_window.h 42 | 43 | FORMS += main_window.ui 44 | 45 | -------------------------------------------------------------------------------- /os/common/local_time.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/common/local_time.h 3 | // 4 | // Functions for getting current time. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #ifndef __os_local_time_h__ 11 | #define __os_local_time_h__ 12 | #include "common.h" 13 | #include 14 | 15 | #ifdef _WIN32 16 | #include 17 | #endif 18 | 19 | struct time_stamp { 20 | // Used by 64DD and Joybus RTC 21 | unsigned year; /* Year starting from 1900 [96-195] */ 22 | unsigned month; /* Month [1-12] */ 23 | unsigned day; /* Day [1-31] */ 24 | unsigned hour; /* Hour [0-23] */ 25 | unsigned min; /* Minute [0-59] */ 26 | unsigned sec; /* Second [0-59] */ 27 | // Used only by Joybus RTC 28 | unsigned week_day; /* Day of Week [0-6] (Sun-Sat) */ 29 | }; 30 | 31 | void get_local_time(struct time_stamp *ts, int32_t offset_seconds); 32 | 33 | int32_t get_offset_seconds(const struct time_stamp * ts); 34 | 35 | static inline uint8_t byte2bcd(unsigned byte) { 36 | byte %= 100; 37 | return ((byte / 10) << 4) | (byte % 10); 38 | } 39 | 40 | static inline uint8_t bcd2byte(uint8_t bcd) { 41 | uint8_t hi = (bcd & 0xF0) >> 4; 42 | uint8_t lo = bcd & 0x0F; 43 | return (hi * 10) + lo; 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /cmake/Modules/FindIconv.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find Iconv 2 | # Once done this will define 3 | # 4 | # ICONV_FOUND - system has Iconv 5 | # ICONV_INCLUDE_DIR - the Iconv include directory 6 | # ICONV_LIBRARIES - Link these to use Iconv 7 | # ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const 8 | # 9 | 10 | IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 11 | # Already in cache, be silent 12 | SET(ICONV_FIND_QUIETLY TRUE) 13 | ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 14 | 15 | FIND_PATH(ICONV_INCLUDE_DIR iconv.h) 16 | 17 | FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c) 18 | 19 | IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 20 | SET(ICONV_FOUND TRUE) 21 | ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 22 | 23 | set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) 24 | set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES}) 25 | set(CMAKE_REQUIRED_INCLUDES) 26 | set(CMAKE_REQUIRED_LIBRARIES) 27 | 28 | IF(ICONV_FOUND) 29 | IF(NOT ICONV_FIND_QUIETLY) 30 | MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") 31 | ENDIF(NOT ICONV_FIND_QUIETLY) 32 | ELSE(ICONV_FOUND) 33 | IF(Iconv_FIND_REQUIRED) 34 | MESSAGE(FATAL_ERROR "Could not find Iconv") 35 | ENDIF(Iconv_FIND_REQUIRED) 36 | ENDIF(ICONV_FOUND) 37 | 38 | MARK_AS_ADVANCED( 39 | ICONV_INCLUDE_DIR 40 | ICONV_LIBRARIES 41 | ) 42 | -------------------------------------------------------------------------------- /vr4300/icache.h: -------------------------------------------------------------------------------- 1 | // 2 | // vr4300/icache.h: VR4300 instruction cache. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __vr4300_icache_h__ 12 | #define __vr4300_icache_h__ 13 | #include "common.h" 14 | 15 | struct vr4300_icache_line { 16 | uint8_t data[8 * 4]; 17 | uint32_t metadata; 18 | }; 19 | 20 | struct vr4300_icache { 21 | struct vr4300_icache_line lines[512]; 22 | }; 23 | 24 | cen64_cold void vr4300_icache_init(struct vr4300_icache *icache); 25 | 26 | cen64_hot const struct vr4300_icache_line* vr4300_icache_probe( 27 | const struct vr4300_icache *icache, uint64_t vaddr, uint32_t paddr); 28 | 29 | void vr4300_icache_fill(struct vr4300_icache *icache, 30 | uint64_t vaddr, uint32_t paddr, const void *data); 31 | uint32_t vr4300_icache_get_tag(const struct vr4300_icache *icache, 32 | uint64_t vaddr); 33 | void vr4300_icache_invalidate(struct vr4300_icache *icache, uint64_t vaddr); 34 | void vr4300_icache_invalidate_hit(struct vr4300_icache *icache, 35 | uint64_t vaddr, uint32_t paddr); 36 | void vr4300_icache_set_taglo(struct vr4300_icache *icache, 37 | uint64_t vaddr, uint32_t tag); 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vmul.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmul.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | // 9 | // TODO: CHECK ME. 10 | // 11 | 12 | static inline __m128i rsp_vmulf_vmulu(uint32_t iw, __m128i vs, __m128i vt, 13 | __m128i zero, __m128i *acc_lo, __m128i *acc_md, __m128i *acc_hi) { 14 | __m128i lo, hi, round, sign1, sign2, eq, neq, neg; 15 | 16 | lo = _mm_mullo_epi16(vs, vt); 17 | round = _mm_cmpeq_epi16(zero, zero); 18 | sign1 = _mm_srli_epi16(lo, 15); 19 | lo = _mm_add_epi16(lo, lo); 20 | round = _mm_slli_epi16(round, 15); 21 | hi = _mm_mulhi_epi16(vs, vt); 22 | sign2 = _mm_srli_epi16(lo, 15); 23 | *acc_lo = _mm_add_epi16(round, lo); 24 | sign1 = _mm_add_epi16(sign1, sign2); 25 | 26 | hi = _mm_slli_epi16(hi, 1); 27 | neq = eq = _mm_cmpeq_epi16(vs, vt); 28 | *acc_md = _mm_add_epi16(hi, sign1); 29 | 30 | neg = _mm_srai_epi16(*acc_md, 15); 31 | 32 | // VMULU 33 | if (iw & 0x1) { 34 | *acc_hi = _mm_andnot_si128(eq, neg); 35 | hi =_mm_or_si128(*acc_md, neg); 36 | return _mm_andnot_si128(*acc_hi, hi); 37 | } 38 | 39 | // VMULF 40 | else { 41 | eq = _mm_and_si128(eq, neg); 42 | *acc_hi = _mm_andnot_si128(neq, neg); 43 | return _mm_add_epi16(*acc_md, eq); 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /os/winapi/cpuid.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/cpuid.c 3 | // 4 | // Functions for calling cpuid on x86. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #include "os/cpuid.h" 11 | #include 12 | 13 | 14 | void cen64_cpuid(uint32_t eax, uint32_t ecx, struct cen64_cpuid_t *cpuid) { 15 | int cpuInfo[4]; 16 | 17 | #ifdef _MSC_VER 18 | __cpuidex(cpuInfo, eax, ecx); 19 | #else 20 | __asm__ __volatile__( 21 | "cpuid\n\t" 22 | 23 | : "=a"(cpuInfo[0]), "=b"(cpuInfo[1]), "=c"(cpuInfo[2]), "=d"(cpuInfo[3]) 24 | : "0"(eax), "2"(ecx) 25 | ); 26 | #endif 27 | 28 | cpuid->eax = cpuInfo[0]; 29 | cpuid->ebx = cpuInfo[1]; 30 | cpuid->ecx = cpuInfo[2]; 31 | cpuid->edx = cpuInfo[3]; 32 | } 33 | 34 | void cen64_cpuid_get_vendor(char vendor[13]) { 35 | int cpuInfo[4]; 36 | 37 | #ifdef _MSC_VER 38 | __cpuidex(cpuInfo, 0, 0); 39 | #else 40 | __asm__ __volatile__( 41 | "cpuid\n\t" 42 | 43 | : "=a"(cpuInfo[0]), "=b"(cpuInfo[1]), "=c"(cpuInfo[2]), "=d"(cpuInfo[3]) 44 | : "0"(0), "2"(0) 45 | ); 46 | #endif 47 | 48 | memcpy(vendor + 0, cpuInfo + 1, sizeof(*cpuInfo)); 49 | memcpy(vendor + 4, cpuInfo + 3, sizeof(*cpuInfo)); 50 | memcpy(vendor + 8, cpuInfo + 2, sizeof(*cpuInfo)); 51 | vendor[sizeof(vendor) - 1] = '\0'; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /rsp/decoder.h: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/decoder.h: RSP decoder. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __rsp_decoder_h__ 12 | #define __rsp_decoder_h__ 13 | #include "common.h" 14 | #include "rsp/opcodes.h" 15 | 16 | #define GET_RS(iw) ((iw) >> 21 & 0x1F) 17 | #define GET_RT(iw) ((iw) >> 16 & 0x1F) 18 | #define GET_RD(iw) ((iw) >> 11 & 0x1F) 19 | 20 | #define GET_VS(iw) ((iw) >> 11 & 0x1F) 21 | #define GET_VT(iw) ((iw) >> 16 & 0x1F) 22 | #define GET_VD(iw) ((iw) >> 6 & 0x1F) 23 | #define GET_DE(iw) ((iw) >> 11 & 0x1F) 24 | #define GET_EL(iw) ((iw) >> 7 & 0xF) 25 | #define GET_E(iw) ((iw) >> 21 & 0xF) 26 | 27 | #define OPCODE_INFO_NONE (0) 28 | #define OPCODE_INFO_VECTOR (1U << 1) 29 | #define OPCODE_INFO_BRANCH (1U << 31) 30 | #define OPCODE_INFO_NEEDRS (1U << 3) 31 | #define OPCODE_INFO_NEEDRT (1U << 4) 32 | #define OPCODE_INFO_NEEDVS (1U << 3) 33 | #define OPCODE_INFO_NEEDVT (1U << 4) 34 | #define OPCODE_INFO_LOAD (1U << 5) 35 | #define OPCODE_INFO_STORE (1U << 6) 36 | 37 | struct rsp_opcode { 38 | uint32_t id; 39 | uint32_t flags; 40 | }; 41 | 42 | cen64_hot const struct rsp_opcode* rsp_decode_instruction(uint32_t); 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /vr4300/debug.h: -------------------------------------------------------------------------------- 1 | // 2 | // vr4300/debug.h: VR4300 debug hooks. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __vr4300_debug_h__ 12 | #define __vr4300_debug_h__ 13 | #include "common.h" 14 | #include "common/hash_table.h" 15 | #include "vr4300/interface.h" 16 | 17 | enum vr4300_debug_signals { 18 | VR4300_DEBUG_SIGNALS_BREAK = 0x000000001, 19 | }; 20 | 21 | struct vr4300_debug { 22 | struct hash_table breakpoints; 23 | vr4300_debug_break_handler break_handler; 24 | void* break_handler_data; 25 | unsigned signals; 26 | }; 27 | 28 | cen64_cold void vr4300_debug_init(struct vr4300_debug* debug); 29 | 30 | cen64_cold void vr4300_debug_cleanup(struct vr4300_debug* debug); 31 | cen64_cold void vr4300_debug_check_breakpoints(struct vr4300_debug* debug, uint64_t pc); 32 | cen64_cold void vr4300_debug_exception(struct vr4300_debug* debug); 33 | cen64_cold void vr4300_debug_set_breakpoint(struct vr4300_debug* debug, uint64_t pc); 34 | cen64_cold void vr4300_debug_remove_breakpoint(struct vr4300_debug* debug, uint64_t pc); 35 | 36 | cen64_cold void vr4300_debug_signal(struct vr4300_debug* debug, enum vr4300_debug_signals signal); 37 | 38 | #endif -------------------------------------------------------------------------------- /debugger/disassembly_view.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // disassembly_view.cpp: CEN64D disassembly view (MVC). 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "disassembly_view.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | DisassemblyView::DisassemblyView() { 19 | QFont monospacedFont("Courier New"); 20 | monospacedFont.setFixedPitch(true); 21 | monospacedFont.setPointSize(10); 22 | setFont(monospacedFont); 23 | 24 | QFontMetrics metrics(monospacedFont); 25 | fontWidth = metrics.width('0'); 26 | fontHeight = metrics.height(); 27 | } 28 | 29 | DisassemblyView::~DisassemblyView() { 30 | } 31 | 32 | void DisassemblyView::paintEvent(QPaintEvent* event) { 33 | QSize area = viewport()->size(); 34 | 35 | // TODO: Fonts don't seem to render exactly 36 | // where we want them, so add a fudge factor. 37 | float fudge = 2.0 / 3.0; 38 | unsigned start = fontHeight * fudge; 39 | 40 | QPainter painter(viewport()); 41 | 42 | painter.fillRect(0, 0, area.width(), area.height(), QBrush(Qt::white)); 43 | painter.drawText(1, start, "This is the disassembly view."); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/vabs.s: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/vabs.s 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .include "rsp/gcc/defs.h" 12 | 13 | .text 14 | 15 | .ifdef __MINGW__ 16 | .globl RSP_VABS 17 | .def RSP_VABS; .scl 2; .type 32; .endef 18 | .seh_proc RSP_VABS 19 | .ifndef __VECTORCALL__ 20 | RSP_VABS: 21 | movdqa (%r8), %xmm0 22 | movdqa (%r9), %xmm1 23 | pxor %xmm2, %xmm2 24 | .endif 25 | .else 26 | .global RSP_VABS 27 | .type RSP_VABS, @function 28 | RSP_VABS: 29 | .endif 30 | 31 | .ifdef __AVX__ 32 | vpsraw $0xf, %xmm1, %xmm3 33 | vpsignw %xmm1, %xmm0, acc_lo 34 | vpaddw %xmm3, acc_lo, %xmm2 35 | vpsubsw %xmm3, %xmm2, %xmm0 36 | retq 37 | 38 | .elseif __SSSE3__ == 1 39 | psignw %xmm1, %xmm0 40 | psraw $0xF, %xmm1 41 | movdqa %xmm0, acc_lo 42 | paddw %xmm1, %xmm0 43 | psubsw %xmm1, %xmm0 44 | retq 45 | 46 | .else 47 | pcmpeqw %xmm1, %xmm2 48 | psraw $0xF, %xmm1 49 | pandn %xmm0, %xmm2 50 | pxor %xmm1, %xmm2 51 | movdqa %xmm2, acc_lo 52 | psubsw %xmm1, %xmm2 53 | psubw %xmm1, acc_lo 54 | movdqa %xmm2, %xmm0 55 | retq 56 | .endif 57 | 58 | .ifdef __MINGW__ 59 | .seh_endproc 60 | .else 61 | .size RSP_VABS,.-RSP_VABS 62 | .endif 63 | 64 | -------------------------------------------------------------------------------- /os/winapi/gl_context.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/winapi/gl_context.h: WinAPI GL context definitions. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_WINAPI_GL_CONTEXT 12 | #define CEN64_OS_WINAPI_GL_CONTEXT 13 | #include "gl_common.h" 14 | #include "gl_display.h" 15 | #include "gl_screen.h" 16 | #include "gl_window.h" 17 | #include 18 | 19 | #define CEN64_GL_CONTEXT_BAD (NULL) 20 | typedef HGLRC cen64_gl_context; 21 | 22 | // 23 | // Creates a cen64_gl_context and binds it to the cen64_gl_window. 24 | // 25 | static inline cen64_gl_context cen64_gl_context_create(cen64_gl_window window) { 26 | cen64_gl_context c; 27 | 28 | if ((c = wglCreateContext(window->hdc)) == NULL) 29 | return CEN64_GL_CONTEXT_BAD; 30 | 31 | if (wglMakeCurrent(window->hdc, c) != TRUE) { 32 | wglDeleteContext(c); 33 | c = CEN64_GL_CONTEXT_BAD; 34 | } 35 | 36 | return c; 37 | } 38 | 39 | // 40 | // Unbinds the cen64_gl_context from the window and releases the context. 41 | // 42 | static inline void cen64_gl_context_destroy( 43 | cen64_gl_context context, cen64_gl_window window) { 44 | wglMakeCurrent(NULL, NULL); 45 | wglDeleteContext(context); 46 | } 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/vmrg.s: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/vmrg.s 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .include "rsp/gcc/defs.h" 12 | 13 | .text 14 | 15 | .ifdef __MINGW__ 16 | .globl RSP_VMRG 17 | .def RSP_VMRG; .scl 2; .type 32; .endef 18 | .seh_proc RSP_VMRG 19 | .ifndef __VECTORCALL__ 20 | RSP_VMRG: 21 | movdqa (%r8), %xmm0 22 | movdqa (%r9), %xmm1 23 | #pxor %xmm2, %xmm2 24 | .endif 25 | .else 26 | .global RSP_VMRG 27 | .type RSP_VMRG, @function 28 | RSP_VMRG: 29 | .endif 30 | 31 | .ifdef __AVX__ 32 | vpblendvb vcc_lo, %xmm1, %xmm0, %xmm0 33 | pxor vco_lo, vco_lo 34 | movdqa %xmm0, acc_lo 35 | pxor vco_hi, vco_hi 36 | retq 37 | 38 | .elseif __SSE4_1__ == 1 39 | movdqa %xmm0, acc_lo 40 | movdqa vcc_lo, %xmm0 41 | pxor vco_lo, vco_lo 42 | pblendvb %xmm0, %xmm1, acc_lo 43 | pxor vco_hi, vco_hi 44 | movdqa acc_lo, %xmm0 45 | retq 46 | 47 | .else 48 | movdqa vcc_lo, acc_lo 49 | pxor vco_lo, vco_lo 50 | pand acc_lo, %xmm1 51 | pandn %xmm0, acc_lo 52 | pxor vco_hi, vco_hi 53 | por %xmm1, acc_lo 54 | movdqa acc_lo, %xmm0 55 | retq 56 | .endif 57 | 58 | .ifdef __MINGW__ 59 | .seh_endproc 60 | .else 61 | .size RSP_VMRG,.-RSP_VMRG 62 | .endif 63 | 64 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vcr.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vcr.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_vcr(__m128i vs, __m128i vt, 11 | __m128i zero, __m128i *ge, __m128i *le) { 12 | __m128i diff_sel_mask, diff_gez, diff_lez; 13 | __m128i sign, sign_notvt; 14 | 15 | // sign = (vs ^ vt) < 0 16 | sign = _mm_xor_si128(vs, vt); 17 | sign = _mm_srai_epi16(sign, 15); 18 | 19 | // Compute le 20 | diff_lez = _mm_and_si128(vs, sign); 21 | diff_lez = _mm_add_epi16(diff_lez, vt); 22 | *le = _mm_srai_epi16(diff_lez, 15); 23 | 24 | // Compute ge 25 | diff_gez = _mm_or_si128(vs, sign); 26 | diff_gez = _mm_min_epi16(diff_gez, vt); 27 | *ge = _mm_cmpeq_epi16(diff_gez, vt); 28 | 29 | // sign_notvt = sn ? ~vt : vt 30 | sign_notvt = _mm_xor_si128(vt, sign); 31 | 32 | // Compute result: 33 | #ifdef __SSE4_1__ 34 | diff_sel_mask = _mm_blendv_epi8(*ge, *le, sign); 35 | return _mm_blendv_epi8(vs, sign_notvt, diff_sel_mask); 36 | #else 37 | diff_sel_mask = _mm_sub_epi16(*le, *ge); 38 | diff_sel_mask = _mm_and_si128(diff_sel_mask, sign); 39 | diff_sel_mask = _mm_add_epi16(diff_sel_mask, *ge); 40 | 41 | zero = _mm_sub_epi16(sign_notvt, vs); 42 | zero = _mm_and_si128(zero, diff_sel_mask); 43 | return _mm_add_epi16(zero, vs); 44 | #endif 45 | } 46 | 47 | -------------------------------------------------------------------------------- /os/common/local_time.c: -------------------------------------------------------------------------------- 1 | // 2 | // os/common/local_time.c 3 | // 4 | // Functions for getting the current time. 5 | // 6 | // This file is subject to the terms and conditions defined in 7 | // 'LICENSE', which is part of this source code package. 8 | // 9 | 10 | #include 11 | #include "local_time.h" 12 | 13 | void get_local_time(struct time_stamp *ts, int32_t offset_seconds) { 14 | time_t now = time(NULL); 15 | now += offset_seconds; 16 | 17 | struct tm tm = { 0, }; 18 | #ifdef _WIN32 19 | localtime_s(&now, &tm); 20 | #else 21 | localtime_r(&now, &tm); 22 | #endif 23 | 24 | // Copy tm into time_stamp struct 25 | ts->year = tm.tm_year; 26 | ts->month = tm.tm_mon + 1; // time_stamp month is zero-indexed 27 | ts->day = tm.tm_mday; 28 | ts->hour = tm.tm_hour; 29 | ts->min = tm.tm_min; 30 | ts->sec = tm.tm_sec; 31 | ts->week_day = tm.tm_wday; 32 | } 33 | 34 | int32_t get_offset_seconds(const struct time_stamp * ts) { 35 | struct tm tm = { 0, }; 36 | 37 | // Copy time_stamp into tm struct 38 | tm.tm_year = ts->year; 39 | tm.tm_mon = ts->month - 1; // time_stamp month is zero-indexed 40 | tm.tm_mday = ts->day; 41 | tm.tm_hour = ts->hour; 42 | tm.tm_min = ts->min; 43 | tm.tm_sec = ts->sec; 44 | tm.tm_wday = ts->week_day; 45 | tm.tm_isdst = -1; // Auto-adjust for DST 46 | 47 | time_t then = mktime(&tm); 48 | time_t now = time(NULL); 49 | 50 | return then - now; 51 | } 52 | -------------------------------------------------------------------------------- /debugger/main_window.h: -------------------------------------------------------------------------------- 1 | // 2 | // main_window.h: CEN64D main window. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef MAIN_WINDOW_H 12 | #define MAIN_WINDOW_H 13 | 14 | #include "network_handle.h" 15 | #include "memory_window.h" 16 | #include "rdp_window.h" 17 | #include "rsp_window.h" 18 | #include "vr4300_window.h" 19 | #include 20 | #include 21 | #include 22 | 23 | namespace Ui { 24 | class MainWindow; 25 | } 26 | 27 | class MainWindow : public QMainWindow { 28 | Q_OBJECT 29 | Ui::MainWindow *ui; 30 | 31 | NetworkHandle *networkHandle; 32 | MemoryWindow *memoryWindow; 33 | RDPWindow *rdpWindow; 34 | RSPWindow *rspWindow; 35 | VR4300Window *vr4300Window; 36 | 37 | QMenu *fileMenu; 38 | QAction *fileQuitAction; 39 | 40 | QMenu *viewMenu; 41 | QAction *viewMemoryWindowAction; 42 | QAction *viewRDPWindowAction; 43 | QAction *viewRSPWindowAction; 44 | QAction *viewVR4300WindowAction; 45 | 46 | QMenu *helpMenu; 47 | QAction *helpAboutAction; 48 | 49 | void setupActions(); 50 | void setupMenuBar(QMenuBar *menuBar); 51 | 52 | private slots: 53 | void showAboutWindow(); 54 | 55 | public: 56 | explicit MainWindow(QWidget *parent = 0); 57 | ~MainWindow(); 58 | }; 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /os/x11/gl_context.h: -------------------------------------------------------------------------------- 1 | // 2 | // os/x11/gl_context.h: X11 GL context definitions. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef CEN64_OS_X11_GL_CONTEXT 12 | #define CEN64_OS_X11_GL_CONTEXT 13 | #include "gl_common.h" 14 | #include "gl_display.h" 15 | #include "gl_screen.h" 16 | #include "gl_window.h" 17 | #include 18 | 19 | #define CEN64_GL_CONTEXT_BAD (NULL) 20 | typedef GLXContext cen64_gl_context; 21 | 22 | // Creates a cen64_gl_context and binds it to the cen64_gl_window. 23 | static inline cen64_gl_context cen64_gl_context_create(cen64_gl_window window) { 24 | cen64_gl_context c; 25 | 26 | if ((c = glXCreateContext(window->display, window->visual_info, 27 | NULL, True)) == CEN64_GL_CONTEXT_BAD) 28 | return CEN64_GL_CONTEXT_BAD; 29 | 30 | if (glXMakeCurrent(window->display, window->window, c) != True) { 31 | glXDestroyContext(window->display, c); 32 | c = CEN64_GL_CONTEXT_BAD; 33 | } 34 | 35 | return c; 36 | } 37 | 38 | // Unbinds the cen64_gl_context from the window and releases the context. 39 | static inline void cen64_gl_context_destroy( 40 | cen64_gl_context context, cen64_gl_window window) { 41 | glXMakeCurrent(window->display, None, NULL); 42 | glXDestroyContext(window->display, context); 43 | } 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "{branch}-ci-{build}" 2 | image: Visual Studio 2015 3 | 4 | branches: 5 | only: 6 | - master 7 | 8 | environment: 9 | matrix: 10 | - build: msvc 11 | platform: x64 12 | CMAKEFILE: "Visual Studio 14 Win64" 13 | - build: mingw-w64 14 | platform: x64 15 | CMAKEFILE: "MSYS Makefiles" 16 | 17 | install: 18 | - appveyor DownloadFile https://cfhcable.dl.sourceforge.net/project/gnuwin32/libiconv/1.9.2-1/libiconv-1.9.2-1.exe 19 | - libiconv-1.9.2-1.exe /SILENT /SUPPRESSMSGBOXES 20 | - appveyor DownloadFile http://openal-soft.org/openal-binaries/openal-soft-1.17.2-bin.zip 21 | - 7z x openal-soft-1.17.2-bin.zip 22 | 23 | before_build: 24 | - set PATH=%PATH%;C:\projects\cen64\openal-soft-1.17.2-bin 25 | - set PATH=%PATH:C:\Program Files\Git\bin;=% 26 | - set PATH=%PATH:C:\Program Files\Git\usr\bin;=% 27 | - if "%build%"=="msvc" set PATH=%PATH%;C:\Program Files (x86)\GnuWin32\bin 28 | - if "%build%"=="mingw-w64" set PATH=%PATH%;C:\msys64\mingw64;C:\msys64\mingw64\bin;C:\msys64\mingw64\lib;C:\msys64\mingw64\include;C:\msys64\usr\bin\; 29 | - call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" %platform% 30 | - if "%platform%"=="X64" set platform=x64 31 | 32 | build_script: 33 | - mkdir build 34 | - cd build 35 | - cmake .. -G "%CMAKEFILE%" 36 | - if "%build%"=="msvc" MSBuild .\cen64.sln /p:Configuration=Release /p:Platform=%platform% 37 | - if "%build%"=="mingw-w64" bash -lc "cd /c/projects/cen64/build; make all" 38 | 39 | test_script: 40 | - ctest -C Release --verbose 41 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/vcmp.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vcmp.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "common.h" 9 | 10 | static inline __m128i rsp_veq_vge_vlt_vne(uint32_t iw, __m128i vs, __m128i vt, 11 | __m128i zero, __m128i *le, __m128i eq, __m128i sign) { 12 | __m128i equal = _mm_cmpeq_epi16(vs, vt); 13 | 14 | // VNE & VGE 15 | if (iw & 0x2) { 16 | // VGE 17 | if (iw & 0x1) { 18 | __m128i gt = _mm_cmpgt_epi16(vs, vt); 19 | __m128i equalsign = _mm_and_si128(eq, sign); 20 | 21 | equal = _mm_andnot_si128(equalsign, equal); 22 | *le = _mm_or_si128(gt, equal); 23 | } 24 | 25 | // VNE 26 | else { 27 | __m128i nequal = _mm_cmpeq_epi16(equal, zero); 28 | 29 | *le = _mm_and_si128(eq, equal); 30 | *le = _mm_or_si128(*le, nequal); 31 | } 32 | } 33 | 34 | // VEQ & VLT 35 | else { 36 | // VEQ 37 | if (iw & 0x1) 38 | *le = _mm_andnot_si128(eq, equal); 39 | 40 | // VLT 41 | else { 42 | __m128i lt = _mm_cmplt_epi16(vs, vt); 43 | 44 | equal = _mm_and_si128(eq, equal); 45 | equal = _mm_and_si128(sign, equal); 46 | *le = _mm_or_si128(lt, equal); 47 | } 48 | } 49 | 50 | #ifdef __SSE4_1__ 51 | return _mm_blendv_epi8(vt, vs, *le); 52 | #else 53 | vs = _mm_and_si128(*le, vs); 54 | vt = _mm_andnot_si128(*le, vt); 55 | return _mm_or_si128(vs, vt); 56 | #endif 57 | } 58 | 59 | -------------------------------------------------------------------------------- /rsp/cp2.h: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/cp2.h: RSP control coprocessor. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __rsp_cp2_h__ 12 | #define __rsp_cp2_h__ 13 | #include "common.h" 14 | #include "rsp/rsp.h" 15 | 16 | enum rsp_flags_t { 17 | RSP_VCO = 0, 18 | RSP_VCC = 1, 19 | RSP_VCE = 2 20 | }; 21 | 22 | enum rsp_acc_t { 23 | RSP_ACC_LO = 16, 24 | RSP_ACC_MD = 8, 25 | RSP_ACC_HI = 0, 26 | }; 27 | 28 | union aligned_rsp_3vect_t { 29 | rsp_vect_t __align[3]; 30 | uint16_t e[24]; 31 | }; 32 | 33 | union aligned_rsp_2vect_t { 34 | rsp_vect_t __align[2]; 35 | uint16_t e[16]; 36 | }; 37 | 38 | union aligned_rsp_1vect_t { 39 | rsp_vect_t __align; 40 | uint16_t e[8]; 41 | }; 42 | 43 | struct rsp_cp2 { 44 | union aligned_rsp_1vect_t regs[32]; 45 | union aligned_rsp_2vect_t flags[3]; 46 | union aligned_rsp_3vect_t acc; 47 | 48 | int16_t div_out; 49 | int16_t div_in; 50 | char dp_flag; 51 | }; 52 | 53 | void RSP_CFC2(struct rsp *rsp, uint32_t iw, uint32_t rs, uint32_t rt); 54 | void RSP_CTC2(struct rsp *rsp, uint32_t iw, uint32_t rs, uint32_t rt); 55 | void RSP_MFC2(struct rsp *rsp, uint32_t iw, uint32_t rs, uint32_t rt); 56 | void RSP_MTC2(struct rsp *rsp, uint32_t iw, uint32_t rs, uint32_t rt); 57 | 58 | cen64_cold void rsp_cp2_init(struct rsp *rsp); 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /rsp/opcodes.h: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/opcodes.h: RSP opcode types and info. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __rsp_opcodes_h__ 12 | #define __rsp_opcodes_h__ 13 | #include "common.h" 14 | #include "rsp/rsp.h" 15 | 16 | enum rsp_opcode_id { 17 | #define X(op) RSP_OPCODE_##op, 18 | #include "rsp/opcodes.md" 19 | NUM_RSP_OPCODES 20 | #undef X 21 | }; 22 | 23 | enum rsp_vector_opcode_id { 24 | #define X(op) RSP_OPCODE_##op, 25 | #include "rsp/vector_opcodes.md" 26 | NUM_RSP_VECTOR_OPCODES 27 | #undef X 28 | }; 29 | 30 | struct rsp; 31 | typedef void (*rsp_function)(struct rsp *, 32 | uint32_t, uint32_t, uint32_t); 33 | 34 | typedef rsp_vect_t (*rsp_vector_function)(struct rsp *rsp, uint32_t iw, 35 | rsp_vect_t vt_shuffle, rsp_vect_t vs, rsp_vect_t zero); 36 | 37 | extern const rsp_function rsp_function_table[NUM_RSP_OPCODES]; 38 | extern const char *rsp_opcode_mnemonics[NUM_RSP_OPCODES]; 39 | extern const rsp_vector_function rsp_vector_function_table[NUM_RSP_VECTOR_OPCODES]; 40 | extern const char *rsp_vector_opcode_mnemonics[NUM_RSP_VECTOR_OPCODES]; 41 | 42 | void RSP_INVALID(struct rsp *, 43 | uint32_t, uint32_t, uint32_t); 44 | 45 | cen64_cold rsp_vect_t RSP_VINVALID(struct rsp *rsp, uint32_t iw, 46 | rsp_vect_t vt_shuffle, rsp_vect_t vs, rsp_vect_t zero); 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /vr4300/decoder.h: -------------------------------------------------------------------------------- 1 | // 2 | // vr4300/decoder.h: VR4300 decoder. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __vr4300_decoder_h__ 12 | #define __vr4300_decoder_h__ 13 | #include "common.h" 14 | #include "vr4300/opcodes.h" 15 | 16 | #define GET_RS(iw) ((iw) >> 21 & 0x1F) 17 | #define GET_RT(iw) ((iw) >> 16 & 0x1F) 18 | #define GET_RD(iw) ((iw) >> 11 & 0x1F) 19 | 20 | #define GET_FS(iw) (((iw) >> 11 & 0x1F) + VR4300_REGISTER_CP1_0) 21 | #define GET_FT(iw) (((iw) >> 16 & 0x1F) + VR4300_REGISTER_CP1_0) 22 | #define GET_FD(iw) (((iw) >> 6 & 0x1F) + VR4300_REGISTER_CP1_0) 23 | #define GET_FMT(iw) ((iw) >> 21 & 0x1F) 24 | 25 | #define OPCODE_INFO_NONE (0) 26 | #define OPCODE_INFO_FPU (1U << 2) 27 | #define OPCODE_INFO_BRANCH (1U << 31) 28 | #define OPCODE_INFO_NEEDRS (1U << 3) 29 | #define OPCODE_INFO_NEEDFS ((1U << 3) | (1U << 0)) 30 | #define OPCODE_INFO_NEEDRT (1U << 4) 31 | #define OPCODE_INFO_NEEDFT ((1U << 4) | (1U << 1)) 32 | #define OPCODE_INFO_LOAD (1U << 5) 33 | #define OPCODE_INFO_STORE (1U << 6) 34 | 35 | enum vr4300_fmt { 36 | VR4300_FMT_S = 16, 37 | VR4300_FMT_D = 17, 38 | VR4300_FMT_W = 20, 39 | VR4300_FMT_L = 21, 40 | }; 41 | 42 | struct vr4300_opcode { 43 | uint32_t id; 44 | uint32_t flags; 45 | }; 46 | 47 | cen64_hot const struct vr4300_opcode* vr4300_decode_instruction(uint32_t); 48 | 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /debugger/toggle_window.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // toggle_window.cpp: Toggle-able window. 3 | // 4 | // CEN64D: Cycle-Accurate Nintendo 64 Debugger 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #include "toggle_window.h" 12 | 13 | ToggleWindow::ToggleWindow(const QString &windowTitle, 14 | QAction *toggleAction, bool initiallyVisible) : toggleAction(toggleAction) { 15 | setWindowTitle(windowTitle); 16 | 17 | // Create states and connect signals to slots. 18 | windowHiddenState.addTransition(toggleAction, 19 | SIGNAL(triggered()), &windowExposedState); 20 | 21 | windowExposedState.addTransition(toggleAction, 22 | SIGNAL(triggered()), &windowHiddenState); 23 | 24 | QObject::connect(&windowHiddenState, SIGNAL(entered()), this, SLOT(hide())); 25 | QObject::connect(&windowExposedState, SIGNAL(entered()), this, SLOT(show())); 26 | 27 | if (toggleAction->isCheckable()) 28 | toggleAction->setChecked(initiallyVisible); 29 | 30 | // Setup the state machine. 31 | windowMachine.addState(&windowHiddenState); 32 | windowMachine.addState(&windowExposedState); 33 | windowMachine.setInitialState(initiallyVisible 34 | ? &windowExposedState 35 | : &windowHiddenState); 36 | 37 | windowMachine.start(); 38 | } 39 | 40 | ToggleWindow::~ToggleWindow() { 41 | } 42 | 43 | void ToggleWindow::closeEvent(QCloseEvent *event) { 44 | toggleAction->trigger(); 45 | event->accept(); 46 | } 47 | -------------------------------------------------------------------------------- /si/gb.h: -------------------------------------------------------------------------------- 1 | // 2 | // si/gb.h: Game Boy pak definitions 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2016, Jason Benaim. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __si_gb_h__ 12 | #define __si_gb_h__ 13 | #include "pak.h" 14 | 15 | struct gb_cart { 16 | int mbc_type; 17 | int cartrom_num_banks; 18 | int reg_rom_bank_low; // low bits of ROM bank 19 | int reg_rom_bank_high; // high bits of ROM bank 20 | uint8_t* bootrom; 21 | size_t bootromsize; 22 | uint8_t* cartrom; 23 | uint8_t* cartromValid; 24 | uint8_t* cartrom_bank_zero; 25 | uint8_t* cartrom_bank_n; 26 | uint8_t* cartromValid_bank_n; 27 | uint16_t cart_bank_num; 28 | size_t cartromsize; 29 | uint8_t* extram; 30 | uint8_t* extramValidRead; 31 | uint8_t* extramValidWrite; 32 | uint8_t* extram_bank; 33 | uint8_t* extram_bank_validRead; 34 | uint8_t* extram_bank_validWrite; 35 | uint8_t extram_bank_num; 36 | int extram_enabled; 37 | int mbc1_mode; 38 | size_t extram_size; 39 | int extram_num_banks; 40 | int battery_backed; 41 | void (*cleanup)(void); 42 | char savename[256]; 43 | int huc3_ram_mode; 44 | FILE *fd; 45 | int chardev_mode; 46 | }; 47 | 48 | struct controller; 49 | uint8_t gb_read(struct controller *controller, uint16_t address); 50 | void gb_write(struct controller *controller, uint16_t address, uint8_t data); 51 | void gb_init(struct controller *controller); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /arch/x86_64/rsp/gcc/vlt.s: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/gcc/vlt.s 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | .include "rsp/gcc/defs.h" 12 | 13 | .text 14 | 15 | .ifdef __MINGW__ 16 | .globl RSP_VLT 17 | .def RSP_VLT; .scl 2; .type 32; .endef 18 | .seh_proc RSP_VLT 19 | .ifndef __VECTORCALL__ 20 | RSP_VLT: 21 | movdqa (%r8), %xmm0 22 | movdqa (%r9), %xmm1 23 | #pxor %xmm2, %xmm2 24 | .endif 25 | .else 26 | .global RSP_VLT 27 | .type RSP_VLT, @function 28 | RSP_VLT: 29 | .endif 30 | 31 | .ifdef __AVX__ 32 | vpcmpeqw %xmm1, %xmm0, %xmm3 33 | vpcmpgtw %xmm1, %xmm0, %xmm4 34 | pxor vcc_hi, vcc_hi 35 | // vpandn %xmm3, vco_hi, %xmm3 36 | vpand %xmm3, vco_hi, %xmm3 37 | pxor vco_hi, vco_hi 38 | pand vco_lo, %xmm3 39 | vpor %xmm3, %xmm4, vcc_lo 40 | pxor vco_lo, vco_lo 41 | vpblendvb vcc_lo, %xmm1, %xmm0, %xmm0 42 | movdqa %xmm0, acc_lo 43 | retq 44 | 45 | .else 46 | movdqa %xmm1, %xmm3 47 | movdqa %xmm0, vcc_lo 48 | pcmpeqw %xmm0, %xmm3 49 | pcmpgtw %xmm1, vcc_lo 50 | // pandn vco_lo, vco_hi 51 | pand vco_lo, vco_hi 52 | pminsw %xmm1, %xmm0 53 | pand %xmm3, vco_hi 54 | pxor vcc_hi, vcc_hi 55 | movdqa %xmm0, acc_lo 56 | por vco_hi, vcc_lo 57 | pxor vco_lo, vco_lo 58 | pxor vco_hi, vco_hi 59 | retq 60 | .endif 61 | 62 | .ifdef __MINGW__ 63 | .seh_endproc 64 | .else 65 | .size RSP_VLT,.-RSP_VLT 66 | .endif 67 | 68 | --------------------------------------------------------------------------------