Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Tyler Stachecki
committed
Mar 8, 2014
0 parents
commit 2f3aded
Showing
34 changed files
with
2,119 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Other data. | ||
/data | ||
|
||
# Build files. | ||
/build | ||
|
||
# Swap files. | ||
*.swp | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# | ||
# CEN64: Cycle-Accurate Nintendo 64 Simulator. | ||
# Copyright (C) 2014, Tyler J. Stachecki. | ||
# | ||
# This file is subject to the terms and conditions defined in | ||
# 'LICENSE', which is part of this source code package. | ||
# | ||
|
||
cmake_minimum_required(VERSION 2.6) | ||
project(cen64) | ||
|
||
if ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU") | ||
set(CMAKE_C_FLAGS "-Wall -Wextra -std=c99 -D_POSIX_SOURCE") | ||
|
||
set(CMAKE_C_FLAGS_DEBUG "-ggdb3 -g3 -O0") | ||
set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG") | ||
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") | ||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Og") | ||
endif ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU") | ||
|
||
include_directories(${PROJECT_SOURCE_DIR}) | ||
include_directories(${PROJECT_SOURCE_DIR}/bus) | ||
include_directories(${PROJECT_SOURCE_DIR}/pif) | ||
include_directories(${PROJECT_SOURCE_DIR}/vr4300) | ||
|
||
# Glob all the files together. | ||
file(GLOB BUS_SOURCES ${PROJECT_SOURCE_DIR}/bus/*.c) | ||
file(GLOB CEN64_SOURCES ${PROJECT_SOURCE_DIR}/*.c) | ||
file(GLOB PIF_SOURCES ${PROJECT_SOURCE_DIR}/pif/*.c) | ||
file(GLOB VR4300_SOURCES ${PROJECT_SOURCE_DIR}/vr4300/*.c) | ||
|
||
# Create the executable. | ||
add_executable(cen64 ${CEN64_SOURCES} ${BUS_SOURCES} ${PIF_SOURCES} | ||
${VR4300_SOURCES}) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Copyright (c) 2014, Tyler J. Stachecki | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
* Redistributions of source code must retain the above copyright | ||
notice, this list of conditions and the following disclaimer. | ||
* Redistributions in binary form must reproduce the above copyright | ||
notice, this list of conditions and the following disclaimer in the | ||
documentation and/or other materials provided with the distribution. | ||
* Neither the name of the Tyler J. Stachecki nor the names of its | ||
contributors may be used to endorse or promote products derived from | ||
this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL TYLER J. STACHECKI BE LIABLE FOR ANY DIRECT, | ||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | ||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<p align="center"> | ||
<img src="/assets/logo.png" /> | ||
</p> | ||
|
||
# About | ||
|
||
This is my pet project. It's something I pick up whenever I get bored. To me, | ||
what Nintendo and SGI did with this console is nothing short of amazing. The | ||
ingenuity and design of the hardware was well-ahead of it's time, and it is | ||
an absolute blast to reverse-engineer and study. I started this project in | ||
order to learn more about what _really_ went on at the hardware level back in | ||
the (good old) days. | ||
|
||
That being said, I've also grown tired of people complaining that "cycle | ||
accurate simulation on N-gen consoles is impossible." Not to be a bigot, but | ||
no, it's not. Is it hard to write a simulator that is capable of running fast | ||
enough to emulate a 93.75MHz processor on modern machines? Absolutely. Is it | ||
impossible? No, certainly not. It just takes time. Programming is an art, | ||
and like anything else, it takes time if done well. | ||
|
||
Getting back on track: this simulator attempts to be everything that every | ||
other emulator hoped to be, but never quite attained due to... emulation. My | ||
hopes are that properly simulating things at the cycle and pixel-accurate level | ||
will preserve the original fidelity of the work that so many companies put | ||
out. | ||
|
||
Thank you to every single one of you developers for filling my childhood | ||
with excellent memories. I'd also like to thank the community on all their | ||
hard work and effort spent reverse-engineering this little gem. Without | ||
further ado... | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
0.3 |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// | ||
// bus/controller.c: System bus controller. | ||
// | ||
// CEN64: Cycle-Accurate Nintendo 64 Simulator. | ||
// Copyright (C) 2014, Tyler J. Stachecki. | ||
// | ||
// This file is subject to the terms and conditions defined in | ||
// 'LICENSE', which is part of this source code package. | ||
// | ||
|
||
#include "common.h" | ||
#include "bus/controller.h" | ||
#include "pif/controller.h" | ||
|
||
// Initializes the bus component. | ||
int bus_init(struct bus_controller *bus) { | ||
bus->num_requests = 0; | ||
bus->rq_head = 0; | ||
bus->rq_tail = 0; | ||
|
||
return 0; | ||
} | ||
|
||
// Issues a read request to the bus. | ||
unsigned bus_read_word(struct bus_controller *bus, | ||
uint32_t address, uint32_t *word) { | ||
|
||
if (address >= 0x1FC00000 && address < 0x1FC07C00) | ||
return read_pifrom(bus->pif, word, address & 0xFFC); | ||
|
||
printf("bus_read_word: Failed to access: 0x%.8X\n", address); | ||
abort(); | ||
|
||
return 0; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// | ||
// bus/controller.h: System bus controller. | ||
// | ||
// CEN64: Cycle-Accurate Nintendo 64 Simulator. | ||
// Copyright (C) 2014, Tyler J. Stachecki. | ||
// | ||
// This file is subject to the terms and conditions defined in | ||
// 'LICENSE', which is part of this source code package. | ||
// | ||
|
||
#ifndef __bus_controller_h__ | ||
#define __bus_controller_h__ | ||
#define BUS_REQUEST_QUEUE_SIZE 8 | ||
|
||
struct bus_request; | ||
struct vr4300; | ||
|
||
struct bus_controller { | ||
struct bus_request *rq[BUS_REQUEST_QUEUE_SIZE]; | ||
unsigned num_requests, rq_head, rq_tail; | ||
|
||
struct pif_controller *pif; | ||
struct vr4300 *vr4300; | ||
}; | ||
|
||
int bus_init(struct bus_controller *bus); | ||
unsigned bus_read_word(struct bus_controller *bus, | ||
uint32_t address, uint32_t *word); | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// | ||
// cen64.c: CEN64 entry point. | ||
// | ||
// CEN64: Cycle-Accurate Nintendo 64 Simulator. | ||
// Copyright (C) 2014, Tyler J. Stachecki. | ||
// | ||
// This file is subject to the terms and conditions defined in | ||
// 'LICENSE', which is part of this source code package. | ||
// | ||
|
||
#include "common.h" | ||
#include "device.h" | ||
|
||
int main(int argc, const char *argv[]) { | ||
struct cen64_device *device; | ||
|
||
if (argc < 2) { | ||
printf("%s <pifrom.bin>\n", argv[0]); | ||
return 0; | ||
} | ||
|
||
if ((device = device_create(argv[1])) == NULL) { | ||
printf("Failed to create a device.\n"); | ||
return 1; | ||
} | ||
|
||
device_run(device); | ||
|
||
device_destroy(device); | ||
return 0; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// | ||
// common.h: Common definitions and such. | ||
// | ||
// CEN64: Cycle-Accurate Nintendo 64 Simulator. | ||
// Copyright (C) 2014, Tyler J. Stachecki. | ||
// | ||
// This file is subject to the terms and conditions defined in | ||
// 'LICENSE', which is part of this source code package. | ||
// | ||
|
||
#ifndef __common_h__ | ||
#define __common_h__ | ||
|
||
#ifdef _MSC_VER | ||
#define inline _inline | ||
#endif | ||
|
||
#ifndef __cplusplus | ||
#include <assert.h> | ||
#include <stddef.h> | ||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#else | ||
#include <cassert> | ||
#include <cstddef> | ||
#include <cstdlib> | ||
#include <cstdint> | ||
#include <cstdio> | ||
#include <cstring> | ||
#endif | ||
|
||
#ifndef _MSC_VER | ||
#ifndef __cplusplus | ||
#include <stdbool.h> | ||
#else | ||
#include <cstdbool> | ||
#endif | ||
|
||
#else | ||
typedef char bool; | ||
#define false 0 | ||
#define true 1 | ||
#endif | ||
|
||
#ifndef NDEBUG | ||
#ifndef __cplusplus | ||
#include <stdio.h> | ||
#else | ||
#include <cstdio> | ||
#endif | ||
#endif | ||
|
||
#define CACHE_LINE_SIZE 64 | ||
|
||
// Define cen64_align(). | ||
#ifdef _MSC_VER | ||
#define cen64_align(decl, value) __declspec(align(value)) decl | ||
|
||
#elif (defined __GNUC__) | ||
#define cen64_align(decl, value) decl __attribute__ ((aligned(value))) | ||
|
||
#else | ||
#define cen64_align(decl, value) decl value | ||
#endif | ||
|
||
// Define likely()/unlikely(). | ||
#ifdef __GNUC__ | ||
#define likely(expr) __builtin_expect(!!(expr), !0) | ||
#define unlikely(expr) __builtin_expect(!!(expr), 0) | ||
|
||
#else | ||
#define likely(expr) expr | ||
#define unlikely(expr) expr | ||
#endif | ||
|
||
// Define unused(). | ||
#ifdef __GNUC__ | ||
#define unused(decl) __attribute__((unused)) decl | ||
#else | ||
#define unused(decl) decl | ||
#endif | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// | ||
// device.c: CEN64 device container. | ||
// | ||
// CEN64: Cycle-Accurate Nintendo 64 Simulator. | ||
// Copyright (C) 2014, Tyler J. Stachecki. | ||
// | ||
// This file is subject to the terms and conditions defined in | ||
// 'LICENSE', which is part of this source code package. | ||
// | ||
|
||
#include "common.h" | ||
#include "device.h" | ||
#include "pif/controller.h" | ||
|
||
// Loads the PIFROM from a file into memory. | ||
static int load_pifrom(const char *file, uint8_t *rom) { | ||
int status = 0; | ||
size_t i, last; | ||
FILE *f; | ||
|
||
if ((f = fopen(file, "rb")) == NULL) { | ||
printf("load_pifrom: Failed to open: %s\n", file); | ||
return -1; | ||
} | ||
|
||
for (i = 0; i < PIFROM_SIZE; i += last) { | ||
last = fread(rom + i, 1, PIFROM_SIZE - i, f); | ||
|
||
if (feof(f)) { | ||
printf("load_pifrom: ROM file is smaller than expected.\n"); | ||
status = -1; | ||
break; | ||
} | ||
|
||
else if (ferror(f)) { | ||
printf("load_pifrom: An error occured while reading the ROM.\n"); | ||
status = -2; | ||
break; | ||
} | ||
} | ||
|
||
fclose(f); | ||
return status; | ||
} | ||
|
||
// Creates and initializes a device. | ||
struct cen64_device *device_create(const char *pifrom) { | ||
struct cen64_device *device; | ||
|
||
// Allocate memory. | ||
if ((device = (struct cen64_device*) malloc(sizeof(*device))) == NULL) | ||
return NULL; | ||
|
||
// Initialize the PIF. | ||
if (load_pifrom(pifrom, device->pifrom) < 0 || | ||
init_pif(&device->pif, &device->bus, device->pifrom)) { | ||
printf("create_device: Failed to initialize the PIF.\n"); | ||
|
||
free(device); | ||
return NULL; | ||
} | ||
|
||
// Initialize the bus. | ||
if (bus_init(&device->bus)) { | ||
printf("create_device: Failed to initialize the bus.\n"); | ||
|
||
free(device); | ||
return NULL; | ||
} | ||
|
||
device->bus.pif = &device->pif; | ||
device->bus.vr4300 = &device->vr4300; | ||
|
||
// Initialize the VR4300. | ||
if (vr4300_init(&device->vr4300, &device->bus)) { | ||
printf("create_device: Failed to initialize the VR4300.\n"); | ||
|
||
free(device); | ||
return NULL; | ||
} | ||
|
||
return device; | ||
} | ||
|
||
// Deallocates and cleans up a device. | ||
void device_destroy(struct cen64_device *device) { | ||
free(device); | ||
} | ||
|
||
// Kicks off threads and starts the device. | ||
void device_run(struct cen64_device *device) { | ||
unsigned i; | ||
|
||
for (i = 0; i < 93750000; i++) | ||
vr4300_cycle(&device->vr4300); | ||
} | ||
|
Oops, something went wrong.