Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
boytacean
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
João Magalhães
boytacean
Commits
4ca8872c
Verified
Commit
4ca8872c
authored
2 years ago
by
João Magalhães
Browse files
Options
Downloads
Patches
Plain Diff
feat: initial int and DMA support
parent
d41afb79
No related branches found
No related tags found
No related merge requests found
Pipeline
#893
passed
2 years ago
Stage: build
Stage: deploy
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
examples/sdl/src/main.rs
+2
-2
2 additions, 2 deletions
examples/sdl/src/main.rs
src/cpu.rs
+17
-2
17 additions, 2 deletions
src/cpu.rs
src/mmu.rs
+28
-1
28 additions, 1 deletion
src/mmu.rs
src/ppu.rs
+34
-19
34 additions, 19 deletions
src/ppu.rs
with
81 additions
and
24 deletions
examples/sdl/src/main.rs
+
2
−
2
View file @
4ca8872c
...
...
@@ -83,7 +83,7 @@ fn main() {
let
mut
game_boy
=
GameBoy
::
new
();
game_boy
.load_boot_dmg_bootix
();
//
game_boy.load_rom_file("../../res/roms.prop/tetris.gb");
game_boy
.load_rom_file
(
"../../res/roms.prop/tetris.gb"
);
//game_boy.load_rom_file("../../res/roms.prop/alleyway.gb");
//game_boy.load_rom_file("../../res/roms/firstwhite.gb");
...
...
@@ -97,7 +97,7 @@ fn main() {
//game_boy.load_rom_file("../../res/roms/paradius/cpu/06-ld r,r.gb"); // PASSED
//game_boy.load_rom_file("../../res/roms/paradius/cpu/07-jr,jp,call,ret,rst.gb"); // PASSED
//game_boy.load_rom_file("../../res/roms/paradius/cpu/08-misc instrs.gb"); // PASSED
game_boy
.load_rom_file
(
"../../res/roms/paradius/cpu/09-op r,r.gb"
);
// NO FINISH
//
game_boy.load_rom_file("../../res/roms/paradius/cpu/09-op r,r.gb"); // NO FINISH
//game_boy.load_rom_file("../../res/roms/paradius/cpu/11-op a,(hl).gb"); // NO FINISH
'main
:
loop
{
...
...
This diff is collapsed.
Click to expand it.
src/cpu.rs
+
17
−
2
View file @
4ca8872c
...
...
@@ -18,6 +18,7 @@ pub struct Cpu {
pub
e
:
u8
,
pub
h
:
u8
,
pub
l
:
u8
,
ime
:
bool
,
zero
:
bool
,
sub
:
bool
,
half_carry
:
bool
,
...
...
@@ -65,6 +66,7 @@ impl Cpu {
e
:
0x0
,
h
:
0x0
,
l
:
0x0
,
ime
:
false
,
zero
:
false
,
sub
:
false
,
half_carry
:
false
,
...
...
@@ -90,6 +92,19 @@ impl Cpu {
panic!
(
"Invalid PC area at 0x{:04x}"
,
pc
);
}
if
self
.ime
{
// @todo aggregate all of this interrupts in the MMU
if
self
.mmu
.ppu
()
.int_vblank
()
{
println!
(
"VAI FAZER HANDLING VBLANK"
);
let
pc
=
self
.pc
;
self
.disable_int
();
self
.push_word
(
pc
);
self
.pc
=
0x40
;
self
.mmu
.ppu
()
.ack_vblank
();
return
16
;
}
}
// fetches the current instruction and increments
// the PC (program counter) accordingly
let
mut
opcode
=
self
.mmu
.read
(
self
.pc
);
...
...
@@ -313,11 +328,11 @@ impl Cpu {
#[inline(always)]
pub
fn
enable_int
(
&
mut
self
)
{
// @todo implement this one
self
.ime
=
true
;
}
#[inline(always)]
pub
fn
disable_int
(
&
mut
self
)
{
// @todo implement this one
self
.ime
=
false
;
}
}
This diff is collapsed.
Click to expand it.
src/mmu.rs
+
28
−
1
View file @
4ca8872c
...
...
@@ -152,7 +152,17 @@ impl Mmu {
_
=>
println!
(
"Writing to unknown IO control 0x{:04x}"
,
addr
),
},
0x40
|
0x60
|
0x70
=>
{
self
.ppu
.write
(
addr
,
value
);
match
addr
&
0x00ff
{
0x0046
=>
{
// @todo must increment the cycle count by 160
// and make this a separated dma.rs file
println!
(
"GOING TO START DMA transfer to 0x{:x}00"
,
value
);
let
data
=
self
.read_many
((
value
as
u16
)
<<
8
,
160
);
self
.write_many
(
0xfe00
,
&
data
);
println!
(
"FINISHED DMA transfer"
)
}
_
=>
self
.ppu
.write
(
addr
,
value
),
}
}
0x50
=>
match
addr
&
0x00ff
{
0x50
=>
self
.boot_active
=
false
,
...
...
@@ -168,6 +178,23 @@ impl Mmu {
}
}
pub
fn
write_many
(
&
mut
self
,
addr
:
u16
,
data
:
&
Vec
<
u8
>
)
{
for
index
in
0
..
data
.len
()
{
self
.write
(
addr
+
index
as
u16
,
data
[
index
])
}
}
pub
fn
read_many
(
&
mut
self
,
addr
:
u16
,
count
:
u16
)
->
Vec
<
u8
>
{
let
mut
data
:
Vec
<
u8
>
=
vec!
[];
for
index
in
0
..
count
{
let
byte
=
self
.read
(
addr
+
index
);
data
.push
(
byte
);
}
return
data
;
}
pub
fn
write_boot
(
&
mut
self
,
addr
:
u16
,
buffer
:
&
[
u8
])
{
self
.boot
[
addr
as
usize
..
addr
as
usize
+
buffer
.len
()]
.clone_from_slice
(
buffer
);
}
...
...
This diff is collapsed.
Click to expand it.
src/ppu.rs
+
34
−
19
View file @
4ca8872c
...
...
@@ -84,6 +84,8 @@ pub struct Ppu {
bg_tile
:
bool
,
// Controls if the window is meant to be drawn.
switch_window
:
bool
,
// Controls the offset of the map that is going to be drawn
// for the window section of the screen.
window_map
:
bool
,
/// Flag that controls if the LCD screen is ON and displaying
/// content.
...
...
@@ -92,6 +94,9 @@ pub struct Ppu {
stat_vblank
:
bool
,
stat_oam
:
bool
,
stat_lyc
:
bool
,
// Boolean value set when the V-Blank interrupt should be handled
// by the next CPU clock.
int_vblank
:
bool
,
}
#[derive(Clone,
Copy,
PartialEq)]
...
...
@@ -130,6 +135,7 @@ impl Ppu {
stat_vblank
:
false
,
stat_oam
:
false
,
stat_lyc
:
false
,
int_vblank
:
false
,
}
}
...
...
@@ -166,6 +172,7 @@ impl Ppu {
// in case we've reached the end of the
// screen we're now entering the v-blank
if
self
.ly
==
144
{
self
.int_vblank
=
true
;
self
.mode
=
PpuMode
::
VBlank
;
// self.drawData
// @todo implement this one
...
...
@@ -289,6 +296,33 @@ impl Ppu {
}
}
pub
fn
fill_frame_buffer
(
&
mut
self
,
color
:
Pixel
)
{
for
index
in
(
0
..
self
.frame_buffer
.len
())
.step_by
(
RGB_SIZE
)
{
self
.frame_buffer
[
index
]
=
color
[
0
];
self
.frame_buffer
[
index
+
1
]
=
color
[
1
];
self
.frame_buffer
[
index
+
2
]
=
color
[
2
];
}
}
pub
fn
int_vblank
(
&
self
)
->
bool
{
self
.int_vblank
}
pub
fn
ack_vblank
(
&
mut
self
)
{
self
.int_vblank
=
false
;
}
/// Prints the tile data information to the stdout, this is
/// useful for debugging purposes.
pub
fn
draw_tile_stdout
(
&
self
,
tile_index
:
usize
)
{
for
y
in
0
..
8
{
for
x
in
0
..
8
{
print!
(
"{}"
,
self
.tiles
[
tile_index
][
y
as
usize
][
x
as
usize
]);
}
print!
(
"
\n
"
);
}
}
/// Updates the tile structure with the value that has
/// just been written to a location on the VRAM associated
/// with tiles.
...
...
@@ -378,25 +412,6 @@ impl Ppu {
}
}
pub
fn
fill_frame_buffer
(
&
mut
self
,
color
:
Pixel
)
{
for
index
in
(
0
..
self
.frame_buffer
.len
())
.step_by
(
RGB_SIZE
)
{
self
.frame_buffer
[
index
]
=
color
[
0
];
self
.frame_buffer
[
index
+
1
]
=
color
[
1
];
self
.frame_buffer
[
index
+
2
]
=
color
[
2
];
}
}
/// Prints the tile data information to the stdout, this is
/// useful for debugging purposes.
pub
fn
draw_tile_stdout
(
&
self
,
tile_index
:
usize
)
{
for
y
in
0
..
8
{
for
x
in
0
..
8
{
print!
(
"{}"
,
self
.tiles
[
tile_index
][
y
as
usize
][
x
as
usize
]);
}
print!
(
"
\n
"
);
}
}
/// Obtains the current level of the LCD interrupt by
/// checking the current PPU state in various sections.
fn
interrupt_level
(
&
self
)
->
bool
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment