-
Notifications
You must be signed in to change notification settings - Fork 56
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
0 parents
commit 7e3a322
Showing
79 changed files
with
8,247 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,8 @@ | ||
*~ | ||
*.swp | ||
*.gb | ||
*.o | ||
/roms | ||
/target | ||
/Cargo.lock | ||
/*.dll |
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,14 @@ | ||
[package] | ||
|
||
name = "mooneye-gb" | ||
version = "0.0.0" | ||
authors = ["Joonas Javanainen <[email protected]>"] | ||
|
||
[dependencies.sdl2] | ||
git = "https://github.com/AngryLawyer/rust-sdl2.git" | ||
|
||
[dependencies.snooze-rs] | ||
git = "https://github.com/Gekkio/snooze-rs.git" | ||
|
||
[dependencies.time] | ||
git = "https://github.com/rust-lang/time.git" |
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,15 @@ | ||
This software is licensed under the Apache 2 license, quoted below. | ||
|
||
Copyright 2014 Joonas Javanainen <[email protected]> | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
use this file except in compliance with the License. You may obtain a copy of | ||
the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
License for the specific language governing permissions and limitations under | ||
the License. |
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,8 @@ | ||
# Mooneye GB | ||
|
||
Another Gameboy emulator written in Rust. | ||
|
||
**Warning**: | ||
|
||
* Project is WIP | ||
* Doesn't work properly without a boot ROM |
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,30 @@ | ||
# Boot rom emulation accuracy | ||
|
||
## Open questions | ||
|
||
## Answered questions | ||
|
||
### Is it possible to restore the bootrom by writing some value to $FF50? | ||
|
||
*Answer*: No | ||
|
||
This was tested on a GBP (MGB-001) with the following test ROM, which attempts to write all possible values to $FF50: | ||
|
||
ld hl, $0000 | ||
ld b, $00 ; value to be written to $FF50 | ||
|
||
- ld a, b | ||
ld ($FF00+$50), a | ||
ld a, (HL) | ||
cp $31 ; DMG bootrom should have $31 at $0000 | ||
jr z, + | ||
inc b ; attempt next value | ||
jr nz, - ; retry until overflow | ||
|
||
+ nop | ||
|
||
; if A is $FF and B is $00, test failed | ||
; A should be $31 | ||
; B should contain the written value | ||
jp finish |
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,38 @@ | ||
# CPU emulation accuracy | ||
|
||
## Open questions | ||
|
||
### What is the exact behaviour of DI and EI? | ||
|
||
These instructions don't change interrupts immediately, but with a delay. What happens if you do another DI/EI while a delayed operation is ongoing? | ||
|
||
### Some instructions take more cycles than just the memory accesses. At which point in the instruction execution do these extra cycles occur? | ||
|
||
These instructions cost more than the memory accesses: | ||
|
||
* LD SP, HL | ||
* LD HL, (SP+e) | ||
* ADD HL, rr | ||
* ADD SP, e | ||
* JP cc, nn | ||
* JP nn | ||
* JR cc, n | ||
* JR n | ||
* INC rr | ||
* DEC rr | ||
* PUSH rr | ||
* RST | ||
* RET cc | ||
* RET | ||
* RETI | ||
|
||
Most of these instructions involve writing a 16-bit register, which could explain the timing. | ||
|
||
## Answered questions | ||
|
||
### Does BIT b, (HL) take 12 or 16 cycles? | ||
|
||
*Answer:* 12 cycles | ||
|
||
Blargg's instruction timing ROM confirms that BIT takes 12, and RES/SET take 16 cycles, which makes perfect sense. | ||
Some opcode listings in the internet (e.g. GBCPUman.pdf) are wrong. |
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,20 @@ | ||
# Joypad emulation accuracy | ||
|
||
## Open questions | ||
|
||
### Do joypad interrupts depend on the select bits P14-P15, or do we get an interrupt whenever any key is pressed regardless of select bit state? | ||
|
||
## Answered questions | ||
|
||
### The joypad register (P1) has only 4 inputs (P10-P13). What happens if you enable both key select bits P14-P15 and press overlapping keys? | ||
|
||
Both sets of keys are "merged" in the input bits P10-P13. So, if you have both key select bits enabled and press any combination of A and Right, you will see P10 go down (= "set"). Also, if you press A and Right, and then stop pressing Right, P10 should still be down because A is still being pressed. | ||
|
||
### What is the initial state of the joypad register (P1)? Does the boot rom write to it? | ||
|
||
The DMG/GBP boot rom doesn't write to the joypad register, and the initial value is 0xCF. | ||
This means that key select bits P14-P15 (bits 4-5) are low (= "set"). | ||
|
||
If GBC is used with old Gameboy games, the boot rom writes and reads from P1, because old games support | ||
palette switches with certain key combinations during boot. After booting, the value is 0xFF. | ||
This means all bits are high (= "unset"). |
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,15 @@ | ||
# Timer emulation accuracy | ||
|
||
## Open questions | ||
|
||
## Answered questions | ||
|
||
### Does writing to DIV ($FF04) reset both the internal and the visible register? | ||
|
||
*Answer:* Yes | ||
|
||
DIV is incremented every 64 t-cycles, so there is an internal counter that counts to 64. If we write any value to the DIV register, it is reset to 0, but we don't know if the internal counter is also reset. | ||
|
||
Consider the case where at time t=0 we reset the counter, and at time t=1 the DIV register would have incremented if we didn't do the reset. Do we see the DIV increment at time t=1 or t=64? | ||
|
||
A test ROM confirmed that increment happens at t=64, so the internal counter is also reset. See tests/div_timing. |
Empty file.
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,49 @@ | ||
use std::comm; | ||
use std::error::Error; | ||
use std::sync::Arc; | ||
use machine::MachineMessage; | ||
|
||
pub mod sdl; | ||
|
||
pub trait Backend<C: BackendSharedMemory> { | ||
fn main_loop(&mut self, SyncSender<BackendMessage>, Receiver<MachineMessage>); | ||
fn shared_memory(&self) -> Arc<C>; | ||
} | ||
|
||
pub trait BackendSharedMemory { | ||
fn draw_scanline(&self, &[GbColor, ..160], y: u8); | ||
} | ||
|
||
pub enum BackendMessage { | ||
KeyDown(GbKey), KeyUp(GbKey), Break, Step, Run, Turbo(bool) | ||
} | ||
|
||
#[deriving(Show)] | ||
pub enum GbKey { | ||
Right, Left, Up, Down, A, B, Select, Start | ||
} | ||
|
||
#[deriving(PartialEq, FromPrimitive, Copy)] | ||
pub enum GbColor { | ||
Off = 0, | ||
Light = 1, | ||
Dark = 2, | ||
On = 3 | ||
} | ||
|
||
impl GbColor { | ||
pub fn from_u8(value: u8) -> GbColor { | ||
FromPrimitive::from_u8(value).unwrap_or(GbColor::Off) | ||
} | ||
} | ||
|
||
pub fn init() -> Result<sdl::SdlBackend, Box<Error>> { | ||
match sdl::SdlBackend::init() { | ||
Ok(backend) => Ok(backend), | ||
Err(error) => Err(box error as Box<Error>) | ||
} | ||
} | ||
|
||
pub fn new_channel() -> (SyncSender<BackendMessage>, Receiver<BackendMessage>) { | ||
comm::sync_channel(128) | ||
} |
Binary file not shown.
Oops, something went wrong.